]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.md
i386.md (atansf2, [...]): Move near atan2?f3 expanders.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_PROBE 10)
67 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SET_GOT 12)
69 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70
71 ; TLS support
72 (UNSPEC_TP 15)
73 (UNSPEC_TLS_GD 16)
74 (UNSPEC_TLS_LD_BASE 17)
75
76 ; Other random patterns
77 (UNSPEC_SCAS 20)
78 (UNSPEC_SIN 21)
79 (UNSPEC_COS 22)
80 (UNSPEC_FNSTSW 24)
81 (UNSPEC_SAHF 25)
82 (UNSPEC_FSTCW 26)
83 (UNSPEC_ADD_CARRY 27)
84 (UNSPEC_FLDCW 28)
85
86 ; For SSE/MMX support:
87 (UNSPEC_FIX 30)
88 (UNSPEC_MASKMOV 32)
89 (UNSPEC_MOVMSK 33)
90 (UNSPEC_MOVNT 34)
91 (UNSPEC_MOVA 38)
92 (UNSPEC_MOVU 39)
93 (UNSPEC_SHUFFLE 41)
94 (UNSPEC_RCP 42)
95 (UNSPEC_RSQRT 43)
96 (UNSPEC_SFENCE 44)
97 (UNSPEC_NOP 45) ; prevents combiner cleverness
98 (UNSPEC_PAVGUSB 49)
99 (UNSPEC_PFRCP 50)
100 (UNSPEC_PFRCPIT1 51)
101 (UNSPEC_PFRCPIT2 52)
102 (UNSPEC_PFRSQRT 53)
103 (UNSPEC_PFRSQIT1 54)
104 (UNSPEC_PSHUFLW 55)
105 (UNSPEC_PSHUFHW 56)
106 (UNSPEC_MFENCE 59)
107 (UNSPEC_LFENCE 60)
108 (UNSPEC_PSADBW 61)
109 (UNSPEC_ADDSUB 71)
110 (UNSPEC_HADD 72)
111 (UNSPEC_HSUB 73)
112 (UNSPEC_MOVSHDUP 74)
113 (UNSPEC_MOVSLDUP 75)
114 (UNSPEC_LDQQU 76)
115 (UNSPEC_MOVDDUP 77)
116
117 ; x87 Floating point
118 (UNSPEC_FPATAN 65)
119 (UNSPEC_FYL2X 66)
120 (UNSPEC_FRNDINT 68)
121 (UNSPEC_F2XM1 69)
122
123 ; x87 Double output FP
124 (UNSPEC_SINCOS_COS 80)
125 (UNSPEC_SINCOS_SIN 81)
126 (UNSPEC_TAN_ONE 82)
127 (UNSPEC_TAN_TAN 83)
128 (UNSPEC_XTRACT_FRACT 84)
129 (UNSPEC_XTRACT_EXP 85)
130 (UNSPEC_FSCALE_FRACT 86)
131 (UNSPEC_FSCALE_EXP 87)
132
133 ; REP instruction
134 (UNSPEC_REP 75)
135 ])
136
137 (define_constants
138 [(UNSPECV_BLOCKAGE 0)
139 (UNSPECV_EH_RETURN 13)
140 (UNSPECV_EMMS 31)
141 (UNSPECV_LDMXCSR 37)
142 (UNSPECV_STMXCSR 40)
143 (UNSPECV_FEMMS 46)
144 (UNSPECV_CLFLUSH 57)
145 (UNSPECV_ALIGN 68)
146 (UNSPECV_MONITOR 69)
147 (UNSPECV_MWAIT 70)
148 ])
149
150 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
151 ;; from i386.c.
152
153 ;; In C guard expressions, put expressions which may be compile-time
154 ;; constants first. This allows for better optimization. For
155 ;; example, write "TARGET_64BIT && reload_completed", not
156 ;; "reload_completed && TARGET_64BIT".
157
158 \f
159 ;; Processor type. This attribute must exactly match the processor_type
160 ;; enumeration in i386.h.
161 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
162 (const (symbol_ref "ix86_tune")))
163
164 ;; A basic instruction type. Refinements due to arguments to be
165 ;; provided in other attributes.
166 (define_attr "type"
167 "other,multi,
168 alu,alu1,negnot,imov,imovx,lea,
169 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
170 icmp,test,ibr,setcc,icmov,
171 push,pop,call,callv,leave,
172 str,cld,
173 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
174 sselog,sseiadd,sseishft,sseimul,
175 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
176 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
177 (const_string "other"))
178
179 ;; Main data type used by the insn
180 (define_attr "mode"
181 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
182 (const_string "unknown"))
183
184 ;; The CPU unit operations uses.
185 (define_attr "unit" "integer,i387,sse,mmx,unknown"
186 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
187 (const_string "i387")
188 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
189 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
190 (const_string "sse")
191 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
192 (const_string "mmx")
193 (eq_attr "type" "other")
194 (const_string "unknown")]
195 (const_string "integer")))
196
197 ;; The (bounding maximum) length of an instruction immediate.
198 (define_attr "length_immediate" ""
199 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
200 (const_int 0)
201 (eq_attr "unit" "i387,sse,mmx")
202 (const_int 0)
203 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
204 imul,icmp,push,pop")
205 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
206 (eq_attr "type" "imov,test")
207 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
208 (eq_attr "type" "call")
209 (if_then_else (match_operand 0 "constant_call_address_operand" "")
210 (const_int 4)
211 (const_int 0))
212 (eq_attr "type" "callv")
213 (if_then_else (match_operand 1 "constant_call_address_operand" "")
214 (const_int 4)
215 (const_int 0))
216 ;; We don't know the size before shorten_branches. Expect
217 ;; the instruction to fit for better scheduling.
218 (eq_attr "type" "ibr")
219 (const_int 1)
220 ]
221 (symbol_ref "/* Update immediate_length and other attributes! */
222 abort(),1")))
223
224 ;; The (bounding maximum) length of an instruction address.
225 (define_attr "length_address" ""
226 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
227 (const_int 0)
228 (and (eq_attr "type" "call")
229 (match_operand 0 "constant_call_address_operand" ""))
230 (const_int 0)
231 (and (eq_attr "type" "callv")
232 (match_operand 1 "constant_call_address_operand" ""))
233 (const_int 0)
234 ]
235 (symbol_ref "ix86_attr_length_address_default (insn)")))
236
237 ;; Set when length prefix is used.
238 (define_attr "prefix_data16" ""
239 (if_then_else (ior (eq_attr "mode" "HI")
240 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
241 (const_int 1)
242 (const_int 0)))
243
244 ;; Set when string REP prefix is used.
245 (define_attr "prefix_rep" ""
246 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
247 (const_int 1)
248 (const_int 0)))
249
250 ;; Set when 0f opcode prefix is used.
251 (define_attr "prefix_0f" ""
252 (if_then_else
253 (ior (eq_attr "type" "imovx,setcc,icmov")
254 (eq_attr "unit" "sse,mmx"))
255 (const_int 1)
256 (const_int 0)))
257
258 ;; Set when REX opcode prefix is used.
259 (define_attr "prefix_rex" ""
260 (cond [(and (eq_attr "mode" "DI")
261 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
262 (const_int 1)
263 (and (eq_attr "mode" "QI")
264 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
265 (const_int 0)))
266 (const_int 1)
267 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
268 (const_int 0))
269 (const_int 1)
270 ]
271 (const_int 0)))
272
273 ;; Set when modrm byte is used.
274 (define_attr "modrm" ""
275 (cond [(eq_attr "type" "str,cld,leave")
276 (const_int 0)
277 (eq_attr "unit" "i387")
278 (const_int 0)
279 (and (eq_attr "type" "incdec")
280 (ior (match_operand:SI 1 "register_operand" "")
281 (match_operand:HI 1 "register_operand" "")))
282 (const_int 0)
283 (and (eq_attr "type" "push")
284 (not (match_operand 1 "memory_operand" "")))
285 (const_int 0)
286 (and (eq_attr "type" "pop")
287 (not (match_operand 0 "memory_operand" "")))
288 (const_int 0)
289 (and (eq_attr "type" "imov")
290 (and (match_operand 0 "register_operand" "")
291 (match_operand 1 "immediate_operand" "")))
292 (const_int 0)
293 (and (eq_attr "type" "call")
294 (match_operand 0 "constant_call_address_operand" ""))
295 (const_int 0)
296 (and (eq_attr "type" "callv")
297 (match_operand 1 "constant_call_address_operand" ""))
298 (const_int 0)
299 ]
300 (const_int 1)))
301
302 ;; The (bounding maximum) length of an instruction in bytes.
303 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
304 ;; to split it and compute proper length as for other insns.
305 (define_attr "length" ""
306 (cond [(eq_attr "type" "other,multi,fistp")
307 (const_int 16)
308 (eq_attr "type" "fcmp")
309 (const_int 4)
310 (eq_attr "unit" "i387")
311 (plus (const_int 2)
312 (plus (attr "prefix_data16")
313 (attr "length_address")))]
314 (plus (plus (attr "modrm")
315 (plus (attr "prefix_0f")
316 (plus (attr "prefix_rex")
317 (const_int 1))))
318 (plus (attr "prefix_rep")
319 (plus (attr "prefix_data16")
320 (plus (attr "length_immediate")
321 (attr "length_address")))))))
322
323 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
324 ;; `store' if there is a simple memory reference therein, or `unknown'
325 ;; if the instruction is complex.
326
327 (define_attr "memory" "none,load,store,both,unknown"
328 (cond [(eq_attr "type" "other,multi,str")
329 (const_string "unknown")
330 (eq_attr "type" "lea,fcmov,fpspc,cld")
331 (const_string "none")
332 (eq_attr "type" "fistp,leave")
333 (const_string "both")
334 (eq_attr "type" "push")
335 (if_then_else (match_operand 1 "memory_operand" "")
336 (const_string "both")
337 (const_string "store"))
338 (eq_attr "type" "pop")
339 (if_then_else (match_operand 0 "memory_operand" "")
340 (const_string "both")
341 (const_string "load"))
342 (eq_attr "type" "setcc")
343 (if_then_else (match_operand 0 "memory_operand" "")
344 (const_string "store")
345 (const_string "none"))
346 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
347 (if_then_else (ior (match_operand 0 "memory_operand" "")
348 (match_operand 1 "memory_operand" ""))
349 (const_string "load")
350 (const_string "none"))
351 (eq_attr "type" "ibr")
352 (if_then_else (match_operand 0 "memory_operand" "")
353 (const_string "load")
354 (const_string "none"))
355 (eq_attr "type" "call")
356 (if_then_else (match_operand 0 "constant_call_address_operand" "")
357 (const_string "none")
358 (const_string "load"))
359 (eq_attr "type" "callv")
360 (if_then_else (match_operand 1 "constant_call_address_operand" "")
361 (const_string "none")
362 (const_string "load"))
363 (and (eq_attr "type" "alu1,negnot,ishift1")
364 (match_operand 1 "memory_operand" ""))
365 (const_string "both")
366 (and (match_operand 0 "memory_operand" "")
367 (match_operand 1 "memory_operand" ""))
368 (const_string "both")
369 (match_operand 0 "memory_operand" "")
370 (const_string "store")
371 (match_operand 1 "memory_operand" "")
372 (const_string "load")
373 (and (eq_attr "type"
374 "!alu1,negnot,ishift1,
375 imov,imovx,icmp,test,
376 fmov,fcmp,fsgn,
377 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
378 mmx,mmxmov,mmxcmp,mmxcvt")
379 (match_operand 2 "memory_operand" ""))
380 (const_string "load")
381 (and (eq_attr "type" "icmov")
382 (match_operand 3 "memory_operand" ""))
383 (const_string "load")
384 ]
385 (const_string "none")))
386
387 ;; Indicates if an instruction has both an immediate and a displacement.
388
389 (define_attr "imm_disp" "false,true,unknown"
390 (cond [(eq_attr "type" "other,multi")
391 (const_string "unknown")
392 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
393 (and (match_operand 0 "memory_displacement_operand" "")
394 (match_operand 1 "immediate_operand" "")))
395 (const_string "true")
396 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
397 (and (match_operand 0 "memory_displacement_operand" "")
398 (match_operand 2 "immediate_operand" "")))
399 (const_string "true")
400 ]
401 (const_string "false")))
402
403 ;; Indicates if an FP operation has an integer source.
404
405 (define_attr "fp_int_src" "false,true"
406 (const_string "false"))
407
408 ;; Describe a user's asm statement.
409 (define_asm_attributes
410 [(set_attr "length" "128")
411 (set_attr "type" "multi")])
412 \f
413 (include "pentium.md")
414 (include "ppro.md")
415 (include "k6.md")
416 (include "athlon.md")
417 \f
418 ;; Compare instructions.
419
420 ;; All compare insns have expanders that save the operands away without
421 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
422 ;; after the cmp) will actually emit the cmpM.
423
424 (define_expand "cmpdi"
425 [(set (reg:CC 17)
426 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
427 (match_operand:DI 1 "x86_64_general_operand" "")))]
428 ""
429 {
430 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
431 operands[0] = force_reg (DImode, operands[0]);
432 ix86_compare_op0 = operands[0];
433 ix86_compare_op1 = operands[1];
434 DONE;
435 })
436
437 (define_expand "cmpsi"
438 [(set (reg:CC 17)
439 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
440 (match_operand:SI 1 "general_operand" "")))]
441 ""
442 {
443 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
444 operands[0] = force_reg (SImode, operands[0]);
445 ix86_compare_op0 = operands[0];
446 ix86_compare_op1 = operands[1];
447 DONE;
448 })
449
450 (define_expand "cmphi"
451 [(set (reg:CC 17)
452 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
453 (match_operand:HI 1 "general_operand" "")))]
454 ""
455 {
456 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
457 operands[0] = force_reg (HImode, operands[0]);
458 ix86_compare_op0 = operands[0];
459 ix86_compare_op1 = operands[1];
460 DONE;
461 })
462
463 (define_expand "cmpqi"
464 [(set (reg:CC 17)
465 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
466 (match_operand:QI 1 "general_operand" "")))]
467 "TARGET_QIMODE_MATH"
468 {
469 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
470 operands[0] = force_reg (QImode, operands[0]);
471 ix86_compare_op0 = operands[0];
472 ix86_compare_op1 = operands[1];
473 DONE;
474 })
475
476 (define_insn "cmpdi_ccno_1_rex64"
477 [(set (reg 17)
478 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
479 (match_operand:DI 1 "const0_operand" "n,n")))]
480 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
481 "@
482 test{q}\t{%0, %0|%0, %0}
483 cmp{q}\t{%1, %0|%0, %1}"
484 [(set_attr "type" "test,icmp")
485 (set_attr "length_immediate" "0,1")
486 (set_attr "mode" "DI")])
487
488 (define_insn "*cmpdi_minus_1_rex64"
489 [(set (reg 17)
490 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
491 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
492 (const_int 0)))]
493 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
494 "cmp{q}\t{%1, %0|%0, %1}"
495 [(set_attr "type" "icmp")
496 (set_attr "mode" "DI")])
497
498 (define_expand "cmpdi_1_rex64"
499 [(set (reg:CC 17)
500 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
501 (match_operand:DI 1 "general_operand" "")))]
502 "TARGET_64BIT"
503 "")
504
505 (define_insn "cmpdi_1_insn_rex64"
506 [(set (reg 17)
507 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
508 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
509 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
510 "cmp{q}\t{%1, %0|%0, %1}"
511 [(set_attr "type" "icmp")
512 (set_attr "mode" "DI")])
513
514
515 (define_insn "*cmpsi_ccno_1"
516 [(set (reg 17)
517 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
518 (match_operand:SI 1 "const0_operand" "n,n")))]
519 "ix86_match_ccmode (insn, CCNOmode)"
520 "@
521 test{l}\t{%0, %0|%0, %0}
522 cmp{l}\t{%1, %0|%0, %1}"
523 [(set_attr "type" "test,icmp")
524 (set_attr "length_immediate" "0,1")
525 (set_attr "mode" "SI")])
526
527 (define_insn "*cmpsi_minus_1"
528 [(set (reg 17)
529 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
530 (match_operand:SI 1 "general_operand" "ri,mr"))
531 (const_int 0)))]
532 "ix86_match_ccmode (insn, CCGOCmode)"
533 "cmp{l}\t{%1, %0|%0, %1}"
534 [(set_attr "type" "icmp")
535 (set_attr "mode" "SI")])
536
537 (define_expand "cmpsi_1"
538 [(set (reg:CC 17)
539 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
540 (match_operand:SI 1 "general_operand" "ri,mr")))]
541 ""
542 "")
543
544 (define_insn "*cmpsi_1_insn"
545 [(set (reg 17)
546 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
547 (match_operand:SI 1 "general_operand" "ri,mr")))]
548 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
549 && ix86_match_ccmode (insn, CCmode)"
550 "cmp{l}\t{%1, %0|%0, %1}"
551 [(set_attr "type" "icmp")
552 (set_attr "mode" "SI")])
553
554 (define_insn "*cmphi_ccno_1"
555 [(set (reg 17)
556 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
557 (match_operand:HI 1 "const0_operand" "n,n")))]
558 "ix86_match_ccmode (insn, CCNOmode)"
559 "@
560 test{w}\t{%0, %0|%0, %0}
561 cmp{w}\t{%1, %0|%0, %1}"
562 [(set_attr "type" "test,icmp")
563 (set_attr "length_immediate" "0,1")
564 (set_attr "mode" "HI")])
565
566 (define_insn "*cmphi_minus_1"
567 [(set (reg 17)
568 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
569 (match_operand:HI 1 "general_operand" "ri,mr"))
570 (const_int 0)))]
571 "ix86_match_ccmode (insn, CCGOCmode)"
572 "cmp{w}\t{%1, %0|%0, %1}"
573 [(set_attr "type" "icmp")
574 (set_attr "mode" "HI")])
575
576 (define_insn "*cmphi_1"
577 [(set (reg 17)
578 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
579 (match_operand:HI 1 "general_operand" "ri,mr")))]
580 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
581 && ix86_match_ccmode (insn, CCmode)"
582 "cmp{w}\t{%1, %0|%0, %1}"
583 [(set_attr "type" "icmp")
584 (set_attr "mode" "HI")])
585
586 (define_insn "*cmpqi_ccno_1"
587 [(set (reg 17)
588 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
589 (match_operand:QI 1 "const0_operand" "n,n")))]
590 "ix86_match_ccmode (insn, CCNOmode)"
591 "@
592 test{b}\t{%0, %0|%0, %0}
593 cmp{b}\t{$0, %0|%0, 0}"
594 [(set_attr "type" "test,icmp")
595 (set_attr "length_immediate" "0,1")
596 (set_attr "mode" "QI")])
597
598 (define_insn "*cmpqi_1"
599 [(set (reg 17)
600 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
601 (match_operand:QI 1 "general_operand" "qi,mq")))]
602 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
603 && ix86_match_ccmode (insn, CCmode)"
604 "cmp{b}\t{%1, %0|%0, %1}"
605 [(set_attr "type" "icmp")
606 (set_attr "mode" "QI")])
607
608 (define_insn "*cmpqi_minus_1"
609 [(set (reg 17)
610 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
611 (match_operand:QI 1 "general_operand" "qi,mq"))
612 (const_int 0)))]
613 "ix86_match_ccmode (insn, CCGOCmode)"
614 "cmp{b}\t{%1, %0|%0, %1}"
615 [(set_attr "type" "icmp")
616 (set_attr "mode" "QI")])
617
618 (define_insn "*cmpqi_ext_1"
619 [(set (reg 17)
620 (compare
621 (match_operand:QI 0 "general_operand" "Qm")
622 (subreg:QI
623 (zero_extract:SI
624 (match_operand 1 "ext_register_operand" "Q")
625 (const_int 8)
626 (const_int 8)) 0)))]
627 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
628 "cmp{b}\t{%h1, %0|%0, %h1}"
629 [(set_attr "type" "icmp")
630 (set_attr "mode" "QI")])
631
632 (define_insn "*cmpqi_ext_1_rex64"
633 [(set (reg 17)
634 (compare
635 (match_operand:QI 0 "register_operand" "Q")
636 (subreg:QI
637 (zero_extract:SI
638 (match_operand 1 "ext_register_operand" "Q")
639 (const_int 8)
640 (const_int 8)) 0)))]
641 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
642 "cmp{b}\t{%h1, %0|%0, %h1}"
643 [(set_attr "type" "icmp")
644 (set_attr "mode" "QI")])
645
646 (define_insn "*cmpqi_ext_2"
647 [(set (reg 17)
648 (compare
649 (subreg:QI
650 (zero_extract:SI
651 (match_operand 0 "ext_register_operand" "Q")
652 (const_int 8)
653 (const_int 8)) 0)
654 (match_operand:QI 1 "const0_operand" "n")))]
655 "ix86_match_ccmode (insn, CCNOmode)"
656 "test{b}\t%h0, %h0"
657 [(set_attr "type" "test")
658 (set_attr "length_immediate" "0")
659 (set_attr "mode" "QI")])
660
661 (define_expand "cmpqi_ext_3"
662 [(set (reg:CC 17)
663 (compare:CC
664 (subreg:QI
665 (zero_extract:SI
666 (match_operand 0 "ext_register_operand" "")
667 (const_int 8)
668 (const_int 8)) 0)
669 (match_operand:QI 1 "general_operand" "")))]
670 ""
671 "")
672
673 (define_insn "cmpqi_ext_3_insn"
674 [(set (reg 17)
675 (compare
676 (subreg:QI
677 (zero_extract:SI
678 (match_operand 0 "ext_register_operand" "Q")
679 (const_int 8)
680 (const_int 8)) 0)
681 (match_operand:QI 1 "general_operand" "Qmn")))]
682 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
683 "cmp{b}\t{%1, %h0|%h0, %1}"
684 [(set_attr "type" "icmp")
685 (set_attr "mode" "QI")])
686
687 (define_insn "cmpqi_ext_3_insn_rex64"
688 [(set (reg 17)
689 (compare
690 (subreg:QI
691 (zero_extract:SI
692 (match_operand 0 "ext_register_operand" "Q")
693 (const_int 8)
694 (const_int 8)) 0)
695 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
696 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
697 "cmp{b}\t{%1, %h0|%h0, %1}"
698 [(set_attr "type" "icmp")
699 (set_attr "mode" "QI")])
700
701 (define_insn "*cmpqi_ext_4"
702 [(set (reg 17)
703 (compare
704 (subreg:QI
705 (zero_extract:SI
706 (match_operand 0 "ext_register_operand" "Q")
707 (const_int 8)
708 (const_int 8)) 0)
709 (subreg:QI
710 (zero_extract:SI
711 (match_operand 1 "ext_register_operand" "Q")
712 (const_int 8)
713 (const_int 8)) 0)))]
714 "ix86_match_ccmode (insn, CCmode)"
715 "cmp{b}\t{%h1, %h0|%h0, %h1}"
716 [(set_attr "type" "icmp")
717 (set_attr "mode" "QI")])
718
719 ;; These implement float point compares.
720 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
721 ;; which would allow mix and match FP modes on the compares. Which is what
722 ;; the old patterns did, but with many more of them.
723
724 (define_expand "cmpxf"
725 [(set (reg:CC 17)
726 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
727 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
728 "TARGET_80387"
729 {
730 ix86_compare_op0 = operands[0];
731 ix86_compare_op1 = operands[1];
732 DONE;
733 })
734
735 (define_expand "cmpdf"
736 [(set (reg:CC 17)
737 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
738 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
739 "TARGET_80387 || TARGET_SSE2"
740 {
741 ix86_compare_op0 = operands[0];
742 ix86_compare_op1 = operands[1];
743 DONE;
744 })
745
746 (define_expand "cmpsf"
747 [(set (reg:CC 17)
748 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
749 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
750 "TARGET_80387 || TARGET_SSE"
751 {
752 ix86_compare_op0 = operands[0];
753 ix86_compare_op1 = operands[1];
754 DONE;
755 })
756
757 ;; FP compares, step 1:
758 ;; Set the FP condition codes.
759 ;;
760 ;; CCFPmode compare with exceptions
761 ;; CCFPUmode compare with no exceptions
762
763 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
764 ;; and that fp moves clobber the condition codes, and that there is
765 ;; currently no way to describe this fact to reg-stack. So there are
766 ;; no splitters yet for this.
767
768 ;; %%% YIKES! This scheme does not retain a strong connection between
769 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
770 ;; work! Only allow tos/mem with tos in op 0.
771 ;;
772 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
773 ;; things aren't as bad as they sound...
774
775 (define_insn "*cmpfp_0"
776 [(set (match_operand:HI 0 "register_operand" "=a")
777 (unspec:HI
778 [(compare:CCFP (match_operand 1 "register_operand" "f")
779 (match_operand 2 "const0_operand" "X"))]
780 UNSPEC_FNSTSW))]
781 "TARGET_80387
782 && FLOAT_MODE_P (GET_MODE (operands[1]))
783 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
784 {
785 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
786 return "ftst\;fnstsw\t%0\;fstp\t%y0";
787 else
788 return "ftst\;fnstsw\t%0";
789 }
790 [(set_attr "type" "multi")
791 (set (attr "mode")
792 (cond [(match_operand:SF 1 "" "")
793 (const_string "SF")
794 (match_operand:DF 1 "" "")
795 (const_string "DF")
796 ]
797 (const_string "XF")))])
798
799 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
800 ;; used to manage the reg stack popping would not be preserved.
801
802 (define_insn "*cmpfp_2_sf"
803 [(set (reg:CCFP 18)
804 (compare:CCFP
805 (match_operand:SF 0 "register_operand" "f")
806 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
807 "TARGET_80387"
808 "* return output_fp_compare (insn, operands, 0, 0);"
809 [(set_attr "type" "fcmp")
810 (set_attr "mode" "SF")])
811
812 (define_insn "*cmpfp_2_sf_1"
813 [(set (match_operand:HI 0 "register_operand" "=a")
814 (unspec:HI
815 [(compare:CCFP
816 (match_operand:SF 1 "register_operand" "f")
817 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
818 UNSPEC_FNSTSW))]
819 "TARGET_80387"
820 "* return output_fp_compare (insn, operands, 2, 0);"
821 [(set_attr "type" "fcmp")
822 (set_attr "mode" "SF")])
823
824 (define_insn "*cmpfp_2_df"
825 [(set (reg:CCFP 18)
826 (compare:CCFP
827 (match_operand:DF 0 "register_operand" "f")
828 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
829 "TARGET_80387"
830 "* return output_fp_compare (insn, operands, 0, 0);"
831 [(set_attr "type" "fcmp")
832 (set_attr "mode" "DF")])
833
834 (define_insn "*cmpfp_2_df_1"
835 [(set (match_operand:HI 0 "register_operand" "=a")
836 (unspec:HI
837 [(compare:CCFP
838 (match_operand:DF 1 "register_operand" "f")
839 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
840 UNSPEC_FNSTSW))]
841 "TARGET_80387"
842 "* return output_fp_compare (insn, operands, 2, 0);"
843 [(set_attr "type" "multi")
844 (set_attr "mode" "DF")])
845
846 (define_insn "*cmpfp_2_xf"
847 [(set (reg:CCFP 18)
848 (compare:CCFP
849 (match_operand:XF 0 "register_operand" "f")
850 (match_operand:XF 1 "register_operand" "f")))]
851 "TARGET_80387"
852 "* return output_fp_compare (insn, operands, 0, 0);"
853 [(set_attr "type" "fcmp")
854 (set_attr "mode" "XF")])
855
856 (define_insn "*cmpfp_2_xf_1"
857 [(set (match_operand:HI 0 "register_operand" "=a")
858 (unspec:HI
859 [(compare:CCFP
860 (match_operand:XF 1 "register_operand" "f")
861 (match_operand:XF 2 "register_operand" "f"))]
862 UNSPEC_FNSTSW))]
863 "TARGET_80387"
864 "* return output_fp_compare (insn, operands, 2, 0);"
865 [(set_attr "type" "multi")
866 (set_attr "mode" "XF")])
867
868 (define_insn "*cmpfp_2u"
869 [(set (reg:CCFPU 18)
870 (compare:CCFPU
871 (match_operand 0 "register_operand" "f")
872 (match_operand 1 "register_operand" "f")))]
873 "TARGET_80387
874 && FLOAT_MODE_P (GET_MODE (operands[0]))
875 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
876 "* return output_fp_compare (insn, operands, 0, 1);"
877 [(set_attr "type" "fcmp")
878 (set (attr "mode")
879 (cond [(match_operand:SF 1 "" "")
880 (const_string "SF")
881 (match_operand:DF 1 "" "")
882 (const_string "DF")
883 ]
884 (const_string "XF")))])
885
886 (define_insn "*cmpfp_2u_1"
887 [(set (match_operand:HI 0 "register_operand" "=a")
888 (unspec:HI
889 [(compare:CCFPU
890 (match_operand 1 "register_operand" "f")
891 (match_operand 2 "register_operand" "f"))]
892 UNSPEC_FNSTSW))]
893 "TARGET_80387
894 && FLOAT_MODE_P (GET_MODE (operands[1]))
895 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
896 "* return output_fp_compare (insn, operands, 2, 1);"
897 [(set_attr "type" "multi")
898 (set (attr "mode")
899 (cond [(match_operand:SF 1 "" "")
900 (const_string "SF")
901 (match_operand:DF 1 "" "")
902 (const_string "DF")
903 ]
904 (const_string "XF")))])
905
906 ;; Patterns to match the SImode-in-memory ficom instructions.
907 ;;
908 ;; %%% Play games with accepting gp registers, as otherwise we have to
909 ;; force them to memory during rtl generation, which is no good. We
910 ;; can get rid of this once we teach reload to do memory input reloads
911 ;; via pushes.
912
913 (define_insn "*ficom_1"
914 [(set (reg:CCFP 18)
915 (compare:CCFP
916 (match_operand 0 "register_operand" "f,f")
917 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
918 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
919 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
920 "#")
921
922 ;; Split the not-really-implemented gp register case into a
923 ;; push-op-pop sequence.
924 ;;
925 ;; %%% This is most efficient, but am I gonna get in trouble
926 ;; for separating cc0_setter and cc0_user?
927
928 (define_split
929 [(set (reg:CCFP 18)
930 (compare:CCFP
931 (match_operand:SF 0 "register_operand" "")
932 (float (match_operand:SI 1 "register_operand" ""))))]
933 "0 && TARGET_80387 && reload_completed"
934 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
935 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
936 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
937 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
938 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
939 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
940
941 ;; FP compares, step 2
942 ;; Move the fpsw to ax.
943
944 (define_insn "*x86_fnstsw_1"
945 [(set (match_operand:HI 0 "register_operand" "=a")
946 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
947 "TARGET_80387"
948 "fnstsw\t%0"
949 [(set_attr "length" "2")
950 (set_attr "mode" "SI")
951 (set_attr "unit" "i387")])
952
953 ;; FP compares, step 3
954 ;; Get ax into flags, general case.
955
956 (define_insn "x86_sahf_1"
957 [(set (reg:CC 17)
958 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
959 "!TARGET_64BIT"
960 "sahf"
961 [(set_attr "length" "1")
962 (set_attr "athlon_decode" "vector")
963 (set_attr "mode" "SI")])
964
965 ;; Pentium Pro can do steps 1 through 3 in one go.
966
967 (define_insn "*cmpfp_i"
968 [(set (reg:CCFP 17)
969 (compare:CCFP (match_operand 0 "register_operand" "f")
970 (match_operand 1 "register_operand" "f")))]
971 "TARGET_80387 && TARGET_CMOVE
972 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
973 && FLOAT_MODE_P (GET_MODE (operands[0]))
974 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
975 "* return output_fp_compare (insn, operands, 1, 0);"
976 [(set_attr "type" "fcmp")
977 (set (attr "mode")
978 (cond [(match_operand:SF 1 "" "")
979 (const_string "SF")
980 (match_operand:DF 1 "" "")
981 (const_string "DF")
982 ]
983 (const_string "XF")))
984 (set_attr "athlon_decode" "vector")])
985
986 (define_insn "*cmpfp_i_sse"
987 [(set (reg:CCFP 17)
988 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
989 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
990 "TARGET_80387
991 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
992 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
993 "* return output_fp_compare (insn, operands, 1, 0);"
994 [(set_attr "type" "fcmp,ssecomi")
995 (set (attr "mode")
996 (if_then_else (match_operand:SF 1 "" "")
997 (const_string "SF")
998 (const_string "DF")))
999 (set_attr "athlon_decode" "vector")])
1000
1001 (define_insn "*cmpfp_i_sse_only"
1002 [(set (reg:CCFP 17)
1003 (compare:CCFP (match_operand 0 "register_operand" "x")
1004 (match_operand 1 "nonimmediate_operand" "xm")))]
1005 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1006 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1007 "* return output_fp_compare (insn, operands, 1, 0);"
1008 [(set_attr "type" "ssecomi")
1009 (set (attr "mode")
1010 (if_then_else (match_operand:SF 1 "" "")
1011 (const_string "SF")
1012 (const_string "DF")))
1013 (set_attr "athlon_decode" "vector")])
1014
1015 (define_insn "*cmpfp_iu"
1016 [(set (reg:CCFPU 17)
1017 (compare:CCFPU (match_operand 0 "register_operand" "f")
1018 (match_operand 1 "register_operand" "f")))]
1019 "TARGET_80387 && TARGET_CMOVE
1020 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && FLOAT_MODE_P (GET_MODE (operands[0]))
1022 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1023 "* return output_fp_compare (insn, operands, 1, 1);"
1024 [(set_attr "type" "fcmp")
1025 (set (attr "mode")
1026 (cond [(match_operand:SF 1 "" "")
1027 (const_string "SF")
1028 (match_operand:DF 1 "" "")
1029 (const_string "DF")
1030 ]
1031 (const_string "XF")))
1032 (set_attr "athlon_decode" "vector")])
1033
1034 (define_insn "*cmpfp_iu_sse"
1035 [(set (reg:CCFPU 17)
1036 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1037 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1038 "TARGET_80387
1039 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1040 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1041 "* return output_fp_compare (insn, operands, 1, 1);"
1042 [(set_attr "type" "fcmp,ssecomi")
1043 (set (attr "mode")
1044 (if_then_else (match_operand:SF 1 "" "")
1045 (const_string "SF")
1046 (const_string "DF")))
1047 (set_attr "athlon_decode" "vector")])
1048
1049 (define_insn "*cmpfp_iu_sse_only"
1050 [(set (reg:CCFPU 17)
1051 (compare:CCFPU (match_operand 0 "register_operand" "x")
1052 (match_operand 1 "nonimmediate_operand" "xm")))]
1053 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1054 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055 "* return output_fp_compare (insn, operands, 1, 1);"
1056 [(set_attr "type" "ssecomi")
1057 (set (attr "mode")
1058 (if_then_else (match_operand:SF 1 "" "")
1059 (const_string "SF")
1060 (const_string "DF")))
1061 (set_attr "athlon_decode" "vector")])
1062 \f
1063 ;; Move instructions.
1064
1065 ;; General case of fullword move.
1066
1067 (define_expand "movsi"
1068 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1069 (match_operand:SI 1 "general_operand" ""))]
1070 ""
1071 "ix86_expand_move (SImode, operands); DONE;")
1072
1073 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1074 ;; general_operand.
1075 ;;
1076 ;; %%% We don't use a post-inc memory reference because x86 is not a
1077 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1078 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1079 ;; targets without our curiosities, and it is just as easy to represent
1080 ;; this differently.
1081
1082 (define_insn "*pushsi2"
1083 [(set (match_operand:SI 0 "push_operand" "=<")
1084 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1085 "!TARGET_64BIT"
1086 "push{l}\t%1"
1087 [(set_attr "type" "push")
1088 (set_attr "mode" "SI")])
1089
1090 ;; For 64BIT abi we always round up to 8 bytes.
1091 (define_insn "*pushsi2_rex64"
1092 [(set (match_operand:SI 0 "push_operand" "=X")
1093 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1094 "TARGET_64BIT"
1095 "push{q}\t%q1"
1096 [(set_attr "type" "push")
1097 (set_attr "mode" "SI")])
1098
1099 (define_insn "*pushsi2_prologue"
1100 [(set (match_operand:SI 0 "push_operand" "=<")
1101 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1102 (clobber (mem:BLK (scratch)))]
1103 "!TARGET_64BIT"
1104 "push{l}\t%1"
1105 [(set_attr "type" "push")
1106 (set_attr "mode" "SI")])
1107
1108 (define_insn "*popsi1_epilogue"
1109 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1110 (mem:SI (reg:SI 7)))
1111 (set (reg:SI 7)
1112 (plus:SI (reg:SI 7) (const_int 4)))
1113 (clobber (mem:BLK (scratch)))]
1114 "!TARGET_64BIT"
1115 "pop{l}\t%0"
1116 [(set_attr "type" "pop")
1117 (set_attr "mode" "SI")])
1118
1119 (define_insn "popsi1"
1120 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1121 (mem:SI (reg:SI 7)))
1122 (set (reg:SI 7)
1123 (plus:SI (reg:SI 7) (const_int 4)))]
1124 "!TARGET_64BIT"
1125 "pop{l}\t%0"
1126 [(set_attr "type" "pop")
1127 (set_attr "mode" "SI")])
1128
1129 (define_insn "*movsi_xor"
1130 [(set (match_operand:SI 0 "register_operand" "=r")
1131 (match_operand:SI 1 "const0_operand" "i"))
1132 (clobber (reg:CC 17))]
1133 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1134 "xor{l}\t{%0, %0|%0, %0}"
1135 [(set_attr "type" "alu1")
1136 (set_attr "mode" "SI")
1137 (set_attr "length_immediate" "0")])
1138
1139 (define_insn "*movsi_or"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (match_operand:SI 1 "immediate_operand" "i"))
1142 (clobber (reg:CC 17))]
1143 "reload_completed
1144 && operands[1] == constm1_rtx
1145 && (TARGET_PENTIUM || optimize_size)"
1146 {
1147 operands[1] = constm1_rtx;
1148 return "or{l}\t{%1, %0|%0, %1}";
1149 }
1150 [(set_attr "type" "alu1")
1151 (set_attr "mode" "SI")
1152 (set_attr "length_immediate" "1")])
1153
1154 (define_insn "*movsi_1"
1155 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1156 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1157 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1158 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1159 {
1160 switch (get_attr_type (insn))
1161 {
1162 case TYPE_SSEMOV:
1163 if (get_attr_mode (insn) == MODE_TI)
1164 return "movdqa\t{%1, %0|%0, %1}";
1165 return "movd\t{%1, %0|%0, %1}";
1166
1167 case TYPE_MMXMOV:
1168 if (get_attr_mode (insn) == MODE_DI)
1169 return "movq\t{%1, %0|%0, %1}";
1170 return "movd\t{%1, %0|%0, %1}";
1171
1172 case TYPE_LEA:
1173 return "lea{l}\t{%1, %0|%0, %1}";
1174
1175 default:
1176 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1177 abort();
1178 return "mov{l}\t{%1, %0|%0, %1}";
1179 }
1180 }
1181 [(set (attr "type")
1182 (cond [(eq_attr "alternative" "2,3,4")
1183 (const_string "mmxmov")
1184 (eq_attr "alternative" "5,6,7")
1185 (const_string "ssemov")
1186 (and (ne (symbol_ref "flag_pic") (const_int 0))
1187 (match_operand:SI 1 "symbolic_operand" ""))
1188 (const_string "lea")
1189 ]
1190 (const_string "imov")))
1191 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1192
1193 (define_insn "*movsi_1_nointernunit"
1194 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1195 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1196 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1197 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1198 {
1199 switch (get_attr_type (insn))
1200 {
1201 case TYPE_SSEMOV:
1202 if (get_attr_mode (insn) == MODE_TI)
1203 return "movdqa\t{%1, %0|%0, %1}";
1204 return "movd\t{%1, %0|%0, %1}";
1205
1206 case TYPE_MMXMOV:
1207 if (get_attr_mode (insn) == MODE_DI)
1208 return "movq\t{%1, %0|%0, %1}";
1209 return "movd\t{%1, %0|%0, %1}";
1210
1211 case TYPE_LEA:
1212 return "lea{l}\t{%1, %0|%0, %1}";
1213
1214 default:
1215 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1216 abort();
1217 return "mov{l}\t{%1, %0|%0, %1}";
1218 }
1219 }
1220 [(set (attr "type")
1221 (cond [(eq_attr "alternative" "2,3,4")
1222 (const_string "mmxmov")
1223 (eq_attr "alternative" "5,6,7")
1224 (const_string "ssemov")
1225 (and (ne (symbol_ref "flag_pic") (const_int 0))
1226 (match_operand:SI 1 "symbolic_operand" ""))
1227 (const_string "lea")
1228 ]
1229 (const_string "imov")))
1230 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1231
1232 ;; Stores and loads of ax to arbitrary constant address.
1233 ;; We fake an second form of instruction to force reload to load address
1234 ;; into register when rax is not available
1235 (define_insn "*movabssi_1_rex64"
1236 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1237 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1238 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1239 "@
1240 movabs{l}\t{%1, %P0|%P0, %1}
1241 mov{l}\t{%1, %a0|%a0, %1}"
1242 [(set_attr "type" "imov")
1243 (set_attr "modrm" "0,*")
1244 (set_attr "length_address" "8,0")
1245 (set_attr "length_immediate" "0,*")
1246 (set_attr "memory" "store")
1247 (set_attr "mode" "SI")])
1248
1249 (define_insn "*movabssi_2_rex64"
1250 [(set (match_operand:SI 0 "register_operand" "=a,r")
1251 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1252 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1253 "@
1254 movabs{l}\t{%P1, %0|%0, %P1}
1255 mov{l}\t{%a1, %0|%0, %a1}"
1256 [(set_attr "type" "imov")
1257 (set_attr "modrm" "0,*")
1258 (set_attr "length_address" "8,0")
1259 (set_attr "length_immediate" "0")
1260 (set_attr "memory" "load")
1261 (set_attr "mode" "SI")])
1262
1263 (define_insn "*swapsi"
1264 [(set (match_operand:SI 0 "register_operand" "+r")
1265 (match_operand:SI 1 "register_operand" "+r"))
1266 (set (match_dup 1)
1267 (match_dup 0))]
1268 ""
1269 "xchg{l}\t%1, %0"
1270 [(set_attr "type" "imov")
1271 (set_attr "pent_pair" "np")
1272 (set_attr "athlon_decode" "vector")
1273 (set_attr "mode" "SI")
1274 (set_attr "modrm" "0")])
1275
1276 (define_expand "movhi"
1277 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1278 (match_operand:HI 1 "general_operand" ""))]
1279 ""
1280 "ix86_expand_move (HImode, operands); DONE;")
1281
1282 (define_insn "*pushhi2"
1283 [(set (match_operand:HI 0 "push_operand" "=<,<")
1284 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1285 "!TARGET_64BIT"
1286 "@
1287 push{w}\t{|WORD PTR }%1
1288 push{w}\t%1"
1289 [(set_attr "type" "push")
1290 (set_attr "mode" "HI")])
1291
1292 ;; For 64BIT abi we always round up to 8 bytes.
1293 (define_insn "*pushhi2_rex64"
1294 [(set (match_operand:HI 0 "push_operand" "=X")
1295 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1296 "TARGET_64BIT"
1297 "push{q}\t%q1"
1298 [(set_attr "type" "push")
1299 (set_attr "mode" "QI")])
1300
1301 (define_insn "*movhi_1"
1302 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1303 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1304 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1305 {
1306 switch (get_attr_type (insn))
1307 {
1308 case TYPE_IMOVX:
1309 /* movzwl is faster than movw on p2 due to partial word stalls,
1310 though not as fast as an aligned movl. */
1311 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1312 default:
1313 if (get_attr_mode (insn) == MODE_SI)
1314 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1315 else
1316 return "mov{w}\t{%1, %0|%0, %1}";
1317 }
1318 }
1319 [(set (attr "type")
1320 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1321 (const_string "imov")
1322 (and (eq_attr "alternative" "0")
1323 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1324 (const_int 0))
1325 (eq (symbol_ref "TARGET_HIMODE_MATH")
1326 (const_int 0))))
1327 (const_string "imov")
1328 (and (eq_attr "alternative" "1,2")
1329 (match_operand:HI 1 "aligned_operand" ""))
1330 (const_string "imov")
1331 (and (ne (symbol_ref "TARGET_MOVX")
1332 (const_int 0))
1333 (eq_attr "alternative" "0,2"))
1334 (const_string "imovx")
1335 ]
1336 (const_string "imov")))
1337 (set (attr "mode")
1338 (cond [(eq_attr "type" "imovx")
1339 (const_string "SI")
1340 (and (eq_attr "alternative" "1,2")
1341 (match_operand:HI 1 "aligned_operand" ""))
1342 (const_string "SI")
1343 (and (eq_attr "alternative" "0")
1344 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1345 (const_int 0))
1346 (eq (symbol_ref "TARGET_HIMODE_MATH")
1347 (const_int 0))))
1348 (const_string "SI")
1349 ]
1350 (const_string "HI")))])
1351
1352 ;; Stores and loads of ax to arbitrary constant address.
1353 ;; We fake an second form of instruction to force reload to load address
1354 ;; into register when rax is not available
1355 (define_insn "*movabshi_1_rex64"
1356 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1357 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1358 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1359 "@
1360 movabs{w}\t{%1, %P0|%P0, %1}
1361 mov{w}\t{%1, %a0|%a0, %1}"
1362 [(set_attr "type" "imov")
1363 (set_attr "modrm" "0,*")
1364 (set_attr "length_address" "8,0")
1365 (set_attr "length_immediate" "0,*")
1366 (set_attr "memory" "store")
1367 (set_attr "mode" "HI")])
1368
1369 (define_insn "*movabshi_2_rex64"
1370 [(set (match_operand:HI 0 "register_operand" "=a,r")
1371 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1372 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1373 "@
1374 movabs{w}\t{%P1, %0|%0, %P1}
1375 mov{w}\t{%a1, %0|%0, %a1}"
1376 [(set_attr "type" "imov")
1377 (set_attr "modrm" "0,*")
1378 (set_attr "length_address" "8,0")
1379 (set_attr "length_immediate" "0")
1380 (set_attr "memory" "load")
1381 (set_attr "mode" "HI")])
1382
1383 (define_insn "*swaphi_1"
1384 [(set (match_operand:HI 0 "register_operand" "+r")
1385 (match_operand:HI 1 "register_operand" "+r"))
1386 (set (match_dup 1)
1387 (match_dup 0))]
1388 "TARGET_PARTIAL_REG_STALL"
1389 "xchg{w}\t%1, %0"
1390 [(set_attr "type" "imov")
1391 (set_attr "pent_pair" "np")
1392 (set_attr "mode" "HI")
1393 (set_attr "modrm" "0")])
1394
1395 (define_insn "*swaphi_2"
1396 [(set (match_operand:HI 0 "register_operand" "+r")
1397 (match_operand:HI 1 "register_operand" "+r"))
1398 (set (match_dup 1)
1399 (match_dup 0))]
1400 "! TARGET_PARTIAL_REG_STALL"
1401 "xchg{l}\t%k1, %k0"
1402 [(set_attr "type" "imov")
1403 (set_attr "pent_pair" "np")
1404 (set_attr "mode" "SI")
1405 (set_attr "modrm" "0")])
1406
1407 (define_expand "movstricthi"
1408 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1409 (match_operand:HI 1 "general_operand" ""))]
1410 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1411 {
1412 /* Don't generate memory->memory moves, go through a register */
1413 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1414 operands[1] = force_reg (HImode, operands[1]);
1415 })
1416
1417 (define_insn "*movstricthi_1"
1418 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1419 (match_operand:HI 1 "general_operand" "rn,m"))]
1420 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1421 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1422 "mov{w}\t{%1, %0|%0, %1}"
1423 [(set_attr "type" "imov")
1424 (set_attr "mode" "HI")])
1425
1426 (define_insn "*movstricthi_xor"
1427 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1428 (match_operand:HI 1 "const0_operand" "i"))
1429 (clobber (reg:CC 17))]
1430 "reload_completed
1431 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1432 "xor{w}\t{%0, %0|%0, %0}"
1433 [(set_attr "type" "alu1")
1434 (set_attr "mode" "HI")
1435 (set_attr "length_immediate" "0")])
1436
1437 (define_expand "movqi"
1438 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1439 (match_operand:QI 1 "general_operand" ""))]
1440 ""
1441 "ix86_expand_move (QImode, operands); DONE;")
1442
1443 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1444 ;; "push a byte". But actually we use pushw, which has the effect
1445 ;; of rounding the amount pushed up to a halfword.
1446
1447 (define_insn "*pushqi2"
1448 [(set (match_operand:QI 0 "push_operand" "=X,X")
1449 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1450 "!TARGET_64BIT"
1451 "@
1452 push{w}\t{|word ptr }%1
1453 push{w}\t%w1"
1454 [(set_attr "type" "push")
1455 (set_attr "mode" "HI")])
1456
1457 ;; For 64BIT abi we always round up to 8 bytes.
1458 (define_insn "*pushqi2_rex64"
1459 [(set (match_operand:QI 0 "push_operand" "=X")
1460 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1461 "TARGET_64BIT"
1462 "push{q}\t%q1"
1463 [(set_attr "type" "push")
1464 (set_attr "mode" "QI")])
1465
1466 ;; Situation is quite tricky about when to choose full sized (SImode) move
1467 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1468 ;; partial register dependency machines (such as AMD Athlon), where QImode
1469 ;; moves issue extra dependency and for partial register stalls machines
1470 ;; that don't use QImode patterns (and QImode move cause stall on the next
1471 ;; instruction).
1472 ;;
1473 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1474 ;; register stall machines with, where we use QImode instructions, since
1475 ;; partial register stall can be caused there. Then we use movzx.
1476 (define_insn "*movqi_1"
1477 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1478 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1479 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1480 {
1481 switch (get_attr_type (insn))
1482 {
1483 case TYPE_IMOVX:
1484 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1485 abort ();
1486 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1487 default:
1488 if (get_attr_mode (insn) == MODE_SI)
1489 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1490 else
1491 return "mov{b}\t{%1, %0|%0, %1}";
1492 }
1493 }
1494 [(set (attr "type")
1495 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1496 (const_string "imov")
1497 (and (eq_attr "alternative" "3")
1498 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1499 (const_int 0))
1500 (eq (symbol_ref "TARGET_QIMODE_MATH")
1501 (const_int 0))))
1502 (const_string "imov")
1503 (eq_attr "alternative" "3,5")
1504 (const_string "imovx")
1505 (and (ne (symbol_ref "TARGET_MOVX")
1506 (const_int 0))
1507 (eq_attr "alternative" "2"))
1508 (const_string "imovx")
1509 ]
1510 (const_string "imov")))
1511 (set (attr "mode")
1512 (cond [(eq_attr "alternative" "3,4,5")
1513 (const_string "SI")
1514 (eq_attr "alternative" "6")
1515 (const_string "QI")
1516 (eq_attr "type" "imovx")
1517 (const_string "SI")
1518 (and (eq_attr "type" "imov")
1519 (and (eq_attr "alternative" "0,1,2")
1520 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1521 (const_int 0))))
1522 (const_string "SI")
1523 ;; Avoid partial register stalls when not using QImode arithmetic
1524 (and (eq_attr "type" "imov")
1525 (and (eq_attr "alternative" "0,1,2")
1526 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527 (const_int 0))
1528 (eq (symbol_ref "TARGET_QIMODE_MATH")
1529 (const_int 0)))))
1530 (const_string "SI")
1531 ]
1532 (const_string "QI")))])
1533
1534 (define_expand "reload_outqi"
1535 [(parallel [(match_operand:QI 0 "" "=m")
1536 (match_operand:QI 1 "register_operand" "r")
1537 (match_operand:QI 2 "register_operand" "=&q")])]
1538 ""
1539 {
1540 rtx op0, op1, op2;
1541 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1542
1543 if (reg_overlap_mentioned_p (op2, op0))
1544 abort ();
1545 if (! q_regs_operand (op1, QImode))
1546 {
1547 emit_insn (gen_movqi (op2, op1));
1548 op1 = op2;
1549 }
1550 emit_insn (gen_movqi (op0, op1));
1551 DONE;
1552 })
1553
1554 (define_insn "*swapqi"
1555 [(set (match_operand:QI 0 "register_operand" "+r")
1556 (match_operand:QI 1 "register_operand" "+r"))
1557 (set (match_dup 1)
1558 (match_dup 0))]
1559 ""
1560 "xchg{b}\t%1, %0"
1561 [(set_attr "type" "imov")
1562 (set_attr "pent_pair" "np")
1563 (set_attr "mode" "QI")
1564 (set_attr "modrm" "0")])
1565
1566 (define_expand "movstrictqi"
1567 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1568 (match_operand:QI 1 "general_operand" ""))]
1569 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1570 {
1571 /* Don't generate memory->memory moves, go through a register. */
1572 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1573 operands[1] = force_reg (QImode, operands[1]);
1574 })
1575
1576 (define_insn "*movstrictqi_1"
1577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1578 (match_operand:QI 1 "general_operand" "*qn,m"))]
1579 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1580 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1581 "mov{b}\t{%1, %0|%0, %1}"
1582 [(set_attr "type" "imov")
1583 (set_attr "mode" "QI")])
1584
1585 (define_insn "*movstrictqi_xor"
1586 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1587 (match_operand:QI 1 "const0_operand" "i"))
1588 (clobber (reg:CC 17))]
1589 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1590 "xor{b}\t{%0, %0|%0, %0}"
1591 [(set_attr "type" "alu1")
1592 (set_attr "mode" "QI")
1593 (set_attr "length_immediate" "0")])
1594
1595 (define_insn "*movsi_extv_1"
1596 [(set (match_operand:SI 0 "register_operand" "=R")
1597 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1598 (const_int 8)
1599 (const_int 8)))]
1600 ""
1601 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1602 [(set_attr "type" "imovx")
1603 (set_attr "mode" "SI")])
1604
1605 (define_insn "*movhi_extv_1"
1606 [(set (match_operand:HI 0 "register_operand" "=R")
1607 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1608 (const_int 8)
1609 (const_int 8)))]
1610 ""
1611 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1612 [(set_attr "type" "imovx")
1613 (set_attr "mode" "SI")])
1614
1615 (define_insn "*movqi_extv_1"
1616 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1617 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1618 (const_int 8)
1619 (const_int 8)))]
1620 "!TARGET_64BIT"
1621 {
1622 switch (get_attr_type (insn))
1623 {
1624 case TYPE_IMOVX:
1625 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1626 default:
1627 return "mov{b}\t{%h1, %0|%0, %h1}";
1628 }
1629 }
1630 [(set (attr "type")
1631 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1632 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1633 (ne (symbol_ref "TARGET_MOVX")
1634 (const_int 0))))
1635 (const_string "imovx")
1636 (const_string "imov")))
1637 (set (attr "mode")
1638 (if_then_else (eq_attr "type" "imovx")
1639 (const_string "SI")
1640 (const_string "QI")))])
1641
1642 (define_insn "*movqi_extv_1_rex64"
1643 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1644 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1645 (const_int 8)
1646 (const_int 8)))]
1647 "TARGET_64BIT"
1648 {
1649 switch (get_attr_type (insn))
1650 {
1651 case TYPE_IMOVX:
1652 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1653 default:
1654 return "mov{b}\t{%h1, %0|%0, %h1}";
1655 }
1656 }
1657 [(set (attr "type")
1658 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1659 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1660 (ne (symbol_ref "TARGET_MOVX")
1661 (const_int 0))))
1662 (const_string "imovx")
1663 (const_string "imov")))
1664 (set (attr "mode")
1665 (if_then_else (eq_attr "type" "imovx")
1666 (const_string "SI")
1667 (const_string "QI")))])
1668
1669 ;; Stores and loads of ax to arbitrary constant address.
1670 ;; We fake an second form of instruction to force reload to load address
1671 ;; into register when rax is not available
1672 (define_insn "*movabsqi_1_rex64"
1673 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1674 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1675 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1676 "@
1677 movabs{b}\t{%1, %P0|%P0, %1}
1678 mov{b}\t{%1, %a0|%a0, %1}"
1679 [(set_attr "type" "imov")
1680 (set_attr "modrm" "0,*")
1681 (set_attr "length_address" "8,0")
1682 (set_attr "length_immediate" "0,*")
1683 (set_attr "memory" "store")
1684 (set_attr "mode" "QI")])
1685
1686 (define_insn "*movabsqi_2_rex64"
1687 [(set (match_operand:QI 0 "register_operand" "=a,r")
1688 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1689 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1690 "@
1691 movabs{b}\t{%P1, %0|%0, %P1}
1692 mov{b}\t{%a1, %0|%0, %a1}"
1693 [(set_attr "type" "imov")
1694 (set_attr "modrm" "0,*")
1695 (set_attr "length_address" "8,0")
1696 (set_attr "length_immediate" "0")
1697 (set_attr "memory" "load")
1698 (set_attr "mode" "QI")])
1699
1700 (define_insn "*movsi_extzv_1"
1701 [(set (match_operand:SI 0 "register_operand" "=R")
1702 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1703 (const_int 8)
1704 (const_int 8)))]
1705 ""
1706 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1707 [(set_attr "type" "imovx")
1708 (set_attr "mode" "SI")])
1709
1710 (define_insn "*movqi_extzv_2"
1711 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1712 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1713 (const_int 8)
1714 (const_int 8)) 0))]
1715 "!TARGET_64BIT"
1716 {
1717 switch (get_attr_type (insn))
1718 {
1719 case TYPE_IMOVX:
1720 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1721 default:
1722 return "mov{b}\t{%h1, %0|%0, %h1}";
1723 }
1724 }
1725 [(set (attr "type")
1726 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1727 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1728 (ne (symbol_ref "TARGET_MOVX")
1729 (const_int 0))))
1730 (const_string "imovx")
1731 (const_string "imov")))
1732 (set (attr "mode")
1733 (if_then_else (eq_attr "type" "imovx")
1734 (const_string "SI")
1735 (const_string "QI")))])
1736
1737 (define_insn "*movqi_extzv_2_rex64"
1738 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1739 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1740 (const_int 8)
1741 (const_int 8)) 0))]
1742 "TARGET_64BIT"
1743 {
1744 switch (get_attr_type (insn))
1745 {
1746 case TYPE_IMOVX:
1747 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1748 default:
1749 return "mov{b}\t{%h1, %0|%0, %h1}";
1750 }
1751 }
1752 [(set (attr "type")
1753 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1754 (ne (symbol_ref "TARGET_MOVX")
1755 (const_int 0)))
1756 (const_string "imovx")
1757 (const_string "imov")))
1758 (set (attr "mode")
1759 (if_then_else (eq_attr "type" "imovx")
1760 (const_string "SI")
1761 (const_string "QI")))])
1762
1763 (define_insn "movsi_insv_1"
1764 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1765 (const_int 8)
1766 (const_int 8))
1767 (match_operand:SI 1 "general_operand" "Qmn"))]
1768 "!TARGET_64BIT"
1769 "mov{b}\t{%b1, %h0|%h0, %b1}"
1770 [(set_attr "type" "imov")
1771 (set_attr "mode" "QI")])
1772
1773 (define_insn "*movsi_insv_1_rex64"
1774 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1775 (const_int 8)
1776 (const_int 8))
1777 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1778 "TARGET_64BIT"
1779 "mov{b}\t{%b1, %h0|%h0, %b1}"
1780 [(set_attr "type" "imov")
1781 (set_attr "mode" "QI")])
1782
1783 (define_insn "*movqi_insv_2"
1784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1785 (const_int 8)
1786 (const_int 8))
1787 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1788 (const_int 8)))]
1789 ""
1790 "mov{b}\t{%h1, %h0|%h0, %h1}"
1791 [(set_attr "type" "imov")
1792 (set_attr "mode" "QI")])
1793
1794 (define_expand "movdi"
1795 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1796 (match_operand:DI 1 "general_operand" ""))]
1797 ""
1798 "ix86_expand_move (DImode, operands); DONE;")
1799
1800 (define_insn "*pushdi"
1801 [(set (match_operand:DI 0 "push_operand" "=<")
1802 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1803 "!TARGET_64BIT"
1804 "#")
1805
1806 (define_insn "pushdi2_rex64"
1807 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1808 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1809 "TARGET_64BIT"
1810 "@
1811 push{q}\t%1
1812 #"
1813 [(set_attr "type" "push,multi")
1814 (set_attr "mode" "DI")])
1815
1816 ;; Convert impossible pushes of immediate to existing instructions.
1817 ;; First try to get scratch register and go through it. In case this
1818 ;; fails, push sign extended lower part first and then overwrite
1819 ;; upper part by 32bit move.
1820 (define_peephole2
1821 [(match_scratch:DI 2 "r")
1822 (set (match_operand:DI 0 "push_operand" "")
1823 (match_operand:DI 1 "immediate_operand" ""))]
1824 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1825 && !x86_64_immediate_operand (operands[1], DImode)"
1826 [(set (match_dup 2) (match_dup 1))
1827 (set (match_dup 0) (match_dup 2))]
1828 "")
1829
1830 ;; We need to define this as both peepholer and splitter for case
1831 ;; peephole2 pass is not run.
1832 (define_peephole2
1833 [(set (match_operand:DI 0 "push_operand" "")
1834 (match_operand:DI 1 "immediate_operand" ""))]
1835 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1836 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1837 [(set (match_dup 0) (match_dup 1))
1838 (set (match_dup 2) (match_dup 3))]
1839 "split_di (operands + 1, 1, operands + 2, operands + 3);
1840 operands[1] = gen_lowpart (DImode, operands[2]);
1841 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842 GEN_INT (4)));
1843 ")
1844
1845 (define_split
1846 [(set (match_operand:DI 0 "push_operand" "")
1847 (match_operand:DI 1 "immediate_operand" ""))]
1848 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1849 && !symbolic_operand (operands[1], DImode)
1850 && !x86_64_immediate_operand (operands[1], DImode)"
1851 [(set (match_dup 0) (match_dup 1))
1852 (set (match_dup 2) (match_dup 3))]
1853 "split_di (operands + 1, 1, operands + 2, operands + 3);
1854 operands[1] = gen_lowpart (DImode, operands[2]);
1855 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1856 GEN_INT (4)));
1857 ")
1858
1859 (define_insn "*pushdi2_prologue_rex64"
1860 [(set (match_operand:DI 0 "push_operand" "=<")
1861 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1862 (clobber (mem:BLK (scratch)))]
1863 "TARGET_64BIT"
1864 "push{q}\t%1"
1865 [(set_attr "type" "push")
1866 (set_attr "mode" "DI")])
1867
1868 (define_insn "*popdi1_epilogue_rex64"
1869 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1870 (mem:DI (reg:DI 7)))
1871 (set (reg:DI 7)
1872 (plus:DI (reg:DI 7) (const_int 8)))
1873 (clobber (mem:BLK (scratch)))]
1874 "TARGET_64BIT"
1875 "pop{q}\t%0"
1876 [(set_attr "type" "pop")
1877 (set_attr "mode" "DI")])
1878
1879 (define_insn "popdi1"
1880 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1881 (mem:DI (reg:DI 7)))
1882 (set (reg:DI 7)
1883 (plus:DI (reg:DI 7) (const_int 8)))]
1884 "TARGET_64BIT"
1885 "pop{q}\t%0"
1886 [(set_attr "type" "pop")
1887 (set_attr "mode" "DI")])
1888
1889 (define_insn "*movdi_xor_rex64"
1890 [(set (match_operand:DI 0 "register_operand" "=r")
1891 (match_operand:DI 1 "const0_operand" "i"))
1892 (clobber (reg:CC 17))]
1893 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1894 && reload_completed"
1895 "xor{l}\t{%k0, %k0|%k0, %k0}"
1896 [(set_attr "type" "alu1")
1897 (set_attr "mode" "SI")
1898 (set_attr "length_immediate" "0")])
1899
1900 (define_insn "*movdi_or_rex64"
1901 [(set (match_operand:DI 0 "register_operand" "=r")
1902 (match_operand:DI 1 "const_int_operand" "i"))
1903 (clobber (reg:CC 17))]
1904 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1905 && reload_completed
1906 && operands[1] == constm1_rtx"
1907 {
1908 operands[1] = constm1_rtx;
1909 return "or{q}\t{%1, %0|%0, %1}";
1910 }
1911 [(set_attr "type" "alu1")
1912 (set_attr "mode" "DI")
1913 (set_attr "length_immediate" "1")])
1914
1915 (define_insn "*movdi_2"
1916 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1917 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1918 "!TARGET_64BIT
1919 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1920 "@
1921 #
1922 #
1923 movq\t{%1, %0|%0, %1}
1924 movq\t{%1, %0|%0, %1}
1925 movq\t{%1, %0|%0, %1}
1926 movdqa\t{%1, %0|%0, %1}
1927 movq\t{%1, %0|%0, %1}"
1928 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1929 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1930
1931 (define_split
1932 [(set (match_operand:DI 0 "push_operand" "")
1933 (match_operand:DI 1 "general_operand" ""))]
1934 "!TARGET_64BIT && reload_completed
1935 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1936 [(const_int 0)]
1937 "ix86_split_long_move (operands); DONE;")
1938
1939 ;; %%% This multiword shite has got to go.
1940 (define_split
1941 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1942 (match_operand:DI 1 "general_operand" ""))]
1943 "!TARGET_64BIT && reload_completed
1944 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1945 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1946 [(const_int 0)]
1947 "ix86_split_long_move (operands); DONE;")
1948
1949 (define_insn "*movdi_1_rex64"
1950 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1951 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1952 "TARGET_64BIT
1953 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1954 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1955 {
1956 switch (get_attr_type (insn))
1957 {
1958 case TYPE_SSEMOV:
1959 if (get_attr_mode (insn) == MODE_TI)
1960 return "movdqa\t{%1, %0|%0, %1}";
1961 /* FALLTHRU */
1962 case TYPE_MMXMOV:
1963 /* Moves from and into integer register is done using movd opcode with
1964 REX prefix. */
1965 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1966 return "movd\t{%1, %0|%0, %1}";
1967 return "movq\t{%1, %0|%0, %1}";
1968 case TYPE_MULTI:
1969 return "#";
1970 case TYPE_LEA:
1971 return "lea{q}\t{%a1, %0|%0, %a1}";
1972 default:
1973 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1974 abort ();
1975 if (get_attr_mode (insn) == MODE_SI)
1976 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1977 else if (which_alternative == 2)
1978 return "movabs{q}\t{%1, %0|%0, %1}";
1979 else
1980 return "mov{q}\t{%1, %0|%0, %1}";
1981 }
1982 }
1983 [(set (attr "type")
1984 (cond [(eq_attr "alternative" "5,6,7")
1985 (const_string "mmxmov")
1986 (eq_attr "alternative" "8,9,10")
1987 (const_string "ssemov")
1988 (eq_attr "alternative" "4")
1989 (const_string "multi")
1990 (and (ne (symbol_ref "flag_pic") (const_int 0))
1991 (match_operand:DI 1 "symbolic_operand" ""))
1992 (const_string "lea")
1993 ]
1994 (const_string "imov")))
1995 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
1996 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
1997 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
1998
1999 (define_insn "*movdi_1_rex64_nointerunit"
2000 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2001 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2002 "TARGET_64BIT
2003 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2004 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2005 {
2006 switch (get_attr_type (insn))
2007 {
2008 case TYPE_SSEMOV:
2009 if (get_attr_mode (insn) == MODE_TI)
2010 return "movdqa\t{%1, %0|%0, %1}";
2011 /* FALLTHRU */
2012 case TYPE_MMXMOV:
2013 return "movq\t{%1, %0|%0, %1}";
2014 case TYPE_MULTI:
2015 return "#";
2016 case TYPE_LEA:
2017 return "lea{q}\t{%a1, %0|%0, %a1}";
2018 default:
2019 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2020 abort ();
2021 if (get_attr_mode (insn) == MODE_SI)
2022 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2023 else if (which_alternative == 2)
2024 return "movabs{q}\t{%1, %0|%0, %1}";
2025 else
2026 return "mov{q}\t{%1, %0|%0, %1}";
2027 }
2028 }
2029 [(set (attr "type")
2030 (cond [(eq_attr "alternative" "5,6,7")
2031 (const_string "mmxmov")
2032 (eq_attr "alternative" "8,9,10")
2033 (const_string "ssemov")
2034 (eq_attr "alternative" "4")
2035 (const_string "multi")
2036 (and (ne (symbol_ref "flag_pic") (const_int 0))
2037 (match_operand:DI 1 "symbolic_operand" ""))
2038 (const_string "lea")
2039 ]
2040 (const_string "imov")))
2041 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2042 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2043 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2044
2045 ;; Stores and loads of ax to arbitrary constant address.
2046 ;; We fake an second form of instruction to force reload to load address
2047 ;; into register when rax is not available
2048 (define_insn "*movabsdi_1_rex64"
2049 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2050 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2051 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2052 "@
2053 movabs{q}\t{%1, %P0|%P0, %1}
2054 mov{q}\t{%1, %a0|%a0, %1}"
2055 [(set_attr "type" "imov")
2056 (set_attr "modrm" "0,*")
2057 (set_attr "length_address" "8,0")
2058 (set_attr "length_immediate" "0,*")
2059 (set_attr "memory" "store")
2060 (set_attr "mode" "DI")])
2061
2062 (define_insn "*movabsdi_2_rex64"
2063 [(set (match_operand:DI 0 "register_operand" "=a,r")
2064 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2065 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2066 "@
2067 movabs{q}\t{%P1, %0|%0, %P1}
2068 mov{q}\t{%a1, %0|%0, %a1}"
2069 [(set_attr "type" "imov")
2070 (set_attr "modrm" "0,*")
2071 (set_attr "length_address" "8,0")
2072 (set_attr "length_immediate" "0")
2073 (set_attr "memory" "load")
2074 (set_attr "mode" "DI")])
2075
2076 ;; Convert impossible stores of immediate to existing instructions.
2077 ;; First try to get scratch register and go through it. In case this
2078 ;; fails, move by 32bit parts.
2079 (define_peephole2
2080 [(match_scratch:DI 2 "r")
2081 (set (match_operand:DI 0 "memory_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode)"
2085 [(set (match_dup 2) (match_dup 1))
2086 (set (match_dup 0) (match_dup 2))]
2087 "")
2088
2089 ;; We need to define this as both peepholer and splitter for case
2090 ;; peephole2 pass is not run.
2091 (define_peephole2
2092 [(set (match_operand:DI 0 "memory_operand" "")
2093 (match_operand:DI 1 "immediate_operand" ""))]
2094 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2095 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2096 [(set (match_dup 2) (match_dup 3))
2097 (set (match_dup 4) (match_dup 5))]
2098 "split_di (operands, 2, operands + 2, operands + 4);")
2099
2100 (define_split
2101 [(set (match_operand:DI 0 "memory_operand" "")
2102 (match_operand:DI 1 "immediate_operand" ""))]
2103 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2104 && !symbolic_operand (operands[1], DImode)
2105 && !x86_64_immediate_operand (operands[1], DImode)"
2106 [(set (match_dup 2) (match_dup 3))
2107 (set (match_dup 4) (match_dup 5))]
2108 "split_di (operands, 2, operands + 2, operands + 4);")
2109
2110 (define_insn "*swapdi_rex64"
2111 [(set (match_operand:DI 0 "register_operand" "+r")
2112 (match_operand:DI 1 "register_operand" "+r"))
2113 (set (match_dup 1)
2114 (match_dup 0))]
2115 "TARGET_64BIT"
2116 "xchg{q}\t%1, %0"
2117 [(set_attr "type" "imov")
2118 (set_attr "pent_pair" "np")
2119 (set_attr "athlon_decode" "vector")
2120 (set_attr "mode" "DI")
2121 (set_attr "modrm" "0")])
2122
2123
2124 (define_expand "movsf"
2125 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2126 (match_operand:SF 1 "general_operand" ""))]
2127 ""
2128 "ix86_expand_move (SFmode, operands); DONE;")
2129
2130 (define_insn "*pushsf"
2131 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2132 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2133 "!TARGET_64BIT"
2134 {
2135 switch (which_alternative)
2136 {
2137 case 1:
2138 return "push{l}\t%1";
2139
2140 default:
2141 /* This insn should be already split before reg-stack. */
2142 abort ();
2143 }
2144 }
2145 [(set_attr "type" "multi,push,multi")
2146 (set_attr "mode" "SF,SI,SF")])
2147
2148 (define_insn "*pushsf_rex64"
2149 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2150 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2151 "TARGET_64BIT"
2152 {
2153 switch (which_alternative)
2154 {
2155 case 1:
2156 return "push{q}\t%q1";
2157
2158 default:
2159 /* This insn should be already split before reg-stack. */
2160 abort ();
2161 }
2162 }
2163 [(set_attr "type" "multi,push,multi")
2164 (set_attr "mode" "SF,DI,SF")])
2165
2166 (define_split
2167 [(set (match_operand:SF 0 "push_operand" "")
2168 (match_operand:SF 1 "memory_operand" ""))]
2169 "reload_completed
2170 && GET_CODE (operands[1]) == MEM
2171 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2172 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2173 [(set (match_dup 0)
2174 (match_dup 1))]
2175 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2176
2177
2178 ;; %%% Kill this when call knows how to work this out.
2179 (define_split
2180 [(set (match_operand:SF 0 "push_operand" "")
2181 (match_operand:SF 1 "any_fp_register_operand" ""))]
2182 "!TARGET_64BIT"
2183 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2184 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2185
2186 (define_split
2187 [(set (match_operand:SF 0 "push_operand" "")
2188 (match_operand:SF 1 "any_fp_register_operand" ""))]
2189 "TARGET_64BIT"
2190 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2191 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2192
2193 (define_insn "*movsf_1"
2194 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2195 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2196 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2197 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2198 && (reload_in_progress || reload_completed
2199 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2200 || GET_CODE (operands[1]) != CONST_DOUBLE
2201 || memory_operand (operands[0], SFmode))"
2202 {
2203 switch (which_alternative)
2204 {
2205 case 0:
2206 return output_387_reg_move (insn, operands);
2207
2208 case 1:
2209 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2210 return "fstp%z0\t%y0";
2211 else
2212 return "fst%z0\t%y0";
2213
2214 case 2:
2215 return standard_80387_constant_opcode (operands[1]);
2216
2217 case 3:
2218 case 4:
2219 return "mov{l}\t{%1, %0|%0, %1}";
2220 case 5:
2221 if (get_attr_mode (insn) == MODE_TI)
2222 return "pxor\t%0, %0";
2223 else
2224 return "xorps\t%0, %0";
2225 case 6:
2226 if (get_attr_mode (insn) == MODE_V4SF)
2227 return "movaps\t{%1, %0|%0, %1}";
2228 else
2229 return "movss\t{%1, %0|%0, %1}";
2230 case 7:
2231 case 8:
2232 return "movss\t{%1, %0|%0, %1}";
2233
2234 case 9:
2235 case 10:
2236 return "movd\t{%1, %0|%0, %1}";
2237
2238 case 11:
2239 return "movq\t{%1, %0|%0, %1}";
2240
2241 default:
2242 abort();
2243 }
2244 }
2245 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2246 (set (attr "mode")
2247 (cond [(eq_attr "alternative" "3,4,9,10")
2248 (const_string "SI")
2249 (eq_attr "alternative" "5")
2250 (if_then_else
2251 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2252 (const_int 0))
2253 (ne (symbol_ref "TARGET_SSE2")
2254 (const_int 0)))
2255 (eq (symbol_ref "optimize_size")
2256 (const_int 0)))
2257 (const_string "TI")
2258 (const_string "V4SF"))
2259 /* For architectures resolving dependencies on
2260 whole SSE registers use APS move to break dependency
2261 chains, otherwise use short move to avoid extra work.
2262
2263 Do the same for architectures resolving dependencies on
2264 the parts. While in DF mode it is better to always handle
2265 just register parts, the SF mode is different due to lack
2266 of instructions to load just part of the register. It is
2267 better to maintain the whole registers in single format
2268 to avoid problems on using packed logical operations. */
2269 (eq_attr "alternative" "6")
2270 (if_then_else
2271 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2272 (const_int 0))
2273 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2274 (const_int 0)))
2275 (const_string "V4SF")
2276 (const_string "SF"))
2277 (eq_attr "alternative" "11")
2278 (const_string "DI")]
2279 (const_string "SF")))])
2280
2281 (define_insn "*movsf_1_nointerunit"
2282 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2283 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2284 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2285 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2286 && (reload_in_progress || reload_completed
2287 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288 || GET_CODE (operands[1]) != CONST_DOUBLE
2289 || memory_operand (operands[0], SFmode))"
2290 {
2291 switch (which_alternative)
2292 {
2293 case 0:
2294 return output_387_reg_move (insn, operands);
2295
2296 case 1:
2297 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298 return "fstp%z0\t%y0";
2299 else
2300 return "fst%z0\t%y0";
2301
2302 case 2:
2303 return standard_80387_constant_opcode (operands[1]);
2304
2305 case 3:
2306 case 4:
2307 return "mov{l}\t{%1, %0|%0, %1}";
2308 case 5:
2309 if (get_attr_mode (insn) == MODE_TI)
2310 return "pxor\t%0, %0";
2311 else
2312 return "xorps\t%0, %0";
2313 case 6:
2314 if (get_attr_mode (insn) == MODE_V4SF)
2315 return "movaps\t{%1, %0|%0, %1}";
2316 else
2317 return "movss\t{%1, %0|%0, %1}";
2318 case 7:
2319 case 8:
2320 return "movss\t{%1, %0|%0, %1}";
2321
2322 case 9:
2323 case 10:
2324 return "movd\t{%1, %0|%0, %1}";
2325
2326 case 11:
2327 return "movq\t{%1, %0|%0, %1}";
2328
2329 default:
2330 abort();
2331 }
2332 }
2333 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334 (set (attr "mode")
2335 (cond [(eq_attr "alternative" "3,4,9,10")
2336 (const_string "SI")
2337 (eq_attr "alternative" "5")
2338 (if_then_else
2339 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340 (const_int 0))
2341 (ne (symbol_ref "TARGET_SSE2")
2342 (const_int 0)))
2343 (eq (symbol_ref "optimize_size")
2344 (const_int 0)))
2345 (const_string "TI")
2346 (const_string "V4SF"))
2347 /* For architectures resolving dependencies on
2348 whole SSE registers use APS move to break dependency
2349 chains, otherwise use short move to avoid extra work.
2350
2351 Do the same for architectures resolving dependencies on
2352 the parts. While in DF mode it is better to always handle
2353 just register parts, the SF mode is different due to lack
2354 of instructions to load just part of the register. It is
2355 better to maintain the whole registers in single format
2356 to avoid problems on using packed logical operations. */
2357 (eq_attr "alternative" "6")
2358 (if_then_else
2359 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360 (const_int 0))
2361 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2362 (const_int 0)))
2363 (const_string "V4SF")
2364 (const_string "SF"))
2365 (eq_attr "alternative" "11")
2366 (const_string "DI")]
2367 (const_string "SF")))])
2368
2369 (define_insn "*swapsf"
2370 [(set (match_operand:SF 0 "register_operand" "+f")
2371 (match_operand:SF 1 "register_operand" "+f"))
2372 (set (match_dup 1)
2373 (match_dup 0))]
2374 "reload_completed || !TARGET_SSE"
2375 {
2376 if (STACK_TOP_P (operands[0]))
2377 return "fxch\t%1";
2378 else
2379 return "fxch\t%0";
2380 }
2381 [(set_attr "type" "fxch")
2382 (set_attr "mode" "SF")])
2383
2384 (define_expand "movdf"
2385 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386 (match_operand:DF 1 "general_operand" ""))]
2387 ""
2388 "ix86_expand_move (DFmode, operands); DONE;")
2389
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter. Allow this
2393 ;; pattern for optimize_size too.
2394
2395 (define_insn "*pushdf_nointeger"
2396 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2398 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2399 {
2400 /* This insn should be already split before reg-stack. */
2401 abort ();
2402 }
2403 [(set_attr "type" "multi")
2404 (set_attr "mode" "DF,SI,SI,DF")])
2405
2406 (define_insn "*pushdf_integer"
2407 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2408 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2409 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2410 {
2411 /* This insn should be already split before reg-stack. */
2412 abort ();
2413 }
2414 [(set_attr "type" "multi")
2415 (set_attr "mode" "DF,SI,DF")])
2416
2417 ;; %%% Kill this when call knows how to work this out.
2418 (define_split
2419 [(set (match_operand:DF 0 "push_operand" "")
2420 (match_operand:DF 1 "any_fp_register_operand" ""))]
2421 "!TARGET_64BIT && reload_completed"
2422 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2423 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2424 "")
2425
2426 (define_split
2427 [(set (match_operand:DF 0 "push_operand" "")
2428 (match_operand:DF 1 "any_fp_register_operand" ""))]
2429 "TARGET_64BIT && reload_completed"
2430 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2431 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2432 "")
2433
2434 (define_split
2435 [(set (match_operand:DF 0 "push_operand" "")
2436 (match_operand:DF 1 "general_operand" ""))]
2437 "reload_completed"
2438 [(const_int 0)]
2439 "ix86_split_long_move (operands); DONE;")
2440
2441 ;; Moving is usually shorter when only FP registers are used. This separate
2442 ;; movdf pattern avoids the use of integer registers for FP operations
2443 ;; when optimizing for size.
2444
2445 (define_insn "*movdf_nointeger"
2446 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2447 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2448 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2449 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2450 && (reload_in_progress || reload_completed
2451 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2452 || GET_CODE (operands[1]) != CONST_DOUBLE
2453 || memory_operand (operands[0], DFmode))"
2454 {
2455 switch (which_alternative)
2456 {
2457 case 0:
2458 return output_387_reg_move (insn, operands);
2459
2460 case 1:
2461 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2462 return "fstp%z0\t%y0";
2463 else
2464 return "fst%z0\t%y0";
2465
2466 case 2:
2467 return standard_80387_constant_opcode (operands[1]);
2468
2469 case 3:
2470 case 4:
2471 return "#";
2472 case 5:
2473 switch (get_attr_mode (insn))
2474 {
2475 case MODE_V4SF:
2476 return "xorps\t%0, %0";
2477 case MODE_V2DF:
2478 return "xorpd\t%0, %0";
2479 case MODE_TI:
2480 return "pxor\t%0, %0";
2481 default:
2482 abort ();
2483 }
2484 case 6:
2485 switch (get_attr_mode (insn))
2486 {
2487 case MODE_V4SF:
2488 return "movaps\t{%1, %0|%0, %1}";
2489 case MODE_V2DF:
2490 return "movapd\t{%1, %0|%0, %1}";
2491 case MODE_DF:
2492 return "movsd\t{%1, %0|%0, %1}";
2493 default:
2494 abort ();
2495 }
2496 case 7:
2497 if (get_attr_mode (insn) == MODE_V2DF)
2498 return "movlpd\t{%1, %0|%0, %1}";
2499 else
2500 return "movsd\t{%1, %0|%0, %1}";
2501 case 8:
2502 return "movsd\t{%1, %0|%0, %1}";
2503
2504 default:
2505 abort();
2506 }
2507 }
2508 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2509 (set (attr "mode")
2510 (cond [(eq_attr "alternative" "3,4")
2511 (const_string "SI")
2512 /* xorps is one byte shorter. */
2513 (eq_attr "alternative" "5")
2514 (cond [(ne (symbol_ref "optimize_size")
2515 (const_int 0))
2516 (const_string "V4SF")
2517 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2518 (const_int 0))
2519 (const_string "TI")]
2520 (const_string "V2DF"))
2521 /* For architectures resolving dependencies on
2522 whole SSE registers use APD move to break dependency
2523 chains, otherwise use short move to avoid extra work.
2524
2525 movaps encodes one byte shorter. */
2526 (eq_attr "alternative" "6")
2527 (cond
2528 [(ne (symbol_ref "optimize_size")
2529 (const_int 0))
2530 (const_string "V4SF")
2531 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2532 (const_int 0))
2533 (const_string "V2DF")]
2534 (const_string "DF"))
2535 /* For architectures resolving dependencies on register
2536 parts we may avoid extra work to zero out upper part
2537 of register. */
2538 (eq_attr "alternative" "7")
2539 (if_then_else
2540 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2541 (const_int 0))
2542 (const_string "V2DF")
2543 (const_string "DF"))]
2544 (const_string "DF")))])
2545
2546 (define_insn "*movdf_integer"
2547 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2548 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2549 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2550 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2551 && (reload_in_progress || reload_completed
2552 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2553 || GET_CODE (operands[1]) != CONST_DOUBLE
2554 || memory_operand (operands[0], DFmode))"
2555 {
2556 switch (which_alternative)
2557 {
2558 case 0:
2559 return output_387_reg_move (insn, operands);
2560
2561 case 1:
2562 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2563 return "fstp%z0\t%y0";
2564 else
2565 return "fst%z0\t%y0";
2566
2567 case 2:
2568 return standard_80387_constant_opcode (operands[1]);
2569
2570 case 3:
2571 case 4:
2572 return "#";
2573
2574 case 5:
2575 switch (get_attr_mode (insn))
2576 {
2577 case MODE_V4SF:
2578 return "xorps\t%0, %0";
2579 case MODE_V2DF:
2580 return "xorpd\t%0, %0";
2581 case MODE_TI:
2582 return "pxor\t%0, %0";
2583 default:
2584 abort ();
2585 }
2586 case 6:
2587 switch (get_attr_mode (insn))
2588 {
2589 case MODE_V4SF:
2590 return "movaps\t{%1, %0|%0, %1}";
2591 case MODE_V2DF:
2592 return "movapd\t{%1, %0|%0, %1}";
2593 case MODE_DF:
2594 return "movsd\t{%1, %0|%0, %1}";
2595 default:
2596 abort ();
2597 }
2598 case 7:
2599 if (get_attr_mode (insn) == MODE_V2DF)
2600 return "movlpd\t{%1, %0|%0, %1}";
2601 else
2602 return "movsd\t{%1, %0|%0, %1}";
2603 case 8:
2604 return "movsd\t{%1, %0|%0, %1}";
2605
2606 default:
2607 abort();
2608 }
2609 }
2610 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2611 (set (attr "mode")
2612 (cond [(eq_attr "alternative" "3,4")
2613 (const_string "SI")
2614 /* xorps is one byte shorter. */
2615 (eq_attr "alternative" "5")
2616 (cond [(ne (symbol_ref "optimize_size")
2617 (const_int 0))
2618 (const_string "V4SF")
2619 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2620 (const_int 0))
2621 (const_string "TI")]
2622 (const_string "V2DF"))
2623 /* For architectures resolving dependencies on
2624 whole SSE registers use APD move to break dependency
2625 chains, otherwise use short move to avoid extra work.
2626
2627 movaps encodes one byte shorter. */
2628 (eq_attr "alternative" "6")
2629 (cond
2630 [(ne (symbol_ref "optimize_size")
2631 (const_int 0))
2632 (const_string "V4SF")
2633 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2634 (const_int 0))
2635 (const_string "V2DF")]
2636 (const_string "DF"))
2637 /* For architectures resolving dependencies on register
2638 parts we may avoid extra work to zero out upper part
2639 of register. */
2640 (eq_attr "alternative" "7")
2641 (if_then_else
2642 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2643 (const_int 0))
2644 (const_string "V2DF")
2645 (const_string "DF"))]
2646 (const_string "DF")))])
2647
2648 (define_split
2649 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2650 (match_operand:DF 1 "general_operand" ""))]
2651 "reload_completed
2652 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2653 && ! (ANY_FP_REG_P (operands[0]) ||
2654 (GET_CODE (operands[0]) == SUBREG
2655 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2656 && ! (ANY_FP_REG_P (operands[1]) ||
2657 (GET_CODE (operands[1]) == SUBREG
2658 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2659 [(const_int 0)]
2660 "ix86_split_long_move (operands); DONE;")
2661
2662 (define_insn "*swapdf"
2663 [(set (match_operand:DF 0 "register_operand" "+f")
2664 (match_operand:DF 1 "register_operand" "+f"))
2665 (set (match_dup 1)
2666 (match_dup 0))]
2667 "reload_completed || !TARGET_SSE2"
2668 {
2669 if (STACK_TOP_P (operands[0]))
2670 return "fxch\t%1";
2671 else
2672 return "fxch\t%0";
2673 }
2674 [(set_attr "type" "fxch")
2675 (set_attr "mode" "DF")])
2676
2677 (define_expand "movxf"
2678 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2679 (match_operand:XF 1 "general_operand" ""))]
2680 ""
2681 "ix86_expand_move (XFmode, operands); DONE;")
2682
2683 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2684 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2685 ;; Pushing using integer instructions is longer except for constants
2686 ;; and direct memory references.
2687 ;; (assuming that any given constant is pushed only once, but this ought to be
2688 ;; handled elsewhere).
2689
2690 (define_insn "*pushxf_nointeger"
2691 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2692 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2693 "optimize_size"
2694 {
2695 /* This insn should be already split before reg-stack. */
2696 abort ();
2697 }
2698 [(set_attr "type" "multi")
2699 (set_attr "mode" "XF,SI,SI")])
2700
2701 (define_insn "*pushxf_integer"
2702 [(set (match_operand:XF 0 "push_operand" "=<,<")
2703 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2704 "!optimize_size"
2705 {
2706 /* This insn should be already split before reg-stack. */
2707 abort ();
2708 }
2709 [(set_attr "type" "multi")
2710 (set_attr "mode" "XF,SI")])
2711
2712 (define_split
2713 [(set (match_operand 0 "push_operand" "")
2714 (match_operand 1 "general_operand" ""))]
2715 "reload_completed
2716 && (GET_MODE (operands[0]) == XFmode
2717 || GET_MODE (operands[0]) == DFmode)
2718 && !ANY_FP_REG_P (operands[1])"
2719 [(const_int 0)]
2720 "ix86_split_long_move (operands); DONE;")
2721
2722 (define_split
2723 [(set (match_operand:XF 0 "push_operand" "")
2724 (match_operand:XF 1 "any_fp_register_operand" ""))]
2725 "!TARGET_64BIT"
2726 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2727 (set (mem:XF (reg:SI 7)) (match_dup 1))]
2728 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2729
2730 (define_split
2731 [(set (match_operand:XF 0 "push_operand" "")
2732 (match_operand:XF 1 "any_fp_register_operand" ""))]
2733 "TARGET_64BIT"
2734 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2735 (set (mem:XF (reg:DI 7)) (match_dup 1))]
2736 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2737
2738 ;; Do not use integer registers when optimizing for size
2739 (define_insn "*movxf_nointeger"
2740 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2741 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2742 "optimize_size
2743 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2744 && (reload_in_progress || reload_completed
2745 || GET_CODE (operands[1]) != CONST_DOUBLE
2746 || memory_operand (operands[0], XFmode))"
2747 {
2748 switch (which_alternative)
2749 {
2750 case 0:
2751 return output_387_reg_move (insn, operands);
2752
2753 case 1:
2754 /* There is no non-popping store to memory for XFmode. So if
2755 we need one, follow the store with a load. */
2756 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2757 return "fstp%z0\t%y0\;fld%z0\t%y0";
2758 else
2759 return "fstp%z0\t%y0";
2760
2761 case 2:
2762 return standard_80387_constant_opcode (operands[1]);
2763
2764 case 3: case 4:
2765 return "#";
2766 }
2767 abort();
2768 }
2769 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2770 (set_attr "mode" "XF,XF,XF,SI,SI")])
2771
2772 (define_insn "*movxf_integer"
2773 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2774 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2775 "!optimize_size
2776 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2777 && (reload_in_progress || reload_completed
2778 || GET_CODE (operands[1]) != CONST_DOUBLE
2779 || memory_operand (operands[0], XFmode))"
2780 {
2781 switch (which_alternative)
2782 {
2783 case 0:
2784 return output_387_reg_move (insn, operands);
2785
2786 case 1:
2787 /* There is no non-popping store to memory for XFmode. So if
2788 we need one, follow the store with a load. */
2789 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2790 return "fstp%z0\t%y0\;fld%z0\t%y0";
2791 else
2792 return "fstp%z0\t%y0";
2793
2794 case 2:
2795 return standard_80387_constant_opcode (operands[1]);
2796
2797 case 3: case 4:
2798 return "#";
2799 }
2800 abort();
2801 }
2802 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2803 (set_attr "mode" "XF,XF,XF,SI,SI")])
2804
2805 (define_split
2806 [(set (match_operand 0 "nonimmediate_operand" "")
2807 (match_operand 1 "general_operand" ""))]
2808 "reload_completed
2809 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2810 && GET_MODE (operands[0]) == XFmode
2811 && ! (ANY_FP_REG_P (operands[0]) ||
2812 (GET_CODE (operands[0]) == SUBREG
2813 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2814 && ! (ANY_FP_REG_P (operands[1]) ||
2815 (GET_CODE (operands[1]) == SUBREG
2816 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2817 [(const_int 0)]
2818 "ix86_split_long_move (operands); DONE;")
2819
2820 (define_split
2821 [(set (match_operand 0 "register_operand" "")
2822 (match_operand 1 "memory_operand" ""))]
2823 "reload_completed
2824 && GET_CODE (operands[1]) == MEM
2825 && (GET_MODE (operands[0]) == XFmode
2826 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2827 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2828 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2829 [(set (match_dup 0) (match_dup 1))]
2830 {
2831 rtx c = get_pool_constant (XEXP (operands[1], 0));
2832 rtx r = operands[0];
2833
2834 if (GET_CODE (r) == SUBREG)
2835 r = SUBREG_REG (r);
2836
2837 if (SSE_REG_P (r))
2838 {
2839 if (!standard_sse_constant_p (c))
2840 FAIL;
2841 }
2842 else if (FP_REG_P (r))
2843 {
2844 if (!standard_80387_constant_p (c))
2845 FAIL;
2846 }
2847 else if (MMX_REG_P (r))
2848 FAIL;
2849
2850 operands[1] = c;
2851 })
2852
2853 (define_insn "swapxf"
2854 [(set (match_operand:XF 0 "register_operand" "+f")
2855 (match_operand:XF 1 "register_operand" "+f"))
2856 (set (match_dup 1)
2857 (match_dup 0))]
2858 ""
2859 {
2860 if (STACK_TOP_P (operands[0]))
2861 return "fxch\t%1";
2862 else
2863 return "fxch\t%0";
2864 }
2865 [(set_attr "type" "fxch")
2866 (set_attr "mode" "XF")])
2867 \f
2868 ;; Zero extension instructions
2869
2870 (define_expand "zero_extendhisi2"
2871 [(set (match_operand:SI 0 "register_operand" "")
2872 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2873 ""
2874 {
2875 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2876 {
2877 operands[1] = force_reg (HImode, operands[1]);
2878 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2879 DONE;
2880 }
2881 })
2882
2883 (define_insn "zero_extendhisi2_and"
2884 [(set (match_operand:SI 0 "register_operand" "=r")
2885 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2886 (clobber (reg:CC 17))]
2887 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2888 "#"
2889 [(set_attr "type" "alu1")
2890 (set_attr "mode" "SI")])
2891
2892 (define_split
2893 [(set (match_operand:SI 0 "register_operand" "")
2894 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2895 (clobber (reg:CC 17))]
2896 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2897 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2898 (clobber (reg:CC 17))])]
2899 "")
2900
2901 (define_insn "*zero_extendhisi2_movzwl"
2902 [(set (match_operand:SI 0 "register_operand" "=r")
2903 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2904 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2905 "movz{wl|x}\t{%1, %0|%0, %1}"
2906 [(set_attr "type" "imovx")
2907 (set_attr "mode" "SI")])
2908
2909 (define_expand "zero_extendqihi2"
2910 [(parallel
2911 [(set (match_operand:HI 0 "register_operand" "")
2912 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2913 (clobber (reg:CC 17))])]
2914 ""
2915 "")
2916
2917 (define_insn "*zero_extendqihi2_and"
2918 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2919 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2920 (clobber (reg:CC 17))]
2921 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2922 "#"
2923 [(set_attr "type" "alu1")
2924 (set_attr "mode" "HI")])
2925
2926 (define_insn "*zero_extendqihi2_movzbw_and"
2927 [(set (match_operand:HI 0 "register_operand" "=r,r")
2928 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2929 (clobber (reg:CC 17))]
2930 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2931 "#"
2932 [(set_attr "type" "imovx,alu1")
2933 (set_attr "mode" "HI")])
2934
2935 (define_insn "*zero_extendqihi2_movzbw"
2936 [(set (match_operand:HI 0 "register_operand" "=r")
2937 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2938 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2939 "movz{bw|x}\t{%1, %0|%0, %1}"
2940 [(set_attr "type" "imovx")
2941 (set_attr "mode" "HI")])
2942
2943 ;; For the movzbw case strip only the clobber
2944 (define_split
2945 [(set (match_operand:HI 0 "register_operand" "")
2946 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2947 (clobber (reg:CC 17))]
2948 "reload_completed
2949 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2950 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2951 [(set (match_operand:HI 0 "register_operand" "")
2952 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2953
2954 ;; When source and destination does not overlap, clear destination
2955 ;; first and then do the movb
2956 (define_split
2957 [(set (match_operand:HI 0 "register_operand" "")
2958 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2959 (clobber (reg:CC 17))]
2960 "reload_completed
2961 && ANY_QI_REG_P (operands[0])
2962 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2963 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2964 [(set (match_dup 0) (const_int 0))
2965 (set (strict_low_part (match_dup 2)) (match_dup 1))]
2966 "operands[2] = gen_lowpart (QImode, operands[0]);")
2967
2968 ;; Rest is handled by single and.
2969 (define_split
2970 [(set (match_operand:HI 0 "register_operand" "")
2971 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2972 (clobber (reg:CC 17))]
2973 "reload_completed
2974 && true_regnum (operands[0]) == true_regnum (operands[1])"
2975 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2976 (clobber (reg:CC 17))])]
2977 "")
2978
2979 (define_expand "zero_extendqisi2"
2980 [(parallel
2981 [(set (match_operand:SI 0 "register_operand" "")
2982 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2983 (clobber (reg:CC 17))])]
2984 ""
2985 "")
2986
2987 (define_insn "*zero_extendqisi2_and"
2988 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2989 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2990 (clobber (reg:CC 17))]
2991 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2992 "#"
2993 [(set_attr "type" "alu1")
2994 (set_attr "mode" "SI")])
2995
2996 (define_insn "*zero_extendqisi2_movzbw_and"
2997 [(set (match_operand:SI 0 "register_operand" "=r,r")
2998 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2999 (clobber (reg:CC 17))]
3000 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3001 "#"
3002 [(set_attr "type" "imovx,alu1")
3003 (set_attr "mode" "SI")])
3004
3005 (define_insn "*zero_extendqisi2_movzbw"
3006 [(set (match_operand:SI 0 "register_operand" "=r")
3007 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3008 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3009 "movz{bl|x}\t{%1, %0|%0, %1}"
3010 [(set_attr "type" "imovx")
3011 (set_attr "mode" "SI")])
3012
3013 ;; For the movzbl case strip only the clobber
3014 (define_split
3015 [(set (match_operand:SI 0 "register_operand" "")
3016 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3017 (clobber (reg:CC 17))]
3018 "reload_completed
3019 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3020 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3021 [(set (match_dup 0)
3022 (zero_extend:SI (match_dup 1)))])
3023
3024 ;; When source and destination does not overlap, clear destination
3025 ;; first and then do the movb
3026 (define_split
3027 [(set (match_operand:SI 0 "register_operand" "")
3028 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3029 (clobber (reg:CC 17))]
3030 "reload_completed
3031 && ANY_QI_REG_P (operands[0])
3032 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3033 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3034 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3035 [(set (match_dup 0) (const_int 0))
3036 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3037 "operands[2] = gen_lowpart (QImode, operands[0]);")
3038
3039 ;; Rest is handled by single and.
3040 (define_split
3041 [(set (match_operand:SI 0 "register_operand" "")
3042 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3043 (clobber (reg:CC 17))]
3044 "reload_completed
3045 && true_regnum (operands[0]) == true_regnum (operands[1])"
3046 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3047 (clobber (reg:CC 17))])]
3048 "")
3049
3050 ;; %%% Kill me once multi-word ops are sane.
3051 (define_expand "zero_extendsidi2"
3052 [(set (match_operand:DI 0 "register_operand" "=r")
3053 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3054 ""
3055 "if (!TARGET_64BIT)
3056 {
3057 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3058 DONE;
3059 }
3060 ")
3061
3062 (define_insn "zero_extendsidi2_32"
3063 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3064 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3065 (clobber (reg:CC 17))]
3066 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3067 "@
3068 #
3069 #
3070 #
3071 movd\t{%1, %0|%0, %1}
3072 movd\t{%1, %0|%0, %1}"
3073 [(set_attr "mode" "SI,SI,SI,DI,TI")
3074 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3075
3076 (define_insn "*zero_extendsidi2_32_1"
3077 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3078 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3079 (clobber (reg:CC 17))]
3080 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3081 "@
3082 #
3083 #
3084 #
3085 movd\t{%1, %0|%0, %1}
3086 movd\t{%1, %0|%0, %1}"
3087 [(set_attr "mode" "SI,SI,SI,DI,TI")
3088 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3089
3090 (define_insn "zero_extendsidi2_rex64"
3091 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3092 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3093 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3094 "@
3095 mov\t{%k1, %k0|%k0, %k1}
3096 #
3097 movd\t{%1, %0|%0, %1}
3098 movd\t{%1, %0|%0, %1}"
3099 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3100 (set_attr "mode" "SI,DI,DI,TI")])
3101
3102 (define_insn "*zero_extendsidi2_rex64_1"
3103 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3104 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3105 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3106 "@
3107 mov\t{%k1, %k0|%k0, %k1}
3108 #
3109 movd\t{%1, %0|%0, %1}
3110 movd\t{%1, %0|%0, %1}"
3111 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3112 (set_attr "mode" "SI,DI,SI,SI")])
3113
3114 (define_split
3115 [(set (match_operand:DI 0 "memory_operand" "")
3116 (zero_extend:DI (match_dup 0)))]
3117 "TARGET_64BIT"
3118 [(set (match_dup 4) (const_int 0))]
3119 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3120
3121 (define_split
3122 [(set (match_operand:DI 0 "register_operand" "")
3123 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3124 (clobber (reg:CC 17))]
3125 "!TARGET_64BIT && reload_completed
3126 && true_regnum (operands[0]) == true_regnum (operands[1])"
3127 [(set (match_dup 4) (const_int 0))]
3128 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3129
3130 (define_split
3131 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3132 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3133 (clobber (reg:CC 17))]
3134 "!TARGET_64BIT && reload_completed
3135 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3136 [(set (match_dup 3) (match_dup 1))
3137 (set (match_dup 4) (const_int 0))]
3138 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3139
3140 (define_insn "zero_extendhidi2"
3141 [(set (match_operand:DI 0 "register_operand" "=r,r")
3142 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3143 "TARGET_64BIT"
3144 "@
3145 movz{wl|x}\t{%1, %k0|%k0, %1}
3146 movz{wq|x}\t{%1, %0|%0, %1}"
3147 [(set_attr "type" "imovx")
3148 (set_attr "mode" "SI,DI")])
3149
3150 (define_insn "zero_extendqidi2"
3151 [(set (match_operand:DI 0 "register_operand" "=r,r")
3152 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3153 "TARGET_64BIT"
3154 "@
3155 movz{bl|x}\t{%1, %k0|%k0, %1}
3156 movz{bq|x}\t{%1, %0|%0, %1}"
3157 [(set_attr "type" "imovx")
3158 (set_attr "mode" "SI,DI")])
3159 \f
3160 ;; Sign extension instructions
3161
3162 (define_expand "extendsidi2"
3163 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3164 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3165 (clobber (reg:CC 17))
3166 (clobber (match_scratch:SI 2 ""))])]
3167 ""
3168 {
3169 if (TARGET_64BIT)
3170 {
3171 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3172 DONE;
3173 }
3174 })
3175
3176 (define_insn "*extendsidi2_1"
3177 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3178 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3179 (clobber (reg:CC 17))
3180 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3181 "!TARGET_64BIT"
3182 "#")
3183
3184 (define_insn "extendsidi2_rex64"
3185 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3186 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3187 "TARGET_64BIT"
3188 "@
3189 {cltq|cdqe}
3190 movs{lq|x}\t{%1,%0|%0, %1}"
3191 [(set_attr "type" "imovx")
3192 (set_attr "mode" "DI")
3193 (set_attr "prefix_0f" "0")
3194 (set_attr "modrm" "0,1")])
3195
3196 (define_insn "extendhidi2"
3197 [(set (match_operand:DI 0 "register_operand" "=r")
3198 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3199 "TARGET_64BIT"
3200 "movs{wq|x}\t{%1,%0|%0, %1}"
3201 [(set_attr "type" "imovx")
3202 (set_attr "mode" "DI")])
3203
3204 (define_insn "extendqidi2"
3205 [(set (match_operand:DI 0 "register_operand" "=r")
3206 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3207 "TARGET_64BIT"
3208 "movs{bq|x}\t{%1,%0|%0, %1}"
3209 [(set_attr "type" "imovx")
3210 (set_attr "mode" "DI")])
3211
3212 ;; Extend to memory case when source register does die.
3213 (define_split
3214 [(set (match_operand:DI 0 "memory_operand" "")
3215 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3216 (clobber (reg:CC 17))
3217 (clobber (match_operand:SI 2 "register_operand" ""))]
3218 "(reload_completed
3219 && dead_or_set_p (insn, operands[1])
3220 && !reg_mentioned_p (operands[1], operands[0]))"
3221 [(set (match_dup 3) (match_dup 1))
3222 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3223 (clobber (reg:CC 17))])
3224 (set (match_dup 4) (match_dup 1))]
3225 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3226
3227 ;; Extend to memory case when source register does not die.
3228 (define_split
3229 [(set (match_operand:DI 0 "memory_operand" "")
3230 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3231 (clobber (reg:CC 17))
3232 (clobber (match_operand:SI 2 "register_operand" ""))]
3233 "reload_completed"
3234 [(const_int 0)]
3235 {
3236 split_di (&operands[0], 1, &operands[3], &operands[4]);
3237
3238 emit_move_insn (operands[3], operands[1]);
3239
3240 /* Generate a cltd if possible and doing so it profitable. */
3241 if (true_regnum (operands[1]) == 0
3242 && true_regnum (operands[2]) == 1
3243 && (optimize_size || TARGET_USE_CLTD))
3244 {
3245 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3246 }
3247 else
3248 {
3249 emit_move_insn (operands[2], operands[1]);
3250 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3251 }
3252 emit_move_insn (operands[4], operands[2]);
3253 DONE;
3254 })
3255
3256 ;; Extend to register case. Optimize case where source and destination
3257 ;; registers match and cases where we can use cltd.
3258 (define_split
3259 [(set (match_operand:DI 0 "register_operand" "")
3260 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3261 (clobber (reg:CC 17))
3262 (clobber (match_scratch:SI 2 ""))]
3263 "reload_completed"
3264 [(const_int 0)]
3265 {
3266 split_di (&operands[0], 1, &operands[3], &operands[4]);
3267
3268 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3269 emit_move_insn (operands[3], operands[1]);
3270
3271 /* Generate a cltd if possible and doing so it profitable. */
3272 if (true_regnum (operands[3]) == 0
3273 && (optimize_size || TARGET_USE_CLTD))
3274 {
3275 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3276 DONE;
3277 }
3278
3279 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3280 emit_move_insn (operands[4], operands[1]);
3281
3282 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3283 DONE;
3284 })
3285
3286 (define_insn "extendhisi2"
3287 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3288 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3289 ""
3290 {
3291 switch (get_attr_prefix_0f (insn))
3292 {
3293 case 0:
3294 return "{cwtl|cwde}";
3295 default:
3296 return "movs{wl|x}\t{%1,%0|%0, %1}";
3297 }
3298 }
3299 [(set_attr "type" "imovx")
3300 (set_attr "mode" "SI")
3301 (set (attr "prefix_0f")
3302 ;; movsx is short decodable while cwtl is vector decoded.
3303 (if_then_else (and (eq_attr "cpu" "!k6")
3304 (eq_attr "alternative" "0"))
3305 (const_string "0")
3306 (const_string "1")))
3307 (set (attr "modrm")
3308 (if_then_else (eq_attr "prefix_0f" "0")
3309 (const_string "0")
3310 (const_string "1")))])
3311
3312 (define_insn "*extendhisi2_zext"
3313 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3314 (zero_extend:DI
3315 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3316 "TARGET_64BIT"
3317 {
3318 switch (get_attr_prefix_0f (insn))
3319 {
3320 case 0:
3321 return "{cwtl|cwde}";
3322 default:
3323 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3324 }
3325 }
3326 [(set_attr "type" "imovx")
3327 (set_attr "mode" "SI")
3328 (set (attr "prefix_0f")
3329 ;; movsx is short decodable while cwtl is vector decoded.
3330 (if_then_else (and (eq_attr "cpu" "!k6")
3331 (eq_attr "alternative" "0"))
3332 (const_string "0")
3333 (const_string "1")))
3334 (set (attr "modrm")
3335 (if_then_else (eq_attr "prefix_0f" "0")
3336 (const_string "0")
3337 (const_string "1")))])
3338
3339 (define_insn "extendqihi2"
3340 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3341 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3342 ""
3343 {
3344 switch (get_attr_prefix_0f (insn))
3345 {
3346 case 0:
3347 return "{cbtw|cbw}";
3348 default:
3349 return "movs{bw|x}\t{%1,%0|%0, %1}";
3350 }
3351 }
3352 [(set_attr "type" "imovx")
3353 (set_attr "mode" "HI")
3354 (set (attr "prefix_0f")
3355 ;; movsx is short decodable while cwtl is vector decoded.
3356 (if_then_else (and (eq_attr "cpu" "!k6")
3357 (eq_attr "alternative" "0"))
3358 (const_string "0")
3359 (const_string "1")))
3360 (set (attr "modrm")
3361 (if_then_else (eq_attr "prefix_0f" "0")
3362 (const_string "0")
3363 (const_string "1")))])
3364
3365 (define_insn "extendqisi2"
3366 [(set (match_operand:SI 0 "register_operand" "=r")
3367 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3368 ""
3369 "movs{bl|x}\t{%1,%0|%0, %1}"
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "SI")])
3372
3373 (define_insn "*extendqisi2_zext"
3374 [(set (match_operand:DI 0 "register_operand" "=r")
3375 (zero_extend:DI
3376 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3377 "TARGET_64BIT"
3378 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3379 [(set_attr "type" "imovx")
3380 (set_attr "mode" "SI")])
3381 \f
3382 ;; Conversions between float and double.
3383
3384 ;; These are all no-ops in the model used for the 80387. So just
3385 ;; emit moves.
3386
3387 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3388 (define_insn "*dummy_extendsfdf2"
3389 [(set (match_operand:DF 0 "push_operand" "=<")
3390 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3391 "0"
3392 "#")
3393
3394 (define_split
3395 [(set (match_operand:DF 0 "push_operand" "")
3396 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3397 "!TARGET_64BIT"
3398 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3399 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3400
3401 (define_split
3402 [(set (match_operand:DF 0 "push_operand" "")
3403 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3404 "TARGET_64BIT"
3405 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3406 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3407
3408 (define_insn "*dummy_extendsfxf2"
3409 [(set (match_operand:XF 0 "push_operand" "=<")
3410 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3411 "0"
3412 "#")
3413
3414 (define_split
3415 [(set (match_operand:XF 0 "push_operand" "")
3416 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3417 ""
3418 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3419 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3420 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3421
3422 (define_split
3423 [(set (match_operand:XF 0 "push_operand" "")
3424 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3425 "TARGET_64BIT"
3426 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3427 (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3428 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3429
3430 (define_split
3431 [(set (match_operand:XF 0 "push_operand" "")
3432 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3433 ""
3434 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3435 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3436 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3437
3438 (define_split
3439 [(set (match_operand:XF 0 "push_operand" "")
3440 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3441 "TARGET_64BIT"
3442 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3443 (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3444 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3445
3446 (define_expand "extendsfdf2"
3447 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3448 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3449 "TARGET_80387 || TARGET_SSE2"
3450 {
3451 /* ??? Needed for compress_float_constant since all fp constants
3452 are LEGITIMATE_CONSTANT_P. */
3453 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3454 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3455 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3456 operands[1] = force_reg (SFmode, operands[1]);
3457 })
3458
3459 (define_insn "*extendsfdf2_1"
3460 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3461 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3462 "(TARGET_80387 || TARGET_SSE2)
3463 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3464 {
3465 switch (which_alternative)
3466 {
3467 case 0:
3468 return output_387_reg_move (insn, operands);
3469
3470 case 1:
3471 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3472 return "fstp%z0\t%y0";
3473 else
3474 return "fst%z0\t%y0";
3475
3476 case 2:
3477 return "cvtss2sd\t{%1, %0|%0, %1}";
3478
3479 default:
3480 abort ();
3481 }
3482 }
3483 [(set_attr "type" "fmov,fmov,ssecvt")
3484 (set_attr "mode" "SF,XF,DF")])
3485
3486 (define_insn "*extendsfdf2_1_sse_only"
3487 [(set (match_operand:DF 0 "register_operand" "=Y")
3488 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3489 "!TARGET_80387 && TARGET_SSE2
3490 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3491 "cvtss2sd\t{%1, %0|%0, %1}"
3492 [(set_attr "type" "ssecvt")
3493 (set_attr "mode" "DF")])
3494
3495 (define_expand "extendsfxf2"
3496 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3497 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3498 "TARGET_80387"
3499 {
3500 /* ??? Needed for compress_float_constant since all fp constants
3501 are LEGITIMATE_CONSTANT_P. */
3502 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3503 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3504 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3505 operands[1] = force_reg (SFmode, operands[1]);
3506 })
3507
3508 (define_insn "*extendsfxf2_1"
3509 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3510 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3511 "TARGET_80387
3512 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3513 {
3514 switch (which_alternative)
3515 {
3516 case 0:
3517 return output_387_reg_move (insn, operands);
3518
3519 case 1:
3520 /* There is no non-popping store to memory for XFmode. So if
3521 we need one, follow the store with a load. */
3522 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3523 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3524 else
3525 return "fstp%z0\t%y0";
3526
3527 default:
3528 abort ();
3529 }
3530 }
3531 [(set_attr "type" "fmov")
3532 (set_attr "mode" "SF,XF")])
3533
3534 (define_expand "extenddfxf2"
3535 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3536 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3537 "TARGET_80387"
3538 {
3539 /* ??? Needed for compress_float_constant since all fp constants
3540 are LEGITIMATE_CONSTANT_P. */
3541 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3542 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3543 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3544 operands[1] = force_reg (DFmode, operands[1]);
3545 })
3546
3547 (define_insn "*extenddfxf2_1"
3548 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3549 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3550 "TARGET_80387
3551 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3552 {
3553 switch (which_alternative)
3554 {
3555 case 0:
3556 return output_387_reg_move (insn, operands);
3557
3558 case 1:
3559 /* There is no non-popping store to memory for XFmode. So if
3560 we need one, follow the store with a load. */
3561 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3562 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3563 else
3564 return "fstp%z0\t%y0";
3565
3566 default:
3567 abort ();
3568 }
3569 }
3570 [(set_attr "type" "fmov")
3571 (set_attr "mode" "DF,XF")])
3572
3573 ;; %%% This seems bad bad news.
3574 ;; This cannot output into an f-reg because there is no way to be sure
3575 ;; of truncating in that case. Otherwise this is just like a simple move
3576 ;; insn. So we pretend we can output to a reg in order to get better
3577 ;; register preferencing, but we really use a stack slot.
3578
3579 (define_expand "truncdfsf2"
3580 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3581 (float_truncate:SF
3582 (match_operand:DF 1 "register_operand" "")))
3583 (clobber (match_dup 2))])]
3584 "TARGET_80387 || TARGET_SSE2"
3585 "
3586 if (!TARGET_80387)
3587 {
3588 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3589 DONE;
3590 }
3591 else if (flag_unsafe_math_optimizations)
3592 {
3593 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3594 emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3595 if (reg != operands[0])
3596 emit_move_insn (operands[0], reg);
3597 DONE;
3598 }
3599 else
3600 operands[2] = assign_386_stack_local (SFmode, 0);
3601 ")
3602
3603 (define_insn "truncdfsf2_noop"
3604 [(set (match_operand:SF 0 "register_operand" "=f")
3605 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3606 "TARGET_80387 && flag_unsafe_math_optimizations"
3607 {
3608 return output_387_reg_move (insn, operands);
3609 }
3610 [(set_attr "type" "fmov")
3611 (set_attr "mode" "SF")])
3612
3613 (define_insn "*truncdfsf2_1"
3614 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3615 (float_truncate:SF
3616 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3617 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3618 "TARGET_80387 && !TARGET_SSE2"
3619 {
3620 switch (which_alternative)
3621 {
3622 case 0:
3623 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624 return "fstp%z0\t%y0";
3625 else
3626 return "fst%z0\t%y0";
3627 default:
3628 abort ();
3629 }
3630 }
3631 [(set_attr "type" "fmov,multi,multi,multi")
3632 (set_attr "mode" "SF,SF,SF,SF")])
3633
3634 (define_insn "*truncdfsf2_1_sse"
3635 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3636 (float_truncate:SF
3637 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3638 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3639 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3640 {
3641 switch (which_alternative)
3642 {
3643 case 0:
3644 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3645 return "fstp%z0\t%y0";
3646 else
3647 return "fst%z0\t%y0";
3648 case 4:
3649 return "#";
3650 default:
3651 abort ();
3652 }
3653 }
3654 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3655 (set_attr "mode" "SF,SF,SF,SF,DF")])
3656
3657 (define_insn "*truncdfsf2_1_sse_nooverlap"
3658 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3659 (float_truncate:SF
3660 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3661 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3662 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3663 {
3664 switch (which_alternative)
3665 {
3666 case 0:
3667 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3668 return "fstp%z0\t%y0";
3669 else
3670 return "fst%z0\t%y0";
3671 case 4:
3672 return "#";
3673 default:
3674 abort ();
3675 }
3676 }
3677 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3678 (set_attr "mode" "SF,SF,SF,SF,DF")])
3679
3680 (define_insn "*truncdfsf2_2"
3681 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3682 (float_truncate:SF
3683 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3684 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3685 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3686 {
3687 switch (which_alternative)
3688 {
3689 case 0:
3690 case 1:
3691 return "cvtsd2ss\t{%1, %0|%0, %1}";
3692 case 2:
3693 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3694 return "fstp%z0\t%y0";
3695 else
3696 return "fst%z0\t%y0";
3697 default:
3698 abort ();
3699 }
3700 }
3701 [(set_attr "type" "ssecvt,ssecvt,fmov")
3702 (set_attr "athlon_decode" "vector,double,*")
3703 (set_attr "mode" "SF,SF,SF")])
3704
3705 (define_insn "*truncdfsf2_2_nooverlap"
3706 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3707 (float_truncate:SF
3708 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3709 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3710 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3711 {
3712 switch (which_alternative)
3713 {
3714 case 0:
3715 return "#";
3716 case 1:
3717 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3718 return "fstp%z0\t%y0";
3719 else
3720 return "fst%z0\t%y0";
3721 default:
3722 abort ();
3723 }
3724 }
3725 [(set_attr "type" "ssecvt,fmov")
3726 (set_attr "mode" "DF,SF")])
3727
3728 (define_insn "*truncdfsf2_3"
3729 [(set (match_operand:SF 0 "memory_operand" "=m")
3730 (float_truncate:SF
3731 (match_operand:DF 1 "register_operand" "f")))]
3732 "TARGET_80387"
3733 {
3734 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3735 return "fstp%z0\t%y0";
3736 else
3737 return "fst%z0\t%y0";
3738 }
3739 [(set_attr "type" "fmov")
3740 (set_attr "mode" "SF")])
3741
3742 (define_insn "truncdfsf2_sse_only"
3743 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3744 (float_truncate:SF
3745 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3746 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3747 "cvtsd2ss\t{%1, %0|%0, %1}"
3748 [(set_attr "type" "ssecvt")
3749 (set_attr "athlon_decode" "vector,double")
3750 (set_attr "mode" "SF")])
3751
3752 (define_insn "*truncdfsf2_sse_only_nooverlap"
3753 [(set (match_operand:SF 0 "register_operand" "=&Y")
3754 (float_truncate:SF
3755 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3756 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3757 "#"
3758 [(set_attr "type" "ssecvt")
3759 (set_attr "mode" "DF")])
3760
3761 (define_split
3762 [(set (match_operand:SF 0 "memory_operand" "")
3763 (float_truncate:SF
3764 (match_operand:DF 1 "register_operand" "")))
3765 (clobber (match_operand:SF 2 "memory_operand" ""))]
3766 "TARGET_80387"
3767 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3768 "")
3769
3770 ; Avoid possible reformatting penalty on the destination by first
3771 ; zeroing it out
3772 (define_split
3773 [(set (match_operand:SF 0 "register_operand" "")
3774 (float_truncate:SF
3775 (match_operand:DF 1 "nonimmediate_operand" "")))
3776 (clobber (match_operand 2 "" ""))]
3777 "TARGET_80387 && reload_completed
3778 && SSE_REG_P (operands[0])
3779 && !STACK_REG_P (operands[1])"
3780 [(const_int 0)]
3781 {
3782 rtx src, dest;
3783 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3784 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3785 else
3786 {
3787 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3788 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3789 /* simplify_gen_subreg refuses to widen memory references. */
3790 if (GET_CODE (src) == SUBREG)
3791 alter_subreg (&src);
3792 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3793 abort ();
3794 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3795 emit_insn (gen_cvtsd2ss (dest, dest, src));
3796 }
3797 DONE;
3798 })
3799
3800 (define_split
3801 [(set (match_operand:SF 0 "register_operand" "")
3802 (float_truncate:SF
3803 (match_operand:DF 1 "nonimmediate_operand" "")))]
3804 "TARGET_80387 && reload_completed
3805 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3806 [(const_int 0)]
3807 {
3808 rtx src, dest;
3809 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3810 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3811 /* simplify_gen_subreg refuses to widen memory references. */
3812 if (GET_CODE (src) == SUBREG)
3813 alter_subreg (&src);
3814 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3815 abort ();
3816 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3817 emit_insn (gen_cvtsd2ss (dest, dest, src));
3818 DONE;
3819 })
3820
3821 (define_split
3822 [(set (match_operand:SF 0 "register_operand" "")
3823 (float_truncate:SF
3824 (match_operand:DF 1 "fp_register_operand" "")))
3825 (clobber (match_operand:SF 2 "memory_operand" ""))]
3826 "TARGET_80387 && reload_completed"
3827 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3828 (set (match_dup 0) (match_dup 2))]
3829 "")
3830
3831 (define_expand "truncxfsf2"
3832 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3833 (float_truncate:SF
3834 (match_operand:XF 1 "register_operand" "")))
3835 (clobber (match_dup 2))])]
3836 "TARGET_80387"
3837 "
3838 if (flag_unsafe_math_optimizations)
3839 {
3840 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3841 emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3842 if (reg != operands[0])
3843 emit_move_insn (operands[0], reg);
3844 DONE;
3845 }
3846 else
3847 operands[2] = assign_386_stack_local (SFmode, 0);
3848 ")
3849
3850 (define_insn "truncxfsf2_noop"
3851 [(set (match_operand:SF 0 "register_operand" "=f")
3852 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3853 "TARGET_80387 && flag_unsafe_math_optimizations"
3854 {
3855 return output_387_reg_move (insn, operands);
3856 }
3857 [(set_attr "type" "fmov")
3858 (set_attr "mode" "SF")])
3859
3860 (define_insn "*truncxfsf2_1"
3861 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3862 (float_truncate:SF
3863 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3864 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3865 "TARGET_80387"
3866 {
3867 switch (which_alternative)
3868 {
3869 case 0:
3870 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3871 return "fstp%z0\t%y0";
3872 else
3873 return "fst%z0\t%y0";
3874 default:
3875 abort();
3876 }
3877 }
3878 [(set_attr "type" "fmov,multi,multi,multi")
3879 (set_attr "mode" "SF")])
3880
3881 (define_insn "*truncxfsf2_2"
3882 [(set (match_operand:SF 0 "memory_operand" "=m")
3883 (float_truncate:SF
3884 (match_operand:XF 1 "register_operand" "f")))]
3885 "TARGET_80387"
3886 {
3887 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3888 return "fstp%z0\t%y0";
3889 else
3890 return "fst%z0\t%y0";
3891 }
3892 [(set_attr "type" "fmov")
3893 (set_attr "mode" "SF")])
3894
3895 (define_split
3896 [(set (match_operand:SF 0 "memory_operand" "")
3897 (float_truncate:SF
3898 (match_operand:XF 1 "register_operand" "")))
3899 (clobber (match_operand:SF 2 "memory_operand" ""))]
3900 "TARGET_80387"
3901 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3902 "")
3903
3904 (define_split
3905 [(set (match_operand:SF 0 "register_operand" "")
3906 (float_truncate:SF
3907 (match_operand:XF 1 "register_operand" "")))
3908 (clobber (match_operand:SF 2 "memory_operand" ""))]
3909 "TARGET_80387 && reload_completed"
3910 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3911 (set (match_dup 0) (match_dup 2))]
3912 "")
3913
3914 (define_expand "truncxfdf2"
3915 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3916 (float_truncate:DF
3917 (match_operand:XF 1 "register_operand" "")))
3918 (clobber (match_dup 2))])]
3919 "TARGET_80387"
3920 "
3921 if (flag_unsafe_math_optimizations)
3922 {
3923 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3924 emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3925 if (reg != operands[0])
3926 emit_move_insn (operands[0], reg);
3927 DONE;
3928 }
3929 else
3930 operands[2] = assign_386_stack_local (DFmode, 0);
3931 ")
3932
3933 (define_insn "truncxfdf2_noop"
3934 [(set (match_operand:DF 0 "register_operand" "=f")
3935 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3936 "TARGET_80387 && flag_unsafe_math_optimizations"
3937 {
3938 return output_387_reg_move (insn, operands);
3939 }
3940 [(set_attr "type" "fmov")
3941 (set_attr "mode" "DF")])
3942
3943 (define_insn "*truncxfdf2_1"
3944 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3945 (float_truncate:DF
3946 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3947 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3948 "TARGET_80387"
3949 {
3950 switch (which_alternative)
3951 {
3952 case 0:
3953 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3954 return "fstp%z0\t%y0";
3955 else
3956 return "fst%z0\t%y0";
3957 default:
3958 abort();
3959 }
3960 abort ();
3961 }
3962 [(set_attr "type" "fmov,multi,multi,multi")
3963 (set_attr "mode" "DF")])
3964
3965 (define_insn "*truncxfdf2_2"
3966 [(set (match_operand:DF 0 "memory_operand" "=m")
3967 (float_truncate:DF
3968 (match_operand:XF 1 "register_operand" "f")))]
3969 "TARGET_80387"
3970 {
3971 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3972 return "fstp%z0\t%y0";
3973 else
3974 return "fst%z0\t%y0";
3975 }
3976 [(set_attr "type" "fmov")
3977 (set_attr "mode" "DF")])
3978
3979 (define_split
3980 [(set (match_operand:DF 0 "memory_operand" "")
3981 (float_truncate:DF
3982 (match_operand:XF 1 "register_operand" "")))
3983 (clobber (match_operand:DF 2 "memory_operand" ""))]
3984 "TARGET_80387"
3985 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3986 "")
3987
3988 (define_split
3989 [(set (match_operand:DF 0 "register_operand" "")
3990 (float_truncate:DF
3991 (match_operand:XF 1 "register_operand" "")))
3992 (clobber (match_operand:DF 2 "memory_operand" ""))]
3993 "TARGET_80387 && reload_completed"
3994 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3995 (set (match_dup 0) (match_dup 2))]
3996 "")
3997
3998 \f
3999 ;; %%% Break up all these bad boys.
4000
4001 ;; Signed conversion to DImode.
4002
4003 (define_expand "fix_truncxfdi2"
4004 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4005 (fix:DI (match_operand:XF 1 "register_operand" "")))
4006 (clobber (reg:CC 17))])]
4007 "TARGET_80387"
4008 "")
4009
4010 (define_expand "fix_truncdfdi2"
4011 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4012 (fix:DI (match_operand:DF 1 "register_operand" "")))
4013 (clobber (reg:CC 17))])]
4014 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4015 {
4016 if (TARGET_64BIT && TARGET_SSE2)
4017 {
4018 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4019 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4020 if (out != operands[0])
4021 emit_move_insn (operands[0], out);
4022 DONE;
4023 }
4024 })
4025
4026 (define_expand "fix_truncsfdi2"
4027 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028 (fix:DI (match_operand:SF 1 "register_operand" "")))
4029 (clobber (reg:CC 17))])]
4030 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4031 {
4032 if (TARGET_SSE && TARGET_64BIT)
4033 {
4034 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4035 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4036 if (out != operands[0])
4037 emit_move_insn (operands[0], out);
4038 DONE;
4039 }
4040 })
4041
4042 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4043 ;; of the machinery.
4044 (define_insn_and_split "*fix_truncdi_1"
4045 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4046 (fix:DI (match_operand 1 "register_operand" "f,f")))
4047 (clobber (reg:CC 17))]
4048 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4049 && !reload_completed && !reload_in_progress
4050 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4051 "#"
4052 "&& 1"
4053 [(const_int 0)]
4054 {
4055 ix86_optimize_mode_switching = 1;
4056 operands[2] = assign_386_stack_local (HImode, 1);
4057 operands[3] = assign_386_stack_local (HImode, 2);
4058 if (memory_operand (operands[0], VOIDmode))
4059 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4060 operands[2], operands[3]));
4061 else
4062 {
4063 operands[4] = assign_386_stack_local (DImode, 0);
4064 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4065 operands[2], operands[3],
4066 operands[4]));
4067 }
4068 DONE;
4069 }
4070 [(set_attr "type" "fistp")
4071 (set_attr "mode" "DI")])
4072
4073 (define_insn "fix_truncdi_nomemory"
4074 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4075 (fix:DI (match_operand 1 "register_operand" "f,f")))
4076 (use (match_operand:HI 2 "memory_operand" "m,m"))
4077 (use (match_operand:HI 3 "memory_operand" "m,m"))
4078 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4079 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4080 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4081 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4082 "#"
4083 [(set_attr "type" "fistp")
4084 (set_attr "mode" "DI")])
4085
4086 (define_insn "fix_truncdi_memory"
4087 [(set (match_operand:DI 0 "memory_operand" "=m")
4088 (fix:DI (match_operand 1 "register_operand" "f")))
4089 (use (match_operand:HI 2 "memory_operand" "m"))
4090 (use (match_operand:HI 3 "memory_operand" "m"))
4091 (clobber (match_scratch:DF 4 "=&1f"))]
4092 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4093 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4094 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4095 [(set_attr "type" "fistp")
4096 (set_attr "mode" "DI")])
4097
4098 (define_split
4099 [(set (match_operand:DI 0 "register_operand" "")
4100 (fix:DI (match_operand 1 "register_operand" "")))
4101 (use (match_operand:HI 2 "memory_operand" ""))
4102 (use (match_operand:HI 3 "memory_operand" ""))
4103 (clobber (match_operand:DI 4 "memory_operand" ""))
4104 (clobber (match_scratch 5 ""))]
4105 "reload_completed"
4106 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4107 (use (match_dup 2))
4108 (use (match_dup 3))
4109 (clobber (match_dup 5))])
4110 (set (match_dup 0) (match_dup 4))]
4111 "")
4112
4113 (define_split
4114 [(set (match_operand:DI 0 "memory_operand" "")
4115 (fix:DI (match_operand 1 "register_operand" "")))
4116 (use (match_operand:HI 2 "memory_operand" ""))
4117 (use (match_operand:HI 3 "memory_operand" ""))
4118 (clobber (match_operand:DI 4 "memory_operand" ""))
4119 (clobber (match_scratch 5 ""))]
4120 "reload_completed"
4121 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4122 (use (match_dup 2))
4123 (use (match_dup 3))
4124 (clobber (match_dup 5))])]
4125 "")
4126
4127 ;; When SSE available, it is always faster to use it!
4128 (define_insn "fix_truncsfdi_sse"
4129 [(set (match_operand:DI 0 "register_operand" "=r,r")
4130 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4131 "TARGET_64BIT && TARGET_SSE"
4132 "cvttss2si{q}\t{%1, %0|%0, %1}"
4133 [(set_attr "type" "sseicvt")
4134 (set_attr "mode" "SF")
4135 (set_attr "athlon_decode" "double,vector")])
4136
4137 ;; Avoid vector decoded form of the instruction.
4138 (define_peephole2
4139 [(match_scratch:SF 2 "x")
4140 (set (match_operand:DI 0 "register_operand" "")
4141 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4142 "TARGET_K8 && !optimize_size"
4143 [(set (match_dup 2) (match_dup 1))
4144 (set (match_dup 0) (fix:DI (match_dup 2)))]
4145 "")
4146
4147 (define_insn "fix_truncdfdi_sse"
4148 [(set (match_operand:DI 0 "register_operand" "=r,r")
4149 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4150 "TARGET_64BIT && TARGET_SSE2"
4151 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4152 [(set_attr "type" "sseicvt,sseicvt")
4153 (set_attr "mode" "DF")
4154 (set_attr "athlon_decode" "double,vector")])
4155
4156 ;; Avoid vector decoded form of the instruction.
4157 (define_peephole2
4158 [(match_scratch:DF 2 "Y")
4159 (set (match_operand:DI 0 "register_operand" "")
4160 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4161 "TARGET_K8 && !optimize_size"
4162 [(set (match_dup 2) (match_dup 1))
4163 (set (match_dup 0) (fix:DI (match_dup 2)))]
4164 "")
4165
4166 ;; Signed conversion to SImode.
4167
4168 (define_expand "fix_truncxfsi2"
4169 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4170 (fix:SI (match_operand:XF 1 "register_operand" "")))
4171 (clobber (reg:CC 17))])]
4172 "TARGET_80387"
4173 "")
4174
4175 (define_expand "fix_truncdfsi2"
4176 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4177 (fix:SI (match_operand:DF 1 "register_operand" "")))
4178 (clobber (reg:CC 17))])]
4179 "TARGET_80387 || TARGET_SSE2"
4180 {
4181 if (TARGET_SSE2)
4182 {
4183 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4184 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4185 if (out != operands[0])
4186 emit_move_insn (operands[0], out);
4187 DONE;
4188 }
4189 })
4190
4191 (define_expand "fix_truncsfsi2"
4192 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4193 (fix:SI (match_operand:SF 1 "register_operand" "")))
4194 (clobber (reg:CC 17))])]
4195 "TARGET_80387 || TARGET_SSE"
4196 {
4197 if (TARGET_SSE)
4198 {
4199 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4200 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4201 if (out != operands[0])
4202 emit_move_insn (operands[0], out);
4203 DONE;
4204 }
4205 })
4206
4207 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4208 ;; of the machinery.
4209 (define_insn_and_split "*fix_truncsi_1"
4210 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4211 (fix:SI (match_operand 1 "register_operand" "f,f")))
4212 (clobber (reg:CC 17))]
4213 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4214 && !reload_completed && !reload_in_progress
4215 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4216 "#"
4217 "&& 1"
4218 [(const_int 0)]
4219 {
4220 ix86_optimize_mode_switching = 1;
4221 operands[2] = assign_386_stack_local (HImode, 1);
4222 operands[3] = assign_386_stack_local (HImode, 2);
4223 if (memory_operand (operands[0], VOIDmode))
4224 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4225 operands[2], operands[3]));
4226 else
4227 {
4228 operands[4] = assign_386_stack_local (SImode, 0);
4229 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4230 operands[2], operands[3],
4231 operands[4]));
4232 }
4233 DONE;
4234 }
4235 [(set_attr "type" "fistp")
4236 (set_attr "mode" "SI")])
4237
4238 (define_insn "fix_truncsi_nomemory"
4239 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4240 (fix:SI (match_operand 1 "register_operand" "f,f")))
4241 (use (match_operand:HI 2 "memory_operand" "m,m"))
4242 (use (match_operand:HI 3 "memory_operand" "m,m"))
4243 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4244 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4245 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4246 "#"
4247 [(set_attr "type" "fistp")
4248 (set_attr "mode" "SI")])
4249
4250 (define_insn "fix_truncsi_memory"
4251 [(set (match_operand:SI 0 "memory_operand" "=m")
4252 (fix:SI (match_operand 1 "register_operand" "f")))
4253 (use (match_operand:HI 2 "memory_operand" "m"))
4254 (use (match_operand:HI 3 "memory_operand" "m"))]
4255 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4256 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4257 "* return output_fix_trunc (insn, operands);"
4258 [(set_attr "type" "fistp")
4259 (set_attr "mode" "SI")])
4260
4261 ;; When SSE available, it is always faster to use it!
4262 (define_insn "fix_truncsfsi_sse"
4263 [(set (match_operand:SI 0 "register_operand" "=r,r")
4264 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4265 "TARGET_SSE"
4266 "cvttss2si\t{%1, %0|%0, %1}"
4267 [(set_attr "type" "sseicvt")
4268 (set_attr "mode" "DF")
4269 (set_attr "athlon_decode" "double,vector")])
4270
4271 ;; Avoid vector decoded form of the instruction.
4272 (define_peephole2
4273 [(match_scratch:SF 2 "x")
4274 (set (match_operand:SI 0 "register_operand" "")
4275 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4276 "TARGET_K8 && !optimize_size"
4277 [(set (match_dup 2) (match_dup 1))
4278 (set (match_dup 0) (fix:SI (match_dup 2)))]
4279 "")
4280
4281 (define_insn "fix_truncdfsi_sse"
4282 [(set (match_operand:SI 0 "register_operand" "=r,r")
4283 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4284 "TARGET_SSE2"
4285 "cvttsd2si\t{%1, %0|%0, %1}"
4286 [(set_attr "type" "sseicvt")
4287 (set_attr "mode" "DF")
4288 (set_attr "athlon_decode" "double,vector")])
4289
4290 ;; Avoid vector decoded form of the instruction.
4291 (define_peephole2
4292 [(match_scratch:DF 2 "Y")
4293 (set (match_operand:SI 0 "register_operand" "")
4294 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4295 "TARGET_K8 && !optimize_size"
4296 [(set (match_dup 2) (match_dup 1))
4297 (set (match_dup 0) (fix:SI (match_dup 2)))]
4298 "")
4299
4300 (define_split
4301 [(set (match_operand:SI 0 "register_operand" "")
4302 (fix:SI (match_operand 1 "register_operand" "")))
4303 (use (match_operand:HI 2 "memory_operand" ""))
4304 (use (match_operand:HI 3 "memory_operand" ""))
4305 (clobber (match_operand:SI 4 "memory_operand" ""))]
4306 "reload_completed"
4307 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4308 (use (match_dup 2))
4309 (use (match_dup 3))])
4310 (set (match_dup 0) (match_dup 4))]
4311 "")
4312
4313 (define_split
4314 [(set (match_operand:SI 0 "memory_operand" "")
4315 (fix:SI (match_operand 1 "register_operand" "")))
4316 (use (match_operand:HI 2 "memory_operand" ""))
4317 (use (match_operand:HI 3 "memory_operand" ""))
4318 (clobber (match_operand:SI 4 "memory_operand" ""))]
4319 "reload_completed"
4320 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4321 (use (match_dup 2))
4322 (use (match_dup 3))])]
4323 "")
4324
4325 ;; Signed conversion to HImode.
4326
4327 (define_expand "fix_truncxfhi2"
4328 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4329 (fix:HI (match_operand:XF 1 "register_operand" "")))
4330 (clobber (reg:CC 17))])]
4331 "TARGET_80387"
4332 "")
4333
4334 (define_expand "fix_truncdfhi2"
4335 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4336 (fix:HI (match_operand:DF 1 "register_operand" "")))
4337 (clobber (reg:CC 17))])]
4338 "TARGET_80387 && !TARGET_SSE2"
4339 "")
4340
4341 (define_expand "fix_truncsfhi2"
4342 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4343 (fix:HI (match_operand:SF 1 "register_operand" "")))
4344 (clobber (reg:CC 17))])]
4345 "TARGET_80387 && !TARGET_SSE"
4346 "")
4347
4348 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4349 ;; of the machinery.
4350 (define_insn_and_split "*fix_trunchi_1"
4351 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4352 (fix:HI (match_operand 1 "register_operand" "f,f")))
4353 (clobber (reg:CC 17))]
4354 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4355 && !reload_completed && !reload_in_progress
4356 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4357 "#"
4358 ""
4359 [(const_int 0)]
4360 {
4361 ix86_optimize_mode_switching = 1;
4362 operands[2] = assign_386_stack_local (HImode, 1);
4363 operands[3] = assign_386_stack_local (HImode, 2);
4364 if (memory_operand (operands[0], VOIDmode))
4365 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4366 operands[2], operands[3]));
4367 else
4368 {
4369 operands[4] = assign_386_stack_local (HImode, 0);
4370 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4371 operands[2], operands[3],
4372 operands[4]));
4373 }
4374 DONE;
4375 }
4376 [(set_attr "type" "fistp")
4377 (set_attr "mode" "HI")])
4378
4379 (define_insn "fix_trunchi_nomemory"
4380 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4381 (fix:HI (match_operand 1 "register_operand" "f,f")))
4382 (use (match_operand:HI 2 "memory_operand" "m,m"))
4383 (use (match_operand:HI 3 "memory_operand" "m,m"))
4384 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4385 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4386 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4387 "#"
4388 [(set_attr "type" "fistp")
4389 (set_attr "mode" "HI")])
4390
4391 (define_insn "fix_trunchi_memory"
4392 [(set (match_operand:HI 0 "memory_operand" "=m")
4393 (fix:HI (match_operand 1 "register_operand" "f")))
4394 (use (match_operand:HI 2 "memory_operand" "m"))
4395 (use (match_operand:HI 3 "memory_operand" "m"))]
4396 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4397 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4398 "* return output_fix_trunc (insn, operands);"
4399 [(set_attr "type" "fistp")
4400 (set_attr "mode" "HI")])
4401
4402 (define_split
4403 [(set (match_operand:HI 0 "memory_operand" "")
4404 (fix:HI (match_operand 1 "register_operand" "")))
4405 (use (match_operand:HI 2 "memory_operand" ""))
4406 (use (match_operand:HI 3 "memory_operand" ""))
4407 (clobber (match_operand:HI 4 "memory_operand" ""))]
4408 "reload_completed"
4409 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4410 (use (match_dup 2))
4411 (use (match_dup 3))])]
4412 "")
4413
4414 (define_split
4415 [(set (match_operand:HI 0 "register_operand" "")
4416 (fix:HI (match_operand 1 "register_operand" "")))
4417 (use (match_operand:HI 2 "memory_operand" ""))
4418 (use (match_operand:HI 3 "memory_operand" ""))
4419 (clobber (match_operand:HI 4 "memory_operand" ""))]
4420 "reload_completed"
4421 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4422 (use (match_dup 2))
4423 (use (match_dup 3))
4424 (clobber (match_dup 4))])
4425 (set (match_dup 0) (match_dup 4))]
4426 "")
4427
4428 ;; %% Not used yet.
4429 (define_insn "x86_fnstcw_1"
4430 [(set (match_operand:HI 0 "memory_operand" "=m")
4431 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4432 "TARGET_80387"
4433 "fnstcw\t%0"
4434 [(set_attr "length" "2")
4435 (set_attr "mode" "HI")
4436 (set_attr "unit" "i387")])
4437
4438 (define_insn "x86_fldcw_1"
4439 [(set (reg:HI 18)
4440 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4441 "TARGET_80387"
4442 "fldcw\t%0"
4443 [(set_attr "length" "2")
4444 (set_attr "mode" "HI")
4445 (set_attr "unit" "i387")
4446 (set_attr "athlon_decode" "vector")])
4447 \f
4448 ;; Conversion between fixed point and floating point.
4449
4450 ;; Even though we only accept memory inputs, the backend _really_
4451 ;; wants to be able to do this between registers.
4452
4453 (define_expand "floathisf2"
4454 [(set (match_operand:SF 0 "register_operand" "")
4455 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4456 "TARGET_SSE || TARGET_80387"
4457 {
4458 if (TARGET_SSE && TARGET_SSE_MATH)
4459 {
4460 emit_insn (gen_floatsisf2 (operands[0],
4461 convert_to_mode (SImode, operands[1], 0)));
4462 DONE;
4463 }
4464 })
4465
4466 (define_insn "*floathisf2_1"
4467 [(set (match_operand:SF 0 "register_operand" "=f,f")
4468 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4469 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4470 "@
4471 fild%z1\t%1
4472 #"
4473 [(set_attr "type" "fmov,multi")
4474 (set_attr "mode" "SF")
4475 (set_attr "fp_int_src" "true")])
4476
4477 (define_expand "floatsisf2"
4478 [(set (match_operand:SF 0 "register_operand" "")
4479 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4480 "TARGET_SSE || TARGET_80387"
4481 "")
4482
4483 (define_insn "*floatsisf2_i387"
4484 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4485 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4486 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4487 "@
4488 fild%z1\t%1
4489 #
4490 cvtsi2ss\t{%1, %0|%0, %1}
4491 cvtsi2ss\t{%1, %0|%0, %1}"
4492 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4493 (set_attr "mode" "SF")
4494 (set_attr "athlon_decode" "*,*,vector,double")
4495 (set_attr "fp_int_src" "true")])
4496
4497 (define_insn "*floatsisf2_sse"
4498 [(set (match_operand:SF 0 "register_operand" "=x,x")
4499 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4500 "TARGET_SSE"
4501 "cvtsi2ss\t{%1, %0|%0, %1}"
4502 [(set_attr "type" "sseicvt")
4503 (set_attr "mode" "SF")
4504 (set_attr "athlon_decode" "vector,double")
4505 (set_attr "fp_int_src" "true")])
4506
4507 ; Avoid possible reformatting penalty on the destination by first
4508 ; zeroing it out
4509 (define_split
4510 [(set (match_operand:SF 0 "register_operand" "")
4511 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4512 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4513 && SSE_REG_P (operands[0])"
4514 [(const_int 0)]
4515 {
4516 rtx dest;
4517 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4518 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4519 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4520 DONE;
4521 })
4522
4523 (define_expand "floatdisf2"
4524 [(set (match_operand:SF 0 "register_operand" "")
4525 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4526 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4527 "")
4528
4529 (define_insn "*floatdisf2_i387_only"
4530 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4531 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4532 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4533 "@
4534 fild%z1\t%1
4535 #"
4536 [(set_attr "type" "fmov,multi")
4537 (set_attr "mode" "SF")
4538 (set_attr "fp_int_src" "true")])
4539
4540 (define_insn "*floatdisf2_i387"
4541 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4542 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4543 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4544 "@
4545 fild%z1\t%1
4546 #
4547 cvtsi2ss{q}\t{%1, %0|%0, %1}
4548 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4549 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4550 (set_attr "mode" "SF")
4551 (set_attr "athlon_decode" "*,*,vector,double")
4552 (set_attr "fp_int_src" "true")])
4553
4554 (define_insn "*floatdisf2_sse"
4555 [(set (match_operand:SF 0 "register_operand" "=x,x")
4556 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4557 "TARGET_64BIT && TARGET_SSE"
4558 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4559 [(set_attr "type" "sseicvt")
4560 (set_attr "mode" "SF")
4561 (set_attr "athlon_decode" "vector,double")
4562 (set_attr "fp_int_src" "true")])
4563
4564 ; Avoid possible reformatting penalty on the destination by first
4565 ; zeroing it out
4566 (define_split
4567 [(set (match_operand:SF 0 "register_operand" "")
4568 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4569 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4570 && SSE_REG_P (operands[0])"
4571 [(const_int 0)]
4572 {
4573 rtx dest;
4574 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4575 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4576 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4577 DONE;
4578 })
4579
4580 (define_expand "floathidf2"
4581 [(set (match_operand:DF 0 "register_operand" "")
4582 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4583 "TARGET_SSE2 || TARGET_80387"
4584 {
4585 if (TARGET_SSE && TARGET_SSE_MATH)
4586 {
4587 emit_insn (gen_floatsidf2 (operands[0],
4588 convert_to_mode (SImode, operands[1], 0)));
4589 DONE;
4590 }
4591 })
4592
4593 (define_insn "*floathidf2_1"
4594 [(set (match_operand:DF 0 "register_operand" "=f,f")
4595 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4596 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4597 "@
4598 fild%z1\t%1
4599 #"
4600 [(set_attr "type" "fmov,multi")
4601 (set_attr "mode" "DF")
4602 (set_attr "fp_int_src" "true")])
4603
4604 (define_expand "floatsidf2"
4605 [(set (match_operand:DF 0 "register_operand" "")
4606 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4607 "TARGET_80387 || TARGET_SSE2"
4608 "")
4609
4610 (define_insn "*floatsidf2_i387"
4611 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4612 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4613 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4614 "@
4615 fild%z1\t%1
4616 #
4617 cvtsi2sd\t{%1, %0|%0, %1}
4618 cvtsi2sd\t{%1, %0|%0, %1}"
4619 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4620 (set_attr "mode" "DF")
4621 (set_attr "athlon_decode" "*,*,double,direct")
4622 (set_attr "fp_int_src" "true")])
4623
4624 (define_insn "*floatsidf2_sse"
4625 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4626 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4627 "TARGET_SSE2"
4628 "cvtsi2sd\t{%1, %0|%0, %1}"
4629 [(set_attr "type" "sseicvt")
4630 (set_attr "mode" "DF")
4631 (set_attr "athlon_decode" "double,direct")
4632 (set_attr "fp_int_src" "true")])
4633
4634 (define_expand "floatdidf2"
4635 [(set (match_operand:DF 0 "register_operand" "")
4636 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4637 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4638 "")
4639
4640 (define_insn "*floatdidf2_i387_only"
4641 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4642 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4643 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4644 "@
4645 fild%z1\t%1
4646 #"
4647 [(set_attr "type" "fmov,multi")
4648 (set_attr "mode" "DF")
4649 (set_attr "fp_int_src" "true")])
4650
4651 (define_insn "*floatdidf2_i387"
4652 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4653 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4654 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4655 "@
4656 fild%z1\t%1
4657 #
4658 cvtsi2sd{q}\t{%1, %0|%0, %1}
4659 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4660 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4661 (set_attr "mode" "DF")
4662 (set_attr "athlon_decode" "*,*,double,direct")
4663 (set_attr "fp_int_src" "true")])
4664
4665 (define_insn "*floatdidf2_sse"
4666 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4667 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4668 "TARGET_SSE2"
4669 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4670 [(set_attr "type" "sseicvt")
4671 (set_attr "mode" "DF")
4672 (set_attr "athlon_decode" "double,direct")
4673 (set_attr "fp_int_src" "true")])
4674
4675 (define_insn "floathixf2"
4676 [(set (match_operand:XF 0 "register_operand" "=f,f")
4677 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4678 "TARGET_80387"
4679 "@
4680 fild%z1\t%1
4681 #"
4682 [(set_attr "type" "fmov,multi")
4683 (set_attr "mode" "XF")
4684 (set_attr "fp_int_src" "true")])
4685
4686 (define_insn "floatsixf2"
4687 [(set (match_operand:XF 0 "register_operand" "=f,f")
4688 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4689 "TARGET_80387"
4690 "@
4691 fild%z1\t%1
4692 #"
4693 [(set_attr "type" "fmov,multi")
4694 (set_attr "mode" "XF")
4695 (set_attr "fp_int_src" "true")])
4696
4697 (define_insn "floatdixf2"
4698 [(set (match_operand:XF 0 "register_operand" "=f,f")
4699 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4700 "TARGET_80387"
4701 "@
4702 fild%z1\t%1
4703 #"
4704 [(set_attr "type" "fmov,multi")
4705 (set_attr "mode" "XF")
4706 (set_attr "fp_int_src" "true")])
4707
4708 ;; %%% Kill these when reload knows how to do it.
4709 (define_split
4710 [(set (match_operand 0 "fp_register_operand" "")
4711 (float (match_operand 1 "register_operand" "")))]
4712 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4713 [(const_int 0)]
4714 {
4715 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4716 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4717 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4718 ix86_free_from_memory (GET_MODE (operands[1]));
4719 DONE;
4720 })
4721
4722 (define_expand "floatunssisf2"
4723 [(use (match_operand:SF 0 "register_operand" ""))
4724 (use (match_operand:SI 1 "register_operand" ""))]
4725 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4726 "x86_emit_floatuns (operands); DONE;")
4727
4728 (define_expand "floatunsdisf2"
4729 [(use (match_operand:SF 0 "register_operand" ""))
4730 (use (match_operand:DI 1 "register_operand" ""))]
4731 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4732 "x86_emit_floatuns (operands); DONE;")
4733
4734 (define_expand "floatunsdidf2"
4735 [(use (match_operand:DF 0 "register_operand" ""))
4736 (use (match_operand:DI 1 "register_operand" ""))]
4737 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4738 "x86_emit_floatuns (operands); DONE;")
4739 \f
4740 ;; SSE extract/set expanders
4741
4742 (define_expand "vec_setv2df"
4743 [(match_operand:V2DF 0 "register_operand" "")
4744 (match_operand:DF 1 "register_operand" "")
4745 (match_operand 2 "const_int_operand" "")]
4746 "TARGET_SSE2"
4747 {
4748 switch (INTVAL (operands[2]))
4749 {
4750 case 0:
4751 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4752 simplify_gen_subreg (V2DFmode, operands[1],
4753 DFmode, 0)));
4754 break;
4755 case 1:
4756 {
4757 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4758
4759 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4760 }
4761 break;
4762 default:
4763 abort ();
4764 }
4765 DONE;
4766 })
4767
4768 (define_expand "vec_extractv2df"
4769 [(match_operand:DF 0 "register_operand" "")
4770 (match_operand:V2DF 1 "register_operand" "")
4771 (match_operand 2 "const_int_operand" "")]
4772 "TARGET_SSE2"
4773 {
4774 switch (INTVAL (operands[2]))
4775 {
4776 case 0:
4777 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4778 break;
4779 case 1:
4780 {
4781 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4782
4783 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4784 }
4785 break;
4786 default:
4787 abort ();
4788 }
4789 DONE;
4790 })
4791
4792 (define_expand "vec_initv2df"
4793 [(match_operand:V2DF 0 "register_operand" "")
4794 (match_operand 1 "" "")]
4795 "TARGET_SSE2"
4796 {
4797 ix86_expand_vector_init (operands[0], operands[1]);
4798 DONE;
4799 })
4800
4801 (define_expand "vec_setv4sf"
4802 [(match_operand:V4SF 0 "register_operand" "")
4803 (match_operand:SF 1 "register_operand" "")
4804 (match_operand 2 "const_int_operand" "")]
4805 "TARGET_SSE"
4806 {
4807 switch (INTVAL (operands[2]))
4808 {
4809 case 0:
4810 emit_insn (gen_sse_movss (operands[0], operands[0],
4811 simplify_gen_subreg (V4SFmode, operands[1],
4812 SFmode, 0)));
4813 break;
4814 case 1:
4815 {
4816 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4817 rtx tmp = gen_reg_rtx (V4SFmode);
4818
4819 emit_move_insn (tmp, operands[0]);
4820 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4821 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4822 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4823 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4824 }
4825 case 2:
4826 {
4827 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4828 rtx tmp = gen_reg_rtx (V4SFmode);
4829
4830 emit_move_insn (tmp, operands[0]);
4831 emit_insn (gen_sse_movss (tmp, tmp, op1));
4832 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4833 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4834 }
4835 break;
4836 case 3:
4837 {
4838 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4839 rtx tmp = gen_reg_rtx (V4SFmode);
4840
4841 emit_move_insn (tmp, operands[0]);
4842 emit_insn (gen_sse_movss (tmp, tmp, op1));
4843 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4844 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4845 }
4846 break;
4847 default:
4848 abort ();
4849 }
4850 DONE;
4851 })
4852
4853 (define_expand "vec_extractv4sf"
4854 [(match_operand:SF 0 "register_operand" "")
4855 (match_operand:V4SF 1 "register_operand" "")
4856 (match_operand 2 "const_int_operand" "")]
4857 "TARGET_SSE"
4858 {
4859 switch (INTVAL (operands[2]))
4860 {
4861 case 0:
4862 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4863 break;
4864 case 1:
4865 {
4866 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4867 rtx tmp = gen_reg_rtx (V4SFmode);
4868
4869 emit_move_insn (tmp, operands[1]);
4870 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4871 const1_rtx));
4872 }
4873 case 2:
4874 {
4875 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4876 rtx tmp = gen_reg_rtx (V4SFmode);
4877
4878 emit_move_insn (tmp, operands[1]);
4879 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4880 }
4881 case 3:
4882 {
4883 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4884 rtx tmp = gen_reg_rtx (V4SFmode);
4885
4886 emit_move_insn (tmp, operands[1]);
4887 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4888 GEN_INT (3)));
4889 }
4890 default:
4891 abort ();
4892 }
4893 DONE;
4894 })
4895
4896 (define_expand "vec_initv4sf"
4897 [(match_operand:V4SF 0 "register_operand" "")
4898 (match_operand 1 "" "")]
4899 "TARGET_SSE"
4900 {
4901 ix86_expand_vector_init (operands[0], operands[1]);
4902 DONE;
4903 })
4904 \f
4905 ;; Add instructions
4906
4907 ;; %%% splits for addsidi3
4908 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4909 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4910 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4911
4912 (define_expand "adddi3"
4913 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4914 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4915 (match_operand:DI 2 "x86_64_general_operand" "")))
4916 (clobber (reg:CC 17))]
4917 ""
4918 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4919
4920 (define_insn "*adddi3_1"
4921 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4922 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4923 (match_operand:DI 2 "general_operand" "roiF,riF")))
4924 (clobber (reg:CC 17))]
4925 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4926 "#")
4927
4928 (define_split
4929 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4930 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4931 (match_operand:DI 2 "general_operand" "")))
4932 (clobber (reg:CC 17))]
4933 "!TARGET_64BIT && reload_completed"
4934 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4935 UNSPEC_ADD_CARRY))
4936 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4937 (parallel [(set (match_dup 3)
4938 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4939 (match_dup 4))
4940 (match_dup 5)))
4941 (clobber (reg:CC 17))])]
4942 "split_di (operands+0, 1, operands+0, operands+3);
4943 split_di (operands+1, 1, operands+1, operands+4);
4944 split_di (operands+2, 1, operands+2, operands+5);")
4945
4946 (define_insn "adddi3_carry_rex64"
4947 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4948 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4949 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4950 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4951 (clobber (reg:CC 17))]
4952 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4953 "adc{q}\t{%2, %0|%0, %2}"
4954 [(set_attr "type" "alu")
4955 (set_attr "pent_pair" "pu")
4956 (set_attr "mode" "DI")])
4957
4958 (define_insn "*adddi3_cc_rex64"
4959 [(set (reg:CC 17)
4960 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4961 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4962 UNSPEC_ADD_CARRY))
4963 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4964 (plus:DI (match_dup 1) (match_dup 2)))]
4965 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4966 "add{q}\t{%2, %0|%0, %2}"
4967 [(set_attr "type" "alu")
4968 (set_attr "mode" "DI")])
4969
4970 (define_insn "addqi3_carry"
4971 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4972 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4973 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4974 (match_operand:QI 2 "general_operand" "qi,qm")))
4975 (clobber (reg:CC 17))]
4976 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4977 "adc{b}\t{%2, %0|%0, %2}"
4978 [(set_attr "type" "alu")
4979 (set_attr "pent_pair" "pu")
4980 (set_attr "mode" "QI")])
4981
4982 (define_insn "addhi3_carry"
4983 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4984 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4985 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4986 (match_operand:HI 2 "general_operand" "ri,rm")))
4987 (clobber (reg:CC 17))]
4988 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4989 "adc{w}\t{%2, %0|%0, %2}"
4990 [(set_attr "type" "alu")
4991 (set_attr "pent_pair" "pu")
4992 (set_attr "mode" "HI")])
4993
4994 (define_insn "addsi3_carry"
4995 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4996 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4997 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4998 (match_operand:SI 2 "general_operand" "ri,rm")))
4999 (clobber (reg:CC 17))]
5000 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5001 "adc{l}\t{%2, %0|%0, %2}"
5002 [(set_attr "type" "alu")
5003 (set_attr "pent_pair" "pu")
5004 (set_attr "mode" "SI")])
5005
5006 (define_insn "*addsi3_carry_zext"
5007 [(set (match_operand:DI 0 "register_operand" "=r")
5008 (zero_extend:DI
5009 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5010 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5011 (match_operand:SI 2 "general_operand" "rim"))))
5012 (clobber (reg:CC 17))]
5013 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5014 "adc{l}\t{%2, %k0|%k0, %2}"
5015 [(set_attr "type" "alu")
5016 (set_attr "pent_pair" "pu")
5017 (set_attr "mode" "SI")])
5018
5019 (define_insn "*addsi3_cc"
5020 [(set (reg:CC 17)
5021 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5022 (match_operand:SI 2 "general_operand" "ri,rm")]
5023 UNSPEC_ADD_CARRY))
5024 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5025 (plus:SI (match_dup 1) (match_dup 2)))]
5026 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5027 "add{l}\t{%2, %0|%0, %2}"
5028 [(set_attr "type" "alu")
5029 (set_attr "mode" "SI")])
5030
5031 (define_insn "addqi3_cc"
5032 [(set (reg:CC 17)
5033 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5034 (match_operand:QI 2 "general_operand" "qi,qm")]
5035 UNSPEC_ADD_CARRY))
5036 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5037 (plus:QI (match_dup 1) (match_dup 2)))]
5038 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5039 "add{b}\t{%2, %0|%0, %2}"
5040 [(set_attr "type" "alu")
5041 (set_attr "mode" "QI")])
5042
5043 (define_expand "addsi3"
5044 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5045 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5046 (match_operand:SI 2 "general_operand" "")))
5047 (clobber (reg:CC 17))])]
5048 ""
5049 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5050
5051 (define_insn "*lea_1"
5052 [(set (match_operand:SI 0 "register_operand" "=r")
5053 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5054 "!TARGET_64BIT"
5055 "lea{l}\t{%a1, %0|%0, %a1}"
5056 [(set_attr "type" "lea")
5057 (set_attr "mode" "SI")])
5058
5059 (define_insn "*lea_1_rex64"
5060 [(set (match_operand:SI 0 "register_operand" "=r")
5061 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5062 "TARGET_64BIT"
5063 "lea{l}\t{%a1, %0|%0, %a1}"
5064 [(set_attr "type" "lea")
5065 (set_attr "mode" "SI")])
5066
5067 (define_insn "*lea_1_zext"
5068 [(set (match_operand:DI 0 "register_operand" "=r")
5069 (zero_extend:DI
5070 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5071 "TARGET_64BIT"
5072 "lea{l}\t{%a1, %k0|%k0, %a1}"
5073 [(set_attr "type" "lea")
5074 (set_attr "mode" "SI")])
5075
5076 (define_insn "*lea_2_rex64"
5077 [(set (match_operand:DI 0 "register_operand" "=r")
5078 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5079 "TARGET_64BIT"
5080 "lea{q}\t{%a1, %0|%0, %a1}"
5081 [(set_attr "type" "lea")
5082 (set_attr "mode" "DI")])
5083
5084 ;; The lea patterns for non-Pmodes needs to be matched by several
5085 ;; insns converted to real lea by splitters.
5086
5087 (define_insn_and_split "*lea_general_1"
5088 [(set (match_operand 0 "register_operand" "=r")
5089 (plus (plus (match_operand 1 "index_register_operand" "r")
5090 (match_operand 2 "register_operand" "r"))
5091 (match_operand 3 "immediate_operand" "i")))]
5092 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5093 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5094 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5095 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5096 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5097 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5098 || GET_MODE (operands[3]) == VOIDmode)"
5099 "#"
5100 "&& reload_completed"
5101 [(const_int 0)]
5102 {
5103 rtx pat;
5104 operands[0] = gen_lowpart (SImode, operands[0]);
5105 operands[1] = gen_lowpart (Pmode, operands[1]);
5106 operands[2] = gen_lowpart (Pmode, operands[2]);
5107 operands[3] = gen_lowpart (Pmode, operands[3]);
5108 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5109 operands[3]);
5110 if (Pmode != SImode)
5111 pat = gen_rtx_SUBREG (SImode, pat, 0);
5112 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5113 DONE;
5114 }
5115 [(set_attr "type" "lea")
5116 (set_attr "mode" "SI")])
5117
5118 (define_insn_and_split "*lea_general_1_zext"
5119 [(set (match_operand:DI 0 "register_operand" "=r")
5120 (zero_extend:DI
5121 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5122 (match_operand:SI 2 "register_operand" "r"))
5123 (match_operand:SI 3 "immediate_operand" "i"))))]
5124 "TARGET_64BIT"
5125 "#"
5126 "&& reload_completed"
5127 [(set (match_dup 0)
5128 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5129 (match_dup 2))
5130 (match_dup 3)) 0)))]
5131 {
5132 operands[1] = gen_lowpart (Pmode, operands[1]);
5133 operands[2] = gen_lowpart (Pmode, operands[2]);
5134 operands[3] = gen_lowpart (Pmode, operands[3]);
5135 }
5136 [(set_attr "type" "lea")
5137 (set_attr "mode" "SI")])
5138
5139 (define_insn_and_split "*lea_general_2"
5140 [(set (match_operand 0 "register_operand" "=r")
5141 (plus (mult (match_operand 1 "index_register_operand" "r")
5142 (match_operand 2 "const248_operand" "i"))
5143 (match_operand 3 "nonmemory_operand" "ri")))]
5144 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5145 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5146 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5147 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5148 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5149 || GET_MODE (operands[3]) == VOIDmode)"
5150 "#"
5151 "&& reload_completed"
5152 [(const_int 0)]
5153 {
5154 rtx pat;
5155 operands[0] = gen_lowpart (SImode, operands[0]);
5156 operands[1] = gen_lowpart (Pmode, operands[1]);
5157 operands[3] = gen_lowpart (Pmode, operands[3]);
5158 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5159 operands[3]);
5160 if (Pmode != SImode)
5161 pat = gen_rtx_SUBREG (SImode, pat, 0);
5162 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5163 DONE;
5164 }
5165 [(set_attr "type" "lea")
5166 (set_attr "mode" "SI")])
5167
5168 (define_insn_and_split "*lea_general_2_zext"
5169 [(set (match_operand:DI 0 "register_operand" "=r")
5170 (zero_extend:DI
5171 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5172 (match_operand:SI 2 "const248_operand" "n"))
5173 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5174 "TARGET_64BIT"
5175 "#"
5176 "&& reload_completed"
5177 [(set (match_dup 0)
5178 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5179 (match_dup 2))
5180 (match_dup 3)) 0)))]
5181 {
5182 operands[1] = gen_lowpart (Pmode, operands[1]);
5183 operands[3] = gen_lowpart (Pmode, operands[3]);
5184 }
5185 [(set_attr "type" "lea")
5186 (set_attr "mode" "SI")])
5187
5188 (define_insn_and_split "*lea_general_3"
5189 [(set (match_operand 0 "register_operand" "=r")
5190 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5191 (match_operand 2 "const248_operand" "i"))
5192 (match_operand 3 "register_operand" "r"))
5193 (match_operand 4 "immediate_operand" "i")))]
5194 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5195 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5196 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5197 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5198 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5199 "#"
5200 "&& reload_completed"
5201 [(const_int 0)]
5202 {
5203 rtx pat;
5204 operands[0] = gen_lowpart (SImode, operands[0]);
5205 operands[1] = gen_lowpart (Pmode, operands[1]);
5206 operands[3] = gen_lowpart (Pmode, operands[3]);
5207 operands[4] = gen_lowpart (Pmode, operands[4]);
5208 pat = gen_rtx_PLUS (Pmode,
5209 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5210 operands[2]),
5211 operands[3]),
5212 operands[4]);
5213 if (Pmode != SImode)
5214 pat = gen_rtx_SUBREG (SImode, pat, 0);
5215 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5216 DONE;
5217 }
5218 [(set_attr "type" "lea")
5219 (set_attr "mode" "SI")])
5220
5221 (define_insn_and_split "*lea_general_3_zext"
5222 [(set (match_operand:DI 0 "register_operand" "=r")
5223 (zero_extend:DI
5224 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5225 (match_operand:SI 2 "const248_operand" "n"))
5226 (match_operand:SI 3 "register_operand" "r"))
5227 (match_operand:SI 4 "immediate_operand" "i"))))]
5228 "TARGET_64BIT"
5229 "#"
5230 "&& reload_completed"
5231 [(set (match_dup 0)
5232 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5233 (match_dup 2))
5234 (match_dup 3))
5235 (match_dup 4)) 0)))]
5236 {
5237 operands[1] = gen_lowpart (Pmode, operands[1]);
5238 operands[3] = gen_lowpart (Pmode, operands[3]);
5239 operands[4] = gen_lowpart (Pmode, operands[4]);
5240 }
5241 [(set_attr "type" "lea")
5242 (set_attr "mode" "SI")])
5243
5244 (define_insn "*adddi_1_rex64"
5245 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5246 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5247 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5248 (clobber (reg:CC 17))]
5249 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5250 {
5251 switch (get_attr_type (insn))
5252 {
5253 case TYPE_LEA:
5254 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5255 return "lea{q}\t{%a2, %0|%0, %a2}";
5256
5257 case TYPE_INCDEC:
5258 if (! rtx_equal_p (operands[0], operands[1]))
5259 abort ();
5260 if (operands[2] == const1_rtx)
5261 return "inc{q}\t%0";
5262 else if (operands[2] == constm1_rtx)
5263 return "dec{q}\t%0";
5264 else
5265 abort ();
5266
5267 default:
5268 if (! rtx_equal_p (operands[0], operands[1]))
5269 abort ();
5270
5271 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5272 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5273 if (GET_CODE (operands[2]) == CONST_INT
5274 /* Avoid overflows. */
5275 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5276 && (INTVAL (operands[2]) == 128
5277 || (INTVAL (operands[2]) < 0
5278 && INTVAL (operands[2]) != -128)))
5279 {
5280 operands[2] = GEN_INT (-INTVAL (operands[2]));
5281 return "sub{q}\t{%2, %0|%0, %2}";
5282 }
5283 return "add{q}\t{%2, %0|%0, %2}";
5284 }
5285 }
5286 [(set (attr "type")
5287 (cond [(eq_attr "alternative" "2")
5288 (const_string "lea")
5289 ; Current assemblers are broken and do not allow @GOTOFF in
5290 ; ought but a memory context.
5291 (match_operand:DI 2 "pic_symbolic_operand" "")
5292 (const_string "lea")
5293 (match_operand:DI 2 "incdec_operand" "")
5294 (const_string "incdec")
5295 ]
5296 (const_string "alu")))
5297 (set_attr "mode" "DI")])
5298
5299 ;; Convert lea to the lea pattern to avoid flags dependency.
5300 (define_split
5301 [(set (match_operand:DI 0 "register_operand" "")
5302 (plus:DI (match_operand:DI 1 "register_operand" "")
5303 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5304 (clobber (reg:CC 17))]
5305 "TARGET_64BIT && reload_completed
5306 && true_regnum (operands[0]) != true_regnum (operands[1])"
5307 [(set (match_dup 0)
5308 (plus:DI (match_dup 1)
5309 (match_dup 2)))]
5310 "")
5311
5312 (define_insn "*adddi_2_rex64"
5313 [(set (reg 17)
5314 (compare
5315 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5316 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5317 (const_int 0)))
5318 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5319 (plus:DI (match_dup 1) (match_dup 2)))]
5320 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5321 && ix86_binary_operator_ok (PLUS, DImode, operands)
5322 /* Current assemblers are broken and do not allow @GOTOFF in
5323 ought but a memory context. */
5324 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5325 {
5326 switch (get_attr_type (insn))
5327 {
5328 case TYPE_INCDEC:
5329 if (! rtx_equal_p (operands[0], operands[1]))
5330 abort ();
5331 if (operands[2] == const1_rtx)
5332 return "inc{q}\t%0";
5333 else if (operands[2] == constm1_rtx)
5334 return "dec{q}\t%0";
5335 else
5336 abort ();
5337
5338 default:
5339 if (! rtx_equal_p (operands[0], operands[1]))
5340 abort ();
5341 /* ???? We ought to handle there the 32bit case too
5342 - do we need new constraint? */
5343 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5344 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5345 if (GET_CODE (operands[2]) == CONST_INT
5346 /* Avoid overflows. */
5347 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5348 && (INTVAL (operands[2]) == 128
5349 || (INTVAL (operands[2]) < 0
5350 && INTVAL (operands[2]) != -128)))
5351 {
5352 operands[2] = GEN_INT (-INTVAL (operands[2]));
5353 return "sub{q}\t{%2, %0|%0, %2}";
5354 }
5355 return "add{q}\t{%2, %0|%0, %2}";
5356 }
5357 }
5358 [(set (attr "type")
5359 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5360 (const_string "incdec")
5361 (const_string "alu")))
5362 (set_attr "mode" "DI")])
5363
5364 (define_insn "*adddi_3_rex64"
5365 [(set (reg 17)
5366 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5367 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5368 (clobber (match_scratch:DI 0 "=r"))]
5369 "TARGET_64BIT
5370 && ix86_match_ccmode (insn, CCZmode)
5371 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5372 /* Current assemblers are broken and do not allow @GOTOFF in
5373 ought but a memory context. */
5374 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5375 {
5376 switch (get_attr_type (insn))
5377 {
5378 case TYPE_INCDEC:
5379 if (! rtx_equal_p (operands[0], operands[1]))
5380 abort ();
5381 if (operands[2] == const1_rtx)
5382 return "inc{q}\t%0";
5383 else if (operands[2] == constm1_rtx)
5384 return "dec{q}\t%0";
5385 else
5386 abort ();
5387
5388 default:
5389 if (! rtx_equal_p (operands[0], operands[1]))
5390 abort ();
5391 /* ???? We ought to handle there the 32bit case too
5392 - do we need new constraint? */
5393 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5394 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5395 if (GET_CODE (operands[2]) == CONST_INT
5396 /* Avoid overflows. */
5397 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5398 && (INTVAL (operands[2]) == 128
5399 || (INTVAL (operands[2]) < 0
5400 && INTVAL (operands[2]) != -128)))
5401 {
5402 operands[2] = GEN_INT (-INTVAL (operands[2]));
5403 return "sub{q}\t{%2, %0|%0, %2}";
5404 }
5405 return "add{q}\t{%2, %0|%0, %2}";
5406 }
5407 }
5408 [(set (attr "type")
5409 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5410 (const_string "incdec")
5411 (const_string "alu")))
5412 (set_attr "mode" "DI")])
5413
5414 ; For comparisons against 1, -1 and 128, we may generate better code
5415 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5416 ; is matched then. We can't accept general immediate, because for
5417 ; case of overflows, the result is messed up.
5418 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5419 ; when negated.
5420 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5421 ; only for comparisons not depending on it.
5422 (define_insn "*adddi_4_rex64"
5423 [(set (reg 17)
5424 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5425 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5426 (clobber (match_scratch:DI 0 "=rm"))]
5427 "TARGET_64BIT
5428 && ix86_match_ccmode (insn, CCGCmode)"
5429 {
5430 switch (get_attr_type (insn))
5431 {
5432 case TYPE_INCDEC:
5433 if (operands[2] == constm1_rtx)
5434 return "inc{q}\t%0";
5435 else if (operands[2] == const1_rtx)
5436 return "dec{q}\t%0";
5437 else
5438 abort();
5439
5440 default:
5441 if (! rtx_equal_p (operands[0], operands[1]))
5442 abort ();
5443 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5444 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5445 if ((INTVAL (operands[2]) == -128
5446 || (INTVAL (operands[2]) > 0
5447 && INTVAL (operands[2]) != 128))
5448 /* Avoid overflows. */
5449 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5450 return "sub{q}\t{%2, %0|%0, %2}";
5451 operands[2] = GEN_INT (-INTVAL (operands[2]));
5452 return "add{q}\t{%2, %0|%0, %2}";
5453 }
5454 }
5455 [(set (attr "type")
5456 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5457 (const_string "incdec")
5458 (const_string "alu")))
5459 (set_attr "mode" "DI")])
5460
5461 (define_insn "*adddi_5_rex64"
5462 [(set (reg 17)
5463 (compare
5464 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5465 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5466 (const_int 0)))
5467 (clobber (match_scratch:DI 0 "=r"))]
5468 "TARGET_64BIT
5469 && ix86_match_ccmode (insn, CCGOCmode)
5470 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5471 /* Current assemblers are broken and do not allow @GOTOFF in
5472 ought but a memory context. */
5473 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5474 {
5475 switch (get_attr_type (insn))
5476 {
5477 case TYPE_INCDEC:
5478 if (! rtx_equal_p (operands[0], operands[1]))
5479 abort ();
5480 if (operands[2] == const1_rtx)
5481 return "inc{q}\t%0";
5482 else if (operands[2] == constm1_rtx)
5483 return "dec{q}\t%0";
5484 else
5485 abort();
5486
5487 default:
5488 if (! rtx_equal_p (operands[0], operands[1]))
5489 abort ();
5490 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5491 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5492 if (GET_CODE (operands[2]) == CONST_INT
5493 /* Avoid overflows. */
5494 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5495 && (INTVAL (operands[2]) == 128
5496 || (INTVAL (operands[2]) < 0
5497 && INTVAL (operands[2]) != -128)))
5498 {
5499 operands[2] = GEN_INT (-INTVAL (operands[2]));
5500 return "sub{q}\t{%2, %0|%0, %2}";
5501 }
5502 return "add{q}\t{%2, %0|%0, %2}";
5503 }
5504 }
5505 [(set (attr "type")
5506 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5507 (const_string "incdec")
5508 (const_string "alu")))
5509 (set_attr "mode" "DI")])
5510
5511
5512 (define_insn "*addsi_1"
5513 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5514 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5515 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5516 (clobber (reg:CC 17))]
5517 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5518 {
5519 switch (get_attr_type (insn))
5520 {
5521 case TYPE_LEA:
5522 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5523 return "lea{l}\t{%a2, %0|%0, %a2}";
5524
5525 case TYPE_INCDEC:
5526 if (! rtx_equal_p (operands[0], operands[1]))
5527 abort ();
5528 if (operands[2] == const1_rtx)
5529 return "inc{l}\t%0";
5530 else if (operands[2] == constm1_rtx)
5531 return "dec{l}\t%0";
5532 else
5533 abort();
5534
5535 default:
5536 if (! rtx_equal_p (operands[0], operands[1]))
5537 abort ();
5538
5539 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5540 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5541 if (GET_CODE (operands[2]) == CONST_INT
5542 && (INTVAL (operands[2]) == 128
5543 || (INTVAL (operands[2]) < 0
5544 && INTVAL (operands[2]) != -128)))
5545 {
5546 operands[2] = GEN_INT (-INTVAL (operands[2]));
5547 return "sub{l}\t{%2, %0|%0, %2}";
5548 }
5549 return "add{l}\t{%2, %0|%0, %2}";
5550 }
5551 }
5552 [(set (attr "type")
5553 (cond [(eq_attr "alternative" "2")
5554 (const_string "lea")
5555 ; Current assemblers are broken and do not allow @GOTOFF in
5556 ; ought but a memory context.
5557 (match_operand:SI 2 "pic_symbolic_operand" "")
5558 (const_string "lea")
5559 (match_operand:SI 2 "incdec_operand" "")
5560 (const_string "incdec")
5561 ]
5562 (const_string "alu")))
5563 (set_attr "mode" "SI")])
5564
5565 ;; Convert lea to the lea pattern to avoid flags dependency.
5566 (define_split
5567 [(set (match_operand 0 "register_operand" "")
5568 (plus (match_operand 1 "register_operand" "")
5569 (match_operand 2 "nonmemory_operand" "")))
5570 (clobber (reg:CC 17))]
5571 "reload_completed
5572 && true_regnum (operands[0]) != true_regnum (operands[1])"
5573 [(const_int 0)]
5574 {
5575 rtx pat;
5576 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5577 may confuse gen_lowpart. */
5578 if (GET_MODE (operands[0]) != Pmode)
5579 {
5580 operands[1] = gen_lowpart (Pmode, operands[1]);
5581 operands[2] = gen_lowpart (Pmode, operands[2]);
5582 }
5583 operands[0] = gen_lowpart (SImode, operands[0]);
5584 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5585 if (Pmode != SImode)
5586 pat = gen_rtx_SUBREG (SImode, pat, 0);
5587 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5588 DONE;
5589 })
5590
5591 ;; It may seem that nonimmediate operand is proper one for operand 1.
5592 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5593 ;; we take care in ix86_binary_operator_ok to not allow two memory
5594 ;; operands so proper swapping will be done in reload. This allow
5595 ;; patterns constructed from addsi_1 to match.
5596 (define_insn "addsi_1_zext"
5597 [(set (match_operand:DI 0 "register_operand" "=r,r")
5598 (zero_extend:DI
5599 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5600 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5601 (clobber (reg:CC 17))]
5602 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5603 {
5604 switch (get_attr_type (insn))
5605 {
5606 case TYPE_LEA:
5607 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5608 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5609
5610 case TYPE_INCDEC:
5611 if (operands[2] == const1_rtx)
5612 return "inc{l}\t%k0";
5613 else if (operands[2] == constm1_rtx)
5614 return "dec{l}\t%k0";
5615 else
5616 abort();
5617
5618 default:
5619 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5620 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5621 if (GET_CODE (operands[2]) == CONST_INT
5622 && (INTVAL (operands[2]) == 128
5623 || (INTVAL (operands[2]) < 0
5624 && INTVAL (operands[2]) != -128)))
5625 {
5626 operands[2] = GEN_INT (-INTVAL (operands[2]));
5627 return "sub{l}\t{%2, %k0|%k0, %2}";
5628 }
5629 return "add{l}\t{%2, %k0|%k0, %2}";
5630 }
5631 }
5632 [(set (attr "type")
5633 (cond [(eq_attr "alternative" "1")
5634 (const_string "lea")
5635 ; Current assemblers are broken and do not allow @GOTOFF in
5636 ; ought but a memory context.
5637 (match_operand:SI 2 "pic_symbolic_operand" "")
5638 (const_string "lea")
5639 (match_operand:SI 2 "incdec_operand" "")
5640 (const_string "incdec")
5641 ]
5642 (const_string "alu")))
5643 (set_attr "mode" "SI")])
5644
5645 ;; Convert lea to the lea pattern to avoid flags dependency.
5646 (define_split
5647 [(set (match_operand:DI 0 "register_operand" "")
5648 (zero_extend:DI
5649 (plus:SI (match_operand:SI 1 "register_operand" "")
5650 (match_operand:SI 2 "nonmemory_operand" ""))))
5651 (clobber (reg:CC 17))]
5652 "TARGET_64BIT && reload_completed
5653 && true_regnum (operands[0]) != true_regnum (operands[1])"
5654 [(set (match_dup 0)
5655 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5656 {
5657 operands[1] = gen_lowpart (Pmode, operands[1]);
5658 operands[2] = gen_lowpart (Pmode, operands[2]);
5659 })
5660
5661 (define_insn "*addsi_2"
5662 [(set (reg 17)
5663 (compare
5664 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5665 (match_operand:SI 2 "general_operand" "rmni,rni"))
5666 (const_int 0)))
5667 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5668 (plus:SI (match_dup 1) (match_dup 2)))]
5669 "ix86_match_ccmode (insn, CCGOCmode)
5670 && ix86_binary_operator_ok (PLUS, SImode, operands)
5671 /* Current assemblers are broken and do not allow @GOTOFF in
5672 ought but a memory context. */
5673 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5674 {
5675 switch (get_attr_type (insn))
5676 {
5677 case TYPE_INCDEC:
5678 if (! rtx_equal_p (operands[0], operands[1]))
5679 abort ();
5680 if (operands[2] == const1_rtx)
5681 return "inc{l}\t%0";
5682 else if (operands[2] == constm1_rtx)
5683 return "dec{l}\t%0";
5684 else
5685 abort();
5686
5687 default:
5688 if (! rtx_equal_p (operands[0], operands[1]))
5689 abort ();
5690 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5691 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5692 if (GET_CODE (operands[2]) == CONST_INT
5693 && (INTVAL (operands[2]) == 128
5694 || (INTVAL (operands[2]) < 0
5695 && INTVAL (operands[2]) != -128)))
5696 {
5697 operands[2] = GEN_INT (-INTVAL (operands[2]));
5698 return "sub{l}\t{%2, %0|%0, %2}";
5699 }
5700 return "add{l}\t{%2, %0|%0, %2}";
5701 }
5702 }
5703 [(set (attr "type")
5704 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5705 (const_string "incdec")
5706 (const_string "alu")))
5707 (set_attr "mode" "SI")])
5708
5709 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5710 (define_insn "*addsi_2_zext"
5711 [(set (reg 17)
5712 (compare
5713 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5714 (match_operand:SI 2 "general_operand" "rmni"))
5715 (const_int 0)))
5716 (set (match_operand:DI 0 "register_operand" "=r")
5717 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5718 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5719 && ix86_binary_operator_ok (PLUS, SImode, operands)
5720 /* Current assemblers are broken and do not allow @GOTOFF in
5721 ought but a memory context. */
5722 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5723 {
5724 switch (get_attr_type (insn))
5725 {
5726 case TYPE_INCDEC:
5727 if (operands[2] == const1_rtx)
5728 return "inc{l}\t%k0";
5729 else if (operands[2] == constm1_rtx)
5730 return "dec{l}\t%k0";
5731 else
5732 abort();
5733
5734 default:
5735 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5736 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5737 if (GET_CODE (operands[2]) == CONST_INT
5738 && (INTVAL (operands[2]) == 128
5739 || (INTVAL (operands[2]) < 0
5740 && INTVAL (operands[2]) != -128)))
5741 {
5742 operands[2] = GEN_INT (-INTVAL (operands[2]));
5743 return "sub{l}\t{%2, %k0|%k0, %2}";
5744 }
5745 return "add{l}\t{%2, %k0|%k0, %2}";
5746 }
5747 }
5748 [(set (attr "type")
5749 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5750 (const_string "incdec")
5751 (const_string "alu")))
5752 (set_attr "mode" "SI")])
5753
5754 (define_insn "*addsi_3"
5755 [(set (reg 17)
5756 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5757 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5758 (clobber (match_scratch:SI 0 "=r"))]
5759 "ix86_match_ccmode (insn, CCZmode)
5760 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5761 /* Current assemblers are broken and do not allow @GOTOFF in
5762 ought but a memory context. */
5763 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5764 {
5765 switch (get_attr_type (insn))
5766 {
5767 case TYPE_INCDEC:
5768 if (! rtx_equal_p (operands[0], operands[1]))
5769 abort ();
5770 if (operands[2] == const1_rtx)
5771 return "inc{l}\t%0";
5772 else if (operands[2] == constm1_rtx)
5773 return "dec{l}\t%0";
5774 else
5775 abort();
5776
5777 default:
5778 if (! rtx_equal_p (operands[0], operands[1]))
5779 abort ();
5780 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5781 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5782 if (GET_CODE (operands[2]) == CONST_INT
5783 && (INTVAL (operands[2]) == 128
5784 || (INTVAL (operands[2]) < 0
5785 && INTVAL (operands[2]) != -128)))
5786 {
5787 operands[2] = GEN_INT (-INTVAL (operands[2]));
5788 return "sub{l}\t{%2, %0|%0, %2}";
5789 }
5790 return "add{l}\t{%2, %0|%0, %2}";
5791 }
5792 }
5793 [(set (attr "type")
5794 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5795 (const_string "incdec")
5796 (const_string "alu")))
5797 (set_attr "mode" "SI")])
5798
5799 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5800 (define_insn "*addsi_3_zext"
5801 [(set (reg 17)
5802 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5803 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5804 (set (match_operand:DI 0 "register_operand" "=r")
5805 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5806 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5807 && ix86_binary_operator_ok (PLUS, SImode, operands)
5808 /* Current assemblers are broken and do not allow @GOTOFF in
5809 ought but a memory context. */
5810 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5811 {
5812 switch (get_attr_type (insn))
5813 {
5814 case TYPE_INCDEC:
5815 if (operands[2] == const1_rtx)
5816 return "inc{l}\t%k0";
5817 else if (operands[2] == constm1_rtx)
5818 return "dec{l}\t%k0";
5819 else
5820 abort();
5821
5822 default:
5823 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5824 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5825 if (GET_CODE (operands[2]) == CONST_INT
5826 && (INTVAL (operands[2]) == 128
5827 || (INTVAL (operands[2]) < 0
5828 && INTVAL (operands[2]) != -128)))
5829 {
5830 operands[2] = GEN_INT (-INTVAL (operands[2]));
5831 return "sub{l}\t{%2, %k0|%k0, %2}";
5832 }
5833 return "add{l}\t{%2, %k0|%k0, %2}";
5834 }
5835 }
5836 [(set (attr "type")
5837 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5838 (const_string "incdec")
5839 (const_string "alu")))
5840 (set_attr "mode" "SI")])
5841
5842 ; For comparisons against 1, -1 and 128, we may generate better code
5843 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5844 ; is matched then. We can't accept general immediate, because for
5845 ; case of overflows, the result is messed up.
5846 ; This pattern also don't hold of 0x80000000, since the value overflows
5847 ; when negated.
5848 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5849 ; only for comparisons not depending on it.
5850 (define_insn "*addsi_4"
5851 [(set (reg 17)
5852 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5853 (match_operand:SI 2 "const_int_operand" "n")))
5854 (clobber (match_scratch:SI 0 "=rm"))]
5855 "ix86_match_ccmode (insn, CCGCmode)
5856 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5857 {
5858 switch (get_attr_type (insn))
5859 {
5860 case TYPE_INCDEC:
5861 if (operands[2] == constm1_rtx)
5862 return "inc{l}\t%0";
5863 else if (operands[2] == const1_rtx)
5864 return "dec{l}\t%0";
5865 else
5866 abort();
5867
5868 default:
5869 if (! rtx_equal_p (operands[0], operands[1]))
5870 abort ();
5871 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5872 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5873 if ((INTVAL (operands[2]) == -128
5874 || (INTVAL (operands[2]) > 0
5875 && INTVAL (operands[2]) != 128)))
5876 return "sub{l}\t{%2, %0|%0, %2}";
5877 operands[2] = GEN_INT (-INTVAL (operands[2]));
5878 return "add{l}\t{%2, %0|%0, %2}";
5879 }
5880 }
5881 [(set (attr "type")
5882 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5883 (const_string "incdec")
5884 (const_string "alu")))
5885 (set_attr "mode" "SI")])
5886
5887 (define_insn "*addsi_5"
5888 [(set (reg 17)
5889 (compare
5890 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5891 (match_operand:SI 2 "general_operand" "rmni"))
5892 (const_int 0)))
5893 (clobber (match_scratch:SI 0 "=r"))]
5894 "ix86_match_ccmode (insn, CCGOCmode)
5895 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5896 /* Current assemblers are broken and do not allow @GOTOFF in
5897 ought but a memory context. */
5898 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5899 {
5900 switch (get_attr_type (insn))
5901 {
5902 case TYPE_INCDEC:
5903 if (! rtx_equal_p (operands[0], operands[1]))
5904 abort ();
5905 if (operands[2] == const1_rtx)
5906 return "inc{l}\t%0";
5907 else if (operands[2] == constm1_rtx)
5908 return "dec{l}\t%0";
5909 else
5910 abort();
5911
5912 default:
5913 if (! rtx_equal_p (operands[0], operands[1]))
5914 abort ();
5915 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5917 if (GET_CODE (operands[2]) == CONST_INT
5918 && (INTVAL (operands[2]) == 128
5919 || (INTVAL (operands[2]) < 0
5920 && INTVAL (operands[2]) != -128)))
5921 {
5922 operands[2] = GEN_INT (-INTVAL (operands[2]));
5923 return "sub{l}\t{%2, %0|%0, %2}";
5924 }
5925 return "add{l}\t{%2, %0|%0, %2}";
5926 }
5927 }
5928 [(set (attr "type")
5929 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5930 (const_string "incdec")
5931 (const_string "alu")))
5932 (set_attr "mode" "SI")])
5933
5934 (define_expand "addhi3"
5935 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5936 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5937 (match_operand:HI 2 "general_operand" "")))
5938 (clobber (reg:CC 17))])]
5939 "TARGET_HIMODE_MATH"
5940 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5941
5942 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5943 ;; type optimizations enabled by define-splits. This is not important
5944 ;; for PII, and in fact harmful because of partial register stalls.
5945
5946 (define_insn "*addhi_1_lea"
5947 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5948 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5949 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5950 (clobber (reg:CC 17))]
5951 "!TARGET_PARTIAL_REG_STALL
5952 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5953 {
5954 switch (get_attr_type (insn))
5955 {
5956 case TYPE_LEA:
5957 return "#";
5958 case TYPE_INCDEC:
5959 if (operands[2] == const1_rtx)
5960 return "inc{w}\t%0";
5961 else if (operands[2] == constm1_rtx)
5962 return "dec{w}\t%0";
5963 abort();
5964
5965 default:
5966 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5968 if (GET_CODE (operands[2]) == CONST_INT
5969 && (INTVAL (operands[2]) == 128
5970 || (INTVAL (operands[2]) < 0
5971 && INTVAL (operands[2]) != -128)))
5972 {
5973 operands[2] = GEN_INT (-INTVAL (operands[2]));
5974 return "sub{w}\t{%2, %0|%0, %2}";
5975 }
5976 return "add{w}\t{%2, %0|%0, %2}";
5977 }
5978 }
5979 [(set (attr "type")
5980 (if_then_else (eq_attr "alternative" "2")
5981 (const_string "lea")
5982 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5983 (const_string "incdec")
5984 (const_string "alu"))))
5985 (set_attr "mode" "HI,HI,SI")])
5986
5987 (define_insn "*addhi_1"
5988 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5989 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5990 (match_operand:HI 2 "general_operand" "ri,rm")))
5991 (clobber (reg:CC 17))]
5992 "TARGET_PARTIAL_REG_STALL
5993 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5994 {
5995 switch (get_attr_type (insn))
5996 {
5997 case TYPE_INCDEC:
5998 if (operands[2] == const1_rtx)
5999 return "inc{w}\t%0";
6000 else if (operands[2] == constm1_rtx)
6001 return "dec{w}\t%0";
6002 abort();
6003
6004 default:
6005 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6007 if (GET_CODE (operands[2]) == CONST_INT
6008 && (INTVAL (operands[2]) == 128
6009 || (INTVAL (operands[2]) < 0
6010 && INTVAL (operands[2]) != -128)))
6011 {
6012 operands[2] = GEN_INT (-INTVAL (operands[2]));
6013 return "sub{w}\t{%2, %0|%0, %2}";
6014 }
6015 return "add{w}\t{%2, %0|%0, %2}";
6016 }
6017 }
6018 [(set (attr "type")
6019 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6020 (const_string "incdec")
6021 (const_string "alu")))
6022 (set_attr "mode" "HI")])
6023
6024 (define_insn "*addhi_2"
6025 [(set (reg 17)
6026 (compare
6027 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6028 (match_operand:HI 2 "general_operand" "rmni,rni"))
6029 (const_int 0)))
6030 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6031 (plus:HI (match_dup 1) (match_dup 2)))]
6032 "ix86_match_ccmode (insn, CCGOCmode)
6033 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6034 {
6035 switch (get_attr_type (insn))
6036 {
6037 case TYPE_INCDEC:
6038 if (operands[2] == const1_rtx)
6039 return "inc{w}\t%0";
6040 else if (operands[2] == constm1_rtx)
6041 return "dec{w}\t%0";
6042 abort();
6043
6044 default:
6045 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6046 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6047 if (GET_CODE (operands[2]) == CONST_INT
6048 && (INTVAL (operands[2]) == 128
6049 || (INTVAL (operands[2]) < 0
6050 && INTVAL (operands[2]) != -128)))
6051 {
6052 operands[2] = GEN_INT (-INTVAL (operands[2]));
6053 return "sub{w}\t{%2, %0|%0, %2}";
6054 }
6055 return "add{w}\t{%2, %0|%0, %2}";
6056 }
6057 }
6058 [(set (attr "type")
6059 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6060 (const_string "incdec")
6061 (const_string "alu")))
6062 (set_attr "mode" "HI")])
6063
6064 (define_insn "*addhi_3"
6065 [(set (reg 17)
6066 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6067 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6068 (clobber (match_scratch:HI 0 "=r"))]
6069 "ix86_match_ccmode (insn, CCZmode)
6070 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6071 {
6072 switch (get_attr_type (insn))
6073 {
6074 case TYPE_INCDEC:
6075 if (operands[2] == const1_rtx)
6076 return "inc{w}\t%0";
6077 else if (operands[2] == constm1_rtx)
6078 return "dec{w}\t%0";
6079 abort();
6080
6081 default:
6082 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6083 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6084 if (GET_CODE (operands[2]) == CONST_INT
6085 && (INTVAL (operands[2]) == 128
6086 || (INTVAL (operands[2]) < 0
6087 && INTVAL (operands[2]) != -128)))
6088 {
6089 operands[2] = GEN_INT (-INTVAL (operands[2]));
6090 return "sub{w}\t{%2, %0|%0, %2}";
6091 }
6092 return "add{w}\t{%2, %0|%0, %2}";
6093 }
6094 }
6095 [(set (attr "type")
6096 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6097 (const_string "incdec")
6098 (const_string "alu")))
6099 (set_attr "mode" "HI")])
6100
6101 ; See comments above addsi_3_imm for details.
6102 (define_insn "*addhi_4"
6103 [(set (reg 17)
6104 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6105 (match_operand:HI 2 "const_int_operand" "n")))
6106 (clobber (match_scratch:HI 0 "=rm"))]
6107 "ix86_match_ccmode (insn, CCGCmode)
6108 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6109 {
6110 switch (get_attr_type (insn))
6111 {
6112 case TYPE_INCDEC:
6113 if (operands[2] == constm1_rtx)
6114 return "inc{w}\t%0";
6115 else if (operands[2] == const1_rtx)
6116 return "dec{w}\t%0";
6117 else
6118 abort();
6119
6120 default:
6121 if (! rtx_equal_p (operands[0], operands[1]))
6122 abort ();
6123 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6124 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6125 if ((INTVAL (operands[2]) == -128
6126 || (INTVAL (operands[2]) > 0
6127 && INTVAL (operands[2]) != 128)))
6128 return "sub{w}\t{%2, %0|%0, %2}";
6129 operands[2] = GEN_INT (-INTVAL (operands[2]));
6130 return "add{w}\t{%2, %0|%0, %2}";
6131 }
6132 }
6133 [(set (attr "type")
6134 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6135 (const_string "incdec")
6136 (const_string "alu")))
6137 (set_attr "mode" "SI")])
6138
6139
6140 (define_insn "*addhi_5"
6141 [(set (reg 17)
6142 (compare
6143 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6144 (match_operand:HI 2 "general_operand" "rmni"))
6145 (const_int 0)))
6146 (clobber (match_scratch:HI 0 "=r"))]
6147 "ix86_match_ccmode (insn, CCGOCmode)
6148 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6149 {
6150 switch (get_attr_type (insn))
6151 {
6152 case TYPE_INCDEC:
6153 if (operands[2] == const1_rtx)
6154 return "inc{w}\t%0";
6155 else if (operands[2] == constm1_rtx)
6156 return "dec{w}\t%0";
6157 abort();
6158
6159 default:
6160 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6161 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6162 if (GET_CODE (operands[2]) == CONST_INT
6163 && (INTVAL (operands[2]) == 128
6164 || (INTVAL (operands[2]) < 0
6165 && INTVAL (operands[2]) != -128)))
6166 {
6167 operands[2] = GEN_INT (-INTVAL (operands[2]));
6168 return "sub{w}\t{%2, %0|%0, %2}";
6169 }
6170 return "add{w}\t{%2, %0|%0, %2}";
6171 }
6172 }
6173 [(set (attr "type")
6174 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6175 (const_string "incdec")
6176 (const_string "alu")))
6177 (set_attr "mode" "HI")])
6178
6179 (define_expand "addqi3"
6180 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6181 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6182 (match_operand:QI 2 "general_operand" "")))
6183 (clobber (reg:CC 17))])]
6184 "TARGET_QIMODE_MATH"
6185 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6186
6187 ;; %%% Potential partial reg stall on alternative 2. What to do?
6188 (define_insn "*addqi_1_lea"
6189 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6190 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6191 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6192 (clobber (reg:CC 17))]
6193 "!TARGET_PARTIAL_REG_STALL
6194 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6195 {
6196 int widen = (which_alternative == 2);
6197 switch (get_attr_type (insn))
6198 {
6199 case TYPE_LEA:
6200 return "#";
6201 case TYPE_INCDEC:
6202 if (operands[2] == const1_rtx)
6203 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6204 else if (operands[2] == constm1_rtx)
6205 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6206 abort();
6207
6208 default:
6209 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6210 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6211 if (GET_CODE (operands[2]) == CONST_INT
6212 && (INTVAL (operands[2]) == 128
6213 || (INTVAL (operands[2]) < 0
6214 && INTVAL (operands[2]) != -128)))
6215 {
6216 operands[2] = GEN_INT (-INTVAL (operands[2]));
6217 if (widen)
6218 return "sub{l}\t{%2, %k0|%k0, %2}";
6219 else
6220 return "sub{b}\t{%2, %0|%0, %2}";
6221 }
6222 if (widen)
6223 return "add{l}\t{%k2, %k0|%k0, %k2}";
6224 else
6225 return "add{b}\t{%2, %0|%0, %2}";
6226 }
6227 }
6228 [(set (attr "type")
6229 (if_then_else (eq_attr "alternative" "3")
6230 (const_string "lea")
6231 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6232 (const_string "incdec")
6233 (const_string "alu"))))
6234 (set_attr "mode" "QI,QI,SI,SI")])
6235
6236 (define_insn "*addqi_1"
6237 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6238 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6239 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6240 (clobber (reg:CC 17))]
6241 "TARGET_PARTIAL_REG_STALL
6242 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6243 {
6244 int widen = (which_alternative == 2);
6245 switch (get_attr_type (insn))
6246 {
6247 case TYPE_INCDEC:
6248 if (operands[2] == const1_rtx)
6249 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6250 else if (operands[2] == constm1_rtx)
6251 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6252 abort();
6253
6254 default:
6255 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6256 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6257 if (GET_CODE (operands[2]) == CONST_INT
6258 && (INTVAL (operands[2]) == 128
6259 || (INTVAL (operands[2]) < 0
6260 && INTVAL (operands[2]) != -128)))
6261 {
6262 operands[2] = GEN_INT (-INTVAL (operands[2]));
6263 if (widen)
6264 return "sub{l}\t{%2, %k0|%k0, %2}";
6265 else
6266 return "sub{b}\t{%2, %0|%0, %2}";
6267 }
6268 if (widen)
6269 return "add{l}\t{%k2, %k0|%k0, %k2}";
6270 else
6271 return "add{b}\t{%2, %0|%0, %2}";
6272 }
6273 }
6274 [(set (attr "type")
6275 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6276 (const_string "incdec")
6277 (const_string "alu")))
6278 (set_attr "mode" "QI,QI,SI")])
6279
6280 (define_insn "*addqi_1_slp"
6281 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6282 (plus:QI (match_dup 0)
6283 (match_operand:QI 1 "general_operand" "qn,qnm")))
6284 (clobber (reg:CC 17))]
6285 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6286 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6287 {
6288 switch (get_attr_type (insn))
6289 {
6290 case TYPE_INCDEC:
6291 if (operands[1] == const1_rtx)
6292 return "inc{b}\t%0";
6293 else if (operands[1] == constm1_rtx)
6294 return "dec{b}\t%0";
6295 abort();
6296
6297 default:
6298 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6299 if (GET_CODE (operands[1]) == CONST_INT
6300 && INTVAL (operands[1]) < 0)
6301 {
6302 operands[1] = GEN_INT (-INTVAL (operands[1]));
6303 return "sub{b}\t{%1, %0|%0, %1}";
6304 }
6305 return "add{b}\t{%1, %0|%0, %1}";
6306 }
6307 }
6308 [(set (attr "type")
6309 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6310 (const_string "incdec")
6311 (const_string "alu1")))
6312 (set_attr "mode" "QI")])
6313
6314 (define_insn "*addqi_2"
6315 [(set (reg 17)
6316 (compare
6317 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6318 (match_operand:QI 2 "general_operand" "qmni,qni"))
6319 (const_int 0)))
6320 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6321 (plus:QI (match_dup 1) (match_dup 2)))]
6322 "ix86_match_ccmode (insn, CCGOCmode)
6323 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6324 {
6325 switch (get_attr_type (insn))
6326 {
6327 case TYPE_INCDEC:
6328 if (operands[2] == const1_rtx)
6329 return "inc{b}\t%0";
6330 else if (operands[2] == constm1_rtx
6331 || (GET_CODE (operands[2]) == CONST_INT
6332 && INTVAL (operands[2]) == 255))
6333 return "dec{b}\t%0";
6334 abort();
6335
6336 default:
6337 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6338 if (GET_CODE (operands[2]) == CONST_INT
6339 && INTVAL (operands[2]) < 0)
6340 {
6341 operands[2] = GEN_INT (-INTVAL (operands[2]));
6342 return "sub{b}\t{%2, %0|%0, %2}";
6343 }
6344 return "add{b}\t{%2, %0|%0, %2}";
6345 }
6346 }
6347 [(set (attr "type")
6348 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6349 (const_string "incdec")
6350 (const_string "alu")))
6351 (set_attr "mode" "QI")])
6352
6353 (define_insn "*addqi_3"
6354 [(set (reg 17)
6355 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6356 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6357 (clobber (match_scratch:QI 0 "=q"))]
6358 "ix86_match_ccmode (insn, CCZmode)
6359 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6360 {
6361 switch (get_attr_type (insn))
6362 {
6363 case TYPE_INCDEC:
6364 if (operands[2] == const1_rtx)
6365 return "inc{b}\t%0";
6366 else if (operands[2] == constm1_rtx
6367 || (GET_CODE (operands[2]) == CONST_INT
6368 && INTVAL (operands[2]) == 255))
6369 return "dec{b}\t%0";
6370 abort();
6371
6372 default:
6373 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6374 if (GET_CODE (operands[2]) == CONST_INT
6375 && INTVAL (operands[2]) < 0)
6376 {
6377 operands[2] = GEN_INT (-INTVAL (operands[2]));
6378 return "sub{b}\t{%2, %0|%0, %2}";
6379 }
6380 return "add{b}\t{%2, %0|%0, %2}";
6381 }
6382 }
6383 [(set (attr "type")
6384 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6385 (const_string "incdec")
6386 (const_string "alu")))
6387 (set_attr "mode" "QI")])
6388
6389 ; See comments above addsi_3_imm for details.
6390 (define_insn "*addqi_4"
6391 [(set (reg 17)
6392 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6393 (match_operand:QI 2 "const_int_operand" "n")))
6394 (clobber (match_scratch:QI 0 "=qm"))]
6395 "ix86_match_ccmode (insn, CCGCmode)
6396 && (INTVAL (operands[2]) & 0xff) != 0x80"
6397 {
6398 switch (get_attr_type (insn))
6399 {
6400 case TYPE_INCDEC:
6401 if (operands[2] == constm1_rtx
6402 || (GET_CODE (operands[2]) == CONST_INT
6403 && INTVAL (operands[2]) == 255))
6404 return "inc{b}\t%0";
6405 else if (operands[2] == const1_rtx)
6406 return "dec{b}\t%0";
6407 else
6408 abort();
6409
6410 default:
6411 if (! rtx_equal_p (operands[0], operands[1]))
6412 abort ();
6413 if (INTVAL (operands[2]) < 0)
6414 {
6415 operands[2] = GEN_INT (-INTVAL (operands[2]));
6416 return "add{b}\t{%2, %0|%0, %2}";
6417 }
6418 return "sub{b}\t{%2, %0|%0, %2}";
6419 }
6420 }
6421 [(set (attr "type")
6422 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6423 (const_string "incdec")
6424 (const_string "alu")))
6425 (set_attr "mode" "QI")])
6426
6427
6428 (define_insn "*addqi_5"
6429 [(set (reg 17)
6430 (compare
6431 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6432 (match_operand:QI 2 "general_operand" "qmni"))
6433 (const_int 0)))
6434 (clobber (match_scratch:QI 0 "=q"))]
6435 "ix86_match_ccmode (insn, CCGOCmode)
6436 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6437 {
6438 switch (get_attr_type (insn))
6439 {
6440 case TYPE_INCDEC:
6441 if (operands[2] == const1_rtx)
6442 return "inc{b}\t%0";
6443 else if (operands[2] == constm1_rtx
6444 || (GET_CODE (operands[2]) == CONST_INT
6445 && INTVAL (operands[2]) == 255))
6446 return "dec{b}\t%0";
6447 abort();
6448
6449 default:
6450 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6451 if (GET_CODE (operands[2]) == CONST_INT
6452 && INTVAL (operands[2]) < 0)
6453 {
6454 operands[2] = GEN_INT (-INTVAL (operands[2]));
6455 return "sub{b}\t{%2, %0|%0, %2}";
6456 }
6457 return "add{b}\t{%2, %0|%0, %2}";
6458 }
6459 }
6460 [(set (attr "type")
6461 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6462 (const_string "incdec")
6463 (const_string "alu")))
6464 (set_attr "mode" "QI")])
6465
6466
6467 (define_insn "addqi_ext_1"
6468 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6469 (const_int 8)
6470 (const_int 8))
6471 (plus:SI
6472 (zero_extract:SI
6473 (match_operand 1 "ext_register_operand" "0")
6474 (const_int 8)
6475 (const_int 8))
6476 (match_operand:QI 2 "general_operand" "Qmn")))
6477 (clobber (reg:CC 17))]
6478 "!TARGET_64BIT"
6479 {
6480 switch (get_attr_type (insn))
6481 {
6482 case TYPE_INCDEC:
6483 if (operands[2] == const1_rtx)
6484 return "inc{b}\t%h0";
6485 else if (operands[2] == constm1_rtx
6486 || (GET_CODE (operands[2]) == CONST_INT
6487 && INTVAL (operands[2]) == 255))
6488 return "dec{b}\t%h0";
6489 abort();
6490
6491 default:
6492 return "add{b}\t{%2, %h0|%h0, %2}";
6493 }
6494 }
6495 [(set (attr "type")
6496 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6497 (const_string "incdec")
6498 (const_string "alu")))
6499 (set_attr "mode" "QI")])
6500
6501 (define_insn "*addqi_ext_1_rex64"
6502 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6503 (const_int 8)
6504 (const_int 8))
6505 (plus:SI
6506 (zero_extract:SI
6507 (match_operand 1 "ext_register_operand" "0")
6508 (const_int 8)
6509 (const_int 8))
6510 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6511 (clobber (reg:CC 17))]
6512 "TARGET_64BIT"
6513 {
6514 switch (get_attr_type (insn))
6515 {
6516 case TYPE_INCDEC:
6517 if (operands[2] == const1_rtx)
6518 return "inc{b}\t%h0";
6519 else if (operands[2] == constm1_rtx
6520 || (GET_CODE (operands[2]) == CONST_INT
6521 && INTVAL (operands[2]) == 255))
6522 return "dec{b}\t%h0";
6523 abort();
6524
6525 default:
6526 return "add{b}\t{%2, %h0|%h0, %2}";
6527 }
6528 }
6529 [(set (attr "type")
6530 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6531 (const_string "incdec")
6532 (const_string "alu")))
6533 (set_attr "mode" "QI")])
6534
6535 (define_insn "*addqi_ext_2"
6536 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6537 (const_int 8)
6538 (const_int 8))
6539 (plus:SI
6540 (zero_extract:SI
6541 (match_operand 1 "ext_register_operand" "%0")
6542 (const_int 8)
6543 (const_int 8))
6544 (zero_extract:SI
6545 (match_operand 2 "ext_register_operand" "Q")
6546 (const_int 8)
6547 (const_int 8))))
6548 (clobber (reg:CC 17))]
6549 ""
6550 "add{b}\t{%h2, %h0|%h0, %h2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "mode" "QI")])
6553
6554 ;; The patterns that match these are at the end of this file.
6555
6556 (define_expand "addxf3"
6557 [(set (match_operand:XF 0 "register_operand" "")
6558 (plus:XF (match_operand:XF 1 "register_operand" "")
6559 (match_operand:XF 2 "register_operand" "")))]
6560 "TARGET_80387"
6561 "")
6562
6563 (define_expand "adddf3"
6564 [(set (match_operand:DF 0 "register_operand" "")
6565 (plus:DF (match_operand:DF 1 "register_operand" "")
6566 (match_operand:DF 2 "nonimmediate_operand" "")))]
6567 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6568 "")
6569
6570 (define_expand "addsf3"
6571 [(set (match_operand:SF 0 "register_operand" "")
6572 (plus:SF (match_operand:SF 1 "register_operand" "")
6573 (match_operand:SF 2 "nonimmediate_operand" "")))]
6574 "TARGET_80387 || TARGET_SSE_MATH"
6575 "")
6576 \f
6577 ;; Subtract instructions
6578
6579 ;; %%% splits for subsidi3
6580
6581 (define_expand "subdi3"
6582 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6583 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6584 (match_operand:DI 2 "x86_64_general_operand" "")))
6585 (clobber (reg:CC 17))])]
6586 ""
6587 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6588
6589 (define_insn "*subdi3_1"
6590 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6591 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6592 (match_operand:DI 2 "general_operand" "roiF,riF")))
6593 (clobber (reg:CC 17))]
6594 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6595 "#")
6596
6597 (define_split
6598 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6599 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6600 (match_operand:DI 2 "general_operand" "")))
6601 (clobber (reg:CC 17))]
6602 "!TARGET_64BIT && reload_completed"
6603 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6604 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6605 (parallel [(set (match_dup 3)
6606 (minus:SI (match_dup 4)
6607 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6608 (match_dup 5))))
6609 (clobber (reg:CC 17))])]
6610 "split_di (operands+0, 1, operands+0, operands+3);
6611 split_di (operands+1, 1, operands+1, operands+4);
6612 split_di (operands+2, 1, operands+2, operands+5);")
6613
6614 (define_insn "subdi3_carry_rex64"
6615 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6616 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6617 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6618 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6619 (clobber (reg:CC 17))]
6620 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6621 "sbb{q}\t{%2, %0|%0, %2}"
6622 [(set_attr "type" "alu")
6623 (set_attr "pent_pair" "pu")
6624 (set_attr "mode" "DI")])
6625
6626 (define_insn "*subdi_1_rex64"
6627 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6628 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6629 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6630 (clobber (reg:CC 17))]
6631 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6632 "sub{q}\t{%2, %0|%0, %2}"
6633 [(set_attr "type" "alu")
6634 (set_attr "mode" "DI")])
6635
6636 (define_insn "*subdi_2_rex64"
6637 [(set (reg 17)
6638 (compare
6639 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6640 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6641 (const_int 0)))
6642 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6643 (minus:DI (match_dup 1) (match_dup 2)))]
6644 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6645 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6646 "sub{q}\t{%2, %0|%0, %2}"
6647 [(set_attr "type" "alu")
6648 (set_attr "mode" "DI")])
6649
6650 (define_insn "*subdi_3_rex63"
6651 [(set (reg 17)
6652 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6653 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6654 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6655 (minus:DI (match_dup 1) (match_dup 2)))]
6656 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6657 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6658 "sub{q}\t{%2, %0|%0, %2}"
6659 [(set_attr "type" "alu")
6660 (set_attr "mode" "DI")])
6661
6662 (define_insn "subqi3_carry"
6663 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6664 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6665 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6666 (match_operand:QI 2 "general_operand" "qi,qm"))))
6667 (clobber (reg:CC 17))]
6668 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6669 "sbb{b}\t{%2, %0|%0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "pent_pair" "pu")
6672 (set_attr "mode" "QI")])
6673
6674 (define_insn "subhi3_carry"
6675 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6676 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6677 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6678 (match_operand:HI 2 "general_operand" "ri,rm"))))
6679 (clobber (reg:CC 17))]
6680 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6681 "sbb{w}\t{%2, %0|%0, %2}"
6682 [(set_attr "type" "alu")
6683 (set_attr "pent_pair" "pu")
6684 (set_attr "mode" "HI")])
6685
6686 (define_insn "subsi3_carry"
6687 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6688 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6689 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6690 (match_operand:SI 2 "general_operand" "ri,rm"))))
6691 (clobber (reg:CC 17))]
6692 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6693 "sbb{l}\t{%2, %0|%0, %2}"
6694 [(set_attr "type" "alu")
6695 (set_attr "pent_pair" "pu")
6696 (set_attr "mode" "SI")])
6697
6698 (define_insn "subsi3_carry_zext"
6699 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6700 (zero_extend:DI
6701 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6702 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6703 (match_operand:SI 2 "general_operand" "ri,rm")))))
6704 (clobber (reg:CC 17))]
6705 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6706 "sbb{l}\t{%2, %k0|%k0, %2}"
6707 [(set_attr "type" "alu")
6708 (set_attr "pent_pair" "pu")
6709 (set_attr "mode" "SI")])
6710
6711 (define_expand "subsi3"
6712 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6713 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6714 (match_operand:SI 2 "general_operand" "")))
6715 (clobber (reg:CC 17))])]
6716 ""
6717 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6718
6719 (define_insn "*subsi_1"
6720 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6721 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6722 (match_operand:SI 2 "general_operand" "ri,rm")))
6723 (clobber (reg:CC 17))]
6724 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6725 "sub{l}\t{%2, %0|%0, %2}"
6726 [(set_attr "type" "alu")
6727 (set_attr "mode" "SI")])
6728
6729 (define_insn "*subsi_1_zext"
6730 [(set (match_operand:DI 0 "register_operand" "=r")
6731 (zero_extend:DI
6732 (minus:SI (match_operand:SI 1 "register_operand" "0")
6733 (match_operand:SI 2 "general_operand" "rim"))))
6734 (clobber (reg:CC 17))]
6735 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6736 "sub{l}\t{%2, %k0|%k0, %2}"
6737 [(set_attr "type" "alu")
6738 (set_attr "mode" "SI")])
6739
6740 (define_insn "*subsi_2"
6741 [(set (reg 17)
6742 (compare
6743 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6744 (match_operand:SI 2 "general_operand" "ri,rm"))
6745 (const_int 0)))
6746 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6747 (minus:SI (match_dup 1) (match_dup 2)))]
6748 "ix86_match_ccmode (insn, CCGOCmode)
6749 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6750 "sub{l}\t{%2, %0|%0, %2}"
6751 [(set_attr "type" "alu")
6752 (set_attr "mode" "SI")])
6753
6754 (define_insn "*subsi_2_zext"
6755 [(set (reg 17)
6756 (compare
6757 (minus:SI (match_operand:SI 1 "register_operand" "0")
6758 (match_operand:SI 2 "general_operand" "rim"))
6759 (const_int 0)))
6760 (set (match_operand:DI 0 "register_operand" "=r")
6761 (zero_extend:DI
6762 (minus:SI (match_dup 1)
6763 (match_dup 2))))]
6764 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6765 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6766 "sub{l}\t{%2, %k0|%k0, %2}"
6767 [(set_attr "type" "alu")
6768 (set_attr "mode" "SI")])
6769
6770 (define_insn "*subsi_3"
6771 [(set (reg 17)
6772 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6773 (match_operand:SI 2 "general_operand" "ri,rm")))
6774 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6775 (minus:SI (match_dup 1) (match_dup 2)))]
6776 "ix86_match_ccmode (insn, CCmode)
6777 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6778 "sub{l}\t{%2, %0|%0, %2}"
6779 [(set_attr "type" "alu")
6780 (set_attr "mode" "SI")])
6781
6782 (define_insn "*subsi_3_zext"
6783 [(set (reg 17)
6784 (compare (match_operand:SI 1 "register_operand" "0")
6785 (match_operand:SI 2 "general_operand" "rim")))
6786 (set (match_operand:DI 0 "register_operand" "=r")
6787 (zero_extend:DI
6788 (minus:SI (match_dup 1)
6789 (match_dup 2))))]
6790 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6791 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6792 "sub{q}\t{%2, %0|%0, %2}"
6793 [(set_attr "type" "alu")
6794 (set_attr "mode" "DI")])
6795
6796 (define_expand "subhi3"
6797 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6798 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6799 (match_operand:HI 2 "general_operand" "")))
6800 (clobber (reg:CC 17))])]
6801 "TARGET_HIMODE_MATH"
6802 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6803
6804 (define_insn "*subhi_1"
6805 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6806 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6807 (match_operand:HI 2 "general_operand" "ri,rm")))
6808 (clobber (reg:CC 17))]
6809 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6810 "sub{w}\t{%2, %0|%0, %2}"
6811 [(set_attr "type" "alu")
6812 (set_attr "mode" "HI")])
6813
6814 (define_insn "*subhi_2"
6815 [(set (reg 17)
6816 (compare
6817 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6818 (match_operand:HI 2 "general_operand" "ri,rm"))
6819 (const_int 0)))
6820 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6821 (minus:HI (match_dup 1) (match_dup 2)))]
6822 "ix86_match_ccmode (insn, CCGOCmode)
6823 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6824 "sub{w}\t{%2, %0|%0, %2}"
6825 [(set_attr "type" "alu")
6826 (set_attr "mode" "HI")])
6827
6828 (define_insn "*subhi_3"
6829 [(set (reg 17)
6830 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6831 (match_operand:HI 2 "general_operand" "ri,rm")))
6832 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6833 (minus:HI (match_dup 1) (match_dup 2)))]
6834 "ix86_match_ccmode (insn, CCmode)
6835 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6836 "sub{w}\t{%2, %0|%0, %2}"
6837 [(set_attr "type" "alu")
6838 (set_attr "mode" "HI")])
6839
6840 (define_expand "subqi3"
6841 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6842 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6843 (match_operand:QI 2 "general_operand" "")))
6844 (clobber (reg:CC 17))])]
6845 "TARGET_QIMODE_MATH"
6846 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6847
6848 (define_insn "*subqi_1"
6849 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6850 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6851 (match_operand:QI 2 "general_operand" "qn,qmn")))
6852 (clobber (reg:CC 17))]
6853 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6854 "sub{b}\t{%2, %0|%0, %2}"
6855 [(set_attr "type" "alu")
6856 (set_attr "mode" "QI")])
6857
6858 (define_insn "*subqi_1_slp"
6859 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6860 (minus:QI (match_dup 0)
6861 (match_operand:QI 1 "general_operand" "qn,qmn")))
6862 (clobber (reg:CC 17))]
6863 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6864 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6865 "sub{b}\t{%1, %0|%0, %1}"
6866 [(set_attr "type" "alu1")
6867 (set_attr "mode" "QI")])
6868
6869 (define_insn "*subqi_2"
6870 [(set (reg 17)
6871 (compare
6872 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6873 (match_operand:QI 2 "general_operand" "qi,qm"))
6874 (const_int 0)))
6875 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6876 (minus:HI (match_dup 1) (match_dup 2)))]
6877 "ix86_match_ccmode (insn, CCGOCmode)
6878 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6879 "sub{b}\t{%2, %0|%0, %2}"
6880 [(set_attr "type" "alu")
6881 (set_attr "mode" "QI")])
6882
6883 (define_insn "*subqi_3"
6884 [(set (reg 17)
6885 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6886 (match_operand:QI 2 "general_operand" "qi,qm")))
6887 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6888 (minus:HI (match_dup 1) (match_dup 2)))]
6889 "ix86_match_ccmode (insn, CCmode)
6890 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6891 "sub{b}\t{%2, %0|%0, %2}"
6892 [(set_attr "type" "alu")
6893 (set_attr "mode" "QI")])
6894
6895 ;; The patterns that match these are at the end of this file.
6896
6897 (define_expand "subxf3"
6898 [(set (match_operand:XF 0 "register_operand" "")
6899 (minus:XF (match_operand:XF 1 "register_operand" "")
6900 (match_operand:XF 2 "register_operand" "")))]
6901 "TARGET_80387"
6902 "")
6903
6904 (define_expand "subdf3"
6905 [(set (match_operand:DF 0 "register_operand" "")
6906 (minus:DF (match_operand:DF 1 "register_operand" "")
6907 (match_operand:DF 2 "nonimmediate_operand" "")))]
6908 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6909 "")
6910
6911 (define_expand "subsf3"
6912 [(set (match_operand:SF 0 "register_operand" "")
6913 (minus:SF (match_operand:SF 1 "register_operand" "")
6914 (match_operand:SF 2 "nonimmediate_operand" "")))]
6915 "TARGET_80387 || TARGET_SSE_MATH"
6916 "")
6917 \f
6918 ;; Multiply instructions
6919
6920 (define_expand "muldi3"
6921 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6922 (mult:DI (match_operand:DI 1 "register_operand" "")
6923 (match_operand:DI 2 "x86_64_general_operand" "")))
6924 (clobber (reg:CC 17))])]
6925 "TARGET_64BIT"
6926 "")
6927
6928 (define_insn "*muldi3_1_rex64"
6929 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6930 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6931 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6932 (clobber (reg:CC 17))]
6933 "TARGET_64BIT
6934 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6935 "@
6936 imul{q}\t{%2, %1, %0|%0, %1, %2}
6937 imul{q}\t{%2, %1, %0|%0, %1, %2}
6938 imul{q}\t{%2, %0|%0, %2}"
6939 [(set_attr "type" "imul")
6940 (set_attr "prefix_0f" "0,0,1")
6941 (set (attr "athlon_decode")
6942 (cond [(eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (eq_attr "alternative" "1")
6945 (const_string "vector")
6946 (and (eq_attr "alternative" "2")
6947 (match_operand 1 "memory_operand" ""))
6948 (const_string "vector")]
6949 (const_string "direct")))
6950 (set_attr "mode" "DI")])
6951
6952 (define_expand "mulsi3"
6953 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6954 (mult:SI (match_operand:SI 1 "register_operand" "")
6955 (match_operand:SI 2 "general_operand" "")))
6956 (clobber (reg:CC 17))])]
6957 ""
6958 "")
6959
6960 (define_insn "*mulsi3_1"
6961 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6962 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6963 (match_operand:SI 2 "general_operand" "K,i,mr")))
6964 (clobber (reg:CC 17))]
6965 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6966 "@
6967 imul{l}\t{%2, %1, %0|%0, %1, %2}
6968 imul{l}\t{%2, %1, %0|%0, %1, %2}
6969 imul{l}\t{%2, %0|%0, %2}"
6970 [(set_attr "type" "imul")
6971 (set_attr "prefix_0f" "0,0,1")
6972 (set (attr "athlon_decode")
6973 (cond [(eq_attr "cpu" "athlon")
6974 (const_string "vector")
6975 (eq_attr "alternative" "1")
6976 (const_string "vector")
6977 (and (eq_attr "alternative" "2")
6978 (match_operand 1 "memory_operand" ""))
6979 (const_string "vector")]
6980 (const_string "direct")))
6981 (set_attr "mode" "SI")])
6982
6983 (define_insn "*mulsi3_1_zext"
6984 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6985 (zero_extend:DI
6986 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6987 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6988 (clobber (reg:CC 17))]
6989 "TARGET_64BIT
6990 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6991 "@
6992 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6993 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6994 imul{l}\t{%2, %k0|%k0, %2}"
6995 [(set_attr "type" "imul")
6996 (set_attr "prefix_0f" "0,0,1")
6997 (set (attr "athlon_decode")
6998 (cond [(eq_attr "cpu" "athlon")
6999 (const_string "vector")
7000 (eq_attr "alternative" "1")
7001 (const_string "vector")
7002 (and (eq_attr "alternative" "2")
7003 (match_operand 1 "memory_operand" ""))
7004 (const_string "vector")]
7005 (const_string "direct")))
7006 (set_attr "mode" "SI")])
7007
7008 (define_expand "mulhi3"
7009 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7010 (mult:HI (match_operand:HI 1 "register_operand" "")
7011 (match_operand:HI 2 "general_operand" "")))
7012 (clobber (reg:CC 17))])]
7013 "TARGET_HIMODE_MATH"
7014 "")
7015
7016 (define_insn "*mulhi3_1"
7017 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7018 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7019 (match_operand:HI 2 "general_operand" "K,i,mr")))
7020 (clobber (reg:CC 17))]
7021 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7022 "@
7023 imul{w}\t{%2, %1, %0|%0, %1, %2}
7024 imul{w}\t{%2, %1, %0|%0, %1, %2}
7025 imul{w}\t{%2, %0|%0, %2}"
7026 [(set_attr "type" "imul")
7027 (set_attr "prefix_0f" "0,0,1")
7028 (set (attr "athlon_decode")
7029 (cond [(eq_attr "cpu" "athlon")
7030 (const_string "vector")
7031 (eq_attr "alternative" "1,2")
7032 (const_string "vector")]
7033 (const_string "direct")))
7034 (set_attr "mode" "HI")])
7035
7036 (define_expand "mulqi3"
7037 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7038 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7039 (match_operand:QI 2 "register_operand" "")))
7040 (clobber (reg:CC 17))])]
7041 "TARGET_QIMODE_MATH"
7042 "")
7043
7044 (define_insn "*mulqi3_1"
7045 [(set (match_operand:QI 0 "register_operand" "=a")
7046 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7047 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7048 (clobber (reg:CC 17))]
7049 "TARGET_QIMODE_MATH
7050 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7051 "mul{b}\t%2"
7052 [(set_attr "type" "imul")
7053 (set_attr "length_immediate" "0")
7054 (set (attr "athlon_decode")
7055 (if_then_else (eq_attr "cpu" "athlon")
7056 (const_string "vector")
7057 (const_string "direct")))
7058 (set_attr "mode" "QI")])
7059
7060 (define_expand "umulqihi3"
7061 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7062 (mult:HI (zero_extend:HI
7063 (match_operand:QI 1 "nonimmediate_operand" ""))
7064 (zero_extend:HI
7065 (match_operand:QI 2 "register_operand" ""))))
7066 (clobber (reg:CC 17))])]
7067 "TARGET_QIMODE_MATH"
7068 "")
7069
7070 (define_insn "*umulqihi3_1"
7071 [(set (match_operand:HI 0 "register_operand" "=a")
7072 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7073 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7074 (clobber (reg:CC 17))]
7075 "TARGET_QIMODE_MATH
7076 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7077 "mul{b}\t%2"
7078 [(set_attr "type" "imul")
7079 (set_attr "length_immediate" "0")
7080 (set (attr "athlon_decode")
7081 (if_then_else (eq_attr "cpu" "athlon")
7082 (const_string "vector")
7083 (const_string "direct")))
7084 (set_attr "mode" "QI")])
7085
7086 (define_expand "mulqihi3"
7087 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7088 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7089 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7090 (clobber (reg:CC 17))])]
7091 "TARGET_QIMODE_MATH"
7092 "")
7093
7094 (define_insn "*mulqihi3_insn"
7095 [(set (match_operand:HI 0 "register_operand" "=a")
7096 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7097 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7098 (clobber (reg:CC 17))]
7099 "TARGET_QIMODE_MATH
7100 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7101 "imul{b}\t%2"
7102 [(set_attr "type" "imul")
7103 (set_attr "length_immediate" "0")
7104 (set (attr "athlon_decode")
7105 (if_then_else (eq_attr "cpu" "athlon")
7106 (const_string "vector")
7107 (const_string "direct")))
7108 (set_attr "mode" "QI")])
7109
7110 (define_expand "umulditi3"
7111 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7112 (mult:TI (zero_extend:TI
7113 (match_operand:DI 1 "nonimmediate_operand" ""))
7114 (zero_extend:TI
7115 (match_operand:DI 2 "register_operand" ""))))
7116 (clobber (reg:CC 17))])]
7117 "TARGET_64BIT"
7118 "")
7119
7120 (define_insn "*umulditi3_insn"
7121 [(set (match_operand:TI 0 "register_operand" "=A")
7122 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7123 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7124 (clobber (reg:CC 17))]
7125 "TARGET_64BIT
7126 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7127 "mul{q}\t%2"
7128 [(set_attr "type" "imul")
7129 (set_attr "length_immediate" "0")
7130 (set (attr "athlon_decode")
7131 (if_then_else (eq_attr "cpu" "athlon")
7132 (const_string "vector")
7133 (const_string "double")))
7134 (set_attr "mode" "DI")])
7135
7136 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7137 (define_expand "umulsidi3"
7138 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7139 (mult:DI (zero_extend:DI
7140 (match_operand:SI 1 "nonimmediate_operand" ""))
7141 (zero_extend:DI
7142 (match_operand:SI 2 "register_operand" ""))))
7143 (clobber (reg:CC 17))])]
7144 "!TARGET_64BIT"
7145 "")
7146
7147 (define_insn "*umulsidi3_insn"
7148 [(set (match_operand:DI 0 "register_operand" "=A")
7149 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7150 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7151 (clobber (reg:CC 17))]
7152 "!TARGET_64BIT
7153 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7154 "mul{l}\t%2"
7155 [(set_attr "type" "imul")
7156 (set_attr "length_immediate" "0")
7157 (set (attr "athlon_decode")
7158 (if_then_else (eq_attr "cpu" "athlon")
7159 (const_string "vector")
7160 (const_string "double")))
7161 (set_attr "mode" "SI")])
7162
7163 (define_expand "mulditi3"
7164 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7165 (mult:TI (sign_extend:TI
7166 (match_operand:DI 1 "nonimmediate_operand" ""))
7167 (sign_extend:TI
7168 (match_operand:DI 2 "register_operand" ""))))
7169 (clobber (reg:CC 17))])]
7170 "TARGET_64BIT"
7171 "")
7172
7173 (define_insn "*mulditi3_insn"
7174 [(set (match_operand:TI 0 "register_operand" "=A")
7175 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7176 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7177 (clobber (reg:CC 17))]
7178 "TARGET_64BIT
7179 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7180 "imul{q}\t%2"
7181 [(set_attr "type" "imul")
7182 (set_attr "length_immediate" "0")
7183 (set (attr "athlon_decode")
7184 (if_then_else (eq_attr "cpu" "athlon")
7185 (const_string "vector")
7186 (const_string "double")))
7187 (set_attr "mode" "DI")])
7188
7189 (define_expand "mulsidi3"
7190 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7191 (mult:DI (sign_extend:DI
7192 (match_operand:SI 1 "nonimmediate_operand" ""))
7193 (sign_extend:DI
7194 (match_operand:SI 2 "register_operand" ""))))
7195 (clobber (reg:CC 17))])]
7196 "!TARGET_64BIT"
7197 "")
7198
7199 (define_insn "*mulsidi3_insn"
7200 [(set (match_operand:DI 0 "register_operand" "=A")
7201 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7202 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7203 (clobber (reg:CC 17))]
7204 "!TARGET_64BIT
7205 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7206 "imul{l}\t%2"
7207 [(set_attr "type" "imul")
7208 (set_attr "length_immediate" "0")
7209 (set (attr "athlon_decode")
7210 (if_then_else (eq_attr "cpu" "athlon")
7211 (const_string "vector")
7212 (const_string "double")))
7213 (set_attr "mode" "SI")])
7214
7215 (define_expand "umuldi3_highpart"
7216 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7217 (truncate:DI
7218 (lshiftrt:TI
7219 (mult:TI (zero_extend:TI
7220 (match_operand:DI 1 "nonimmediate_operand" ""))
7221 (zero_extend:TI
7222 (match_operand:DI 2 "register_operand" "")))
7223 (const_int 64))))
7224 (clobber (match_scratch:DI 3 ""))
7225 (clobber (reg:CC 17))])]
7226 "TARGET_64BIT"
7227 "")
7228
7229 (define_insn "*umuldi3_highpart_rex64"
7230 [(set (match_operand:DI 0 "register_operand" "=d")
7231 (truncate:DI
7232 (lshiftrt:TI
7233 (mult:TI (zero_extend:TI
7234 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7235 (zero_extend:TI
7236 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7237 (const_int 64))))
7238 (clobber (match_scratch:DI 3 "=1"))
7239 (clobber (reg:CC 17))]
7240 "TARGET_64BIT
7241 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7242 "mul{q}\t%2"
7243 [(set_attr "type" "imul")
7244 (set_attr "length_immediate" "0")
7245 (set (attr "athlon_decode")
7246 (if_then_else (eq_attr "cpu" "athlon")
7247 (const_string "vector")
7248 (const_string "double")))
7249 (set_attr "mode" "DI")])
7250
7251 (define_expand "umulsi3_highpart"
7252 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7253 (truncate:SI
7254 (lshiftrt:DI
7255 (mult:DI (zero_extend:DI
7256 (match_operand:SI 1 "nonimmediate_operand" ""))
7257 (zero_extend:DI
7258 (match_operand:SI 2 "register_operand" "")))
7259 (const_int 32))))
7260 (clobber (match_scratch:SI 3 ""))
7261 (clobber (reg:CC 17))])]
7262 ""
7263 "")
7264
7265 (define_insn "*umulsi3_highpart_insn"
7266 [(set (match_operand:SI 0 "register_operand" "=d")
7267 (truncate:SI
7268 (lshiftrt:DI
7269 (mult:DI (zero_extend:DI
7270 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7271 (zero_extend:DI
7272 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7273 (const_int 32))))
7274 (clobber (match_scratch:SI 3 "=1"))
7275 (clobber (reg:CC 17))]
7276 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7277 "mul{l}\t%2"
7278 [(set_attr "type" "imul")
7279 (set_attr "length_immediate" "0")
7280 (set (attr "athlon_decode")
7281 (if_then_else (eq_attr "cpu" "athlon")
7282 (const_string "vector")
7283 (const_string "double")))
7284 (set_attr "mode" "SI")])
7285
7286 (define_insn "*umulsi3_highpart_zext"
7287 [(set (match_operand:DI 0 "register_operand" "=d")
7288 (zero_extend:DI (truncate:SI
7289 (lshiftrt:DI
7290 (mult:DI (zero_extend:DI
7291 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7292 (zero_extend:DI
7293 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7294 (const_int 32)))))
7295 (clobber (match_scratch:SI 3 "=1"))
7296 (clobber (reg:CC 17))]
7297 "TARGET_64BIT
7298 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7299 "mul{l}\t%2"
7300 [(set_attr "type" "imul")
7301 (set_attr "length_immediate" "0")
7302 (set (attr "athlon_decode")
7303 (if_then_else (eq_attr "cpu" "athlon")
7304 (const_string "vector")
7305 (const_string "double")))
7306 (set_attr "mode" "SI")])
7307
7308 (define_expand "smuldi3_highpart"
7309 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7310 (truncate:DI
7311 (lshiftrt:TI
7312 (mult:TI (sign_extend:TI
7313 (match_operand:DI 1 "nonimmediate_operand" ""))
7314 (sign_extend:TI
7315 (match_operand:DI 2 "register_operand" "")))
7316 (const_int 64))))
7317 (clobber (match_scratch:DI 3 ""))
7318 (clobber (reg:CC 17))])]
7319 "TARGET_64BIT"
7320 "")
7321
7322 (define_insn "*smuldi3_highpart_rex64"
7323 [(set (match_operand:DI 0 "register_operand" "=d")
7324 (truncate:DI
7325 (lshiftrt:TI
7326 (mult:TI (sign_extend:TI
7327 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7328 (sign_extend:TI
7329 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7330 (const_int 64))))
7331 (clobber (match_scratch:DI 3 "=1"))
7332 (clobber (reg:CC 17))]
7333 "TARGET_64BIT
7334 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7335 "imul{q}\t%2"
7336 [(set_attr "type" "imul")
7337 (set (attr "athlon_decode")
7338 (if_then_else (eq_attr "cpu" "athlon")
7339 (const_string "vector")
7340 (const_string "double")))
7341 (set_attr "mode" "DI")])
7342
7343 (define_expand "smulsi3_highpart"
7344 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7345 (truncate:SI
7346 (lshiftrt:DI
7347 (mult:DI (sign_extend:DI
7348 (match_operand:SI 1 "nonimmediate_operand" ""))
7349 (sign_extend:DI
7350 (match_operand:SI 2 "register_operand" "")))
7351 (const_int 32))))
7352 (clobber (match_scratch:SI 3 ""))
7353 (clobber (reg:CC 17))])]
7354 ""
7355 "")
7356
7357 (define_insn "*smulsi3_highpart_insn"
7358 [(set (match_operand:SI 0 "register_operand" "=d")
7359 (truncate:SI
7360 (lshiftrt:DI
7361 (mult:DI (sign_extend:DI
7362 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7363 (sign_extend:DI
7364 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7365 (const_int 32))))
7366 (clobber (match_scratch:SI 3 "=1"))
7367 (clobber (reg:CC 17))]
7368 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7369 "imul{l}\t%2"
7370 [(set_attr "type" "imul")
7371 (set (attr "athlon_decode")
7372 (if_then_else (eq_attr "cpu" "athlon")
7373 (const_string "vector")
7374 (const_string "double")))
7375 (set_attr "mode" "SI")])
7376
7377 (define_insn "*smulsi3_highpart_zext"
7378 [(set (match_operand:DI 0 "register_operand" "=d")
7379 (zero_extend:DI (truncate:SI
7380 (lshiftrt:DI
7381 (mult:DI (sign_extend:DI
7382 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7383 (sign_extend:DI
7384 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7385 (const_int 32)))))
7386 (clobber (match_scratch:SI 3 "=1"))
7387 (clobber (reg:CC 17))]
7388 "TARGET_64BIT
7389 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7390 "imul{l}\t%2"
7391 [(set_attr "type" "imul")
7392 (set (attr "athlon_decode")
7393 (if_then_else (eq_attr "cpu" "athlon")
7394 (const_string "vector")
7395 (const_string "double")))
7396 (set_attr "mode" "SI")])
7397
7398 ;; The patterns that match these are at the end of this file.
7399
7400 (define_expand "mulxf3"
7401 [(set (match_operand:XF 0 "register_operand" "")
7402 (mult:XF (match_operand:XF 1 "register_operand" "")
7403 (match_operand:XF 2 "register_operand" "")))]
7404 "TARGET_80387"
7405 "")
7406
7407 (define_expand "muldf3"
7408 [(set (match_operand:DF 0 "register_operand" "")
7409 (mult:DF (match_operand:DF 1 "register_operand" "")
7410 (match_operand:DF 2 "nonimmediate_operand" "")))]
7411 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7412 "")
7413
7414 (define_expand "mulsf3"
7415 [(set (match_operand:SF 0 "register_operand" "")
7416 (mult:SF (match_operand:SF 1 "register_operand" "")
7417 (match_operand:SF 2 "nonimmediate_operand" "")))]
7418 "TARGET_80387 || TARGET_SSE_MATH"
7419 "")
7420 \f
7421 ;; Divide instructions
7422
7423 (define_insn "divqi3"
7424 [(set (match_operand:QI 0 "register_operand" "=a")
7425 (div:QI (match_operand:HI 1 "register_operand" "0")
7426 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7427 (clobber (reg:CC 17))]
7428 "TARGET_QIMODE_MATH"
7429 "idiv{b}\t%2"
7430 [(set_attr "type" "idiv")
7431 (set_attr "mode" "QI")])
7432
7433 (define_insn "udivqi3"
7434 [(set (match_operand:QI 0 "register_operand" "=a")
7435 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7436 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7437 (clobber (reg:CC 17))]
7438 "TARGET_QIMODE_MATH"
7439 "div{b}\t%2"
7440 [(set_attr "type" "idiv")
7441 (set_attr "mode" "QI")])
7442
7443 ;; The patterns that match these are at the end of this file.
7444
7445 (define_expand "divxf3"
7446 [(set (match_operand:XF 0 "register_operand" "")
7447 (div:XF (match_operand:XF 1 "register_operand" "")
7448 (match_operand:XF 2 "register_operand" "")))]
7449 "TARGET_80387"
7450 "")
7451
7452 (define_expand "divdf3"
7453 [(set (match_operand:DF 0 "register_operand" "")
7454 (div:DF (match_operand:DF 1 "register_operand" "")
7455 (match_operand:DF 2 "nonimmediate_operand" "")))]
7456 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7457 "")
7458
7459 (define_expand "divsf3"
7460 [(set (match_operand:SF 0 "register_operand" "")
7461 (div:SF (match_operand:SF 1 "register_operand" "")
7462 (match_operand:SF 2 "nonimmediate_operand" "")))]
7463 "TARGET_80387 || TARGET_SSE_MATH"
7464 "")
7465 \f
7466 ;; Remainder instructions.
7467
7468 (define_expand "divmoddi4"
7469 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7470 (div:DI (match_operand:DI 1 "register_operand" "")
7471 (match_operand:DI 2 "nonimmediate_operand" "")))
7472 (set (match_operand:DI 3 "register_operand" "")
7473 (mod:DI (match_dup 1) (match_dup 2)))
7474 (clobber (reg:CC 17))])]
7475 "TARGET_64BIT"
7476 "")
7477
7478 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7479 ;; Penalize eax case slightly because it results in worse scheduling
7480 ;; of code.
7481 (define_insn "*divmoddi4_nocltd_rex64"
7482 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7483 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7484 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7485 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7486 (mod:DI (match_dup 2) (match_dup 3)))
7487 (clobber (reg:CC 17))]
7488 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7489 "#"
7490 [(set_attr "type" "multi")])
7491
7492 (define_insn "*divmoddi4_cltd_rex64"
7493 [(set (match_operand:DI 0 "register_operand" "=a")
7494 (div:DI (match_operand:DI 2 "register_operand" "a")
7495 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7496 (set (match_operand:DI 1 "register_operand" "=&d")
7497 (mod:DI (match_dup 2) (match_dup 3)))
7498 (clobber (reg:CC 17))]
7499 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7500 "#"
7501 [(set_attr "type" "multi")])
7502
7503 (define_insn "*divmoddi_noext_rex64"
7504 [(set (match_operand:DI 0 "register_operand" "=a")
7505 (div:DI (match_operand:DI 1 "register_operand" "0")
7506 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7507 (set (match_operand:DI 3 "register_operand" "=d")
7508 (mod:DI (match_dup 1) (match_dup 2)))
7509 (use (match_operand:DI 4 "register_operand" "3"))
7510 (clobber (reg:CC 17))]
7511 "TARGET_64BIT"
7512 "idiv{q}\t%2"
7513 [(set_attr "type" "idiv")
7514 (set_attr "mode" "DI")])
7515
7516 (define_split
7517 [(set (match_operand:DI 0 "register_operand" "")
7518 (div:DI (match_operand:DI 1 "register_operand" "")
7519 (match_operand:DI 2 "nonimmediate_operand" "")))
7520 (set (match_operand:DI 3 "register_operand" "")
7521 (mod:DI (match_dup 1) (match_dup 2)))
7522 (clobber (reg:CC 17))]
7523 "TARGET_64BIT && reload_completed"
7524 [(parallel [(set (match_dup 3)
7525 (ashiftrt:DI (match_dup 4) (const_int 63)))
7526 (clobber (reg:CC 17))])
7527 (parallel [(set (match_dup 0)
7528 (div:DI (reg:DI 0) (match_dup 2)))
7529 (set (match_dup 3)
7530 (mod:DI (reg:DI 0) (match_dup 2)))
7531 (use (match_dup 3))
7532 (clobber (reg:CC 17))])]
7533 {
7534 /* Avoid use of cltd in favor of a mov+shift. */
7535 if (!TARGET_USE_CLTD && !optimize_size)
7536 {
7537 if (true_regnum (operands[1]))
7538 emit_move_insn (operands[0], operands[1]);
7539 else
7540 emit_move_insn (operands[3], operands[1]);
7541 operands[4] = operands[3];
7542 }
7543 else
7544 {
7545 if (true_regnum (operands[1]))
7546 abort();
7547 operands[4] = operands[1];
7548 }
7549 })
7550
7551
7552 (define_expand "divmodsi4"
7553 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7554 (div:SI (match_operand:SI 1 "register_operand" "")
7555 (match_operand:SI 2 "nonimmediate_operand" "")))
7556 (set (match_operand:SI 3 "register_operand" "")
7557 (mod:SI (match_dup 1) (match_dup 2)))
7558 (clobber (reg:CC 17))])]
7559 ""
7560 "")
7561
7562 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7563 ;; Penalize eax case slightly because it results in worse scheduling
7564 ;; of code.
7565 (define_insn "*divmodsi4_nocltd"
7566 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7567 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7568 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7569 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7570 (mod:SI (match_dup 2) (match_dup 3)))
7571 (clobber (reg:CC 17))]
7572 "!optimize_size && !TARGET_USE_CLTD"
7573 "#"
7574 [(set_attr "type" "multi")])
7575
7576 (define_insn "*divmodsi4_cltd"
7577 [(set (match_operand:SI 0 "register_operand" "=a")
7578 (div:SI (match_operand:SI 2 "register_operand" "a")
7579 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7580 (set (match_operand:SI 1 "register_operand" "=&d")
7581 (mod:SI (match_dup 2) (match_dup 3)))
7582 (clobber (reg:CC 17))]
7583 "optimize_size || TARGET_USE_CLTD"
7584 "#"
7585 [(set_attr "type" "multi")])
7586
7587 (define_insn "*divmodsi_noext"
7588 [(set (match_operand:SI 0 "register_operand" "=a")
7589 (div:SI (match_operand:SI 1 "register_operand" "0")
7590 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7591 (set (match_operand:SI 3 "register_operand" "=d")
7592 (mod:SI (match_dup 1) (match_dup 2)))
7593 (use (match_operand:SI 4 "register_operand" "3"))
7594 (clobber (reg:CC 17))]
7595 ""
7596 "idiv{l}\t%2"
7597 [(set_attr "type" "idiv")
7598 (set_attr "mode" "SI")])
7599
7600 (define_split
7601 [(set (match_operand:SI 0 "register_operand" "")
7602 (div:SI (match_operand:SI 1 "register_operand" "")
7603 (match_operand:SI 2 "nonimmediate_operand" "")))
7604 (set (match_operand:SI 3 "register_operand" "")
7605 (mod:SI (match_dup 1) (match_dup 2)))
7606 (clobber (reg:CC 17))]
7607 "reload_completed"
7608 [(parallel [(set (match_dup 3)
7609 (ashiftrt:SI (match_dup 4) (const_int 31)))
7610 (clobber (reg:CC 17))])
7611 (parallel [(set (match_dup 0)
7612 (div:SI (reg:SI 0) (match_dup 2)))
7613 (set (match_dup 3)
7614 (mod:SI (reg:SI 0) (match_dup 2)))
7615 (use (match_dup 3))
7616 (clobber (reg:CC 17))])]
7617 {
7618 /* Avoid use of cltd in favor of a mov+shift. */
7619 if (!TARGET_USE_CLTD && !optimize_size)
7620 {
7621 if (true_regnum (operands[1]))
7622 emit_move_insn (operands[0], operands[1]);
7623 else
7624 emit_move_insn (operands[3], operands[1]);
7625 operands[4] = operands[3];
7626 }
7627 else
7628 {
7629 if (true_regnum (operands[1]))
7630 abort();
7631 operands[4] = operands[1];
7632 }
7633 })
7634 ;; %%% Split me.
7635 (define_insn "divmodhi4"
7636 [(set (match_operand:HI 0 "register_operand" "=a")
7637 (div:HI (match_operand:HI 1 "register_operand" "0")
7638 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7639 (set (match_operand:HI 3 "register_operand" "=&d")
7640 (mod:HI (match_dup 1) (match_dup 2)))
7641 (clobber (reg:CC 17))]
7642 "TARGET_HIMODE_MATH"
7643 "cwtd\;idiv{w}\t%2"
7644 [(set_attr "type" "multi")
7645 (set_attr "length_immediate" "0")
7646 (set_attr "mode" "SI")])
7647
7648 (define_insn "udivmoddi4"
7649 [(set (match_operand:DI 0 "register_operand" "=a")
7650 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7651 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7652 (set (match_operand:DI 3 "register_operand" "=&d")
7653 (umod:DI (match_dup 1) (match_dup 2)))
7654 (clobber (reg:CC 17))]
7655 "TARGET_64BIT"
7656 "xor{q}\t%3, %3\;div{q}\t%2"
7657 [(set_attr "type" "multi")
7658 (set_attr "length_immediate" "0")
7659 (set_attr "mode" "DI")])
7660
7661 (define_insn "*udivmoddi4_noext"
7662 [(set (match_operand:DI 0 "register_operand" "=a")
7663 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7664 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7665 (set (match_operand:DI 3 "register_operand" "=d")
7666 (umod:DI (match_dup 1) (match_dup 2)))
7667 (use (match_dup 3))
7668 (clobber (reg:CC 17))]
7669 "TARGET_64BIT"
7670 "div{q}\t%2"
7671 [(set_attr "type" "idiv")
7672 (set_attr "mode" "DI")])
7673
7674 (define_split
7675 [(set (match_operand:DI 0 "register_operand" "")
7676 (udiv:DI (match_operand:DI 1 "register_operand" "")
7677 (match_operand:DI 2 "nonimmediate_operand" "")))
7678 (set (match_operand:DI 3 "register_operand" "")
7679 (umod:DI (match_dup 1) (match_dup 2)))
7680 (clobber (reg:CC 17))]
7681 "TARGET_64BIT && reload_completed"
7682 [(set (match_dup 3) (const_int 0))
7683 (parallel [(set (match_dup 0)
7684 (udiv:DI (match_dup 1) (match_dup 2)))
7685 (set (match_dup 3)
7686 (umod:DI (match_dup 1) (match_dup 2)))
7687 (use (match_dup 3))
7688 (clobber (reg:CC 17))])]
7689 "")
7690
7691 (define_insn "udivmodsi4"
7692 [(set (match_operand:SI 0 "register_operand" "=a")
7693 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7694 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7695 (set (match_operand:SI 3 "register_operand" "=&d")
7696 (umod:SI (match_dup 1) (match_dup 2)))
7697 (clobber (reg:CC 17))]
7698 ""
7699 "xor{l}\t%3, %3\;div{l}\t%2"
7700 [(set_attr "type" "multi")
7701 (set_attr "length_immediate" "0")
7702 (set_attr "mode" "SI")])
7703
7704 (define_insn "*udivmodsi4_noext"
7705 [(set (match_operand:SI 0 "register_operand" "=a")
7706 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7707 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7708 (set (match_operand:SI 3 "register_operand" "=d")
7709 (umod:SI (match_dup 1) (match_dup 2)))
7710 (use (match_dup 3))
7711 (clobber (reg:CC 17))]
7712 ""
7713 "div{l}\t%2"
7714 [(set_attr "type" "idiv")
7715 (set_attr "mode" "SI")])
7716
7717 (define_split
7718 [(set (match_operand:SI 0 "register_operand" "")
7719 (udiv:SI (match_operand:SI 1 "register_operand" "")
7720 (match_operand:SI 2 "nonimmediate_operand" "")))
7721 (set (match_operand:SI 3 "register_operand" "")
7722 (umod:SI (match_dup 1) (match_dup 2)))
7723 (clobber (reg:CC 17))]
7724 "reload_completed"
7725 [(set (match_dup 3) (const_int 0))
7726 (parallel [(set (match_dup 0)
7727 (udiv:SI (match_dup 1) (match_dup 2)))
7728 (set (match_dup 3)
7729 (umod:SI (match_dup 1) (match_dup 2)))
7730 (use (match_dup 3))
7731 (clobber (reg:CC 17))])]
7732 "")
7733
7734 (define_expand "udivmodhi4"
7735 [(set (match_dup 4) (const_int 0))
7736 (parallel [(set (match_operand:HI 0 "register_operand" "")
7737 (udiv:HI (match_operand:HI 1 "register_operand" "")
7738 (match_operand:HI 2 "nonimmediate_operand" "")))
7739 (set (match_operand:HI 3 "register_operand" "")
7740 (umod:HI (match_dup 1) (match_dup 2)))
7741 (use (match_dup 4))
7742 (clobber (reg:CC 17))])]
7743 "TARGET_HIMODE_MATH"
7744 "operands[4] = gen_reg_rtx (HImode);")
7745
7746 (define_insn "*udivmodhi_noext"
7747 [(set (match_operand:HI 0 "register_operand" "=a")
7748 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7749 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7750 (set (match_operand:HI 3 "register_operand" "=d")
7751 (umod:HI (match_dup 1) (match_dup 2)))
7752 (use (match_operand:HI 4 "register_operand" "3"))
7753 (clobber (reg:CC 17))]
7754 ""
7755 "div{w}\t%2"
7756 [(set_attr "type" "idiv")
7757 (set_attr "mode" "HI")])
7758
7759 ;; We can not use div/idiv for double division, because it causes
7760 ;; "division by zero" on the overflow and that's not what we expect
7761 ;; from truncate. Because true (non truncating) double division is
7762 ;; never generated, we can't create this insn anyway.
7763 ;
7764 ;(define_insn ""
7765 ; [(set (match_operand:SI 0 "register_operand" "=a")
7766 ; (truncate:SI
7767 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7768 ; (zero_extend:DI
7769 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7770 ; (set (match_operand:SI 3 "register_operand" "=d")
7771 ; (truncate:SI
7772 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7773 ; (clobber (reg:CC 17))]
7774 ; ""
7775 ; "div{l}\t{%2, %0|%0, %2}"
7776 ; [(set_attr "type" "idiv")])
7777 \f
7778 ;;- Logical AND instructions
7779
7780 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7781 ;; Note that this excludes ah.
7782
7783 (define_insn "*testdi_1_rex64"
7784 [(set (reg 17)
7785 (compare
7786 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7787 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7788 (const_int 0)))]
7789 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7790 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7791 "@
7792 test{l}\t{%k1, %k0|%k0, %k1}
7793 test{l}\t{%k1, %k0|%k0, %k1}
7794 test{q}\t{%1, %0|%0, %1}
7795 test{q}\t{%1, %0|%0, %1}
7796 test{q}\t{%1, %0|%0, %1}"
7797 [(set_attr "type" "test")
7798 (set_attr "modrm" "0,1,0,1,1")
7799 (set_attr "mode" "SI,SI,DI,DI,DI")
7800 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7801
7802 (define_insn "testsi_1"
7803 [(set (reg 17)
7804 (compare
7805 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7806 (match_operand:SI 1 "general_operand" "in,in,rin"))
7807 (const_int 0)))]
7808 "ix86_match_ccmode (insn, CCNOmode)
7809 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7810 "test{l}\t{%1, %0|%0, %1}"
7811 [(set_attr "type" "test")
7812 (set_attr "modrm" "0,1,1")
7813 (set_attr "mode" "SI")
7814 (set_attr "pent_pair" "uv,np,uv")])
7815
7816 (define_expand "testsi_ccno_1"
7817 [(set (reg:CCNO 17)
7818 (compare:CCNO
7819 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7820 (match_operand:SI 1 "nonmemory_operand" ""))
7821 (const_int 0)))]
7822 ""
7823 "")
7824
7825 (define_insn "*testhi_1"
7826 [(set (reg 17)
7827 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7828 (match_operand:HI 1 "general_operand" "n,n,rn"))
7829 (const_int 0)))]
7830 "ix86_match_ccmode (insn, CCNOmode)
7831 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7832 "test{w}\t{%1, %0|%0, %1}"
7833 [(set_attr "type" "test")
7834 (set_attr "modrm" "0,1,1")
7835 (set_attr "mode" "HI")
7836 (set_attr "pent_pair" "uv,np,uv")])
7837
7838 (define_expand "testqi_ccz_1"
7839 [(set (reg:CCZ 17)
7840 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7841 (match_operand:QI 1 "nonmemory_operand" ""))
7842 (const_int 0)))]
7843 ""
7844 "")
7845
7846 (define_insn "*testqi_1"
7847 [(set (reg 17)
7848 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7849 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7850 (const_int 0)))]
7851 "ix86_match_ccmode (insn, CCNOmode)
7852 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7853 {
7854 if (which_alternative == 3)
7855 {
7856 if (GET_CODE (operands[1]) == CONST_INT
7857 && (INTVAL (operands[1]) & 0xffffff00))
7858 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7859 return "test{l}\t{%1, %k0|%k0, %1}";
7860 }
7861 return "test{b}\t{%1, %0|%0, %1}";
7862 }
7863 [(set_attr "type" "test")
7864 (set_attr "modrm" "0,1,1,1")
7865 (set_attr "mode" "QI,QI,QI,SI")
7866 (set_attr "pent_pair" "uv,np,uv,np")])
7867
7868 (define_expand "testqi_ext_ccno_0"
7869 [(set (reg:CCNO 17)
7870 (compare:CCNO
7871 (and:SI
7872 (zero_extract:SI
7873 (match_operand 0 "ext_register_operand" "")
7874 (const_int 8)
7875 (const_int 8))
7876 (match_operand 1 "const_int_operand" ""))
7877 (const_int 0)))]
7878 ""
7879 "")
7880
7881 (define_insn "*testqi_ext_0"
7882 [(set (reg 17)
7883 (compare
7884 (and:SI
7885 (zero_extract:SI
7886 (match_operand 0 "ext_register_operand" "Q")
7887 (const_int 8)
7888 (const_int 8))
7889 (match_operand 1 "const_int_operand" "n"))
7890 (const_int 0)))]
7891 "ix86_match_ccmode (insn, CCNOmode)"
7892 "test{b}\t{%1, %h0|%h0, %1}"
7893 [(set_attr "type" "test")
7894 (set_attr "mode" "QI")
7895 (set_attr "length_immediate" "1")
7896 (set_attr "pent_pair" "np")])
7897
7898 (define_insn "*testqi_ext_1"
7899 [(set (reg 17)
7900 (compare
7901 (and:SI
7902 (zero_extract:SI
7903 (match_operand 0 "ext_register_operand" "Q")
7904 (const_int 8)
7905 (const_int 8))
7906 (zero_extend:SI
7907 (match_operand:QI 1 "general_operand" "Qm")))
7908 (const_int 0)))]
7909 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7910 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7911 "test{b}\t{%1, %h0|%h0, %1}"
7912 [(set_attr "type" "test")
7913 (set_attr "mode" "QI")])
7914
7915 (define_insn "*testqi_ext_1_rex64"
7916 [(set (reg 17)
7917 (compare
7918 (and:SI
7919 (zero_extract:SI
7920 (match_operand 0 "ext_register_operand" "Q")
7921 (const_int 8)
7922 (const_int 8))
7923 (zero_extend:SI
7924 (match_operand:QI 1 "register_operand" "Q")))
7925 (const_int 0)))]
7926 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7927 "test{b}\t{%1, %h0|%h0, %1}"
7928 [(set_attr "type" "test")
7929 (set_attr "mode" "QI")])
7930
7931 (define_insn "*testqi_ext_2"
7932 [(set (reg 17)
7933 (compare
7934 (and:SI
7935 (zero_extract:SI
7936 (match_operand 0 "ext_register_operand" "Q")
7937 (const_int 8)
7938 (const_int 8))
7939 (zero_extract:SI
7940 (match_operand 1 "ext_register_operand" "Q")
7941 (const_int 8)
7942 (const_int 8)))
7943 (const_int 0)))]
7944 "ix86_match_ccmode (insn, CCNOmode)"
7945 "test{b}\t{%h1, %h0|%h0, %h1}"
7946 [(set_attr "type" "test")
7947 (set_attr "mode" "QI")])
7948
7949 ;; Combine likes to form bit extractions for some tests. Humor it.
7950 (define_insn "*testqi_ext_3"
7951 [(set (reg 17)
7952 (compare (zero_extract:SI
7953 (match_operand 0 "nonimmediate_operand" "rm")
7954 (match_operand:SI 1 "const_int_operand" "")
7955 (match_operand:SI 2 "const_int_operand" ""))
7956 (const_int 0)))]
7957 "ix86_match_ccmode (insn, CCNOmode)
7958 && (GET_MODE (operands[0]) == SImode
7959 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7960 || GET_MODE (operands[0]) == HImode
7961 || GET_MODE (operands[0]) == QImode)"
7962 "#")
7963
7964 (define_insn "*testqi_ext_3_rex64"
7965 [(set (reg 17)
7966 (compare (zero_extract:DI
7967 (match_operand 0 "nonimmediate_operand" "rm")
7968 (match_operand:DI 1 "const_int_operand" "")
7969 (match_operand:DI 2 "const_int_operand" ""))
7970 (const_int 0)))]
7971 "TARGET_64BIT
7972 && ix86_match_ccmode (insn, CCNOmode)
7973 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7974 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7975 /* Ensure that resulting mask is zero or sign extended operand. */
7976 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7977 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7978 && INTVAL (operands[1]) > 32))
7979 && (GET_MODE (operands[0]) == SImode
7980 || GET_MODE (operands[0]) == DImode
7981 || GET_MODE (operands[0]) == HImode
7982 || GET_MODE (operands[0]) == QImode)"
7983 "#")
7984
7985 (define_split
7986 [(set (reg 17)
7987 (compare (zero_extract
7988 (match_operand 0 "nonimmediate_operand" "")
7989 (match_operand 1 "const_int_operand" "")
7990 (match_operand 2 "const_int_operand" ""))
7991 (const_int 0)))]
7992 "ix86_match_ccmode (insn, CCNOmode)"
7993 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
7994 {
7995 HOST_WIDE_INT len = INTVAL (operands[1]);
7996 HOST_WIDE_INT pos = INTVAL (operands[2]);
7997 HOST_WIDE_INT mask;
7998 enum machine_mode mode, submode;
7999
8000 mode = GET_MODE (operands[0]);
8001 if (GET_CODE (operands[0]) == MEM)
8002 {
8003 /* ??? Combine likes to put non-volatile mem extractions in QImode
8004 no matter the size of the test. So find a mode that works. */
8005 if (! MEM_VOLATILE_P (operands[0]))
8006 {
8007 mode = smallest_mode_for_size (pos + len, MODE_INT);
8008 operands[0] = adjust_address (operands[0], mode, 0);
8009 }
8010 }
8011 else if (GET_CODE (operands[0]) == SUBREG
8012 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8013 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8014 && pos + len <= GET_MODE_BITSIZE (submode))
8015 {
8016 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8017 mode = submode;
8018 operands[0] = SUBREG_REG (operands[0]);
8019 }
8020 else if (mode == HImode && pos + len <= 8)
8021 {
8022 /* Small HImode tests can be converted to QImode. */
8023 mode = QImode;
8024 operands[0] = gen_lowpart (QImode, operands[0]);
8025 }
8026
8027 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8028 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8029
8030 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8031 })
8032
8033 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8034 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8035 ;; this is relatively important trick.
8036 ;; Do the conversion only post-reload to avoid limiting of the register class
8037 ;; to QI regs.
8038 (define_split
8039 [(set (reg 17)
8040 (compare
8041 (and (match_operand 0 "register_operand" "")
8042 (match_operand 1 "const_int_operand" ""))
8043 (const_int 0)))]
8044 "reload_completed
8045 && QI_REG_P (operands[0])
8046 && ((ix86_match_ccmode (insn, CCZmode)
8047 && !(INTVAL (operands[1]) & ~(255 << 8)))
8048 || (ix86_match_ccmode (insn, CCNOmode)
8049 && !(INTVAL (operands[1]) & ~(127 << 8))))
8050 && GET_MODE (operands[0]) != QImode"
8051 [(set (reg:CCNO 17)
8052 (compare:CCNO
8053 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8054 (match_dup 1))
8055 (const_int 0)))]
8056 "operands[0] = gen_lowpart (SImode, operands[0]);
8057 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8058
8059 (define_split
8060 [(set (reg 17)
8061 (compare
8062 (and (match_operand 0 "nonimmediate_operand" "")
8063 (match_operand 1 "const_int_operand" ""))
8064 (const_int 0)))]
8065 "reload_completed
8066 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8067 && ((ix86_match_ccmode (insn, CCZmode)
8068 && !(INTVAL (operands[1]) & ~255))
8069 || (ix86_match_ccmode (insn, CCNOmode)
8070 && !(INTVAL (operands[1]) & ~127)))
8071 && GET_MODE (operands[0]) != QImode"
8072 [(set (reg:CCNO 17)
8073 (compare:CCNO
8074 (and:QI (match_dup 0)
8075 (match_dup 1))
8076 (const_int 0)))]
8077 "operands[0] = gen_lowpart (QImode, operands[0]);
8078 operands[1] = gen_lowpart (QImode, operands[1]);")
8079
8080
8081 ;; %%% This used to optimize known byte-wide and operations to memory,
8082 ;; and sometimes to QImode registers. If this is considered useful,
8083 ;; it should be done with splitters.
8084
8085 (define_expand "anddi3"
8086 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8087 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8088 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8089 (clobber (reg:CC 17))]
8090 "TARGET_64BIT"
8091 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8092
8093 (define_insn "*anddi_1_rex64"
8094 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8095 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8096 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8097 (clobber (reg:CC 17))]
8098 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8099 {
8100 switch (get_attr_type (insn))
8101 {
8102 case TYPE_IMOVX:
8103 {
8104 enum machine_mode mode;
8105
8106 if (GET_CODE (operands[2]) != CONST_INT)
8107 abort ();
8108 if (INTVAL (operands[2]) == 0xff)
8109 mode = QImode;
8110 else if (INTVAL (operands[2]) == 0xffff)
8111 mode = HImode;
8112 else
8113 abort ();
8114
8115 operands[1] = gen_lowpart (mode, operands[1]);
8116 if (mode == QImode)
8117 return "movz{bq|x}\t{%1,%0|%0, %1}";
8118 else
8119 return "movz{wq|x}\t{%1,%0|%0, %1}";
8120 }
8121
8122 default:
8123 if (! rtx_equal_p (operands[0], operands[1]))
8124 abort ();
8125 if (get_attr_mode (insn) == MODE_SI)
8126 return "and{l}\t{%k2, %k0|%k0, %k2}";
8127 else
8128 return "and{q}\t{%2, %0|%0, %2}";
8129 }
8130 }
8131 [(set_attr "type" "alu,alu,alu,imovx")
8132 (set_attr "length_immediate" "*,*,*,0")
8133 (set_attr "mode" "SI,DI,DI,DI")])
8134
8135 (define_insn "*anddi_2"
8136 [(set (reg 17)
8137 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8138 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8139 (const_int 0)))
8140 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8141 (and:DI (match_dup 1) (match_dup 2)))]
8142 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8143 && ix86_binary_operator_ok (AND, DImode, operands)"
8144 "@
8145 and{l}\t{%k2, %k0|%k0, %k2}
8146 and{q}\t{%2, %0|%0, %2}
8147 and{q}\t{%2, %0|%0, %2}"
8148 [(set_attr "type" "alu")
8149 (set_attr "mode" "SI,DI,DI")])
8150
8151 (define_expand "andsi3"
8152 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8153 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8154 (match_operand:SI 2 "general_operand" "")))
8155 (clobber (reg:CC 17))]
8156 ""
8157 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8158
8159 (define_insn "*andsi_1"
8160 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8161 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8162 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8163 (clobber (reg:CC 17))]
8164 "ix86_binary_operator_ok (AND, SImode, operands)"
8165 {
8166 switch (get_attr_type (insn))
8167 {
8168 case TYPE_IMOVX:
8169 {
8170 enum machine_mode mode;
8171
8172 if (GET_CODE (operands[2]) != CONST_INT)
8173 abort ();
8174 if (INTVAL (operands[2]) == 0xff)
8175 mode = QImode;
8176 else if (INTVAL (operands[2]) == 0xffff)
8177 mode = HImode;
8178 else
8179 abort ();
8180
8181 operands[1] = gen_lowpart (mode, operands[1]);
8182 if (mode == QImode)
8183 return "movz{bl|x}\t{%1,%0|%0, %1}";
8184 else
8185 return "movz{wl|x}\t{%1,%0|%0, %1}";
8186 }
8187
8188 default:
8189 if (! rtx_equal_p (operands[0], operands[1]))
8190 abort ();
8191 return "and{l}\t{%2, %0|%0, %2}";
8192 }
8193 }
8194 [(set_attr "type" "alu,alu,imovx")
8195 (set_attr "length_immediate" "*,*,0")
8196 (set_attr "mode" "SI")])
8197
8198 (define_split
8199 [(set (match_operand 0 "register_operand" "")
8200 (and (match_dup 0)
8201 (const_int -65536)))
8202 (clobber (reg:CC 17))]
8203 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8204 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8205 "operands[1] = gen_lowpart (HImode, operands[0]);")
8206
8207 (define_split
8208 [(set (match_operand 0 "ext_register_operand" "")
8209 (and (match_dup 0)
8210 (const_int -256)))
8211 (clobber (reg:CC 17))]
8212 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8213 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8214 "operands[1] = gen_lowpart (QImode, operands[0]);")
8215
8216 (define_split
8217 [(set (match_operand 0 "ext_register_operand" "")
8218 (and (match_dup 0)
8219 (const_int -65281)))
8220 (clobber (reg:CC 17))]
8221 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8222 [(parallel [(set (zero_extract:SI (match_dup 0)
8223 (const_int 8)
8224 (const_int 8))
8225 (xor:SI
8226 (zero_extract:SI (match_dup 0)
8227 (const_int 8)
8228 (const_int 8))
8229 (zero_extract:SI (match_dup 0)
8230 (const_int 8)
8231 (const_int 8))))
8232 (clobber (reg:CC 17))])]
8233 "operands[0] = gen_lowpart (SImode, operands[0]);")
8234
8235 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8236 (define_insn "*andsi_1_zext"
8237 [(set (match_operand:DI 0 "register_operand" "=r")
8238 (zero_extend:DI
8239 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8240 (match_operand:SI 2 "general_operand" "rim"))))
8241 (clobber (reg:CC 17))]
8242 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8243 "and{l}\t{%2, %k0|%k0, %2}"
8244 [(set_attr "type" "alu")
8245 (set_attr "mode" "SI")])
8246
8247 (define_insn "*andsi_2"
8248 [(set (reg 17)
8249 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8250 (match_operand:SI 2 "general_operand" "rim,ri"))
8251 (const_int 0)))
8252 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8253 (and:SI (match_dup 1) (match_dup 2)))]
8254 "ix86_match_ccmode (insn, CCNOmode)
8255 && ix86_binary_operator_ok (AND, SImode, operands)"
8256 "and{l}\t{%2, %0|%0, %2}"
8257 [(set_attr "type" "alu")
8258 (set_attr "mode" "SI")])
8259
8260 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8261 (define_insn "*andsi_2_zext"
8262 [(set (reg 17)
8263 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8264 (match_operand:SI 2 "general_operand" "rim"))
8265 (const_int 0)))
8266 (set (match_operand:DI 0 "register_operand" "=r")
8267 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8268 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8269 && ix86_binary_operator_ok (AND, SImode, operands)"
8270 "and{l}\t{%2, %k0|%k0, %2}"
8271 [(set_attr "type" "alu")
8272 (set_attr "mode" "SI")])
8273
8274 (define_expand "andhi3"
8275 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8276 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8277 (match_operand:HI 2 "general_operand" "")))
8278 (clobber (reg:CC 17))]
8279 "TARGET_HIMODE_MATH"
8280 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8281
8282 (define_insn "*andhi_1"
8283 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8284 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8285 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8286 (clobber (reg:CC 17))]
8287 "ix86_binary_operator_ok (AND, HImode, operands)"
8288 {
8289 switch (get_attr_type (insn))
8290 {
8291 case TYPE_IMOVX:
8292 if (GET_CODE (operands[2]) != CONST_INT)
8293 abort ();
8294 if (INTVAL (operands[2]) == 0xff)
8295 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8296 abort ();
8297
8298 default:
8299 if (! rtx_equal_p (operands[0], operands[1]))
8300 abort ();
8301
8302 return "and{w}\t{%2, %0|%0, %2}";
8303 }
8304 }
8305 [(set_attr "type" "alu,alu,imovx")
8306 (set_attr "length_immediate" "*,*,0")
8307 (set_attr "mode" "HI,HI,SI")])
8308
8309 (define_insn "*andhi_2"
8310 [(set (reg 17)
8311 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8312 (match_operand:HI 2 "general_operand" "rim,ri"))
8313 (const_int 0)))
8314 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8315 (and:HI (match_dup 1) (match_dup 2)))]
8316 "ix86_match_ccmode (insn, CCNOmode)
8317 && ix86_binary_operator_ok (AND, HImode, operands)"
8318 "and{w}\t{%2, %0|%0, %2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "mode" "HI")])
8321
8322 (define_expand "andqi3"
8323 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8324 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8325 (match_operand:QI 2 "general_operand" "")))
8326 (clobber (reg:CC 17))]
8327 "TARGET_QIMODE_MATH"
8328 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8329
8330 ;; %%% Potential partial reg stall on alternative 2. What to do?
8331 (define_insn "*andqi_1"
8332 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8333 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8334 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8335 (clobber (reg:CC 17))]
8336 "ix86_binary_operator_ok (AND, QImode, operands)"
8337 "@
8338 and{b}\t{%2, %0|%0, %2}
8339 and{b}\t{%2, %0|%0, %2}
8340 and{l}\t{%k2, %k0|%k0, %k2}"
8341 [(set_attr "type" "alu")
8342 (set_attr "mode" "QI,QI,SI")])
8343
8344 (define_insn "*andqi_1_slp"
8345 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8346 (and:QI (match_dup 0)
8347 (match_operand:QI 1 "general_operand" "qi,qmi")))
8348 (clobber (reg:CC 17))]
8349 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8350 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8351 "and{b}\t{%1, %0|%0, %1}"
8352 [(set_attr "type" "alu1")
8353 (set_attr "mode" "QI")])
8354
8355 (define_insn "*andqi_2"
8356 [(set (reg 17)
8357 (compare (and:QI
8358 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8359 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8360 (const_int 0)))
8361 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8362 (and:QI (match_dup 1) (match_dup 2)))]
8363 "ix86_match_ccmode (insn, CCNOmode)
8364 && ix86_binary_operator_ok (AND, QImode, operands)"
8365 {
8366 if (which_alternative == 2)
8367 {
8368 if (GET_CODE (operands[2]) == CONST_INT
8369 && (INTVAL (operands[2]) & 0xffffff00))
8370 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8371 return "and{l}\t{%2, %k0|%k0, %2}";
8372 }
8373 return "and{b}\t{%2, %0|%0, %2}";
8374 }
8375 [(set_attr "type" "alu")
8376 (set_attr "mode" "QI,QI,SI")])
8377
8378 (define_insn "*andqi_2_slp"
8379 [(set (reg 17)
8380 (compare (and:QI
8381 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8382 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8383 (const_int 0)))
8384 (set (strict_low_part (match_dup 0))
8385 (and:QI (match_dup 0) (match_dup 1)))]
8386 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8387 && ix86_match_ccmode (insn, CCNOmode)
8388 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8389 "and{b}\t{%1, %0|%0, %1}"
8390 [(set_attr "type" "alu1")
8391 (set_attr "mode" "QI")])
8392
8393 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8394 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8395 ;; for a QImode operand, which of course failed.
8396
8397 (define_insn "andqi_ext_0"
8398 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8399 (const_int 8)
8400 (const_int 8))
8401 (and:SI
8402 (zero_extract:SI
8403 (match_operand 1 "ext_register_operand" "0")
8404 (const_int 8)
8405 (const_int 8))
8406 (match_operand 2 "const_int_operand" "n")))
8407 (clobber (reg:CC 17))]
8408 ""
8409 "and{b}\t{%2, %h0|%h0, %2}"
8410 [(set_attr "type" "alu")
8411 (set_attr "length_immediate" "1")
8412 (set_attr "mode" "QI")])
8413
8414 ;; Generated by peephole translating test to and. This shows up
8415 ;; often in fp comparisons.
8416
8417 (define_insn "*andqi_ext_0_cc"
8418 [(set (reg 17)
8419 (compare
8420 (and:SI
8421 (zero_extract:SI
8422 (match_operand 1 "ext_register_operand" "0")
8423 (const_int 8)
8424 (const_int 8))
8425 (match_operand 2 "const_int_operand" "n"))
8426 (const_int 0)))
8427 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8428 (const_int 8)
8429 (const_int 8))
8430 (and:SI
8431 (zero_extract:SI
8432 (match_dup 1)
8433 (const_int 8)
8434 (const_int 8))
8435 (match_dup 2)))]
8436 "ix86_match_ccmode (insn, CCNOmode)"
8437 "and{b}\t{%2, %h0|%h0, %2}"
8438 [(set_attr "type" "alu")
8439 (set_attr "length_immediate" "1")
8440 (set_attr "mode" "QI")])
8441
8442 (define_insn "*andqi_ext_1"
8443 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444 (const_int 8)
8445 (const_int 8))
8446 (and:SI
8447 (zero_extract:SI
8448 (match_operand 1 "ext_register_operand" "0")
8449 (const_int 8)
8450 (const_int 8))
8451 (zero_extend:SI
8452 (match_operand:QI 2 "general_operand" "Qm"))))
8453 (clobber (reg:CC 17))]
8454 "!TARGET_64BIT"
8455 "and{b}\t{%2, %h0|%h0, %2}"
8456 [(set_attr "type" "alu")
8457 (set_attr "length_immediate" "0")
8458 (set_attr "mode" "QI")])
8459
8460 (define_insn "*andqi_ext_1_rex64"
8461 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8462 (const_int 8)
8463 (const_int 8))
8464 (and:SI
8465 (zero_extract:SI
8466 (match_operand 1 "ext_register_operand" "0")
8467 (const_int 8)
8468 (const_int 8))
8469 (zero_extend:SI
8470 (match_operand 2 "ext_register_operand" "Q"))))
8471 (clobber (reg:CC 17))]
8472 "TARGET_64BIT"
8473 "and{b}\t{%2, %h0|%h0, %2}"
8474 [(set_attr "type" "alu")
8475 (set_attr "length_immediate" "0")
8476 (set_attr "mode" "QI")])
8477
8478 (define_insn "*andqi_ext_2"
8479 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8480 (const_int 8)
8481 (const_int 8))
8482 (and:SI
8483 (zero_extract:SI
8484 (match_operand 1 "ext_register_operand" "%0")
8485 (const_int 8)
8486 (const_int 8))
8487 (zero_extract:SI
8488 (match_operand 2 "ext_register_operand" "Q")
8489 (const_int 8)
8490 (const_int 8))))
8491 (clobber (reg:CC 17))]
8492 ""
8493 "and{b}\t{%h2, %h0|%h0, %h2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "length_immediate" "0")
8496 (set_attr "mode" "QI")])
8497
8498 ;; Convert wide AND instructions with immediate operand to shorter QImode
8499 ;; equivalents when possible.
8500 ;; Don't do the splitting with memory operands, since it introduces risk
8501 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8502 ;; for size, but that can (should?) be handled by generic code instead.
8503 (define_split
8504 [(set (match_operand 0 "register_operand" "")
8505 (and (match_operand 1 "register_operand" "")
8506 (match_operand 2 "const_int_operand" "")))
8507 (clobber (reg:CC 17))]
8508 "reload_completed
8509 && QI_REG_P (operands[0])
8510 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8511 && !(~INTVAL (operands[2]) & ~(255 << 8))
8512 && GET_MODE (operands[0]) != QImode"
8513 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8514 (and:SI (zero_extract:SI (match_dup 1)
8515 (const_int 8) (const_int 8))
8516 (match_dup 2)))
8517 (clobber (reg:CC 17))])]
8518 "operands[0] = gen_lowpart (SImode, operands[0]);
8519 operands[1] = gen_lowpart (SImode, operands[1]);
8520 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8521
8522 ;; Since AND can be encoded with sign extended immediate, this is only
8523 ;; profitable when 7th bit is not set.
8524 (define_split
8525 [(set (match_operand 0 "register_operand" "")
8526 (and (match_operand 1 "general_operand" "")
8527 (match_operand 2 "const_int_operand" "")))
8528 (clobber (reg:CC 17))]
8529 "reload_completed
8530 && ANY_QI_REG_P (operands[0])
8531 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8532 && !(~INTVAL (operands[2]) & ~255)
8533 && !(INTVAL (operands[2]) & 128)
8534 && GET_MODE (operands[0]) != QImode"
8535 [(parallel [(set (strict_low_part (match_dup 0))
8536 (and:QI (match_dup 1)
8537 (match_dup 2)))
8538 (clobber (reg:CC 17))])]
8539 "operands[0] = gen_lowpart (QImode, operands[0]);
8540 operands[1] = gen_lowpart (QImode, operands[1]);
8541 operands[2] = gen_lowpart (QImode, operands[2]);")
8542 \f
8543 ;; Logical inclusive OR instructions
8544
8545 ;; %%% This used to optimize known byte-wide and operations to memory.
8546 ;; If this is considered useful, it should be done with splitters.
8547
8548 (define_expand "iordi3"
8549 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8550 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8551 (match_operand:DI 2 "x86_64_general_operand" "")))
8552 (clobber (reg:CC 17))]
8553 "TARGET_64BIT"
8554 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8555
8556 (define_insn "*iordi_1_rex64"
8557 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8558 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8559 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8560 (clobber (reg:CC 17))]
8561 "TARGET_64BIT
8562 && ix86_binary_operator_ok (IOR, DImode, operands)"
8563 "or{q}\t{%2, %0|%0, %2}"
8564 [(set_attr "type" "alu")
8565 (set_attr "mode" "DI")])
8566
8567 (define_insn "*iordi_2_rex64"
8568 [(set (reg 17)
8569 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8570 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8571 (const_int 0)))
8572 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8573 (ior:DI (match_dup 1) (match_dup 2)))]
8574 "TARGET_64BIT
8575 && ix86_match_ccmode (insn, CCNOmode)
8576 && ix86_binary_operator_ok (IOR, DImode, operands)"
8577 "or{q}\t{%2, %0|%0, %2}"
8578 [(set_attr "type" "alu")
8579 (set_attr "mode" "DI")])
8580
8581 (define_insn "*iordi_3_rex64"
8582 [(set (reg 17)
8583 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8584 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8585 (const_int 0)))
8586 (clobber (match_scratch:DI 0 "=r"))]
8587 "TARGET_64BIT
8588 && ix86_match_ccmode (insn, CCNOmode)
8589 && ix86_binary_operator_ok (IOR, DImode, operands)"
8590 "or{q}\t{%2, %0|%0, %2}"
8591 [(set_attr "type" "alu")
8592 (set_attr "mode" "DI")])
8593
8594
8595 (define_expand "iorsi3"
8596 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8597 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8598 (match_operand:SI 2 "general_operand" "")))
8599 (clobber (reg:CC 17))]
8600 ""
8601 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8602
8603 (define_insn "*iorsi_1"
8604 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8605 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8606 (match_operand:SI 2 "general_operand" "ri,rmi")))
8607 (clobber (reg:CC 17))]
8608 "ix86_binary_operator_ok (IOR, SImode, operands)"
8609 "or{l}\t{%2, %0|%0, %2}"
8610 [(set_attr "type" "alu")
8611 (set_attr "mode" "SI")])
8612
8613 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8614 (define_insn "*iorsi_1_zext"
8615 [(set (match_operand:DI 0 "register_operand" "=rm")
8616 (zero_extend:DI
8617 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8618 (match_operand:SI 2 "general_operand" "rim"))))
8619 (clobber (reg:CC 17))]
8620 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8621 "or{l}\t{%2, %k0|%k0, %2}"
8622 [(set_attr "type" "alu")
8623 (set_attr "mode" "SI")])
8624
8625 (define_insn "*iorsi_1_zext_imm"
8626 [(set (match_operand:DI 0 "register_operand" "=rm")
8627 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8628 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8629 (clobber (reg:CC 17))]
8630 "TARGET_64BIT"
8631 "or{l}\t{%2, %k0|%k0, %2}"
8632 [(set_attr "type" "alu")
8633 (set_attr "mode" "SI")])
8634
8635 (define_insn "*iorsi_2"
8636 [(set (reg 17)
8637 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8638 (match_operand:SI 2 "general_operand" "rim,ri"))
8639 (const_int 0)))
8640 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8641 (ior:SI (match_dup 1) (match_dup 2)))]
8642 "ix86_match_ccmode (insn, CCNOmode)
8643 && ix86_binary_operator_ok (IOR, SImode, operands)"
8644 "or{l}\t{%2, %0|%0, %2}"
8645 [(set_attr "type" "alu")
8646 (set_attr "mode" "SI")])
8647
8648 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8649 ;; ??? Special case for immediate operand is missing - it is tricky.
8650 (define_insn "*iorsi_2_zext"
8651 [(set (reg 17)
8652 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8653 (match_operand:SI 2 "general_operand" "rim"))
8654 (const_int 0)))
8655 (set (match_operand:DI 0 "register_operand" "=r")
8656 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8657 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8658 && ix86_binary_operator_ok (IOR, SImode, operands)"
8659 "or{l}\t{%2, %k0|%k0, %2}"
8660 [(set_attr "type" "alu")
8661 (set_attr "mode" "SI")])
8662
8663 (define_insn "*iorsi_2_zext_imm"
8664 [(set (reg 17)
8665 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8666 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8667 (const_int 0)))
8668 (set (match_operand:DI 0 "register_operand" "=r")
8669 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8670 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8671 && ix86_binary_operator_ok (IOR, SImode, operands)"
8672 "or{l}\t{%2, %k0|%k0, %2}"
8673 [(set_attr "type" "alu")
8674 (set_attr "mode" "SI")])
8675
8676 (define_insn "*iorsi_3"
8677 [(set (reg 17)
8678 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8679 (match_operand:SI 2 "general_operand" "rim"))
8680 (const_int 0)))
8681 (clobber (match_scratch:SI 0 "=r"))]
8682 "ix86_match_ccmode (insn, CCNOmode)
8683 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8684 "or{l}\t{%2, %0|%0, %2}"
8685 [(set_attr "type" "alu")
8686 (set_attr "mode" "SI")])
8687
8688 (define_expand "iorhi3"
8689 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8690 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8691 (match_operand:HI 2 "general_operand" "")))
8692 (clobber (reg:CC 17))]
8693 "TARGET_HIMODE_MATH"
8694 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8695
8696 (define_insn "*iorhi_1"
8697 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8698 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8699 (match_operand:HI 2 "general_operand" "rmi,ri")))
8700 (clobber (reg:CC 17))]
8701 "ix86_binary_operator_ok (IOR, HImode, operands)"
8702 "or{w}\t{%2, %0|%0, %2}"
8703 [(set_attr "type" "alu")
8704 (set_attr "mode" "HI")])
8705
8706 (define_insn "*iorhi_2"
8707 [(set (reg 17)
8708 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8709 (match_operand:HI 2 "general_operand" "rim,ri"))
8710 (const_int 0)))
8711 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8712 (ior:HI (match_dup 1) (match_dup 2)))]
8713 "ix86_match_ccmode (insn, CCNOmode)
8714 && ix86_binary_operator_ok (IOR, HImode, operands)"
8715 "or{w}\t{%2, %0|%0, %2}"
8716 [(set_attr "type" "alu")
8717 (set_attr "mode" "HI")])
8718
8719 (define_insn "*iorhi_3"
8720 [(set (reg 17)
8721 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8722 (match_operand:HI 2 "general_operand" "rim"))
8723 (const_int 0)))
8724 (clobber (match_scratch:HI 0 "=r"))]
8725 "ix86_match_ccmode (insn, CCNOmode)
8726 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8727 "or{w}\t{%2, %0|%0, %2}"
8728 [(set_attr "type" "alu")
8729 (set_attr "mode" "HI")])
8730
8731 (define_expand "iorqi3"
8732 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8733 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8734 (match_operand:QI 2 "general_operand" "")))
8735 (clobber (reg:CC 17))]
8736 "TARGET_QIMODE_MATH"
8737 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8738
8739 ;; %%% Potential partial reg stall on alternative 2. What to do?
8740 (define_insn "*iorqi_1"
8741 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8742 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8743 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8744 (clobber (reg:CC 17))]
8745 "ix86_binary_operator_ok (IOR, QImode, operands)"
8746 "@
8747 or{b}\t{%2, %0|%0, %2}
8748 or{b}\t{%2, %0|%0, %2}
8749 or{l}\t{%k2, %k0|%k0, %k2}"
8750 [(set_attr "type" "alu")
8751 (set_attr "mode" "QI,QI,SI")])
8752
8753 (define_insn "*iorqi_1_slp"
8754 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8755 (ior:QI (match_dup 0)
8756 (match_operand:QI 1 "general_operand" "qmi,qi")))
8757 (clobber (reg:CC 17))]
8758 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8759 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8760 "or{b}\t{%1, %0|%0, %1}"
8761 [(set_attr "type" "alu1")
8762 (set_attr "mode" "QI")])
8763
8764 (define_insn "*iorqi_2"
8765 [(set (reg 17)
8766 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8767 (match_operand:QI 2 "general_operand" "qim,qi"))
8768 (const_int 0)))
8769 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8770 (ior:QI (match_dup 1) (match_dup 2)))]
8771 "ix86_match_ccmode (insn, CCNOmode)
8772 && ix86_binary_operator_ok (IOR, QImode, operands)"
8773 "or{b}\t{%2, %0|%0, %2}"
8774 [(set_attr "type" "alu")
8775 (set_attr "mode" "QI")])
8776
8777 (define_insn "*iorqi_2_slp"
8778 [(set (reg 17)
8779 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8780 (match_operand:QI 1 "general_operand" "qim,qi"))
8781 (const_int 0)))
8782 (set (strict_low_part (match_dup 0))
8783 (ior:QI (match_dup 0) (match_dup 1)))]
8784 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8785 && ix86_match_ccmode (insn, CCNOmode)
8786 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8787 "or{b}\t{%1, %0|%0, %1}"
8788 [(set_attr "type" "alu1")
8789 (set_attr "mode" "QI")])
8790
8791 (define_insn "*iorqi_3"
8792 [(set (reg 17)
8793 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8794 (match_operand:QI 2 "general_operand" "qim"))
8795 (const_int 0)))
8796 (clobber (match_scratch:QI 0 "=q"))]
8797 "ix86_match_ccmode (insn, CCNOmode)
8798 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8799 "or{b}\t{%2, %0|%0, %2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "mode" "QI")])
8802
8803 (define_insn "iorqi_ext_0"
8804 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8805 (const_int 8)
8806 (const_int 8))
8807 (ior:SI
8808 (zero_extract:SI
8809 (match_operand 1 "ext_register_operand" "0")
8810 (const_int 8)
8811 (const_int 8))
8812 (match_operand 2 "const_int_operand" "n")))
8813 (clobber (reg:CC 17))]
8814 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8815 "or{b}\t{%2, %h0|%h0, %2}"
8816 [(set_attr "type" "alu")
8817 (set_attr "length_immediate" "1")
8818 (set_attr "mode" "QI")])
8819
8820 (define_insn "*iorqi_ext_1"
8821 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8822 (const_int 8)
8823 (const_int 8))
8824 (ior:SI
8825 (zero_extract:SI
8826 (match_operand 1 "ext_register_operand" "0")
8827 (const_int 8)
8828 (const_int 8))
8829 (zero_extend:SI
8830 (match_operand:QI 2 "general_operand" "Qm"))))
8831 (clobber (reg:CC 17))]
8832 "!TARGET_64BIT
8833 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8834 "or{b}\t{%2, %h0|%h0, %2}"
8835 [(set_attr "type" "alu")
8836 (set_attr "length_immediate" "0")
8837 (set_attr "mode" "QI")])
8838
8839 (define_insn "*iorqi_ext_1_rex64"
8840 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8841 (const_int 8)
8842 (const_int 8))
8843 (ior:SI
8844 (zero_extract:SI
8845 (match_operand 1 "ext_register_operand" "0")
8846 (const_int 8)
8847 (const_int 8))
8848 (zero_extend:SI
8849 (match_operand 2 "ext_register_operand" "Q"))))
8850 (clobber (reg:CC 17))]
8851 "TARGET_64BIT
8852 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8853 "or{b}\t{%2, %h0|%h0, %2}"
8854 [(set_attr "type" "alu")
8855 (set_attr "length_immediate" "0")
8856 (set_attr "mode" "QI")])
8857
8858 (define_insn "*iorqi_ext_2"
8859 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8860 (const_int 8)
8861 (const_int 8))
8862 (ior:SI
8863 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8864 (const_int 8)
8865 (const_int 8))
8866 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8867 (const_int 8)
8868 (const_int 8))))
8869 (clobber (reg:CC 17))]
8870 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8871 "ior{b}\t{%h2, %h0|%h0, %h2}"
8872 [(set_attr "type" "alu")
8873 (set_attr "length_immediate" "0")
8874 (set_attr "mode" "QI")])
8875
8876 (define_split
8877 [(set (match_operand 0 "register_operand" "")
8878 (ior (match_operand 1 "register_operand" "")
8879 (match_operand 2 "const_int_operand" "")))
8880 (clobber (reg:CC 17))]
8881 "reload_completed
8882 && QI_REG_P (operands[0])
8883 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8884 && !(INTVAL (operands[2]) & ~(255 << 8))
8885 && GET_MODE (operands[0]) != QImode"
8886 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8887 (ior:SI (zero_extract:SI (match_dup 1)
8888 (const_int 8) (const_int 8))
8889 (match_dup 2)))
8890 (clobber (reg:CC 17))])]
8891 "operands[0] = gen_lowpart (SImode, operands[0]);
8892 operands[1] = gen_lowpart (SImode, operands[1]);
8893 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8894
8895 ;; Since OR can be encoded with sign extended immediate, this is only
8896 ;; profitable when 7th bit is set.
8897 (define_split
8898 [(set (match_operand 0 "register_operand" "")
8899 (ior (match_operand 1 "general_operand" "")
8900 (match_operand 2 "const_int_operand" "")))
8901 (clobber (reg:CC 17))]
8902 "reload_completed
8903 && ANY_QI_REG_P (operands[0])
8904 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8905 && !(INTVAL (operands[2]) & ~255)
8906 && (INTVAL (operands[2]) & 128)
8907 && GET_MODE (operands[0]) != QImode"
8908 [(parallel [(set (strict_low_part (match_dup 0))
8909 (ior:QI (match_dup 1)
8910 (match_dup 2)))
8911 (clobber (reg:CC 17))])]
8912 "operands[0] = gen_lowpart (QImode, operands[0]);
8913 operands[1] = gen_lowpart (QImode, operands[1]);
8914 operands[2] = gen_lowpart (QImode, operands[2]);")
8915 \f
8916 ;; Logical XOR instructions
8917
8918 ;; %%% This used to optimize known byte-wide and operations to memory.
8919 ;; If this is considered useful, it should be done with splitters.
8920
8921 (define_expand "xordi3"
8922 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8923 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8924 (match_operand:DI 2 "x86_64_general_operand" "")))
8925 (clobber (reg:CC 17))]
8926 "TARGET_64BIT"
8927 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8928
8929 (define_insn "*xordi_1_rex64"
8930 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8931 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8932 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8933 (clobber (reg:CC 17))]
8934 "TARGET_64BIT
8935 && ix86_binary_operator_ok (XOR, DImode, operands)"
8936 "@
8937 xor{q}\t{%2, %0|%0, %2}
8938 xor{q}\t{%2, %0|%0, %2}"
8939 [(set_attr "type" "alu")
8940 (set_attr "mode" "DI,DI")])
8941
8942 (define_insn "*xordi_2_rex64"
8943 [(set (reg 17)
8944 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8945 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8946 (const_int 0)))
8947 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8948 (xor:DI (match_dup 1) (match_dup 2)))]
8949 "TARGET_64BIT
8950 && ix86_match_ccmode (insn, CCNOmode)
8951 && ix86_binary_operator_ok (XOR, DImode, operands)"
8952 "@
8953 xor{q}\t{%2, %0|%0, %2}
8954 xor{q}\t{%2, %0|%0, %2}"
8955 [(set_attr "type" "alu")
8956 (set_attr "mode" "DI,DI")])
8957
8958 (define_insn "*xordi_3_rex64"
8959 [(set (reg 17)
8960 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8961 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8962 (const_int 0)))
8963 (clobber (match_scratch:DI 0 "=r"))]
8964 "TARGET_64BIT
8965 && ix86_match_ccmode (insn, CCNOmode)
8966 && ix86_binary_operator_ok (XOR, DImode, operands)"
8967 "xor{q}\t{%2, %0|%0, %2}"
8968 [(set_attr "type" "alu")
8969 (set_attr "mode" "DI")])
8970
8971 (define_expand "xorsi3"
8972 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8973 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8974 (match_operand:SI 2 "general_operand" "")))
8975 (clobber (reg:CC 17))]
8976 ""
8977 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8978
8979 (define_insn "*xorsi_1"
8980 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8981 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8982 (match_operand:SI 2 "general_operand" "ri,rm")))
8983 (clobber (reg:CC 17))]
8984 "ix86_binary_operator_ok (XOR, SImode, operands)"
8985 "xor{l}\t{%2, %0|%0, %2}"
8986 [(set_attr "type" "alu")
8987 (set_attr "mode" "SI")])
8988
8989 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8990 ;; Add speccase for immediates
8991 (define_insn "*xorsi_1_zext"
8992 [(set (match_operand:DI 0 "register_operand" "=r")
8993 (zero_extend:DI
8994 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8995 (match_operand:SI 2 "general_operand" "rim"))))
8996 (clobber (reg:CC 17))]
8997 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8998 "xor{l}\t{%2, %k0|%k0, %2}"
8999 [(set_attr "type" "alu")
9000 (set_attr "mode" "SI")])
9001
9002 (define_insn "*xorsi_1_zext_imm"
9003 [(set (match_operand:DI 0 "register_operand" "=r")
9004 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9005 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9006 (clobber (reg:CC 17))]
9007 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9008 "xor{l}\t{%2, %k0|%k0, %2}"
9009 [(set_attr "type" "alu")
9010 (set_attr "mode" "SI")])
9011
9012 (define_insn "*xorsi_2"
9013 [(set (reg 17)
9014 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9015 (match_operand:SI 2 "general_operand" "rim,ri"))
9016 (const_int 0)))
9017 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9018 (xor:SI (match_dup 1) (match_dup 2)))]
9019 "ix86_match_ccmode (insn, CCNOmode)
9020 && ix86_binary_operator_ok (XOR, SImode, operands)"
9021 "xor{l}\t{%2, %0|%0, %2}"
9022 [(set_attr "type" "alu")
9023 (set_attr "mode" "SI")])
9024
9025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9026 ;; ??? Special case for immediate operand is missing - it is tricky.
9027 (define_insn "*xorsi_2_zext"
9028 [(set (reg 17)
9029 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9030 (match_operand:SI 2 "general_operand" "rim"))
9031 (const_int 0)))
9032 (set (match_operand:DI 0 "register_operand" "=r")
9033 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9034 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9035 && ix86_binary_operator_ok (XOR, SImode, operands)"
9036 "xor{l}\t{%2, %k0|%k0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "SI")])
9039
9040 (define_insn "*xorsi_2_zext_imm"
9041 [(set (reg 17)
9042 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9043 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9044 (const_int 0)))
9045 (set (match_operand:DI 0 "register_operand" "=r")
9046 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9047 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9048 && ix86_binary_operator_ok (XOR, SImode, operands)"
9049 "xor{l}\t{%2, %k0|%k0, %2}"
9050 [(set_attr "type" "alu")
9051 (set_attr "mode" "SI")])
9052
9053 (define_insn "*xorsi_3"
9054 [(set (reg 17)
9055 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9056 (match_operand:SI 2 "general_operand" "rim"))
9057 (const_int 0)))
9058 (clobber (match_scratch:SI 0 "=r"))]
9059 "ix86_match_ccmode (insn, CCNOmode)
9060 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9061 "xor{l}\t{%2, %0|%0, %2}"
9062 [(set_attr "type" "alu")
9063 (set_attr "mode" "SI")])
9064
9065 (define_expand "xorhi3"
9066 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9067 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9068 (match_operand:HI 2 "general_operand" "")))
9069 (clobber (reg:CC 17))]
9070 "TARGET_HIMODE_MATH"
9071 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9072
9073 (define_insn "*xorhi_1"
9074 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9075 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9076 (match_operand:HI 2 "general_operand" "rmi,ri")))
9077 (clobber (reg:CC 17))]
9078 "ix86_binary_operator_ok (XOR, HImode, operands)"
9079 "xor{w}\t{%2, %0|%0, %2}"
9080 [(set_attr "type" "alu")
9081 (set_attr "mode" "HI")])
9082
9083 (define_insn "*xorhi_2"
9084 [(set (reg 17)
9085 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9086 (match_operand:HI 2 "general_operand" "rim,ri"))
9087 (const_int 0)))
9088 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9089 (xor:HI (match_dup 1) (match_dup 2)))]
9090 "ix86_match_ccmode (insn, CCNOmode)
9091 && ix86_binary_operator_ok (XOR, HImode, operands)"
9092 "xor{w}\t{%2, %0|%0, %2}"
9093 [(set_attr "type" "alu")
9094 (set_attr "mode" "HI")])
9095
9096 (define_insn "*xorhi_3"
9097 [(set (reg 17)
9098 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9099 (match_operand:HI 2 "general_operand" "rim"))
9100 (const_int 0)))
9101 (clobber (match_scratch:HI 0 "=r"))]
9102 "ix86_match_ccmode (insn, CCNOmode)
9103 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9104 "xor{w}\t{%2, %0|%0, %2}"
9105 [(set_attr "type" "alu")
9106 (set_attr "mode" "HI")])
9107
9108 (define_expand "xorqi3"
9109 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9110 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9111 (match_operand:QI 2 "general_operand" "")))
9112 (clobber (reg:CC 17))]
9113 "TARGET_QIMODE_MATH"
9114 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9115
9116 ;; %%% Potential partial reg stall on alternative 2. What to do?
9117 (define_insn "*xorqi_1"
9118 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9119 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9120 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9121 (clobber (reg:CC 17))]
9122 "ix86_binary_operator_ok (XOR, QImode, operands)"
9123 "@
9124 xor{b}\t{%2, %0|%0, %2}
9125 xor{b}\t{%2, %0|%0, %2}
9126 xor{l}\t{%k2, %k0|%k0, %k2}"
9127 [(set_attr "type" "alu")
9128 (set_attr "mode" "QI,QI,SI")])
9129
9130 (define_insn "*xorqi_1_slp"
9131 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9132 (xor:QI (match_dup 0)
9133 (match_operand:QI 1 "general_operand" "qi,qmi")))
9134 (clobber (reg:CC 17))]
9135 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9136 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9137 "xor{b}\t{%1, %0|%0, %1}"
9138 [(set_attr "type" "alu1")
9139 (set_attr "mode" "QI")])
9140
9141 (define_insn "xorqi_ext_0"
9142 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9143 (const_int 8)
9144 (const_int 8))
9145 (xor:SI
9146 (zero_extract:SI
9147 (match_operand 1 "ext_register_operand" "0")
9148 (const_int 8)
9149 (const_int 8))
9150 (match_operand 2 "const_int_operand" "n")))
9151 (clobber (reg:CC 17))]
9152 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9153 "xor{b}\t{%2, %h0|%h0, %2}"
9154 [(set_attr "type" "alu")
9155 (set_attr "length_immediate" "1")
9156 (set_attr "mode" "QI")])
9157
9158 (define_insn "*xorqi_ext_1"
9159 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9160 (const_int 8)
9161 (const_int 8))
9162 (xor:SI
9163 (zero_extract:SI
9164 (match_operand 1 "ext_register_operand" "0")
9165 (const_int 8)
9166 (const_int 8))
9167 (zero_extend:SI
9168 (match_operand:QI 2 "general_operand" "Qm"))))
9169 (clobber (reg:CC 17))]
9170 "!TARGET_64BIT
9171 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9172 "xor{b}\t{%2, %h0|%h0, %2}"
9173 [(set_attr "type" "alu")
9174 (set_attr "length_immediate" "0")
9175 (set_attr "mode" "QI")])
9176
9177 (define_insn "*xorqi_ext_1_rex64"
9178 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9179 (const_int 8)
9180 (const_int 8))
9181 (xor:SI
9182 (zero_extract:SI
9183 (match_operand 1 "ext_register_operand" "0")
9184 (const_int 8)
9185 (const_int 8))
9186 (zero_extend:SI
9187 (match_operand 2 "ext_register_operand" "Q"))))
9188 (clobber (reg:CC 17))]
9189 "TARGET_64BIT
9190 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9191 "xor{b}\t{%2, %h0|%h0, %2}"
9192 [(set_attr "type" "alu")
9193 (set_attr "length_immediate" "0")
9194 (set_attr "mode" "QI")])
9195
9196 (define_insn "*xorqi_ext_2"
9197 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9198 (const_int 8)
9199 (const_int 8))
9200 (xor:SI
9201 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9202 (const_int 8)
9203 (const_int 8))
9204 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9205 (const_int 8)
9206 (const_int 8))))
9207 (clobber (reg:CC 17))]
9208 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9209 "xor{b}\t{%h2, %h0|%h0, %h2}"
9210 [(set_attr "type" "alu")
9211 (set_attr "length_immediate" "0")
9212 (set_attr "mode" "QI")])
9213
9214 (define_insn "*xorqi_cc_1"
9215 [(set (reg 17)
9216 (compare
9217 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9218 (match_operand:QI 2 "general_operand" "qim,qi"))
9219 (const_int 0)))
9220 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9221 (xor:QI (match_dup 1) (match_dup 2)))]
9222 "ix86_match_ccmode (insn, CCNOmode)
9223 && ix86_binary_operator_ok (XOR, QImode, operands)"
9224 "xor{b}\t{%2, %0|%0, %2}"
9225 [(set_attr "type" "alu")
9226 (set_attr "mode" "QI")])
9227
9228 (define_insn "*xorqi_2_slp"
9229 [(set (reg 17)
9230 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9231 (match_operand:QI 1 "general_operand" "qim,qi"))
9232 (const_int 0)))
9233 (set (strict_low_part (match_dup 0))
9234 (xor:QI (match_dup 0) (match_dup 1)))]
9235 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9236 && ix86_match_ccmode (insn, CCNOmode)
9237 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9238 "xor{b}\t{%1, %0|%0, %1}"
9239 [(set_attr "type" "alu1")
9240 (set_attr "mode" "QI")])
9241
9242 (define_insn "*xorqi_cc_2"
9243 [(set (reg 17)
9244 (compare
9245 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9246 (match_operand:QI 2 "general_operand" "qim"))
9247 (const_int 0)))
9248 (clobber (match_scratch:QI 0 "=q"))]
9249 "ix86_match_ccmode (insn, CCNOmode)
9250 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9251 "xor{b}\t{%2, %0|%0, %2}"
9252 [(set_attr "type" "alu")
9253 (set_attr "mode" "QI")])
9254
9255 (define_insn "*xorqi_cc_ext_1"
9256 [(set (reg 17)
9257 (compare
9258 (xor:SI
9259 (zero_extract:SI
9260 (match_operand 1 "ext_register_operand" "0")
9261 (const_int 8)
9262 (const_int 8))
9263 (match_operand:QI 2 "general_operand" "qmn"))
9264 (const_int 0)))
9265 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9266 (const_int 8)
9267 (const_int 8))
9268 (xor:SI
9269 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9270 (match_dup 2)))]
9271 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9272 "xor{b}\t{%2, %h0|%h0, %2}"
9273 [(set_attr "type" "alu")
9274 (set_attr "mode" "QI")])
9275
9276 (define_insn "*xorqi_cc_ext_1_rex64"
9277 [(set (reg 17)
9278 (compare
9279 (xor:SI
9280 (zero_extract:SI
9281 (match_operand 1 "ext_register_operand" "0")
9282 (const_int 8)
9283 (const_int 8))
9284 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9285 (const_int 0)))
9286 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9287 (const_int 8)
9288 (const_int 8))
9289 (xor:SI
9290 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9291 (match_dup 2)))]
9292 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9293 "xor{b}\t{%2, %h0|%h0, %2}"
9294 [(set_attr "type" "alu")
9295 (set_attr "mode" "QI")])
9296
9297 (define_expand "xorqi_cc_ext_1"
9298 [(parallel [
9299 (set (reg:CCNO 17)
9300 (compare:CCNO
9301 (xor:SI
9302 (zero_extract:SI
9303 (match_operand 1 "ext_register_operand" "")
9304 (const_int 8)
9305 (const_int 8))
9306 (match_operand:QI 2 "general_operand" ""))
9307 (const_int 0)))
9308 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9309 (const_int 8)
9310 (const_int 8))
9311 (xor:SI
9312 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9313 (match_dup 2)))])]
9314 ""
9315 "")
9316
9317 (define_split
9318 [(set (match_operand 0 "register_operand" "")
9319 (xor (match_operand 1 "register_operand" "")
9320 (match_operand 2 "const_int_operand" "")))
9321 (clobber (reg:CC 17))]
9322 "reload_completed
9323 && QI_REG_P (operands[0])
9324 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9325 && !(INTVAL (operands[2]) & ~(255 << 8))
9326 && GET_MODE (operands[0]) != QImode"
9327 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9328 (xor:SI (zero_extract:SI (match_dup 1)
9329 (const_int 8) (const_int 8))
9330 (match_dup 2)))
9331 (clobber (reg:CC 17))])]
9332 "operands[0] = gen_lowpart (SImode, operands[0]);
9333 operands[1] = gen_lowpart (SImode, operands[1]);
9334 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9335
9336 ;; Since XOR can be encoded with sign extended immediate, this is only
9337 ;; profitable when 7th bit is set.
9338 (define_split
9339 [(set (match_operand 0 "register_operand" "")
9340 (xor (match_operand 1 "general_operand" "")
9341 (match_operand 2 "const_int_operand" "")))
9342 (clobber (reg:CC 17))]
9343 "reload_completed
9344 && ANY_QI_REG_P (operands[0])
9345 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9346 && !(INTVAL (operands[2]) & ~255)
9347 && (INTVAL (operands[2]) & 128)
9348 && GET_MODE (operands[0]) != QImode"
9349 [(parallel [(set (strict_low_part (match_dup 0))
9350 (xor:QI (match_dup 1)
9351 (match_dup 2)))
9352 (clobber (reg:CC 17))])]
9353 "operands[0] = gen_lowpart (QImode, operands[0]);
9354 operands[1] = gen_lowpart (QImode, operands[1]);
9355 operands[2] = gen_lowpart (QImode, operands[2]);")
9356 \f
9357 ;; Negation instructions
9358
9359 (define_expand "negdi2"
9360 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9361 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9362 (clobber (reg:CC 17))])]
9363 ""
9364 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9365
9366 (define_insn "*negdi2_1"
9367 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9368 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9369 (clobber (reg:CC 17))]
9370 "!TARGET_64BIT
9371 && ix86_unary_operator_ok (NEG, DImode, operands)"
9372 "#")
9373
9374 (define_split
9375 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9376 (neg:DI (match_operand:DI 1 "general_operand" "")))
9377 (clobber (reg:CC 17))]
9378 "!TARGET_64BIT && reload_completed"
9379 [(parallel
9380 [(set (reg:CCZ 17)
9381 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9382 (set (match_dup 0) (neg:SI (match_dup 2)))])
9383 (parallel
9384 [(set (match_dup 1)
9385 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9386 (match_dup 3))
9387 (const_int 0)))
9388 (clobber (reg:CC 17))])
9389 (parallel
9390 [(set (match_dup 1)
9391 (neg:SI (match_dup 1)))
9392 (clobber (reg:CC 17))])]
9393 "split_di (operands+1, 1, operands+2, operands+3);
9394 split_di (operands+0, 1, operands+0, operands+1);")
9395
9396 (define_insn "*negdi2_1_rex64"
9397 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9398 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9399 (clobber (reg:CC 17))]
9400 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9401 "neg{q}\t%0"
9402 [(set_attr "type" "negnot")
9403 (set_attr "mode" "DI")])
9404
9405 ;; The problem with neg is that it does not perform (compare x 0),
9406 ;; it really performs (compare 0 x), which leaves us with the zero
9407 ;; flag being the only useful item.
9408
9409 (define_insn "*negdi2_cmpz_rex64"
9410 [(set (reg:CCZ 17)
9411 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9412 (const_int 0)))
9413 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9414 (neg:DI (match_dup 1)))]
9415 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9416 "neg{q}\t%0"
9417 [(set_attr "type" "negnot")
9418 (set_attr "mode" "DI")])
9419
9420
9421 (define_expand "negsi2"
9422 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9423 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9424 (clobber (reg:CC 17))])]
9425 ""
9426 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9427
9428 (define_insn "*negsi2_1"
9429 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9430 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9431 (clobber (reg:CC 17))]
9432 "ix86_unary_operator_ok (NEG, SImode, operands)"
9433 "neg{l}\t%0"
9434 [(set_attr "type" "negnot")
9435 (set_attr "mode" "SI")])
9436
9437 ;; Combine is quite creative about this pattern.
9438 (define_insn "*negsi2_1_zext"
9439 [(set (match_operand:DI 0 "register_operand" "=r")
9440 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9441 (const_int 32)))
9442 (const_int 32)))
9443 (clobber (reg:CC 17))]
9444 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9445 "neg{l}\t%k0"
9446 [(set_attr "type" "negnot")
9447 (set_attr "mode" "SI")])
9448
9449 ;; The problem with neg is that it does not perform (compare x 0),
9450 ;; it really performs (compare 0 x), which leaves us with the zero
9451 ;; flag being the only useful item.
9452
9453 (define_insn "*negsi2_cmpz"
9454 [(set (reg:CCZ 17)
9455 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9456 (const_int 0)))
9457 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9458 (neg:SI (match_dup 1)))]
9459 "ix86_unary_operator_ok (NEG, SImode, operands)"
9460 "neg{l}\t%0"
9461 [(set_attr "type" "negnot")
9462 (set_attr "mode" "SI")])
9463
9464 (define_insn "*negsi2_cmpz_zext"
9465 [(set (reg:CCZ 17)
9466 (compare:CCZ (lshiftrt:DI
9467 (neg:DI (ashift:DI
9468 (match_operand:DI 1 "register_operand" "0")
9469 (const_int 32)))
9470 (const_int 32))
9471 (const_int 0)))
9472 (set (match_operand:DI 0 "register_operand" "=r")
9473 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9474 (const_int 32)))
9475 (const_int 32)))]
9476 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9477 "neg{l}\t%k0"
9478 [(set_attr "type" "negnot")
9479 (set_attr "mode" "SI")])
9480
9481 (define_expand "neghi2"
9482 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9483 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9484 (clobber (reg:CC 17))])]
9485 "TARGET_HIMODE_MATH"
9486 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9487
9488 (define_insn "*neghi2_1"
9489 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9490 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9491 (clobber (reg:CC 17))]
9492 "ix86_unary_operator_ok (NEG, HImode, operands)"
9493 "neg{w}\t%0"
9494 [(set_attr "type" "negnot")
9495 (set_attr "mode" "HI")])
9496
9497 (define_insn "*neghi2_cmpz"
9498 [(set (reg:CCZ 17)
9499 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9500 (const_int 0)))
9501 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9502 (neg:HI (match_dup 1)))]
9503 "ix86_unary_operator_ok (NEG, HImode, operands)"
9504 "neg{w}\t%0"
9505 [(set_attr "type" "negnot")
9506 (set_attr "mode" "HI")])
9507
9508 (define_expand "negqi2"
9509 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9510 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9511 (clobber (reg:CC 17))])]
9512 "TARGET_QIMODE_MATH"
9513 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9514
9515 (define_insn "*negqi2_1"
9516 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9517 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9518 (clobber (reg:CC 17))]
9519 "ix86_unary_operator_ok (NEG, QImode, operands)"
9520 "neg{b}\t%0"
9521 [(set_attr "type" "negnot")
9522 (set_attr "mode" "QI")])
9523
9524 (define_insn "*negqi2_cmpz"
9525 [(set (reg:CCZ 17)
9526 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9527 (const_int 0)))
9528 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9529 (neg:QI (match_dup 1)))]
9530 "ix86_unary_operator_ok (NEG, QImode, operands)"
9531 "neg{b}\t%0"
9532 [(set_attr "type" "negnot")
9533 (set_attr "mode" "QI")])
9534
9535 ;; Changing of sign for FP values is doable using integer unit too.
9536
9537 (define_expand "negsf2"
9538 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9539 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9540 (clobber (reg:CC 17))])]
9541 "TARGET_80387"
9542 "if (TARGET_SSE)
9543 {
9544 /* In case operand is in memory, we will not use SSE. */
9545 if (memory_operand (operands[0], VOIDmode)
9546 && rtx_equal_p (operands[0], operands[1]))
9547 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9548 else
9549 {
9550 /* Using SSE is tricky, since we need bitwise negation of -0
9551 in register. */
9552 rtx reg = gen_reg_rtx (SFmode);
9553 rtx dest = operands[0];
9554 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9555
9556 operands[1] = force_reg (SFmode, operands[1]);
9557 operands[0] = force_reg (SFmode, operands[0]);
9558 reg = force_reg (V4SFmode,
9559 gen_rtx_CONST_VECTOR (V4SFmode,
9560 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9561 CONST0_RTX (SFmode),
9562 CONST0_RTX (SFmode))));
9563 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9564 if (dest != operands[0])
9565 emit_move_insn (dest, operands[0]);
9566 }
9567 DONE;
9568 }
9569 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9570
9571 (define_insn "negsf2_memory"
9572 [(set (match_operand:SF 0 "memory_operand" "=m")
9573 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9574 (clobber (reg:CC 17))]
9575 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9576 "#")
9577
9578 (define_insn "negsf2_ifs"
9579 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9580 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9581 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9582 (clobber (reg:CC 17))]
9583 "TARGET_SSE
9584 && (reload_in_progress || reload_completed
9585 || (register_operand (operands[0], VOIDmode)
9586 && register_operand (operands[1], VOIDmode)))"
9587 "#")
9588
9589 (define_split
9590 [(set (match_operand:SF 0 "memory_operand" "")
9591 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9592 (use (match_operand:SF 2 "" ""))
9593 (clobber (reg:CC 17))]
9594 ""
9595 [(parallel [(set (match_dup 0)
9596 (neg:SF (match_dup 1)))
9597 (clobber (reg:CC 17))])])
9598
9599 (define_split
9600 [(set (match_operand:SF 0 "register_operand" "")
9601 (neg:SF (match_operand:SF 1 "register_operand" "")))
9602 (use (match_operand:V4SF 2 "" ""))
9603 (clobber (reg:CC 17))]
9604 "reload_completed && !SSE_REG_P (operands[0])"
9605 [(parallel [(set (match_dup 0)
9606 (neg:SF (match_dup 1)))
9607 (clobber (reg:CC 17))])])
9608
9609 (define_split
9610 [(set (match_operand:SF 0 "register_operand" "")
9611 (neg:SF (match_operand:SF 1 "register_operand" "")))
9612 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9613 (clobber (reg:CC 17))]
9614 "reload_completed && SSE_REG_P (operands[0])"
9615 [(set (match_dup 0)
9616 (xor:V4SF (match_dup 1)
9617 (match_dup 2)))]
9618 {
9619 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9620 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9621 if (operands_match_p (operands[0], operands[2]))
9622 {
9623 rtx tmp;
9624 tmp = operands[1];
9625 operands[1] = operands[2];
9626 operands[2] = tmp;
9627 }
9628 })
9629
9630
9631 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9632 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9633 ;; to itself.
9634 (define_insn "*negsf2_if"
9635 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9636 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9637 (clobber (reg:CC 17))]
9638 "TARGET_80387 && !TARGET_SSE
9639 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9640 "#")
9641
9642 (define_split
9643 [(set (match_operand:SF 0 "fp_register_operand" "")
9644 (neg:SF (match_operand:SF 1 "register_operand" "")))
9645 (clobber (reg:CC 17))]
9646 "TARGET_80387 && reload_completed"
9647 [(set (match_dup 0)
9648 (neg:SF (match_dup 1)))]
9649 "")
9650
9651 (define_split
9652 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9653 (neg:SF (match_operand:SF 1 "register_operand" "")))
9654 (clobber (reg:CC 17))]
9655 "TARGET_80387 && reload_completed"
9656 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9657 (clobber (reg:CC 17))])]
9658 "operands[1] = gen_int_mode (0x80000000, SImode);
9659 operands[0] = gen_lowpart (SImode, operands[0]);")
9660
9661 (define_split
9662 [(set (match_operand 0 "memory_operand" "")
9663 (neg (match_operand 1 "memory_operand" "")))
9664 (clobber (reg:CC 17))]
9665 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9666 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9667 (clobber (reg:CC 17))])]
9668 {
9669 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9670
9671 if (GET_MODE (operands[1]) == XFmode)
9672 size = 10;
9673 operands[0] = adjust_address (operands[0], QImode, size - 1);
9674 operands[1] = gen_int_mode (0x80, QImode);
9675 })
9676
9677 (define_expand "negdf2"
9678 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9679 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9680 (clobber (reg:CC 17))])]
9681 "TARGET_80387"
9682 "if (TARGET_SSE2)
9683 {
9684 /* In case operand is in memory, we will not use SSE. */
9685 if (memory_operand (operands[0], VOIDmode)
9686 && rtx_equal_p (operands[0], operands[1]))
9687 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9688 else
9689 {
9690 /* Using SSE is tricky, since we need bitwise negation of -0
9691 in register. */
9692 rtx reg;
9693 #if HOST_BITS_PER_WIDE_INT >= 64
9694 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9695 #else
9696 rtx imm = immed_double_const (0, 0x80000000, DImode);
9697 #endif
9698 rtx dest = operands[0];
9699
9700 operands[1] = force_reg (DFmode, operands[1]);
9701 operands[0] = force_reg (DFmode, operands[0]);
9702 imm = gen_lowpart (DFmode, imm);
9703 reg = force_reg (V2DFmode,
9704 gen_rtx_CONST_VECTOR (V2DFmode,
9705 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9706 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9707 if (dest != operands[0])
9708 emit_move_insn (dest, operands[0]);
9709 }
9710 DONE;
9711 }
9712 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9713
9714 (define_insn "negdf2_memory"
9715 [(set (match_operand:DF 0 "memory_operand" "=m")
9716 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9717 (clobber (reg:CC 17))]
9718 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9719 "#")
9720
9721 (define_insn "negdf2_ifs"
9722 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9723 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9724 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9725 (clobber (reg:CC 17))]
9726 "!TARGET_64BIT && TARGET_SSE2
9727 && (reload_in_progress || reload_completed
9728 || (register_operand (operands[0], VOIDmode)
9729 && register_operand (operands[1], VOIDmode)))"
9730 "#")
9731
9732 (define_insn "*negdf2_ifs_rex64"
9733 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9734 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9735 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9736 (clobber (reg:CC 17))]
9737 "TARGET_64BIT && TARGET_SSE2
9738 && (reload_in_progress || reload_completed
9739 || (register_operand (operands[0], VOIDmode)
9740 && register_operand (operands[1], VOIDmode)))"
9741 "#")
9742
9743 (define_split
9744 [(set (match_operand:DF 0 "memory_operand" "")
9745 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9746 (use (match_operand:V2DF 2 "" ""))
9747 (clobber (reg:CC 17))]
9748 ""
9749 [(parallel [(set (match_dup 0)
9750 (neg:DF (match_dup 1)))
9751 (clobber (reg:CC 17))])])
9752
9753 (define_split
9754 [(set (match_operand:DF 0 "register_operand" "")
9755 (neg:DF (match_operand:DF 1 "register_operand" "")))
9756 (use (match_operand:V2DF 2 "" ""))
9757 (clobber (reg:CC 17))]
9758 "reload_completed && !SSE_REG_P (operands[0])
9759 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9760 [(parallel [(set (match_dup 0)
9761 (neg:DF (match_dup 1)))
9762 (clobber (reg:CC 17))])])
9763
9764 (define_split
9765 [(set (match_operand:DF 0 "register_operand" "")
9766 (neg:DF (match_operand:DF 1 "register_operand" "")))
9767 (use (match_operand:V2DF 2 "" ""))
9768 (clobber (reg:CC 17))]
9769 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9770 [(parallel [(set (match_dup 0)
9771 (xor:DI (match_dup 1) (match_dup 2)))
9772 (clobber (reg:CC 17))])]
9773 "operands[0] = gen_lowpart (DImode, operands[0]);
9774 operands[1] = gen_lowpart (DImode, operands[1]);
9775 operands[2] = gen_lowpart (DImode, operands[2]);")
9776
9777 (define_split
9778 [(set (match_operand:DF 0 "register_operand" "")
9779 (neg:DF (match_operand:DF 1 "register_operand" "")))
9780 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9781 (clobber (reg:CC 17))]
9782 "reload_completed && SSE_REG_P (operands[0])"
9783 [(set (match_dup 0)
9784 (xor:V2DF (match_dup 1)
9785 (match_dup 2)))]
9786 {
9787 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9788 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9789 /* Avoid possible reformatting on the operands. */
9790 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9791 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9792 if (operands_match_p (operands[0], operands[2]))
9793 {
9794 rtx tmp;
9795 tmp = operands[1];
9796 operands[1] = operands[2];
9797 operands[2] = tmp;
9798 }
9799 })
9800
9801 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9802 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9803 ;; to itself.
9804 (define_insn "*negdf2_if"
9805 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9806 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9807 (clobber (reg:CC 17))]
9808 "!TARGET_64BIT && TARGET_80387
9809 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9810 "#")
9811
9812 ;; FIXME: We should to allow integer registers here. Problem is that
9813 ;; we need another scratch register to get constant from.
9814 ;; Forcing constant to mem if no register available in peep2 should be
9815 ;; safe even for PIC mode, because of RIP relative addressing.
9816 (define_insn "*negdf2_if_rex64"
9817 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9818 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9819 (clobber (reg:CC 17))]
9820 "TARGET_64BIT && TARGET_80387
9821 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9822 "#")
9823
9824 (define_split
9825 [(set (match_operand:DF 0 "fp_register_operand" "")
9826 (neg:DF (match_operand:DF 1 "register_operand" "")))
9827 (clobber (reg:CC 17))]
9828 "TARGET_80387 && reload_completed"
9829 [(set (match_dup 0)
9830 (neg:DF (match_dup 1)))]
9831 "")
9832
9833 (define_split
9834 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9835 (neg:DF (match_operand:DF 1 "register_operand" "")))
9836 (clobber (reg:CC 17))]
9837 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9838 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9839 (clobber (reg:CC 17))])]
9840 "operands[4] = gen_int_mode (0x80000000, SImode);
9841 split_di (operands+0, 1, operands+2, operands+3);")
9842
9843 (define_expand "negxf2"
9844 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9845 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9846 (clobber (reg:CC 17))])]
9847 "TARGET_80387"
9848 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9849
9850 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9851 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9852 ;; to itself.
9853 (define_insn "*negxf2_if"
9854 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9855 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9856 (clobber (reg:CC 17))]
9857 "TARGET_80387
9858 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9859 "#")
9860
9861 (define_split
9862 [(set (match_operand:XF 0 "fp_register_operand" "")
9863 (neg:XF (match_operand:XF 1 "register_operand" "")))
9864 (clobber (reg:CC 17))]
9865 "TARGET_80387 && reload_completed"
9866 [(set (match_dup 0)
9867 (neg:XF (match_dup 1)))]
9868 "")
9869
9870 (define_split
9871 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9872 (neg:XF (match_operand:XF 1 "register_operand" "")))
9873 (clobber (reg:CC 17))]
9874 "TARGET_80387 && reload_completed"
9875 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9876 (clobber (reg:CC 17))])]
9877 "operands[1] = GEN_INT (0x8000);
9878 operands[0] = gen_rtx_REG (SImode,
9879 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9880
9881 ;; Conditionalize these after reload. If they matches before reload, we
9882 ;; lose the clobber and ability to use integer instructions.
9883
9884 (define_insn "*negsf2_1"
9885 [(set (match_operand:SF 0 "register_operand" "=f")
9886 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9887 "TARGET_80387 && reload_completed"
9888 "fchs"
9889 [(set_attr "type" "fsgn")
9890 (set_attr "mode" "SF")])
9891
9892 (define_insn "*negdf2_1"
9893 [(set (match_operand:DF 0 "register_operand" "=f")
9894 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9895 "TARGET_80387 && reload_completed"
9896 "fchs"
9897 [(set_attr "type" "fsgn")
9898 (set_attr "mode" "DF")])
9899
9900 (define_insn "*negextendsfdf2"
9901 [(set (match_operand:DF 0 "register_operand" "=f")
9902 (neg:DF (float_extend:DF
9903 (match_operand:SF 1 "register_operand" "0"))))]
9904 "TARGET_80387"
9905 "fchs"
9906 [(set_attr "type" "fsgn")
9907 (set_attr "mode" "DF")])
9908
9909 (define_insn "*negxf2_1"
9910 [(set (match_operand:XF 0 "register_operand" "=f")
9911 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9912 "TARGET_80387 && reload_completed"
9913 "fchs"
9914 [(set_attr "type" "fsgn")
9915 (set_attr "mode" "XF")])
9916
9917 (define_insn "*negextenddfxf2"
9918 [(set (match_operand:XF 0 "register_operand" "=f")
9919 (neg:XF (float_extend:XF
9920 (match_operand:DF 1 "register_operand" "0"))))]
9921 "TARGET_80387"
9922 "fchs"
9923 [(set_attr "type" "fsgn")
9924 (set_attr "mode" "XF")])
9925
9926 (define_insn "*negextendsfxf2"
9927 [(set (match_operand:XF 0 "register_operand" "=f")
9928 (neg:XF (float_extend:XF
9929 (match_operand:SF 1 "register_operand" "0"))))]
9930 "TARGET_80387"
9931 "fchs"
9932 [(set_attr "type" "fsgn")
9933 (set_attr "mode" "XF")])
9934 \f
9935 ;; Absolute value instructions
9936
9937 (define_expand "abssf2"
9938 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9939 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9940 (clobber (reg:CC 17))])]
9941 "TARGET_80387"
9942 "if (TARGET_SSE)
9943 {
9944 /* In case operand is in memory, we will not use SSE. */
9945 if (memory_operand (operands[0], VOIDmode)
9946 && rtx_equal_p (operands[0], operands[1]))
9947 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9948 else
9949 {
9950 /* Using SSE is tricky, since we need bitwise negation of -0
9951 in register. */
9952 rtx reg = gen_reg_rtx (V4SFmode);
9953 rtx dest = operands[0];
9954 rtx imm;
9955
9956 operands[1] = force_reg (SFmode, operands[1]);
9957 operands[0] = force_reg (SFmode, operands[0]);
9958 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9959 reg = force_reg (V4SFmode,
9960 gen_rtx_CONST_VECTOR (V4SFmode,
9961 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9962 CONST0_RTX (SFmode),
9963 CONST0_RTX (SFmode))));
9964 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9965 if (dest != operands[0])
9966 emit_move_insn (dest, operands[0]);
9967 }
9968 DONE;
9969 }
9970 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9971
9972 (define_insn "abssf2_memory"
9973 [(set (match_operand:SF 0 "memory_operand" "=m")
9974 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9975 (clobber (reg:CC 17))]
9976 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9977 "#")
9978
9979 (define_insn "abssf2_ifs"
9980 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9981 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9982 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9983 (clobber (reg:CC 17))]
9984 "TARGET_SSE
9985 && (reload_in_progress || reload_completed
9986 || (register_operand (operands[0], VOIDmode)
9987 && register_operand (operands[1], VOIDmode)))"
9988 "#")
9989
9990 (define_split
9991 [(set (match_operand:SF 0 "memory_operand" "")
9992 (abs:SF (match_operand:SF 1 "memory_operand" "")))
9993 (use (match_operand:V4SF 2 "" ""))
9994 (clobber (reg:CC 17))]
9995 ""
9996 [(parallel [(set (match_dup 0)
9997 (abs:SF (match_dup 1)))
9998 (clobber (reg:CC 17))])])
9999
10000 (define_split
10001 [(set (match_operand:SF 0 "register_operand" "")
10002 (abs:SF (match_operand:SF 1 "register_operand" "")))
10003 (use (match_operand:V4SF 2 "" ""))
10004 (clobber (reg:CC 17))]
10005 "reload_completed && !SSE_REG_P (operands[0])"
10006 [(parallel [(set (match_dup 0)
10007 (abs:SF (match_dup 1)))
10008 (clobber (reg:CC 17))])])
10009
10010 (define_split
10011 [(set (match_operand:SF 0 "register_operand" "")
10012 (abs:SF (match_operand:SF 1 "register_operand" "")))
10013 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10014 (clobber (reg:CC 17))]
10015 "reload_completed && SSE_REG_P (operands[0])"
10016 [(set (match_dup 0)
10017 (and:V4SF (match_dup 1)
10018 (match_dup 2)))]
10019 {
10020 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10021 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10022 if (operands_match_p (operands[0], operands[2]))
10023 {
10024 rtx tmp;
10025 tmp = operands[1];
10026 operands[1] = operands[2];
10027 operands[2] = tmp;
10028 }
10029 })
10030
10031 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10032 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10033 ;; to itself.
10034 (define_insn "*abssf2_if"
10035 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10036 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10037 (clobber (reg:CC 17))]
10038 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10039 "#")
10040
10041 (define_split
10042 [(set (match_operand:SF 0 "fp_register_operand" "")
10043 (abs:SF (match_operand:SF 1 "register_operand" "")))
10044 (clobber (reg:CC 17))]
10045 "TARGET_80387 && reload_completed"
10046 [(set (match_dup 0)
10047 (abs:SF (match_dup 1)))]
10048 "")
10049
10050 (define_split
10051 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10052 (abs:SF (match_operand:SF 1 "register_operand" "")))
10053 (clobber (reg:CC 17))]
10054 "TARGET_80387 && reload_completed"
10055 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10056 (clobber (reg:CC 17))])]
10057 "operands[1] = gen_int_mode (~0x80000000, SImode);
10058 operands[0] = gen_lowpart (SImode, operands[0]);")
10059
10060 (define_split
10061 [(set (match_operand 0 "memory_operand" "")
10062 (abs (match_operand 1 "memory_operand" "")))
10063 (clobber (reg:CC 17))]
10064 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10065 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10066 (clobber (reg:CC 17))])]
10067 {
10068 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10069
10070 if (GET_MODE (operands[1]) == XFmode)
10071 size = 10;
10072 operands[0] = adjust_address (operands[0], QImode, size - 1);
10073 operands[1] = gen_int_mode (~0x80, QImode);
10074 })
10075
10076 (define_expand "absdf2"
10077 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10078 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10079 (clobber (reg:CC 17))])]
10080 "TARGET_80387"
10081 "if (TARGET_SSE2)
10082 {
10083 /* In case operand is in memory, we will not use SSE. */
10084 if (memory_operand (operands[0], VOIDmode)
10085 && rtx_equal_p (operands[0], operands[1]))
10086 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10087 else
10088 {
10089 /* Using SSE is tricky, since we need bitwise negation of -0
10090 in register. */
10091 rtx reg = gen_reg_rtx (V2DFmode);
10092 #if HOST_BITS_PER_WIDE_INT >= 64
10093 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10094 #else
10095 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10096 #endif
10097 rtx dest = operands[0];
10098
10099 operands[1] = force_reg (DFmode, operands[1]);
10100 operands[0] = force_reg (DFmode, operands[0]);
10101
10102 /* Produce LONG_DOUBLE with the proper immediate argument. */
10103 imm = gen_lowpart (DFmode, imm);
10104 reg = force_reg (V2DFmode,
10105 gen_rtx_CONST_VECTOR (V2DFmode,
10106 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10107 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10108 if (dest != operands[0])
10109 emit_move_insn (dest, operands[0]);
10110 }
10111 DONE;
10112 }
10113 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10114
10115 (define_insn "absdf2_memory"
10116 [(set (match_operand:DF 0 "memory_operand" "=m")
10117 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10118 (clobber (reg:CC 17))]
10119 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10120 "#")
10121
10122 (define_insn "absdf2_ifs"
10123 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10124 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10125 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10126 (clobber (reg:CC 17))]
10127 "!TARGET_64BIT && TARGET_SSE2
10128 && (reload_in_progress || reload_completed
10129 || (register_operand (operands[0], VOIDmode)
10130 && register_operand (operands[1], VOIDmode)))"
10131 "#")
10132
10133 (define_insn "*absdf2_ifs_rex64"
10134 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10135 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10136 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10137 (clobber (reg:CC 17))]
10138 "TARGET_64BIT && TARGET_SSE2
10139 && (reload_in_progress || reload_completed
10140 || (register_operand (operands[0], VOIDmode)
10141 && register_operand (operands[1], VOIDmode)))"
10142 "#")
10143
10144 (define_split
10145 [(set (match_operand:DF 0 "memory_operand" "")
10146 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10147 (use (match_operand:V2DF 2 "" ""))
10148 (clobber (reg:CC 17))]
10149 ""
10150 [(parallel [(set (match_dup 0)
10151 (abs:DF (match_dup 1)))
10152 (clobber (reg:CC 17))])])
10153
10154 (define_split
10155 [(set (match_operand:DF 0 "register_operand" "")
10156 (abs:DF (match_operand:DF 1 "register_operand" "")))
10157 (use (match_operand:V2DF 2 "" ""))
10158 (clobber (reg:CC 17))]
10159 "reload_completed && !SSE_REG_P (operands[0])"
10160 [(parallel [(set (match_dup 0)
10161 (abs:DF (match_dup 1)))
10162 (clobber (reg:CC 17))])])
10163
10164 (define_split
10165 [(set (match_operand:DF 0 "register_operand" "")
10166 (abs:DF (match_operand:DF 1 "register_operand" "")))
10167 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10168 (clobber (reg:CC 17))]
10169 "reload_completed && SSE_REG_P (operands[0])"
10170 [(set (match_dup 0)
10171 (and:V2DF (match_dup 1)
10172 (match_dup 2)))]
10173 {
10174 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10175 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10176 /* Avoid possible reformatting on the operands. */
10177 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10178 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10179 if (operands_match_p (operands[0], operands[2]))
10180 {
10181 rtx tmp;
10182 tmp = operands[1];
10183 operands[1] = operands[2];
10184 operands[2] = tmp;
10185 }
10186 })
10187
10188
10189 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10190 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10191 ;; to itself.
10192 (define_insn "*absdf2_if"
10193 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10194 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10195 (clobber (reg:CC 17))]
10196 "!TARGET_64BIT && TARGET_80387
10197 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10198 "#")
10199
10200 ;; FIXME: We should to allow integer registers here. Problem is that
10201 ;; we need another scratch register to get constant from.
10202 ;; Forcing constant to mem if no register available in peep2 should be
10203 ;; safe even for PIC mode, because of RIP relative addressing.
10204 (define_insn "*absdf2_if_rex64"
10205 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10206 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10207 (clobber (reg:CC 17))]
10208 "TARGET_64BIT && TARGET_80387
10209 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10210 "#")
10211
10212 (define_split
10213 [(set (match_operand:DF 0 "fp_register_operand" "")
10214 (abs:DF (match_operand:DF 1 "register_operand" "")))
10215 (clobber (reg:CC 17))]
10216 "TARGET_80387 && reload_completed"
10217 [(set (match_dup 0)
10218 (abs:DF (match_dup 1)))]
10219 "")
10220
10221 (define_split
10222 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10223 (abs:DF (match_operand:DF 1 "register_operand" "")))
10224 (clobber (reg:CC 17))]
10225 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10226 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10227 (clobber (reg:CC 17))])]
10228 "operands[4] = gen_int_mode (~0x80000000, SImode);
10229 split_di (operands+0, 1, operands+2, operands+3);")
10230
10231 (define_expand "absxf2"
10232 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10233 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10234 (clobber (reg:CC 17))])]
10235 "TARGET_80387"
10236 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10237
10238 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10239 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10240 ;; to itself.
10241 (define_insn "*absxf2_if"
10242 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10243 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10244 (clobber (reg:CC 17))]
10245 "TARGET_80387
10246 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10247 "#")
10248
10249 (define_split
10250 [(set (match_operand:XF 0 "fp_register_operand" "")
10251 (abs:XF (match_operand:XF 1 "register_operand" "")))
10252 (clobber (reg:CC 17))]
10253 "TARGET_80387 && reload_completed"
10254 [(set (match_dup 0)
10255 (abs:XF (match_dup 1)))]
10256 "")
10257
10258 (define_split
10259 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10260 (abs:XF (match_operand:XF 1 "register_operand" "")))
10261 (clobber (reg:CC 17))]
10262 "TARGET_80387 && reload_completed"
10263 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10264 (clobber (reg:CC 17))])]
10265 "operands[1] = GEN_INT (~0x8000);
10266 operands[0] = gen_rtx_REG (SImode,
10267 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10268
10269 (define_insn "*abssf2_1"
10270 [(set (match_operand:SF 0 "register_operand" "=f")
10271 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10272 "TARGET_80387 && reload_completed"
10273 "fabs"
10274 [(set_attr "type" "fsgn")
10275 (set_attr "mode" "SF")])
10276
10277 (define_insn "*absdf2_1"
10278 [(set (match_operand:DF 0 "register_operand" "=f")
10279 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10280 "TARGET_80387 && reload_completed"
10281 "fabs"
10282 [(set_attr "type" "fsgn")
10283 (set_attr "mode" "DF")])
10284
10285 (define_insn "*absextendsfdf2"
10286 [(set (match_operand:DF 0 "register_operand" "=f")
10287 (abs:DF (float_extend:DF
10288 (match_operand:SF 1 "register_operand" "0"))))]
10289 "TARGET_80387"
10290 "fabs"
10291 [(set_attr "type" "fsgn")
10292 (set_attr "mode" "DF")])
10293
10294 (define_insn "*absxf2_1"
10295 [(set (match_operand:XF 0 "register_operand" "=f")
10296 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10297 "TARGET_80387 && reload_completed"
10298 "fabs"
10299 [(set_attr "type" "fsgn")
10300 (set_attr "mode" "DF")])
10301
10302 (define_insn "*absextenddfxf2"
10303 [(set (match_operand:XF 0 "register_operand" "=f")
10304 (abs:XF (float_extend:XF
10305 (match_operand:DF 1 "register_operand" "0"))))]
10306 "TARGET_80387"
10307 "fabs"
10308 [(set_attr "type" "fsgn")
10309 (set_attr "mode" "XF")])
10310
10311 (define_insn "*absextendsfxf2"
10312 [(set (match_operand:XF 0 "register_operand" "=f")
10313 (abs:XF (float_extend:XF
10314 (match_operand:SF 1 "register_operand" "0"))))]
10315 "TARGET_80387"
10316 "fabs"
10317 [(set_attr "type" "fsgn")
10318 (set_attr "mode" "XF")])
10319 \f
10320 ;; One complement instructions
10321
10322 (define_expand "one_cmpldi2"
10323 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10324 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10325 "TARGET_64BIT"
10326 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10327
10328 (define_insn "*one_cmpldi2_1_rex64"
10329 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10330 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10331 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10332 "not{q}\t%0"
10333 [(set_attr "type" "negnot")
10334 (set_attr "mode" "DI")])
10335
10336 (define_insn "*one_cmpldi2_2_rex64"
10337 [(set (reg 17)
10338 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10339 (const_int 0)))
10340 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10341 (not:DI (match_dup 1)))]
10342 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10343 && ix86_unary_operator_ok (NOT, DImode, operands)"
10344 "#"
10345 [(set_attr "type" "alu1")
10346 (set_attr "mode" "DI")])
10347
10348 (define_split
10349 [(set (reg 17)
10350 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10351 (const_int 0)))
10352 (set (match_operand:DI 0 "nonimmediate_operand" "")
10353 (not:DI (match_dup 1)))]
10354 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10355 [(parallel [(set (reg:CCNO 17)
10356 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10357 (const_int 0)))
10358 (set (match_dup 0)
10359 (xor:DI (match_dup 1) (const_int -1)))])]
10360 "")
10361
10362 (define_expand "one_cmplsi2"
10363 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10364 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10365 ""
10366 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10367
10368 (define_insn "*one_cmplsi2_1"
10369 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10370 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10371 "ix86_unary_operator_ok (NOT, SImode, operands)"
10372 "not{l}\t%0"
10373 [(set_attr "type" "negnot")
10374 (set_attr "mode" "SI")])
10375
10376 ;; ??? Currently never generated - xor is used instead.
10377 (define_insn "*one_cmplsi2_1_zext"
10378 [(set (match_operand:DI 0 "register_operand" "=r")
10379 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10380 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10381 "not{l}\t%k0"
10382 [(set_attr "type" "negnot")
10383 (set_attr "mode" "SI")])
10384
10385 (define_insn "*one_cmplsi2_2"
10386 [(set (reg 17)
10387 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10388 (const_int 0)))
10389 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10390 (not:SI (match_dup 1)))]
10391 "ix86_match_ccmode (insn, CCNOmode)
10392 && ix86_unary_operator_ok (NOT, SImode, operands)"
10393 "#"
10394 [(set_attr "type" "alu1")
10395 (set_attr "mode" "SI")])
10396
10397 (define_split
10398 [(set (reg 17)
10399 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10400 (const_int 0)))
10401 (set (match_operand:SI 0 "nonimmediate_operand" "")
10402 (not:SI (match_dup 1)))]
10403 "ix86_match_ccmode (insn, CCNOmode)"
10404 [(parallel [(set (reg:CCNO 17)
10405 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10406 (const_int 0)))
10407 (set (match_dup 0)
10408 (xor:SI (match_dup 1) (const_int -1)))])]
10409 "")
10410
10411 ;; ??? Currently never generated - xor is used instead.
10412 (define_insn "*one_cmplsi2_2_zext"
10413 [(set (reg 17)
10414 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10415 (const_int 0)))
10416 (set (match_operand:DI 0 "register_operand" "=r")
10417 (zero_extend:DI (not:SI (match_dup 1))))]
10418 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10419 && ix86_unary_operator_ok (NOT, SImode, operands)"
10420 "#"
10421 [(set_attr "type" "alu1")
10422 (set_attr "mode" "SI")])
10423
10424 (define_split
10425 [(set (reg 17)
10426 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10427 (const_int 0)))
10428 (set (match_operand:DI 0 "register_operand" "")
10429 (zero_extend:DI (not:SI (match_dup 1))))]
10430 "ix86_match_ccmode (insn, CCNOmode)"
10431 [(parallel [(set (reg:CCNO 17)
10432 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10433 (const_int 0)))
10434 (set (match_dup 0)
10435 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10436 "")
10437
10438 (define_expand "one_cmplhi2"
10439 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10440 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10441 "TARGET_HIMODE_MATH"
10442 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10443
10444 (define_insn "*one_cmplhi2_1"
10445 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10446 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10447 "ix86_unary_operator_ok (NOT, HImode, operands)"
10448 "not{w}\t%0"
10449 [(set_attr "type" "negnot")
10450 (set_attr "mode" "HI")])
10451
10452 (define_insn "*one_cmplhi2_2"
10453 [(set (reg 17)
10454 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10455 (const_int 0)))
10456 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10457 (not:HI (match_dup 1)))]
10458 "ix86_match_ccmode (insn, CCNOmode)
10459 && ix86_unary_operator_ok (NEG, HImode, operands)"
10460 "#"
10461 [(set_attr "type" "alu1")
10462 (set_attr "mode" "HI")])
10463
10464 (define_split
10465 [(set (reg 17)
10466 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10467 (const_int 0)))
10468 (set (match_operand:HI 0 "nonimmediate_operand" "")
10469 (not:HI (match_dup 1)))]
10470 "ix86_match_ccmode (insn, CCNOmode)"
10471 [(parallel [(set (reg:CCNO 17)
10472 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10473 (const_int 0)))
10474 (set (match_dup 0)
10475 (xor:HI (match_dup 1) (const_int -1)))])]
10476 "")
10477
10478 ;; %%% Potential partial reg stall on alternative 1. What to do?
10479 (define_expand "one_cmplqi2"
10480 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10481 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10482 "TARGET_QIMODE_MATH"
10483 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10484
10485 (define_insn "*one_cmplqi2_1"
10486 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10487 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10488 "ix86_unary_operator_ok (NOT, QImode, operands)"
10489 "@
10490 not{b}\t%0
10491 not{l}\t%k0"
10492 [(set_attr "type" "negnot")
10493 (set_attr "mode" "QI,SI")])
10494
10495 (define_insn "*one_cmplqi2_2"
10496 [(set (reg 17)
10497 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10498 (const_int 0)))
10499 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10500 (not:QI (match_dup 1)))]
10501 "ix86_match_ccmode (insn, CCNOmode)
10502 && ix86_unary_operator_ok (NOT, QImode, operands)"
10503 "#"
10504 [(set_attr "type" "alu1")
10505 (set_attr "mode" "QI")])
10506
10507 (define_split
10508 [(set (reg 17)
10509 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10510 (const_int 0)))
10511 (set (match_operand:QI 0 "nonimmediate_operand" "")
10512 (not:QI (match_dup 1)))]
10513 "ix86_match_ccmode (insn, CCNOmode)"
10514 [(parallel [(set (reg:CCNO 17)
10515 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10516 (const_int 0)))
10517 (set (match_dup 0)
10518 (xor:QI (match_dup 1) (const_int -1)))])]
10519 "")
10520 \f
10521 ;; Arithmetic shift instructions
10522
10523 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10524 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10525 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10526 ;; from the assembler input.
10527 ;;
10528 ;; This instruction shifts the target reg/mem as usual, but instead of
10529 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10530 ;; is a left shift double, bits are taken from the high order bits of
10531 ;; reg, else if the insn is a shift right double, bits are taken from the
10532 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10533 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10534 ;;
10535 ;; Since sh[lr]d does not change the `reg' operand, that is done
10536 ;; separately, making all shifts emit pairs of shift double and normal
10537 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10538 ;; support a 63 bit shift, each shift where the count is in a reg expands
10539 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10540 ;;
10541 ;; If the shift count is a constant, we need never emit more than one
10542 ;; shift pair, instead using moves and sign extension for counts greater
10543 ;; than 31.
10544
10545 (define_expand "ashldi3"
10546 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10547 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10548 (match_operand:QI 2 "nonmemory_operand" "")))
10549 (clobber (reg:CC 17))])]
10550 ""
10551 {
10552 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10553 {
10554 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10555 DONE;
10556 }
10557 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10558 DONE;
10559 })
10560
10561 (define_insn "*ashldi3_1_rex64"
10562 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10563 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10564 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10565 (clobber (reg:CC 17))]
10566 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10567 {
10568 switch (get_attr_type (insn))
10569 {
10570 case TYPE_ALU:
10571 if (operands[2] != const1_rtx)
10572 abort ();
10573 if (!rtx_equal_p (operands[0], operands[1]))
10574 abort ();
10575 return "add{q}\t{%0, %0|%0, %0}";
10576
10577 case TYPE_LEA:
10578 if (GET_CODE (operands[2]) != CONST_INT
10579 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10580 abort ();
10581 operands[1] = gen_rtx_MULT (DImode, operands[1],
10582 GEN_INT (1 << INTVAL (operands[2])));
10583 return "lea{q}\t{%a1, %0|%0, %a1}";
10584
10585 default:
10586 if (REG_P (operands[2]))
10587 return "sal{q}\t{%b2, %0|%0, %b2}";
10588 else if (operands[2] == const1_rtx
10589 && (TARGET_SHIFT1 || optimize_size))
10590 return "sal{q}\t%0";
10591 else
10592 return "sal{q}\t{%2, %0|%0, %2}";
10593 }
10594 }
10595 [(set (attr "type")
10596 (cond [(eq_attr "alternative" "1")
10597 (const_string "lea")
10598 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10599 (const_int 0))
10600 (match_operand 0 "register_operand" ""))
10601 (match_operand 2 "const1_operand" ""))
10602 (const_string "alu")
10603 ]
10604 (const_string "ishift")))
10605 (set_attr "mode" "DI")])
10606
10607 ;; Convert lea to the lea pattern to avoid flags dependency.
10608 (define_split
10609 [(set (match_operand:DI 0 "register_operand" "")
10610 (ashift:DI (match_operand:DI 1 "register_operand" "")
10611 (match_operand:QI 2 "immediate_operand" "")))
10612 (clobber (reg:CC 17))]
10613 "TARGET_64BIT && reload_completed
10614 && true_regnum (operands[0]) != true_regnum (operands[1])"
10615 [(set (match_dup 0)
10616 (mult:DI (match_dup 1)
10617 (match_dup 2)))]
10618 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10619
10620 ;; This pattern can't accept a variable shift count, since shifts by
10621 ;; zero don't affect the flags. We assume that shifts by constant
10622 ;; zero are optimized away.
10623 (define_insn "*ashldi3_cmp_rex64"
10624 [(set (reg 17)
10625 (compare
10626 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10627 (match_operand:QI 2 "immediate_operand" "e"))
10628 (const_int 0)))
10629 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10630 (ashift:DI (match_dup 1) (match_dup 2)))]
10631 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10632 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10633 {
10634 switch (get_attr_type (insn))
10635 {
10636 case TYPE_ALU:
10637 if (operands[2] != const1_rtx)
10638 abort ();
10639 return "add{q}\t{%0, %0|%0, %0}";
10640
10641 default:
10642 if (REG_P (operands[2]))
10643 return "sal{q}\t{%b2, %0|%0, %b2}";
10644 else if (operands[2] == const1_rtx
10645 && (TARGET_SHIFT1 || optimize_size))
10646 return "sal{q}\t%0";
10647 else
10648 return "sal{q}\t{%2, %0|%0, %2}";
10649 }
10650 }
10651 [(set (attr "type")
10652 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10653 (const_int 0))
10654 (match_operand 0 "register_operand" ""))
10655 (match_operand 2 "const1_operand" ""))
10656 (const_string "alu")
10657 ]
10658 (const_string "ishift")))
10659 (set_attr "mode" "DI")])
10660
10661 (define_insn "ashldi3_1"
10662 [(set (match_operand:DI 0 "register_operand" "=r")
10663 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10664 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10665 (clobber (match_scratch:SI 3 "=&r"))
10666 (clobber (reg:CC 17))]
10667 "!TARGET_64BIT && TARGET_CMOVE"
10668 "#"
10669 [(set_attr "type" "multi")])
10670
10671 (define_insn "*ashldi3_2"
10672 [(set (match_operand:DI 0 "register_operand" "=r")
10673 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10674 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10675 (clobber (reg:CC 17))]
10676 "!TARGET_64BIT"
10677 "#"
10678 [(set_attr "type" "multi")])
10679
10680 (define_split
10681 [(set (match_operand:DI 0 "register_operand" "")
10682 (ashift:DI (match_operand:DI 1 "register_operand" "")
10683 (match_operand:QI 2 "nonmemory_operand" "")))
10684 (clobber (match_scratch:SI 3 ""))
10685 (clobber (reg:CC 17))]
10686 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10687 [(const_int 0)]
10688 "ix86_split_ashldi (operands, operands[3]); DONE;")
10689
10690 (define_split
10691 [(set (match_operand:DI 0 "register_operand" "")
10692 (ashift:DI (match_operand:DI 1 "register_operand" "")
10693 (match_operand:QI 2 "nonmemory_operand" "")))
10694 (clobber (reg:CC 17))]
10695 "!TARGET_64BIT && reload_completed"
10696 [(const_int 0)]
10697 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10698
10699 (define_insn "x86_shld_1"
10700 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10701 (ior:SI (ashift:SI (match_dup 0)
10702 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10703 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10704 (minus:QI (const_int 32) (match_dup 2)))))
10705 (clobber (reg:CC 17))]
10706 ""
10707 "@
10708 shld{l}\t{%2, %1, %0|%0, %1, %2}
10709 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10710 [(set_attr "type" "ishift")
10711 (set_attr "prefix_0f" "1")
10712 (set_attr "mode" "SI")
10713 (set_attr "pent_pair" "np")
10714 (set_attr "athlon_decode" "vector")])
10715
10716 (define_expand "x86_shift_adj_1"
10717 [(set (reg:CCZ 17)
10718 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10719 (const_int 32))
10720 (const_int 0)))
10721 (set (match_operand:SI 0 "register_operand" "")
10722 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10723 (match_operand:SI 1 "register_operand" "")
10724 (match_dup 0)))
10725 (set (match_dup 1)
10726 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10727 (match_operand:SI 3 "register_operand" "r")
10728 (match_dup 1)))]
10729 "TARGET_CMOVE"
10730 "")
10731
10732 (define_expand "x86_shift_adj_2"
10733 [(use (match_operand:SI 0 "register_operand" ""))
10734 (use (match_operand:SI 1 "register_operand" ""))
10735 (use (match_operand:QI 2 "register_operand" ""))]
10736 ""
10737 {
10738 rtx label = gen_label_rtx ();
10739 rtx tmp;
10740
10741 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10742
10743 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10744 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10745 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10746 gen_rtx_LABEL_REF (VOIDmode, label),
10747 pc_rtx);
10748 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10749 JUMP_LABEL (tmp) = label;
10750
10751 emit_move_insn (operands[0], operands[1]);
10752 emit_move_insn (operands[1], const0_rtx);
10753
10754 emit_label (label);
10755 LABEL_NUSES (label) = 1;
10756
10757 DONE;
10758 })
10759
10760 (define_expand "ashlsi3"
10761 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10762 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10763 (match_operand:QI 2 "nonmemory_operand" "")))
10764 (clobber (reg:CC 17))]
10765 ""
10766 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10767
10768 (define_insn "*ashlsi3_1"
10769 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10770 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10771 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10772 (clobber (reg:CC 17))]
10773 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10774 {
10775 switch (get_attr_type (insn))
10776 {
10777 case TYPE_ALU:
10778 if (operands[2] != const1_rtx)
10779 abort ();
10780 if (!rtx_equal_p (operands[0], operands[1]))
10781 abort ();
10782 return "add{l}\t{%0, %0|%0, %0}";
10783
10784 case TYPE_LEA:
10785 return "#";
10786
10787 default:
10788 if (REG_P (operands[2]))
10789 return "sal{l}\t{%b2, %0|%0, %b2}";
10790 else if (operands[2] == const1_rtx
10791 && (TARGET_SHIFT1 || optimize_size))
10792 return "sal{l}\t%0";
10793 else
10794 return "sal{l}\t{%2, %0|%0, %2}";
10795 }
10796 }
10797 [(set (attr "type")
10798 (cond [(eq_attr "alternative" "1")
10799 (const_string "lea")
10800 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10801 (const_int 0))
10802 (match_operand 0 "register_operand" ""))
10803 (match_operand 2 "const1_operand" ""))
10804 (const_string "alu")
10805 ]
10806 (const_string "ishift")))
10807 (set_attr "mode" "SI")])
10808
10809 ;; Convert lea to the lea pattern to avoid flags dependency.
10810 (define_split
10811 [(set (match_operand 0 "register_operand" "")
10812 (ashift (match_operand 1 "index_register_operand" "")
10813 (match_operand:QI 2 "const_int_operand" "")))
10814 (clobber (reg:CC 17))]
10815 "reload_completed
10816 && true_regnum (operands[0]) != true_regnum (operands[1])"
10817 [(const_int 0)]
10818 {
10819 rtx pat;
10820 operands[0] = gen_lowpart (SImode, operands[0]);
10821 operands[1] = gen_lowpart (Pmode, operands[1]);
10822 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10823 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10824 if (Pmode != SImode)
10825 pat = gen_rtx_SUBREG (SImode, pat, 0);
10826 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10827 DONE;
10828 })
10829
10830 ;; Rare case of shifting RSP is handled by generating move and shift
10831 (define_split
10832 [(set (match_operand 0 "register_operand" "")
10833 (ashift (match_operand 1 "register_operand" "")
10834 (match_operand:QI 2 "const_int_operand" "")))
10835 (clobber (reg:CC 17))]
10836 "reload_completed
10837 && true_regnum (operands[0]) != true_regnum (operands[1])"
10838 [(const_int 0)]
10839 {
10840 rtx pat, clob;
10841 emit_move_insn (operands[1], operands[0]);
10842 pat = gen_rtx_SET (VOIDmode, operands[0],
10843 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10844 operands[0], operands[2]));
10845 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10846 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10847 DONE;
10848 })
10849
10850 (define_insn "*ashlsi3_1_zext"
10851 [(set (match_operand:DI 0 "register_operand" "=r,r")
10852 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10853 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10854 (clobber (reg:CC 17))]
10855 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10856 {
10857 switch (get_attr_type (insn))
10858 {
10859 case TYPE_ALU:
10860 if (operands[2] != const1_rtx)
10861 abort ();
10862 return "add{l}\t{%k0, %k0|%k0, %k0}";
10863
10864 case TYPE_LEA:
10865 return "#";
10866
10867 default:
10868 if (REG_P (operands[2]))
10869 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10870 else if (operands[2] == const1_rtx
10871 && (TARGET_SHIFT1 || optimize_size))
10872 return "sal{l}\t%k0";
10873 else
10874 return "sal{l}\t{%2, %k0|%k0, %2}";
10875 }
10876 }
10877 [(set (attr "type")
10878 (cond [(eq_attr "alternative" "1")
10879 (const_string "lea")
10880 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10881 (const_int 0))
10882 (match_operand 2 "const1_operand" ""))
10883 (const_string "alu")
10884 ]
10885 (const_string "ishift")))
10886 (set_attr "mode" "SI")])
10887
10888 ;; Convert lea to the lea pattern to avoid flags dependency.
10889 (define_split
10890 [(set (match_operand:DI 0 "register_operand" "")
10891 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10892 (match_operand:QI 2 "const_int_operand" ""))))
10893 (clobber (reg:CC 17))]
10894 "TARGET_64BIT && reload_completed
10895 && true_regnum (operands[0]) != true_regnum (operands[1])"
10896 [(set (match_dup 0) (zero_extend:DI
10897 (subreg:SI (mult:SI (match_dup 1)
10898 (match_dup 2)) 0)))]
10899 {
10900 operands[1] = gen_lowpart (Pmode, operands[1]);
10901 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10902 })
10903
10904 ;; This pattern can't accept a variable shift count, since shifts by
10905 ;; zero don't affect the flags. We assume that shifts by constant
10906 ;; zero are optimized away.
10907 (define_insn "*ashlsi3_cmp"
10908 [(set (reg 17)
10909 (compare
10910 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10911 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10912 (const_int 0)))
10913 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10914 (ashift:SI (match_dup 1) (match_dup 2)))]
10915 "ix86_match_ccmode (insn, CCGOCmode)
10916 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10917 {
10918 switch (get_attr_type (insn))
10919 {
10920 case TYPE_ALU:
10921 if (operands[2] != const1_rtx)
10922 abort ();
10923 return "add{l}\t{%0, %0|%0, %0}";
10924
10925 default:
10926 if (REG_P (operands[2]))
10927 return "sal{l}\t{%b2, %0|%0, %b2}";
10928 else if (operands[2] == const1_rtx
10929 && (TARGET_SHIFT1 || optimize_size))
10930 return "sal{l}\t%0";
10931 else
10932 return "sal{l}\t{%2, %0|%0, %2}";
10933 }
10934 }
10935 [(set (attr "type")
10936 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10937 (const_int 0))
10938 (match_operand 0 "register_operand" ""))
10939 (match_operand 2 "const1_operand" ""))
10940 (const_string "alu")
10941 ]
10942 (const_string "ishift")))
10943 (set_attr "mode" "SI")])
10944
10945 (define_insn "*ashlsi3_cmp_zext"
10946 [(set (reg 17)
10947 (compare
10948 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10949 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10950 (const_int 0)))
10951 (set (match_operand:DI 0 "register_operand" "=r")
10952 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10953 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10954 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10955 {
10956 switch (get_attr_type (insn))
10957 {
10958 case TYPE_ALU:
10959 if (operands[2] != const1_rtx)
10960 abort ();
10961 return "add{l}\t{%k0, %k0|%k0, %k0}";
10962
10963 default:
10964 if (REG_P (operands[2]))
10965 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10966 else if (operands[2] == const1_rtx
10967 && (TARGET_SHIFT1 || optimize_size))
10968 return "sal{l}\t%k0";
10969 else
10970 return "sal{l}\t{%2, %k0|%k0, %2}";
10971 }
10972 }
10973 [(set (attr "type")
10974 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10975 (const_int 0))
10976 (match_operand 2 "const1_operand" ""))
10977 (const_string "alu")
10978 ]
10979 (const_string "ishift")))
10980 (set_attr "mode" "SI")])
10981
10982 (define_expand "ashlhi3"
10983 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10984 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10985 (match_operand:QI 2 "nonmemory_operand" "")))
10986 (clobber (reg:CC 17))]
10987 "TARGET_HIMODE_MATH"
10988 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10989
10990 (define_insn "*ashlhi3_1_lea"
10991 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10992 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10993 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10994 (clobber (reg:CC 17))]
10995 "!TARGET_PARTIAL_REG_STALL
10996 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10997 {
10998 switch (get_attr_type (insn))
10999 {
11000 case TYPE_LEA:
11001 return "#";
11002 case TYPE_ALU:
11003 if (operands[2] != const1_rtx)
11004 abort ();
11005 return "add{w}\t{%0, %0|%0, %0}";
11006
11007 default:
11008 if (REG_P (operands[2]))
11009 return "sal{w}\t{%b2, %0|%0, %b2}";
11010 else if (operands[2] == const1_rtx
11011 && (TARGET_SHIFT1 || optimize_size))
11012 return "sal{w}\t%0";
11013 else
11014 return "sal{w}\t{%2, %0|%0, %2}";
11015 }
11016 }
11017 [(set (attr "type")
11018 (cond [(eq_attr "alternative" "1")
11019 (const_string "lea")
11020 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11021 (const_int 0))
11022 (match_operand 0 "register_operand" ""))
11023 (match_operand 2 "const1_operand" ""))
11024 (const_string "alu")
11025 ]
11026 (const_string "ishift")))
11027 (set_attr "mode" "HI,SI")])
11028
11029 (define_insn "*ashlhi3_1"
11030 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11031 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11032 (match_operand:QI 2 "nonmemory_operand" "cI")))
11033 (clobber (reg:CC 17))]
11034 "TARGET_PARTIAL_REG_STALL
11035 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11036 {
11037 switch (get_attr_type (insn))
11038 {
11039 case TYPE_ALU:
11040 if (operands[2] != const1_rtx)
11041 abort ();
11042 return "add{w}\t{%0, %0|%0, %0}";
11043
11044 default:
11045 if (REG_P (operands[2]))
11046 return "sal{w}\t{%b2, %0|%0, %b2}";
11047 else if (operands[2] == const1_rtx
11048 && (TARGET_SHIFT1 || optimize_size))
11049 return "sal{w}\t%0";
11050 else
11051 return "sal{w}\t{%2, %0|%0, %2}";
11052 }
11053 }
11054 [(set (attr "type")
11055 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11056 (const_int 0))
11057 (match_operand 0 "register_operand" ""))
11058 (match_operand 2 "const1_operand" ""))
11059 (const_string "alu")
11060 ]
11061 (const_string "ishift")))
11062 (set_attr "mode" "HI")])
11063
11064 ;; This pattern can't accept a variable shift count, since shifts by
11065 ;; zero don't affect the flags. We assume that shifts by constant
11066 ;; zero are optimized away.
11067 (define_insn "*ashlhi3_cmp"
11068 [(set (reg 17)
11069 (compare
11070 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11071 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11072 (const_int 0)))
11073 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11074 (ashift:HI (match_dup 1) (match_dup 2)))]
11075 "ix86_match_ccmode (insn, CCGOCmode)
11076 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11077 {
11078 switch (get_attr_type (insn))
11079 {
11080 case TYPE_ALU:
11081 if (operands[2] != const1_rtx)
11082 abort ();
11083 return "add{w}\t{%0, %0|%0, %0}";
11084
11085 default:
11086 if (REG_P (operands[2]))
11087 return "sal{w}\t{%b2, %0|%0, %b2}";
11088 else if (operands[2] == const1_rtx
11089 && (TARGET_SHIFT1 || optimize_size))
11090 return "sal{w}\t%0";
11091 else
11092 return "sal{w}\t{%2, %0|%0, %2}";
11093 }
11094 }
11095 [(set (attr "type")
11096 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11097 (const_int 0))
11098 (match_operand 0 "register_operand" ""))
11099 (match_operand 2 "const1_operand" ""))
11100 (const_string "alu")
11101 ]
11102 (const_string "ishift")))
11103 (set_attr "mode" "HI")])
11104
11105 (define_expand "ashlqi3"
11106 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11107 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11108 (match_operand:QI 2 "nonmemory_operand" "")))
11109 (clobber (reg:CC 17))]
11110 "TARGET_QIMODE_MATH"
11111 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11112
11113 ;; %%% Potential partial reg stall on alternative 2. What to do?
11114
11115 (define_insn "*ashlqi3_1_lea"
11116 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11117 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11118 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11119 (clobber (reg:CC 17))]
11120 "!TARGET_PARTIAL_REG_STALL
11121 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11122 {
11123 switch (get_attr_type (insn))
11124 {
11125 case TYPE_LEA:
11126 return "#";
11127 case TYPE_ALU:
11128 if (operands[2] != const1_rtx)
11129 abort ();
11130 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11131 return "add{l}\t{%k0, %k0|%k0, %k0}";
11132 else
11133 return "add{b}\t{%0, %0|%0, %0}";
11134
11135 default:
11136 if (REG_P (operands[2]))
11137 {
11138 if (get_attr_mode (insn) == MODE_SI)
11139 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11140 else
11141 return "sal{b}\t{%b2, %0|%0, %b2}";
11142 }
11143 else if (operands[2] == const1_rtx
11144 && (TARGET_SHIFT1 || optimize_size))
11145 {
11146 if (get_attr_mode (insn) == MODE_SI)
11147 return "sal{l}\t%0";
11148 else
11149 return "sal{b}\t%0";
11150 }
11151 else
11152 {
11153 if (get_attr_mode (insn) == MODE_SI)
11154 return "sal{l}\t{%2, %k0|%k0, %2}";
11155 else
11156 return "sal{b}\t{%2, %0|%0, %2}";
11157 }
11158 }
11159 }
11160 [(set (attr "type")
11161 (cond [(eq_attr "alternative" "2")
11162 (const_string "lea")
11163 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11164 (const_int 0))
11165 (match_operand 0 "register_operand" ""))
11166 (match_operand 2 "const1_operand" ""))
11167 (const_string "alu")
11168 ]
11169 (const_string "ishift")))
11170 (set_attr "mode" "QI,SI,SI")])
11171
11172 (define_insn "*ashlqi3_1"
11173 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11174 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11175 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11176 (clobber (reg:CC 17))]
11177 "TARGET_PARTIAL_REG_STALL
11178 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11179 {
11180 switch (get_attr_type (insn))
11181 {
11182 case TYPE_ALU:
11183 if (operands[2] != const1_rtx)
11184 abort ();
11185 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11186 return "add{l}\t{%k0, %k0|%k0, %k0}";
11187 else
11188 return "add{b}\t{%0, %0|%0, %0}";
11189
11190 default:
11191 if (REG_P (operands[2]))
11192 {
11193 if (get_attr_mode (insn) == MODE_SI)
11194 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11195 else
11196 return "sal{b}\t{%b2, %0|%0, %b2}";
11197 }
11198 else if (operands[2] == const1_rtx
11199 && (TARGET_SHIFT1 || optimize_size))
11200 {
11201 if (get_attr_mode (insn) == MODE_SI)
11202 return "sal{l}\t%0";
11203 else
11204 return "sal{b}\t%0";
11205 }
11206 else
11207 {
11208 if (get_attr_mode (insn) == MODE_SI)
11209 return "sal{l}\t{%2, %k0|%k0, %2}";
11210 else
11211 return "sal{b}\t{%2, %0|%0, %2}";
11212 }
11213 }
11214 }
11215 [(set (attr "type")
11216 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11217 (const_int 0))
11218 (match_operand 0 "register_operand" ""))
11219 (match_operand 2 "const1_operand" ""))
11220 (const_string "alu")
11221 ]
11222 (const_string "ishift")))
11223 (set_attr "mode" "QI,SI")])
11224
11225 ;; This pattern can't accept a variable shift count, since shifts by
11226 ;; zero don't affect the flags. We assume that shifts by constant
11227 ;; zero are optimized away.
11228 (define_insn "*ashlqi3_cmp"
11229 [(set (reg 17)
11230 (compare
11231 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11232 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11233 (const_int 0)))
11234 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11235 (ashift:QI (match_dup 1) (match_dup 2)))]
11236 "ix86_match_ccmode (insn, CCGOCmode)
11237 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11238 {
11239 switch (get_attr_type (insn))
11240 {
11241 case TYPE_ALU:
11242 if (operands[2] != const1_rtx)
11243 abort ();
11244 return "add{b}\t{%0, %0|%0, %0}";
11245
11246 default:
11247 if (REG_P (operands[2]))
11248 return "sal{b}\t{%b2, %0|%0, %b2}";
11249 else if (operands[2] == const1_rtx
11250 && (TARGET_SHIFT1 || optimize_size))
11251 return "sal{b}\t%0";
11252 else
11253 return "sal{b}\t{%2, %0|%0, %2}";
11254 }
11255 }
11256 [(set (attr "type")
11257 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11258 (const_int 0))
11259 (match_operand 0 "register_operand" ""))
11260 (match_operand 2 "const1_operand" ""))
11261 (const_string "alu")
11262 ]
11263 (const_string "ishift")))
11264 (set_attr "mode" "QI")])
11265
11266 ;; See comment above `ashldi3' about how this works.
11267
11268 (define_expand "ashrdi3"
11269 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11270 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11271 (match_operand:QI 2 "nonmemory_operand" "")))
11272 (clobber (reg:CC 17))])]
11273 ""
11274 {
11275 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11276 {
11277 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11278 DONE;
11279 }
11280 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11281 DONE;
11282 })
11283
11284 (define_insn "ashrdi3_63_rex64"
11285 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11286 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11287 (match_operand:DI 2 "const_int_operand" "i,i")))
11288 (clobber (reg:CC 17))]
11289 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11290 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11291 "@
11292 {cqto|cqo}
11293 sar{q}\t{%2, %0|%0, %2}"
11294 [(set_attr "type" "imovx,ishift")
11295 (set_attr "prefix_0f" "0,*")
11296 (set_attr "length_immediate" "0,*")
11297 (set_attr "modrm" "0,1")
11298 (set_attr "mode" "DI")])
11299
11300 (define_insn "*ashrdi3_1_one_bit_rex64"
11301 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11302 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11303 (match_operand:QI 2 "const1_operand" "")))
11304 (clobber (reg:CC 17))]
11305 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11306 && (TARGET_SHIFT1 || optimize_size)"
11307 "sar{q}\t%0"
11308 [(set_attr "type" "ishift")
11309 (set (attr "length")
11310 (if_then_else (match_operand:DI 0 "register_operand" "")
11311 (const_string "2")
11312 (const_string "*")))])
11313
11314 (define_insn "*ashrdi3_1_rex64"
11315 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11316 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11317 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11318 (clobber (reg:CC 17))]
11319 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11320 "@
11321 sar{q}\t{%2, %0|%0, %2}
11322 sar{q}\t{%b2, %0|%0, %b2}"
11323 [(set_attr "type" "ishift")
11324 (set_attr "mode" "DI")])
11325
11326 ;; This pattern can't accept a variable shift count, since shifts by
11327 ;; zero don't affect the flags. We assume that shifts by constant
11328 ;; zero are optimized away.
11329 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11330 [(set (reg 17)
11331 (compare
11332 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11333 (match_operand:QI 2 "const1_operand" ""))
11334 (const_int 0)))
11335 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11336 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11337 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11338 && (TARGET_SHIFT1 || optimize_size)
11339 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11340 "sar{q}\t%0"
11341 [(set_attr "type" "ishift")
11342 (set (attr "length")
11343 (if_then_else (match_operand:DI 0 "register_operand" "")
11344 (const_string "2")
11345 (const_string "*")))])
11346
11347 ;; This pattern can't accept a variable shift count, since shifts by
11348 ;; zero don't affect the flags. We assume that shifts by constant
11349 ;; zero are optimized away.
11350 (define_insn "*ashrdi3_cmp_rex64"
11351 [(set (reg 17)
11352 (compare
11353 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11354 (match_operand:QI 2 "const_int_operand" "n"))
11355 (const_int 0)))
11356 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11357 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11358 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11359 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11360 "sar{q}\t{%2, %0|%0, %2}"
11361 [(set_attr "type" "ishift")
11362 (set_attr "mode" "DI")])
11363
11364
11365 (define_insn "ashrdi3_1"
11366 [(set (match_operand:DI 0 "register_operand" "=r")
11367 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11368 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11369 (clobber (match_scratch:SI 3 "=&r"))
11370 (clobber (reg:CC 17))]
11371 "!TARGET_64BIT && TARGET_CMOVE"
11372 "#"
11373 [(set_attr "type" "multi")])
11374
11375 (define_insn "*ashrdi3_2"
11376 [(set (match_operand:DI 0 "register_operand" "=r")
11377 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11378 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11379 (clobber (reg:CC 17))]
11380 "!TARGET_64BIT"
11381 "#"
11382 [(set_attr "type" "multi")])
11383
11384 (define_split
11385 [(set (match_operand:DI 0 "register_operand" "")
11386 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11387 (match_operand:QI 2 "nonmemory_operand" "")))
11388 (clobber (match_scratch:SI 3 ""))
11389 (clobber (reg:CC 17))]
11390 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11391 [(const_int 0)]
11392 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11393
11394 (define_split
11395 [(set (match_operand:DI 0 "register_operand" "")
11396 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11397 (match_operand:QI 2 "nonmemory_operand" "")))
11398 (clobber (reg:CC 17))]
11399 "!TARGET_64BIT && reload_completed"
11400 [(const_int 0)]
11401 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11402
11403 (define_insn "x86_shrd_1"
11404 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11405 (ior:SI (ashiftrt:SI (match_dup 0)
11406 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11407 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11408 (minus:QI (const_int 32) (match_dup 2)))))
11409 (clobber (reg:CC 17))]
11410 ""
11411 "@
11412 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11413 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11414 [(set_attr "type" "ishift")
11415 (set_attr "prefix_0f" "1")
11416 (set_attr "pent_pair" "np")
11417 (set_attr "mode" "SI")])
11418
11419 (define_expand "x86_shift_adj_3"
11420 [(use (match_operand:SI 0 "register_operand" ""))
11421 (use (match_operand:SI 1 "register_operand" ""))
11422 (use (match_operand:QI 2 "register_operand" ""))]
11423 ""
11424 {
11425 rtx label = gen_label_rtx ();
11426 rtx tmp;
11427
11428 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11429
11430 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11431 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11432 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11433 gen_rtx_LABEL_REF (VOIDmode, label),
11434 pc_rtx);
11435 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11436 JUMP_LABEL (tmp) = label;
11437
11438 emit_move_insn (operands[0], operands[1]);
11439 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11440
11441 emit_label (label);
11442 LABEL_NUSES (label) = 1;
11443
11444 DONE;
11445 })
11446
11447 (define_insn "ashrsi3_31"
11448 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11449 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11450 (match_operand:SI 2 "const_int_operand" "i,i")))
11451 (clobber (reg:CC 17))]
11452 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11453 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11454 "@
11455 {cltd|cdq}
11456 sar{l}\t{%2, %0|%0, %2}"
11457 [(set_attr "type" "imovx,ishift")
11458 (set_attr "prefix_0f" "0,*")
11459 (set_attr "length_immediate" "0,*")
11460 (set_attr "modrm" "0,1")
11461 (set_attr "mode" "SI")])
11462
11463 (define_insn "*ashrsi3_31_zext"
11464 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11465 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11466 (match_operand:SI 2 "const_int_operand" "i,i"))))
11467 (clobber (reg:CC 17))]
11468 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11469 && INTVAL (operands[2]) == 31
11470 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11471 "@
11472 {cltd|cdq}
11473 sar{l}\t{%2, %k0|%k0, %2}"
11474 [(set_attr "type" "imovx,ishift")
11475 (set_attr "prefix_0f" "0,*")
11476 (set_attr "length_immediate" "0,*")
11477 (set_attr "modrm" "0,1")
11478 (set_attr "mode" "SI")])
11479
11480 (define_expand "ashrsi3"
11481 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11482 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11483 (match_operand:QI 2 "nonmemory_operand" "")))
11484 (clobber (reg:CC 17))]
11485 ""
11486 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11487
11488 (define_insn "*ashrsi3_1_one_bit"
11489 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11490 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11491 (match_operand:QI 2 "const1_operand" "")))
11492 (clobber (reg:CC 17))]
11493 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11494 && (TARGET_SHIFT1 || optimize_size)"
11495 "sar{l}\t%0"
11496 [(set_attr "type" "ishift")
11497 (set (attr "length")
11498 (if_then_else (match_operand:SI 0 "register_operand" "")
11499 (const_string "2")
11500 (const_string "*")))])
11501
11502 (define_insn "*ashrsi3_1_one_bit_zext"
11503 [(set (match_operand:DI 0 "register_operand" "=r")
11504 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11505 (match_operand:QI 2 "const1_operand" ""))))
11506 (clobber (reg:CC 17))]
11507 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11508 && (TARGET_SHIFT1 || optimize_size)"
11509 "sar{l}\t%k0"
11510 [(set_attr "type" "ishift")
11511 (set_attr "length" "2")])
11512
11513 (define_insn "*ashrsi3_1"
11514 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11515 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11516 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11517 (clobber (reg:CC 17))]
11518 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11519 "@
11520 sar{l}\t{%2, %0|%0, %2}
11521 sar{l}\t{%b2, %0|%0, %b2}"
11522 [(set_attr "type" "ishift")
11523 (set_attr "mode" "SI")])
11524
11525 (define_insn "*ashrsi3_1_zext"
11526 [(set (match_operand:DI 0 "register_operand" "=r,r")
11527 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11528 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11529 (clobber (reg:CC 17))]
11530 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11531 "@
11532 sar{l}\t{%2, %k0|%k0, %2}
11533 sar{l}\t{%b2, %k0|%k0, %b2}"
11534 [(set_attr "type" "ishift")
11535 (set_attr "mode" "SI")])
11536
11537 ;; This pattern can't accept a variable shift count, since shifts by
11538 ;; zero don't affect the flags. We assume that shifts by constant
11539 ;; zero are optimized away.
11540 (define_insn "*ashrsi3_one_bit_cmp"
11541 [(set (reg 17)
11542 (compare
11543 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11544 (match_operand:QI 2 "const1_operand" ""))
11545 (const_int 0)))
11546 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11547 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11548 "ix86_match_ccmode (insn, CCGOCmode)
11549 && (TARGET_SHIFT1 || optimize_size)
11550 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11551 "sar{l}\t%0"
11552 [(set_attr "type" "ishift")
11553 (set (attr "length")
11554 (if_then_else (match_operand:SI 0 "register_operand" "")
11555 (const_string "2")
11556 (const_string "*")))])
11557
11558 (define_insn "*ashrsi3_one_bit_cmp_zext"
11559 [(set (reg 17)
11560 (compare
11561 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11562 (match_operand:QI 2 "const1_operand" ""))
11563 (const_int 0)))
11564 (set (match_operand:DI 0 "register_operand" "=r")
11565 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11566 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11567 && (TARGET_SHIFT1 || optimize_size)
11568 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11569 "sar{l}\t%k0"
11570 [(set_attr "type" "ishift")
11571 (set_attr "length" "2")])
11572
11573 ;; This pattern can't accept a variable shift count, since shifts by
11574 ;; zero don't affect the flags. We assume that shifts by constant
11575 ;; zero are optimized away.
11576 (define_insn "*ashrsi3_cmp"
11577 [(set (reg 17)
11578 (compare
11579 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11580 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11581 (const_int 0)))
11582 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11583 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11584 "ix86_match_ccmode (insn, CCGOCmode)
11585 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11586 "sar{l}\t{%2, %0|%0, %2}"
11587 [(set_attr "type" "ishift")
11588 (set_attr "mode" "SI")])
11589
11590 (define_insn "*ashrsi3_cmp_zext"
11591 [(set (reg 17)
11592 (compare
11593 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11594 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11595 (const_int 0)))
11596 (set (match_operand:DI 0 "register_operand" "=r")
11597 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11598 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11599 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11600 "sar{l}\t{%2, %k0|%k0, %2}"
11601 [(set_attr "type" "ishift")
11602 (set_attr "mode" "SI")])
11603
11604 (define_expand "ashrhi3"
11605 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11606 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11607 (match_operand:QI 2 "nonmemory_operand" "")))
11608 (clobber (reg:CC 17))]
11609 "TARGET_HIMODE_MATH"
11610 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11611
11612 (define_insn "*ashrhi3_1_one_bit"
11613 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11614 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11615 (match_operand:QI 2 "const1_operand" "")))
11616 (clobber (reg:CC 17))]
11617 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11618 && (TARGET_SHIFT1 || optimize_size)"
11619 "sar{w}\t%0"
11620 [(set_attr "type" "ishift")
11621 (set (attr "length")
11622 (if_then_else (match_operand 0 "register_operand" "")
11623 (const_string "2")
11624 (const_string "*")))])
11625
11626 (define_insn "*ashrhi3_1"
11627 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11628 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11629 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11630 (clobber (reg:CC 17))]
11631 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11632 "@
11633 sar{w}\t{%2, %0|%0, %2}
11634 sar{w}\t{%b2, %0|%0, %b2}"
11635 [(set_attr "type" "ishift")
11636 (set_attr "mode" "HI")])
11637
11638 ;; This pattern can't accept a variable shift count, since shifts by
11639 ;; zero don't affect the flags. We assume that shifts by constant
11640 ;; zero are optimized away.
11641 (define_insn "*ashrhi3_one_bit_cmp"
11642 [(set (reg 17)
11643 (compare
11644 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11645 (match_operand:QI 2 "const1_operand" ""))
11646 (const_int 0)))
11647 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11648 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11649 "ix86_match_ccmode (insn, CCGOCmode)
11650 && (TARGET_SHIFT1 || optimize_size)
11651 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11652 "sar{w}\t%0"
11653 [(set_attr "type" "ishift")
11654 (set (attr "length")
11655 (if_then_else (match_operand 0 "register_operand" "")
11656 (const_string "2")
11657 (const_string "*")))])
11658
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags. We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*ashrhi3_cmp"
11663 [(set (reg 17)
11664 (compare
11665 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11666 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11667 (const_int 0)))
11668 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11669 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11670 "ix86_match_ccmode (insn, CCGOCmode)
11671 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11672 "sar{w}\t{%2, %0|%0, %2}"
11673 [(set_attr "type" "ishift")
11674 (set_attr "mode" "HI")])
11675
11676 (define_expand "ashrqi3"
11677 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11678 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11679 (match_operand:QI 2 "nonmemory_operand" "")))
11680 (clobber (reg:CC 17))]
11681 "TARGET_QIMODE_MATH"
11682 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11683
11684 (define_insn "*ashrqi3_1_one_bit"
11685 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11686 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11687 (match_operand:QI 2 "const1_operand" "")))
11688 (clobber (reg:CC 17))]
11689 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11690 && (TARGET_SHIFT1 || optimize_size)"
11691 "sar{b}\t%0"
11692 [(set_attr "type" "ishift")
11693 (set (attr "length")
11694 (if_then_else (match_operand 0 "register_operand" "")
11695 (const_string "2")
11696 (const_string "*")))])
11697
11698 (define_insn "*ashrqi3_1_one_bit_slp"
11699 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11700 (ashiftrt:QI (match_dup 0)
11701 (match_operand:QI 1 "const1_operand" "")))
11702 (clobber (reg:CC 17))]
11703 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11704 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11705 && (TARGET_SHIFT1 || optimize_size)"
11706 "sar{b}\t%0"
11707 [(set_attr "type" "ishift1")
11708 (set (attr "length")
11709 (if_then_else (match_operand 0 "register_operand" "")
11710 (const_string "2")
11711 (const_string "*")))])
11712
11713 (define_insn "*ashrqi3_1"
11714 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11715 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11716 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11717 (clobber (reg:CC 17))]
11718 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11719 "@
11720 sar{b}\t{%2, %0|%0, %2}
11721 sar{b}\t{%b2, %0|%0, %b2}"
11722 [(set_attr "type" "ishift")
11723 (set_attr "mode" "QI")])
11724
11725 (define_insn "*ashrqi3_1_slp"
11726 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11727 (ashiftrt:QI (match_dup 0)
11728 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11729 (clobber (reg:CC 17))]
11730 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11731 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11732 "@
11733 sar{b}\t{%1, %0|%0, %1}
11734 sar{b}\t{%b1, %0|%0, %b1}"
11735 [(set_attr "type" "ishift1")
11736 (set_attr "mode" "QI")])
11737
11738 ;; This pattern can't accept a variable shift count, since shifts by
11739 ;; zero don't affect the flags. We assume that shifts by constant
11740 ;; zero are optimized away.
11741 (define_insn "*ashrqi3_one_bit_cmp"
11742 [(set (reg 17)
11743 (compare
11744 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11745 (match_operand:QI 2 "const1_operand" "I"))
11746 (const_int 0)))
11747 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11748 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11749 "ix86_match_ccmode (insn, CCGOCmode)
11750 && (TARGET_SHIFT1 || optimize_size)
11751 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11752 "sar{b}\t%0"
11753 [(set_attr "type" "ishift")
11754 (set (attr "length")
11755 (if_then_else (match_operand 0 "register_operand" "")
11756 (const_string "2")
11757 (const_string "*")))])
11758
11759 ;; This pattern can't accept a variable shift count, since shifts by
11760 ;; zero don't affect the flags. We assume that shifts by constant
11761 ;; zero are optimized away.
11762 (define_insn "*ashrqi3_cmp"
11763 [(set (reg 17)
11764 (compare
11765 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11766 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11767 (const_int 0)))
11768 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11769 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11770 "ix86_match_ccmode (insn, CCGOCmode)
11771 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11772 "sar{b}\t{%2, %0|%0, %2}"
11773 [(set_attr "type" "ishift")
11774 (set_attr "mode" "QI")])
11775 \f
11776 ;; Logical shift instructions
11777
11778 ;; See comment above `ashldi3' about how this works.
11779
11780 (define_expand "lshrdi3"
11781 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11782 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11783 (match_operand:QI 2 "nonmemory_operand" "")))
11784 (clobber (reg:CC 17))])]
11785 ""
11786 {
11787 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11788 {
11789 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11790 DONE;
11791 }
11792 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11793 DONE;
11794 })
11795
11796 (define_insn "*lshrdi3_1_one_bit_rex64"
11797 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11798 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11799 (match_operand:QI 2 "const1_operand" "")))
11800 (clobber (reg:CC 17))]
11801 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11802 && (TARGET_SHIFT1 || optimize_size)"
11803 "shr{q}\t%0"
11804 [(set_attr "type" "ishift")
11805 (set (attr "length")
11806 (if_then_else (match_operand:DI 0 "register_operand" "")
11807 (const_string "2")
11808 (const_string "*")))])
11809
11810 (define_insn "*lshrdi3_1_rex64"
11811 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11812 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11813 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11814 (clobber (reg:CC 17))]
11815 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11816 "@
11817 shr{q}\t{%2, %0|%0, %2}
11818 shr{q}\t{%b2, %0|%0, %b2}"
11819 [(set_attr "type" "ishift")
11820 (set_attr "mode" "DI")])
11821
11822 ;; This pattern can't accept a variable shift count, since shifts by
11823 ;; zero don't affect the flags. We assume that shifts by constant
11824 ;; zero are optimized away.
11825 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11826 [(set (reg 17)
11827 (compare
11828 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11829 (match_operand:QI 2 "const1_operand" ""))
11830 (const_int 0)))
11831 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11832 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11833 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11834 && (TARGET_SHIFT1 || optimize_size)
11835 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11836 "shr{q}\t%0"
11837 [(set_attr "type" "ishift")
11838 (set (attr "length")
11839 (if_then_else (match_operand:DI 0 "register_operand" "")
11840 (const_string "2")
11841 (const_string "*")))])
11842
11843 ;; This pattern can't accept a variable shift count, since shifts by
11844 ;; zero don't affect the flags. We assume that shifts by constant
11845 ;; zero are optimized away.
11846 (define_insn "*lshrdi3_cmp_rex64"
11847 [(set (reg 17)
11848 (compare
11849 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11850 (match_operand:QI 2 "const_int_operand" "e"))
11851 (const_int 0)))
11852 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11853 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11854 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11855 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11856 "shr{q}\t{%2, %0|%0, %2}"
11857 [(set_attr "type" "ishift")
11858 (set_attr "mode" "DI")])
11859
11860 (define_insn "lshrdi3_1"
11861 [(set (match_operand:DI 0 "register_operand" "=r")
11862 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11863 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11864 (clobber (match_scratch:SI 3 "=&r"))
11865 (clobber (reg:CC 17))]
11866 "!TARGET_64BIT && TARGET_CMOVE"
11867 "#"
11868 [(set_attr "type" "multi")])
11869
11870 (define_insn "*lshrdi3_2"
11871 [(set (match_operand:DI 0 "register_operand" "=r")
11872 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11873 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11874 (clobber (reg:CC 17))]
11875 "!TARGET_64BIT"
11876 "#"
11877 [(set_attr "type" "multi")])
11878
11879 (define_split
11880 [(set (match_operand:DI 0 "register_operand" "")
11881 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11882 (match_operand:QI 2 "nonmemory_operand" "")))
11883 (clobber (match_scratch:SI 3 ""))
11884 (clobber (reg:CC 17))]
11885 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11886 [(const_int 0)]
11887 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11888
11889 (define_split
11890 [(set (match_operand:DI 0 "register_operand" "")
11891 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11892 (match_operand:QI 2 "nonmemory_operand" "")))
11893 (clobber (reg:CC 17))]
11894 "!TARGET_64BIT && reload_completed"
11895 [(const_int 0)]
11896 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11897
11898 (define_expand "lshrsi3"
11899 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11900 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11901 (match_operand:QI 2 "nonmemory_operand" "")))
11902 (clobber (reg:CC 17))]
11903 ""
11904 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11905
11906 (define_insn "*lshrsi3_1_one_bit"
11907 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11908 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11909 (match_operand:QI 2 "const1_operand" "")))
11910 (clobber (reg:CC 17))]
11911 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11912 && (TARGET_SHIFT1 || optimize_size)"
11913 "shr{l}\t%0"
11914 [(set_attr "type" "ishift")
11915 (set (attr "length")
11916 (if_then_else (match_operand:SI 0 "register_operand" "")
11917 (const_string "2")
11918 (const_string "*")))])
11919
11920 (define_insn "*lshrsi3_1_one_bit_zext"
11921 [(set (match_operand:DI 0 "register_operand" "=r")
11922 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11923 (match_operand:QI 2 "const1_operand" "")))
11924 (clobber (reg:CC 17))]
11925 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11926 && (TARGET_SHIFT1 || optimize_size)"
11927 "shr{l}\t%k0"
11928 [(set_attr "type" "ishift")
11929 (set_attr "length" "2")])
11930
11931 (define_insn "*lshrsi3_1"
11932 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11933 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11934 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11935 (clobber (reg:CC 17))]
11936 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11937 "@
11938 shr{l}\t{%2, %0|%0, %2}
11939 shr{l}\t{%b2, %0|%0, %b2}"
11940 [(set_attr "type" "ishift")
11941 (set_attr "mode" "SI")])
11942
11943 (define_insn "*lshrsi3_1_zext"
11944 [(set (match_operand:DI 0 "register_operand" "=r,r")
11945 (zero_extend:DI
11946 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11947 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11948 (clobber (reg:CC 17))]
11949 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11950 "@
11951 shr{l}\t{%2, %k0|%k0, %2}
11952 shr{l}\t{%b2, %k0|%k0, %b2}"
11953 [(set_attr "type" "ishift")
11954 (set_attr "mode" "SI")])
11955
11956 ;; This pattern can't accept a variable shift count, since shifts by
11957 ;; zero don't affect the flags. We assume that shifts by constant
11958 ;; zero are optimized away.
11959 (define_insn "*lshrsi3_one_bit_cmp"
11960 [(set (reg 17)
11961 (compare
11962 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11963 (match_operand:QI 2 "const1_operand" ""))
11964 (const_int 0)))
11965 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11966 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11967 "ix86_match_ccmode (insn, CCGOCmode)
11968 && (TARGET_SHIFT1 || optimize_size)
11969 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11970 "shr{l}\t%0"
11971 [(set_attr "type" "ishift")
11972 (set (attr "length")
11973 (if_then_else (match_operand:SI 0 "register_operand" "")
11974 (const_string "2")
11975 (const_string "*")))])
11976
11977 (define_insn "*lshrsi3_cmp_one_bit_zext"
11978 [(set (reg 17)
11979 (compare
11980 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11981 (match_operand:QI 2 "const1_operand" ""))
11982 (const_int 0)))
11983 (set (match_operand:DI 0 "register_operand" "=r")
11984 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11985 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11986 && (TARGET_SHIFT1 || optimize_size)
11987 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11988 "shr{l}\t%k0"
11989 [(set_attr "type" "ishift")
11990 (set_attr "length" "2")])
11991
11992 ;; This pattern can't accept a variable shift count, since shifts by
11993 ;; zero don't affect the flags. We assume that shifts by constant
11994 ;; zero are optimized away.
11995 (define_insn "*lshrsi3_cmp"
11996 [(set (reg 17)
11997 (compare
11998 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11999 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12000 (const_int 0)))
12001 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12002 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12003 "ix86_match_ccmode (insn, CCGOCmode)
12004 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12005 "shr{l}\t{%2, %0|%0, %2}"
12006 [(set_attr "type" "ishift")
12007 (set_attr "mode" "SI")])
12008
12009 (define_insn "*lshrsi3_cmp_zext"
12010 [(set (reg 17)
12011 (compare
12012 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12013 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12014 (const_int 0)))
12015 (set (match_operand:DI 0 "register_operand" "=r")
12016 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12017 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12018 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12019 "shr{l}\t{%2, %k0|%k0, %2}"
12020 [(set_attr "type" "ishift")
12021 (set_attr "mode" "SI")])
12022
12023 (define_expand "lshrhi3"
12024 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12025 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12026 (match_operand:QI 2 "nonmemory_operand" "")))
12027 (clobber (reg:CC 17))]
12028 "TARGET_HIMODE_MATH"
12029 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12030
12031 (define_insn "*lshrhi3_1_one_bit"
12032 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12033 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12034 (match_operand:QI 2 "const1_operand" "")))
12035 (clobber (reg:CC 17))]
12036 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12037 && (TARGET_SHIFT1 || optimize_size)"
12038 "shr{w}\t%0"
12039 [(set_attr "type" "ishift")
12040 (set (attr "length")
12041 (if_then_else (match_operand 0 "register_operand" "")
12042 (const_string "2")
12043 (const_string "*")))])
12044
12045 (define_insn "*lshrhi3_1"
12046 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12047 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12048 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12049 (clobber (reg:CC 17))]
12050 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12051 "@
12052 shr{w}\t{%2, %0|%0, %2}
12053 shr{w}\t{%b2, %0|%0, %b2}"
12054 [(set_attr "type" "ishift")
12055 (set_attr "mode" "HI")])
12056
12057 ;; This pattern can't accept a variable shift count, since shifts by
12058 ;; zero don't affect the flags. We assume that shifts by constant
12059 ;; zero are optimized away.
12060 (define_insn "*lshrhi3_one_bit_cmp"
12061 [(set (reg 17)
12062 (compare
12063 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12064 (match_operand:QI 2 "const1_operand" ""))
12065 (const_int 0)))
12066 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12067 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12068 "ix86_match_ccmode (insn, CCGOCmode)
12069 && (TARGET_SHIFT1 || optimize_size)
12070 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12071 "shr{w}\t%0"
12072 [(set_attr "type" "ishift")
12073 (set (attr "length")
12074 (if_then_else (match_operand:SI 0 "register_operand" "")
12075 (const_string "2")
12076 (const_string "*")))])
12077
12078 ;; This pattern can't accept a variable shift count, since shifts by
12079 ;; zero don't affect the flags. We assume that shifts by constant
12080 ;; zero are optimized away.
12081 (define_insn "*lshrhi3_cmp"
12082 [(set (reg 17)
12083 (compare
12084 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12085 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12086 (const_int 0)))
12087 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12088 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12089 "ix86_match_ccmode (insn, CCGOCmode)
12090 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12091 "shr{w}\t{%2, %0|%0, %2}"
12092 [(set_attr "type" "ishift")
12093 (set_attr "mode" "HI")])
12094
12095 (define_expand "lshrqi3"
12096 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12097 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12098 (match_operand:QI 2 "nonmemory_operand" "")))
12099 (clobber (reg:CC 17))]
12100 "TARGET_QIMODE_MATH"
12101 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12102
12103 (define_insn "*lshrqi3_1_one_bit"
12104 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12105 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12106 (match_operand:QI 2 "const1_operand" "")))
12107 (clobber (reg:CC 17))]
12108 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12109 && (TARGET_SHIFT1 || optimize_size)"
12110 "shr{b}\t%0"
12111 [(set_attr "type" "ishift")
12112 (set (attr "length")
12113 (if_then_else (match_operand 0 "register_operand" "")
12114 (const_string "2")
12115 (const_string "*")))])
12116
12117 (define_insn "*lshrqi3_1_one_bit_slp"
12118 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12119 (lshiftrt:QI (match_dup 0)
12120 (match_operand:QI 1 "const1_operand" "")))
12121 (clobber (reg:CC 17))]
12122 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12123 && (TARGET_SHIFT1 || optimize_size)"
12124 "shr{b}\t%0"
12125 [(set_attr "type" "ishift1")
12126 (set (attr "length")
12127 (if_then_else (match_operand 0 "register_operand" "")
12128 (const_string "2")
12129 (const_string "*")))])
12130
12131 (define_insn "*lshrqi3_1"
12132 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12133 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12134 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12135 (clobber (reg:CC 17))]
12136 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12137 "@
12138 shr{b}\t{%2, %0|%0, %2}
12139 shr{b}\t{%b2, %0|%0, %b2}"
12140 [(set_attr "type" "ishift")
12141 (set_attr "mode" "QI")])
12142
12143 (define_insn "*lshrqi3_1_slp"
12144 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12145 (lshiftrt:QI (match_dup 0)
12146 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12147 (clobber (reg:CC 17))]
12148 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12149 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12150 "@
12151 shr{b}\t{%1, %0|%0, %1}
12152 shr{b}\t{%b1, %0|%0, %b1}"
12153 [(set_attr "type" "ishift1")
12154 (set_attr "mode" "QI")])
12155
12156 ;; This pattern can't accept a variable shift count, since shifts by
12157 ;; zero don't affect the flags. We assume that shifts by constant
12158 ;; zero are optimized away.
12159 (define_insn "*lshrqi2_one_bit_cmp"
12160 [(set (reg 17)
12161 (compare
12162 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12163 (match_operand:QI 2 "const1_operand" ""))
12164 (const_int 0)))
12165 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12166 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12167 "ix86_match_ccmode (insn, CCGOCmode)
12168 && (TARGET_SHIFT1 || optimize_size)
12169 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12170 "shr{b}\t%0"
12171 [(set_attr "type" "ishift")
12172 (set (attr "length")
12173 (if_then_else (match_operand:SI 0 "register_operand" "")
12174 (const_string "2")
12175 (const_string "*")))])
12176
12177 ;; This pattern can't accept a variable shift count, since shifts by
12178 ;; zero don't affect the flags. We assume that shifts by constant
12179 ;; zero are optimized away.
12180 (define_insn "*lshrqi2_cmp"
12181 [(set (reg 17)
12182 (compare
12183 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12184 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12185 (const_int 0)))
12186 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12187 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12188 "ix86_match_ccmode (insn, CCGOCmode)
12189 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12190 "shr{b}\t{%2, %0|%0, %2}"
12191 [(set_attr "type" "ishift")
12192 (set_attr "mode" "QI")])
12193 \f
12194 ;; Rotate instructions
12195
12196 (define_expand "rotldi3"
12197 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12198 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12199 (match_operand:QI 2 "nonmemory_operand" "")))
12200 (clobber (reg:CC 17))]
12201 "TARGET_64BIT"
12202 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12203
12204 (define_insn "*rotlsi3_1_one_bit_rex64"
12205 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12206 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12207 (match_operand:QI 2 "const1_operand" "")))
12208 (clobber (reg:CC 17))]
12209 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12210 && (TARGET_SHIFT1 || optimize_size)"
12211 "rol{q}\t%0"
12212 [(set_attr "type" "rotate")
12213 (set (attr "length")
12214 (if_then_else (match_operand:DI 0 "register_operand" "")
12215 (const_string "2")
12216 (const_string "*")))])
12217
12218 (define_insn "*rotldi3_1_rex64"
12219 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12220 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12221 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12222 (clobber (reg:CC 17))]
12223 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12224 "@
12225 rol{q}\t{%2, %0|%0, %2}
12226 rol{q}\t{%b2, %0|%0, %b2}"
12227 [(set_attr "type" "rotate")
12228 (set_attr "mode" "DI")])
12229
12230 (define_expand "rotlsi3"
12231 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12232 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12233 (match_operand:QI 2 "nonmemory_operand" "")))
12234 (clobber (reg:CC 17))]
12235 ""
12236 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12237
12238 (define_insn "*rotlsi3_1_one_bit"
12239 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12240 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12241 (match_operand:QI 2 "const1_operand" "")))
12242 (clobber (reg:CC 17))]
12243 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12244 && (TARGET_SHIFT1 || optimize_size)"
12245 "rol{l}\t%0"
12246 [(set_attr "type" "rotate")
12247 (set (attr "length")
12248 (if_then_else (match_operand:SI 0 "register_operand" "")
12249 (const_string "2")
12250 (const_string "*")))])
12251
12252 (define_insn "*rotlsi3_1_one_bit_zext"
12253 [(set (match_operand:DI 0 "register_operand" "=r")
12254 (zero_extend:DI
12255 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12256 (match_operand:QI 2 "const1_operand" ""))))
12257 (clobber (reg:CC 17))]
12258 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12259 && (TARGET_SHIFT1 || optimize_size)"
12260 "rol{l}\t%k0"
12261 [(set_attr "type" "rotate")
12262 (set_attr "length" "2")])
12263
12264 (define_insn "*rotlsi3_1"
12265 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12266 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12267 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12268 (clobber (reg:CC 17))]
12269 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12270 "@
12271 rol{l}\t{%2, %0|%0, %2}
12272 rol{l}\t{%b2, %0|%0, %b2}"
12273 [(set_attr "type" "rotate")
12274 (set_attr "mode" "SI")])
12275
12276 (define_insn "*rotlsi3_1_zext"
12277 [(set (match_operand:DI 0 "register_operand" "=r,r")
12278 (zero_extend:DI
12279 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12280 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12281 (clobber (reg:CC 17))]
12282 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12283 "@
12284 rol{l}\t{%2, %k0|%k0, %2}
12285 rol{l}\t{%b2, %k0|%k0, %b2}"
12286 [(set_attr "type" "rotate")
12287 (set_attr "mode" "SI")])
12288
12289 (define_expand "rotlhi3"
12290 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12291 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12292 (match_operand:QI 2 "nonmemory_operand" "")))
12293 (clobber (reg:CC 17))]
12294 "TARGET_HIMODE_MATH"
12295 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12296
12297 (define_insn "*rotlhi3_1_one_bit"
12298 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12299 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12300 (match_operand:QI 2 "const1_operand" "")))
12301 (clobber (reg:CC 17))]
12302 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12303 && (TARGET_SHIFT1 || optimize_size)"
12304 "rol{w}\t%0"
12305 [(set_attr "type" "rotate")
12306 (set (attr "length")
12307 (if_then_else (match_operand 0 "register_operand" "")
12308 (const_string "2")
12309 (const_string "*")))])
12310
12311 (define_insn "*rotlhi3_1"
12312 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12313 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12314 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12315 (clobber (reg:CC 17))]
12316 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12317 "@
12318 rol{w}\t{%2, %0|%0, %2}
12319 rol{w}\t{%b2, %0|%0, %b2}"
12320 [(set_attr "type" "rotate")
12321 (set_attr "mode" "HI")])
12322
12323 (define_expand "rotlqi3"
12324 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12325 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12326 (match_operand:QI 2 "nonmemory_operand" "")))
12327 (clobber (reg:CC 17))]
12328 "TARGET_QIMODE_MATH"
12329 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12330
12331 (define_insn "*rotlqi3_1_one_bit_slp"
12332 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12333 (rotate:QI (match_dup 0)
12334 (match_operand:QI 1 "const1_operand" "")))
12335 (clobber (reg:CC 17))]
12336 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12337 && (TARGET_SHIFT1 || optimize_size)"
12338 "rol{b}\t%0"
12339 [(set_attr "type" "rotate1")
12340 (set (attr "length")
12341 (if_then_else (match_operand 0 "register_operand" "")
12342 (const_string "2")
12343 (const_string "*")))])
12344
12345 (define_insn "*rotlqi3_1_one_bit"
12346 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12347 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12348 (match_operand:QI 2 "const1_operand" "")))
12349 (clobber (reg:CC 17))]
12350 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12351 && (TARGET_SHIFT1 || optimize_size)"
12352 "rol{b}\t%0"
12353 [(set_attr "type" "rotate")
12354 (set (attr "length")
12355 (if_then_else (match_operand 0 "register_operand" "")
12356 (const_string "2")
12357 (const_string "*")))])
12358
12359 (define_insn "*rotlqi3_1_slp"
12360 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12361 (rotate:QI (match_dup 0)
12362 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12363 (clobber (reg:CC 17))]
12364 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12365 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12366 "@
12367 rol{b}\t{%1, %0|%0, %1}
12368 rol{b}\t{%b1, %0|%0, %b1}"
12369 [(set_attr "type" "rotate1")
12370 (set_attr "mode" "QI")])
12371
12372 (define_insn "*rotlqi3_1"
12373 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12374 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12375 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12376 (clobber (reg:CC 17))]
12377 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12378 "@
12379 rol{b}\t{%2, %0|%0, %2}
12380 rol{b}\t{%b2, %0|%0, %b2}"
12381 [(set_attr "type" "rotate")
12382 (set_attr "mode" "QI")])
12383
12384 (define_expand "rotrdi3"
12385 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12386 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12387 (match_operand:QI 2 "nonmemory_operand" "")))
12388 (clobber (reg:CC 17))]
12389 "TARGET_64BIT"
12390 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12391
12392 (define_insn "*rotrdi3_1_one_bit_rex64"
12393 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12394 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12395 (match_operand:QI 2 "const1_operand" "")))
12396 (clobber (reg:CC 17))]
12397 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12398 && (TARGET_SHIFT1 || optimize_size)"
12399 "ror{q}\t%0"
12400 [(set_attr "type" "rotate")
12401 (set (attr "length")
12402 (if_then_else (match_operand:DI 0 "register_operand" "")
12403 (const_string "2")
12404 (const_string "*")))])
12405
12406 (define_insn "*rotrdi3_1_rex64"
12407 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12408 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12409 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12410 (clobber (reg:CC 17))]
12411 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12412 "@
12413 ror{q}\t{%2, %0|%0, %2}
12414 ror{q}\t{%b2, %0|%0, %b2}"
12415 [(set_attr "type" "rotate")
12416 (set_attr "mode" "DI")])
12417
12418 (define_expand "rotrsi3"
12419 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12420 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12421 (match_operand:QI 2 "nonmemory_operand" "")))
12422 (clobber (reg:CC 17))]
12423 ""
12424 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12425
12426 (define_insn "*rotrsi3_1_one_bit"
12427 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12428 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12429 (match_operand:QI 2 "const1_operand" "")))
12430 (clobber (reg:CC 17))]
12431 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12432 && (TARGET_SHIFT1 || optimize_size)"
12433 "ror{l}\t%0"
12434 [(set_attr "type" "rotate")
12435 (set (attr "length")
12436 (if_then_else (match_operand:SI 0 "register_operand" "")
12437 (const_string "2")
12438 (const_string "*")))])
12439
12440 (define_insn "*rotrsi3_1_one_bit_zext"
12441 [(set (match_operand:DI 0 "register_operand" "=r")
12442 (zero_extend:DI
12443 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12444 (match_operand:QI 2 "const1_operand" ""))))
12445 (clobber (reg:CC 17))]
12446 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12447 && (TARGET_SHIFT1 || optimize_size)"
12448 "ror{l}\t%k0"
12449 [(set_attr "type" "rotate")
12450 (set (attr "length")
12451 (if_then_else (match_operand:SI 0 "register_operand" "")
12452 (const_string "2")
12453 (const_string "*")))])
12454
12455 (define_insn "*rotrsi3_1"
12456 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12457 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12458 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12459 (clobber (reg:CC 17))]
12460 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12461 "@
12462 ror{l}\t{%2, %0|%0, %2}
12463 ror{l}\t{%b2, %0|%0, %b2}"
12464 [(set_attr "type" "rotate")
12465 (set_attr "mode" "SI")])
12466
12467 (define_insn "*rotrsi3_1_zext"
12468 [(set (match_operand:DI 0 "register_operand" "=r,r")
12469 (zero_extend:DI
12470 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12471 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12472 (clobber (reg:CC 17))]
12473 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12474 "@
12475 ror{l}\t{%2, %k0|%k0, %2}
12476 ror{l}\t{%b2, %k0|%k0, %b2}"
12477 [(set_attr "type" "rotate")
12478 (set_attr "mode" "SI")])
12479
12480 (define_expand "rotrhi3"
12481 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12482 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12483 (match_operand:QI 2 "nonmemory_operand" "")))
12484 (clobber (reg:CC 17))]
12485 "TARGET_HIMODE_MATH"
12486 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12487
12488 (define_insn "*rotrhi3_one_bit"
12489 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12490 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12491 (match_operand:QI 2 "const1_operand" "")))
12492 (clobber (reg:CC 17))]
12493 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12494 && (TARGET_SHIFT1 || optimize_size)"
12495 "ror{w}\t%0"
12496 [(set_attr "type" "rotate")
12497 (set (attr "length")
12498 (if_then_else (match_operand 0 "register_operand" "")
12499 (const_string "2")
12500 (const_string "*")))])
12501
12502 (define_insn "*rotrhi3"
12503 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12504 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12505 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12506 (clobber (reg:CC 17))]
12507 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12508 "@
12509 ror{w}\t{%2, %0|%0, %2}
12510 ror{w}\t{%b2, %0|%0, %b2}"
12511 [(set_attr "type" "rotate")
12512 (set_attr "mode" "HI")])
12513
12514 (define_expand "rotrqi3"
12515 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12516 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12517 (match_operand:QI 2 "nonmemory_operand" "")))
12518 (clobber (reg:CC 17))]
12519 "TARGET_QIMODE_MATH"
12520 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12521
12522 (define_insn "*rotrqi3_1_one_bit"
12523 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12524 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12525 (match_operand:QI 2 "const1_operand" "")))
12526 (clobber (reg:CC 17))]
12527 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12528 && (TARGET_SHIFT1 || optimize_size)"
12529 "ror{b}\t%0"
12530 [(set_attr "type" "rotate")
12531 (set (attr "length")
12532 (if_then_else (match_operand 0 "register_operand" "")
12533 (const_string "2")
12534 (const_string "*")))])
12535
12536 (define_insn "*rotrqi3_1_one_bit_slp"
12537 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12538 (rotatert:QI (match_dup 0)
12539 (match_operand:QI 1 "const1_operand" "")))
12540 (clobber (reg:CC 17))]
12541 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12542 && (TARGET_SHIFT1 || optimize_size)"
12543 "ror{b}\t%0"
12544 [(set_attr "type" "rotate1")
12545 (set (attr "length")
12546 (if_then_else (match_operand 0 "register_operand" "")
12547 (const_string "2")
12548 (const_string "*")))])
12549
12550 (define_insn "*rotrqi3_1"
12551 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12552 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12553 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12554 (clobber (reg:CC 17))]
12555 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12556 "@
12557 ror{b}\t{%2, %0|%0, %2}
12558 ror{b}\t{%b2, %0|%0, %b2}"
12559 [(set_attr "type" "rotate")
12560 (set_attr "mode" "QI")])
12561
12562 (define_insn "*rotrqi3_1_slp"
12563 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12564 (rotatert:QI (match_dup 0)
12565 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12566 (clobber (reg:CC 17))]
12567 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12568 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12569 "@
12570 ror{b}\t{%1, %0|%0, %1}
12571 ror{b}\t{%b1, %0|%0, %b1}"
12572 [(set_attr "type" "rotate1")
12573 (set_attr "mode" "QI")])
12574 \f
12575 ;; Bit set / bit test instructions
12576
12577 (define_expand "extv"
12578 [(set (match_operand:SI 0 "register_operand" "")
12579 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12580 (match_operand:SI 2 "immediate_operand" "")
12581 (match_operand:SI 3 "immediate_operand" "")))]
12582 ""
12583 {
12584 /* Handle extractions from %ah et al. */
12585 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12586 FAIL;
12587
12588 /* From mips.md: extract_bit_field doesn't verify that our source
12589 matches the predicate, so check it again here. */
12590 if (! register_operand (operands[1], VOIDmode))
12591 FAIL;
12592 })
12593
12594 (define_expand "extzv"
12595 [(set (match_operand:SI 0 "register_operand" "")
12596 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12597 (match_operand:SI 2 "immediate_operand" "")
12598 (match_operand:SI 3 "immediate_operand" "")))]
12599 ""
12600 {
12601 /* Handle extractions from %ah et al. */
12602 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12603 FAIL;
12604
12605 /* From mips.md: extract_bit_field doesn't verify that our source
12606 matches the predicate, so check it again here. */
12607 if (! register_operand (operands[1], VOIDmode))
12608 FAIL;
12609 })
12610
12611 (define_expand "insv"
12612 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12613 (match_operand:SI 1 "immediate_operand" "")
12614 (match_operand:SI 2 "immediate_operand" ""))
12615 (match_operand:SI 3 "register_operand" ""))]
12616 ""
12617 {
12618 /* Handle extractions from %ah et al. */
12619 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12620 FAIL;
12621
12622 /* From mips.md: insert_bit_field doesn't verify that our source
12623 matches the predicate, so check it again here. */
12624 if (! register_operand (operands[0], VOIDmode))
12625 FAIL;
12626 })
12627
12628 ;; %%% bts, btr, btc, bt.
12629 \f
12630 ;; Store-flag instructions.
12631
12632 ;; For all sCOND expanders, also expand the compare or test insn that
12633 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12634
12635 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12636 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12637 ;; way, which can later delete the movzx if only QImode is needed.
12638
12639 (define_expand "seq"
12640 [(set (match_operand:QI 0 "register_operand" "")
12641 (eq:QI (reg:CC 17) (const_int 0)))]
12642 ""
12643 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12644
12645 (define_expand "sne"
12646 [(set (match_operand:QI 0 "register_operand" "")
12647 (ne:QI (reg:CC 17) (const_int 0)))]
12648 ""
12649 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12650
12651 (define_expand "sgt"
12652 [(set (match_operand:QI 0 "register_operand" "")
12653 (gt:QI (reg:CC 17) (const_int 0)))]
12654 ""
12655 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12656
12657 (define_expand "sgtu"
12658 [(set (match_operand:QI 0 "register_operand" "")
12659 (gtu:QI (reg:CC 17) (const_int 0)))]
12660 ""
12661 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12662
12663 (define_expand "slt"
12664 [(set (match_operand:QI 0 "register_operand" "")
12665 (lt:QI (reg:CC 17) (const_int 0)))]
12666 ""
12667 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12668
12669 (define_expand "sltu"
12670 [(set (match_operand:QI 0 "register_operand" "")
12671 (ltu:QI (reg:CC 17) (const_int 0)))]
12672 ""
12673 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12674
12675 (define_expand "sge"
12676 [(set (match_operand:QI 0 "register_operand" "")
12677 (ge:QI (reg:CC 17) (const_int 0)))]
12678 ""
12679 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12680
12681 (define_expand "sgeu"
12682 [(set (match_operand:QI 0 "register_operand" "")
12683 (geu:QI (reg:CC 17) (const_int 0)))]
12684 ""
12685 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12686
12687 (define_expand "sle"
12688 [(set (match_operand:QI 0 "register_operand" "")
12689 (le:QI (reg:CC 17) (const_int 0)))]
12690 ""
12691 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12692
12693 (define_expand "sleu"
12694 [(set (match_operand:QI 0 "register_operand" "")
12695 (leu:QI (reg:CC 17) (const_int 0)))]
12696 ""
12697 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12698
12699 (define_expand "sunordered"
12700 [(set (match_operand:QI 0 "register_operand" "")
12701 (unordered:QI (reg:CC 17) (const_int 0)))]
12702 "TARGET_80387 || TARGET_SSE"
12703 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12704
12705 (define_expand "sordered"
12706 [(set (match_operand:QI 0 "register_operand" "")
12707 (ordered:QI (reg:CC 17) (const_int 0)))]
12708 "TARGET_80387"
12709 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12710
12711 (define_expand "suneq"
12712 [(set (match_operand:QI 0 "register_operand" "")
12713 (uneq:QI (reg:CC 17) (const_int 0)))]
12714 "TARGET_80387 || TARGET_SSE"
12715 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12716
12717 (define_expand "sunge"
12718 [(set (match_operand:QI 0 "register_operand" "")
12719 (unge:QI (reg:CC 17) (const_int 0)))]
12720 "TARGET_80387 || TARGET_SSE"
12721 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12722
12723 (define_expand "sungt"
12724 [(set (match_operand:QI 0 "register_operand" "")
12725 (ungt:QI (reg:CC 17) (const_int 0)))]
12726 "TARGET_80387 || TARGET_SSE"
12727 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12728
12729 (define_expand "sunle"
12730 [(set (match_operand:QI 0 "register_operand" "")
12731 (unle:QI (reg:CC 17) (const_int 0)))]
12732 "TARGET_80387 || TARGET_SSE"
12733 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12734
12735 (define_expand "sunlt"
12736 [(set (match_operand:QI 0 "register_operand" "")
12737 (unlt:QI (reg:CC 17) (const_int 0)))]
12738 "TARGET_80387 || TARGET_SSE"
12739 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12740
12741 (define_expand "sltgt"
12742 [(set (match_operand:QI 0 "register_operand" "")
12743 (ltgt:QI (reg:CC 17) (const_int 0)))]
12744 "TARGET_80387 || TARGET_SSE"
12745 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12746
12747 (define_insn "*setcc_1"
12748 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12749 (match_operator:QI 1 "ix86_comparison_operator"
12750 [(reg 17) (const_int 0)]))]
12751 ""
12752 "set%C1\t%0"
12753 [(set_attr "type" "setcc")
12754 (set_attr "mode" "QI")])
12755
12756 (define_insn "setcc_2"
12757 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12758 (match_operator:QI 1 "ix86_comparison_operator"
12759 [(reg 17) (const_int 0)]))]
12760 ""
12761 "set%C1\t%0"
12762 [(set_attr "type" "setcc")
12763 (set_attr "mode" "QI")])
12764
12765 ;; In general it is not safe to assume too much about CCmode registers,
12766 ;; so simplify-rtx stops when it sees a second one. Under certain
12767 ;; conditions this is safe on x86, so help combine not create
12768 ;;
12769 ;; seta %al
12770 ;; testb %al, %al
12771 ;; sete %al
12772
12773 (define_split
12774 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12775 (ne:QI (match_operator 1 "ix86_comparison_operator"
12776 [(reg 17) (const_int 0)])
12777 (const_int 0)))]
12778 ""
12779 [(set (match_dup 0) (match_dup 1))]
12780 {
12781 PUT_MODE (operands[1], QImode);
12782 })
12783
12784 (define_split
12785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12786 (ne:QI (match_operator 1 "ix86_comparison_operator"
12787 [(reg 17) (const_int 0)])
12788 (const_int 0)))]
12789 ""
12790 [(set (match_dup 0) (match_dup 1))]
12791 {
12792 PUT_MODE (operands[1], QImode);
12793 })
12794
12795 (define_split
12796 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12797 (eq:QI (match_operator 1 "ix86_comparison_operator"
12798 [(reg 17) (const_int 0)])
12799 (const_int 0)))]
12800 ""
12801 [(set (match_dup 0) (match_dup 1))]
12802 {
12803 rtx new_op1 = copy_rtx (operands[1]);
12804 operands[1] = new_op1;
12805 PUT_MODE (new_op1, QImode);
12806 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12807 GET_MODE (XEXP (new_op1, 0))));
12808
12809 /* Make sure that (a) the CCmode we have for the flags is strong
12810 enough for the reversed compare or (b) we have a valid FP compare. */
12811 if (! ix86_comparison_operator (new_op1, VOIDmode))
12812 FAIL;
12813 })
12814
12815 (define_split
12816 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12817 (eq:QI (match_operator 1 "ix86_comparison_operator"
12818 [(reg 17) (const_int 0)])
12819 (const_int 0)))]
12820 ""
12821 [(set (match_dup 0) (match_dup 1))]
12822 {
12823 rtx new_op1 = copy_rtx (operands[1]);
12824 operands[1] = new_op1;
12825 PUT_MODE (new_op1, QImode);
12826 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12827 GET_MODE (XEXP (new_op1, 0))));
12828
12829 /* Make sure that (a) the CCmode we have for the flags is strong
12830 enough for the reversed compare or (b) we have a valid FP compare. */
12831 if (! ix86_comparison_operator (new_op1, VOIDmode))
12832 FAIL;
12833 })
12834
12835 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12836 ;; subsequent logical operations are used to imitate conditional moves.
12837 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12838 ;; it directly. Further holding this value in pseudo register might bring
12839 ;; problem in implicit normalization in spill code.
12840 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12841 ;; instructions after reload by splitting the conditional move patterns.
12842
12843 (define_insn "*sse_setccsf"
12844 [(set (match_operand:SF 0 "register_operand" "=x")
12845 (match_operator:SF 1 "sse_comparison_operator"
12846 [(match_operand:SF 2 "register_operand" "0")
12847 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12848 "TARGET_SSE && reload_completed"
12849 "cmp%D1ss\t{%3, %0|%0, %3}"
12850 [(set_attr "type" "ssecmp")
12851 (set_attr "mode" "SF")])
12852
12853 (define_insn "*sse_setccdf"
12854 [(set (match_operand:DF 0 "register_operand" "=Y")
12855 (match_operator:DF 1 "sse_comparison_operator"
12856 [(match_operand:DF 2 "register_operand" "0")
12857 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12858 "TARGET_SSE2 && reload_completed"
12859 "cmp%D1sd\t{%3, %0|%0, %3}"
12860 [(set_attr "type" "ssecmp")
12861 (set_attr "mode" "DF")])
12862 \f
12863 ;; Basic conditional jump instructions.
12864 ;; We ignore the overflow flag for signed branch instructions.
12865
12866 ;; For all bCOND expanders, also expand the compare or test insn that
12867 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12868
12869 (define_expand "beq"
12870 [(set (pc)
12871 (if_then_else (match_dup 1)
12872 (label_ref (match_operand 0 "" ""))
12873 (pc)))]
12874 ""
12875 "ix86_expand_branch (EQ, operands[0]); DONE;")
12876
12877 (define_expand "bne"
12878 [(set (pc)
12879 (if_then_else (match_dup 1)
12880 (label_ref (match_operand 0 "" ""))
12881 (pc)))]
12882 ""
12883 "ix86_expand_branch (NE, operands[0]); DONE;")
12884
12885 (define_expand "bgt"
12886 [(set (pc)
12887 (if_then_else (match_dup 1)
12888 (label_ref (match_operand 0 "" ""))
12889 (pc)))]
12890 ""
12891 "ix86_expand_branch (GT, operands[0]); DONE;")
12892
12893 (define_expand "bgtu"
12894 [(set (pc)
12895 (if_then_else (match_dup 1)
12896 (label_ref (match_operand 0 "" ""))
12897 (pc)))]
12898 ""
12899 "ix86_expand_branch (GTU, operands[0]); DONE;")
12900
12901 (define_expand "blt"
12902 [(set (pc)
12903 (if_then_else (match_dup 1)
12904 (label_ref (match_operand 0 "" ""))
12905 (pc)))]
12906 ""
12907 "ix86_expand_branch (LT, operands[0]); DONE;")
12908
12909 (define_expand "bltu"
12910 [(set (pc)
12911 (if_then_else (match_dup 1)
12912 (label_ref (match_operand 0 "" ""))
12913 (pc)))]
12914 ""
12915 "ix86_expand_branch (LTU, operands[0]); DONE;")
12916
12917 (define_expand "bge"
12918 [(set (pc)
12919 (if_then_else (match_dup 1)
12920 (label_ref (match_operand 0 "" ""))
12921 (pc)))]
12922 ""
12923 "ix86_expand_branch (GE, operands[0]); DONE;")
12924
12925 (define_expand "bgeu"
12926 [(set (pc)
12927 (if_then_else (match_dup 1)
12928 (label_ref (match_operand 0 "" ""))
12929 (pc)))]
12930 ""
12931 "ix86_expand_branch (GEU, operands[0]); DONE;")
12932
12933 (define_expand "ble"
12934 [(set (pc)
12935 (if_then_else (match_dup 1)
12936 (label_ref (match_operand 0 "" ""))
12937 (pc)))]
12938 ""
12939 "ix86_expand_branch (LE, operands[0]); DONE;")
12940
12941 (define_expand "bleu"
12942 [(set (pc)
12943 (if_then_else (match_dup 1)
12944 (label_ref (match_operand 0 "" ""))
12945 (pc)))]
12946 ""
12947 "ix86_expand_branch (LEU, operands[0]); DONE;")
12948
12949 (define_expand "bunordered"
12950 [(set (pc)
12951 (if_then_else (match_dup 1)
12952 (label_ref (match_operand 0 "" ""))
12953 (pc)))]
12954 "TARGET_80387 || TARGET_SSE"
12955 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12956
12957 (define_expand "bordered"
12958 [(set (pc)
12959 (if_then_else (match_dup 1)
12960 (label_ref (match_operand 0 "" ""))
12961 (pc)))]
12962 "TARGET_80387 || TARGET_SSE"
12963 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12964
12965 (define_expand "buneq"
12966 [(set (pc)
12967 (if_then_else (match_dup 1)
12968 (label_ref (match_operand 0 "" ""))
12969 (pc)))]
12970 "TARGET_80387 || TARGET_SSE"
12971 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12972
12973 (define_expand "bunge"
12974 [(set (pc)
12975 (if_then_else (match_dup 1)
12976 (label_ref (match_operand 0 "" ""))
12977 (pc)))]
12978 "TARGET_80387 || TARGET_SSE"
12979 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12980
12981 (define_expand "bungt"
12982 [(set (pc)
12983 (if_then_else (match_dup 1)
12984 (label_ref (match_operand 0 "" ""))
12985 (pc)))]
12986 "TARGET_80387 || TARGET_SSE"
12987 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12988
12989 (define_expand "bunle"
12990 [(set (pc)
12991 (if_then_else (match_dup 1)
12992 (label_ref (match_operand 0 "" ""))
12993 (pc)))]
12994 "TARGET_80387 || TARGET_SSE"
12995 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12996
12997 (define_expand "bunlt"
12998 [(set (pc)
12999 (if_then_else (match_dup 1)
13000 (label_ref (match_operand 0 "" ""))
13001 (pc)))]
13002 "TARGET_80387 || TARGET_SSE"
13003 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13004
13005 (define_expand "bltgt"
13006 [(set (pc)
13007 (if_then_else (match_dup 1)
13008 (label_ref (match_operand 0 "" ""))
13009 (pc)))]
13010 "TARGET_80387 || TARGET_SSE"
13011 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13012
13013 (define_insn "*jcc_1"
13014 [(set (pc)
13015 (if_then_else (match_operator 1 "ix86_comparison_operator"
13016 [(reg 17) (const_int 0)])
13017 (label_ref (match_operand 0 "" ""))
13018 (pc)))]
13019 ""
13020 "%+j%C1\t%l0"
13021 [(set_attr "type" "ibr")
13022 (set_attr "modrm" "0")
13023 (set (attr "length")
13024 (if_then_else (and (ge (minus (match_dup 0) (pc))
13025 (const_int -126))
13026 (lt (minus (match_dup 0) (pc))
13027 (const_int 128)))
13028 (const_int 2)
13029 (const_int 6)))])
13030
13031 (define_insn "*jcc_2"
13032 [(set (pc)
13033 (if_then_else (match_operator 1 "ix86_comparison_operator"
13034 [(reg 17) (const_int 0)])
13035 (pc)
13036 (label_ref (match_operand 0 "" ""))))]
13037 ""
13038 "%+j%c1\t%l0"
13039 [(set_attr "type" "ibr")
13040 (set_attr "modrm" "0")
13041 (set (attr "length")
13042 (if_then_else (and (ge (minus (match_dup 0) (pc))
13043 (const_int -126))
13044 (lt (minus (match_dup 0) (pc))
13045 (const_int 128)))
13046 (const_int 2)
13047 (const_int 6)))])
13048
13049 ;; In general it is not safe to assume too much about CCmode registers,
13050 ;; so simplify-rtx stops when it sees a second one. Under certain
13051 ;; conditions this is safe on x86, so help combine not create
13052 ;;
13053 ;; seta %al
13054 ;; testb %al, %al
13055 ;; je Lfoo
13056
13057 (define_split
13058 [(set (pc)
13059 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13060 [(reg 17) (const_int 0)])
13061 (const_int 0))
13062 (label_ref (match_operand 1 "" ""))
13063 (pc)))]
13064 ""
13065 [(set (pc)
13066 (if_then_else (match_dup 0)
13067 (label_ref (match_dup 1))
13068 (pc)))]
13069 {
13070 PUT_MODE (operands[0], VOIDmode);
13071 })
13072
13073 (define_split
13074 [(set (pc)
13075 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13076 [(reg 17) (const_int 0)])
13077 (const_int 0))
13078 (label_ref (match_operand 1 "" ""))
13079 (pc)))]
13080 ""
13081 [(set (pc)
13082 (if_then_else (match_dup 0)
13083 (label_ref (match_dup 1))
13084 (pc)))]
13085 {
13086 rtx new_op0 = copy_rtx (operands[0]);
13087 operands[0] = new_op0;
13088 PUT_MODE (new_op0, VOIDmode);
13089 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13090 GET_MODE (XEXP (new_op0, 0))));
13091
13092 /* Make sure that (a) the CCmode we have for the flags is strong
13093 enough for the reversed compare or (b) we have a valid FP compare. */
13094 if (! ix86_comparison_operator (new_op0, VOIDmode))
13095 FAIL;
13096 })
13097
13098 ;; Define combination compare-and-branch fp compare instructions to use
13099 ;; during early optimization. Splitting the operation apart early makes
13100 ;; for bad code when we want to reverse the operation.
13101
13102 (define_insn "*fp_jcc_1"
13103 [(set (pc)
13104 (if_then_else (match_operator 0 "comparison_operator"
13105 [(match_operand 1 "register_operand" "f")
13106 (match_operand 2 "register_operand" "f")])
13107 (label_ref (match_operand 3 "" ""))
13108 (pc)))
13109 (clobber (reg:CCFP 18))
13110 (clobber (reg:CCFP 17))]
13111 "TARGET_CMOVE && TARGET_80387
13112 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13113 && FLOAT_MODE_P (GET_MODE (operands[1]))
13114 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13115 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13116 "#")
13117
13118 (define_insn "*fp_jcc_1_sse"
13119 [(set (pc)
13120 (if_then_else (match_operator 0 "comparison_operator"
13121 [(match_operand 1 "register_operand" "f#x,x#f")
13122 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13123 (label_ref (match_operand 3 "" ""))
13124 (pc)))
13125 (clobber (reg:CCFP 18))
13126 (clobber (reg:CCFP 17))]
13127 "TARGET_80387
13128 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13129 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13130 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13131 "#")
13132
13133 (define_insn "*fp_jcc_1_sse_only"
13134 [(set (pc)
13135 (if_then_else (match_operator 0 "comparison_operator"
13136 [(match_operand 1 "register_operand" "x")
13137 (match_operand 2 "nonimmediate_operand" "xm")])
13138 (label_ref (match_operand 3 "" ""))
13139 (pc)))
13140 (clobber (reg:CCFP 18))
13141 (clobber (reg:CCFP 17))]
13142 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13143 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13144 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13145 "#")
13146
13147 (define_insn "*fp_jcc_2"
13148 [(set (pc)
13149 (if_then_else (match_operator 0 "comparison_operator"
13150 [(match_operand 1 "register_operand" "f")
13151 (match_operand 2 "register_operand" "f")])
13152 (pc)
13153 (label_ref (match_operand 3 "" ""))))
13154 (clobber (reg:CCFP 18))
13155 (clobber (reg:CCFP 17))]
13156 "TARGET_CMOVE && TARGET_80387
13157 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13158 && FLOAT_MODE_P (GET_MODE (operands[1]))
13159 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13160 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13161 "#")
13162
13163 (define_insn "*fp_jcc_2_sse"
13164 [(set (pc)
13165 (if_then_else (match_operator 0 "comparison_operator"
13166 [(match_operand 1 "register_operand" "f#x,x#f")
13167 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13168 (pc)
13169 (label_ref (match_operand 3 "" ""))))
13170 (clobber (reg:CCFP 18))
13171 (clobber (reg:CCFP 17))]
13172 "TARGET_80387
13173 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13174 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13175 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13176 "#")
13177
13178 (define_insn "*fp_jcc_2_sse_only"
13179 [(set (pc)
13180 (if_then_else (match_operator 0 "comparison_operator"
13181 [(match_operand 1 "register_operand" "x")
13182 (match_operand 2 "nonimmediate_operand" "xm")])
13183 (pc)
13184 (label_ref (match_operand 3 "" ""))))
13185 (clobber (reg:CCFP 18))
13186 (clobber (reg:CCFP 17))]
13187 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13188 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13189 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13190 "#")
13191
13192 (define_insn "*fp_jcc_3"
13193 [(set (pc)
13194 (if_then_else (match_operator 0 "comparison_operator"
13195 [(match_operand 1 "register_operand" "f")
13196 (match_operand 2 "nonimmediate_operand" "fm")])
13197 (label_ref (match_operand 3 "" ""))
13198 (pc)))
13199 (clobber (reg:CCFP 18))
13200 (clobber (reg:CCFP 17))
13201 (clobber (match_scratch:HI 4 "=a"))]
13202 "TARGET_80387
13203 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13204 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13205 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13206 && SELECT_CC_MODE (GET_CODE (operands[0]),
13207 operands[1], operands[2]) == CCFPmode
13208 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13209 "#")
13210
13211 (define_insn "*fp_jcc_4"
13212 [(set (pc)
13213 (if_then_else (match_operator 0 "comparison_operator"
13214 [(match_operand 1 "register_operand" "f")
13215 (match_operand 2 "nonimmediate_operand" "fm")])
13216 (pc)
13217 (label_ref (match_operand 3 "" ""))))
13218 (clobber (reg:CCFP 18))
13219 (clobber (reg:CCFP 17))
13220 (clobber (match_scratch:HI 4 "=a"))]
13221 "TARGET_80387
13222 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13223 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13224 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13225 && SELECT_CC_MODE (GET_CODE (operands[0]),
13226 operands[1], operands[2]) == CCFPmode
13227 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13228 "#")
13229
13230 (define_insn "*fp_jcc_5"
13231 [(set (pc)
13232 (if_then_else (match_operator 0 "comparison_operator"
13233 [(match_operand 1 "register_operand" "f")
13234 (match_operand 2 "register_operand" "f")])
13235 (label_ref (match_operand 3 "" ""))
13236 (pc)))
13237 (clobber (reg:CCFP 18))
13238 (clobber (reg:CCFP 17))
13239 (clobber (match_scratch:HI 4 "=a"))]
13240 "TARGET_80387
13241 && FLOAT_MODE_P (GET_MODE (operands[1]))
13242 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13243 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13244 "#")
13245
13246 (define_insn "*fp_jcc_6"
13247 [(set (pc)
13248 (if_then_else (match_operator 0 "comparison_operator"
13249 [(match_operand 1 "register_operand" "f")
13250 (match_operand 2 "register_operand" "f")])
13251 (pc)
13252 (label_ref (match_operand 3 "" ""))))
13253 (clobber (reg:CCFP 18))
13254 (clobber (reg:CCFP 17))
13255 (clobber (match_scratch:HI 4 "=a"))]
13256 "TARGET_80387
13257 && FLOAT_MODE_P (GET_MODE (operands[1]))
13258 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13259 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13260 "#")
13261
13262 (define_split
13263 [(set (pc)
13264 (if_then_else (match_operator 0 "comparison_operator"
13265 [(match_operand 1 "register_operand" "")
13266 (match_operand 2 "nonimmediate_operand" "")])
13267 (match_operand 3 "" "")
13268 (match_operand 4 "" "")))
13269 (clobber (reg:CCFP 18))
13270 (clobber (reg:CCFP 17))]
13271 "reload_completed"
13272 [(const_int 0)]
13273 {
13274 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13275 operands[3], operands[4], NULL_RTX);
13276 DONE;
13277 })
13278
13279 (define_split
13280 [(set (pc)
13281 (if_then_else (match_operator 0 "comparison_operator"
13282 [(match_operand 1 "register_operand" "")
13283 (match_operand 2 "nonimmediate_operand" "")])
13284 (match_operand 3 "" "")
13285 (match_operand 4 "" "")))
13286 (clobber (reg:CCFP 18))
13287 (clobber (reg:CCFP 17))
13288 (clobber (match_scratch:HI 5 "=a"))]
13289 "reload_completed"
13290 [(set (pc)
13291 (if_then_else (match_dup 6)
13292 (match_dup 3)
13293 (match_dup 4)))]
13294 {
13295 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13296 operands[3], operands[4], operands[5]);
13297 DONE;
13298 })
13299 \f
13300 ;; Unconditional and other jump instructions
13301
13302 (define_insn "jump"
13303 [(set (pc)
13304 (label_ref (match_operand 0 "" "")))]
13305 ""
13306 "jmp\t%l0"
13307 [(set_attr "type" "ibr")
13308 (set (attr "length")
13309 (if_then_else (and (ge (minus (match_dup 0) (pc))
13310 (const_int -126))
13311 (lt (minus (match_dup 0) (pc))
13312 (const_int 128)))
13313 (const_int 2)
13314 (const_int 5)))
13315 (set_attr "modrm" "0")])
13316
13317 (define_expand "indirect_jump"
13318 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13319 ""
13320 "")
13321
13322 (define_insn "*indirect_jump"
13323 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13324 "!TARGET_64BIT"
13325 "jmp\t%A0"
13326 [(set_attr "type" "ibr")
13327 (set_attr "length_immediate" "0")])
13328
13329 (define_insn "*indirect_jump_rtx64"
13330 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13331 "TARGET_64BIT"
13332 "jmp\t%A0"
13333 [(set_attr "type" "ibr")
13334 (set_attr "length_immediate" "0")])
13335
13336 (define_expand "tablejump"
13337 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13338 (use (label_ref (match_operand 1 "" "")))])]
13339 ""
13340 {
13341 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13342 relative. Convert the relative address to an absolute address. */
13343 if (flag_pic)
13344 {
13345 rtx op0, op1;
13346 enum rtx_code code;
13347
13348 if (TARGET_64BIT)
13349 {
13350 code = PLUS;
13351 op0 = operands[0];
13352 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13353 }
13354 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13355 {
13356 code = PLUS;
13357 op0 = operands[0];
13358 op1 = pic_offset_table_rtx;
13359 }
13360 else
13361 {
13362 code = MINUS;
13363 op0 = pic_offset_table_rtx;
13364 op1 = operands[0];
13365 }
13366
13367 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13368 OPTAB_DIRECT);
13369 }
13370 })
13371
13372 (define_insn "*tablejump_1"
13373 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13374 (use (label_ref (match_operand 1 "" "")))]
13375 "!TARGET_64BIT"
13376 "jmp\t%A0"
13377 [(set_attr "type" "ibr")
13378 (set_attr "length_immediate" "0")])
13379
13380 (define_insn "*tablejump_1_rtx64"
13381 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13382 (use (label_ref (match_operand 1 "" "")))]
13383 "TARGET_64BIT"
13384 "jmp\t%A0"
13385 [(set_attr "type" "ibr")
13386 (set_attr "length_immediate" "0")])
13387 \f
13388 ;; Loop instruction
13389 ;;
13390 ;; This is all complicated by the fact that since this is a jump insn
13391 ;; we must handle our own reloads.
13392
13393 (define_expand "doloop_end"
13394 [(use (match_operand 0 "" "")) ; loop pseudo
13395 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13396 (use (match_operand 2 "" "")) ; max iterations
13397 (use (match_operand 3 "" "")) ; loop level
13398 (use (match_operand 4 "" ""))] ; label
13399 "!TARGET_64BIT && TARGET_USE_LOOP"
13400 "
13401 {
13402 /* Only use cloop on innermost loops. */
13403 if (INTVAL (operands[3]) > 1)
13404 FAIL;
13405 if (GET_MODE (operands[0]) != SImode)
13406 FAIL;
13407 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13408 operands[0]));
13409 DONE;
13410 }")
13411
13412 (define_insn "doloop_end_internal"
13413 [(set (pc)
13414 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13415 (const_int 1))
13416 (label_ref (match_operand 0 "" ""))
13417 (pc)))
13418 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13419 (plus:SI (match_dup 1)
13420 (const_int -1)))
13421 (clobber (match_scratch:SI 3 "=X,X,r"))
13422 (clobber (reg:CC 17))]
13423 "!TARGET_64BIT && TARGET_USE_LOOP
13424 && (reload_in_progress || reload_completed
13425 || register_operand (operands[2], VOIDmode))"
13426 {
13427 if (which_alternative != 0)
13428 return "#";
13429 if (get_attr_length (insn) == 2)
13430 return "%+loop\t%l0";
13431 else
13432 return "dec{l}\t%1\;%+jne\t%l0";
13433 }
13434 [(set (attr "length")
13435 (if_then_else (and (eq_attr "alternative" "0")
13436 (and (ge (minus (match_dup 0) (pc))
13437 (const_int -126))
13438 (lt (minus (match_dup 0) (pc))
13439 (const_int 128))))
13440 (const_int 2)
13441 (const_int 16)))
13442 ;; We don't know the type before shorten branches. Optimistically expect
13443 ;; the loop instruction to match.
13444 (set (attr "type") (const_string "ibr"))])
13445
13446 (define_split
13447 [(set (pc)
13448 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13449 (const_int 1))
13450 (match_operand 0 "" "")
13451 (pc)))
13452 (set (match_dup 1)
13453 (plus:SI (match_dup 1)
13454 (const_int -1)))
13455 (clobber (match_scratch:SI 2 ""))
13456 (clobber (reg:CC 17))]
13457 "!TARGET_64BIT && TARGET_USE_LOOP
13458 && reload_completed
13459 && REGNO (operands[1]) != 2"
13460 [(parallel [(set (reg:CCZ 17)
13461 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13462 (const_int 0)))
13463 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13464 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13465 (match_dup 0)
13466 (pc)))]
13467 "")
13468
13469 (define_split
13470 [(set (pc)
13471 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13472 (const_int 1))
13473 (match_operand 0 "" "")
13474 (pc)))
13475 (set (match_operand:SI 2 "nonimmediate_operand" "")
13476 (plus:SI (match_dup 1)
13477 (const_int -1)))
13478 (clobber (match_scratch:SI 3 ""))
13479 (clobber (reg:CC 17))]
13480 "!TARGET_64BIT && TARGET_USE_LOOP
13481 && reload_completed
13482 && (! REG_P (operands[2])
13483 || ! rtx_equal_p (operands[1], operands[2]))"
13484 [(set (match_dup 3) (match_dup 1))
13485 (parallel [(set (reg:CCZ 17)
13486 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13487 (const_int 0)))
13488 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13489 (set (match_dup 2) (match_dup 3))
13490 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13491 (match_dup 0)
13492 (pc)))]
13493 "")
13494
13495 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13496
13497 (define_peephole2
13498 [(set (reg 17) (match_operand 0 "" ""))
13499 (set (match_operand:QI 1 "register_operand" "")
13500 (match_operator:QI 2 "ix86_comparison_operator"
13501 [(reg 17) (const_int 0)]))
13502 (set (match_operand 3 "q_regs_operand" "")
13503 (zero_extend (match_dup 1)))]
13504 "(peep2_reg_dead_p (3, operands[1])
13505 || operands_match_p (operands[1], operands[3]))
13506 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13507 [(set (match_dup 4) (match_dup 0))
13508 (set (strict_low_part (match_dup 5))
13509 (match_dup 2))]
13510 {
13511 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13512 operands[5] = gen_lowpart (QImode, operands[3]);
13513 ix86_expand_clear (operands[3]);
13514 })
13515
13516 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13517
13518 (define_peephole2
13519 [(set (reg 17) (match_operand 0 "" ""))
13520 (set (match_operand:QI 1 "register_operand" "")
13521 (match_operator:QI 2 "ix86_comparison_operator"
13522 [(reg 17) (const_int 0)]))
13523 (parallel [(set (match_operand 3 "q_regs_operand" "")
13524 (zero_extend (match_dup 1)))
13525 (clobber (reg:CC 17))])]
13526 "(peep2_reg_dead_p (3, operands[1])
13527 || operands_match_p (operands[1], operands[3]))
13528 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13529 [(set (match_dup 4) (match_dup 0))
13530 (set (strict_low_part (match_dup 5))
13531 (match_dup 2))]
13532 {
13533 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13534 operands[5] = gen_lowpart (QImode, operands[3]);
13535 ix86_expand_clear (operands[3]);
13536 })
13537 \f
13538 ;; Call instructions.
13539
13540 ;; The predicates normally associated with named expanders are not properly
13541 ;; checked for calls. This is a bug in the generic code, but it isn't that
13542 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13543
13544 ;; Call subroutine returning no value.
13545
13546 (define_expand "call_pop"
13547 [(parallel [(call (match_operand:QI 0 "" "")
13548 (match_operand:SI 1 "" ""))
13549 (set (reg:SI 7)
13550 (plus:SI (reg:SI 7)
13551 (match_operand:SI 3 "" "")))])]
13552 "!TARGET_64BIT"
13553 {
13554 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13555 DONE;
13556 })
13557
13558 (define_insn "*call_pop_0"
13559 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13560 (match_operand:SI 1 "" ""))
13561 (set (reg:SI 7) (plus:SI (reg:SI 7)
13562 (match_operand:SI 2 "immediate_operand" "")))]
13563 "!TARGET_64BIT"
13564 {
13565 if (SIBLING_CALL_P (insn))
13566 return "jmp\t%P0";
13567 else
13568 return "call\t%P0";
13569 }
13570 [(set_attr "type" "call")])
13571
13572 (define_insn "*call_pop_1"
13573 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13574 (match_operand:SI 1 "" ""))
13575 (set (reg:SI 7) (plus:SI (reg:SI 7)
13576 (match_operand:SI 2 "immediate_operand" "i")))]
13577 "!TARGET_64BIT"
13578 {
13579 if (constant_call_address_operand (operands[0], Pmode))
13580 {
13581 if (SIBLING_CALL_P (insn))
13582 return "jmp\t%P0";
13583 else
13584 return "call\t%P0";
13585 }
13586 if (SIBLING_CALL_P (insn))
13587 return "jmp\t%A0";
13588 else
13589 return "call\t%A0";
13590 }
13591 [(set_attr "type" "call")])
13592
13593 (define_expand "call"
13594 [(call (match_operand:QI 0 "" "")
13595 (match_operand 1 "" ""))
13596 (use (match_operand 2 "" ""))]
13597 ""
13598 {
13599 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13600 DONE;
13601 })
13602
13603 (define_expand "sibcall"
13604 [(call (match_operand:QI 0 "" "")
13605 (match_operand 1 "" ""))
13606 (use (match_operand 2 "" ""))]
13607 ""
13608 {
13609 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13610 DONE;
13611 })
13612
13613 (define_insn "*call_0"
13614 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13615 (match_operand 1 "" ""))]
13616 ""
13617 {
13618 if (SIBLING_CALL_P (insn))
13619 return "jmp\t%P0";
13620 else
13621 return "call\t%P0";
13622 }
13623 [(set_attr "type" "call")])
13624
13625 (define_insn "*call_1"
13626 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13627 (match_operand 1 "" ""))]
13628 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13629 {
13630 if (constant_call_address_operand (operands[0], QImode))
13631 return "call\t%P0";
13632 return "call\t%A0";
13633 }
13634 [(set_attr "type" "call")])
13635
13636 (define_insn "*sibcall_1"
13637 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13638 (match_operand 1 "" ""))]
13639 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13640 {
13641 if (constant_call_address_operand (operands[0], QImode))
13642 return "jmp\t%P0";
13643 return "jmp\t%A0";
13644 }
13645 [(set_attr "type" "call")])
13646
13647 (define_insn "*call_1_rex64"
13648 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13649 (match_operand 1 "" ""))]
13650 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13651 {
13652 if (constant_call_address_operand (operands[0], QImode))
13653 return "call\t%P0";
13654 return "call\t%A0";
13655 }
13656 [(set_attr "type" "call")])
13657
13658 (define_insn "*sibcall_1_rex64"
13659 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13660 (match_operand 1 "" ""))]
13661 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13662 "jmp\t%P0"
13663 [(set_attr "type" "call")])
13664
13665 (define_insn "*sibcall_1_rex64_v"
13666 [(call (mem:QI (reg:DI 40))
13667 (match_operand 0 "" ""))]
13668 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13669 "jmp\t*%%r11"
13670 [(set_attr "type" "call")])
13671
13672
13673 ;; Call subroutine, returning value in operand 0
13674
13675 (define_expand "call_value_pop"
13676 [(parallel [(set (match_operand 0 "" "")
13677 (call (match_operand:QI 1 "" "")
13678 (match_operand:SI 2 "" "")))
13679 (set (reg:SI 7)
13680 (plus:SI (reg:SI 7)
13681 (match_operand:SI 4 "" "")))])]
13682 "!TARGET_64BIT"
13683 {
13684 ix86_expand_call (operands[0], operands[1], operands[2],
13685 operands[3], operands[4], 0);
13686 DONE;
13687 })
13688
13689 (define_expand "call_value"
13690 [(set (match_operand 0 "" "")
13691 (call (match_operand:QI 1 "" "")
13692 (match_operand:SI 2 "" "")))
13693 (use (match_operand:SI 3 "" ""))]
13694 ;; Operand 2 not used on the i386.
13695 ""
13696 {
13697 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13698 DONE;
13699 })
13700
13701 (define_expand "sibcall_value"
13702 [(set (match_operand 0 "" "")
13703 (call (match_operand:QI 1 "" "")
13704 (match_operand:SI 2 "" "")))
13705 (use (match_operand:SI 3 "" ""))]
13706 ;; Operand 2 not used on the i386.
13707 ""
13708 {
13709 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13710 DONE;
13711 })
13712
13713 ;; Call subroutine returning any type.
13714
13715 (define_expand "untyped_call"
13716 [(parallel [(call (match_operand 0 "" "")
13717 (const_int 0))
13718 (match_operand 1 "" "")
13719 (match_operand 2 "" "")])]
13720 ""
13721 {
13722 int i;
13723
13724 /* In order to give reg-stack an easier job in validating two
13725 coprocessor registers as containing a possible return value,
13726 simply pretend the untyped call returns a complex long double
13727 value. */
13728
13729 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13730 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13731 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13732 NULL, 0);
13733
13734 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13735 {
13736 rtx set = XVECEXP (operands[2], 0, i);
13737 emit_move_insn (SET_DEST (set), SET_SRC (set));
13738 }
13739
13740 /* The optimizer does not know that the call sets the function value
13741 registers we stored in the result block. We avoid problems by
13742 claiming that all hard registers are used and clobbered at this
13743 point. */
13744 emit_insn (gen_blockage (const0_rtx));
13745
13746 DONE;
13747 })
13748 \f
13749 ;; Prologue and epilogue instructions
13750
13751 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13752 ;; all of memory. This blocks insns from being moved across this point.
13753
13754 (define_insn "blockage"
13755 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13756 ""
13757 ""
13758 [(set_attr "length" "0")])
13759
13760 ;; Insn emitted into the body of a function to return from a function.
13761 ;; This is only done if the function's epilogue is known to be simple.
13762 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13763
13764 (define_expand "return"
13765 [(return)]
13766 "ix86_can_use_return_insn_p ()"
13767 {
13768 if (current_function_pops_args)
13769 {
13770 rtx popc = GEN_INT (current_function_pops_args);
13771 emit_jump_insn (gen_return_pop_internal (popc));
13772 DONE;
13773 }
13774 })
13775
13776 (define_insn "return_internal"
13777 [(return)]
13778 "reload_completed"
13779 "ret"
13780 [(set_attr "length" "1")
13781 (set_attr "length_immediate" "0")
13782 (set_attr "modrm" "0")])
13783
13784 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13785 ;; instruction Athlon and K8 have.
13786
13787 (define_insn "return_internal_long"
13788 [(return)
13789 (unspec [(const_int 0)] UNSPEC_REP)]
13790 "reload_completed"
13791 "rep {;} ret"
13792 [(set_attr "length" "1")
13793 (set_attr "length_immediate" "0")
13794 (set_attr "prefix_rep" "1")
13795 (set_attr "modrm" "0")])
13796
13797 (define_insn "return_pop_internal"
13798 [(return)
13799 (use (match_operand:SI 0 "const_int_operand" ""))]
13800 "reload_completed"
13801 "ret\t%0"
13802 [(set_attr "length" "3")
13803 (set_attr "length_immediate" "2")
13804 (set_attr "modrm" "0")])
13805
13806 (define_insn "return_indirect_internal"
13807 [(return)
13808 (use (match_operand:SI 0 "register_operand" "r"))]
13809 "reload_completed"
13810 "jmp\t%A0"
13811 [(set_attr "type" "ibr")
13812 (set_attr "length_immediate" "0")])
13813
13814 (define_insn "nop"
13815 [(const_int 0)]
13816 ""
13817 "nop"
13818 [(set_attr "length" "1")
13819 (set_attr "length_immediate" "0")
13820 (set_attr "modrm" "0")])
13821
13822 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13823 ;; branch prediction penalty for the third jump in a 16-byte
13824 ;; block on K8.
13825
13826 (define_insn "align"
13827 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13828 ""
13829 {
13830 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13831 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13832 #else
13833 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13834 The align insn is used to avoid 3 jump instructions in the row to improve
13835 branch prediction and the benefits hardly outweight the cost of extra 8
13836 nops on the average inserted by full alignment pseudo operation. */
13837 #endif
13838 return "";
13839 }
13840 [(set_attr "length" "16")])
13841
13842 (define_expand "prologue"
13843 [(const_int 1)]
13844 ""
13845 "ix86_expand_prologue (); DONE;")
13846
13847 (define_insn "set_got"
13848 [(set (match_operand:SI 0 "register_operand" "=r")
13849 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13850 (clobber (reg:CC 17))]
13851 "!TARGET_64BIT"
13852 { return output_set_got (operands[0]); }
13853 [(set_attr "type" "multi")
13854 (set_attr "length" "12")])
13855
13856 (define_expand "epilogue"
13857 [(const_int 1)]
13858 ""
13859 "ix86_expand_epilogue (1); DONE;")
13860
13861 (define_expand "sibcall_epilogue"
13862 [(const_int 1)]
13863 ""
13864 "ix86_expand_epilogue (0); DONE;")
13865
13866 (define_expand "eh_return"
13867 [(use (match_operand 0 "register_operand" ""))]
13868 ""
13869 {
13870 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13871
13872 /* Tricky bit: we write the address of the handler to which we will
13873 be returning into someone else's stack frame, one word below the
13874 stack address we wish to restore. */
13875 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13876 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13877 tmp = gen_rtx_MEM (Pmode, tmp);
13878 emit_move_insn (tmp, ra);
13879
13880 if (Pmode == SImode)
13881 emit_insn (gen_eh_return_si (sa));
13882 else
13883 emit_insn (gen_eh_return_di (sa));
13884 emit_barrier ();
13885 DONE;
13886 })
13887
13888 (define_insn_and_split "eh_return_si"
13889 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13890 UNSPECV_EH_RETURN)]
13891 "!TARGET_64BIT"
13892 "#"
13893 "reload_completed"
13894 [(const_int 1)]
13895 "ix86_expand_epilogue (2); DONE;")
13896
13897 (define_insn_and_split "eh_return_di"
13898 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13899 UNSPECV_EH_RETURN)]
13900 "TARGET_64BIT"
13901 "#"
13902 "reload_completed"
13903 [(const_int 1)]
13904 "ix86_expand_epilogue (2); DONE;")
13905
13906 (define_insn "leave"
13907 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13908 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13909 (clobber (mem:BLK (scratch)))]
13910 "!TARGET_64BIT"
13911 "leave"
13912 [(set_attr "type" "leave")])
13913
13914 (define_insn "leave_rex64"
13915 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13916 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13917 (clobber (mem:BLK (scratch)))]
13918 "TARGET_64BIT"
13919 "leave"
13920 [(set_attr "type" "leave")])
13921 \f
13922 (define_expand "ffssi2"
13923 [(parallel
13924 [(set (match_operand:SI 0 "register_operand" "")
13925 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13926 (clobber (match_scratch:SI 2 ""))
13927 (clobber (reg:CC 17))])]
13928 ""
13929 "")
13930
13931 (define_insn_and_split "*ffs_cmove"
13932 [(set (match_operand:SI 0 "register_operand" "=r")
13933 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13934 (clobber (match_scratch:SI 2 "=&r"))
13935 (clobber (reg:CC 17))]
13936 "TARGET_CMOVE"
13937 "#"
13938 "&& reload_completed"
13939 [(set (match_dup 2) (const_int -1))
13940 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13941 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13942 (set (match_dup 0) (if_then_else:SI
13943 (eq (reg:CCZ 17) (const_int 0))
13944 (match_dup 2)
13945 (match_dup 0)))
13946 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13947 (clobber (reg:CC 17))])]
13948 "")
13949
13950 (define_insn_and_split "*ffs_no_cmove"
13951 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13952 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13953 (clobber (match_scratch:SI 2 "=&q"))
13954 (clobber (reg:CC 17))]
13955 ""
13956 "#"
13957 "reload_completed"
13958 [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13959 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13960 (set (strict_low_part (match_dup 3))
13961 (eq:QI (reg:CCZ 17) (const_int 0)))
13962 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13963 (clobber (reg:CC 17))])
13964 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13965 (clobber (reg:CC 17))])
13966 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13967 (clobber (reg:CC 17))])]
13968 {
13969 operands[3] = gen_lowpart (QImode, operands[2]);
13970 ix86_expand_clear (operands[2]);
13971 })
13972
13973 (define_insn "*ffssi_1"
13974 [(set (reg:CCZ 17)
13975 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13976 (const_int 0)))
13977 (set (match_operand:SI 0 "register_operand" "=r")
13978 (ctz:SI (match_dup 1)))]
13979 ""
13980 "bsf{l}\t{%1, %0|%0, %1}"
13981 [(set_attr "prefix_0f" "1")])
13982
13983 (define_insn "ctzsi2"
13984 [(set (match_operand:SI 0 "register_operand" "=r")
13985 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13986 (clobber (reg:CC 17))]
13987 ""
13988 "bsf{l}\t{%1, %0|%0, %1}"
13989 [(set_attr "prefix_0f" "1")])
13990
13991 (define_expand "clzsi2"
13992 [(parallel
13993 [(set (match_operand:SI 0 "register_operand" "")
13994 (minus:SI (const_int 31)
13995 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13996 (clobber (reg:CC 17))])
13997 (parallel
13998 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13999 (clobber (reg:CC 17))])]
14000 ""
14001 "")
14002
14003 (define_insn "*bsr"
14004 [(set (match_operand:SI 0 "register_operand" "=r")
14005 (minus:SI (const_int 31)
14006 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14007 (clobber (reg:CC 17))]
14008 ""
14009 "bsr{l}\t{%1, %0|%0, %1}"
14010 [(set_attr "prefix_0f" "1")])
14011 \f
14012 ;; Thread-local storage patterns for ELF.
14013 ;;
14014 ;; Note that these code sequences must appear exactly as shown
14015 ;; in order to allow linker relaxation.
14016
14017 (define_insn "*tls_global_dynamic_32_gnu"
14018 [(set (match_operand:SI 0 "register_operand" "=a")
14019 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14020 (match_operand:SI 2 "tls_symbolic_operand" "")
14021 (match_operand:SI 3 "call_insn_operand" "")]
14022 UNSPEC_TLS_GD))
14023 (clobber (match_scratch:SI 4 "=d"))
14024 (clobber (match_scratch:SI 5 "=c"))
14025 (clobber (reg:CC 17))]
14026 "!TARGET_64BIT && TARGET_GNU_TLS"
14027 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14028 [(set_attr "type" "multi")
14029 (set_attr "length" "12")])
14030
14031 (define_insn "*tls_global_dynamic_32_sun"
14032 [(set (match_operand:SI 0 "register_operand" "=a")
14033 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14034 (match_operand:SI 2 "tls_symbolic_operand" "")
14035 (match_operand:SI 3 "call_insn_operand" "")]
14036 UNSPEC_TLS_GD))
14037 (clobber (match_scratch:SI 4 "=d"))
14038 (clobber (match_scratch:SI 5 "=c"))
14039 (clobber (reg:CC 17))]
14040 "!TARGET_64BIT && TARGET_SUN_TLS"
14041 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14042 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14043 [(set_attr "type" "multi")
14044 (set_attr "length" "14")])
14045
14046 (define_expand "tls_global_dynamic_32"
14047 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14048 (unspec:SI
14049 [(match_dup 2)
14050 (match_operand:SI 1 "tls_symbolic_operand" "")
14051 (match_dup 3)]
14052 UNSPEC_TLS_GD))
14053 (clobber (match_scratch:SI 4 ""))
14054 (clobber (match_scratch:SI 5 ""))
14055 (clobber (reg:CC 17))])]
14056 ""
14057 {
14058 if (flag_pic)
14059 operands[2] = pic_offset_table_rtx;
14060 else
14061 {
14062 operands[2] = gen_reg_rtx (Pmode);
14063 emit_insn (gen_set_got (operands[2]));
14064 }
14065 operands[3] = ix86_tls_get_addr ();
14066 })
14067
14068 (define_insn "*tls_global_dynamic_64"
14069 [(set (match_operand:DI 0 "register_operand" "=a")
14070 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14071 (match_operand:DI 3 "" "")))
14072 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14073 UNSPEC_TLS_GD)]
14074 "TARGET_64BIT"
14075 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14076 [(set_attr "type" "multi")
14077 (set_attr "length" "16")])
14078
14079 (define_expand "tls_global_dynamic_64"
14080 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14081 (call (mem:QI (match_dup 2)) (const_int 0)))
14082 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14083 UNSPEC_TLS_GD)])]
14084 ""
14085 {
14086 operands[2] = ix86_tls_get_addr ();
14087 })
14088
14089 (define_insn "*tls_local_dynamic_base_32_gnu"
14090 [(set (match_operand:SI 0 "register_operand" "=a")
14091 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14092 (match_operand:SI 2 "call_insn_operand" "")]
14093 UNSPEC_TLS_LD_BASE))
14094 (clobber (match_scratch:SI 3 "=d"))
14095 (clobber (match_scratch:SI 4 "=c"))
14096 (clobber (reg:CC 17))]
14097 "!TARGET_64BIT && TARGET_GNU_TLS"
14098 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14099 [(set_attr "type" "multi")
14100 (set_attr "length" "11")])
14101
14102 (define_insn "*tls_local_dynamic_base_32_sun"
14103 [(set (match_operand:SI 0 "register_operand" "=a")
14104 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14105 (match_operand:SI 2 "call_insn_operand" "")]
14106 UNSPEC_TLS_LD_BASE))
14107 (clobber (match_scratch:SI 3 "=d"))
14108 (clobber (match_scratch:SI 4 "=c"))
14109 (clobber (reg:CC 17))]
14110 "!TARGET_64BIT && TARGET_SUN_TLS"
14111 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14112 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14113 [(set_attr "type" "multi")
14114 (set_attr "length" "13")])
14115
14116 (define_expand "tls_local_dynamic_base_32"
14117 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14118 (unspec:SI [(match_dup 1) (match_dup 2)]
14119 UNSPEC_TLS_LD_BASE))
14120 (clobber (match_scratch:SI 3 ""))
14121 (clobber (match_scratch:SI 4 ""))
14122 (clobber (reg:CC 17))])]
14123 ""
14124 {
14125 if (flag_pic)
14126 operands[1] = pic_offset_table_rtx;
14127 else
14128 {
14129 operands[1] = gen_reg_rtx (Pmode);
14130 emit_insn (gen_set_got (operands[1]));
14131 }
14132 operands[2] = ix86_tls_get_addr ();
14133 })
14134
14135 (define_insn "*tls_local_dynamic_base_64"
14136 [(set (match_operand:DI 0 "register_operand" "=a")
14137 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14138 (match_operand:DI 2 "" "")))
14139 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14140 "TARGET_64BIT"
14141 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14142 [(set_attr "type" "multi")
14143 (set_attr "length" "12")])
14144
14145 (define_expand "tls_local_dynamic_base_64"
14146 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14147 (call (mem:QI (match_dup 1)) (const_int 0)))
14148 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14149 ""
14150 {
14151 operands[1] = ix86_tls_get_addr ();
14152 })
14153
14154 ;; Local dynamic of a single variable is a lose. Show combine how
14155 ;; to convert that back to global dynamic.
14156
14157 (define_insn_and_split "*tls_local_dynamic_32_once"
14158 [(set (match_operand:SI 0 "register_operand" "=a")
14159 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14160 (match_operand:SI 2 "call_insn_operand" "")]
14161 UNSPEC_TLS_LD_BASE)
14162 (const:SI (unspec:SI
14163 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14164 UNSPEC_DTPOFF))))
14165 (clobber (match_scratch:SI 4 "=d"))
14166 (clobber (match_scratch:SI 5 "=c"))
14167 (clobber (reg:CC 17))]
14168 ""
14169 "#"
14170 ""
14171 [(parallel [(set (match_dup 0)
14172 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14173 UNSPEC_TLS_GD))
14174 (clobber (match_dup 4))
14175 (clobber (match_dup 5))
14176 (clobber (reg:CC 17))])]
14177 "")
14178
14179 ;; Load and add the thread base pointer from %gs:0.
14180
14181 (define_insn "*load_tp_si"
14182 [(set (match_operand:SI 0 "register_operand" "=r")
14183 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14184 "!TARGET_64BIT"
14185 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14186 [(set_attr "type" "imov")
14187 (set_attr "modrm" "0")
14188 (set_attr "length" "7")
14189 (set_attr "memory" "load")
14190 (set_attr "imm_disp" "false")])
14191
14192 (define_insn "*add_tp_si"
14193 [(set (match_operand:SI 0 "register_operand" "=r")
14194 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14195 (match_operand:SI 1 "register_operand" "0")))
14196 (clobber (reg:CC 17))]
14197 "!TARGET_64BIT"
14198 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14199 [(set_attr "type" "alu")
14200 (set_attr "modrm" "0")
14201 (set_attr "length" "7")
14202 (set_attr "memory" "load")
14203 (set_attr "imm_disp" "false")])
14204
14205 (define_insn "*load_tp_di"
14206 [(set (match_operand:DI 0 "register_operand" "=r")
14207 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14208 "TARGET_64BIT"
14209 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14210 [(set_attr "type" "imov")
14211 (set_attr "modrm" "0")
14212 (set_attr "length" "7")
14213 (set_attr "memory" "load")
14214 (set_attr "imm_disp" "false")])
14215
14216 (define_insn "*add_tp_di"
14217 [(set (match_operand:DI 0 "register_operand" "=r")
14218 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14219 (match_operand:DI 1 "register_operand" "0")))
14220 (clobber (reg:CC 17))]
14221 "TARGET_64BIT"
14222 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14223 [(set_attr "type" "alu")
14224 (set_attr "modrm" "0")
14225 (set_attr "length" "7")
14226 (set_attr "memory" "load")
14227 (set_attr "imm_disp" "false")])
14228 \f
14229 ;; These patterns match the binary 387 instructions for addM3, subM3,
14230 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14231 ;; SFmode. The first is the normal insn, the second the same insn but
14232 ;; with one operand a conversion, and the third the same insn but with
14233 ;; the other operand a conversion. The conversion may be SFmode or
14234 ;; SImode if the target mode DFmode, but only SImode if the target mode
14235 ;; is SFmode.
14236
14237 ;; Gcc is slightly more smart about handling normal two address instructions
14238 ;; so use special patterns for add and mull.
14239 (define_insn "*fop_sf_comm_nosse"
14240 [(set (match_operand:SF 0 "register_operand" "=f")
14241 (match_operator:SF 3 "binary_fp_operator"
14242 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14243 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14244 "TARGET_80387 && !TARGET_SSE_MATH
14245 && COMMUTATIVE_ARITH_P (operands[3])
14246 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14247 "* return output_387_binary_op (insn, operands);"
14248 [(set (attr "type")
14249 (if_then_else (match_operand:SF 3 "mult_operator" "")
14250 (const_string "fmul")
14251 (const_string "fop")))
14252 (set_attr "mode" "SF")])
14253
14254 (define_insn "*fop_sf_comm"
14255 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14256 (match_operator:SF 3 "binary_fp_operator"
14257 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14258 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14259 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14260 && COMMUTATIVE_ARITH_P (operands[3])
14261 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14262 "* return output_387_binary_op (insn, operands);"
14263 [(set (attr "type")
14264 (if_then_else (eq_attr "alternative" "1")
14265 (if_then_else (match_operand:SF 3 "mult_operator" "")
14266 (const_string "ssemul")
14267 (const_string "sseadd"))
14268 (if_then_else (match_operand:SF 3 "mult_operator" "")
14269 (const_string "fmul")
14270 (const_string "fop"))))
14271 (set_attr "mode" "SF")])
14272
14273 (define_insn "*fop_sf_comm_sse"
14274 [(set (match_operand:SF 0 "register_operand" "=x")
14275 (match_operator:SF 3 "binary_fp_operator"
14276 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14277 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14278 "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14279 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14280 "* return output_387_binary_op (insn, operands);"
14281 [(set (attr "type")
14282 (if_then_else (match_operand:SF 3 "mult_operator" "")
14283 (const_string "ssemul")
14284 (const_string "sseadd")))
14285 (set_attr "mode" "SF")])
14286
14287 (define_insn "*fop_df_comm_nosse"
14288 [(set (match_operand:DF 0 "register_operand" "=f")
14289 (match_operator:DF 3 "binary_fp_operator"
14290 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14291 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14292 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14293 && COMMUTATIVE_ARITH_P (operands[3])
14294 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14295 "* return output_387_binary_op (insn, operands);"
14296 [(set (attr "type")
14297 (if_then_else (match_operand:SF 3 "mult_operator" "")
14298 (const_string "fmul")
14299 (const_string "fop")))
14300 (set_attr "mode" "DF")])
14301
14302 (define_insn "*fop_df_comm"
14303 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14304 (match_operator:DF 3 "binary_fp_operator"
14305 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14306 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14307 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14308 && COMMUTATIVE_ARITH_P (operands[3])
14309 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14310 "* return output_387_binary_op (insn, operands);"
14311 [(set (attr "type")
14312 (if_then_else (eq_attr "alternative" "1")
14313 (if_then_else (match_operand:SF 3 "mult_operator" "")
14314 (const_string "ssemul")
14315 (const_string "sseadd"))
14316 (if_then_else (match_operand:SF 3 "mult_operator" "")
14317 (const_string "fmul")
14318 (const_string "fop"))))
14319 (set_attr "mode" "DF")])
14320
14321 (define_insn "*fop_df_comm_sse"
14322 [(set (match_operand:DF 0 "register_operand" "=Y")
14323 (match_operator:DF 3 "binary_fp_operator"
14324 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14325 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14326 "TARGET_SSE2 && TARGET_SSE_MATH
14327 && COMMUTATIVE_ARITH_P (operands[3])
14328 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14329 "* return output_387_binary_op (insn, operands);"
14330 [(set (attr "type")
14331 (if_then_else (match_operand:SF 3 "mult_operator" "")
14332 (const_string "ssemul")
14333 (const_string "sseadd")))
14334 (set_attr "mode" "DF")])
14335
14336 (define_insn "*fop_xf_comm"
14337 [(set (match_operand:XF 0 "register_operand" "=f")
14338 (match_operator:XF 3 "binary_fp_operator"
14339 [(match_operand:XF 1 "register_operand" "%0")
14340 (match_operand:XF 2 "register_operand" "f")]))]
14341 "TARGET_80387
14342 && COMMUTATIVE_ARITH_P (operands[3])"
14343 "* return output_387_binary_op (insn, operands);"
14344 [(set (attr "type")
14345 (if_then_else (match_operand:XF 3 "mult_operator" "")
14346 (const_string "fmul")
14347 (const_string "fop")))
14348 (set_attr "mode" "XF")])
14349
14350 (define_insn "*fop_sf_1_nosse"
14351 [(set (match_operand:SF 0 "register_operand" "=f,f")
14352 (match_operator:SF 3 "binary_fp_operator"
14353 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14354 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14355 "TARGET_80387 && !TARGET_SSE_MATH
14356 && !COMMUTATIVE_ARITH_P (operands[3])
14357 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14358 "* return output_387_binary_op (insn, operands);"
14359 [(set (attr "type")
14360 (cond [(match_operand:SF 3 "mult_operator" "")
14361 (const_string "fmul")
14362 (match_operand:SF 3 "div_operator" "")
14363 (const_string "fdiv")
14364 ]
14365 (const_string "fop")))
14366 (set_attr "mode" "SF")])
14367
14368 (define_insn "*fop_sf_1"
14369 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14370 (match_operator:SF 3 "binary_fp_operator"
14371 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14372 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14373 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14374 && !COMMUTATIVE_ARITH_P (operands[3])
14375 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14376 "* return output_387_binary_op (insn, operands);"
14377 [(set (attr "type")
14378 (cond [(and (eq_attr "alternative" "2")
14379 (match_operand:SF 3 "mult_operator" ""))
14380 (const_string "ssemul")
14381 (and (eq_attr "alternative" "2")
14382 (match_operand:SF 3 "div_operator" ""))
14383 (const_string "ssediv")
14384 (eq_attr "alternative" "2")
14385 (const_string "sseadd")
14386 (match_operand:SF 3 "mult_operator" "")
14387 (const_string "fmul")
14388 (match_operand:SF 3 "div_operator" "")
14389 (const_string "fdiv")
14390 ]
14391 (const_string "fop")))
14392 (set_attr "mode" "SF")])
14393
14394 (define_insn "*fop_sf_1_sse"
14395 [(set (match_operand:SF 0 "register_operand" "=x")
14396 (match_operator:SF 3 "binary_fp_operator"
14397 [(match_operand:SF 1 "register_operand" "0")
14398 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14399 "TARGET_SSE_MATH
14400 && !COMMUTATIVE_ARITH_P (operands[3])"
14401 "* return output_387_binary_op (insn, operands);"
14402 [(set (attr "type")
14403 (cond [(match_operand:SF 3 "mult_operator" "")
14404 (const_string "ssemul")
14405 (match_operand:SF 3 "div_operator" "")
14406 (const_string "ssediv")
14407 ]
14408 (const_string "sseadd")))
14409 (set_attr "mode" "SF")])
14410
14411 ;; ??? Add SSE splitters for these!
14412 (define_insn "*fop_sf_2"
14413 [(set (match_operand:SF 0 "register_operand" "=f,f")
14414 (match_operator:SF 3 "binary_fp_operator"
14415 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14416 (match_operand:SF 2 "register_operand" "0,0")]))]
14417 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14418 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14419 [(set (attr "type")
14420 (cond [(match_operand:SF 3 "mult_operator" "")
14421 (const_string "fmul")
14422 (match_operand:SF 3 "div_operator" "")
14423 (const_string "fdiv")
14424 ]
14425 (const_string "fop")))
14426 (set_attr "fp_int_src" "true")
14427 (set_attr "mode" "SI")])
14428
14429 (define_insn "*fop_sf_3"
14430 [(set (match_operand:SF 0 "register_operand" "=f,f")
14431 (match_operator:SF 3 "binary_fp_operator"
14432 [(match_operand:SF 1 "register_operand" "0,0")
14433 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14434 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14435 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14436 [(set (attr "type")
14437 (cond [(match_operand:SF 3 "mult_operator" "")
14438 (const_string "fmul")
14439 (match_operand:SF 3 "div_operator" "")
14440 (const_string "fdiv")
14441 ]
14442 (const_string "fop")))
14443 (set_attr "fp_int_src" "true")
14444 (set_attr "mode" "SI")])
14445
14446 (define_insn "*fop_df_1_nosse"
14447 [(set (match_operand:DF 0 "register_operand" "=f,f")
14448 (match_operator:DF 3 "binary_fp_operator"
14449 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14450 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14451 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14452 && !COMMUTATIVE_ARITH_P (operands[3])
14453 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14454 "* return output_387_binary_op (insn, operands);"
14455 [(set (attr "type")
14456 (cond [(match_operand:DF 3 "mult_operator" "")
14457 (const_string "fmul")
14458 (match_operand:DF 3 "div_operator" "")
14459 (const_string "fdiv")
14460 ]
14461 (const_string "fop")))
14462 (set_attr "mode" "DF")])
14463
14464
14465 (define_insn "*fop_df_1"
14466 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14467 (match_operator:DF 3 "binary_fp_operator"
14468 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14469 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14470 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14471 && !COMMUTATIVE_ARITH_P (operands[3])
14472 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14473 "* return output_387_binary_op (insn, operands);"
14474 [(set (attr "type")
14475 (cond [(and (eq_attr "alternative" "2")
14476 (match_operand:SF 3 "mult_operator" ""))
14477 (const_string "ssemul")
14478 (and (eq_attr "alternative" "2")
14479 (match_operand:SF 3 "div_operator" ""))
14480 (const_string "ssediv")
14481 (eq_attr "alternative" "2")
14482 (const_string "sseadd")
14483 (match_operand:DF 3 "mult_operator" "")
14484 (const_string "fmul")
14485 (match_operand:DF 3 "div_operator" "")
14486 (const_string "fdiv")
14487 ]
14488 (const_string "fop")))
14489 (set_attr "mode" "DF")])
14490
14491 (define_insn "*fop_df_1_sse"
14492 [(set (match_operand:DF 0 "register_operand" "=Y")
14493 (match_operator:DF 3 "binary_fp_operator"
14494 [(match_operand:DF 1 "register_operand" "0")
14495 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14496 "TARGET_SSE2 && TARGET_SSE_MATH
14497 && !COMMUTATIVE_ARITH_P (operands[3])"
14498 "* return output_387_binary_op (insn, operands);"
14499 [(set_attr "mode" "DF")
14500 (set (attr "type")
14501 (cond [(match_operand:SF 3 "mult_operator" "")
14502 (const_string "ssemul")
14503 (match_operand:SF 3 "div_operator" "")
14504 (const_string "ssediv")
14505 ]
14506 (const_string "sseadd")))])
14507
14508 ;; ??? Add SSE splitters for these!
14509 (define_insn "*fop_df_2"
14510 [(set (match_operand:DF 0 "register_operand" "=f,f")
14511 (match_operator:DF 3 "binary_fp_operator"
14512 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14513 (match_operand:DF 2 "register_operand" "0,0")]))]
14514 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14515 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14516 [(set (attr "type")
14517 (cond [(match_operand:DF 3 "mult_operator" "")
14518 (const_string "fmul")
14519 (match_operand:DF 3 "div_operator" "")
14520 (const_string "fdiv")
14521 ]
14522 (const_string "fop")))
14523 (set_attr "fp_int_src" "true")
14524 (set_attr "mode" "SI")])
14525
14526 (define_insn "*fop_df_3"
14527 [(set (match_operand:DF 0 "register_operand" "=f,f")
14528 (match_operator:DF 3 "binary_fp_operator"
14529 [(match_operand:DF 1 "register_operand" "0,0")
14530 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14531 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14532 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14533 [(set (attr "type")
14534 (cond [(match_operand:DF 3 "mult_operator" "")
14535 (const_string "fmul")
14536 (match_operand:DF 3 "div_operator" "")
14537 (const_string "fdiv")
14538 ]
14539 (const_string "fop")))
14540 (set_attr "fp_int_src" "true")
14541 (set_attr "mode" "SI")])
14542
14543 (define_insn "*fop_df_4"
14544 [(set (match_operand:DF 0 "register_operand" "=f,f")
14545 (match_operator:DF 3 "binary_fp_operator"
14546 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14547 (match_operand:DF 2 "register_operand" "0,f")]))]
14548 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14549 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14550 "* return output_387_binary_op (insn, operands);"
14551 [(set (attr "type")
14552 (cond [(match_operand:DF 3 "mult_operator" "")
14553 (const_string "fmul")
14554 (match_operand:DF 3 "div_operator" "")
14555 (const_string "fdiv")
14556 ]
14557 (const_string "fop")))
14558 (set_attr "mode" "SF")])
14559
14560 (define_insn "*fop_df_5"
14561 [(set (match_operand:DF 0 "register_operand" "=f,f")
14562 (match_operator:DF 3 "binary_fp_operator"
14563 [(match_operand:DF 1 "register_operand" "0,f")
14564 (float_extend:DF
14565 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14566 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14567 "* return output_387_binary_op (insn, operands);"
14568 [(set (attr "type")
14569 (cond [(match_operand:DF 3 "mult_operator" "")
14570 (const_string "fmul")
14571 (match_operand:DF 3 "div_operator" "")
14572 (const_string "fdiv")
14573 ]
14574 (const_string "fop")))
14575 (set_attr "mode" "SF")])
14576
14577 (define_insn "*fop_df_6"
14578 [(set (match_operand:DF 0 "register_operand" "=f,f")
14579 (match_operator:DF 3 "binary_fp_operator"
14580 [(float_extend:DF
14581 (match_operand:SF 1 "register_operand" "0,f"))
14582 (float_extend:DF
14583 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14584 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14585 "* return output_387_binary_op (insn, operands);"
14586 [(set (attr "type")
14587 (cond [(match_operand:DF 3 "mult_operator" "")
14588 (const_string "fmul")
14589 (match_operand:DF 3 "div_operator" "")
14590 (const_string "fdiv")
14591 ]
14592 (const_string "fop")))
14593 (set_attr "mode" "SF")])
14594
14595 (define_insn "*fop_xf_1"
14596 [(set (match_operand:XF 0 "register_operand" "=f,f")
14597 (match_operator:XF 3 "binary_fp_operator"
14598 [(match_operand:XF 1 "register_operand" "0,f")
14599 (match_operand:XF 2 "register_operand" "f,0")]))]
14600 "TARGET_80387
14601 && !COMMUTATIVE_ARITH_P (operands[3])"
14602 "* return output_387_binary_op (insn, operands);"
14603 [(set (attr "type")
14604 (cond [(match_operand:XF 3 "mult_operator" "")
14605 (const_string "fmul")
14606 (match_operand:XF 3 "div_operator" "")
14607 (const_string "fdiv")
14608 ]
14609 (const_string "fop")))
14610 (set_attr "mode" "XF")])
14611
14612 (define_insn "*fop_xf_2"
14613 [(set (match_operand:XF 0 "register_operand" "=f,f")
14614 (match_operator:XF 3 "binary_fp_operator"
14615 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14616 (match_operand:XF 2 "register_operand" "0,0")]))]
14617 "TARGET_80387 && TARGET_USE_FIOP"
14618 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14619 [(set (attr "type")
14620 (cond [(match_operand:XF 3 "mult_operator" "")
14621 (const_string "fmul")
14622 (match_operand:XF 3 "div_operator" "")
14623 (const_string "fdiv")
14624 ]
14625 (const_string "fop")))
14626 (set_attr "fp_int_src" "true")
14627 (set_attr "mode" "SI")])
14628
14629 (define_insn "*fop_xf_3"
14630 [(set (match_operand:XF 0 "register_operand" "=f,f")
14631 (match_operator:XF 3 "binary_fp_operator"
14632 [(match_operand:XF 1 "register_operand" "0,0")
14633 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14634 "TARGET_80387 && TARGET_USE_FIOP"
14635 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14636 [(set (attr "type")
14637 (cond [(match_operand:XF 3 "mult_operator" "")
14638 (const_string "fmul")
14639 (match_operand:XF 3 "div_operator" "")
14640 (const_string "fdiv")
14641 ]
14642 (const_string "fop")))
14643 (set_attr "fp_int_src" "true")
14644 (set_attr "mode" "SI")])
14645
14646 (define_insn "*fop_xf_4"
14647 [(set (match_operand:XF 0 "register_operand" "=f,f")
14648 (match_operator:XF 3 "binary_fp_operator"
14649 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14650 (match_operand:XF 2 "register_operand" "0,f")]))]
14651 "TARGET_80387"
14652 "* return output_387_binary_op (insn, operands);"
14653 [(set (attr "type")
14654 (cond [(match_operand:XF 3 "mult_operator" "")
14655 (const_string "fmul")
14656 (match_operand:XF 3 "div_operator" "")
14657 (const_string "fdiv")
14658 ]
14659 (const_string "fop")))
14660 (set_attr "mode" "SF")])
14661
14662 (define_insn "*fop_xf_5"
14663 [(set (match_operand:XF 0 "register_operand" "=f,f")
14664 (match_operator:XF 3 "binary_fp_operator"
14665 [(match_operand:XF 1 "register_operand" "0,f")
14666 (float_extend:XF
14667 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14668 "TARGET_80387"
14669 "* return output_387_binary_op (insn, operands);"
14670 [(set (attr "type")
14671 (cond [(match_operand:XF 3 "mult_operator" "")
14672 (const_string "fmul")
14673 (match_operand:XF 3 "div_operator" "")
14674 (const_string "fdiv")
14675 ]
14676 (const_string "fop")))
14677 (set_attr "mode" "SF")])
14678
14679 (define_insn "*fop_xf_6"
14680 [(set (match_operand:XF 0 "register_operand" "=f,f")
14681 (match_operator:XF 3 "binary_fp_operator"
14682 [(float_extend:XF
14683 (match_operand 1 "register_operand" "0,f"))
14684 (float_extend:XF
14685 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14686 "TARGET_80387"
14687 "* return output_387_binary_op (insn, operands);"
14688 [(set (attr "type")
14689 (cond [(match_operand:XF 3 "mult_operator" "")
14690 (const_string "fmul")
14691 (match_operand:XF 3 "div_operator" "")
14692 (const_string "fdiv")
14693 ]
14694 (const_string "fop")))
14695 (set_attr "mode" "SF")])
14696
14697 (define_split
14698 [(set (match_operand 0 "register_operand" "")
14699 (match_operator 3 "binary_fp_operator"
14700 [(float (match_operand:SI 1 "register_operand" ""))
14701 (match_operand 2 "register_operand" "")]))]
14702 "TARGET_80387 && reload_completed
14703 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14704 [(const_int 0)]
14705 {
14706 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14707 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14708 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14709 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14710 GET_MODE (operands[3]),
14711 operands[4],
14712 operands[2])));
14713 ix86_free_from_memory (GET_MODE (operands[1]));
14714 DONE;
14715 })
14716
14717 (define_split
14718 [(set (match_operand 0 "register_operand" "")
14719 (match_operator 3 "binary_fp_operator"
14720 [(match_operand 1 "register_operand" "")
14721 (float (match_operand:SI 2 "register_operand" ""))]))]
14722 "TARGET_80387 && reload_completed
14723 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14724 [(const_int 0)]
14725 {
14726 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14727 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14728 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14729 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14730 GET_MODE (operands[3]),
14731 operands[1],
14732 operands[4])));
14733 ix86_free_from_memory (GET_MODE (operands[2]));
14734 DONE;
14735 })
14736 \f
14737 ;; FPU special functions.
14738
14739 (define_expand "sqrtsf2"
14740 [(set (match_operand:SF 0 "register_operand" "")
14741 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14742 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14743 {
14744 if (!TARGET_SSE_MATH)
14745 operands[1] = force_reg (SFmode, operands[1]);
14746 })
14747
14748 (define_insn "sqrtsf2_1"
14749 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14750 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14751 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14752 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14753 "@
14754 fsqrt
14755 sqrtss\t{%1, %0|%0, %1}"
14756 [(set_attr "type" "fpspc,sse")
14757 (set_attr "mode" "SF,SF")
14758 (set_attr "athlon_decode" "direct,*")])
14759
14760 (define_insn "sqrtsf2_1_sse_only"
14761 [(set (match_operand:SF 0 "register_operand" "=x")
14762 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14763 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14764 "sqrtss\t{%1, %0|%0, %1}"
14765 [(set_attr "type" "sse")
14766 (set_attr "mode" "SF")
14767 (set_attr "athlon_decode" "*")])
14768
14769 (define_insn "sqrtsf2_i387"
14770 [(set (match_operand:SF 0 "register_operand" "=f")
14771 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14772 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14773 && !TARGET_SSE_MATH"
14774 "fsqrt"
14775 [(set_attr "type" "fpspc")
14776 (set_attr "mode" "SF")
14777 (set_attr "athlon_decode" "direct")])
14778
14779 (define_expand "sqrtdf2"
14780 [(set (match_operand:DF 0 "register_operand" "")
14781 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14782 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14783 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14784 {
14785 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14786 operands[1] = force_reg (DFmode, operands[1]);
14787 })
14788
14789 (define_insn "sqrtdf2_1"
14790 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14791 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14792 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14793 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14794 "@
14795 fsqrt
14796 sqrtsd\t{%1, %0|%0, %1}"
14797 [(set_attr "type" "fpspc,sse")
14798 (set_attr "mode" "DF,DF")
14799 (set_attr "athlon_decode" "direct,*")])
14800
14801 (define_insn "sqrtdf2_1_sse_only"
14802 [(set (match_operand:DF 0 "register_operand" "=Y")
14803 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14804 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14805 "sqrtsd\t{%1, %0|%0, %1}"
14806 [(set_attr "type" "sse")
14807 (set_attr "mode" "DF")
14808 (set_attr "athlon_decode" "*")])
14809
14810 (define_insn "sqrtdf2_i387"
14811 [(set (match_operand:DF 0 "register_operand" "=f")
14812 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14813 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14814 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14815 "fsqrt"
14816 [(set_attr "type" "fpspc")
14817 (set_attr "mode" "DF")
14818 (set_attr "athlon_decode" "direct")])
14819
14820 (define_insn "*sqrtextendsfdf2"
14821 [(set (match_operand:DF 0 "register_operand" "=f")
14822 (sqrt:DF (float_extend:DF
14823 (match_operand:SF 1 "register_operand" "0"))))]
14824 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14825 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14826 "fsqrt"
14827 [(set_attr "type" "fpspc")
14828 (set_attr "mode" "DF")
14829 (set_attr "athlon_decode" "direct")])
14830
14831 (define_insn "sqrtxf2"
14832 [(set (match_operand:XF 0 "register_operand" "=f")
14833 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14834 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14835 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14836 "fsqrt"
14837 [(set_attr "type" "fpspc")
14838 (set_attr "mode" "XF")
14839 (set_attr "athlon_decode" "direct")])
14840
14841 (define_insn "*sqrtextenddfxf2"
14842 [(set (match_operand:XF 0 "register_operand" "=f")
14843 (sqrt:XF (float_extend:XF
14844 (match_operand:DF 1 "register_operand" "0"))))]
14845 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14846 "fsqrt"
14847 [(set_attr "type" "fpspc")
14848 (set_attr "mode" "XF")
14849 (set_attr "athlon_decode" "direct")])
14850
14851 (define_insn "*sqrtextendsfxf2"
14852 [(set (match_operand:XF 0 "register_operand" "=f")
14853 (sqrt:XF (float_extend:XF
14854 (match_operand:SF 1 "register_operand" "0"))))]
14855 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14856 "fsqrt"
14857 [(set_attr "type" "fpspc")
14858 (set_attr "mode" "XF")
14859 (set_attr "athlon_decode" "direct")])
14860
14861 (define_insn "*sindf2"
14862 [(set (match_operand:DF 0 "register_operand" "=f")
14863 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14864 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14865 && flag_unsafe_math_optimizations"
14866 "fsin"
14867 [(set_attr "type" "fpspc")
14868 (set_attr "mode" "DF")])
14869
14870 (define_insn "*sinsf2"
14871 [(set (match_operand:SF 0 "register_operand" "=f")
14872 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14873 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14874 && flag_unsafe_math_optimizations"
14875 "fsin"
14876 [(set_attr "type" "fpspc")
14877 (set_attr "mode" "SF")])
14878
14879 (define_insn "*sinextendsfdf2"
14880 [(set (match_operand:DF 0 "register_operand" "=f")
14881 (unspec:DF [(float_extend:DF
14882 (match_operand:SF 1 "register_operand" "0"))]
14883 UNSPEC_SIN))]
14884 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14885 && flag_unsafe_math_optimizations"
14886 "fsin"
14887 [(set_attr "type" "fpspc")
14888 (set_attr "mode" "DF")])
14889
14890 (define_insn "*sinxf2"
14891 [(set (match_operand:XF 0 "register_operand" "=f")
14892 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14893 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14894 && flag_unsafe_math_optimizations"
14895 "fsin"
14896 [(set_attr "type" "fpspc")
14897 (set_attr "mode" "XF")])
14898
14899 (define_insn "*cosdf2"
14900 [(set (match_operand:DF 0 "register_operand" "=f")
14901 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14902 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14903 && flag_unsafe_math_optimizations"
14904 "fcos"
14905 [(set_attr "type" "fpspc")
14906 (set_attr "mode" "DF")])
14907
14908 (define_insn "*cossf2"
14909 [(set (match_operand:SF 0 "register_operand" "=f")
14910 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14911 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14912 && flag_unsafe_math_optimizations"
14913 "fcos"
14914 [(set_attr "type" "fpspc")
14915 (set_attr "mode" "SF")])
14916
14917 (define_insn "*cosextendsfdf2"
14918 [(set (match_operand:DF 0 "register_operand" "=f")
14919 (unspec:DF [(float_extend:DF
14920 (match_operand:SF 1 "register_operand" "0"))]
14921 UNSPEC_COS))]
14922 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14923 && flag_unsafe_math_optimizations"
14924 "fcos"
14925 [(set_attr "type" "fpspc")
14926 (set_attr "mode" "DF")])
14927
14928 (define_insn "*cosxf2"
14929 [(set (match_operand:XF 0 "register_operand" "=f")
14930 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14931 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14932 && flag_unsafe_math_optimizations"
14933 "fcos"
14934 [(set_attr "type" "fpspc")
14935 (set_attr "mode" "XF")])
14936
14937 ;; With sincos pattern defined, sin and cos builtin function will be
14938 ;; expanded to sincos pattern with one of its outputs left unused.
14939 ;; Cse pass will detected, if two sincos patterns can be combined,
14940 ;; otherwise sincos pattern will be splitted back to sin or cos pattern,
14941 ;; depending on the unused output.
14942
14943 (define_insn "sincosdf3"
14944 [(set (match_operand:DF 0 "register_operand" "=f")
14945 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14946 UNSPEC_SINCOS_COS))
14947 (set (match_operand:DF 1 "register_operand" "=u")
14948 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14949 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14950 && flag_unsafe_math_optimizations"
14951 "fsincos"
14952 [(set_attr "type" "fpspc")
14953 (set_attr "mode" "DF")])
14954
14955 (define_split
14956 [(set (match_operand:DF 0 "register_operand" "")
14957 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14958 UNSPEC_SINCOS_COS))
14959 (set (match_operand:DF 1 "register_operand" "")
14960 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14961 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14962 && !reload_completed && !reload_in_progress"
14963 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14964 "")
14965
14966 (define_split
14967 [(set (match_operand:DF 0 "register_operand" "")
14968 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14969 UNSPEC_SINCOS_COS))
14970 (set (match_operand:DF 1 "register_operand" "")
14971 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14972 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14973 && !reload_completed && !reload_in_progress"
14974 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14975 "")
14976
14977 (define_insn "sincossf3"
14978 [(set (match_operand:SF 0 "register_operand" "=f")
14979 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14980 UNSPEC_SINCOS_COS))
14981 (set (match_operand:SF 1 "register_operand" "=u")
14982 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14983 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14984 && flag_unsafe_math_optimizations"
14985 "fsincos"
14986 [(set_attr "type" "fpspc")
14987 (set_attr "mode" "SF")])
14988
14989 (define_split
14990 [(set (match_operand:SF 0 "register_operand" "")
14991 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14992 UNSPEC_SINCOS_COS))
14993 (set (match_operand:SF 1 "register_operand" "")
14994 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14995 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14996 && !reload_completed && !reload_in_progress"
14997 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14998 "")
14999
15000 (define_split
15001 [(set (match_operand:SF 0 "register_operand" "")
15002 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15003 UNSPEC_SINCOS_COS))
15004 (set (match_operand:SF 1 "register_operand" "")
15005 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15006 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15007 && !reload_completed && !reload_in_progress"
15008 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15009 "")
15010
15011 (define_insn "*sincosextendsfdf3"
15012 [(set (match_operand:DF 0 "register_operand" "=f")
15013 (unspec:DF [(float_extend:DF
15014 (match_operand:SF 2 "register_operand" "0"))]
15015 UNSPEC_SINCOS_COS))
15016 (set (match_operand:DF 1 "register_operand" "=u")
15017 (unspec:DF [(float_extend:DF
15018 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15019 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15020 && flag_unsafe_math_optimizations"
15021 "fsincos"
15022 [(set_attr "type" "fpspc")
15023 (set_attr "mode" "DF")])
15024
15025 (define_split
15026 [(set (match_operand:DF 0 "register_operand" "")
15027 (unspec:DF [(float_extend:DF
15028 (match_operand:SF 2 "register_operand" ""))]
15029 UNSPEC_SINCOS_COS))
15030 (set (match_operand:DF 1 "register_operand" "")
15031 (unspec:DF [(float_extend:DF
15032 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15033 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15034 && !reload_completed && !reload_in_progress"
15035 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15036 (match_dup 2))] UNSPEC_SIN))]
15037 "")
15038
15039 (define_split
15040 [(set (match_operand:DF 0 "register_operand" "")
15041 (unspec:DF [(float_extend:DF
15042 (match_operand:SF 2 "register_operand" ""))]
15043 UNSPEC_SINCOS_COS))
15044 (set (match_operand:DF 1 "register_operand" "")
15045 (unspec:DF [(float_extend:DF
15046 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15047 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15048 && !reload_completed && !reload_in_progress"
15049 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15050 (match_dup 2))] UNSPEC_COS))]
15051 "")
15052
15053 (define_insn "sincosxf3"
15054 [(set (match_operand:XF 0 "register_operand" "=f")
15055 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15056 UNSPEC_SINCOS_COS))
15057 (set (match_operand:XF 1 "register_operand" "=u")
15058 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15059 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15060 && flag_unsafe_math_optimizations"
15061 "fsincos"
15062 [(set_attr "type" "fpspc")
15063 (set_attr "mode" "XF")])
15064
15065 (define_split
15066 [(set (match_operand:XF 0 "register_operand" "")
15067 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15068 UNSPEC_SINCOS_COS))
15069 (set (match_operand:XF 1 "register_operand" "")
15070 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15071 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15072 && !reload_completed && !reload_in_progress"
15073 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15074 "")
15075
15076 (define_split
15077 [(set (match_operand:XF 0 "register_operand" "")
15078 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15079 UNSPEC_SINCOS_COS))
15080 (set (match_operand:XF 1 "register_operand" "")
15081 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15082 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15083 && !reload_completed && !reload_in_progress"
15084 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15085 "")
15086
15087 (define_insn "*tandf3_1"
15088 [(set (match_operand:DF 0 "register_operand" "=f")
15089 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15090 UNSPEC_TAN_ONE))
15091 (set (match_operand:DF 1 "register_operand" "=u")
15092 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15093 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15094 && flag_unsafe_math_optimizations"
15095 "fptan"
15096 [(set_attr "type" "fpspc")
15097 (set_attr "mode" "DF")])
15098
15099 ;; optimize sequence: fptan
15100 ;; fstp %st(0)
15101 ;; fld1
15102 ;; into fptan insn.
15103
15104 (define_peephole2
15105 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15106 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15107 UNSPEC_TAN_ONE))
15108 (set (match_operand:DF 1 "register_operand" "")
15109 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15110 (set (match_dup 0)
15111 (match_operand:DF 3 "immediate_operand" ""))]
15112 "standard_80387_constant_p (operands[3]) == 2"
15113 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15114 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15115 "")
15116
15117 (define_expand "tandf2"
15118 [(parallel [(set (match_dup 2)
15119 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15120 UNSPEC_TAN_ONE))
15121 (set (match_operand:DF 0 "register_operand" "")
15122 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15123 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15124 && flag_unsafe_math_optimizations"
15125 {
15126 operands[2] = gen_reg_rtx (DFmode);
15127 })
15128
15129 (define_insn "*tansf3_1"
15130 [(set (match_operand:SF 0 "register_operand" "=f")
15131 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15132 UNSPEC_TAN_ONE))
15133 (set (match_operand:SF 1 "register_operand" "=u")
15134 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15135 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15136 && flag_unsafe_math_optimizations"
15137 "fptan"
15138 [(set_attr "type" "fpspc")
15139 (set_attr "mode" "SF")])
15140
15141 ;; optimize sequence: fptan
15142 ;; fstp %st(0)
15143 ;; fld1
15144 ;; into fptan insn.
15145
15146 (define_peephole2
15147 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15148 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15149 UNSPEC_TAN_ONE))
15150 (set (match_operand:SF 1 "register_operand" "")
15151 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15152 (set (match_dup 0)
15153 (match_operand:SF 3 "immediate_operand" ""))]
15154 "standard_80387_constant_p (operands[3]) == 2"
15155 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15156 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15157 "")
15158
15159 (define_expand "tansf2"
15160 [(parallel [(set (match_dup 2)
15161 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15162 UNSPEC_TAN_ONE))
15163 (set (match_operand:SF 0 "register_operand" "")
15164 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15165 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15166 && flag_unsafe_math_optimizations"
15167 {
15168 operands[2] = gen_reg_rtx (SFmode);
15169 })
15170
15171 (define_insn "*tanxf3_1"
15172 [(set (match_operand:XF 0 "register_operand" "=f")
15173 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15174 UNSPEC_TAN_ONE))
15175 (set (match_operand:XF 1 "register_operand" "=u")
15176 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15177 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15178 && flag_unsafe_math_optimizations"
15179 "fptan"
15180 [(set_attr "type" "fpspc")
15181 (set_attr "mode" "XF")])
15182
15183 ;; optimize sequence: fptan
15184 ;; fstp %st(0)
15185 ;; fld1
15186 ;; into fptan insn.
15187
15188 (define_peephole2
15189 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15190 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15191 UNSPEC_TAN_ONE))
15192 (set (match_operand:XF 1 "register_operand" "")
15193 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15194 (set (match_dup 0)
15195 (match_operand:XF 3 "immediate_operand" ""))]
15196 "standard_80387_constant_p (operands[3]) == 2"
15197 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15198 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15199 "")
15200
15201 (define_expand "tanxf2"
15202 [(parallel [(set (match_dup 2)
15203 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15204 UNSPEC_TAN_ONE))
15205 (set (match_operand:XF 0 "register_operand" "")
15206 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15207 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15208 && flag_unsafe_math_optimizations"
15209 {
15210 operands[2] = gen_reg_rtx (XFmode);
15211 })
15212
15213 (define_insn "atan2df3_1"
15214 [(set (match_operand:DF 0 "register_operand" "=f")
15215 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15216 (match_operand:DF 1 "register_operand" "u")]
15217 UNSPEC_FPATAN))
15218 (clobber (match_scratch:DF 3 "=1"))]
15219 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15220 && flag_unsafe_math_optimizations"
15221 "fpatan"
15222 [(set_attr "type" "fpspc")
15223 (set_attr "mode" "DF")])
15224
15225 (define_expand "atan2df3"
15226 [(use (match_operand:DF 0 "register_operand" "=f"))
15227 (use (match_operand:DF 2 "register_operand" "0"))
15228 (use (match_operand:DF 1 "register_operand" "u"))]
15229 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15230 && flag_unsafe_math_optimizations"
15231 {
15232 rtx copy = gen_reg_rtx (DFmode);
15233 emit_move_insn (copy, operands[1]);
15234 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15235 DONE;
15236 })
15237
15238 (define_expand "atandf2"
15239 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15240 (unspec:DF [(match_dup 2)
15241 (match_operand:DF 1 "register_operand" "")]
15242 UNSPEC_FPATAN))
15243 (clobber (match_scratch:DF 3 ""))])]
15244 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15245 && flag_unsafe_math_optimizations"
15246 {
15247 operands[2] = gen_reg_rtx (DFmode);
15248 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15249 })
15250
15251 (define_insn "atan2sf3_1"
15252 [(set (match_operand:SF 0 "register_operand" "=f")
15253 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15254 (match_operand:SF 1 "register_operand" "u")]
15255 UNSPEC_FPATAN))
15256 (clobber (match_scratch:SF 3 "=1"))]
15257 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15258 && flag_unsafe_math_optimizations"
15259 "fpatan"
15260 [(set_attr "type" "fpspc")
15261 (set_attr "mode" "SF")])
15262
15263 (define_expand "atan2sf3"
15264 [(use (match_operand:SF 0 "register_operand" "=f"))
15265 (use (match_operand:SF 2 "register_operand" "0"))
15266 (use (match_operand:SF 1 "register_operand" "u"))]
15267 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15268 && flag_unsafe_math_optimizations"
15269 {
15270 rtx copy = gen_reg_rtx (SFmode);
15271 emit_move_insn (copy, operands[1]);
15272 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15273 DONE;
15274 })
15275
15276 (define_expand "atansf2"
15277 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15278 (unspec:SF [(match_dup 2)
15279 (match_operand:SF 1 "register_operand" "")]
15280 UNSPEC_FPATAN))
15281 (clobber (match_scratch:SF 3 ""))])]
15282 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15283 && flag_unsafe_math_optimizations"
15284 {
15285 operands[2] = gen_reg_rtx (SFmode);
15286 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15287 })
15288
15289 (define_insn "atan2xf3_1"
15290 [(set (match_operand:XF 0 "register_operand" "=f")
15291 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15292 (match_operand:XF 1 "register_operand" "u")]
15293 UNSPEC_FPATAN))
15294 (clobber (match_scratch:XF 3 "=1"))]
15295 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15296 && flag_unsafe_math_optimizations"
15297 "fpatan"
15298 [(set_attr "type" "fpspc")
15299 (set_attr "mode" "XF")])
15300
15301 (define_expand "atan2xf3"
15302 [(use (match_operand:XF 0 "register_operand" "=f"))
15303 (use (match_operand:XF 2 "register_operand" "0"))
15304 (use (match_operand:XF 1 "register_operand" "u"))]
15305 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15306 && flag_unsafe_math_optimizations"
15307 {
15308 rtx copy = gen_reg_rtx (XFmode);
15309 emit_move_insn (copy, operands[1]);
15310 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15311 DONE;
15312 })
15313
15314 (define_expand "atanxf2"
15315 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15316 (unspec:XF [(match_dup 2)
15317 (match_operand:XF 1 "register_operand" "")]
15318 UNSPEC_FPATAN))
15319 (clobber (match_scratch:XF 3 ""))])]
15320 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15321 && flag_unsafe_math_optimizations"
15322 {
15323 operands[2] = gen_reg_rtx (XFmode);
15324 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15325 })
15326
15327 (define_expand "asindf2"
15328 [(set (match_dup 2)
15329 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15330 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15331 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15332 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15333 (parallel [(set (match_dup 7)
15334 (unspec:XF [(match_dup 6) (match_dup 2)]
15335 UNSPEC_FPATAN))
15336 (clobber (match_scratch:XF 8 ""))])
15337 (set (match_operand:DF 0 "register_operand" "")
15338 (float_truncate:DF (match_dup 7)))]
15339 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15340 && flag_unsafe_math_optimizations"
15341 {
15342 int i;
15343
15344 for (i=2; i<8; i++)
15345 operands[i] = gen_reg_rtx (XFmode);
15346
15347 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15348 })
15349
15350 (define_expand "asinsf2"
15351 [(set (match_dup 2)
15352 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15353 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15354 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15355 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15356 (parallel [(set (match_dup 7)
15357 (unspec:XF [(match_dup 6) (match_dup 2)]
15358 UNSPEC_FPATAN))
15359 (clobber (match_scratch:XF 8 ""))])
15360 (set (match_operand:SF 0 "register_operand" "")
15361 (float_truncate:SF (match_dup 7)))]
15362 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15363 && flag_unsafe_math_optimizations"
15364 {
15365 int i;
15366
15367 for (i=2; i<8; i++)
15368 operands[i] = gen_reg_rtx (XFmode);
15369
15370 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15371 })
15372
15373 (define_expand "asinxf2"
15374 [(set (match_dup 2)
15375 (mult:XF (match_operand:XF 1 "register_operand" "")
15376 (match_dup 1)))
15377 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15378 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15379 (parallel [(set (match_operand:XF 0 "register_operand" "")
15380 (unspec:XF [(match_dup 5) (match_dup 1)]
15381 UNSPEC_FPATAN))
15382 (clobber (match_scratch:XF 6 ""))])]
15383 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15384 && flag_unsafe_math_optimizations"
15385 {
15386 int i;
15387
15388 for (i=2; i<6; i++)
15389 operands[i] = gen_reg_rtx (XFmode);
15390
15391 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15392 })
15393
15394 (define_expand "acosdf2"
15395 [(set (match_dup 2)
15396 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15397 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15398 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15399 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15400 (parallel [(set (match_dup 7)
15401 (unspec:XF [(match_dup 2) (match_dup 6)]
15402 UNSPEC_FPATAN))
15403 (clobber (match_scratch:XF 8 ""))])
15404 (set (match_operand:DF 0 "register_operand" "")
15405 (float_truncate:DF (match_dup 7)))]
15406 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15407 && flag_unsafe_math_optimizations"
15408 {
15409 int i;
15410
15411 for (i=2; i<8; i++)
15412 operands[i] = gen_reg_rtx (XFmode);
15413
15414 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15415 })
15416
15417 (define_expand "acossf2"
15418 [(set (match_dup 2)
15419 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15420 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15421 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15422 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15423 (parallel [(set (match_dup 7)
15424 (unspec:XF [(match_dup 2) (match_dup 6)]
15425 UNSPEC_FPATAN))
15426 (clobber (match_scratch:XF 8 ""))])
15427 (set (match_operand:SF 0 "register_operand" "")
15428 (float_truncate:SF (match_dup 7)))]
15429 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15430 && flag_unsafe_math_optimizations"
15431 {
15432 int i;
15433
15434 for (i=2; i<8; i++)
15435 operands[i] = gen_reg_rtx (XFmode);
15436
15437 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15438 })
15439
15440 (define_expand "acosxf2"
15441 [(set (match_dup 2)
15442 (mult:XF (match_operand:XF 1 "register_operand" "")
15443 (match_dup 1)))
15444 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15445 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15446 (parallel [(set (match_operand:XF 0 "register_operand" "")
15447 (unspec:XF [(match_dup 1) (match_dup 5)]
15448 UNSPEC_FPATAN))
15449 (clobber (match_scratch:XF 6 ""))])]
15450 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15451 && flag_unsafe_math_optimizations"
15452 {
15453 int i;
15454
15455 for (i=2; i<6; i++)
15456 operands[i] = gen_reg_rtx (XFmode);
15457
15458 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15459 })
15460
15461 (define_insn "*fyl2x_sfxf3"
15462 [(set (match_operand:SF 0 "register_operand" "=f")
15463 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15464 (match_operand:XF 1 "register_operand" "u")]
15465 UNSPEC_FYL2X))
15466 (clobber (match_scratch:SF 3 "=1"))]
15467 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15468 && flag_unsafe_math_optimizations"
15469 "fyl2x"
15470 [(set_attr "type" "fpspc")
15471 (set_attr "mode" "SF")])
15472
15473 (define_insn "*fyl2x_dfxf3"
15474 [(set (match_operand:DF 0 "register_operand" "=f")
15475 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15476 (match_operand:XF 1 "register_operand" "u")]
15477 UNSPEC_FYL2X))
15478 (clobber (match_scratch:DF 3 "=1"))]
15479 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15480 && flag_unsafe_math_optimizations"
15481 "fyl2x"
15482 [(set_attr "type" "fpspc")
15483 (set_attr "mode" "DF")])
15484
15485 (define_insn "*fyl2x_xf3"
15486 [(set (match_operand:XF 0 "register_operand" "=f")
15487 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15488 (match_operand:XF 1 "register_operand" "u")]
15489 UNSPEC_FYL2X))
15490 (clobber (match_scratch:XF 3 "=1"))]
15491 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15492 && flag_unsafe_math_optimizations"
15493 "fyl2x"
15494 [(set_attr "type" "fpspc")
15495 (set_attr "mode" "XF")])
15496
15497 (define_expand "logsf2"
15498 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15499 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15500 (match_dup 2)] UNSPEC_FYL2X))
15501 (clobber (match_scratch:SF 3 ""))])]
15502 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15503 && flag_unsafe_math_optimizations"
15504 {
15505 rtx temp;
15506
15507 operands[2] = gen_reg_rtx (XFmode);
15508 temp = standard_80387_constant_rtx (4); /* fldln2 */
15509 emit_move_insn (operands[2], temp);
15510 })
15511
15512 (define_expand "logdf2"
15513 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15514 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15515 (match_dup 2)] UNSPEC_FYL2X))
15516 (clobber (match_scratch:DF 3 ""))])]
15517 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15518 && flag_unsafe_math_optimizations"
15519 {
15520 rtx temp;
15521
15522 operands[2] = gen_reg_rtx (XFmode);
15523 temp = standard_80387_constant_rtx (4); /* fldln2 */
15524 emit_move_insn (operands[2], temp);
15525 })
15526
15527 (define_expand "logxf2"
15528 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15529 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15530 (match_dup 2)] UNSPEC_FYL2X))
15531 (clobber (match_scratch:XF 3 ""))])]
15532 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15533 && flag_unsafe_math_optimizations"
15534 {
15535 rtx temp;
15536
15537 operands[2] = gen_reg_rtx (XFmode);
15538 temp = standard_80387_constant_rtx (4); /* fldln2 */
15539 emit_move_insn (operands[2], temp);
15540 })
15541
15542 (define_expand "log10sf2"
15543 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15544 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15545 (match_dup 2)] UNSPEC_FYL2X))
15546 (clobber (match_scratch:SF 3 ""))])]
15547 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15548 && flag_unsafe_math_optimizations"
15549 {
15550 rtx temp;
15551
15552 operands[2] = gen_reg_rtx (XFmode);
15553 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15554 emit_move_insn (operands[2], temp);
15555 })
15556
15557 (define_expand "log10df2"
15558 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15559 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15560 (match_dup 2)] UNSPEC_FYL2X))
15561 (clobber (match_scratch:DF 3 ""))])]
15562 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15563 && flag_unsafe_math_optimizations"
15564 {
15565 rtx temp;
15566
15567 operands[2] = gen_reg_rtx (XFmode);
15568 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15569 emit_move_insn (operands[2], temp);
15570 })
15571
15572 (define_expand "log10xf2"
15573 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15574 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15575 (match_dup 2)] UNSPEC_FYL2X))
15576 (clobber (match_scratch:XF 3 ""))])]
15577 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15578 && flag_unsafe_math_optimizations"
15579 {
15580 rtx temp;
15581
15582 operands[2] = gen_reg_rtx (XFmode);
15583 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15584 emit_move_insn (operands[2], temp);
15585 })
15586
15587 (define_expand "log2sf2"
15588 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15589 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15590 (match_dup 2)] UNSPEC_FYL2X))
15591 (clobber (match_scratch:SF 3 ""))])]
15592 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15593 && flag_unsafe_math_optimizations"
15594 {
15595 operands[2] = gen_reg_rtx (XFmode);
15596 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15597
15598 })
15599
15600 (define_expand "log2df2"
15601 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15602 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15603 (match_dup 2)] UNSPEC_FYL2X))
15604 (clobber (match_scratch:DF 3 ""))])]
15605 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15606 && flag_unsafe_math_optimizations"
15607 {
15608 operands[2] = gen_reg_rtx (XFmode);
15609 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15610 })
15611
15612 (define_expand "log2xf2"
15613 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15614 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15615 (match_dup 2)] UNSPEC_FYL2X))
15616 (clobber (match_scratch:XF 3 ""))])]
15617 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15618 && flag_unsafe_math_optimizations"
15619 {
15620 operands[2] = gen_reg_rtx (XFmode);
15621 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15622 })
15623
15624 (define_insn "*fxtractdf3"
15625 [(set (match_operand:DF 0 "register_operand" "=f")
15626 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15627 UNSPEC_XTRACT_FRACT))
15628 (set (match_operand:DF 1 "register_operand" "=u")
15629 (unspec:DF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15630 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15631 && flag_unsafe_math_optimizations"
15632 "fxtract"
15633 [(set_attr "type" "fpspc")
15634 (set_attr "mode" "DF")])
15635
15636 (define_expand "logbdf2"
15637 [(parallel [(set (match_dup 2)
15638 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15639 UNSPEC_XTRACT_FRACT))
15640 (set (match_operand:DF 0 "register_operand" "")
15641 (unspec:DF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15642 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15643 && flag_unsafe_math_optimizations"
15644 {
15645 operands[2] = gen_reg_rtx (DFmode);
15646 })
15647
15648 (define_insn "*fxtractsf3"
15649 [(set (match_operand:SF 0 "register_operand" "=f")
15650 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15651 UNSPEC_XTRACT_FRACT))
15652 (set (match_operand:SF 1 "register_operand" "=u")
15653 (unspec:SF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15654 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15655 && flag_unsafe_math_optimizations"
15656 "fxtract"
15657 [(set_attr "type" "fpspc")
15658 (set_attr "mode" "SF")])
15659
15660 (define_expand "logbsf2"
15661 [(parallel [(set (match_dup 2)
15662 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15663 UNSPEC_XTRACT_FRACT))
15664 (set (match_operand:SF 0 "register_operand" "")
15665 (unspec:SF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15666 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15667 && flag_unsafe_math_optimizations"
15668 {
15669 operands[2] = gen_reg_rtx (SFmode);
15670 })
15671
15672 (define_insn "*fxtractxf3"
15673 [(set (match_operand:XF 0 "register_operand" "=f")
15674 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15675 UNSPEC_XTRACT_FRACT))
15676 (set (match_operand:XF 1 "register_operand" "=u")
15677 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15678 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15679 && flag_unsafe_math_optimizations"
15680 "fxtract"
15681 [(set_attr "type" "fpspc")
15682 (set_attr "mode" "XF")])
15683
15684 (define_expand "logbxf2"
15685 [(parallel [(set (match_dup 2)
15686 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15687 UNSPEC_XTRACT_FRACT))
15688 (set (match_operand:XF 0 "register_operand" "")
15689 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15690 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15691 && flag_unsafe_math_optimizations"
15692 {
15693 operands[2] = gen_reg_rtx (XFmode);
15694 })
15695
15696 (define_expand "ilogbsi2"
15697 [(parallel [(set (match_dup 2)
15698 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15699 UNSPEC_XTRACT_FRACT))
15700 (set (match_operand:XF 3 "register_operand" "")
15701 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15702 (parallel [(set (match_operand:SI 0 "register_operand" "")
15703 (fix:SI (match_dup 3)))
15704 (clobber (reg:CC 17))])]
15705 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15706 && flag_unsafe_math_optimizations"
15707 {
15708 operands[2] = gen_reg_rtx (XFmode);
15709 operands[3] = gen_reg_rtx (XFmode);
15710 })
15711
15712 (define_insn "*frndintxf2"
15713 [(set (match_operand:XF 0 "register_operand" "=f")
15714 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15715 UNSPEC_FRNDINT))]
15716 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15717 && flag_unsafe_math_optimizations"
15718 "frndint"
15719 [(set_attr "type" "fpspc")
15720 (set_attr "mode" "XF")])
15721
15722 (define_insn "*f2xm1xf2"
15723 [(set (match_operand:XF 0 "register_operand" "=f")
15724 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15725 UNSPEC_F2XM1))]
15726 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15727 && flag_unsafe_math_optimizations"
15728 "f2xm1"
15729 [(set_attr "type" "fpspc")
15730 (set_attr "mode" "XF")])
15731
15732 (define_insn "*fscalexf4"
15733 [(set (match_operand:XF 0 "register_operand" "=f")
15734 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15735 (match_operand:XF 3 "register_operand" "1")]
15736 UNSPEC_FSCALE_FRACT))
15737 (set (match_operand:XF 1 "register_operand" "=u")
15738 (unspec:XF [(match_dup 2) (match_dup 3)]
15739 UNSPEC_FSCALE_EXP))]
15740 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15741 && flag_unsafe_math_optimizations"
15742 "fscale"
15743 [(set_attr "type" "fpspc")
15744 (set_attr "mode" "DF")])
15745
15746 (define_expand "expsf2"
15747 [(set (match_dup 2)
15748 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15749 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15750 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15751 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15752 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15753 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15754 (parallel [(set (match_dup 10)
15755 (unspec:XF [(match_dup 9) (match_dup 5)]
15756 UNSPEC_FSCALE_FRACT))
15757 (set (match_dup 11)
15758 (unspec:XF [(match_dup 9) (match_dup 5)]
15759 UNSPEC_FSCALE_EXP))])
15760 (set (match_operand:SF 0 "register_operand" "")
15761 (float_truncate:SF (match_dup 10)))]
15762 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15763 && flag_unsafe_math_optimizations"
15764 {
15765 rtx temp;
15766 int i;
15767
15768 for (i=2; i<12; i++)
15769 operands[i] = gen_reg_rtx (XFmode);
15770 temp = standard_80387_constant_rtx (5); /* fldl2e */
15771 emit_move_insn (operands[3], temp);
15772 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15773 })
15774
15775 (define_expand "expdf2"
15776 [(set (match_dup 2)
15777 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15778 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15779 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15780 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15781 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15782 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15783 (parallel [(set (match_dup 10)
15784 (unspec:XF [(match_dup 9) (match_dup 5)]
15785 UNSPEC_FSCALE_FRACT))
15786 (set (match_dup 11)
15787 (unspec:XF [(match_dup 9) (match_dup 5)]
15788 UNSPEC_FSCALE_EXP))])
15789 (set (match_operand:DF 0 "register_operand" "")
15790 (float_truncate:DF (match_dup 10)))]
15791 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15792 && flag_unsafe_math_optimizations"
15793 {
15794 rtx temp;
15795 int i;
15796
15797 for (i=2; i<12; i++)
15798 operands[i] = gen_reg_rtx (XFmode);
15799 temp = standard_80387_constant_rtx (5); /* fldl2e */
15800 emit_move_insn (operands[3], temp);
15801 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15802 })
15803
15804 (define_expand "expxf2"
15805 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15806 (match_dup 2)))
15807 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15808 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15809 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15810 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15811 (parallel [(set (match_operand:XF 0 "register_operand" "")
15812 (unspec:XF [(match_dup 8) (match_dup 4)]
15813 UNSPEC_FSCALE_FRACT))
15814 (set (match_dup 9)
15815 (unspec:XF [(match_dup 8) (match_dup 4)]
15816 UNSPEC_FSCALE_EXP))])]
15817 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15818 && flag_unsafe_math_optimizations"
15819 {
15820 rtx temp;
15821 int i;
15822
15823 for (i=2; i<10; i++)
15824 operands[i] = gen_reg_rtx (XFmode);
15825 temp = standard_80387_constant_rtx (5); /* fldl2e */
15826 emit_move_insn (operands[2], temp);
15827 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15828 })
15829
15830 (define_expand "exp10sf2"
15831 [(set (match_dup 2)
15832 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15833 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15834 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15835 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15836 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15837 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15838 (parallel [(set (match_dup 10)
15839 (unspec:XF [(match_dup 9) (match_dup 5)]
15840 UNSPEC_FSCALE_FRACT))
15841 (set (match_dup 11)
15842 (unspec:XF [(match_dup 9) (match_dup 5)]
15843 UNSPEC_FSCALE_EXP))])
15844 (set (match_operand:SF 0 "register_operand" "")
15845 (float_truncate:SF (match_dup 10)))]
15846 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15847 && flag_unsafe_math_optimizations"
15848 {
15849 rtx temp;
15850 int i;
15851
15852 for (i=2; i<12; i++)
15853 operands[i] = gen_reg_rtx (XFmode);
15854 temp = standard_80387_constant_rtx (6); /* fldl2t */
15855 emit_move_insn (operands[3], temp);
15856 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15857 })
15858
15859 (define_expand "exp10df2"
15860 [(set (match_dup 2)
15861 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15862 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15863 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15864 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15865 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15866 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15867 (parallel [(set (match_dup 10)
15868 (unspec:XF [(match_dup 9) (match_dup 5)]
15869 UNSPEC_FSCALE_FRACT))
15870 (set (match_dup 11)
15871 (unspec:XF [(match_dup 9) (match_dup 5)]
15872 UNSPEC_FSCALE_EXP))])
15873 (set (match_operand:DF 0 "register_operand" "")
15874 (float_truncate:DF (match_dup 10)))]
15875 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15876 && flag_unsafe_math_optimizations"
15877 {
15878 rtx temp;
15879 int i;
15880
15881 for (i=2; i<12; i++)
15882 operands[i] = gen_reg_rtx (XFmode);
15883 temp = standard_80387_constant_rtx (6); /* fldl2t */
15884 emit_move_insn (operands[3], temp);
15885 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15886 })
15887
15888 (define_expand "exp10xf2"
15889 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15890 (match_dup 2)))
15891 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15892 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15893 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15894 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15895 (parallel [(set (match_operand:XF 0 "register_operand" "")
15896 (unspec:XF [(match_dup 8) (match_dup 4)]
15897 UNSPEC_FSCALE_FRACT))
15898 (set (match_dup 9)
15899 (unspec:XF [(match_dup 8) (match_dup 4)]
15900 UNSPEC_FSCALE_EXP))])]
15901 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15902 && flag_unsafe_math_optimizations"
15903 {
15904 rtx temp;
15905 int i;
15906
15907 for (i=2; i<10; i++)
15908 operands[i] = gen_reg_rtx (XFmode);
15909 temp = standard_80387_constant_rtx (6); /* fldl2t */
15910 emit_move_insn (operands[2], temp);
15911 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15912 })
15913
15914 (define_expand "exp2sf2"
15915 [(set (match_dup 2)
15916 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15917 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15918 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15919 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15920 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15921 (parallel [(set (match_dup 8)
15922 (unspec:XF [(match_dup 7) (match_dup 3)]
15923 UNSPEC_FSCALE_FRACT))
15924 (set (match_dup 9)
15925 (unspec:XF [(match_dup 7) (match_dup 3)]
15926 UNSPEC_FSCALE_EXP))])
15927 (set (match_operand:SF 0 "register_operand" "")
15928 (float_truncate:SF (match_dup 8)))]
15929 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15930 && flag_unsafe_math_optimizations"
15931 {
15932 int i;
15933
15934 for (i=2; i<10; i++)
15935 operands[i] = gen_reg_rtx (XFmode);
15936 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15937 })
15938
15939 (define_expand "exp2df2"
15940 [(set (match_dup 2)
15941 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15942 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15943 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15944 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15945 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15946 (parallel [(set (match_dup 8)
15947 (unspec:XF [(match_dup 7) (match_dup 3)]
15948 UNSPEC_FSCALE_FRACT))
15949 (set (match_dup 9)
15950 (unspec:XF [(match_dup 7) (match_dup 3)]
15951 UNSPEC_FSCALE_EXP))])
15952 (set (match_operand:DF 0 "register_operand" "")
15953 (float_truncate:DF (match_dup 8)))]
15954 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15955 && flag_unsafe_math_optimizations"
15956 {
15957 int i;
15958
15959 for (i=2; i<10; i++)
15960 operands[i] = gen_reg_rtx (XFmode);
15961 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15962 })
15963
15964 (define_expand "exp2xf2"
15965 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15966 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15967 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15968 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15969 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15970 (parallel [(set (match_operand:XF 0 "register_operand" "")
15971 (unspec:XF [(match_dup 7) (match_dup 3)]
15972 UNSPEC_FSCALE_FRACT))
15973 (set (match_dup 8)
15974 (unspec:XF [(match_dup 7) (match_dup 3)]
15975 UNSPEC_FSCALE_EXP))])]
15976 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15977 && flag_unsafe_math_optimizations"
15978 {
15979 int i;
15980
15981 for (i=2; i<9; i++)
15982 operands[i] = gen_reg_rtx (XFmode);
15983 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15984 })
15985 \f
15986 ;; Block operation instructions
15987
15988 (define_insn "cld"
15989 [(set (reg:SI 19) (const_int 0))]
15990 ""
15991 "cld"
15992 [(set_attr "type" "cld")])
15993
15994 (define_expand "movstrsi"
15995 [(use (match_operand:BLK 0 "memory_operand" ""))
15996 (use (match_operand:BLK 1 "memory_operand" ""))
15997 (use (match_operand:SI 2 "nonmemory_operand" ""))
15998 (use (match_operand:SI 3 "const_int_operand" ""))]
15999 "! optimize_size"
16000 {
16001 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16002 DONE;
16003 else
16004 FAIL;
16005 })
16006
16007 (define_expand "movstrdi"
16008 [(use (match_operand:BLK 0 "memory_operand" ""))
16009 (use (match_operand:BLK 1 "memory_operand" ""))
16010 (use (match_operand:DI 2 "nonmemory_operand" ""))
16011 (use (match_operand:DI 3 "const_int_operand" ""))]
16012 "TARGET_64BIT"
16013 {
16014 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16015 DONE;
16016 else
16017 FAIL;
16018 })
16019
16020 ;; Most CPUs don't like single string operations
16021 ;; Handle this case here to simplify previous expander.
16022
16023 (define_expand "strmov"
16024 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16025 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16026 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16027 (clobber (reg:CC 17))])
16028 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16029 (clobber (reg:CC 17))])]
16030 ""
16031 {
16032 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16033
16034 /* If .md ever supports :P for Pmode, these can be directly
16035 in the pattern above. */
16036 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16037 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16038
16039 if (TARGET_SINGLE_STRINGOP || optimize_size)
16040 {
16041 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16042 operands[2], operands[3],
16043 operands[5], operands[6]));
16044 DONE;
16045 }
16046
16047 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16048 })
16049
16050 (define_expand "strmov_singleop"
16051 [(parallel [(set (match_operand 1 "memory_operand" "")
16052 (match_operand 3 "memory_operand" ""))
16053 (set (match_operand 0 "register_operand" "")
16054 (match_operand 4 "" ""))
16055 (set (match_operand 2 "register_operand" "")
16056 (match_operand 5 "" ""))
16057 (use (reg:SI 19))])]
16058 "TARGET_SINGLE_STRINGOP || optimize_size"
16059 "")
16060
16061 (define_insn "*strmovdi_rex_1"
16062 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16063 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16064 (set (match_operand:DI 0 "register_operand" "=D")
16065 (plus:DI (match_dup 2)
16066 (const_int 8)))
16067 (set (match_operand:DI 1 "register_operand" "=S")
16068 (plus:DI (match_dup 3)
16069 (const_int 8)))
16070 (use (reg:SI 19))]
16071 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16072 "movsq"
16073 [(set_attr "type" "str")
16074 (set_attr "mode" "DI")
16075 (set_attr "memory" "both")])
16076
16077 (define_insn "*strmovsi_1"
16078 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16079 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16080 (set (match_operand:SI 0 "register_operand" "=D")
16081 (plus:SI (match_dup 2)
16082 (const_int 4)))
16083 (set (match_operand:SI 1 "register_operand" "=S")
16084 (plus:SI (match_dup 3)
16085 (const_int 4)))
16086 (use (reg:SI 19))]
16087 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16088 "{movsl|movsd}"
16089 [(set_attr "type" "str")
16090 (set_attr "mode" "SI")
16091 (set_attr "memory" "both")])
16092
16093 (define_insn "*strmovsi_rex_1"
16094 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16095 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16096 (set (match_operand:DI 0 "register_operand" "=D")
16097 (plus:DI (match_dup 2)
16098 (const_int 4)))
16099 (set (match_operand:DI 1 "register_operand" "=S")
16100 (plus:DI (match_dup 3)
16101 (const_int 4)))
16102 (use (reg:SI 19))]
16103 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16104 "{movsl|movsd}"
16105 [(set_attr "type" "str")
16106 (set_attr "mode" "SI")
16107 (set_attr "memory" "both")])
16108
16109 (define_insn "*strmovhi_1"
16110 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16111 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16112 (set (match_operand:SI 0 "register_operand" "=D")
16113 (plus:SI (match_dup 2)
16114 (const_int 2)))
16115 (set (match_operand:SI 1 "register_operand" "=S")
16116 (plus:SI (match_dup 3)
16117 (const_int 2)))
16118 (use (reg:SI 19))]
16119 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16120 "movsw"
16121 [(set_attr "type" "str")
16122 (set_attr "memory" "both")
16123 (set_attr "mode" "HI")])
16124
16125 (define_insn "*strmovhi_rex_1"
16126 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16127 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16128 (set (match_operand:DI 0 "register_operand" "=D")
16129 (plus:DI (match_dup 2)
16130 (const_int 2)))
16131 (set (match_operand:DI 1 "register_operand" "=S")
16132 (plus:DI (match_dup 3)
16133 (const_int 2)))
16134 (use (reg:SI 19))]
16135 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16136 "movsw"
16137 [(set_attr "type" "str")
16138 (set_attr "memory" "both")
16139 (set_attr "mode" "HI")])
16140
16141 (define_insn "*strmovqi_1"
16142 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16143 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16144 (set (match_operand:SI 0 "register_operand" "=D")
16145 (plus:SI (match_dup 2)
16146 (const_int 1)))
16147 (set (match_operand:SI 1 "register_operand" "=S")
16148 (plus:SI (match_dup 3)
16149 (const_int 1)))
16150 (use (reg:SI 19))]
16151 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16152 "movsb"
16153 [(set_attr "type" "str")
16154 (set_attr "memory" "both")
16155 (set_attr "mode" "QI")])
16156
16157 (define_insn "*strmovqi_rex_1"
16158 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16159 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16160 (set (match_operand:DI 0 "register_operand" "=D")
16161 (plus:DI (match_dup 2)
16162 (const_int 1)))
16163 (set (match_operand:DI 1 "register_operand" "=S")
16164 (plus:DI (match_dup 3)
16165 (const_int 1)))
16166 (use (reg:SI 19))]
16167 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16168 "movsb"
16169 [(set_attr "type" "str")
16170 (set_attr "memory" "both")
16171 (set_attr "mode" "QI")])
16172
16173 (define_expand "rep_mov"
16174 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16175 (set (match_operand 0 "register_operand" "")
16176 (match_operand 5 "" ""))
16177 (set (match_operand 2 "register_operand" "")
16178 (match_operand 6 "" ""))
16179 (set (match_operand 1 "memory_operand" "")
16180 (match_operand 3 "memory_operand" ""))
16181 (use (match_dup 4))
16182 (use (reg:SI 19))])]
16183 ""
16184 "")
16185
16186 (define_insn "*rep_movdi_rex64"
16187 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16188 (set (match_operand:DI 0 "register_operand" "=D")
16189 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16190 (const_int 3))
16191 (match_operand:DI 3 "register_operand" "0")))
16192 (set (match_operand:DI 1 "register_operand" "=S")
16193 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16194 (match_operand:DI 4 "register_operand" "1")))
16195 (set (mem:BLK (match_dup 3))
16196 (mem:BLK (match_dup 4)))
16197 (use (match_dup 5))
16198 (use (reg:SI 19))]
16199 "TARGET_64BIT"
16200 "{rep\;movsq|rep movsq}"
16201 [(set_attr "type" "str")
16202 (set_attr "prefix_rep" "1")
16203 (set_attr "memory" "both")
16204 (set_attr "mode" "DI")])
16205
16206 (define_insn "*rep_movsi"
16207 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16208 (set (match_operand:SI 0 "register_operand" "=D")
16209 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16210 (const_int 2))
16211 (match_operand:SI 3 "register_operand" "0")))
16212 (set (match_operand:SI 1 "register_operand" "=S")
16213 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16214 (match_operand:SI 4 "register_operand" "1")))
16215 (set (mem:BLK (match_dup 3))
16216 (mem:BLK (match_dup 4)))
16217 (use (match_dup 5))
16218 (use (reg:SI 19))]
16219 "!TARGET_64BIT"
16220 "{rep\;movsl|rep movsd}"
16221 [(set_attr "type" "str")
16222 (set_attr "prefix_rep" "1")
16223 (set_attr "memory" "both")
16224 (set_attr "mode" "SI")])
16225
16226 (define_insn "*rep_movsi_rex64"
16227 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16228 (set (match_operand:DI 0 "register_operand" "=D")
16229 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16230 (const_int 2))
16231 (match_operand:DI 3 "register_operand" "0")))
16232 (set (match_operand:DI 1 "register_operand" "=S")
16233 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16234 (match_operand:DI 4 "register_operand" "1")))
16235 (set (mem:BLK (match_dup 3))
16236 (mem:BLK (match_dup 4)))
16237 (use (match_dup 5))
16238 (use (reg:SI 19))]
16239 "TARGET_64BIT"
16240 "{rep\;movsl|rep movsd}"
16241 [(set_attr "type" "str")
16242 (set_attr "prefix_rep" "1")
16243 (set_attr "memory" "both")
16244 (set_attr "mode" "SI")])
16245
16246 (define_insn "*rep_movqi"
16247 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16248 (set (match_operand:SI 0 "register_operand" "=D")
16249 (plus:SI (match_operand:SI 3 "register_operand" "0")
16250 (match_operand:SI 5 "register_operand" "2")))
16251 (set (match_operand:SI 1 "register_operand" "=S")
16252 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16253 (set (mem:BLK (match_dup 3))
16254 (mem:BLK (match_dup 4)))
16255 (use (match_dup 5))
16256 (use (reg:SI 19))]
16257 "!TARGET_64BIT"
16258 "{rep\;movsb|rep movsb}"
16259 [(set_attr "type" "str")
16260 (set_attr "prefix_rep" "1")
16261 (set_attr "memory" "both")
16262 (set_attr "mode" "SI")])
16263
16264 (define_insn "*rep_movqi_rex64"
16265 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16266 (set (match_operand:DI 0 "register_operand" "=D")
16267 (plus:DI (match_operand:DI 3 "register_operand" "0")
16268 (match_operand:DI 5 "register_operand" "2")))
16269 (set (match_operand:DI 1 "register_operand" "=S")
16270 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16271 (set (mem:BLK (match_dup 3))
16272 (mem:BLK (match_dup 4)))
16273 (use (match_dup 5))
16274 (use (reg:SI 19))]
16275 "TARGET_64BIT"
16276 "{rep\;movsb|rep movsb}"
16277 [(set_attr "type" "str")
16278 (set_attr "prefix_rep" "1")
16279 (set_attr "memory" "both")
16280 (set_attr "mode" "SI")])
16281
16282 (define_expand "clrstrsi"
16283 [(use (match_operand:BLK 0 "memory_operand" ""))
16284 (use (match_operand:SI 1 "nonmemory_operand" ""))
16285 (use (match_operand 2 "const_int_operand" ""))]
16286 ""
16287 {
16288 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16289 DONE;
16290 else
16291 FAIL;
16292 })
16293
16294 (define_expand "clrstrdi"
16295 [(use (match_operand:BLK 0 "memory_operand" ""))
16296 (use (match_operand:DI 1 "nonmemory_operand" ""))
16297 (use (match_operand 2 "const_int_operand" ""))]
16298 "TARGET_64BIT"
16299 {
16300 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16301 DONE;
16302 else
16303 FAIL;
16304 })
16305
16306 ;; Most CPUs don't like single string operations
16307 ;; Handle this case here to simplify previous expander.
16308
16309 (define_expand "strset"
16310 [(set (match_operand 1 "memory_operand" "")
16311 (match_operand 2 "register_operand" ""))
16312 (parallel [(set (match_operand 0 "register_operand" "")
16313 (match_dup 3))
16314 (clobber (reg:CC 17))])]
16315 ""
16316 {
16317 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16318 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16319
16320 /* If .md ever supports :P for Pmode, this can be directly
16321 in the pattern above. */
16322 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16323 GEN_INT (GET_MODE_SIZE (GET_MODE
16324 (operands[2]))));
16325 if (TARGET_SINGLE_STRINGOP || optimize_size)
16326 {
16327 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16328 operands[3]));
16329 DONE;
16330 }
16331 })
16332
16333 (define_expand "strset_singleop"
16334 [(parallel [(set (match_operand 1 "memory_operand" "")
16335 (match_operand 2 "register_operand" ""))
16336 (set (match_operand 0 "register_operand" "")
16337 (match_operand 3 "" ""))
16338 (use (reg:SI 19))])]
16339 "TARGET_SINGLE_STRINGOP || optimize_size"
16340 "")
16341
16342 (define_insn "*strsetdi_rex_1"
16343 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16344 (match_operand:SI 2 "register_operand" "a"))
16345 (set (match_operand:DI 0 "register_operand" "=D")
16346 (plus:DI (match_dup 1)
16347 (const_int 8)))
16348 (use (reg:SI 19))]
16349 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16350 "stosq"
16351 [(set_attr "type" "str")
16352 (set_attr "memory" "store")
16353 (set_attr "mode" "DI")])
16354
16355 (define_insn "*strsetsi_1"
16356 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16357 (match_operand:SI 2 "register_operand" "a"))
16358 (set (match_operand:SI 0 "register_operand" "=D")
16359 (plus:SI (match_dup 1)
16360 (const_int 4)))
16361 (use (reg:SI 19))]
16362 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16363 "{stosl|stosd}"
16364 [(set_attr "type" "str")
16365 (set_attr "memory" "store")
16366 (set_attr "mode" "SI")])
16367
16368 (define_insn "*strsetsi_rex_1"
16369 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16370 (match_operand:SI 2 "register_operand" "a"))
16371 (set (match_operand:DI 0 "register_operand" "=D")
16372 (plus:DI (match_dup 1)
16373 (const_int 4)))
16374 (use (reg:SI 19))]
16375 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16376 "{stosl|stosd}"
16377 [(set_attr "type" "str")
16378 (set_attr "memory" "store")
16379 (set_attr "mode" "SI")])
16380
16381 (define_insn "*strsethi_1"
16382 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16383 (match_operand:HI 2 "register_operand" "a"))
16384 (set (match_operand:SI 0 "register_operand" "=D")
16385 (plus:SI (match_dup 1)
16386 (const_int 2)))
16387 (use (reg:SI 19))]
16388 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16389 "stosw"
16390 [(set_attr "type" "str")
16391 (set_attr "memory" "store")
16392 (set_attr "mode" "HI")])
16393
16394 (define_insn "*strsethi_rex_1"
16395 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16396 (match_operand:HI 2 "register_operand" "a"))
16397 (set (match_operand:DI 0 "register_operand" "=D")
16398 (plus:DI (match_dup 1)
16399 (const_int 2)))
16400 (use (reg:SI 19))]
16401 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16402 "stosw"
16403 [(set_attr "type" "str")
16404 (set_attr "memory" "store")
16405 (set_attr "mode" "HI")])
16406
16407 (define_insn "*strsetqi_1"
16408 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16409 (match_operand:QI 2 "register_operand" "a"))
16410 (set (match_operand:SI 0 "register_operand" "=D")
16411 (plus:SI (match_dup 1)
16412 (const_int 1)))
16413 (use (reg:SI 19))]
16414 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16415 "stosb"
16416 [(set_attr "type" "str")
16417 (set_attr "memory" "store")
16418 (set_attr "mode" "QI")])
16419
16420 (define_insn "*strsetqi_rex_1"
16421 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16422 (match_operand:QI 2 "register_operand" "a"))
16423 (set (match_operand:DI 0 "register_operand" "=D")
16424 (plus:DI (match_dup 1)
16425 (const_int 1)))
16426 (use (reg:SI 19))]
16427 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16428 "stosb"
16429 [(set_attr "type" "str")
16430 (set_attr "memory" "store")
16431 (set_attr "mode" "QI")])
16432
16433 (define_expand "rep_stos"
16434 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16435 (set (match_operand 0 "register_operand" "")
16436 (match_operand 4 "" ""))
16437 (set (match_operand 2 "memory_operand" "") (const_int 0))
16438 (use (match_operand 3 "register_operand" ""))
16439 (use (match_dup 1))
16440 (use (reg:SI 19))])]
16441 ""
16442 "")
16443
16444 (define_insn "*rep_stosdi_rex64"
16445 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16446 (set (match_operand:DI 0 "register_operand" "=D")
16447 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16448 (const_int 3))
16449 (match_operand:DI 3 "register_operand" "0")))
16450 (set (mem:BLK (match_dup 3))
16451 (const_int 0))
16452 (use (match_operand:DI 2 "register_operand" "a"))
16453 (use (match_dup 4))
16454 (use (reg:SI 19))]
16455 "TARGET_64BIT"
16456 "{rep\;stosq|rep stosq}"
16457 [(set_attr "type" "str")
16458 (set_attr "prefix_rep" "1")
16459 (set_attr "memory" "store")
16460 (set_attr "mode" "DI")])
16461
16462 (define_insn "*rep_stossi"
16463 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16464 (set (match_operand:SI 0 "register_operand" "=D")
16465 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16466 (const_int 2))
16467 (match_operand:SI 3 "register_operand" "0")))
16468 (set (mem:BLK (match_dup 3))
16469 (const_int 0))
16470 (use (match_operand:SI 2 "register_operand" "a"))
16471 (use (match_dup 4))
16472 (use (reg:SI 19))]
16473 "!TARGET_64BIT"
16474 "{rep\;stosl|rep stosd}"
16475 [(set_attr "type" "str")
16476 (set_attr "prefix_rep" "1")
16477 (set_attr "memory" "store")
16478 (set_attr "mode" "SI")])
16479
16480 (define_insn "*rep_stossi_rex64"
16481 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16482 (set (match_operand:DI 0 "register_operand" "=D")
16483 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16484 (const_int 2))
16485 (match_operand:DI 3 "register_operand" "0")))
16486 (set (mem:BLK (match_dup 3))
16487 (const_int 0))
16488 (use (match_operand:SI 2 "register_operand" "a"))
16489 (use (match_dup 4))
16490 (use (reg:SI 19))]
16491 "TARGET_64BIT"
16492 "{rep\;stosl|rep stosd}"
16493 [(set_attr "type" "str")
16494 (set_attr "prefix_rep" "1")
16495 (set_attr "memory" "store")
16496 (set_attr "mode" "SI")])
16497
16498 (define_insn "*rep_stosqi"
16499 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16500 (set (match_operand:SI 0 "register_operand" "=D")
16501 (plus:SI (match_operand:SI 3 "register_operand" "0")
16502 (match_operand:SI 4 "register_operand" "1")))
16503 (set (mem:BLK (match_dup 3))
16504 (const_int 0))
16505 (use (match_operand:QI 2 "register_operand" "a"))
16506 (use (match_dup 4))
16507 (use (reg:SI 19))]
16508 "!TARGET_64BIT"
16509 "{rep\;stosb|rep stosb}"
16510 [(set_attr "type" "str")
16511 (set_attr "prefix_rep" "1")
16512 (set_attr "memory" "store")
16513 (set_attr "mode" "QI")])
16514
16515 (define_insn "*rep_stosqi_rex64"
16516 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16517 (set (match_operand:DI 0 "register_operand" "=D")
16518 (plus:DI (match_operand:DI 3 "register_operand" "0")
16519 (match_operand:DI 4 "register_operand" "1")))
16520 (set (mem:BLK (match_dup 3))
16521 (const_int 0))
16522 (use (match_operand:QI 2 "register_operand" "a"))
16523 (use (match_dup 4))
16524 (use (reg:SI 19))]
16525 "TARGET_64BIT"
16526 "{rep\;stosb|rep stosb}"
16527 [(set_attr "type" "str")
16528 (set_attr "prefix_rep" "1")
16529 (set_attr "memory" "store")
16530 (set_attr "mode" "QI")])
16531
16532 (define_expand "cmpstrsi"
16533 [(set (match_operand:SI 0 "register_operand" "")
16534 (compare:SI (match_operand:BLK 1 "general_operand" "")
16535 (match_operand:BLK 2 "general_operand" "")))
16536 (use (match_operand 3 "general_operand" ""))
16537 (use (match_operand 4 "immediate_operand" ""))]
16538 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16539 {
16540 rtx addr1, addr2, out, outlow, count, countreg, align;
16541
16542 /* Can't use this if the user has appropriated esi or edi. */
16543 if (global_regs[4] || global_regs[5])
16544 FAIL;
16545
16546 out = operands[0];
16547 if (GET_CODE (out) != REG)
16548 out = gen_reg_rtx (SImode);
16549
16550 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16551 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16552 if (addr1 != XEXP (operands[1], 0))
16553 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16554 if (addr2 != XEXP (operands[2], 0))
16555 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16556
16557 count = operands[3];
16558 countreg = ix86_zero_extend_to_Pmode (count);
16559
16560 /* %%% Iff we are testing strict equality, we can use known alignment
16561 to good advantage. This may be possible with combine, particularly
16562 once cc0 is dead. */
16563 align = operands[4];
16564
16565 emit_insn (gen_cld ());
16566 if (GET_CODE (count) == CONST_INT)
16567 {
16568 if (INTVAL (count) == 0)
16569 {
16570 emit_move_insn (operands[0], const0_rtx);
16571 DONE;
16572 }
16573 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16574 operands[1], operands[2]));
16575 }
16576 else
16577 {
16578 if (TARGET_64BIT)
16579 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16580 else
16581 emit_insn (gen_cmpsi_1 (countreg, countreg));
16582 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16583 operands[1], operands[2]));
16584 }
16585
16586 outlow = gen_lowpart (QImode, out);
16587 emit_insn (gen_cmpintqi (outlow));
16588 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16589
16590 if (operands[0] != out)
16591 emit_move_insn (operands[0], out);
16592
16593 DONE;
16594 })
16595
16596 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16597
16598 (define_expand "cmpintqi"
16599 [(set (match_dup 1)
16600 (gtu:QI (reg:CC 17) (const_int 0)))
16601 (set (match_dup 2)
16602 (ltu:QI (reg:CC 17) (const_int 0)))
16603 (parallel [(set (match_operand:QI 0 "register_operand" "")
16604 (minus:QI (match_dup 1)
16605 (match_dup 2)))
16606 (clobber (reg:CC 17))])]
16607 ""
16608 "operands[1] = gen_reg_rtx (QImode);
16609 operands[2] = gen_reg_rtx (QImode);")
16610
16611 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16612 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16613
16614 (define_expand "cmpstrqi_nz_1"
16615 [(parallel [(set (reg:CC 17)
16616 (compare:CC (match_operand 4 "memory_operand" "")
16617 (match_operand 5 "memory_operand" "")))
16618 (use (match_operand 2 "register_operand" ""))
16619 (use (match_operand:SI 3 "immediate_operand" ""))
16620 (use (reg:SI 19))
16621 (clobber (match_operand 0 "register_operand" ""))
16622 (clobber (match_operand 1 "register_operand" ""))
16623 (clobber (match_dup 2))])]
16624 ""
16625 "")
16626
16627 (define_insn "*cmpstrqi_nz_1"
16628 [(set (reg:CC 17)
16629 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16630 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16631 (use (match_operand:SI 6 "register_operand" "2"))
16632 (use (match_operand:SI 3 "immediate_operand" "i"))
16633 (use (reg:SI 19))
16634 (clobber (match_operand:SI 0 "register_operand" "=S"))
16635 (clobber (match_operand:SI 1 "register_operand" "=D"))
16636 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16637 "!TARGET_64BIT"
16638 "repz{\;| }cmpsb"
16639 [(set_attr "type" "str")
16640 (set_attr "mode" "QI")
16641 (set_attr "prefix_rep" "1")])
16642
16643 (define_insn "*cmpstrqi_nz_rex_1"
16644 [(set (reg:CC 17)
16645 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16646 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16647 (use (match_operand:DI 6 "register_operand" "2"))
16648 (use (match_operand:SI 3 "immediate_operand" "i"))
16649 (use (reg:SI 19))
16650 (clobber (match_operand:DI 0 "register_operand" "=S"))
16651 (clobber (match_operand:DI 1 "register_operand" "=D"))
16652 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16653 "TARGET_64BIT"
16654 "repz{\;| }cmpsb"
16655 [(set_attr "type" "str")
16656 (set_attr "mode" "QI")
16657 (set_attr "prefix_rep" "1")])
16658
16659 ;; The same, but the count is not known to not be zero.
16660
16661 (define_expand "cmpstrqi_1"
16662 [(parallel [(set (reg:CC 17)
16663 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16664 (const_int 0))
16665 (compare:CC (match_operand 4 "memory_operand" "")
16666 (match_operand 5 "memory_operand" ""))
16667 (const_int 0)))
16668 (use (match_operand:SI 3 "immediate_operand" ""))
16669 (use (reg:CC 17))
16670 (use (reg:SI 19))
16671 (clobber (match_operand 0 "register_operand" ""))
16672 (clobber (match_operand 1 "register_operand" ""))
16673 (clobber (match_dup 2))])]
16674 ""
16675 "")
16676
16677 (define_insn "*cmpstrqi_1"
16678 [(set (reg:CC 17)
16679 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16680 (const_int 0))
16681 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16682 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16683 (const_int 0)))
16684 (use (match_operand:SI 3 "immediate_operand" "i"))
16685 (use (reg:CC 17))
16686 (use (reg:SI 19))
16687 (clobber (match_operand:SI 0 "register_operand" "=S"))
16688 (clobber (match_operand:SI 1 "register_operand" "=D"))
16689 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16690 "!TARGET_64BIT"
16691 "repz{\;| }cmpsb"
16692 [(set_attr "type" "str")
16693 (set_attr "mode" "QI")
16694 (set_attr "prefix_rep" "1")])
16695
16696 (define_insn "*cmpstrqi_rex_1"
16697 [(set (reg:CC 17)
16698 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16699 (const_int 0))
16700 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16701 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16702 (const_int 0)))
16703 (use (match_operand:SI 3 "immediate_operand" "i"))
16704 (use (reg:CC 17))
16705 (use (reg:SI 19))
16706 (clobber (match_operand:DI 0 "register_operand" "=S"))
16707 (clobber (match_operand:DI 1 "register_operand" "=D"))
16708 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16709 "TARGET_64BIT"
16710 "repz{\;| }cmpsb"
16711 [(set_attr "type" "str")
16712 (set_attr "mode" "QI")
16713 (set_attr "prefix_rep" "1")])
16714
16715 (define_expand "strlensi"
16716 [(set (match_operand:SI 0 "register_operand" "")
16717 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16718 (match_operand:QI 2 "immediate_operand" "")
16719 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16720 ""
16721 {
16722 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16723 DONE;
16724 else
16725 FAIL;
16726 })
16727
16728 (define_expand "strlendi"
16729 [(set (match_operand:DI 0 "register_operand" "")
16730 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16731 (match_operand:QI 2 "immediate_operand" "")
16732 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16733 ""
16734 {
16735 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16736 DONE;
16737 else
16738 FAIL;
16739 })
16740
16741 (define_expand "strlenqi_1"
16742 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16743 (use (reg:SI 19))
16744 (clobber (match_operand 1 "register_operand" ""))
16745 (clobber (reg:CC 17))])]
16746 ""
16747 "")
16748
16749 (define_insn "*strlenqi_1"
16750 [(set (match_operand:SI 0 "register_operand" "=&c")
16751 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16752 (match_operand:QI 2 "register_operand" "a")
16753 (match_operand:SI 3 "immediate_operand" "i")
16754 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16755 (use (reg:SI 19))
16756 (clobber (match_operand:SI 1 "register_operand" "=D"))
16757 (clobber (reg:CC 17))]
16758 "!TARGET_64BIT"
16759 "repnz{\;| }scasb"
16760 [(set_attr "type" "str")
16761 (set_attr "mode" "QI")
16762 (set_attr "prefix_rep" "1")])
16763
16764 (define_insn "*strlenqi_rex_1"
16765 [(set (match_operand:DI 0 "register_operand" "=&c")
16766 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16767 (match_operand:QI 2 "register_operand" "a")
16768 (match_operand:DI 3 "immediate_operand" "i")
16769 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16770 (use (reg:SI 19))
16771 (clobber (match_operand:DI 1 "register_operand" "=D"))
16772 (clobber (reg:CC 17))]
16773 "TARGET_64BIT"
16774 "repnz{\;| }scasb"
16775 [(set_attr "type" "str")
16776 (set_attr "mode" "QI")
16777 (set_attr "prefix_rep" "1")])
16778
16779 ;; Peephole optimizations to clean up after cmpstr*. This should be
16780 ;; handled in combine, but it is not currently up to the task.
16781 ;; When used for their truth value, the cmpstr* expanders generate
16782 ;; code like this:
16783 ;;
16784 ;; repz cmpsb
16785 ;; seta %al
16786 ;; setb %dl
16787 ;; cmpb %al, %dl
16788 ;; jcc label
16789 ;;
16790 ;; The intermediate three instructions are unnecessary.
16791
16792 ;; This one handles cmpstr*_nz_1...
16793 (define_peephole2
16794 [(parallel[
16795 (set (reg:CC 17)
16796 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16797 (mem:BLK (match_operand 5 "register_operand" ""))))
16798 (use (match_operand 6 "register_operand" ""))
16799 (use (match_operand:SI 3 "immediate_operand" ""))
16800 (use (reg:SI 19))
16801 (clobber (match_operand 0 "register_operand" ""))
16802 (clobber (match_operand 1 "register_operand" ""))
16803 (clobber (match_operand 2 "register_operand" ""))])
16804 (set (match_operand:QI 7 "register_operand" "")
16805 (gtu:QI (reg:CC 17) (const_int 0)))
16806 (set (match_operand:QI 8 "register_operand" "")
16807 (ltu:QI (reg:CC 17) (const_int 0)))
16808 (set (reg 17)
16809 (compare (match_dup 7) (match_dup 8)))
16810 ]
16811 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16812 [(parallel[
16813 (set (reg:CC 17)
16814 (compare:CC (mem:BLK (match_dup 4))
16815 (mem:BLK (match_dup 5))))
16816 (use (match_dup 6))
16817 (use (match_dup 3))
16818 (use (reg:SI 19))
16819 (clobber (match_dup 0))
16820 (clobber (match_dup 1))
16821 (clobber (match_dup 2))])]
16822 "")
16823
16824 ;; ...and this one handles cmpstr*_1.
16825 (define_peephole2
16826 [(parallel[
16827 (set (reg:CC 17)
16828 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16829 (const_int 0))
16830 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16831 (mem:BLK (match_operand 5 "register_operand" "")))
16832 (const_int 0)))
16833 (use (match_operand:SI 3 "immediate_operand" ""))
16834 (use (reg:CC 17))
16835 (use (reg:SI 19))
16836 (clobber (match_operand 0 "register_operand" ""))
16837 (clobber (match_operand 1 "register_operand" ""))
16838 (clobber (match_operand 2 "register_operand" ""))])
16839 (set (match_operand:QI 7 "register_operand" "")
16840 (gtu:QI (reg:CC 17) (const_int 0)))
16841 (set (match_operand:QI 8 "register_operand" "")
16842 (ltu:QI (reg:CC 17) (const_int 0)))
16843 (set (reg 17)
16844 (compare (match_dup 7) (match_dup 8)))
16845 ]
16846 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16847 [(parallel[
16848 (set (reg:CC 17)
16849 (if_then_else:CC (ne (match_dup 6)
16850 (const_int 0))
16851 (compare:CC (mem:BLK (match_dup 4))
16852 (mem:BLK (match_dup 5)))
16853 (const_int 0)))
16854 (use (match_dup 3))
16855 (use (reg:CC 17))
16856 (use (reg:SI 19))
16857 (clobber (match_dup 0))
16858 (clobber (match_dup 1))
16859 (clobber (match_dup 2))])]
16860 "")
16861
16862
16863 \f
16864 ;; Conditional move instructions.
16865
16866 (define_expand "movdicc"
16867 [(set (match_operand:DI 0 "register_operand" "")
16868 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16869 (match_operand:DI 2 "general_operand" "")
16870 (match_operand:DI 3 "general_operand" "")))]
16871 "TARGET_64BIT"
16872 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16873
16874 (define_insn "x86_movdicc_0_m1_rex64"
16875 [(set (match_operand:DI 0 "register_operand" "=r")
16876 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16877 (const_int -1)
16878 (const_int 0)))
16879 (clobber (reg:CC 17))]
16880 "TARGET_64BIT"
16881 "sbb{q}\t%0, %0"
16882 ; Since we don't have the proper number of operands for an alu insn,
16883 ; fill in all the blanks.
16884 [(set_attr "type" "alu")
16885 (set_attr "pent_pair" "pu")
16886 (set_attr "memory" "none")
16887 (set_attr "imm_disp" "false")
16888 (set_attr "mode" "DI")
16889 (set_attr "length_immediate" "0")])
16890
16891 (define_insn "movdicc_c_rex64"
16892 [(set (match_operand:DI 0 "register_operand" "=r,r")
16893 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16894 [(reg 17) (const_int 0)])
16895 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16896 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16897 "TARGET_64BIT && TARGET_CMOVE
16898 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16899 "@
16900 cmov%O2%C1\t{%2, %0|%0, %2}
16901 cmov%O2%c1\t{%3, %0|%0, %3}"
16902 [(set_attr "type" "icmov")
16903 (set_attr "mode" "DI")])
16904
16905 (define_expand "movsicc"
16906 [(set (match_operand:SI 0 "register_operand" "")
16907 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16908 (match_operand:SI 2 "general_operand" "")
16909 (match_operand:SI 3 "general_operand" "")))]
16910 ""
16911 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16912
16913 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16914 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16915 ;; So just document what we're doing explicitly.
16916
16917 (define_insn "x86_movsicc_0_m1"
16918 [(set (match_operand:SI 0 "register_operand" "=r")
16919 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16920 (const_int -1)
16921 (const_int 0)))
16922 (clobber (reg:CC 17))]
16923 ""
16924 "sbb{l}\t%0, %0"
16925 ; Since we don't have the proper number of operands for an alu insn,
16926 ; fill in all the blanks.
16927 [(set_attr "type" "alu")
16928 (set_attr "pent_pair" "pu")
16929 (set_attr "memory" "none")
16930 (set_attr "imm_disp" "false")
16931 (set_attr "mode" "SI")
16932 (set_attr "length_immediate" "0")])
16933
16934 (define_insn "*movsicc_noc"
16935 [(set (match_operand:SI 0 "register_operand" "=r,r")
16936 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16937 [(reg 17) (const_int 0)])
16938 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16939 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16940 "TARGET_CMOVE
16941 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16942 "@
16943 cmov%O2%C1\t{%2, %0|%0, %2}
16944 cmov%O2%c1\t{%3, %0|%0, %3}"
16945 [(set_attr "type" "icmov")
16946 (set_attr "mode" "SI")])
16947
16948 (define_expand "movhicc"
16949 [(set (match_operand:HI 0 "register_operand" "")
16950 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16951 (match_operand:HI 2 "general_operand" "")
16952 (match_operand:HI 3 "general_operand" "")))]
16953 "TARGET_HIMODE_MATH"
16954 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16955
16956 (define_insn "*movhicc_noc"
16957 [(set (match_operand:HI 0 "register_operand" "=r,r")
16958 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16959 [(reg 17) (const_int 0)])
16960 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16961 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16962 "TARGET_CMOVE
16963 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16964 "@
16965 cmov%O2%C1\t{%2, %0|%0, %2}
16966 cmov%O2%c1\t{%3, %0|%0, %3}"
16967 [(set_attr "type" "icmov")
16968 (set_attr "mode" "HI")])
16969
16970 (define_expand "movqicc"
16971 [(set (match_operand:QI 0 "register_operand" "")
16972 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16973 (match_operand:QI 2 "general_operand" "")
16974 (match_operand:QI 3 "general_operand" "")))]
16975 "TARGET_QIMODE_MATH"
16976 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16977
16978 (define_insn_and_split "*movqicc_noc"
16979 [(set (match_operand:QI 0 "register_operand" "=r,r")
16980 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16981 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16982 (match_operand:QI 2 "register_operand" "r,0")
16983 (match_operand:QI 3 "register_operand" "0,r")))]
16984 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16985 "#"
16986 "&& reload_completed"
16987 [(set (match_dup 0)
16988 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16989 (match_dup 2)
16990 (match_dup 3)))]
16991 "operands[0] = gen_lowpart (SImode, operands[0]);
16992 operands[2] = gen_lowpart (SImode, operands[2]);
16993 operands[3] = gen_lowpart (SImode, operands[3]);"
16994 [(set_attr "type" "icmov")
16995 (set_attr "mode" "SI")])
16996
16997 (define_expand "movsfcc"
16998 [(set (match_operand:SF 0 "register_operand" "")
16999 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17000 (match_operand:SF 2 "register_operand" "")
17001 (match_operand:SF 3 "register_operand" "")))]
17002 "TARGET_CMOVE"
17003 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17004
17005 (define_insn "*movsfcc_1"
17006 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17007 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17008 [(reg 17) (const_int 0)])
17009 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17010 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17011 "TARGET_CMOVE
17012 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17013 "@
17014 fcmov%F1\t{%2, %0|%0, %2}
17015 fcmov%f1\t{%3, %0|%0, %3}
17016 cmov%O2%C1\t{%2, %0|%0, %2}
17017 cmov%O2%c1\t{%3, %0|%0, %3}"
17018 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17019 (set_attr "mode" "SF,SF,SI,SI")])
17020
17021 (define_expand "movdfcc"
17022 [(set (match_operand:DF 0 "register_operand" "")
17023 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17024 (match_operand:DF 2 "register_operand" "")
17025 (match_operand:DF 3 "register_operand" "")))]
17026 "TARGET_CMOVE"
17027 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17028
17029 (define_insn "*movdfcc_1"
17030 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17031 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17032 [(reg 17) (const_int 0)])
17033 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17034 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17035 "!TARGET_64BIT && TARGET_CMOVE
17036 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17037 "@
17038 fcmov%F1\t{%2, %0|%0, %2}
17039 fcmov%f1\t{%3, %0|%0, %3}
17040 #
17041 #"
17042 [(set_attr "type" "fcmov,fcmov,multi,multi")
17043 (set_attr "mode" "DF")])
17044
17045 (define_insn "*movdfcc_1_rex64"
17046 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17047 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17048 [(reg 17) (const_int 0)])
17049 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17050 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17051 "TARGET_64BIT && TARGET_CMOVE
17052 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17053 "@
17054 fcmov%F1\t{%2, %0|%0, %2}
17055 fcmov%f1\t{%3, %0|%0, %3}
17056 cmov%O2%C1\t{%2, %0|%0, %2}
17057 cmov%O2%c1\t{%3, %0|%0, %3}"
17058 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17059 (set_attr "mode" "DF")])
17060
17061 (define_split
17062 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17063 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17064 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17065 (match_operand:DF 2 "nonimmediate_operand" "")
17066 (match_operand:DF 3 "nonimmediate_operand" "")))]
17067 "!TARGET_64BIT && reload_completed"
17068 [(set (match_dup 2)
17069 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17070 (match_dup 5)
17071 (match_dup 7)))
17072 (set (match_dup 3)
17073 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17074 (match_dup 6)
17075 (match_dup 8)))]
17076 "split_di (operands+2, 1, operands+5, operands+6);
17077 split_di (operands+3, 1, operands+7, operands+8);
17078 split_di (operands, 1, operands+2, operands+3);")
17079
17080 (define_expand "movxfcc"
17081 [(set (match_operand:XF 0 "register_operand" "")
17082 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17083 (match_operand:XF 2 "register_operand" "")
17084 (match_operand:XF 3 "register_operand" "")))]
17085 "TARGET_CMOVE"
17086 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17087
17088 (define_insn "*movxfcc_1"
17089 [(set (match_operand:XF 0 "register_operand" "=f,f")
17090 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17091 [(reg 17) (const_int 0)])
17092 (match_operand:XF 2 "register_operand" "f,0")
17093 (match_operand:XF 3 "register_operand" "0,f")))]
17094 "TARGET_CMOVE"
17095 "@
17096 fcmov%F1\t{%2, %0|%0, %2}
17097 fcmov%f1\t{%3, %0|%0, %3}"
17098 [(set_attr "type" "fcmov")
17099 (set_attr "mode" "XF")])
17100
17101 (define_expand "minsf3"
17102 [(parallel [
17103 (set (match_operand:SF 0 "register_operand" "")
17104 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17105 (match_operand:SF 2 "nonimmediate_operand" ""))
17106 (match_dup 1)
17107 (match_dup 2)))
17108 (clobber (reg:CC 17))])]
17109 "TARGET_SSE"
17110 "")
17111
17112 (define_insn "*minsf"
17113 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17114 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17115 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17116 (match_dup 1)
17117 (match_dup 2)))
17118 (clobber (reg:CC 17))]
17119 "TARGET_SSE && TARGET_IEEE_FP"
17120 "#")
17121
17122 (define_insn "*minsf_nonieee"
17123 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17124 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17125 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17126 (match_dup 1)
17127 (match_dup 2)))
17128 (clobber (reg:CC 17))]
17129 "TARGET_SSE && !TARGET_IEEE_FP
17130 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17131 "#")
17132
17133 (define_split
17134 [(set (match_operand:SF 0 "register_operand" "")
17135 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17136 (match_operand:SF 2 "nonimmediate_operand" ""))
17137 (match_operand:SF 3 "register_operand" "")
17138 (match_operand:SF 4 "nonimmediate_operand" "")))
17139 (clobber (reg:CC 17))]
17140 "SSE_REG_P (operands[0]) && reload_completed
17141 && ((operands_match_p (operands[1], operands[3])
17142 && operands_match_p (operands[2], operands[4]))
17143 || (operands_match_p (operands[1], operands[4])
17144 && operands_match_p (operands[2], operands[3])))"
17145 [(set (match_dup 0)
17146 (if_then_else:SF (lt (match_dup 1)
17147 (match_dup 2))
17148 (match_dup 1)
17149 (match_dup 2)))])
17150
17151 ;; Conditional addition patterns
17152 (define_expand "addqicc"
17153 [(match_operand:QI 0 "register_operand" "")
17154 (match_operand 1 "comparison_operator" "")
17155 (match_operand:QI 2 "register_operand" "")
17156 (match_operand:QI 3 "const_int_operand" "")]
17157 ""
17158 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17159
17160 (define_expand "addhicc"
17161 [(match_operand:HI 0 "register_operand" "")
17162 (match_operand 1 "comparison_operator" "")
17163 (match_operand:HI 2 "register_operand" "")
17164 (match_operand:HI 3 "const_int_operand" "")]
17165 ""
17166 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17167
17168 (define_expand "addsicc"
17169 [(match_operand:SI 0 "register_operand" "")
17170 (match_operand 1 "comparison_operator" "")
17171 (match_operand:SI 2 "register_operand" "")
17172 (match_operand:SI 3 "const_int_operand" "")]
17173 ""
17174 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17175
17176 (define_expand "adddicc"
17177 [(match_operand:DI 0 "register_operand" "")
17178 (match_operand 1 "comparison_operator" "")
17179 (match_operand:DI 2 "register_operand" "")
17180 (match_operand:DI 3 "const_int_operand" "")]
17181 "TARGET_64BIT"
17182 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17183
17184 ;; We can't represent the LT test directly. Do this by swapping the operands.
17185
17186 (define_split
17187 [(set (match_operand:SF 0 "fp_register_operand" "")
17188 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17189 (match_operand:SF 2 "register_operand" ""))
17190 (match_operand:SF 3 "register_operand" "")
17191 (match_operand:SF 4 "register_operand" "")))
17192 (clobber (reg:CC 17))]
17193 "reload_completed
17194 && ((operands_match_p (operands[1], operands[3])
17195 && operands_match_p (operands[2], operands[4]))
17196 || (operands_match_p (operands[1], operands[4])
17197 && operands_match_p (operands[2], operands[3])))"
17198 [(set (reg:CCFP 17)
17199 (compare:CCFP (match_dup 2)
17200 (match_dup 1)))
17201 (set (match_dup 0)
17202 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17203 (match_dup 1)
17204 (match_dup 2)))])
17205
17206 (define_insn "*minsf_sse"
17207 [(set (match_operand:SF 0 "register_operand" "=x")
17208 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17209 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17210 (match_dup 1)
17211 (match_dup 2)))]
17212 "TARGET_SSE && reload_completed"
17213 "minss\t{%2, %0|%0, %2}"
17214 [(set_attr "type" "sse")
17215 (set_attr "mode" "SF")])
17216
17217 (define_expand "mindf3"
17218 [(parallel [
17219 (set (match_operand:DF 0 "register_operand" "")
17220 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17221 (match_operand:DF 2 "nonimmediate_operand" ""))
17222 (match_dup 1)
17223 (match_dup 2)))
17224 (clobber (reg:CC 17))])]
17225 "TARGET_SSE2 && TARGET_SSE_MATH"
17226 "#")
17227
17228 (define_insn "*mindf"
17229 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17230 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17231 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17232 (match_dup 1)
17233 (match_dup 2)))
17234 (clobber (reg:CC 17))]
17235 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17236 "#")
17237
17238 (define_insn "*mindf_nonieee"
17239 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17240 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17241 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17242 (match_dup 1)
17243 (match_dup 2)))
17244 (clobber (reg:CC 17))]
17245 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17246 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17247 "#")
17248
17249 (define_split
17250 [(set (match_operand:DF 0 "register_operand" "")
17251 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17252 (match_operand:DF 2 "nonimmediate_operand" ""))
17253 (match_operand:DF 3 "register_operand" "")
17254 (match_operand:DF 4 "nonimmediate_operand" "")))
17255 (clobber (reg:CC 17))]
17256 "SSE_REG_P (operands[0]) && reload_completed
17257 && ((operands_match_p (operands[1], operands[3])
17258 && operands_match_p (operands[2], operands[4]))
17259 || (operands_match_p (operands[1], operands[4])
17260 && operands_match_p (operands[2], operands[3])))"
17261 [(set (match_dup 0)
17262 (if_then_else:DF (lt (match_dup 1)
17263 (match_dup 2))
17264 (match_dup 1)
17265 (match_dup 2)))])
17266
17267 ;; We can't represent the LT test directly. Do this by swapping the operands.
17268 (define_split
17269 [(set (match_operand:DF 0 "fp_register_operand" "")
17270 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17271 (match_operand:DF 2 "register_operand" ""))
17272 (match_operand:DF 3 "register_operand" "")
17273 (match_operand:DF 4 "register_operand" "")))
17274 (clobber (reg:CC 17))]
17275 "reload_completed
17276 && ((operands_match_p (operands[1], operands[3])
17277 && operands_match_p (operands[2], operands[4]))
17278 || (operands_match_p (operands[1], operands[4])
17279 && operands_match_p (operands[2], operands[3])))"
17280 [(set (reg:CCFP 17)
17281 (compare:CCFP (match_dup 2)
17282 (match_dup 1)))
17283 (set (match_dup 0)
17284 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17285 (match_dup 1)
17286 (match_dup 2)))])
17287
17288 (define_insn "*mindf_sse"
17289 [(set (match_operand:DF 0 "register_operand" "=Y")
17290 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17291 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17292 (match_dup 1)
17293 (match_dup 2)))]
17294 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17295 "minsd\t{%2, %0|%0, %2}"
17296 [(set_attr "type" "sse")
17297 (set_attr "mode" "DF")])
17298
17299 (define_expand "maxsf3"
17300 [(parallel [
17301 (set (match_operand:SF 0 "register_operand" "")
17302 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17303 (match_operand:SF 2 "nonimmediate_operand" ""))
17304 (match_dup 1)
17305 (match_dup 2)))
17306 (clobber (reg:CC 17))])]
17307 "TARGET_SSE"
17308 "#")
17309
17310 (define_insn "*maxsf"
17311 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17312 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17313 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17314 (match_dup 1)
17315 (match_dup 2)))
17316 (clobber (reg:CC 17))]
17317 "TARGET_SSE && TARGET_IEEE_FP"
17318 "#")
17319
17320 (define_insn "*maxsf_nonieee"
17321 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17322 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17323 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17324 (match_dup 1)
17325 (match_dup 2)))
17326 (clobber (reg:CC 17))]
17327 "TARGET_SSE && !TARGET_IEEE_FP
17328 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17329 "#")
17330
17331 (define_split
17332 [(set (match_operand:SF 0 "register_operand" "")
17333 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17334 (match_operand:SF 2 "nonimmediate_operand" ""))
17335 (match_operand:SF 3 "register_operand" "")
17336 (match_operand:SF 4 "nonimmediate_operand" "")))
17337 (clobber (reg:CC 17))]
17338 "SSE_REG_P (operands[0]) && reload_completed
17339 && ((operands_match_p (operands[1], operands[3])
17340 && operands_match_p (operands[2], operands[4]))
17341 || (operands_match_p (operands[1], operands[4])
17342 && operands_match_p (operands[2], operands[3])))"
17343 [(set (match_dup 0)
17344 (if_then_else:SF (gt (match_dup 1)
17345 (match_dup 2))
17346 (match_dup 1)
17347 (match_dup 2)))])
17348
17349 (define_split
17350 [(set (match_operand:SF 0 "fp_register_operand" "")
17351 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17352 (match_operand:SF 2 "register_operand" ""))
17353 (match_operand:SF 3 "register_operand" "")
17354 (match_operand:SF 4 "register_operand" "")))
17355 (clobber (reg:CC 17))]
17356 "reload_completed
17357 && ((operands_match_p (operands[1], operands[3])
17358 && operands_match_p (operands[2], operands[4]))
17359 || (operands_match_p (operands[1], operands[4])
17360 && operands_match_p (operands[2], operands[3])))"
17361 [(set (reg:CCFP 17)
17362 (compare:CCFP (match_dup 1)
17363 (match_dup 2)))
17364 (set (match_dup 0)
17365 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17366 (match_dup 1)
17367 (match_dup 2)))])
17368
17369 (define_insn "*maxsf_sse"
17370 [(set (match_operand:SF 0 "register_operand" "=x")
17371 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17372 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17373 (match_dup 1)
17374 (match_dup 2)))]
17375 "TARGET_SSE && reload_completed"
17376 "maxss\t{%2, %0|%0, %2}"
17377 [(set_attr "type" "sse")
17378 (set_attr "mode" "SF")])
17379
17380 (define_expand "maxdf3"
17381 [(parallel [
17382 (set (match_operand:DF 0 "register_operand" "")
17383 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17384 (match_operand:DF 2 "nonimmediate_operand" ""))
17385 (match_dup 1)
17386 (match_dup 2)))
17387 (clobber (reg:CC 17))])]
17388 "TARGET_SSE2 && TARGET_SSE_MATH"
17389 "#")
17390
17391 (define_insn "*maxdf"
17392 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17393 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17394 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17395 (match_dup 1)
17396 (match_dup 2)))
17397 (clobber (reg:CC 17))]
17398 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17399 "#")
17400
17401 (define_insn "*maxdf_nonieee"
17402 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17403 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17404 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17405 (match_dup 1)
17406 (match_dup 2)))
17407 (clobber (reg:CC 17))]
17408 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17409 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17410 "#")
17411
17412 (define_split
17413 [(set (match_operand:DF 0 "register_operand" "")
17414 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17415 (match_operand:DF 2 "nonimmediate_operand" ""))
17416 (match_operand:DF 3 "register_operand" "")
17417 (match_operand:DF 4 "nonimmediate_operand" "")))
17418 (clobber (reg:CC 17))]
17419 "SSE_REG_P (operands[0]) && reload_completed
17420 && ((operands_match_p (operands[1], operands[3])
17421 && operands_match_p (operands[2], operands[4]))
17422 || (operands_match_p (operands[1], operands[4])
17423 && operands_match_p (operands[2], operands[3])))"
17424 [(set (match_dup 0)
17425 (if_then_else:DF (gt (match_dup 1)
17426 (match_dup 2))
17427 (match_dup 1)
17428 (match_dup 2)))])
17429
17430 (define_split
17431 [(set (match_operand:DF 0 "fp_register_operand" "")
17432 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17433 (match_operand:DF 2 "register_operand" ""))
17434 (match_operand:DF 3 "register_operand" "")
17435 (match_operand:DF 4 "register_operand" "")))
17436 (clobber (reg:CC 17))]
17437 "reload_completed
17438 && ((operands_match_p (operands[1], operands[3])
17439 && operands_match_p (operands[2], operands[4]))
17440 || (operands_match_p (operands[1], operands[4])
17441 && operands_match_p (operands[2], operands[3])))"
17442 [(set (reg:CCFP 17)
17443 (compare:CCFP (match_dup 1)
17444 (match_dup 2)))
17445 (set (match_dup 0)
17446 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17447 (match_dup 1)
17448 (match_dup 2)))])
17449
17450 (define_insn "*maxdf_sse"
17451 [(set (match_operand:DF 0 "register_operand" "=Y")
17452 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17453 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17454 (match_dup 1)
17455 (match_dup 2)))]
17456 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17457 "maxsd\t{%2, %0|%0, %2}"
17458 [(set_attr "type" "sse")
17459 (set_attr "mode" "DF")])
17460 \f
17461 ;; Misc patterns (?)
17462
17463 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17464 ;; Otherwise there will be nothing to keep
17465 ;;
17466 ;; [(set (reg ebp) (reg esp))]
17467 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17468 ;; (clobber (eflags)]
17469 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17470 ;;
17471 ;; in proper program order.
17472 (define_insn "pro_epilogue_adjust_stack_1"
17473 [(set (match_operand:SI 0 "register_operand" "=r,r")
17474 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17475 (match_operand:SI 2 "immediate_operand" "i,i")))
17476 (clobber (reg:CC 17))
17477 (clobber (mem:BLK (scratch)))]
17478 "!TARGET_64BIT"
17479 {
17480 switch (get_attr_type (insn))
17481 {
17482 case TYPE_IMOV:
17483 return "mov{l}\t{%1, %0|%0, %1}";
17484
17485 case TYPE_ALU:
17486 if (GET_CODE (operands[2]) == CONST_INT
17487 && (INTVAL (operands[2]) == 128
17488 || (INTVAL (operands[2]) < 0
17489 && INTVAL (operands[2]) != -128)))
17490 {
17491 operands[2] = GEN_INT (-INTVAL (operands[2]));
17492 return "sub{l}\t{%2, %0|%0, %2}";
17493 }
17494 return "add{l}\t{%2, %0|%0, %2}";
17495
17496 case TYPE_LEA:
17497 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17498 return "lea{l}\t{%a2, %0|%0, %a2}";
17499
17500 default:
17501 abort ();
17502 }
17503 }
17504 [(set (attr "type")
17505 (cond [(eq_attr "alternative" "0")
17506 (const_string "alu")
17507 (match_operand:SI 2 "const0_operand" "")
17508 (const_string "imov")
17509 ]
17510 (const_string "lea")))
17511 (set_attr "mode" "SI")])
17512
17513 (define_insn "pro_epilogue_adjust_stack_rex64"
17514 [(set (match_operand:DI 0 "register_operand" "=r,r")
17515 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17516 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17517 (clobber (reg:CC 17))
17518 (clobber (mem:BLK (scratch)))]
17519 "TARGET_64BIT"
17520 {
17521 switch (get_attr_type (insn))
17522 {
17523 case TYPE_IMOV:
17524 return "mov{q}\t{%1, %0|%0, %1}";
17525
17526 case TYPE_ALU:
17527 if (GET_CODE (operands[2]) == CONST_INT
17528 /* Avoid overflows. */
17529 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17530 && (INTVAL (operands[2]) == 128
17531 || (INTVAL (operands[2]) < 0
17532 && INTVAL (operands[2]) != -128)))
17533 {
17534 operands[2] = GEN_INT (-INTVAL (operands[2]));
17535 return "sub{q}\t{%2, %0|%0, %2}";
17536 }
17537 return "add{q}\t{%2, %0|%0, %2}";
17538
17539 case TYPE_LEA:
17540 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17541 return "lea{q}\t{%a2, %0|%0, %a2}";
17542
17543 default:
17544 abort ();
17545 }
17546 }
17547 [(set (attr "type")
17548 (cond [(eq_attr "alternative" "0")
17549 (const_string "alu")
17550 (match_operand:DI 2 "const0_operand" "")
17551 (const_string "imov")
17552 ]
17553 (const_string "lea")))
17554 (set_attr "mode" "DI")])
17555
17556 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17557 [(set (match_operand:DI 0 "register_operand" "=r,r")
17558 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17559 (match_operand:DI 3 "immediate_operand" "i,i")))
17560 (use (match_operand:DI 2 "register_operand" "r,r"))
17561 (clobber (reg:CC 17))
17562 (clobber (mem:BLK (scratch)))]
17563 "TARGET_64BIT"
17564 {
17565 switch (get_attr_type (insn))
17566 {
17567 case TYPE_ALU:
17568 return "add{q}\t{%2, %0|%0, %2}";
17569
17570 case TYPE_LEA:
17571 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17572 return "lea{q}\t{%a2, %0|%0, %a2}";
17573
17574 default:
17575 abort ();
17576 }
17577 }
17578 [(set_attr "type" "alu,lea")
17579 (set_attr "mode" "DI")])
17580
17581 ;; Placeholder for the conditional moves. This one is split either to SSE
17582 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17583 ;; fact is that compares supported by the cmp??ss instructions are exactly
17584 ;; swapped of those supported by cmove sequence.
17585 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17586 ;; supported by i387 comparisons and we do need to emit two conditional moves
17587 ;; in tandem.
17588
17589 (define_insn "sse_movsfcc"
17590 [(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")
17591 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17592 [(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")
17593 (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")])
17594 (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")
17595 (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")))
17596 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17597 (clobber (reg:CC 17))]
17598 "TARGET_SSE
17599 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17600 /* Avoid combine from being smart and converting min/max
17601 instruction patterns into conditional moves. */
17602 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17603 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17604 || !rtx_equal_p (operands[4], operands[2])
17605 || !rtx_equal_p (operands[5], operands[3]))
17606 && (!TARGET_IEEE_FP
17607 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17608 "#")
17609
17610 (define_insn "sse_movsfcc_eq"
17611 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17612 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17613 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17614 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17615 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17616 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17617 (clobber (reg:CC 17))]
17618 "TARGET_SSE
17619 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17620 "#")
17621
17622 (define_insn "sse_movdfcc"
17623 [(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")
17624 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17625 [(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")
17626 (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")])
17627 (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")
17628 (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")))
17629 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17630 (clobber (reg:CC 17))]
17631 "TARGET_SSE2
17632 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17633 /* Avoid combine from being smart and converting min/max
17634 instruction patterns into conditional moves. */
17635 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17636 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17637 || !rtx_equal_p (operands[4], operands[2])
17638 || !rtx_equal_p (operands[5], operands[3]))
17639 && (!TARGET_IEEE_FP
17640 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17641 "#")
17642
17643 (define_insn "sse_movdfcc_eq"
17644 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17645 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17646 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17647 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17648 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17649 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17650 (clobber (reg:CC 17))]
17651 "TARGET_SSE
17652 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17653 "#")
17654
17655 ;; For non-sse moves just expand the usual cmove sequence.
17656 (define_split
17657 [(set (match_operand 0 "register_operand" "")
17658 (if_then_else (match_operator 1 "comparison_operator"
17659 [(match_operand 4 "nonimmediate_operand" "")
17660 (match_operand 5 "register_operand" "")])
17661 (match_operand 2 "nonimmediate_operand" "")
17662 (match_operand 3 "nonimmediate_operand" "")))
17663 (clobber (match_operand 6 "" ""))
17664 (clobber (reg:CC 17))]
17665 "!SSE_REG_P (operands[0]) && reload_completed
17666 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17667 [(const_int 0)]
17668 {
17669 ix86_compare_op0 = operands[5];
17670 ix86_compare_op1 = operands[4];
17671 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17672 VOIDmode, operands[5], operands[4]);
17673 ix86_expand_fp_movcc (operands);
17674 DONE;
17675 })
17676
17677 ;; Split SSE based conditional move into sequence:
17678 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17679 ;; and op2, op0 - zero op2 if comparison was false
17680 ;; nand op0, op3 - load op3 to op0 if comparison was false
17681 ;; or op2, op0 - get the nonzero one into the result.
17682 (define_split
17683 [(set (match_operand:SF 0 "register_operand" "")
17684 (if_then_else (match_operator:SF 1 "sse_comparison_operator"
17685 [(match_operand:SF 4 "register_operand" "")
17686 (match_operand:SF 5 "nonimmediate_operand" "")])
17687 (match_operand:SF 2 "register_operand" "")
17688 (match_operand:SF 3 "register_operand" "")))
17689 (clobber (match_operand 6 "" ""))
17690 (clobber (reg:CC 17))]
17691 "SSE_REG_P (operands[0]) && reload_completed"
17692 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17693 (set (match_dup 2) (and:V4SF (match_dup 2)
17694 (match_dup 8)))
17695 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
17696 (match_dup 3)))
17697 (set (match_dup 0) (ior:V4SF (match_dup 6)
17698 (match_dup 7)))]
17699 {
17700 /* If op2 == op3, op3 would be clobbered before it is used. */
17701 if (operands_match_p (operands[2], operands[3]))
17702 {
17703 emit_move_insn (operands[0], operands[2]);
17704 DONE;
17705 }
17706
17707 PUT_MODE (operands[1], GET_MODE (operands[0]));
17708 if (operands_match_p (operands[0], operands[4]))
17709 operands[6] = operands[4], operands[7] = operands[2];
17710 else
17711 operands[6] = operands[2], operands[7] = operands[4];
17712 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17713 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
17714 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
17715 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
17716 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
17717 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17718 })
17719
17720 (define_split
17721 [(set (match_operand:DF 0 "register_operand" "")
17722 (if_then_else (match_operator:DF 1 "sse_comparison_operator"
17723 [(match_operand:DF 4 "register_operand" "")
17724 (match_operand:DF 5 "nonimmediate_operand" "")])
17725 (match_operand:DF 2 "register_operand" "")
17726 (match_operand:DF 3 "register_operand" "")))
17727 (clobber (match_operand 6 "" ""))
17728 (clobber (reg:CC 17))]
17729 "SSE_REG_P (operands[0]) && reload_completed"
17730 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17731 (set (match_dup 2) (and:V2DF (match_dup 2)
17732 (match_dup 8)))
17733 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
17734 (match_dup 3)))
17735 (set (match_dup 0) (ior:V2DF (match_dup 6)
17736 (match_dup 7)))]
17737 {
17738 if (GET_MODE (operands[2]) == DFmode
17739 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17740 {
17741 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17742 emit_insn (gen_sse2_unpcklpd (op, op, op));
17743 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17744 emit_insn (gen_sse2_unpcklpd (op, op, op));
17745 }
17746
17747 /* If op2 == op3, op3 would be clobbered before it is used. */
17748 if (operands_match_p (operands[2], operands[3]))
17749 {
17750 emit_move_insn (operands[0], operands[2]);
17751 DONE;
17752 }
17753
17754 PUT_MODE (operands[1], GET_MODE (operands[0]));
17755 if (operands_match_p (operands[0], operands[4]))
17756 operands[6] = operands[4], operands[7] = operands[2];
17757 else
17758 operands[6] = operands[2], operands[7] = operands[4];
17759 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17760 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17761 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17762 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
17763 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
17764 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17765 })
17766
17767 ;; Special case of conditional move we can handle effectively.
17768 ;; Do not brother with the integer/floating point case, since these are
17769 ;; bot considerably slower, unlike in the generic case.
17770 (define_insn "*sse_movsfcc_const0_1"
17771 [(set (match_operand:SF 0 "register_operand" "=&x")
17772 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17773 [(match_operand:SF 4 "register_operand" "0")
17774 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17775 (match_operand:SF 2 "register_operand" "x")
17776 (match_operand:SF 3 "const0_operand" "X")))]
17777 "TARGET_SSE"
17778 "#")
17779
17780 (define_insn "*sse_movsfcc_const0_2"
17781 [(set (match_operand:SF 0 "register_operand" "=&x")
17782 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17783 [(match_operand:SF 4 "register_operand" "0")
17784 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17785 (match_operand:SF 2 "const0_operand" "X")
17786 (match_operand:SF 3 "register_operand" "x")))]
17787 "TARGET_SSE"
17788 "#")
17789
17790 (define_insn "*sse_movsfcc_const0_3"
17791 [(set (match_operand:SF 0 "register_operand" "=&x")
17792 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17793 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17794 (match_operand:SF 5 "register_operand" "0")])
17795 (match_operand:SF 2 "register_operand" "x")
17796 (match_operand:SF 3 "const0_operand" "X")))]
17797 "TARGET_SSE"
17798 "#")
17799
17800 (define_insn "*sse_movsfcc_const0_4"
17801 [(set (match_operand:SF 0 "register_operand" "=&x")
17802 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17803 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17804 (match_operand:SF 5 "register_operand" "0")])
17805 (match_operand:SF 2 "const0_operand" "X")
17806 (match_operand:SF 3 "register_operand" "x")))]
17807 "TARGET_SSE"
17808 "#")
17809
17810 (define_insn "*sse_movdfcc_const0_1"
17811 [(set (match_operand:DF 0 "register_operand" "=&Y")
17812 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17813 [(match_operand:DF 4 "register_operand" "0")
17814 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17815 (match_operand:DF 2 "register_operand" "Y")
17816 (match_operand:DF 3 "const0_operand" "X")))]
17817 "TARGET_SSE2"
17818 "#")
17819
17820 (define_insn "*sse_movdfcc_const0_2"
17821 [(set (match_operand:DF 0 "register_operand" "=&Y")
17822 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17823 [(match_operand:DF 4 "register_operand" "0")
17824 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17825 (match_operand:DF 2 "const0_operand" "X")
17826 (match_operand:DF 3 "register_operand" "Y")))]
17827 "TARGET_SSE2"
17828 "#")
17829
17830 (define_insn "*sse_movdfcc_const0_3"
17831 [(set (match_operand:DF 0 "register_operand" "=&Y")
17832 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17833 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17834 (match_operand:DF 5 "register_operand" "0")])
17835 (match_operand:DF 2 "register_operand" "Y")
17836 (match_operand:DF 3 "const0_operand" "X")))]
17837 "TARGET_SSE2"
17838 "#")
17839
17840 (define_insn "*sse_movdfcc_const0_4"
17841 [(set (match_operand:DF 0 "register_operand" "=&Y")
17842 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17843 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17844 (match_operand:DF 5 "register_operand" "0")])
17845 (match_operand:DF 2 "const0_operand" "X")
17846 (match_operand:DF 3 "register_operand" "Y")))]
17847 "TARGET_SSE2"
17848 "#")
17849
17850 (define_split
17851 [(set (match_operand:SF 0 "register_operand" "")
17852 (if_then_else (match_operator:SF 1 "comparison_operator"
17853 [(match_operand:SF 4 "nonimmediate_operand" "")
17854 (match_operand:SF 5 "nonimmediate_operand" "")])
17855 (match_operand:SF 2 "nonmemory_operand" "")
17856 (match_operand:SF 3 "nonmemory_operand" "")))]
17857 "SSE_REG_P (operands[0]) && reload_completed
17858 && (const0_operand (operands[2], GET_MODE (operands[0]))
17859 || const0_operand (operands[3], GET_MODE (operands[0])))"
17860 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17861 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
17862 {
17863 PUT_MODE (operands[1], GET_MODE (operands[0]));
17864 if (!sse_comparison_operator (operands[1], VOIDmode)
17865 || !rtx_equal_p (operands[0], operands[4]))
17866 {
17867 rtx tmp = operands[5];
17868 operands[5] = operands[4];
17869 operands[4] = tmp;
17870 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17871 }
17872 if (!rtx_equal_p (operands[0], operands[4]))
17873 abort ();
17874 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17875 if (const0_operand (operands[2], GET_MODE (operands[2])))
17876 {
17877 operands[7] = operands[3];
17878 operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
17879 }
17880 else
17881 {
17882 operands[7] = operands[2];
17883 operands[6] = operands[0];
17884 }
17885 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17886 })
17887
17888 (define_split
17889 [(set (match_operand:DF 0 "register_operand" "")
17890 (if_then_else (match_operator:DF 1 "comparison_operator"
17891 [(match_operand:DF 4 "nonimmediate_operand" "")
17892 (match_operand:DF 5 "nonimmediate_operand" "")])
17893 (match_operand:DF 2 "nonmemory_operand" "")
17894 (match_operand:DF 3 "nonmemory_operand" "")))]
17895 "SSE_REG_P (operands[0]) && reload_completed
17896 && (const0_operand (operands[2], GET_MODE (operands[0]))
17897 || const0_operand (operands[3], GET_MODE (operands[0])))"
17898 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17899 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
17900 {
17901 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17902 && GET_MODE (operands[2]) == DFmode)
17903 {
17904 if (REG_P (operands[2]))
17905 {
17906 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17907 emit_insn (gen_sse2_unpcklpd (op, op, op));
17908 }
17909 if (REG_P (operands[3]))
17910 {
17911 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17912 emit_insn (gen_sse2_unpcklpd (op, op, op));
17913 }
17914 }
17915 PUT_MODE (operands[1], GET_MODE (operands[0]));
17916 if (!sse_comparison_operator (operands[1], VOIDmode)
17917 || !rtx_equal_p (operands[0], operands[4]))
17918 {
17919 rtx tmp = operands[5];
17920 operands[5] = operands[4];
17921 operands[4] = tmp;
17922 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17923 }
17924 if (!rtx_equal_p (operands[0], operands[4]))
17925 abort ();
17926 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17927 if (const0_operand (operands[2], GET_MODE (operands[2])))
17928 {
17929 operands[7] = operands[3];
17930 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
17931 }
17932 else
17933 {
17934 operands[7] = operands[2];
17935 operands[6] = operands[8];
17936 }
17937 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17938 })
17939
17940 (define_expand "allocate_stack_worker"
17941 [(match_operand:SI 0 "register_operand" "")]
17942 "TARGET_STACK_PROBE"
17943 {
17944 if (reload_completed)
17945 {
17946 if (TARGET_64BIT)
17947 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17948 else
17949 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17950 }
17951 else
17952 {
17953 if (TARGET_64BIT)
17954 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17955 else
17956 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17957 }
17958 DONE;
17959 })
17960
17961 (define_insn "allocate_stack_worker_1"
17962 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17963 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17964 (clobber (match_scratch:SI 1 "=0"))
17965 (clobber (reg:CC 17))]
17966 "!TARGET_64BIT && TARGET_STACK_PROBE"
17967 "call\t__alloca"
17968 [(set_attr "type" "multi")
17969 (set_attr "length" "5")])
17970
17971 (define_expand "allocate_stack_worker_postreload"
17972 [(parallel [(unspec:SI [(match_operand:SI 0 "register_operand" "a")]
17973 UNSPEC_STACK_PROBE)
17974 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17975 (clobber (match_dup 0))
17976 (clobber (reg:CC 17))])]
17977 ""
17978 "")
17979
17980 (define_insn "allocate_stack_worker_rex64"
17981 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17982 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17983 (clobber (match_scratch:DI 1 "=0"))
17984 (clobber (reg:CC 17))]
17985 "TARGET_64BIT && TARGET_STACK_PROBE"
17986 "call\t__alloca"
17987 [(set_attr "type" "multi")
17988 (set_attr "length" "5")])
17989
17990 (define_expand "allocate_stack_worker_rex64_postreload"
17991 [(parallel [(unspec:DI [(match_operand:DI 0 "register_operand" "a")]
17992 UNSPEC_STACK_PROBE)
17993 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17994 (clobber (match_dup 0))
17995 (clobber (reg:CC 17))])]
17996 ""
17997 "")
17998
17999 (define_expand "allocate_stack"
18000 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18001 (minus:SI (reg:SI 7)
18002 (match_operand:SI 1 "general_operand" "")))
18003 (clobber (reg:CC 17))])
18004 (parallel [(set (reg:SI 7)
18005 (minus:SI (reg:SI 7) (match_dup 1)))
18006 (clobber (reg:CC 17))])]
18007 "TARGET_STACK_PROBE"
18008 {
18009 #ifdef CHECK_STACK_LIMIT
18010 if (GET_CODE (operands[1]) == CONST_INT
18011 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18012 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18013 operands[1]));
18014 else
18015 #endif
18016 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18017 operands[1])));
18018
18019 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18020 DONE;
18021 })
18022
18023 (define_expand "builtin_setjmp_receiver"
18024 [(label_ref (match_operand 0 "" ""))]
18025 "!TARGET_64BIT && flag_pic"
18026 {
18027 emit_insn (gen_set_got (pic_offset_table_rtx));
18028 DONE;
18029 })
18030 \f
18031 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18032
18033 (define_split
18034 [(set (match_operand 0 "register_operand" "")
18035 (match_operator 3 "promotable_binary_operator"
18036 [(match_operand 1 "register_operand" "")
18037 (match_operand 2 "aligned_operand" "")]))
18038 (clobber (reg:CC 17))]
18039 "! TARGET_PARTIAL_REG_STALL && reload_completed
18040 && ((GET_MODE (operands[0]) == HImode
18041 && ((!optimize_size && !TARGET_FAST_PREFIX)
18042 || GET_CODE (operands[2]) != CONST_INT
18043 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18044 || (GET_MODE (operands[0]) == QImode
18045 && (TARGET_PROMOTE_QImode || optimize_size)))"
18046 [(parallel [(set (match_dup 0)
18047 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18048 (clobber (reg:CC 17))])]
18049 "operands[0] = gen_lowpart (SImode, operands[0]);
18050 operands[1] = gen_lowpart (SImode, operands[1]);
18051 if (GET_CODE (operands[3]) != ASHIFT)
18052 operands[2] = gen_lowpart (SImode, operands[2]);
18053 PUT_MODE (operands[3], SImode);")
18054
18055 ; Promote the QImode tests, as i386 has encoding of the AND
18056 ; instruction with 32-bit sign-extended immediate and thus the
18057 ; instruction size is unchanged, except in the %eax case for
18058 ; which it is increased by one byte, hence the ! optimize_size.
18059 (define_split
18060 [(set (reg 17)
18061 (compare (and (match_operand 1 "aligned_operand" "")
18062 (match_operand 2 "const_int_operand" ""))
18063 (const_int 0)))
18064 (set (match_operand 0 "register_operand" "")
18065 (and (match_dup 1) (match_dup 2)))]
18066 "! TARGET_PARTIAL_REG_STALL && reload_completed
18067 /* Ensure that the operand will remain sign-extended immediate. */
18068 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18069 && ! optimize_size
18070 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18071 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18072 [(parallel [(set (reg:CCNO 17)
18073 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18074 (const_int 0)))
18075 (set (match_dup 0)
18076 (and:SI (match_dup 1) (match_dup 2)))])]
18077 "operands[2]
18078 = gen_int_mode (INTVAL (operands[2])
18079 & GET_MODE_MASK (GET_MODE (operands[0])),
18080 SImode);
18081 operands[0] = gen_lowpart (SImode, operands[0]);
18082 operands[1] = gen_lowpart (SImode, operands[1]);")
18083
18084 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18085 ; the TEST instruction with 32-bit sign-extended immediate and thus
18086 ; the instruction size would at least double, which is not what we
18087 ; want even with ! optimize_size.
18088 (define_split
18089 [(set (reg 17)
18090 (compare (and (match_operand:HI 0 "aligned_operand" "")
18091 (match_operand:HI 1 "const_int_operand" ""))
18092 (const_int 0)))]
18093 "! TARGET_PARTIAL_REG_STALL && reload_completed
18094 /* Ensure that the operand will remain sign-extended immediate. */
18095 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18096 && ! TARGET_FAST_PREFIX
18097 && ! optimize_size"
18098 [(set (reg:CCNO 17)
18099 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18100 (const_int 0)))]
18101 "operands[1]
18102 = gen_int_mode (INTVAL (operands[1])
18103 & GET_MODE_MASK (GET_MODE (operands[0])),
18104 SImode);
18105 operands[0] = gen_lowpart (SImode, operands[0]);")
18106
18107 (define_split
18108 [(set (match_operand 0 "register_operand" "")
18109 (neg (match_operand 1 "register_operand" "")))
18110 (clobber (reg:CC 17))]
18111 "! TARGET_PARTIAL_REG_STALL && reload_completed
18112 && (GET_MODE (operands[0]) == HImode
18113 || (GET_MODE (operands[0]) == QImode
18114 && (TARGET_PROMOTE_QImode || optimize_size)))"
18115 [(parallel [(set (match_dup 0)
18116 (neg:SI (match_dup 1)))
18117 (clobber (reg:CC 17))])]
18118 "operands[0] = gen_lowpart (SImode, operands[0]);
18119 operands[1] = gen_lowpart (SImode, operands[1]);")
18120
18121 (define_split
18122 [(set (match_operand 0 "register_operand" "")
18123 (not (match_operand 1 "register_operand" "")))]
18124 "! TARGET_PARTIAL_REG_STALL && reload_completed
18125 && (GET_MODE (operands[0]) == HImode
18126 || (GET_MODE (operands[0]) == QImode
18127 && (TARGET_PROMOTE_QImode || optimize_size)))"
18128 [(set (match_dup 0)
18129 (not:SI (match_dup 1)))]
18130 "operands[0] = gen_lowpart (SImode, operands[0]);
18131 operands[1] = gen_lowpart (SImode, operands[1]);")
18132
18133 (define_split
18134 [(set (match_operand 0 "register_operand" "")
18135 (if_then_else (match_operator 1 "comparison_operator"
18136 [(reg 17) (const_int 0)])
18137 (match_operand 2 "register_operand" "")
18138 (match_operand 3 "register_operand" "")))]
18139 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18140 && (GET_MODE (operands[0]) == HImode
18141 || (GET_MODE (operands[0]) == QImode
18142 && (TARGET_PROMOTE_QImode || optimize_size)))"
18143 [(set (match_dup 0)
18144 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18145 "operands[0] = gen_lowpart (SImode, operands[0]);
18146 operands[2] = gen_lowpart (SImode, operands[2]);
18147 operands[3] = gen_lowpart (SImode, operands[3]);")
18148
18149 \f
18150 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18151 ;; transform a complex memory operation into two memory to register operations.
18152
18153 ;; Don't push memory operands
18154 (define_peephole2
18155 [(set (match_operand:SI 0 "push_operand" "")
18156 (match_operand:SI 1 "memory_operand" ""))
18157 (match_scratch:SI 2 "r")]
18158 "! optimize_size && ! TARGET_PUSH_MEMORY"
18159 [(set (match_dup 2) (match_dup 1))
18160 (set (match_dup 0) (match_dup 2))]
18161 "")
18162
18163 (define_peephole2
18164 [(set (match_operand:DI 0 "push_operand" "")
18165 (match_operand:DI 1 "memory_operand" ""))
18166 (match_scratch:DI 2 "r")]
18167 "! optimize_size && ! TARGET_PUSH_MEMORY"
18168 [(set (match_dup 2) (match_dup 1))
18169 (set (match_dup 0) (match_dup 2))]
18170 "")
18171
18172 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18173 ;; SImode pushes.
18174 (define_peephole2
18175 [(set (match_operand:SF 0 "push_operand" "")
18176 (match_operand:SF 1 "memory_operand" ""))
18177 (match_scratch:SF 2 "r")]
18178 "! optimize_size && ! TARGET_PUSH_MEMORY"
18179 [(set (match_dup 2) (match_dup 1))
18180 (set (match_dup 0) (match_dup 2))]
18181 "")
18182
18183 (define_peephole2
18184 [(set (match_operand:HI 0 "push_operand" "")
18185 (match_operand:HI 1 "memory_operand" ""))
18186 (match_scratch:HI 2 "r")]
18187 "! optimize_size && ! TARGET_PUSH_MEMORY"
18188 [(set (match_dup 2) (match_dup 1))
18189 (set (match_dup 0) (match_dup 2))]
18190 "")
18191
18192 (define_peephole2
18193 [(set (match_operand:QI 0 "push_operand" "")
18194 (match_operand:QI 1 "memory_operand" ""))
18195 (match_scratch:QI 2 "q")]
18196 "! optimize_size && ! TARGET_PUSH_MEMORY"
18197 [(set (match_dup 2) (match_dup 1))
18198 (set (match_dup 0) (match_dup 2))]
18199 "")
18200
18201 ;; Don't move an immediate directly to memory when the instruction
18202 ;; gets too big.
18203 (define_peephole2
18204 [(match_scratch:SI 1 "r")
18205 (set (match_operand:SI 0 "memory_operand" "")
18206 (const_int 0))]
18207 "! optimize_size
18208 && ! TARGET_USE_MOV0
18209 && TARGET_SPLIT_LONG_MOVES
18210 && get_attr_length (insn) >= ix86_cost->large_insn
18211 && peep2_regno_dead_p (0, FLAGS_REG)"
18212 [(parallel [(set (match_dup 1) (const_int 0))
18213 (clobber (reg:CC 17))])
18214 (set (match_dup 0) (match_dup 1))]
18215 "")
18216
18217 (define_peephole2
18218 [(match_scratch:HI 1 "r")
18219 (set (match_operand:HI 0 "memory_operand" "")
18220 (const_int 0))]
18221 "! optimize_size
18222 && ! TARGET_USE_MOV0
18223 && TARGET_SPLIT_LONG_MOVES
18224 && get_attr_length (insn) >= ix86_cost->large_insn
18225 && peep2_regno_dead_p (0, FLAGS_REG)"
18226 [(parallel [(set (match_dup 2) (const_int 0))
18227 (clobber (reg:CC 17))])
18228 (set (match_dup 0) (match_dup 1))]
18229 "operands[2] = gen_lowpart (SImode, operands[1]);")
18230
18231 (define_peephole2
18232 [(match_scratch:QI 1 "q")
18233 (set (match_operand:QI 0 "memory_operand" "")
18234 (const_int 0))]
18235 "! optimize_size
18236 && ! TARGET_USE_MOV0
18237 && TARGET_SPLIT_LONG_MOVES
18238 && get_attr_length (insn) >= ix86_cost->large_insn
18239 && peep2_regno_dead_p (0, FLAGS_REG)"
18240 [(parallel [(set (match_dup 2) (const_int 0))
18241 (clobber (reg:CC 17))])
18242 (set (match_dup 0) (match_dup 1))]
18243 "operands[2] = gen_lowpart (SImode, operands[1]);")
18244
18245 (define_peephole2
18246 [(match_scratch:SI 2 "r")
18247 (set (match_operand:SI 0 "memory_operand" "")
18248 (match_operand:SI 1 "immediate_operand" ""))]
18249 "! optimize_size
18250 && get_attr_length (insn) >= ix86_cost->large_insn
18251 && TARGET_SPLIT_LONG_MOVES"
18252 [(set (match_dup 2) (match_dup 1))
18253 (set (match_dup 0) (match_dup 2))]
18254 "")
18255
18256 (define_peephole2
18257 [(match_scratch:HI 2 "r")
18258 (set (match_operand:HI 0 "memory_operand" "")
18259 (match_operand:HI 1 "immediate_operand" ""))]
18260 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18261 && TARGET_SPLIT_LONG_MOVES"
18262 [(set (match_dup 2) (match_dup 1))
18263 (set (match_dup 0) (match_dup 2))]
18264 "")
18265
18266 (define_peephole2
18267 [(match_scratch:QI 2 "q")
18268 (set (match_operand:QI 0 "memory_operand" "")
18269 (match_operand:QI 1 "immediate_operand" ""))]
18270 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18271 && TARGET_SPLIT_LONG_MOVES"
18272 [(set (match_dup 2) (match_dup 1))
18273 (set (match_dup 0) (match_dup 2))]
18274 "")
18275
18276 ;; Don't compare memory with zero, load and use a test instead.
18277 (define_peephole2
18278 [(set (reg 17)
18279 (compare (match_operand:SI 0 "memory_operand" "")
18280 (const_int 0)))
18281 (match_scratch:SI 3 "r")]
18282 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18283 [(set (match_dup 3) (match_dup 0))
18284 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18285 "")
18286
18287 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18288 ;; Don't split NOTs with a displacement operand, because resulting XOR
18289 ;; will not be pairable anyway.
18290 ;;
18291 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18292 ;; represented using a modRM byte. The XOR replacement is long decoded,
18293 ;; so this split helps here as well.
18294 ;;
18295 ;; Note: Can't do this as a regular split because we can't get proper
18296 ;; lifetime information then.
18297
18298 (define_peephole2
18299 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18300 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18301 "!optimize_size
18302 && peep2_regno_dead_p (0, FLAGS_REG)
18303 && ((TARGET_PENTIUM
18304 && (GET_CODE (operands[0]) != MEM
18305 || !memory_displacement_operand (operands[0], SImode)))
18306 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18307 [(parallel [(set (match_dup 0)
18308 (xor:SI (match_dup 1) (const_int -1)))
18309 (clobber (reg:CC 17))])]
18310 "")
18311
18312 (define_peephole2
18313 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18314 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18315 "!optimize_size
18316 && peep2_regno_dead_p (0, FLAGS_REG)
18317 && ((TARGET_PENTIUM
18318 && (GET_CODE (operands[0]) != MEM
18319 || !memory_displacement_operand (operands[0], HImode)))
18320 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18321 [(parallel [(set (match_dup 0)
18322 (xor:HI (match_dup 1) (const_int -1)))
18323 (clobber (reg:CC 17))])]
18324 "")
18325
18326 (define_peephole2
18327 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18328 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18329 "!optimize_size
18330 && peep2_regno_dead_p (0, FLAGS_REG)
18331 && ((TARGET_PENTIUM
18332 && (GET_CODE (operands[0]) != MEM
18333 || !memory_displacement_operand (operands[0], QImode)))
18334 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18335 [(parallel [(set (match_dup 0)
18336 (xor:QI (match_dup 1) (const_int -1)))
18337 (clobber (reg:CC 17))])]
18338 "")
18339
18340 ;; Non pairable "test imm, reg" instructions can be translated to
18341 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18342 ;; byte opcode instead of two, have a short form for byte operands),
18343 ;; so do it for other CPUs as well. Given that the value was dead,
18344 ;; this should not create any new dependencies. Pass on the sub-word
18345 ;; versions if we're concerned about partial register stalls.
18346
18347 (define_peephole2
18348 [(set (reg 17)
18349 (compare (and:SI (match_operand:SI 0 "register_operand" "")
18350 (match_operand:SI 1 "immediate_operand" ""))
18351 (const_int 0)))]
18352 "ix86_match_ccmode (insn, CCNOmode)
18353 && (true_regnum (operands[0]) != 0
18354 || (GET_CODE (operands[1]) == CONST_INT
18355 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18356 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18357 [(parallel
18358 [(set (reg:CCNO 17)
18359 (compare:CCNO (and:SI (match_dup 0)
18360 (match_dup 1))
18361 (const_int 0)))
18362 (set (match_dup 0)
18363 (and:SI (match_dup 0) (match_dup 1)))])]
18364 "")
18365
18366 ;; We don't need to handle HImode case, because it will be promoted to SImode
18367 ;; on ! TARGET_PARTIAL_REG_STALL
18368
18369 (define_peephole2
18370 [(set (reg 17)
18371 (compare (and:QI (match_operand:QI 0 "register_operand" "")
18372 (match_operand:QI 1 "immediate_operand" ""))
18373 (const_int 0)))]
18374 "! TARGET_PARTIAL_REG_STALL
18375 && ix86_match_ccmode (insn, CCNOmode)
18376 && true_regnum (operands[0]) != 0
18377 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18378 [(parallel
18379 [(set (reg:CCNO 17)
18380 (compare:CCNO (and:QI (match_dup 0)
18381 (match_dup 1))
18382 (const_int 0)))
18383 (set (match_dup 0)
18384 (and:QI (match_dup 0) (match_dup 1)))])]
18385 "")
18386
18387 (define_peephole2
18388 [(set (reg 17)
18389 (compare
18390 (and:SI
18391 (zero_extract:SI
18392 (match_operand 0 "ext_register_operand" "")
18393 (const_int 8)
18394 (const_int 8))
18395 (match_operand 1 "const_int_operand" ""))
18396 (const_int 0)))]
18397 "! TARGET_PARTIAL_REG_STALL
18398 && ix86_match_ccmode (insn, CCNOmode)
18399 && true_regnum (operands[0]) != 0
18400 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18401 [(parallel [(set (reg:CCNO 17)
18402 (compare:CCNO
18403 (and:SI
18404 (zero_extract:SI
18405 (match_dup 0)
18406 (const_int 8)
18407 (const_int 8))
18408 (match_dup 1))
18409 (const_int 0)))
18410 (set (zero_extract:SI (match_dup 0)
18411 (const_int 8)
18412 (const_int 8))
18413 (and:SI
18414 (zero_extract:SI
18415 (match_dup 0)
18416 (const_int 8)
18417 (const_int 8))
18418 (match_dup 1)))])]
18419 "")
18420
18421 ;; Don't do logical operations with memory inputs.
18422 (define_peephole2
18423 [(match_scratch:SI 2 "r")
18424 (parallel [(set (match_operand:SI 0 "register_operand" "")
18425 (match_operator:SI 3 "arith_or_logical_operator"
18426 [(match_dup 0)
18427 (match_operand:SI 1 "memory_operand" "")]))
18428 (clobber (reg:CC 17))])]
18429 "! optimize_size && ! TARGET_READ_MODIFY"
18430 [(set (match_dup 2) (match_dup 1))
18431 (parallel [(set (match_dup 0)
18432 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18433 (clobber (reg:CC 17))])]
18434 "")
18435
18436 (define_peephole2
18437 [(match_scratch:SI 2 "r")
18438 (parallel [(set (match_operand:SI 0 "register_operand" "")
18439 (match_operator:SI 3 "arith_or_logical_operator"
18440 [(match_operand:SI 1 "memory_operand" "")
18441 (match_dup 0)]))
18442 (clobber (reg:CC 17))])]
18443 "! optimize_size && ! TARGET_READ_MODIFY"
18444 [(set (match_dup 2) (match_dup 1))
18445 (parallel [(set (match_dup 0)
18446 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18447 (clobber (reg:CC 17))])]
18448 "")
18449
18450 ; Don't do logical operations with memory outputs
18451 ;
18452 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18453 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18454 ; the same decoder scheduling characteristics as the original.
18455
18456 (define_peephole2
18457 [(match_scratch:SI 2 "r")
18458 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18459 (match_operator:SI 3 "arith_or_logical_operator"
18460 [(match_dup 0)
18461 (match_operand:SI 1 "nonmemory_operand" "")]))
18462 (clobber (reg:CC 17))])]
18463 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18464 [(set (match_dup 2) (match_dup 0))
18465 (parallel [(set (match_dup 2)
18466 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18467 (clobber (reg:CC 17))])
18468 (set (match_dup 0) (match_dup 2))]
18469 "")
18470
18471 (define_peephole2
18472 [(match_scratch:SI 2 "r")
18473 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18474 (match_operator:SI 3 "arith_or_logical_operator"
18475 [(match_operand:SI 1 "nonmemory_operand" "")
18476 (match_dup 0)]))
18477 (clobber (reg:CC 17))])]
18478 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18479 [(set (match_dup 2) (match_dup 0))
18480 (parallel [(set (match_dup 2)
18481 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18482 (clobber (reg:CC 17))])
18483 (set (match_dup 0) (match_dup 2))]
18484 "")
18485
18486 ;; Attempt to always use XOR for zeroing registers.
18487 (define_peephole2
18488 [(set (match_operand 0 "register_operand" "")
18489 (const_int 0))]
18490 "(GET_MODE (operands[0]) == QImode
18491 || GET_MODE (operands[0]) == HImode
18492 || GET_MODE (operands[0]) == SImode
18493 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18494 && (! TARGET_USE_MOV0 || optimize_size)
18495 && peep2_regno_dead_p (0, FLAGS_REG)"
18496 [(parallel [(set (match_dup 0) (const_int 0))
18497 (clobber (reg:CC 17))])]
18498 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18499 operands[0]);")
18500
18501 (define_peephole2
18502 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18503 (const_int 0))]
18504 "(GET_MODE (operands[0]) == QImode
18505 || GET_MODE (operands[0]) == HImode)
18506 && (! TARGET_USE_MOV0 || optimize_size)
18507 && peep2_regno_dead_p (0, FLAGS_REG)"
18508 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18509 (clobber (reg:CC 17))])])
18510
18511 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18512 (define_peephole2
18513 [(set (match_operand 0 "register_operand" "")
18514 (const_int -1))]
18515 "(GET_MODE (operands[0]) == HImode
18516 || GET_MODE (operands[0]) == SImode
18517 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18518 && (optimize_size || TARGET_PENTIUM)
18519 && peep2_regno_dead_p (0, FLAGS_REG)"
18520 [(parallel [(set (match_dup 0) (const_int -1))
18521 (clobber (reg:CC 17))])]
18522 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18523 operands[0]);")
18524
18525 ;; Attempt to convert simple leas to adds. These can be created by
18526 ;; move expanders.
18527 (define_peephole2
18528 [(set (match_operand:SI 0 "register_operand" "")
18529 (plus:SI (match_dup 0)
18530 (match_operand:SI 1 "nonmemory_operand" "")))]
18531 "peep2_regno_dead_p (0, FLAGS_REG)"
18532 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18533 (clobber (reg:CC 17))])]
18534 "")
18535
18536 (define_peephole2
18537 [(set (match_operand:SI 0 "register_operand" "")
18538 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18539 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18540 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18541 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18542 (clobber (reg:CC 17))])]
18543 "operands[2] = gen_lowpart (SImode, operands[2]);")
18544
18545 (define_peephole2
18546 [(set (match_operand:DI 0 "register_operand" "")
18547 (plus:DI (match_dup 0)
18548 (match_operand:DI 1 "x86_64_general_operand" "")))]
18549 "peep2_regno_dead_p (0, FLAGS_REG)"
18550 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18551 (clobber (reg:CC 17))])]
18552 "")
18553
18554 (define_peephole2
18555 [(set (match_operand:SI 0 "register_operand" "")
18556 (mult:SI (match_dup 0)
18557 (match_operand:SI 1 "const_int_operand" "")))]
18558 "exact_log2 (INTVAL (operands[1])) >= 0
18559 && peep2_regno_dead_p (0, FLAGS_REG)"
18560 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18561 (clobber (reg:CC 17))])]
18562 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18563
18564 (define_peephole2
18565 [(set (match_operand:DI 0 "register_operand" "")
18566 (mult:DI (match_dup 0)
18567 (match_operand:DI 1 "const_int_operand" "")))]
18568 "exact_log2 (INTVAL (operands[1])) >= 0
18569 && peep2_regno_dead_p (0, FLAGS_REG)"
18570 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18571 (clobber (reg:CC 17))])]
18572 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18573
18574 (define_peephole2
18575 [(set (match_operand:SI 0 "register_operand" "")
18576 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18577 (match_operand:DI 2 "const_int_operand" "")) 0))]
18578 "exact_log2 (INTVAL (operands[2])) >= 0
18579 && REGNO (operands[0]) == REGNO (operands[1])
18580 && peep2_regno_dead_p (0, FLAGS_REG)"
18581 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18582 (clobber (reg:CC 17))])]
18583 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18584
18585 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18586 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18587 ;; many CPUs it is also faster, since special hardware to avoid esp
18588 ;; dependencies is present.
18589
18590 ;; While some of these conversions may be done using splitters, we use peepholes
18591 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18592
18593 ;; Convert prologue esp subtractions to push.
18594 ;; We need register to push. In order to keep verify_flow_info happy we have
18595 ;; two choices
18596 ;; - use scratch and clobber it in order to avoid dependencies
18597 ;; - use already live register
18598 ;; We can't use the second way right now, since there is no reliable way how to
18599 ;; verify that given register is live. First choice will also most likely in
18600 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18601 ;; call clobbered registers are dead. We may want to use base pointer as an
18602 ;; alternative when no register is available later.
18603
18604 (define_peephole2
18605 [(match_scratch:SI 0 "r")
18606 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18607 (clobber (reg:CC 17))
18608 (clobber (mem:BLK (scratch)))])]
18609 "optimize_size || !TARGET_SUB_ESP_4"
18610 [(clobber (match_dup 0))
18611 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18612 (clobber (mem:BLK (scratch)))])])
18613
18614 (define_peephole2
18615 [(match_scratch:SI 0 "r")
18616 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18617 (clobber (reg:CC 17))
18618 (clobber (mem:BLK (scratch)))])]
18619 "optimize_size || !TARGET_SUB_ESP_8"
18620 [(clobber (match_dup 0))
18621 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18622 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18623 (clobber (mem:BLK (scratch)))])])
18624
18625 ;; Convert esp subtractions to push.
18626 (define_peephole2
18627 [(match_scratch:SI 0 "r")
18628 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18629 (clobber (reg:CC 17))])]
18630 "optimize_size || !TARGET_SUB_ESP_4"
18631 [(clobber (match_dup 0))
18632 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18633
18634 (define_peephole2
18635 [(match_scratch:SI 0 "r")
18636 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18637 (clobber (reg:CC 17))])]
18638 "optimize_size || !TARGET_SUB_ESP_8"
18639 [(clobber (match_dup 0))
18640 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18641 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18642
18643 ;; Convert epilogue deallocator to pop.
18644 (define_peephole2
18645 [(match_scratch:SI 0 "r")
18646 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18647 (clobber (reg:CC 17))
18648 (clobber (mem:BLK (scratch)))])]
18649 "optimize_size || !TARGET_ADD_ESP_4"
18650 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18651 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18652 (clobber (mem:BLK (scratch)))])]
18653 "")
18654
18655 ;; Two pops case is tricky, since pop causes dependency on destination register.
18656 ;; We use two registers if available.
18657 (define_peephole2
18658 [(match_scratch:SI 0 "r")
18659 (match_scratch:SI 1 "r")
18660 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18661 (clobber (reg:CC 17))
18662 (clobber (mem:BLK (scratch)))])]
18663 "optimize_size || !TARGET_ADD_ESP_8"
18664 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18665 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18666 (clobber (mem:BLK (scratch)))])
18667 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18668 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18669 "")
18670
18671 (define_peephole2
18672 [(match_scratch:SI 0 "r")
18673 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18674 (clobber (reg:CC 17))
18675 (clobber (mem:BLK (scratch)))])]
18676 "optimize_size"
18677 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18678 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18679 (clobber (mem:BLK (scratch)))])
18680 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18681 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18682 "")
18683
18684 ;; Convert esp additions to pop.
18685 (define_peephole2
18686 [(match_scratch:SI 0 "r")
18687 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18688 (clobber (reg:CC 17))])]
18689 ""
18690 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18691 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18692 "")
18693
18694 ;; Two pops case is tricky, since pop causes dependency on destination register.
18695 ;; We use two registers if available.
18696 (define_peephole2
18697 [(match_scratch:SI 0 "r")
18698 (match_scratch:SI 1 "r")
18699 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18700 (clobber (reg:CC 17))])]
18701 ""
18702 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18703 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18704 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18705 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18706 "")
18707
18708 (define_peephole2
18709 [(match_scratch:SI 0 "r")
18710 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18711 (clobber (reg:CC 17))])]
18712 "optimize_size"
18713 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18714 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18715 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18716 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18717 "")
18718 \f
18719 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18720 ;; required and register dies.
18721 (define_peephole2
18722 [(set (reg 17)
18723 (compare (match_operand:SI 0 "register_operand" "")
18724 (match_operand:SI 1 "incdec_operand" "")))]
18725 "ix86_match_ccmode (insn, CCGCmode)
18726 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18727 [(parallel [(set (reg:CCGC 17)
18728 (compare:CCGC (match_dup 0)
18729 (match_dup 1)))
18730 (clobber (match_dup 0))])]
18731 "")
18732
18733 (define_peephole2
18734 [(set (reg 17)
18735 (compare (match_operand:HI 0 "register_operand" "")
18736 (match_operand:HI 1 "incdec_operand" "")))]
18737 "ix86_match_ccmode (insn, CCGCmode)
18738 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18739 [(parallel [(set (reg:CCGC 17)
18740 (compare:CCGC (match_dup 0)
18741 (match_dup 1)))
18742 (clobber (match_dup 0))])]
18743 "")
18744
18745 (define_peephole2
18746 [(set (reg 17)
18747 (compare (match_operand:QI 0 "register_operand" "")
18748 (match_operand:QI 1 "incdec_operand" "")))]
18749 "ix86_match_ccmode (insn, CCGCmode)
18750 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18751 [(parallel [(set (reg:CCGC 17)
18752 (compare:CCGC (match_dup 0)
18753 (match_dup 1)))
18754 (clobber (match_dup 0))])]
18755 "")
18756
18757 ;; Convert compares with 128 to shorter add -128
18758 (define_peephole2
18759 [(set (reg 17)
18760 (compare (match_operand:SI 0 "register_operand" "")
18761 (const_int 128)))]
18762 "ix86_match_ccmode (insn, CCGCmode)
18763 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18764 [(parallel [(set (reg:CCGC 17)
18765 (compare:CCGC (match_dup 0)
18766 (const_int 128)))
18767 (clobber (match_dup 0))])]
18768 "")
18769
18770 (define_peephole2
18771 [(set (reg 17)
18772 (compare (match_operand:HI 0 "register_operand" "")
18773 (const_int 128)))]
18774 "ix86_match_ccmode (insn, CCGCmode)
18775 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18776 [(parallel [(set (reg:CCGC 17)
18777 (compare:CCGC (match_dup 0)
18778 (const_int 128)))
18779 (clobber (match_dup 0))])]
18780 "")
18781 \f
18782 (define_peephole2
18783 [(match_scratch:DI 0 "r")
18784 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18785 (clobber (reg:CC 17))
18786 (clobber (mem:BLK (scratch)))])]
18787 "optimize_size || !TARGET_SUB_ESP_4"
18788 [(clobber (match_dup 0))
18789 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18790 (clobber (mem:BLK (scratch)))])])
18791
18792 (define_peephole2
18793 [(match_scratch:DI 0 "r")
18794 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18795 (clobber (reg:CC 17))
18796 (clobber (mem:BLK (scratch)))])]
18797 "optimize_size || !TARGET_SUB_ESP_8"
18798 [(clobber (match_dup 0))
18799 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18800 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18801 (clobber (mem:BLK (scratch)))])])
18802
18803 ;; Convert esp subtractions to push.
18804 (define_peephole2
18805 [(match_scratch:DI 0 "r")
18806 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18807 (clobber (reg:CC 17))])]
18808 "optimize_size || !TARGET_SUB_ESP_4"
18809 [(clobber (match_dup 0))
18810 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18811
18812 (define_peephole2
18813 [(match_scratch:DI 0 "r")
18814 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18815 (clobber (reg:CC 17))])]
18816 "optimize_size || !TARGET_SUB_ESP_8"
18817 [(clobber (match_dup 0))
18818 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18819 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18820
18821 ;; Convert epilogue deallocator to pop.
18822 (define_peephole2
18823 [(match_scratch:DI 0 "r")
18824 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18825 (clobber (reg:CC 17))
18826 (clobber (mem:BLK (scratch)))])]
18827 "optimize_size || !TARGET_ADD_ESP_4"
18828 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18829 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18830 (clobber (mem:BLK (scratch)))])]
18831 "")
18832
18833 ;; Two pops case is tricky, since pop causes dependency on destination register.
18834 ;; We use two registers if available.
18835 (define_peephole2
18836 [(match_scratch:DI 0 "r")
18837 (match_scratch:DI 1 "r")
18838 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18839 (clobber (reg:CC 17))
18840 (clobber (mem:BLK (scratch)))])]
18841 "optimize_size || !TARGET_ADD_ESP_8"
18842 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18843 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18844 (clobber (mem:BLK (scratch)))])
18845 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18846 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18847 "")
18848
18849 (define_peephole2
18850 [(match_scratch:DI 0 "r")
18851 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18852 (clobber (reg:CC 17))
18853 (clobber (mem:BLK (scratch)))])]
18854 "optimize_size"
18855 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18856 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18857 (clobber (mem:BLK (scratch)))])
18858 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18859 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18860 "")
18861
18862 ;; Convert esp additions to pop.
18863 (define_peephole2
18864 [(match_scratch:DI 0 "r")
18865 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18866 (clobber (reg:CC 17))])]
18867 ""
18868 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18869 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18870 "")
18871
18872 ;; Two pops case is tricky, since pop causes dependency on destination register.
18873 ;; We use two registers if available.
18874 (define_peephole2
18875 [(match_scratch:DI 0 "r")
18876 (match_scratch:DI 1 "r")
18877 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18878 (clobber (reg:CC 17))])]
18879 ""
18880 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18881 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18882 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18883 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18884 "")
18885
18886 (define_peephole2
18887 [(match_scratch:DI 0 "r")
18888 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18889 (clobber (reg:CC 17))])]
18890 "optimize_size"
18891 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18892 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18893 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18894 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18895 "")
18896 \f
18897 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18898 ;; imul $32bit_imm, reg, reg is direct decoded.
18899 (define_peephole2
18900 [(match_scratch:DI 3 "r")
18901 (parallel [(set (match_operand:DI 0 "register_operand" "")
18902 (mult:DI (match_operand:DI 1 "memory_operand" "")
18903 (match_operand:DI 2 "immediate_operand" "")))
18904 (clobber (reg:CC 17))])]
18905 "TARGET_K8 && !optimize_size
18906 && (GET_CODE (operands[2]) != CONST_INT
18907 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18908 [(set (match_dup 3) (match_dup 1))
18909 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18910 (clobber (reg:CC 17))])]
18911 "")
18912
18913 (define_peephole2
18914 [(match_scratch:SI 3 "r")
18915 (parallel [(set (match_operand:SI 0 "register_operand" "")
18916 (mult:SI (match_operand:SI 1 "memory_operand" "")
18917 (match_operand:SI 2 "immediate_operand" "")))
18918 (clobber (reg:CC 17))])]
18919 "TARGET_K8 && !optimize_size
18920 && (GET_CODE (operands[2]) != CONST_INT
18921 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18922 [(set (match_dup 3) (match_dup 1))
18923 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18924 (clobber (reg:CC 17))])]
18925 "")
18926
18927 (define_peephole2
18928 [(match_scratch:SI 3 "r")
18929 (parallel [(set (match_operand:DI 0 "register_operand" "")
18930 (zero_extend:DI
18931 (mult:SI (match_operand:SI 1 "memory_operand" "")
18932 (match_operand:SI 2 "immediate_operand" ""))))
18933 (clobber (reg:CC 17))])]
18934 "TARGET_K8 && !optimize_size
18935 && (GET_CODE (operands[2]) != CONST_INT
18936 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18937 [(set (match_dup 3) (match_dup 1))
18938 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18939 (clobber (reg:CC 17))])]
18940 "")
18941
18942 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18943 ;; Convert it into imul reg, reg
18944 ;; It would be better to force assembler to encode instruction using long
18945 ;; immediate, but there is apparently no way to do so.
18946 (define_peephole2
18947 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18948 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18949 (match_operand:DI 2 "const_int_operand" "")))
18950 (clobber (reg:CC 17))])
18951 (match_scratch:DI 3 "r")]
18952 "TARGET_K8 && !optimize_size
18953 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18954 [(set (match_dup 3) (match_dup 2))
18955 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18956 (clobber (reg:CC 17))])]
18957 {
18958 if (!rtx_equal_p (operands[0], operands[1]))
18959 emit_move_insn (operands[0], operands[1]);
18960 })
18961
18962 (define_peephole2
18963 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18964 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18965 (match_operand:SI 2 "const_int_operand" "")))
18966 (clobber (reg:CC 17))])
18967 (match_scratch:SI 3 "r")]
18968 "TARGET_K8 && !optimize_size
18969 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18970 [(set (match_dup 3) (match_dup 2))
18971 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18972 (clobber (reg:CC 17))])]
18973 {
18974 if (!rtx_equal_p (operands[0], operands[1]))
18975 emit_move_insn (operands[0], operands[1]);
18976 })
18977
18978 (define_peephole2
18979 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18980 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18981 (match_operand:HI 2 "immediate_operand" "")))
18982 (clobber (reg:CC 17))])
18983 (match_scratch:HI 3 "r")]
18984 "TARGET_K8 && !optimize_size"
18985 [(set (match_dup 3) (match_dup 2))
18986 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18987 (clobber (reg:CC 17))])]
18988 {
18989 if (!rtx_equal_p (operands[0], operands[1]))
18990 emit_move_insn (operands[0], operands[1]);
18991 })
18992 \f
18993 ;; Call-value patterns last so that the wildcard operand does not
18994 ;; disrupt insn-recog's switch tables.
18995
18996 (define_insn "*call_value_pop_0"
18997 [(set (match_operand 0 "" "")
18998 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18999 (match_operand:SI 2 "" "")))
19000 (set (reg:SI 7) (plus:SI (reg:SI 7)
19001 (match_operand:SI 3 "immediate_operand" "")))]
19002 "!TARGET_64BIT"
19003 {
19004 if (SIBLING_CALL_P (insn))
19005 return "jmp\t%P1";
19006 else
19007 return "call\t%P1";
19008 }
19009 [(set_attr "type" "callv")])
19010
19011 (define_insn "*call_value_pop_1"
19012 [(set (match_operand 0 "" "")
19013 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19014 (match_operand:SI 2 "" "")))
19015 (set (reg:SI 7) (plus:SI (reg:SI 7)
19016 (match_operand:SI 3 "immediate_operand" "i")))]
19017 "!TARGET_64BIT"
19018 {
19019 if (constant_call_address_operand (operands[1], QImode))
19020 {
19021 if (SIBLING_CALL_P (insn))
19022 return "jmp\t%P1";
19023 else
19024 return "call\t%P1";
19025 }
19026 if (SIBLING_CALL_P (insn))
19027 return "jmp\t%A1";
19028 else
19029 return "call\t%A1";
19030 }
19031 [(set_attr "type" "callv")])
19032
19033 (define_insn "*call_value_0"
19034 [(set (match_operand 0 "" "")
19035 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19036 (match_operand:SI 2 "" "")))]
19037 "!TARGET_64BIT"
19038 {
19039 if (SIBLING_CALL_P (insn))
19040 return "jmp\t%P1";
19041 else
19042 return "call\t%P1";
19043 }
19044 [(set_attr "type" "callv")])
19045
19046 (define_insn "*call_value_0_rex64"
19047 [(set (match_operand 0 "" "")
19048 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19049 (match_operand:DI 2 "const_int_operand" "")))]
19050 "TARGET_64BIT"
19051 {
19052 if (SIBLING_CALL_P (insn))
19053 return "jmp\t%P1";
19054 else
19055 return "call\t%P1";
19056 }
19057 [(set_attr "type" "callv")])
19058
19059 (define_insn "*call_value_1"
19060 [(set (match_operand 0 "" "")
19061 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19062 (match_operand:SI 2 "" "")))]
19063 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19064 {
19065 if (constant_call_address_operand (operands[1], QImode))
19066 return "call\t%P1";
19067 return "call\t%*%1";
19068 }
19069 [(set_attr "type" "callv")])
19070
19071 (define_insn "*sibcall_value_1"
19072 [(set (match_operand 0 "" "")
19073 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19074 (match_operand:SI 2 "" "")))]
19075 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19076 {
19077 if (constant_call_address_operand (operands[1], QImode))
19078 return "jmp\t%P1";
19079 return "jmp\t%*%1";
19080 }
19081 [(set_attr "type" "callv")])
19082
19083 (define_insn "*call_value_1_rex64"
19084 [(set (match_operand 0 "" "")
19085 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19086 (match_operand:DI 2 "" "")))]
19087 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19088 {
19089 if (constant_call_address_operand (operands[1], QImode))
19090 return "call\t%P1";
19091 return "call\t%A1";
19092 }
19093 [(set_attr "type" "callv")])
19094
19095 (define_insn "*sibcall_value_1_rex64"
19096 [(set (match_operand 0 "" "")
19097 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19098 (match_operand:DI 2 "" "")))]
19099 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19100 "jmp\t%P1"
19101 [(set_attr "type" "callv")])
19102
19103 (define_insn "*sibcall_value_1_rex64_v"
19104 [(set (match_operand 0 "" "")
19105 (call (mem:QI (reg:DI 40))
19106 (match_operand:DI 1 "" "")))]
19107 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19108 "jmp\t*%%r11"
19109 [(set_attr "type" "callv")])
19110 \f
19111 (define_insn "trap"
19112 [(trap_if (const_int 1) (const_int 5))]
19113 ""
19114 "int\t$5")
19115
19116 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19117 ;;; for the sake of bounds checking. By emitting bounds checks as
19118 ;;; conditional traps rather than as conditional jumps around
19119 ;;; unconditional traps we avoid introducing spurious basic-block
19120 ;;; boundaries and facilitate elimination of redundant checks. In
19121 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19122 ;;; interrupt 5.
19123 ;;;
19124 ;;; FIXME: Static branch prediction rules for ix86 are such that
19125 ;;; forward conditional branches predict as untaken. As implemented
19126 ;;; below, pseudo conditional traps violate that rule. We should use
19127 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19128 ;;; section loaded at the end of the text segment and branch forward
19129 ;;; there on bounds-failure, and then jump back immediately (in case
19130 ;;; the system chooses to ignore bounds violations, or to report
19131 ;;; violations and continue execution).
19132
19133 (define_expand "conditional_trap"
19134 [(trap_if (match_operator 0 "comparison_operator"
19135 [(match_dup 2) (const_int 0)])
19136 (match_operand 1 "const_int_operand" ""))]
19137 ""
19138 {
19139 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19140 ix86_expand_compare (GET_CODE (operands[0]),
19141 NULL, NULL),
19142 operands[1]));
19143 DONE;
19144 })
19145
19146 (define_insn "*conditional_trap_1"
19147 [(trap_if (match_operator 0 "comparison_operator"
19148 [(reg 17) (const_int 0)])
19149 (match_operand 1 "const_int_operand" ""))]
19150 ""
19151 {
19152 operands[2] = gen_label_rtx ();
19153 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19154 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19155 CODE_LABEL_NUMBER (operands[2]));
19156 RET;
19157 })
19158
19159 ;; Pentium III SIMD instructions.
19160
19161 ;; Moves for SSE/MMX regs.
19162
19163 (define_insn "movv4sf_internal"
19164 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19165 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19166 "TARGET_SSE"
19167 "@
19168 xorps\t%0, %0
19169 movaps\t{%1, %0|%0, %1}
19170 movaps\t{%1, %0|%0, %1}"
19171 [(set_attr "type" "ssemov")
19172 (set_attr "mode" "V4SF")])
19173
19174 (define_split
19175 [(set (match_operand:V4SF 0 "register_operand" "")
19176 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19177 "TARGET_SSE"
19178 [(set (match_dup 0)
19179 (vec_merge:V4SF
19180 (vec_duplicate:V4SF (match_dup 1))
19181 (match_dup 2)
19182 (const_int 1)))]
19183 {
19184 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19185 operands[2] = CONST0_RTX (V4SFmode);
19186 })
19187
19188 (define_insn "movv4si_internal"
19189 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19190 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19191 "TARGET_SSE"
19192 {
19193 switch (which_alternative)
19194 {
19195 case 0:
19196 if (get_attr_mode (insn) == MODE_V4SF)
19197 return "xorps\t%0, %0";
19198 else
19199 return "pxor\t%0, %0";
19200 case 1:
19201 case 2:
19202 if (get_attr_mode (insn) == MODE_V4SF)
19203 return "movaps\t{%1, %0|%0, %1}";
19204 else
19205 return "movdqa\t{%1, %0|%0, %1}";
19206 default:
19207 abort ();
19208 }
19209 }
19210 [(set_attr "type" "ssemov")
19211 (set (attr "mode")
19212 (cond [(eq_attr "alternative" "0,1")
19213 (if_then_else
19214 (ne (symbol_ref "optimize_size")
19215 (const_int 0))
19216 (const_string "V4SF")
19217 (const_string "TI"))
19218 (eq_attr "alternative" "2")
19219 (if_then_else
19220 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19221 (const_int 0))
19222 (ne (symbol_ref "optimize_size")
19223 (const_int 0)))
19224 (const_string "V4SF")
19225 (const_string "TI"))]
19226 (const_string "TI")))])
19227
19228 (define_insn "movv2di_internal"
19229 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19230 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19231 "TARGET_SSE"
19232 {
19233 switch (which_alternative)
19234 {
19235 case 0:
19236 if (get_attr_mode (insn) == MODE_V4SF)
19237 return "xorps\t%0, %0";
19238 else
19239 return "pxor\t%0, %0";
19240 case 1:
19241 case 2:
19242 if (get_attr_mode (insn) == MODE_V4SF)
19243 return "movaps\t{%1, %0|%0, %1}";
19244 else
19245 return "movdqa\t{%1, %0|%0, %1}";
19246 default:
19247 abort ();
19248 }
19249 }
19250 [(set_attr "type" "ssemov")
19251 (set (attr "mode")
19252 (cond [(eq_attr "alternative" "0,1")
19253 (if_then_else
19254 (ne (symbol_ref "optimize_size")
19255 (const_int 0))
19256 (const_string "V4SF")
19257 (const_string "TI"))
19258 (eq_attr "alternative" "2")
19259 (if_then_else
19260 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19261 (const_int 0))
19262 (ne (symbol_ref "optimize_size")
19263 (const_int 0)))
19264 (const_string "V4SF")
19265 (const_string "TI"))]
19266 (const_string "TI")))])
19267
19268 (define_split
19269 [(set (match_operand:V2DF 0 "register_operand" "")
19270 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19271 "TARGET_SSE2"
19272 [(set (match_dup 0)
19273 (vec_merge:V2DF
19274 (vec_duplicate:V2DF (match_dup 1))
19275 (match_dup 2)
19276 (const_int 1)))]
19277 {
19278 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19279 operands[2] = CONST0_RTX (V2DFmode);
19280 })
19281
19282 (define_insn "movv8qi_internal"
19283 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19284 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19285 "TARGET_MMX
19286 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19287 "@
19288 pxor\t%0, %0
19289 movq\t{%1, %0|%0, %1}
19290 movq\t{%1, %0|%0, %1}"
19291 [(set_attr "type" "mmxmov")
19292 (set_attr "mode" "DI")])
19293
19294 (define_insn "movv4hi_internal"
19295 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19296 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19297 "TARGET_MMX
19298 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19299 "@
19300 pxor\t%0, %0
19301 movq\t{%1, %0|%0, %1}
19302 movq\t{%1, %0|%0, %1}"
19303 [(set_attr "type" "mmxmov")
19304 (set_attr "mode" "DI")])
19305
19306 (define_insn "movv2si_internal"
19307 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19308 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19309 "TARGET_MMX
19310 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19311 "@
19312 pxor\t%0, %0
19313 movq\t{%1, %0|%0, %1}
19314 movq\t{%1, %0|%0, %1}"
19315 [(set_attr "type" "mmxcvt")
19316 (set_attr "mode" "DI")])
19317
19318 (define_insn "movv2sf_internal"
19319 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19320 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19321 "TARGET_3DNOW
19322 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19323 "@
19324 pxor\t%0, %0
19325 movq\t{%1, %0|%0, %1}
19326 movq\t{%1, %0|%0, %1}"
19327 [(set_attr "type" "mmxcvt")
19328 (set_attr "mode" "DI")])
19329
19330 (define_expand "movti"
19331 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19332 (match_operand:TI 1 "nonimmediate_operand" ""))]
19333 "TARGET_SSE || TARGET_64BIT"
19334 {
19335 if (TARGET_64BIT)
19336 ix86_expand_move (TImode, operands);
19337 else
19338 ix86_expand_vector_move (TImode, operands);
19339 DONE;
19340 })
19341
19342 (define_expand "movtf"
19343 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19344 (match_operand:TF 1 "nonimmediate_operand" ""))]
19345 "TARGET_64BIT"
19346 {
19347 if (TARGET_64BIT)
19348 ix86_expand_move (TFmode, operands);
19349 else
19350 ix86_expand_vector_move (TFmode, operands);
19351 DONE;
19352 })
19353
19354 (define_insn "movv2df_internal"
19355 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19356 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19357 "TARGET_SSE2
19358 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19359 {
19360 switch (which_alternative)
19361 {
19362 case 0:
19363 if (get_attr_mode (insn) == MODE_V4SF)
19364 return "xorps\t%0, %0";
19365 else
19366 return "xorpd\t%0, %0";
19367 case 1:
19368 case 2:
19369 if (get_attr_mode (insn) == MODE_V4SF)
19370 return "movaps\t{%1, %0|%0, %1}";
19371 else
19372 return "movapd\t{%1, %0|%0, %1}";
19373 default:
19374 abort ();
19375 }
19376 }
19377 [(set_attr "type" "ssemov")
19378 (set (attr "mode")
19379 (cond [(eq_attr "alternative" "0,1")
19380 (if_then_else
19381 (ne (symbol_ref "optimize_size")
19382 (const_int 0))
19383 (const_string "V4SF")
19384 (const_string "V2DF"))
19385 (eq_attr "alternative" "2")
19386 (if_then_else
19387 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19388 (const_int 0))
19389 (ne (symbol_ref "optimize_size")
19390 (const_int 0)))
19391 (const_string "V4SF")
19392 (const_string "V2DF"))]
19393 (const_string "V2DF")))])
19394
19395 (define_insn "movv8hi_internal"
19396 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19397 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19398 "TARGET_SSE2
19399 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19400 {
19401 switch (which_alternative)
19402 {
19403 case 0:
19404 if (get_attr_mode (insn) == MODE_V4SF)
19405 return "xorps\t%0, %0";
19406 else
19407 return "pxor\t%0, %0";
19408 case 1:
19409 case 2:
19410 if (get_attr_mode (insn) == MODE_V4SF)
19411 return "movaps\t{%1, %0|%0, %1}";
19412 else
19413 return "movdqa\t{%1, %0|%0, %1}";
19414 default:
19415 abort ();
19416 }
19417 }
19418 [(set_attr "type" "ssemov")
19419 (set (attr "mode")
19420 (cond [(eq_attr "alternative" "0,1")
19421 (if_then_else
19422 (ne (symbol_ref "optimize_size")
19423 (const_int 0))
19424 (const_string "V4SF")
19425 (const_string "TI"))
19426 (eq_attr "alternative" "2")
19427 (if_then_else
19428 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19429 (const_int 0))
19430 (ne (symbol_ref "optimize_size")
19431 (const_int 0)))
19432 (const_string "V4SF")
19433 (const_string "TI"))]
19434 (const_string "TI")))])
19435
19436 (define_insn "movv16qi_internal"
19437 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19438 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19439 "TARGET_SSE2
19440 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19441 {
19442 switch (which_alternative)
19443 {
19444 case 0:
19445 if (get_attr_mode (insn) == MODE_V4SF)
19446 return "xorps\t%0, %0";
19447 else
19448 return "pxor\t%0, %0";
19449 case 1:
19450 case 2:
19451 if (get_attr_mode (insn) == MODE_V4SF)
19452 return "movaps\t{%1, %0|%0, %1}";
19453 else
19454 return "movdqa\t{%1, %0|%0, %1}";
19455 default:
19456 abort ();
19457 }
19458 }
19459 [(set_attr "type" "ssemov")
19460 (set (attr "mode")
19461 (cond [(eq_attr "alternative" "0,1")
19462 (if_then_else
19463 (ne (symbol_ref "optimize_size")
19464 (const_int 0))
19465 (const_string "V4SF")
19466 (const_string "TI"))
19467 (eq_attr "alternative" "2")
19468 (if_then_else
19469 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19470 (const_int 0))
19471 (ne (symbol_ref "optimize_size")
19472 (const_int 0)))
19473 (const_string "V4SF")
19474 (const_string "TI"))]
19475 (const_string "TI")))])
19476
19477 (define_expand "movv2df"
19478 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19479 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19480 "TARGET_SSE2"
19481 {
19482 ix86_expand_vector_move (V2DFmode, operands);
19483 DONE;
19484 })
19485
19486 (define_expand "movv8hi"
19487 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19488 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19489 "TARGET_SSE2"
19490 {
19491 ix86_expand_vector_move (V8HImode, operands);
19492 DONE;
19493 })
19494
19495 (define_expand "movv16qi"
19496 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19497 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19498 "TARGET_SSE2"
19499 {
19500 ix86_expand_vector_move (V16QImode, operands);
19501 DONE;
19502 })
19503
19504 (define_expand "movv4sf"
19505 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19506 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19507 "TARGET_SSE"
19508 {
19509 ix86_expand_vector_move (V4SFmode, operands);
19510 DONE;
19511 })
19512
19513 (define_expand "movv4si"
19514 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19515 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19516 "TARGET_SSE"
19517 {
19518 ix86_expand_vector_move (V4SImode, operands);
19519 DONE;
19520 })
19521
19522 (define_expand "movv2di"
19523 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19524 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19525 "TARGET_SSE"
19526 {
19527 ix86_expand_vector_move (V2DImode, operands);
19528 DONE;
19529 })
19530
19531 (define_expand "movv2si"
19532 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19533 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19534 "TARGET_MMX"
19535 {
19536 ix86_expand_vector_move (V2SImode, operands);
19537 DONE;
19538 })
19539
19540 (define_expand "movv4hi"
19541 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19542 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19543 "TARGET_MMX"
19544 {
19545 ix86_expand_vector_move (V4HImode, operands);
19546 DONE;
19547 })
19548
19549 (define_expand "movv8qi"
19550 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19551 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19552 "TARGET_MMX"
19553 {
19554 ix86_expand_vector_move (V8QImode, operands);
19555 DONE;
19556 })
19557
19558 (define_expand "movv2sf"
19559 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19560 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19561 "TARGET_3DNOW"
19562 {
19563 ix86_expand_vector_move (V2SFmode, operands);
19564 DONE;
19565 })
19566
19567 (define_insn "*pushti"
19568 [(set (match_operand:TI 0 "push_operand" "=<")
19569 (match_operand:TI 1 "register_operand" "x"))]
19570 "TARGET_SSE"
19571 "#")
19572
19573 (define_insn "*pushv2df"
19574 [(set (match_operand:V2DF 0 "push_operand" "=<")
19575 (match_operand:V2DF 1 "register_operand" "x"))]
19576 "TARGET_SSE"
19577 "#")
19578
19579 (define_insn "*pushv2di"
19580 [(set (match_operand:V2DI 0 "push_operand" "=<")
19581 (match_operand:V2DI 1 "register_operand" "x"))]
19582 "TARGET_SSE2"
19583 "#")
19584
19585 (define_insn "*pushv8hi"
19586 [(set (match_operand:V8HI 0 "push_operand" "=<")
19587 (match_operand:V8HI 1 "register_operand" "x"))]
19588 "TARGET_SSE2"
19589 "#")
19590
19591 (define_insn "*pushv16qi"
19592 [(set (match_operand:V16QI 0 "push_operand" "=<")
19593 (match_operand:V16QI 1 "register_operand" "x"))]
19594 "TARGET_SSE2"
19595 "#")
19596
19597 (define_insn "*pushv4sf"
19598 [(set (match_operand:V4SF 0 "push_operand" "=<")
19599 (match_operand:V4SF 1 "register_operand" "x"))]
19600 "TARGET_SSE"
19601 "#")
19602
19603 (define_insn "*pushv4si"
19604 [(set (match_operand:V4SI 0 "push_operand" "=<")
19605 (match_operand:V4SI 1 "register_operand" "x"))]
19606 "TARGET_SSE2"
19607 "#")
19608
19609 (define_insn "*pushv2si"
19610 [(set (match_operand:V2SI 0 "push_operand" "=<")
19611 (match_operand:V2SI 1 "register_operand" "y"))]
19612 "TARGET_MMX"
19613 "#")
19614
19615 (define_insn "*pushv4hi"
19616 [(set (match_operand:V4HI 0 "push_operand" "=<")
19617 (match_operand:V4HI 1 "register_operand" "y"))]
19618 "TARGET_MMX"
19619 "#")
19620
19621 (define_insn "*pushv8qi"
19622 [(set (match_operand:V8QI 0 "push_operand" "=<")
19623 (match_operand:V8QI 1 "register_operand" "y"))]
19624 "TARGET_MMX"
19625 "#")
19626
19627 (define_insn "*pushv2sf"
19628 [(set (match_operand:V2SF 0 "push_operand" "=<")
19629 (match_operand:V2SF 1 "register_operand" "y"))]
19630 "TARGET_3DNOW"
19631 "#")
19632
19633 (define_split
19634 [(set (match_operand 0 "push_operand" "")
19635 (match_operand 1 "register_operand" ""))]
19636 "!TARGET_64BIT && reload_completed
19637 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19638 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19639 (set (match_dup 2) (match_dup 1))]
19640 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19641 stack_pointer_rtx);
19642 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19643
19644 (define_split
19645 [(set (match_operand 0 "push_operand" "")
19646 (match_operand 1 "register_operand" ""))]
19647 "TARGET_64BIT && reload_completed
19648 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19649 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19650 (set (match_dup 2) (match_dup 1))]
19651 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19652 stack_pointer_rtx);
19653 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19654
19655
19656 (define_insn "movti_internal"
19657 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19658 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19659 "TARGET_SSE && !TARGET_64BIT
19660 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19661 {
19662 switch (which_alternative)
19663 {
19664 case 0:
19665 if (get_attr_mode (insn) == MODE_V4SF)
19666 return "xorps\t%0, %0";
19667 else
19668 return "pxor\t%0, %0";
19669 case 1:
19670 case 2:
19671 if (get_attr_mode (insn) == MODE_V4SF)
19672 return "movaps\t{%1, %0|%0, %1}";
19673 else
19674 return "movdqa\t{%1, %0|%0, %1}";
19675 default:
19676 abort ();
19677 }
19678 }
19679 [(set_attr "type" "ssemov,ssemov,ssemov")
19680 (set (attr "mode")
19681 (cond [(eq_attr "alternative" "0,1")
19682 (if_then_else
19683 (ne (symbol_ref "optimize_size")
19684 (const_int 0))
19685 (const_string "V4SF")
19686 (const_string "TI"))
19687 (eq_attr "alternative" "2")
19688 (if_then_else
19689 (ne (symbol_ref "optimize_size")
19690 (const_int 0))
19691 (const_string "V4SF")
19692 (const_string "TI"))]
19693 (const_string "TI")))])
19694
19695 (define_insn "*movti_rex64"
19696 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19697 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19698 "TARGET_64BIT
19699 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19700 {
19701 switch (which_alternative)
19702 {
19703 case 0:
19704 case 1:
19705 return "#";
19706 case 2:
19707 if (get_attr_mode (insn) == MODE_V4SF)
19708 return "xorps\t%0, %0";
19709 else
19710 return "pxor\t%0, %0";
19711 case 3:
19712 case 4:
19713 if (get_attr_mode (insn) == MODE_V4SF)
19714 return "movaps\t{%1, %0|%0, %1}";
19715 else
19716 return "movdqa\t{%1, %0|%0, %1}";
19717 default:
19718 abort ();
19719 }
19720 }
19721 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19722 (set (attr "mode")
19723 (cond [(eq_attr "alternative" "2,3")
19724 (if_then_else
19725 (ne (symbol_ref "optimize_size")
19726 (const_int 0))
19727 (const_string "V4SF")
19728 (const_string "TI"))
19729 (eq_attr "alternative" "4")
19730 (if_then_else
19731 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19732 (const_int 0))
19733 (ne (symbol_ref "optimize_size")
19734 (const_int 0)))
19735 (const_string "V4SF")
19736 (const_string "TI"))]
19737 (const_string "DI")))])
19738
19739 (define_insn "*movtf_rex64"
19740 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19741 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19742 "TARGET_64BIT
19743 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19744 {
19745 switch (which_alternative)
19746 {
19747 case 0:
19748 case 1:
19749 return "#";
19750 case 2:
19751 if (get_attr_mode (insn) == MODE_V4SF)
19752 return "xorps\t%0, %0";
19753 else
19754 return "pxor\t%0, %0";
19755 case 3:
19756 case 4:
19757 if (get_attr_mode (insn) == MODE_V4SF)
19758 return "movaps\t{%1, %0|%0, %1}";
19759 else
19760 return "movdqa\t{%1, %0|%0, %1}";
19761 default:
19762 abort ();
19763 }
19764 }
19765 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19766 (set (attr "mode")
19767 (cond [(eq_attr "alternative" "2,3")
19768 (if_then_else
19769 (ne (symbol_ref "optimize_size")
19770 (const_int 0))
19771 (const_string "V4SF")
19772 (const_string "TI"))
19773 (eq_attr "alternative" "4")
19774 (if_then_else
19775 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19776 (const_int 0))
19777 (ne (symbol_ref "optimize_size")
19778 (const_int 0)))
19779 (const_string "V4SF")
19780 (const_string "TI"))]
19781 (const_string "DI")))])
19782
19783 (define_split
19784 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19785 (match_operand:TI 1 "general_operand" ""))]
19786 "reload_completed && !SSE_REG_P (operands[0])
19787 && !SSE_REG_P (operands[1])"
19788 [(const_int 0)]
19789 "ix86_split_long_move (operands); DONE;")
19790
19791 (define_split
19792 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19793 (match_operand:TF 1 "general_operand" ""))]
19794 "reload_completed && !SSE_REG_P (operands[0])
19795 && !SSE_REG_P (operands[1])"
19796 [(const_int 0)]
19797 "ix86_split_long_move (operands); DONE;")
19798
19799 ;; These two patterns are useful for specifying exactly whether to use
19800 ;; movaps or movups
19801 (define_expand "sse_movaps"
19802 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19803 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19804 UNSPEC_MOVA))]
19805 "TARGET_SSE"
19806 {
19807 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19808 {
19809 rtx tmp = gen_reg_rtx (V4SFmode);
19810 emit_insn (gen_sse_movaps (tmp, operands[1]));
19811 emit_move_insn (operands[0], tmp);
19812 DONE;
19813 }
19814 })
19815
19816 (define_insn "*sse_movaps_1"
19817 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19818 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19819 UNSPEC_MOVA))]
19820 "TARGET_SSE
19821 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19822 "movaps\t{%1, %0|%0, %1}"
19823 [(set_attr "type" "ssemov,ssemov")
19824 (set_attr "mode" "V4SF")])
19825
19826 (define_expand "sse_movups"
19827 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19828 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19829 UNSPEC_MOVU))]
19830 "TARGET_SSE"
19831 {
19832 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19833 {
19834 rtx tmp = gen_reg_rtx (V4SFmode);
19835 emit_insn (gen_sse_movups (tmp, operands[1]));
19836 emit_move_insn (operands[0], tmp);
19837 DONE;
19838 }
19839 })
19840
19841 (define_insn "*sse_movups_1"
19842 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19843 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19844 UNSPEC_MOVU))]
19845 "TARGET_SSE
19846 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19847 "movups\t{%1, %0|%0, %1}"
19848 [(set_attr "type" "ssecvt,ssecvt")
19849 (set_attr "mode" "V4SF")])
19850
19851 ;; SSE Strange Moves.
19852
19853 (define_insn "sse_movmskps"
19854 [(set (match_operand:SI 0 "register_operand" "=r")
19855 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19856 UNSPEC_MOVMSK))]
19857 "TARGET_SSE"
19858 "movmskps\t{%1, %0|%0, %1}"
19859 [(set_attr "type" "ssecvt")
19860 (set_attr "mode" "V4SF")])
19861
19862 (define_insn "mmx_pmovmskb"
19863 [(set (match_operand:SI 0 "register_operand" "=r")
19864 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19865 UNSPEC_MOVMSK))]
19866 "TARGET_SSE || TARGET_3DNOW_A"
19867 "pmovmskb\t{%1, %0|%0, %1}"
19868 [(set_attr "type" "ssecvt")
19869 (set_attr "mode" "V4SF")])
19870
19871
19872 (define_insn "mmx_maskmovq"
19873 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19874 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19875 (match_operand:V8QI 2 "register_operand" "y")]
19876 UNSPEC_MASKMOV))]
19877 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19878 ;; @@@ check ordering of operands in intel/nonintel syntax
19879 "maskmovq\t{%2, %1|%1, %2}"
19880 [(set_attr "type" "mmxcvt")
19881 (set_attr "mode" "DI")])
19882
19883 (define_insn "mmx_maskmovq_rex"
19884 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19885 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19886 (match_operand:V8QI 2 "register_operand" "y")]
19887 UNSPEC_MASKMOV))]
19888 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19889 ;; @@@ check ordering of operands in intel/nonintel syntax
19890 "maskmovq\t{%2, %1|%1, %2}"
19891 [(set_attr "type" "mmxcvt")
19892 (set_attr "mode" "DI")])
19893
19894 (define_insn "sse_movntv4sf"
19895 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19896 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19897 UNSPEC_MOVNT))]
19898 "TARGET_SSE"
19899 "movntps\t{%1, %0|%0, %1}"
19900 [(set_attr "type" "ssemov")
19901 (set_attr "mode" "V4SF")])
19902
19903 (define_insn "sse_movntdi"
19904 [(set (match_operand:DI 0 "memory_operand" "=m")
19905 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19906 UNSPEC_MOVNT))]
19907 "TARGET_SSE || TARGET_3DNOW_A"
19908 "movntq\t{%1, %0|%0, %1}"
19909 [(set_attr "type" "mmxmov")
19910 (set_attr "mode" "DI")])
19911
19912 (define_insn "sse_movhlps"
19913 [(set (match_operand:V4SF 0 "register_operand" "=x")
19914 (vec_merge:V4SF
19915 (match_operand:V4SF 1 "register_operand" "0")
19916 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19917 (parallel [(const_int 2)
19918 (const_int 3)
19919 (const_int 0)
19920 (const_int 1)]))
19921 (const_int 3)))]
19922 "TARGET_SSE"
19923 "movhlps\t{%2, %0|%0, %2}"
19924 [(set_attr "type" "ssecvt")
19925 (set_attr "mode" "V4SF")])
19926
19927 (define_insn "sse_movlhps"
19928 [(set (match_operand:V4SF 0 "register_operand" "=x")
19929 (vec_merge:V4SF
19930 (match_operand:V4SF 1 "register_operand" "0")
19931 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19932 (parallel [(const_int 2)
19933 (const_int 3)
19934 (const_int 0)
19935 (const_int 1)]))
19936 (const_int 12)))]
19937 "TARGET_SSE"
19938 "movlhps\t{%2, %0|%0, %2}"
19939 [(set_attr "type" "ssecvt")
19940 (set_attr "mode" "V4SF")])
19941
19942 (define_insn "sse_movhps"
19943 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19944 (vec_merge:V4SF
19945 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19946 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19947 (const_int 12)))]
19948 "TARGET_SSE
19949 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19950 "movhps\t{%2, %0|%0, %2}"
19951 [(set_attr "type" "ssecvt")
19952 (set_attr "mode" "V4SF")])
19953
19954 (define_insn "sse_movlps"
19955 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19956 (vec_merge:V4SF
19957 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19958 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19959 (const_int 3)))]
19960 "TARGET_SSE
19961 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19962 "movlps\t{%2, %0|%0, %2}"
19963 [(set_attr "type" "ssecvt")
19964 (set_attr "mode" "V4SF")])
19965
19966 (define_expand "sse_loadss"
19967 [(match_operand:V4SF 0 "register_operand" "")
19968 (match_operand:SF 1 "memory_operand" "")]
19969 "TARGET_SSE"
19970 {
19971 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19972 CONST0_RTX (V4SFmode)));
19973 DONE;
19974 })
19975
19976 (define_insn "sse_loadss_1"
19977 [(set (match_operand:V4SF 0 "register_operand" "=x")
19978 (vec_merge:V4SF
19979 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19980 (match_operand:V4SF 2 "const0_operand" "X")
19981 (const_int 1)))]
19982 "TARGET_SSE"
19983 "movss\t{%1, %0|%0, %1}"
19984 [(set_attr "type" "ssemov")
19985 (set_attr "mode" "SF")])
19986
19987 (define_insn "sse_movss"
19988 [(set (match_operand:V4SF 0 "register_operand" "=x")
19989 (vec_merge:V4SF
19990 (match_operand:V4SF 1 "register_operand" "0")
19991 (match_operand:V4SF 2 "register_operand" "x")
19992 (const_int 1)))]
19993 "TARGET_SSE"
19994 "movss\t{%2, %0|%0, %2}"
19995 [(set_attr "type" "ssemov")
19996 (set_attr "mode" "SF")])
19997
19998 (define_insn "sse_storess"
19999 [(set (match_operand:SF 0 "memory_operand" "=m")
20000 (vec_select:SF
20001 (match_operand:V4SF 1 "register_operand" "x")
20002 (parallel [(const_int 0)])))]
20003 "TARGET_SSE"
20004 "movss\t{%1, %0|%0, %1}"
20005 [(set_attr "type" "ssemov")
20006 (set_attr "mode" "SF")])
20007
20008 (define_insn "sse_shufps"
20009 [(set (match_operand:V4SF 0 "register_operand" "=x")
20010 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20011 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20012 (match_operand:SI 3 "immediate_operand" "i")]
20013 UNSPEC_SHUFFLE))]
20014 "TARGET_SSE"
20015 ;; @@@ check operand order for intel/nonintel syntax
20016 "shufps\t{%3, %2, %0|%0, %2, %3}"
20017 [(set_attr "type" "ssecvt")
20018 (set_attr "mode" "V4SF")])
20019
20020
20021 ;; SSE arithmetic
20022
20023 (define_insn "addv4sf3"
20024 [(set (match_operand:V4SF 0 "register_operand" "=x")
20025 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20026 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20027 "TARGET_SSE"
20028 "addps\t{%2, %0|%0, %2}"
20029 [(set_attr "type" "sseadd")
20030 (set_attr "mode" "V4SF")])
20031
20032 (define_insn "vmaddv4sf3"
20033 [(set (match_operand:V4SF 0 "register_operand" "=x")
20034 (vec_merge:V4SF
20035 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20036 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20037 (match_dup 1)
20038 (const_int 1)))]
20039 "TARGET_SSE"
20040 "addss\t{%2, %0|%0, %2}"
20041 [(set_attr "type" "sseadd")
20042 (set_attr "mode" "SF")])
20043
20044 (define_insn "subv4sf3"
20045 [(set (match_operand:V4SF 0 "register_operand" "=x")
20046 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20047 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20048 "TARGET_SSE"
20049 "subps\t{%2, %0|%0, %2}"
20050 [(set_attr "type" "sseadd")
20051 (set_attr "mode" "V4SF")])
20052
20053 (define_insn "vmsubv4sf3"
20054 [(set (match_operand:V4SF 0 "register_operand" "=x")
20055 (vec_merge:V4SF
20056 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20057 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20058 (match_dup 1)
20059 (const_int 1)))]
20060 "TARGET_SSE"
20061 "subss\t{%2, %0|%0, %2}"
20062 [(set_attr "type" "sseadd")
20063 (set_attr "mode" "SF")])
20064
20065 (define_insn "mulv4sf3"
20066 [(set (match_operand:V4SF 0 "register_operand" "=x")
20067 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20068 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20069 "TARGET_SSE"
20070 "mulps\t{%2, %0|%0, %2}"
20071 [(set_attr "type" "ssemul")
20072 (set_attr "mode" "V4SF")])
20073
20074 (define_insn "vmmulv4sf3"
20075 [(set (match_operand:V4SF 0 "register_operand" "=x")
20076 (vec_merge:V4SF
20077 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20078 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20079 (match_dup 1)
20080 (const_int 1)))]
20081 "TARGET_SSE"
20082 "mulss\t{%2, %0|%0, %2}"
20083 [(set_attr "type" "ssemul")
20084 (set_attr "mode" "SF")])
20085
20086 (define_insn "divv4sf3"
20087 [(set (match_operand:V4SF 0 "register_operand" "=x")
20088 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20089 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20090 "TARGET_SSE"
20091 "divps\t{%2, %0|%0, %2}"
20092 [(set_attr "type" "ssediv")
20093 (set_attr "mode" "V4SF")])
20094
20095 (define_insn "vmdivv4sf3"
20096 [(set (match_operand:V4SF 0 "register_operand" "=x")
20097 (vec_merge:V4SF
20098 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20099 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20100 (match_dup 1)
20101 (const_int 1)))]
20102 "TARGET_SSE"
20103 "divss\t{%2, %0|%0, %2}"
20104 [(set_attr "type" "ssediv")
20105 (set_attr "mode" "SF")])
20106
20107
20108 ;; SSE square root/reciprocal
20109
20110 (define_insn "rcpv4sf2"
20111 [(set (match_operand:V4SF 0 "register_operand" "=x")
20112 (unspec:V4SF
20113 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20114 "TARGET_SSE"
20115 "rcpps\t{%1, %0|%0, %1}"
20116 [(set_attr "type" "sse")
20117 (set_attr "mode" "V4SF")])
20118
20119 (define_insn "vmrcpv4sf2"
20120 [(set (match_operand:V4SF 0 "register_operand" "=x")
20121 (vec_merge:V4SF
20122 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20123 UNSPEC_RCP)
20124 (match_operand:V4SF 2 "register_operand" "0")
20125 (const_int 1)))]
20126 "TARGET_SSE"
20127 "rcpss\t{%1, %0|%0, %1}"
20128 [(set_attr "type" "sse")
20129 (set_attr "mode" "SF")])
20130
20131 (define_insn "rsqrtv4sf2"
20132 [(set (match_operand:V4SF 0 "register_operand" "=x")
20133 (unspec:V4SF
20134 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20135 "TARGET_SSE"
20136 "rsqrtps\t{%1, %0|%0, %1}"
20137 [(set_attr "type" "sse")
20138 (set_attr "mode" "V4SF")])
20139
20140 (define_insn "vmrsqrtv4sf2"
20141 [(set (match_operand:V4SF 0 "register_operand" "=x")
20142 (vec_merge:V4SF
20143 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20144 UNSPEC_RSQRT)
20145 (match_operand:V4SF 2 "register_operand" "0")
20146 (const_int 1)))]
20147 "TARGET_SSE"
20148 "rsqrtss\t{%1, %0|%0, %1}"
20149 [(set_attr "type" "sse")
20150 (set_attr "mode" "SF")])
20151
20152 (define_insn "sqrtv4sf2"
20153 [(set (match_operand:V4SF 0 "register_operand" "=x")
20154 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20155 "TARGET_SSE"
20156 "sqrtps\t{%1, %0|%0, %1}"
20157 [(set_attr "type" "sse")
20158 (set_attr "mode" "V4SF")])
20159
20160 (define_insn "vmsqrtv4sf2"
20161 [(set (match_operand:V4SF 0 "register_operand" "=x")
20162 (vec_merge:V4SF
20163 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20164 (match_operand:V4SF 2 "register_operand" "0")
20165 (const_int 1)))]
20166 "TARGET_SSE"
20167 "sqrtss\t{%1, %0|%0, %1}"
20168 [(set_attr "type" "sse")
20169 (set_attr "mode" "SF")])
20170
20171 ;; SSE logical operations.
20172
20173 ;; SSE defines logical operations on floating point values. This brings
20174 ;; interesting challenge to RTL representation where logicals are only valid
20175 ;; on integral types. We deal with this by representing the floating point
20176 ;; logical as logical on arguments casted to TImode as this is what hardware
20177 ;; really does. Unfortunately hardware requires the type information to be
20178 ;; present and thus we must avoid subregs from being simplified and eliminated
20179 ;; in later compilation phases.
20180 ;;
20181 ;; We have following variants from each instruction:
20182 ;; sse_andsf3 - the operation taking V4SF vector operands
20183 ;; and doing TImode cast on them
20184 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20185 ;; TImode, since backend insist on eliminating casts
20186 ;; on memory operands
20187 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20188 ;; We can not accept memory operand here as instruction reads
20189 ;; whole scalar. This is generated only post reload by GCC
20190 ;; scalar float operations that expands to logicals (fabs)
20191 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20192 ;; memory operand. Eventually combine can be able
20193 ;; to synthesize these using splitter.
20194 ;; sse2_anddf3, *sse2_anddf3_memory
20195 ;;
20196 ;;
20197 ;; These are not called andti3 etc. because we really really don't want
20198 ;; the compiler to widen DImode ands to TImode ands and then try to move
20199 ;; into DImode subregs of SSE registers, and them together, and move out
20200 ;; of DImode subregs again!
20201 ;; SSE1 single precision floating point logical operation
20202 (define_expand "sse_andv4sf3"
20203 [(set (match_operand:V4SF 0 "register_operand" "")
20204 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20205 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20206 "TARGET_SSE"
20207 "")
20208
20209 (define_insn "*sse_andv4sf3"
20210 [(set (match_operand:V4SF 0 "register_operand" "=x")
20211 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20212 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20213 "TARGET_SSE
20214 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20215 "andps\t{%2, %0|%0, %2}"
20216 [(set_attr "type" "sselog")
20217 (set_attr "mode" "V4SF")])
20218
20219 (define_expand "sse_nandv4sf3"
20220 [(set (match_operand:V4SF 0 "register_operand" "")
20221 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20222 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20223 "TARGET_SSE"
20224 "")
20225
20226 (define_insn "*sse_nandv4sf3"
20227 [(set (match_operand:V4SF 0 "register_operand" "=x")
20228 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20229 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20230 "TARGET_SSE"
20231 "andnps\t{%2, %0|%0, %2}"
20232 [(set_attr "type" "sselog")
20233 (set_attr "mode" "V4SF")])
20234
20235 (define_expand "sse_iorv4sf3"
20236 [(set (match_operand:V4SF 0 "register_operand" "")
20237 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20238 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20239 "TARGET_SSE"
20240 "")
20241
20242 (define_insn "*sse_iorv4sf3"
20243 [(set (match_operand:V4SF 0 "register_operand" "=x")
20244 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20245 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20246 "TARGET_SSE
20247 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20248 "orps\t{%2, %0|%0, %2}"
20249 [(set_attr "type" "sselog")
20250 (set_attr "mode" "V4SF")])
20251
20252 (define_expand "sse_xorv4sf3"
20253 [(set (match_operand:V4SF 0 "register_operand" "")
20254 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20255 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20256 "TARGET_SSE"
20257 "")
20258
20259 (define_insn "*sse_xorv4sf3"
20260 [(set (match_operand:V4SF 0 "register_operand" "=x")
20261 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20262 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20263 "TARGET_SSE
20264 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20265 "xorps\t{%2, %0|%0, %2}"
20266 [(set_attr "type" "sselog")
20267 (set_attr "mode" "V4SF")])
20268
20269 ;; SSE2 double precision floating point logical operation
20270
20271 (define_expand "sse2_andv2df3"
20272 [(set (match_operand:V2DF 0 "register_operand" "")
20273 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20274 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20275 "TARGET_SSE2"
20276 "")
20277
20278 (define_insn "*sse2_andv2df3"
20279 [(set (match_operand:V2DF 0 "register_operand" "=x")
20280 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20281 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20282 "TARGET_SSE2
20283 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20284 "andpd\t{%2, %0|%0, %2}"
20285 [(set_attr "type" "sselog")
20286 (set_attr "mode" "V2DF")])
20287
20288 (define_expand "sse2_nandv2df3"
20289 [(set (match_operand:V2DF 0 "register_operand" "")
20290 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20291 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20292 "TARGET_SSE2"
20293 "")
20294
20295 (define_insn "*sse2_nandv2df3"
20296 [(set (match_operand:V2DF 0 "register_operand" "=x")
20297 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20298 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20299 "TARGET_SSE2"
20300 "andnpd\t{%2, %0|%0, %2}"
20301 [(set_attr "type" "sselog")
20302 (set_attr "mode" "V2DF")])
20303
20304 (define_expand "sse2_iorv2df3"
20305 [(set (match_operand:V2DF 0 "register_operand" "")
20306 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20307 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20308 "TARGET_SSE2"
20309 "")
20310
20311 (define_insn "*sse2_iorv2df3"
20312 [(set (match_operand:V2DF 0 "register_operand" "=x")
20313 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20314 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20315 "TARGET_SSE2
20316 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20317 "orpd\t{%2, %0|%0, %2}"
20318 [(set_attr "type" "sselog")
20319 (set_attr "mode" "V2DF")])
20320
20321 (define_expand "sse2_xorv2df3"
20322 [(set (match_operand:V2DF 0 "register_operand" "")
20323 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20324 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20325 "TARGET_SSE2"
20326 "")
20327
20328 (define_insn "*sse2_xorv2df3"
20329 [(set (match_operand:V2DF 0 "register_operand" "=x")
20330 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20331 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20332 "TARGET_SSE2
20333 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20334 "xorpd\t{%2, %0|%0, %2}"
20335 [(set_attr "type" "sselog")
20336 (set_attr "mode" "V2DF")])
20337
20338 ;; SSE2 integral logicals. These patterns must always come after floating
20339 ;; point ones since we don't want compiler to use integer opcodes on floating
20340 ;; point SSE values to avoid matching of subregs in the match_operand.
20341 (define_insn "*sse2_andti3"
20342 [(set (match_operand:TI 0 "register_operand" "=x")
20343 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20344 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20345 "TARGET_SSE2
20346 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20347 "pand\t{%2, %0|%0, %2}"
20348 [(set_attr "type" "sselog")
20349 (set_attr "mode" "TI")])
20350
20351 (define_insn "sse2_andv2di3"
20352 [(set (match_operand:V2DI 0 "register_operand" "=x")
20353 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20354 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20355 "TARGET_SSE2
20356 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20357 "pand\t{%2, %0|%0, %2}"
20358 [(set_attr "type" "sselog")
20359 (set_attr "mode" "TI")])
20360
20361 (define_insn "*sse2_nandti3"
20362 [(set (match_operand:TI 0 "register_operand" "=x")
20363 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20364 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20365 "TARGET_SSE2"
20366 "pandn\t{%2, %0|%0, %2}"
20367 [(set_attr "type" "sselog")
20368 (set_attr "mode" "TI")])
20369
20370 (define_insn "sse2_nandv2di3"
20371 [(set (match_operand:V2DI 0 "register_operand" "=x")
20372 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20373 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20374 "TARGET_SSE2
20375 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20376 "pandn\t{%2, %0|%0, %2}"
20377 [(set_attr "type" "sselog")
20378 (set_attr "mode" "TI")])
20379
20380 (define_insn "*sse2_iorti3"
20381 [(set (match_operand:TI 0 "register_operand" "=x")
20382 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20383 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20384 "TARGET_SSE2
20385 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20386 "por\t{%2, %0|%0, %2}"
20387 [(set_attr "type" "sselog")
20388 (set_attr "mode" "TI")])
20389
20390 (define_insn "sse2_iorv2di3"
20391 [(set (match_operand:V2DI 0 "register_operand" "=x")
20392 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20393 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20394 "TARGET_SSE2
20395 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20396 "por\t{%2, %0|%0, %2}"
20397 [(set_attr "type" "sselog")
20398 (set_attr "mode" "TI")])
20399
20400 (define_insn "*sse2_xorti3"
20401 [(set (match_operand:TI 0 "register_operand" "=x")
20402 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20403 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20404 "TARGET_SSE2
20405 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20406 "pxor\t{%2, %0|%0, %2}"
20407 [(set_attr "type" "sselog")
20408 (set_attr "mode" "TI")])
20409
20410 (define_insn "sse2_xorv2di3"
20411 [(set (match_operand:V2DI 0 "register_operand" "=x")
20412 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20413 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20414 "TARGET_SSE2
20415 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20416 "pxor\t{%2, %0|%0, %2}"
20417 [(set_attr "type" "sselog")
20418 (set_attr "mode" "TI")])
20419
20420 ;; Use xor, but don't show input operands so they aren't live before
20421 ;; this insn.
20422 (define_insn "sse_clrv4sf"
20423 [(set (match_operand:V4SF 0 "register_operand" "=x")
20424 (match_operand:V4SF 1 "const0_operand" "X"))]
20425 "TARGET_SSE"
20426 {
20427 if (get_attr_mode (insn) == MODE_TI)
20428 return "pxor\t{%0, %0|%0, %0}";
20429 else
20430 return "xorps\t{%0, %0|%0, %0}";
20431 }
20432 [(set_attr "type" "sselog")
20433 (set_attr "memory" "none")
20434 (set (attr "mode")
20435 (if_then_else
20436 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20437 (const_int 0))
20438 (ne (symbol_ref "TARGET_SSE2")
20439 (const_int 0)))
20440 (eq (symbol_ref "optimize_size")
20441 (const_int 0)))
20442 (const_string "TI")
20443 (const_string "V4SF")))])
20444
20445 ;; Use xor, but don't show input operands so they aren't live before
20446 ;; this insn.
20447 (define_insn "sse_clrv2df"
20448 [(set (match_operand:V2DF 0 "register_operand" "=x")
20449 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20450 "TARGET_SSE2"
20451 "xorpd\t{%0, %0|%0, %0}"
20452 [(set_attr "type" "sselog")
20453 (set_attr "memory" "none")
20454 (set_attr "mode" "V4SF")])
20455
20456 ;; SSE mask-generating compares
20457
20458 (define_insn "maskcmpv4sf3"
20459 [(set (match_operand:V4SI 0 "register_operand" "=x")
20460 (match_operator:V4SI 3 "sse_comparison_operator"
20461 [(match_operand:V4SF 1 "register_operand" "0")
20462 (match_operand:V4SF 2 "register_operand" "x")]))]
20463 "TARGET_SSE"
20464 "cmp%D3ps\t{%2, %0|%0, %2}"
20465 [(set_attr "type" "ssecmp")
20466 (set_attr "mode" "V4SF")])
20467
20468 (define_insn "maskncmpv4sf3"
20469 [(set (match_operand:V4SI 0 "register_operand" "=x")
20470 (not:V4SI
20471 (match_operator:V4SI 3 "sse_comparison_operator"
20472 [(match_operand:V4SF 1 "register_operand" "0")
20473 (match_operand:V4SF 2 "register_operand" "x")])))]
20474 "TARGET_SSE"
20475 {
20476 if (GET_CODE (operands[3]) == UNORDERED)
20477 return "cmpordps\t{%2, %0|%0, %2}";
20478 else
20479 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20480 }
20481 [(set_attr "type" "ssecmp")
20482 (set_attr "mode" "V4SF")])
20483
20484 (define_insn "vmmaskcmpv4sf3"
20485 [(set (match_operand:V4SI 0 "register_operand" "=x")
20486 (vec_merge:V4SI
20487 (match_operator:V4SI 3 "sse_comparison_operator"
20488 [(match_operand:V4SF 1 "register_operand" "0")
20489 (match_operand:V4SF 2 "register_operand" "x")])
20490 (subreg:V4SI (match_dup 1) 0)
20491 (const_int 1)))]
20492 "TARGET_SSE"
20493 "cmp%D3ss\t{%2, %0|%0, %2}"
20494 [(set_attr "type" "ssecmp")
20495 (set_attr "mode" "SF")])
20496
20497 (define_insn "vmmaskncmpv4sf3"
20498 [(set (match_operand:V4SI 0 "register_operand" "=x")
20499 (vec_merge:V4SI
20500 (not:V4SI
20501 (match_operator:V4SI 3 "sse_comparison_operator"
20502 [(match_operand:V4SF 1 "register_operand" "0")
20503 (match_operand:V4SF 2 "register_operand" "x")]))
20504 (subreg:V4SI (match_dup 1) 0)
20505 (const_int 1)))]
20506 "TARGET_SSE"
20507 {
20508 if (GET_CODE (operands[3]) == UNORDERED)
20509 return "cmpordss\t{%2, %0|%0, %2}";
20510 else
20511 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20512 }
20513 [(set_attr "type" "ssecmp")
20514 (set_attr "mode" "SF")])
20515
20516 (define_insn "sse_comi"
20517 [(set (reg:CCFP 17)
20518 (compare:CCFP (vec_select:SF
20519 (match_operand:V4SF 0 "register_operand" "x")
20520 (parallel [(const_int 0)]))
20521 (vec_select:SF
20522 (match_operand:V4SF 1 "register_operand" "x")
20523 (parallel [(const_int 0)]))))]
20524 "TARGET_SSE"
20525 "comiss\t{%1, %0|%0, %1}"
20526 [(set_attr "type" "ssecomi")
20527 (set_attr "mode" "SF")])
20528
20529 (define_insn "sse_ucomi"
20530 [(set (reg:CCFPU 17)
20531 (compare:CCFPU (vec_select:SF
20532 (match_operand:V4SF 0 "register_operand" "x")
20533 (parallel [(const_int 0)]))
20534 (vec_select:SF
20535 (match_operand:V4SF 1 "register_operand" "x")
20536 (parallel [(const_int 0)]))))]
20537 "TARGET_SSE"
20538 "ucomiss\t{%1, %0|%0, %1}"
20539 [(set_attr "type" "ssecomi")
20540 (set_attr "mode" "SF")])
20541
20542
20543 ;; SSE unpack
20544
20545 (define_insn "sse_unpckhps"
20546 [(set (match_operand:V4SF 0 "register_operand" "=x")
20547 (vec_merge:V4SF
20548 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20549 (parallel [(const_int 2)
20550 (const_int 0)
20551 (const_int 3)
20552 (const_int 1)]))
20553 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20554 (parallel [(const_int 0)
20555 (const_int 2)
20556 (const_int 1)
20557 (const_int 3)]))
20558 (const_int 5)))]
20559 "TARGET_SSE"
20560 "unpckhps\t{%2, %0|%0, %2}"
20561 [(set_attr "type" "ssecvt")
20562 (set_attr "mode" "V4SF")])
20563
20564 (define_insn "sse_unpcklps"
20565 [(set (match_operand:V4SF 0 "register_operand" "=x")
20566 (vec_merge:V4SF
20567 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20568 (parallel [(const_int 0)
20569 (const_int 2)
20570 (const_int 1)
20571 (const_int 3)]))
20572 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20573 (parallel [(const_int 2)
20574 (const_int 0)
20575 (const_int 3)
20576 (const_int 1)]))
20577 (const_int 5)))]
20578 "TARGET_SSE"
20579 "unpcklps\t{%2, %0|%0, %2}"
20580 [(set_attr "type" "ssecvt")
20581 (set_attr "mode" "V4SF")])
20582
20583
20584 ;; SSE min/max
20585
20586 (define_insn "smaxv4sf3"
20587 [(set (match_operand:V4SF 0 "register_operand" "=x")
20588 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20589 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20590 "TARGET_SSE"
20591 "maxps\t{%2, %0|%0, %2}"
20592 [(set_attr "type" "sse")
20593 (set_attr "mode" "V4SF")])
20594
20595 (define_insn "vmsmaxv4sf3"
20596 [(set (match_operand:V4SF 0 "register_operand" "=x")
20597 (vec_merge:V4SF
20598 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20599 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20600 (match_dup 1)
20601 (const_int 1)))]
20602 "TARGET_SSE"
20603 "maxss\t{%2, %0|%0, %2}"
20604 [(set_attr "type" "sse")
20605 (set_attr "mode" "SF")])
20606
20607 (define_insn "sminv4sf3"
20608 [(set (match_operand:V4SF 0 "register_operand" "=x")
20609 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20610 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20611 "TARGET_SSE"
20612 "minps\t{%2, %0|%0, %2}"
20613 [(set_attr "type" "sse")
20614 (set_attr "mode" "V4SF")])
20615
20616 (define_insn "vmsminv4sf3"
20617 [(set (match_operand:V4SF 0 "register_operand" "=x")
20618 (vec_merge:V4SF
20619 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20620 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20621 (match_dup 1)
20622 (const_int 1)))]
20623 "TARGET_SSE"
20624 "minss\t{%2, %0|%0, %2}"
20625 [(set_attr "type" "sse")
20626 (set_attr "mode" "SF")])
20627
20628 ;; SSE <-> integer/MMX conversions
20629
20630 (define_insn "cvtpi2ps"
20631 [(set (match_operand:V4SF 0 "register_operand" "=x")
20632 (vec_merge:V4SF
20633 (match_operand:V4SF 1 "register_operand" "0")
20634 (vec_duplicate:V4SF
20635 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20636 (const_int 12)))]
20637 "TARGET_SSE"
20638 "cvtpi2ps\t{%2, %0|%0, %2}"
20639 [(set_attr "type" "ssecvt")
20640 (set_attr "mode" "V4SF")])
20641
20642 (define_insn "cvtps2pi"
20643 [(set (match_operand:V2SI 0 "register_operand" "=y")
20644 (vec_select:V2SI
20645 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20646 (parallel [(const_int 0) (const_int 1)])))]
20647 "TARGET_SSE"
20648 "cvtps2pi\t{%1, %0|%0, %1}"
20649 [(set_attr "type" "ssecvt")
20650 (set_attr "mode" "V4SF")])
20651
20652 (define_insn "cvttps2pi"
20653 [(set (match_operand:V2SI 0 "register_operand" "=y")
20654 (vec_select:V2SI
20655 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20656 UNSPEC_FIX)
20657 (parallel [(const_int 0) (const_int 1)])))]
20658 "TARGET_SSE"
20659 "cvttps2pi\t{%1, %0|%0, %1}"
20660 [(set_attr "type" "ssecvt")
20661 (set_attr "mode" "SF")])
20662
20663 (define_insn "cvtsi2ss"
20664 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20665 (vec_merge:V4SF
20666 (match_operand:V4SF 1 "register_operand" "0,0")
20667 (vec_duplicate:V4SF
20668 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20669 (const_int 14)))]
20670 "TARGET_SSE"
20671 "cvtsi2ss\t{%2, %0|%0, %2}"
20672 [(set_attr "type" "sseicvt")
20673 (set_attr "athlon_decode" "vector,double")
20674 (set_attr "mode" "SF")])
20675
20676 (define_insn "cvtsi2ssq"
20677 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20678 (vec_merge:V4SF
20679 (match_operand:V4SF 1 "register_operand" "0,0")
20680 (vec_duplicate:V4SF
20681 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20682 (const_int 14)))]
20683 "TARGET_SSE && TARGET_64BIT"
20684 "cvtsi2ssq\t{%2, %0|%0, %2}"
20685 [(set_attr "type" "sseicvt")
20686 (set_attr "athlon_decode" "vector,double")
20687 (set_attr "mode" "SF")])
20688
20689 (define_insn "cvtss2si"
20690 [(set (match_operand:SI 0 "register_operand" "=r,r")
20691 (vec_select:SI
20692 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20693 (parallel [(const_int 0)])))]
20694 "TARGET_SSE"
20695 "cvtss2si\t{%1, %0|%0, %1}"
20696 [(set_attr "type" "sseicvt")
20697 (set_attr "athlon_decode" "double,vector")
20698 (set_attr "mode" "SI")])
20699
20700 (define_insn "cvtss2siq"
20701 [(set (match_operand:DI 0 "register_operand" "=r,r")
20702 (vec_select:DI
20703 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20704 (parallel [(const_int 0)])))]
20705 "TARGET_SSE"
20706 "cvtss2siq\t{%1, %0|%0, %1}"
20707 [(set_attr "type" "sseicvt")
20708 (set_attr "athlon_decode" "double,vector")
20709 (set_attr "mode" "DI")])
20710
20711 (define_insn "cvttss2si"
20712 [(set (match_operand:SI 0 "register_operand" "=r,r")
20713 (vec_select:SI
20714 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20715 UNSPEC_FIX)
20716 (parallel [(const_int 0)])))]
20717 "TARGET_SSE"
20718 "cvttss2si\t{%1, %0|%0, %1}"
20719 [(set_attr "type" "sseicvt")
20720 (set_attr "mode" "SF")
20721 (set_attr "athlon_decode" "double,vector")])
20722
20723 (define_insn "cvttss2siq"
20724 [(set (match_operand:DI 0 "register_operand" "=r,r")
20725 (vec_select:DI
20726 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20727 UNSPEC_FIX)
20728 (parallel [(const_int 0)])))]
20729 "TARGET_SSE && TARGET_64BIT"
20730 "cvttss2siq\t{%1, %0|%0, %1}"
20731 [(set_attr "type" "sseicvt")
20732 (set_attr "mode" "SF")
20733 (set_attr "athlon_decode" "double,vector")])
20734
20735
20736 ;; MMX insns
20737
20738 ;; MMX arithmetic
20739
20740 (define_insn "addv8qi3"
20741 [(set (match_operand:V8QI 0 "register_operand" "=y")
20742 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20743 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20744 "TARGET_MMX"
20745 "paddb\t{%2, %0|%0, %2}"
20746 [(set_attr "type" "mmxadd")
20747 (set_attr "mode" "DI")])
20748
20749 (define_insn "addv4hi3"
20750 [(set (match_operand:V4HI 0 "register_operand" "=y")
20751 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20752 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20753 "TARGET_MMX"
20754 "paddw\t{%2, %0|%0, %2}"
20755 [(set_attr "type" "mmxadd")
20756 (set_attr "mode" "DI")])
20757
20758 (define_insn "addv2si3"
20759 [(set (match_operand:V2SI 0 "register_operand" "=y")
20760 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20761 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20762 "TARGET_MMX"
20763 "paddd\t{%2, %0|%0, %2}"
20764 [(set_attr "type" "mmxadd")
20765 (set_attr "mode" "DI")])
20766
20767 (define_insn "mmx_adddi3"
20768 [(set (match_operand:DI 0 "register_operand" "=y")
20769 (unspec:DI
20770 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20771 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20772 UNSPEC_NOP))]
20773 "TARGET_MMX"
20774 "paddq\t{%2, %0|%0, %2}"
20775 [(set_attr "type" "mmxadd")
20776 (set_attr "mode" "DI")])
20777
20778 (define_insn "ssaddv8qi3"
20779 [(set (match_operand:V8QI 0 "register_operand" "=y")
20780 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20781 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20782 "TARGET_MMX"
20783 "paddsb\t{%2, %0|%0, %2}"
20784 [(set_attr "type" "mmxadd")
20785 (set_attr "mode" "DI")])
20786
20787 (define_insn "ssaddv4hi3"
20788 [(set (match_operand:V4HI 0 "register_operand" "=y")
20789 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20790 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20791 "TARGET_MMX"
20792 "paddsw\t{%2, %0|%0, %2}"
20793 [(set_attr "type" "mmxadd")
20794 (set_attr "mode" "DI")])
20795
20796 (define_insn "usaddv8qi3"
20797 [(set (match_operand:V8QI 0 "register_operand" "=y")
20798 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20799 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20800 "TARGET_MMX"
20801 "paddusb\t{%2, %0|%0, %2}"
20802 [(set_attr "type" "mmxadd")
20803 (set_attr "mode" "DI")])
20804
20805 (define_insn "usaddv4hi3"
20806 [(set (match_operand:V4HI 0 "register_operand" "=y")
20807 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20808 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20809 "TARGET_MMX"
20810 "paddusw\t{%2, %0|%0, %2}"
20811 [(set_attr "type" "mmxadd")
20812 (set_attr "mode" "DI")])
20813
20814 (define_insn "subv8qi3"
20815 [(set (match_operand:V8QI 0 "register_operand" "=y")
20816 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20817 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20818 "TARGET_MMX"
20819 "psubb\t{%2, %0|%0, %2}"
20820 [(set_attr "type" "mmxadd")
20821 (set_attr "mode" "DI")])
20822
20823 (define_insn "subv4hi3"
20824 [(set (match_operand:V4HI 0 "register_operand" "=y")
20825 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20826 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20827 "TARGET_MMX"
20828 "psubw\t{%2, %0|%0, %2}"
20829 [(set_attr "type" "mmxadd")
20830 (set_attr "mode" "DI")])
20831
20832 (define_insn "subv2si3"
20833 [(set (match_operand:V2SI 0 "register_operand" "=y")
20834 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20835 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20836 "TARGET_MMX"
20837 "psubd\t{%2, %0|%0, %2}"
20838 [(set_attr "type" "mmxadd")
20839 (set_attr "mode" "DI")])
20840
20841 (define_insn "mmx_subdi3"
20842 [(set (match_operand:DI 0 "register_operand" "=y")
20843 (unspec:DI
20844 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20845 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20846 UNSPEC_NOP))]
20847 "TARGET_MMX"
20848 "psubq\t{%2, %0|%0, %2}"
20849 [(set_attr "type" "mmxadd")
20850 (set_attr "mode" "DI")])
20851
20852 (define_insn "sssubv8qi3"
20853 [(set (match_operand:V8QI 0 "register_operand" "=y")
20854 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20855 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20856 "TARGET_MMX"
20857 "psubsb\t{%2, %0|%0, %2}"
20858 [(set_attr "type" "mmxadd")
20859 (set_attr "mode" "DI")])
20860
20861 (define_insn "sssubv4hi3"
20862 [(set (match_operand:V4HI 0 "register_operand" "=y")
20863 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20864 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20865 "TARGET_MMX"
20866 "psubsw\t{%2, %0|%0, %2}"
20867 [(set_attr "type" "mmxadd")
20868 (set_attr "mode" "DI")])
20869
20870 (define_insn "ussubv8qi3"
20871 [(set (match_operand:V8QI 0 "register_operand" "=y")
20872 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20873 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20874 "TARGET_MMX"
20875 "psubusb\t{%2, %0|%0, %2}"
20876 [(set_attr "type" "mmxadd")
20877 (set_attr "mode" "DI")])
20878
20879 (define_insn "ussubv4hi3"
20880 [(set (match_operand:V4HI 0 "register_operand" "=y")
20881 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20882 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20883 "TARGET_MMX"
20884 "psubusw\t{%2, %0|%0, %2}"
20885 [(set_attr "type" "mmxadd")
20886 (set_attr "mode" "DI")])
20887
20888 (define_insn "mulv4hi3"
20889 [(set (match_operand:V4HI 0 "register_operand" "=y")
20890 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20891 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20892 "TARGET_MMX"
20893 "pmullw\t{%2, %0|%0, %2}"
20894 [(set_attr "type" "mmxmul")
20895 (set_attr "mode" "DI")])
20896
20897 (define_insn "smulv4hi3_highpart"
20898 [(set (match_operand:V4HI 0 "register_operand" "=y")
20899 (truncate:V4HI
20900 (lshiftrt:V4SI
20901 (mult:V4SI (sign_extend:V4SI
20902 (match_operand:V4HI 1 "register_operand" "0"))
20903 (sign_extend:V4SI
20904 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20905 (const_int 16))))]
20906 "TARGET_MMX"
20907 "pmulhw\t{%2, %0|%0, %2}"
20908 [(set_attr "type" "mmxmul")
20909 (set_attr "mode" "DI")])
20910
20911 (define_insn "umulv4hi3_highpart"
20912 [(set (match_operand:V4HI 0 "register_operand" "=y")
20913 (truncate:V4HI
20914 (lshiftrt:V4SI
20915 (mult:V4SI (zero_extend:V4SI
20916 (match_operand:V4HI 1 "register_operand" "0"))
20917 (zero_extend:V4SI
20918 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20919 (const_int 16))))]
20920 "TARGET_SSE || TARGET_3DNOW_A"
20921 "pmulhuw\t{%2, %0|%0, %2}"
20922 [(set_attr "type" "mmxmul")
20923 (set_attr "mode" "DI")])
20924
20925 (define_insn "mmx_pmaddwd"
20926 [(set (match_operand:V2SI 0 "register_operand" "=y")
20927 (plus:V2SI
20928 (mult:V2SI
20929 (sign_extend:V2SI
20930 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20931 (parallel [(const_int 0) (const_int 2)])))
20932 (sign_extend:V2SI
20933 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20934 (parallel [(const_int 0) (const_int 2)]))))
20935 (mult:V2SI
20936 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20937 (parallel [(const_int 1)
20938 (const_int 3)])))
20939 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20940 (parallel [(const_int 1)
20941 (const_int 3)]))))))]
20942 "TARGET_MMX"
20943 "pmaddwd\t{%2, %0|%0, %2}"
20944 [(set_attr "type" "mmxmul")
20945 (set_attr "mode" "DI")])
20946
20947
20948 ;; MMX logical operations
20949 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20950 ;; normal code that also wants to use the FPU from getting broken.
20951 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20952 (define_insn "mmx_iordi3"
20953 [(set (match_operand:DI 0 "register_operand" "=y")
20954 (unspec:DI
20955 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20956 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20957 UNSPEC_NOP))]
20958 "TARGET_MMX"
20959 "por\t{%2, %0|%0, %2}"
20960 [(set_attr "type" "mmxadd")
20961 (set_attr "mode" "DI")])
20962
20963 (define_insn "mmx_xordi3"
20964 [(set (match_operand:DI 0 "register_operand" "=y")
20965 (unspec:DI
20966 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20967 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20968 UNSPEC_NOP))]
20969 "TARGET_MMX"
20970 "pxor\t{%2, %0|%0, %2}"
20971 [(set_attr "type" "mmxadd")
20972 (set_attr "mode" "DI")
20973 (set_attr "memory" "none")])
20974
20975 ;; Same as pxor, but don't show input operands so that we don't think
20976 ;; they are live.
20977 (define_insn "mmx_clrdi"
20978 [(set (match_operand:DI 0 "register_operand" "=y")
20979 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20980 "TARGET_MMX"
20981 "pxor\t{%0, %0|%0, %0}"
20982 [(set_attr "type" "mmxadd")
20983 (set_attr "mode" "DI")
20984 (set_attr "memory" "none")])
20985
20986 (define_insn "mmx_anddi3"
20987 [(set (match_operand:DI 0 "register_operand" "=y")
20988 (unspec:DI
20989 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20990 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20991 UNSPEC_NOP))]
20992 "TARGET_MMX"
20993 "pand\t{%2, %0|%0, %2}"
20994 [(set_attr "type" "mmxadd")
20995 (set_attr "mode" "DI")])
20996
20997 (define_insn "mmx_nanddi3"
20998 [(set (match_operand:DI 0 "register_operand" "=y")
20999 (unspec:DI
21000 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21001 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21002 UNSPEC_NOP))]
21003 "TARGET_MMX"
21004 "pandn\t{%2, %0|%0, %2}"
21005 [(set_attr "type" "mmxadd")
21006 (set_attr "mode" "DI")])
21007
21008
21009 ;; MMX unsigned averages/sum of absolute differences
21010
21011 (define_insn "mmx_uavgv8qi3"
21012 [(set (match_operand:V8QI 0 "register_operand" "=y")
21013 (ashiftrt:V8QI
21014 (plus:V8QI (plus:V8QI
21015 (match_operand:V8QI 1 "register_operand" "0")
21016 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21017 (const_vector:V8QI [(const_int 1)
21018 (const_int 1)
21019 (const_int 1)
21020 (const_int 1)
21021 (const_int 1)
21022 (const_int 1)
21023 (const_int 1)
21024 (const_int 1)]))
21025 (const_int 1)))]
21026 "TARGET_SSE || TARGET_3DNOW_A"
21027 "pavgb\t{%2, %0|%0, %2}"
21028 [(set_attr "type" "mmxshft")
21029 (set_attr "mode" "DI")])
21030
21031 (define_insn "mmx_uavgv4hi3"
21032 [(set (match_operand:V4HI 0 "register_operand" "=y")
21033 (ashiftrt:V4HI
21034 (plus:V4HI (plus:V4HI
21035 (match_operand:V4HI 1 "register_operand" "0")
21036 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21037 (const_vector:V4HI [(const_int 1)
21038 (const_int 1)
21039 (const_int 1)
21040 (const_int 1)]))
21041 (const_int 1)))]
21042 "TARGET_SSE || TARGET_3DNOW_A"
21043 "pavgw\t{%2, %0|%0, %2}"
21044 [(set_attr "type" "mmxshft")
21045 (set_attr "mode" "DI")])
21046
21047 (define_insn "mmx_psadbw"
21048 [(set (match_operand:DI 0 "register_operand" "=y")
21049 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21050 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21051 UNSPEC_PSADBW))]
21052 "TARGET_SSE || TARGET_3DNOW_A"
21053 "psadbw\t{%2, %0|%0, %2}"
21054 [(set_attr "type" "mmxshft")
21055 (set_attr "mode" "DI")])
21056
21057
21058 ;; MMX insert/extract/shuffle
21059
21060 (define_insn "mmx_pinsrw"
21061 [(set (match_operand:V4HI 0 "register_operand" "=y")
21062 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21063 (vec_duplicate:V4HI
21064 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21065 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21066 "TARGET_SSE || TARGET_3DNOW_A"
21067 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21068 [(set_attr "type" "mmxcvt")
21069 (set_attr "mode" "DI")])
21070
21071 (define_insn "mmx_pextrw"
21072 [(set (match_operand:SI 0 "register_operand" "=r")
21073 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21074 (parallel
21075 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21076 "TARGET_SSE || TARGET_3DNOW_A"
21077 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21078 [(set_attr "type" "mmxcvt")
21079 (set_attr "mode" "DI")])
21080
21081 (define_insn "mmx_pshufw"
21082 [(set (match_operand:V4HI 0 "register_operand" "=y")
21083 (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21084 (match_operand:SI 2 "immediate_operand" "i")]
21085 UNSPEC_SHUFFLE))]
21086 "TARGET_SSE || TARGET_3DNOW_A"
21087 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21088 [(set_attr "type" "mmxcvt")
21089 (set_attr "mode" "DI")])
21090
21091
21092 ;; MMX mask-generating comparisons
21093
21094 (define_insn "eqv8qi3"
21095 [(set (match_operand:V8QI 0 "register_operand" "=y")
21096 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21097 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21098 "TARGET_MMX"
21099 "pcmpeqb\t{%2, %0|%0, %2}"
21100 [(set_attr "type" "mmxcmp")
21101 (set_attr "mode" "DI")])
21102
21103 (define_insn "eqv4hi3"
21104 [(set (match_operand:V4HI 0 "register_operand" "=y")
21105 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21106 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21107 "TARGET_MMX"
21108 "pcmpeqw\t{%2, %0|%0, %2}"
21109 [(set_attr "type" "mmxcmp")
21110 (set_attr "mode" "DI")])
21111
21112 (define_insn "eqv2si3"
21113 [(set (match_operand:V2SI 0 "register_operand" "=y")
21114 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21115 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21116 "TARGET_MMX"
21117 "pcmpeqd\t{%2, %0|%0, %2}"
21118 [(set_attr "type" "mmxcmp")
21119 (set_attr "mode" "DI")])
21120
21121 (define_insn "gtv8qi3"
21122 [(set (match_operand:V8QI 0 "register_operand" "=y")
21123 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21124 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21125 "TARGET_MMX"
21126 "pcmpgtb\t{%2, %0|%0, %2}"
21127 [(set_attr "type" "mmxcmp")
21128 (set_attr "mode" "DI")])
21129
21130 (define_insn "gtv4hi3"
21131 [(set (match_operand:V4HI 0 "register_operand" "=y")
21132 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21133 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21134 "TARGET_MMX"
21135 "pcmpgtw\t{%2, %0|%0, %2}"
21136 [(set_attr "type" "mmxcmp")
21137 (set_attr "mode" "DI")])
21138
21139 (define_insn "gtv2si3"
21140 [(set (match_operand:V2SI 0 "register_operand" "=y")
21141 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21142 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21143 "TARGET_MMX"
21144 "pcmpgtd\t{%2, %0|%0, %2}"
21145 [(set_attr "type" "mmxcmp")
21146 (set_attr "mode" "DI")])
21147
21148
21149 ;; MMX max/min insns
21150
21151 (define_insn "umaxv8qi3"
21152 [(set (match_operand:V8QI 0 "register_operand" "=y")
21153 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21154 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21155 "TARGET_SSE || TARGET_3DNOW_A"
21156 "pmaxub\t{%2, %0|%0, %2}"
21157 [(set_attr "type" "mmxadd")
21158 (set_attr "mode" "DI")])
21159
21160 (define_insn "smaxv4hi3"
21161 [(set (match_operand:V4HI 0 "register_operand" "=y")
21162 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21163 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21164 "TARGET_SSE || TARGET_3DNOW_A"
21165 "pmaxsw\t{%2, %0|%0, %2}"
21166 [(set_attr "type" "mmxadd")
21167 (set_attr "mode" "DI")])
21168
21169 (define_insn "uminv8qi3"
21170 [(set (match_operand:V8QI 0 "register_operand" "=y")
21171 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21172 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21173 "TARGET_SSE || TARGET_3DNOW_A"
21174 "pminub\t{%2, %0|%0, %2}"
21175 [(set_attr "type" "mmxadd")
21176 (set_attr "mode" "DI")])
21177
21178 (define_insn "sminv4hi3"
21179 [(set (match_operand:V4HI 0 "register_operand" "=y")
21180 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21181 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21182 "TARGET_SSE || TARGET_3DNOW_A"
21183 "pminsw\t{%2, %0|%0, %2}"
21184 [(set_attr "type" "mmxadd")
21185 (set_attr "mode" "DI")])
21186
21187
21188 ;; MMX shifts
21189
21190 (define_insn "ashrv4hi3"
21191 [(set (match_operand:V4HI 0 "register_operand" "=y")
21192 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21193 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21194 "TARGET_MMX"
21195 "psraw\t{%2, %0|%0, %2}"
21196 [(set_attr "type" "mmxshft")
21197 (set_attr "mode" "DI")])
21198
21199 (define_insn "ashrv2si3"
21200 [(set (match_operand:V2SI 0 "register_operand" "=y")
21201 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21202 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21203 "TARGET_MMX"
21204 "psrad\t{%2, %0|%0, %2}"
21205 [(set_attr "type" "mmxshft")
21206 (set_attr "mode" "DI")])
21207
21208 (define_insn "lshrv4hi3"
21209 [(set (match_operand:V4HI 0 "register_operand" "=y")
21210 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21211 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21212 "TARGET_MMX"
21213 "psrlw\t{%2, %0|%0, %2}"
21214 [(set_attr "type" "mmxshft")
21215 (set_attr "mode" "DI")])
21216
21217 (define_insn "lshrv2si3"
21218 [(set (match_operand:V2SI 0 "register_operand" "=y")
21219 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21220 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21221 "TARGET_MMX"
21222 "psrld\t{%2, %0|%0, %2}"
21223 [(set_attr "type" "mmxshft")
21224 (set_attr "mode" "DI")])
21225
21226 ;; See logical MMX insns.
21227 (define_insn "mmx_lshrdi3"
21228 [(set (match_operand:DI 0 "register_operand" "=y")
21229 (unspec:DI
21230 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21231 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21232 UNSPEC_NOP))]
21233 "TARGET_MMX"
21234 "psrlq\t{%2, %0|%0, %2}"
21235 [(set_attr "type" "mmxshft")
21236 (set_attr "mode" "DI")])
21237
21238 (define_insn "ashlv4hi3"
21239 [(set (match_operand:V4HI 0 "register_operand" "=y")
21240 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21241 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21242 "TARGET_MMX"
21243 "psllw\t{%2, %0|%0, %2}"
21244 [(set_attr "type" "mmxshft")
21245 (set_attr "mode" "DI")])
21246
21247 (define_insn "ashlv2si3"
21248 [(set (match_operand:V2SI 0 "register_operand" "=y")
21249 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21250 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21251 "TARGET_MMX"
21252 "pslld\t{%2, %0|%0, %2}"
21253 [(set_attr "type" "mmxshft")
21254 (set_attr "mode" "DI")])
21255
21256 ;; See logical MMX insns.
21257 (define_insn "mmx_ashldi3"
21258 [(set (match_operand:DI 0 "register_operand" "=y")
21259 (unspec:DI
21260 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21261 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21262 UNSPEC_NOP))]
21263 "TARGET_MMX"
21264 "psllq\t{%2, %0|%0, %2}"
21265 [(set_attr "type" "mmxshft")
21266 (set_attr "mode" "DI")])
21267
21268
21269 ;; MMX pack/unpack insns.
21270
21271 (define_insn "mmx_packsswb"
21272 [(set (match_operand:V8QI 0 "register_operand" "=y")
21273 (vec_concat:V8QI
21274 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21275 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21276 "TARGET_MMX"
21277 "packsswb\t{%2, %0|%0, %2}"
21278 [(set_attr "type" "mmxshft")
21279 (set_attr "mode" "DI")])
21280
21281 (define_insn "mmx_packssdw"
21282 [(set (match_operand:V4HI 0 "register_operand" "=y")
21283 (vec_concat:V4HI
21284 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21285 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21286 "TARGET_MMX"
21287 "packssdw\t{%2, %0|%0, %2}"
21288 [(set_attr "type" "mmxshft")
21289 (set_attr "mode" "DI")])
21290
21291 (define_insn "mmx_packuswb"
21292 [(set (match_operand:V8QI 0 "register_operand" "=y")
21293 (vec_concat:V8QI
21294 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21295 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21296 "TARGET_MMX"
21297 "packuswb\t{%2, %0|%0, %2}"
21298 [(set_attr "type" "mmxshft")
21299 (set_attr "mode" "DI")])
21300
21301 (define_insn "mmx_punpckhbw"
21302 [(set (match_operand:V8QI 0 "register_operand" "=y")
21303 (vec_merge:V8QI
21304 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21305 (parallel [(const_int 4)
21306 (const_int 0)
21307 (const_int 5)
21308 (const_int 1)
21309 (const_int 6)
21310 (const_int 2)
21311 (const_int 7)
21312 (const_int 3)]))
21313 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21314 (parallel [(const_int 0)
21315 (const_int 4)
21316 (const_int 1)
21317 (const_int 5)
21318 (const_int 2)
21319 (const_int 6)
21320 (const_int 3)
21321 (const_int 7)]))
21322 (const_int 85)))]
21323 "TARGET_MMX"
21324 "punpckhbw\t{%2, %0|%0, %2}"
21325 [(set_attr "type" "mmxcvt")
21326 (set_attr "mode" "DI")])
21327
21328 (define_insn "mmx_punpckhwd"
21329 [(set (match_operand:V4HI 0 "register_operand" "=y")
21330 (vec_merge:V4HI
21331 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21332 (parallel [(const_int 0)
21333 (const_int 2)
21334 (const_int 1)
21335 (const_int 3)]))
21336 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21337 (parallel [(const_int 2)
21338 (const_int 0)
21339 (const_int 3)
21340 (const_int 1)]))
21341 (const_int 5)))]
21342 "TARGET_MMX"
21343 "punpckhwd\t{%2, %0|%0, %2}"
21344 [(set_attr "type" "mmxcvt")
21345 (set_attr "mode" "DI")])
21346
21347 (define_insn "mmx_punpckhdq"
21348 [(set (match_operand:V2SI 0 "register_operand" "=y")
21349 (vec_merge:V2SI
21350 (match_operand:V2SI 1 "register_operand" "0")
21351 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21352 (parallel [(const_int 1)
21353 (const_int 0)]))
21354 (const_int 1)))]
21355 "TARGET_MMX"
21356 "punpckhdq\t{%2, %0|%0, %2}"
21357 [(set_attr "type" "mmxcvt")
21358 (set_attr "mode" "DI")])
21359
21360 (define_insn "mmx_punpcklbw"
21361 [(set (match_operand:V8QI 0 "register_operand" "=y")
21362 (vec_merge:V8QI
21363 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21364 (parallel [(const_int 0)
21365 (const_int 4)
21366 (const_int 1)
21367 (const_int 5)
21368 (const_int 2)
21369 (const_int 6)
21370 (const_int 3)
21371 (const_int 7)]))
21372 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21373 (parallel [(const_int 4)
21374 (const_int 0)
21375 (const_int 5)
21376 (const_int 1)
21377 (const_int 6)
21378 (const_int 2)
21379 (const_int 7)
21380 (const_int 3)]))
21381 (const_int 85)))]
21382 "TARGET_MMX"
21383 "punpcklbw\t{%2, %0|%0, %2}"
21384 [(set_attr "type" "mmxcvt")
21385 (set_attr "mode" "DI")])
21386
21387 (define_insn "mmx_punpcklwd"
21388 [(set (match_operand:V4HI 0 "register_operand" "=y")
21389 (vec_merge:V4HI
21390 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21391 (parallel [(const_int 2)
21392 (const_int 0)
21393 (const_int 3)
21394 (const_int 1)]))
21395 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21396 (parallel [(const_int 0)
21397 (const_int 2)
21398 (const_int 1)
21399 (const_int 3)]))
21400 (const_int 5)))]
21401 "TARGET_MMX"
21402 "punpcklwd\t{%2, %0|%0, %2}"
21403 [(set_attr "type" "mmxcvt")
21404 (set_attr "mode" "DI")])
21405
21406 (define_insn "mmx_punpckldq"
21407 [(set (match_operand:V2SI 0 "register_operand" "=y")
21408 (vec_merge:V2SI
21409 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21410 (parallel [(const_int 1)
21411 (const_int 0)]))
21412 (match_operand:V2SI 2 "register_operand" "y")
21413 (const_int 1)))]
21414 "TARGET_MMX"
21415 "punpckldq\t{%2, %0|%0, %2}"
21416 [(set_attr "type" "mmxcvt")
21417 (set_attr "mode" "DI")])
21418
21419
21420 ;; Miscellaneous stuff
21421
21422 (define_insn "emms"
21423 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21424 (clobber (reg:XF 8))
21425 (clobber (reg:XF 9))
21426 (clobber (reg:XF 10))
21427 (clobber (reg:XF 11))
21428 (clobber (reg:XF 12))
21429 (clobber (reg:XF 13))
21430 (clobber (reg:XF 14))
21431 (clobber (reg:XF 15))
21432 (clobber (reg:DI 29))
21433 (clobber (reg:DI 30))
21434 (clobber (reg:DI 31))
21435 (clobber (reg:DI 32))
21436 (clobber (reg:DI 33))
21437 (clobber (reg:DI 34))
21438 (clobber (reg:DI 35))
21439 (clobber (reg:DI 36))]
21440 "TARGET_MMX"
21441 "emms"
21442 [(set_attr "type" "mmx")
21443 (set_attr "memory" "unknown")])
21444
21445 (define_insn "ldmxcsr"
21446 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21447 UNSPECV_LDMXCSR)]
21448 "TARGET_SSE"
21449 "ldmxcsr\t%0"
21450 [(set_attr "type" "sse")
21451 (set_attr "memory" "load")])
21452
21453 (define_insn "stmxcsr"
21454 [(set (match_operand:SI 0 "memory_operand" "=m")
21455 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21456 "TARGET_SSE"
21457 "stmxcsr\t%0"
21458 [(set_attr "type" "sse")
21459 (set_attr "memory" "store")])
21460
21461 (define_expand "sfence"
21462 [(set (match_dup 0)
21463 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21464 "TARGET_SSE || TARGET_3DNOW_A"
21465 {
21466 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21467 MEM_VOLATILE_P (operands[0]) = 1;
21468 })
21469
21470 (define_insn "*sfence_insn"
21471 [(set (match_operand:BLK 0 "" "")
21472 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21473 "TARGET_SSE || TARGET_3DNOW_A"
21474 "sfence"
21475 [(set_attr "type" "sse")
21476 (set_attr "memory" "unknown")])
21477
21478 (define_expand "sse_prologue_save"
21479 [(parallel [(set (match_operand:BLK 0 "" "")
21480 (unspec:BLK [(reg:DI 21)
21481 (reg:DI 22)
21482 (reg:DI 23)
21483 (reg:DI 24)
21484 (reg:DI 25)
21485 (reg:DI 26)
21486 (reg:DI 27)
21487 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21488 (use (match_operand:DI 1 "register_operand" ""))
21489 (use (match_operand:DI 2 "immediate_operand" ""))
21490 (use (label_ref:DI (match_operand 3 "" "")))])]
21491 "TARGET_64BIT"
21492 "")
21493
21494 (define_insn "*sse_prologue_save_insn"
21495 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21496 (match_operand:DI 4 "const_int_operand" "n")))
21497 (unspec:BLK [(reg:DI 21)
21498 (reg:DI 22)
21499 (reg:DI 23)
21500 (reg:DI 24)
21501 (reg:DI 25)
21502 (reg:DI 26)
21503 (reg:DI 27)
21504 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21505 (use (match_operand:DI 1 "register_operand" "r"))
21506 (use (match_operand:DI 2 "const_int_operand" "i"))
21507 (use (label_ref:DI (match_operand 3 "" "X")))]
21508 "TARGET_64BIT
21509 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21510 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21511 "*
21512 {
21513 int i;
21514 operands[0] = gen_rtx_MEM (Pmode,
21515 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21516 output_asm_insn (\"jmp\\t%A1\", operands);
21517 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21518 {
21519 operands[4] = adjust_address (operands[0], DImode, i*16);
21520 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21521 PUT_MODE (operands[4], TImode);
21522 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21523 output_asm_insn (\"rex\", operands);
21524 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21525 }
21526 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21527 CODE_LABEL_NUMBER (operands[3]));
21528 RET;
21529 }
21530 "
21531 [(set_attr "type" "other")
21532 (set_attr "length_immediate" "0")
21533 (set_attr "length_address" "0")
21534 (set_attr "length" "135")
21535 (set_attr "memory" "store")
21536 (set_attr "modrm" "0")
21537 (set_attr "mode" "DI")])
21538
21539 ;; 3Dnow! instructions
21540
21541 (define_insn "addv2sf3"
21542 [(set (match_operand:V2SF 0 "register_operand" "=y")
21543 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21544 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21545 "TARGET_3DNOW"
21546 "pfadd\\t{%2, %0|%0, %2}"
21547 [(set_attr "type" "mmxadd")
21548 (set_attr "mode" "V2SF")])
21549
21550 (define_insn "subv2sf3"
21551 [(set (match_operand:V2SF 0 "register_operand" "=y")
21552 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21553 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21554 "TARGET_3DNOW"
21555 "pfsub\\t{%2, %0|%0, %2}"
21556 [(set_attr "type" "mmxadd")
21557 (set_attr "mode" "V2SF")])
21558
21559 (define_insn "subrv2sf3"
21560 [(set (match_operand:V2SF 0 "register_operand" "=y")
21561 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21562 (match_operand:V2SF 1 "register_operand" "0")))]
21563 "TARGET_3DNOW"
21564 "pfsubr\\t{%2, %0|%0, %2}"
21565 [(set_attr "type" "mmxadd")
21566 (set_attr "mode" "V2SF")])
21567
21568 (define_insn "gtv2sf3"
21569 [(set (match_operand:V2SI 0 "register_operand" "=y")
21570 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21571 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21572 "TARGET_3DNOW"
21573 "pfcmpgt\\t{%2, %0|%0, %2}"
21574 [(set_attr "type" "mmxcmp")
21575 (set_attr "mode" "V2SF")])
21576
21577 (define_insn "gev2sf3"
21578 [(set (match_operand:V2SI 0 "register_operand" "=y")
21579 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21580 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21581 "TARGET_3DNOW"
21582 "pfcmpge\\t{%2, %0|%0, %2}"
21583 [(set_attr "type" "mmxcmp")
21584 (set_attr "mode" "V2SF")])
21585
21586 (define_insn "eqv2sf3"
21587 [(set (match_operand:V2SI 0 "register_operand" "=y")
21588 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21589 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21590 "TARGET_3DNOW"
21591 "pfcmpeq\\t{%2, %0|%0, %2}"
21592 [(set_attr "type" "mmxcmp")
21593 (set_attr "mode" "V2SF")])
21594
21595 (define_insn "pfmaxv2sf3"
21596 [(set (match_operand:V2SF 0 "register_operand" "=y")
21597 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21598 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21599 "TARGET_3DNOW"
21600 "pfmax\\t{%2, %0|%0, %2}"
21601 [(set_attr "type" "mmxadd")
21602 (set_attr "mode" "V2SF")])
21603
21604 (define_insn "pfminv2sf3"
21605 [(set (match_operand:V2SF 0 "register_operand" "=y")
21606 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21607 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21608 "TARGET_3DNOW"
21609 "pfmin\\t{%2, %0|%0, %2}"
21610 [(set_attr "type" "mmxadd")
21611 (set_attr "mode" "V2SF")])
21612
21613 (define_insn "mulv2sf3"
21614 [(set (match_operand:V2SF 0 "register_operand" "=y")
21615 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21616 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21617 "TARGET_3DNOW"
21618 "pfmul\\t{%2, %0|%0, %2}"
21619 [(set_attr "type" "mmxmul")
21620 (set_attr "mode" "V2SF")])
21621
21622 (define_insn "femms"
21623 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21624 (clobber (reg:XF 8))
21625 (clobber (reg:XF 9))
21626 (clobber (reg:XF 10))
21627 (clobber (reg:XF 11))
21628 (clobber (reg:XF 12))
21629 (clobber (reg:XF 13))
21630 (clobber (reg:XF 14))
21631 (clobber (reg:XF 15))
21632 (clobber (reg:DI 29))
21633 (clobber (reg:DI 30))
21634 (clobber (reg:DI 31))
21635 (clobber (reg:DI 32))
21636 (clobber (reg:DI 33))
21637 (clobber (reg:DI 34))
21638 (clobber (reg:DI 35))
21639 (clobber (reg:DI 36))]
21640 "TARGET_3DNOW"
21641 "femms"
21642 [(set_attr "type" "mmx")
21643 (set_attr "memory" "none")])
21644
21645 (define_insn "pf2id"
21646 [(set (match_operand:V2SI 0 "register_operand" "=y")
21647 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21648 "TARGET_3DNOW"
21649 "pf2id\\t{%1, %0|%0, %1}"
21650 [(set_attr "type" "mmxcvt")
21651 (set_attr "mode" "V2SF")])
21652
21653 (define_insn "pf2iw"
21654 [(set (match_operand:V2SI 0 "register_operand" "=y")
21655 (sign_extend:V2SI
21656 (ss_truncate:V2HI
21657 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21658 "TARGET_3DNOW_A"
21659 "pf2iw\\t{%1, %0|%0, %1}"
21660 [(set_attr "type" "mmxcvt")
21661 (set_attr "mode" "V2SF")])
21662
21663 (define_insn "pfacc"
21664 [(set (match_operand:V2SF 0 "register_operand" "=y")
21665 (vec_concat:V2SF
21666 (plus:SF
21667 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21668 (parallel [(const_int 0)]))
21669 (vec_select:SF (match_dup 1)
21670 (parallel [(const_int 1)])))
21671 (plus:SF
21672 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21673 (parallel [(const_int 0)]))
21674 (vec_select:SF (match_dup 2)
21675 (parallel [(const_int 1)])))))]
21676 "TARGET_3DNOW"
21677 "pfacc\\t{%2, %0|%0, %2}"
21678 [(set_attr "type" "mmxadd")
21679 (set_attr "mode" "V2SF")])
21680
21681 (define_insn "pfnacc"
21682 [(set (match_operand:V2SF 0 "register_operand" "=y")
21683 (vec_concat:V2SF
21684 (minus:SF
21685 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21686 (parallel [(const_int 0)]))
21687 (vec_select:SF (match_dup 1)
21688 (parallel [(const_int 1)])))
21689 (minus:SF
21690 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21691 (parallel [(const_int 0)]))
21692 (vec_select:SF (match_dup 2)
21693 (parallel [(const_int 1)])))))]
21694 "TARGET_3DNOW_A"
21695 "pfnacc\\t{%2, %0|%0, %2}"
21696 [(set_attr "type" "mmxadd")
21697 (set_attr "mode" "V2SF")])
21698
21699 (define_insn "pfpnacc"
21700 [(set (match_operand:V2SF 0 "register_operand" "=y")
21701 (vec_concat:V2SF
21702 (minus:SF
21703 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21704 (parallel [(const_int 0)]))
21705 (vec_select:SF (match_dup 1)
21706 (parallel [(const_int 1)])))
21707 (plus:SF
21708 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21709 (parallel [(const_int 0)]))
21710 (vec_select:SF (match_dup 2)
21711 (parallel [(const_int 1)])))))]
21712 "TARGET_3DNOW_A"
21713 "pfpnacc\\t{%2, %0|%0, %2}"
21714 [(set_attr "type" "mmxadd")
21715 (set_attr "mode" "V2SF")])
21716
21717 (define_insn "pi2fw"
21718 [(set (match_operand:V2SF 0 "register_operand" "=y")
21719 (float:V2SF
21720 (vec_concat:V2SI
21721 (sign_extend:SI
21722 (truncate:HI
21723 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21724 (parallel [(const_int 0)]))))
21725 (sign_extend:SI
21726 (truncate:HI
21727 (vec_select:SI (match_dup 1)
21728 (parallel [(const_int 1)])))))))]
21729 "TARGET_3DNOW_A"
21730 "pi2fw\\t{%1, %0|%0, %1}"
21731 [(set_attr "type" "mmxcvt")
21732 (set_attr "mode" "V2SF")])
21733
21734 (define_insn "floatv2si2"
21735 [(set (match_operand:V2SF 0 "register_operand" "=y")
21736 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21737 "TARGET_3DNOW"
21738 "pi2fd\\t{%1, %0|%0, %1}"
21739 [(set_attr "type" "mmxcvt")
21740 (set_attr "mode" "V2SF")])
21741
21742 ;; This insn is identical to pavgb in operation, but the opcode is
21743 ;; different. To avoid accidentally matching pavgb, use an unspec.
21744
21745 (define_insn "pavgusb"
21746 [(set (match_operand:V8QI 0 "register_operand" "=y")
21747 (unspec:V8QI
21748 [(match_operand:V8QI 1 "register_operand" "0")
21749 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21750 UNSPEC_PAVGUSB))]
21751 "TARGET_3DNOW"
21752 "pavgusb\\t{%2, %0|%0, %2}"
21753 [(set_attr "type" "mmxshft")
21754 (set_attr "mode" "TI")])
21755
21756 ;; 3DNow reciprocal and sqrt
21757
21758 (define_insn "pfrcpv2sf2"
21759 [(set (match_operand:V2SF 0 "register_operand" "=y")
21760 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21761 UNSPEC_PFRCP))]
21762 "TARGET_3DNOW"
21763 "pfrcp\\t{%1, %0|%0, %1}"
21764 [(set_attr "type" "mmx")
21765 (set_attr "mode" "TI")])
21766
21767 (define_insn "pfrcpit1v2sf3"
21768 [(set (match_operand:V2SF 0 "register_operand" "=y")
21769 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21770 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21771 UNSPEC_PFRCPIT1))]
21772 "TARGET_3DNOW"
21773 "pfrcpit1\\t{%2, %0|%0, %2}"
21774 [(set_attr "type" "mmx")
21775 (set_attr "mode" "TI")])
21776
21777 (define_insn "pfrcpit2v2sf3"
21778 [(set (match_operand:V2SF 0 "register_operand" "=y")
21779 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21780 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21781 UNSPEC_PFRCPIT2))]
21782 "TARGET_3DNOW"
21783 "pfrcpit2\\t{%2, %0|%0, %2}"
21784 [(set_attr "type" "mmx")
21785 (set_attr "mode" "TI")])
21786
21787 (define_insn "pfrsqrtv2sf2"
21788 [(set (match_operand:V2SF 0 "register_operand" "=y")
21789 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21790 UNSPEC_PFRSQRT))]
21791 "TARGET_3DNOW"
21792 "pfrsqrt\\t{%1, %0|%0, %1}"
21793 [(set_attr "type" "mmx")
21794 (set_attr "mode" "TI")])
21795
21796 (define_insn "pfrsqit1v2sf3"
21797 [(set (match_operand:V2SF 0 "register_operand" "=y")
21798 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21799 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21800 UNSPEC_PFRSQIT1))]
21801 "TARGET_3DNOW"
21802 "pfrsqit1\\t{%2, %0|%0, %2}"
21803 [(set_attr "type" "mmx")
21804 (set_attr "mode" "TI")])
21805
21806 (define_insn "pmulhrwv4hi3"
21807 [(set (match_operand:V4HI 0 "register_operand" "=y")
21808 (truncate:V4HI
21809 (lshiftrt:V4SI
21810 (plus:V4SI
21811 (mult:V4SI
21812 (sign_extend:V4SI
21813 (match_operand:V4HI 1 "register_operand" "0"))
21814 (sign_extend:V4SI
21815 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21816 (const_vector:V4SI [(const_int 32768)
21817 (const_int 32768)
21818 (const_int 32768)
21819 (const_int 32768)]))
21820 (const_int 16))))]
21821 "TARGET_3DNOW"
21822 "pmulhrw\\t{%2, %0|%0, %2}"
21823 [(set_attr "type" "mmxmul")
21824 (set_attr "mode" "TI")])
21825
21826 (define_insn "pswapdv2si2"
21827 [(set (match_operand:V2SI 0 "register_operand" "=y")
21828 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21829 (parallel [(const_int 1) (const_int 0)])))]
21830 "TARGET_3DNOW_A"
21831 "pswapd\\t{%1, %0|%0, %1}"
21832 [(set_attr "type" "mmxcvt")
21833 (set_attr "mode" "TI")])
21834
21835 (define_insn "pswapdv2sf2"
21836 [(set (match_operand:V2SF 0 "register_operand" "=y")
21837 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21838 (parallel [(const_int 1) (const_int 0)])))]
21839 "TARGET_3DNOW_A"
21840 "pswapd\\t{%1, %0|%0, %1}"
21841 [(set_attr "type" "mmxcvt")
21842 (set_attr "mode" "TI")])
21843
21844 (define_expand "prefetch"
21845 [(prefetch (match_operand 0 "address_operand" "")
21846 (match_operand:SI 1 "const_int_operand" "")
21847 (match_operand:SI 2 "const_int_operand" ""))]
21848 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21849 {
21850 int rw = INTVAL (operands[1]);
21851 int locality = INTVAL (operands[2]);
21852
21853 if (rw != 0 && rw != 1)
21854 abort ();
21855 if (locality < 0 || locality > 3)
21856 abort ();
21857 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21858 abort ();
21859
21860 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21861 suported by SSE counterpart or the SSE prefetch is not available
21862 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21863 of locality. */
21864 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21865 operands[2] = GEN_INT (3);
21866 else
21867 operands[1] = const0_rtx;
21868 })
21869
21870 (define_insn "*prefetch_sse"
21871 [(prefetch (match_operand:SI 0 "address_operand" "p")
21872 (const_int 0)
21873 (match_operand:SI 1 "const_int_operand" ""))]
21874 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21875 {
21876 static const char * const patterns[4] = {
21877 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21878 };
21879
21880 int locality = INTVAL (operands[1]);
21881 if (locality < 0 || locality > 3)
21882 abort ();
21883
21884 return patterns[locality];
21885 }
21886 [(set_attr "type" "sse")
21887 (set_attr "memory" "none")])
21888
21889 (define_insn "*prefetch_sse_rex"
21890 [(prefetch (match_operand:DI 0 "address_operand" "p")
21891 (const_int 0)
21892 (match_operand:SI 1 "const_int_operand" ""))]
21893 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21894 {
21895 static const char * const patterns[4] = {
21896 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21897 };
21898
21899 int locality = INTVAL (operands[1]);
21900 if (locality < 0 || locality > 3)
21901 abort ();
21902
21903 return patterns[locality];
21904 }
21905 [(set_attr "type" "sse")
21906 (set_attr "memory" "none")])
21907
21908 (define_insn "*prefetch_3dnow"
21909 [(prefetch (match_operand:SI 0 "address_operand" "p")
21910 (match_operand:SI 1 "const_int_operand" "n")
21911 (const_int 3))]
21912 "TARGET_3DNOW && !TARGET_64BIT"
21913 {
21914 if (INTVAL (operands[1]) == 0)
21915 return "prefetch\t%a0";
21916 else
21917 return "prefetchw\t%a0";
21918 }
21919 [(set_attr "type" "mmx")
21920 (set_attr "memory" "none")])
21921
21922 (define_insn "*prefetch_3dnow_rex"
21923 [(prefetch (match_operand:DI 0 "address_operand" "p")
21924 (match_operand:SI 1 "const_int_operand" "n")
21925 (const_int 3))]
21926 "TARGET_3DNOW && TARGET_64BIT"
21927 {
21928 if (INTVAL (operands[1]) == 0)
21929 return "prefetch\t%a0";
21930 else
21931 return "prefetchw\t%a0";
21932 }
21933 [(set_attr "type" "mmx")
21934 (set_attr "memory" "none")])
21935
21936 ;; SSE2 support
21937
21938 (define_insn "addv2df3"
21939 [(set (match_operand:V2DF 0 "register_operand" "=x")
21940 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21941 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21942 "TARGET_SSE2"
21943 "addpd\t{%2, %0|%0, %2}"
21944 [(set_attr "type" "sseadd")
21945 (set_attr "mode" "V2DF")])
21946
21947 (define_insn "vmaddv2df3"
21948 [(set (match_operand:V2DF 0 "register_operand" "=x")
21949 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21950 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21951 (match_dup 1)
21952 (const_int 1)))]
21953 "TARGET_SSE2"
21954 "addsd\t{%2, %0|%0, %2}"
21955 [(set_attr "type" "sseadd")
21956 (set_attr "mode" "DF")])
21957
21958 (define_insn "subv2df3"
21959 [(set (match_operand:V2DF 0 "register_operand" "=x")
21960 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21961 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21962 "TARGET_SSE2"
21963 "subpd\t{%2, %0|%0, %2}"
21964 [(set_attr "type" "sseadd")
21965 (set_attr "mode" "V2DF")])
21966
21967 (define_insn "vmsubv2df3"
21968 [(set (match_operand:V2DF 0 "register_operand" "=x")
21969 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21970 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21971 (match_dup 1)
21972 (const_int 1)))]
21973 "TARGET_SSE2"
21974 "subsd\t{%2, %0|%0, %2}"
21975 [(set_attr "type" "sseadd")
21976 (set_attr "mode" "DF")])
21977
21978 (define_insn "mulv2df3"
21979 [(set (match_operand:V2DF 0 "register_operand" "=x")
21980 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21981 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21982 "TARGET_SSE2"
21983 "mulpd\t{%2, %0|%0, %2}"
21984 [(set_attr "type" "ssemul")
21985 (set_attr "mode" "V2DF")])
21986
21987 (define_insn "vmmulv2df3"
21988 [(set (match_operand:V2DF 0 "register_operand" "=x")
21989 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21990 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21991 (match_dup 1)
21992 (const_int 1)))]
21993 "TARGET_SSE2"
21994 "mulsd\t{%2, %0|%0, %2}"
21995 [(set_attr "type" "ssemul")
21996 (set_attr "mode" "DF")])
21997
21998 (define_insn "divv2df3"
21999 [(set (match_operand:V2DF 0 "register_operand" "=x")
22000 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22001 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22002 "TARGET_SSE2"
22003 "divpd\t{%2, %0|%0, %2}"
22004 [(set_attr "type" "ssediv")
22005 (set_attr "mode" "V2DF")])
22006
22007 (define_insn "vmdivv2df3"
22008 [(set (match_operand:V2DF 0 "register_operand" "=x")
22009 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22010 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22011 (match_dup 1)
22012 (const_int 1)))]
22013 "TARGET_SSE2"
22014 "divsd\t{%2, %0|%0, %2}"
22015 [(set_attr "type" "ssediv")
22016 (set_attr "mode" "DF")])
22017
22018 ;; SSE min/max
22019
22020 (define_insn "smaxv2df3"
22021 [(set (match_operand:V2DF 0 "register_operand" "=x")
22022 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22023 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22024 "TARGET_SSE2"
22025 "maxpd\t{%2, %0|%0, %2}"
22026 [(set_attr "type" "sseadd")
22027 (set_attr "mode" "V2DF")])
22028
22029 (define_insn "vmsmaxv2df3"
22030 [(set (match_operand:V2DF 0 "register_operand" "=x")
22031 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22032 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22033 (match_dup 1)
22034 (const_int 1)))]
22035 "TARGET_SSE2"
22036 "maxsd\t{%2, %0|%0, %2}"
22037 [(set_attr "type" "sseadd")
22038 (set_attr "mode" "DF")])
22039
22040 (define_insn "sminv2df3"
22041 [(set (match_operand:V2DF 0 "register_operand" "=x")
22042 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22043 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22044 "TARGET_SSE2"
22045 "minpd\t{%2, %0|%0, %2}"
22046 [(set_attr "type" "sseadd")
22047 (set_attr "mode" "V2DF")])
22048
22049 (define_insn "vmsminv2df3"
22050 [(set (match_operand:V2DF 0 "register_operand" "=x")
22051 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22052 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22053 (match_dup 1)
22054 (const_int 1)))]
22055 "TARGET_SSE2"
22056 "minsd\t{%2, %0|%0, %2}"
22057 [(set_attr "type" "sseadd")
22058 (set_attr "mode" "DF")])
22059 ;; SSE2 square root. There doesn't appear to be an extension for the
22060 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22061
22062 (define_insn "sqrtv2df2"
22063 [(set (match_operand:V2DF 0 "register_operand" "=x")
22064 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22065 "TARGET_SSE2"
22066 "sqrtpd\t{%1, %0|%0, %1}"
22067 [(set_attr "type" "sse")
22068 (set_attr "mode" "V2DF")])
22069
22070 (define_insn "vmsqrtv2df2"
22071 [(set (match_operand:V2DF 0 "register_operand" "=x")
22072 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22073 (match_operand:V2DF 2 "register_operand" "0")
22074 (const_int 1)))]
22075 "TARGET_SSE2"
22076 "sqrtsd\t{%1, %0|%0, %1}"
22077 [(set_attr "type" "sse")
22078 (set_attr "mode" "SF")])
22079
22080 ;; SSE mask-generating compares
22081
22082 (define_insn "maskcmpv2df3"
22083 [(set (match_operand:V2DI 0 "register_operand" "=x")
22084 (match_operator:V2DI 3 "sse_comparison_operator"
22085 [(match_operand:V2DF 1 "register_operand" "0")
22086 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22087 "TARGET_SSE2"
22088 "cmp%D3pd\t{%2, %0|%0, %2}"
22089 [(set_attr "type" "ssecmp")
22090 (set_attr "mode" "V2DF")])
22091
22092 (define_insn "maskncmpv2df3"
22093 [(set (match_operand:V2DI 0 "register_operand" "=x")
22094 (not:V2DI
22095 (match_operator:V2DI 3 "sse_comparison_operator"
22096 [(match_operand:V2DF 1 "register_operand" "0")
22097 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22098 "TARGET_SSE2"
22099 {
22100 if (GET_CODE (operands[3]) == UNORDERED)
22101 return "cmpordps\t{%2, %0|%0, %2}";
22102 else
22103 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22104 }
22105 [(set_attr "type" "ssecmp")
22106 (set_attr "mode" "V2DF")])
22107
22108 (define_insn "vmmaskcmpv2df3"
22109 [(set (match_operand:V2DI 0 "register_operand" "=x")
22110 (vec_merge:V2DI
22111 (match_operator:V2DI 3 "sse_comparison_operator"
22112 [(match_operand:V2DF 1 "register_operand" "0")
22113 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22114 (subreg:V2DI (match_dup 1) 0)
22115 (const_int 1)))]
22116 "TARGET_SSE2"
22117 "cmp%D3sd\t{%2, %0|%0, %2}"
22118 [(set_attr "type" "ssecmp")
22119 (set_attr "mode" "DF")])
22120
22121 (define_insn "vmmaskncmpv2df3"
22122 [(set (match_operand:V2DI 0 "register_operand" "=x")
22123 (vec_merge:V2DI
22124 (not:V2DI
22125 (match_operator:V2DI 3 "sse_comparison_operator"
22126 [(match_operand:V2DF 1 "register_operand" "0")
22127 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22128 (subreg:V2DI (match_dup 1) 0)
22129 (const_int 1)))]
22130 "TARGET_SSE2"
22131 {
22132 if (GET_CODE (operands[3]) == UNORDERED)
22133 return "cmpordsd\t{%2, %0|%0, %2}";
22134 else
22135 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22136 }
22137 [(set_attr "type" "ssecmp")
22138 (set_attr "mode" "DF")])
22139
22140 (define_insn "sse2_comi"
22141 [(set (reg:CCFP 17)
22142 (compare:CCFP (vec_select:DF
22143 (match_operand:V2DF 0 "register_operand" "x")
22144 (parallel [(const_int 0)]))
22145 (vec_select:DF
22146 (match_operand:V2DF 1 "register_operand" "x")
22147 (parallel [(const_int 0)]))))]
22148 "TARGET_SSE2"
22149 "comisd\t{%1, %0|%0, %1}"
22150 [(set_attr "type" "ssecomi")
22151 (set_attr "mode" "DF")])
22152
22153 (define_insn "sse2_ucomi"
22154 [(set (reg:CCFPU 17)
22155 (compare:CCFPU (vec_select:DF
22156 (match_operand:V2DF 0 "register_operand" "x")
22157 (parallel [(const_int 0)]))
22158 (vec_select:DF
22159 (match_operand:V2DF 1 "register_operand" "x")
22160 (parallel [(const_int 0)]))))]
22161 "TARGET_SSE2"
22162 "ucomisd\t{%1, %0|%0, %1}"
22163 [(set_attr "type" "ssecomi")
22164 (set_attr "mode" "DF")])
22165
22166 ;; SSE Strange Moves.
22167
22168 (define_insn "sse2_movmskpd"
22169 [(set (match_operand:SI 0 "register_operand" "=r")
22170 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22171 UNSPEC_MOVMSK))]
22172 "TARGET_SSE2"
22173 "movmskpd\t{%1, %0|%0, %1}"
22174 [(set_attr "type" "ssecvt")
22175 (set_attr "mode" "V2DF")])
22176
22177 (define_insn "sse2_pmovmskb"
22178 [(set (match_operand:SI 0 "register_operand" "=r")
22179 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22180 UNSPEC_MOVMSK))]
22181 "TARGET_SSE2"
22182 "pmovmskb\t{%1, %0|%0, %1}"
22183 [(set_attr "type" "ssecvt")
22184 (set_attr "mode" "V2DF")])
22185
22186 (define_insn "sse2_maskmovdqu"
22187 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22188 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22189 (match_operand:V16QI 2 "register_operand" "x")]
22190 UNSPEC_MASKMOV))]
22191 "TARGET_SSE2"
22192 ;; @@@ check ordering of operands in intel/nonintel syntax
22193 "maskmovdqu\t{%2, %1|%1, %2}"
22194 [(set_attr "type" "ssecvt")
22195 (set_attr "mode" "TI")])
22196
22197 (define_insn "sse2_maskmovdqu_rex64"
22198 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22199 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22200 (match_operand:V16QI 2 "register_operand" "x")]
22201 UNSPEC_MASKMOV))]
22202 "TARGET_SSE2"
22203 ;; @@@ check ordering of operands in intel/nonintel syntax
22204 "maskmovdqu\t{%2, %1|%1, %2}"
22205 [(set_attr "type" "ssecvt")
22206 (set_attr "mode" "TI")])
22207
22208 (define_insn "sse2_movntv2df"
22209 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22210 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22211 UNSPEC_MOVNT))]
22212 "TARGET_SSE2"
22213 "movntpd\t{%1, %0|%0, %1}"
22214 [(set_attr "type" "ssecvt")
22215 (set_attr "mode" "V2DF")])
22216
22217 (define_insn "sse2_movntv2di"
22218 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22219 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22220 UNSPEC_MOVNT))]
22221 "TARGET_SSE2"
22222 "movntdq\t{%1, %0|%0, %1}"
22223 [(set_attr "type" "ssecvt")
22224 (set_attr "mode" "TI")])
22225
22226 (define_insn "sse2_movntsi"
22227 [(set (match_operand:SI 0 "memory_operand" "=m")
22228 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22229 UNSPEC_MOVNT))]
22230 "TARGET_SSE2"
22231 "movnti\t{%1, %0|%0, %1}"
22232 [(set_attr "type" "ssecvt")
22233 (set_attr "mode" "V2DF")])
22234
22235 ;; SSE <-> integer/MMX conversions
22236
22237 ;; Conversions between SI and SF
22238
22239 (define_insn "cvtdq2ps"
22240 [(set (match_operand:V4SF 0 "register_operand" "=x")
22241 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22242 "TARGET_SSE2"
22243 "cvtdq2ps\t{%1, %0|%0, %1}"
22244 [(set_attr "type" "ssecvt")
22245 (set_attr "mode" "V2DF")])
22246
22247 (define_insn "cvtps2dq"
22248 [(set (match_operand:V4SI 0 "register_operand" "=x")
22249 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22250 "TARGET_SSE2"
22251 "cvtps2dq\t{%1, %0|%0, %1}"
22252 [(set_attr "type" "ssecvt")
22253 (set_attr "mode" "TI")])
22254
22255 (define_insn "cvttps2dq"
22256 [(set (match_operand:V4SI 0 "register_operand" "=x")
22257 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22258 UNSPEC_FIX))]
22259 "TARGET_SSE2"
22260 "cvttps2dq\t{%1, %0|%0, %1}"
22261 [(set_attr "type" "ssecvt")
22262 (set_attr "mode" "TI")])
22263
22264 ;; Conversions between SI and DF
22265
22266 (define_insn "cvtdq2pd"
22267 [(set (match_operand:V2DF 0 "register_operand" "=x")
22268 (float:V2DF (vec_select:V2SI
22269 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22270 (parallel
22271 [(const_int 0)
22272 (const_int 1)]))))]
22273 "TARGET_SSE2"
22274 "cvtdq2pd\t{%1, %0|%0, %1}"
22275 [(set_attr "type" "ssecvt")
22276 (set_attr "mode" "V2DF")])
22277
22278 (define_insn "cvtpd2dq"
22279 [(set (match_operand:V4SI 0 "register_operand" "=x")
22280 (vec_concat:V4SI
22281 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22282 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22283 "TARGET_SSE2"
22284 "cvtpd2dq\t{%1, %0|%0, %1}"
22285 [(set_attr "type" "ssecvt")
22286 (set_attr "mode" "TI")])
22287
22288 (define_insn "cvttpd2dq"
22289 [(set (match_operand:V4SI 0 "register_operand" "=x")
22290 (vec_concat:V4SI
22291 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22292 UNSPEC_FIX)
22293 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22294 "TARGET_SSE2"
22295 "cvttpd2dq\t{%1, %0|%0, %1}"
22296 [(set_attr "type" "ssecvt")
22297 (set_attr "mode" "TI")])
22298
22299 (define_insn "cvtpd2pi"
22300 [(set (match_operand:V2SI 0 "register_operand" "=y")
22301 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22302 "TARGET_SSE2"
22303 "cvtpd2pi\t{%1, %0|%0, %1}"
22304 [(set_attr "type" "ssecvt")
22305 (set_attr "mode" "TI")])
22306
22307 (define_insn "cvttpd2pi"
22308 [(set (match_operand:V2SI 0 "register_operand" "=y")
22309 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22310 UNSPEC_FIX))]
22311 "TARGET_SSE2"
22312 "cvttpd2pi\t{%1, %0|%0, %1}"
22313 [(set_attr "type" "ssecvt")
22314 (set_attr "mode" "TI")])
22315
22316 (define_insn "cvtpi2pd"
22317 [(set (match_operand:V2DF 0 "register_operand" "=x")
22318 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22319 "TARGET_SSE2"
22320 "cvtpi2pd\t{%1, %0|%0, %1}"
22321 [(set_attr "type" "ssecvt")
22322 (set_attr "mode" "TI")])
22323
22324 ;; Conversions between SI and DF
22325
22326 (define_insn "cvtsd2si"
22327 [(set (match_operand:SI 0 "register_operand" "=r,r")
22328 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22329 (parallel [(const_int 0)]))))]
22330 "TARGET_SSE2"
22331 "cvtsd2si\t{%1, %0|%0, %1}"
22332 [(set_attr "type" "sseicvt")
22333 (set_attr "athlon_decode" "double,vector")
22334 (set_attr "mode" "SI")])
22335
22336 (define_insn "cvtsd2siq"
22337 [(set (match_operand:DI 0 "register_operand" "=r,r")
22338 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22339 (parallel [(const_int 0)]))))]
22340 "TARGET_SSE2 && TARGET_64BIT"
22341 "cvtsd2siq\t{%1, %0|%0, %1}"
22342 [(set_attr "type" "sseicvt")
22343 (set_attr "athlon_decode" "double,vector")
22344 (set_attr "mode" "DI")])
22345
22346 (define_insn "cvttsd2si"
22347 [(set (match_operand:SI 0 "register_operand" "=r,r")
22348 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22349 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22350 "TARGET_SSE2"
22351 "cvttsd2si\t{%1, %0|%0, %1}"
22352 [(set_attr "type" "sseicvt")
22353 (set_attr "mode" "SI")
22354 (set_attr "athlon_decode" "double,vector")])
22355
22356 (define_insn "cvttsd2siq"
22357 [(set (match_operand:DI 0 "register_operand" "=r,r")
22358 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22359 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22360 "TARGET_SSE2 && TARGET_64BIT"
22361 "cvttsd2siq\t{%1, %0|%0, %1}"
22362 [(set_attr "type" "sseicvt")
22363 (set_attr "mode" "DI")
22364 (set_attr "athlon_decode" "double,vector")])
22365
22366 (define_insn "cvtsi2sd"
22367 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22368 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22369 (vec_duplicate:V2DF
22370 (float:DF
22371 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22372 (const_int 2)))]
22373 "TARGET_SSE2"
22374 "cvtsi2sd\t{%2, %0|%0, %2}"
22375 [(set_attr "type" "sseicvt")
22376 (set_attr "mode" "DF")
22377 (set_attr "athlon_decode" "double,direct")])
22378
22379 (define_insn "cvtsi2sdq"
22380 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22381 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22382 (vec_duplicate:V2DF
22383 (float:DF
22384 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22385 (const_int 2)))]
22386 "TARGET_SSE2 && TARGET_64BIT"
22387 "cvtsi2sdq\t{%2, %0|%0, %2}"
22388 [(set_attr "type" "sseicvt")
22389 (set_attr "mode" "DF")
22390 (set_attr "athlon_decode" "double,direct")])
22391
22392 ;; Conversions between SF and DF
22393
22394 (define_insn "cvtsd2ss"
22395 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22396 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22397 (vec_duplicate:V4SF
22398 (float_truncate:V2SF
22399 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22400 (const_int 14)))]
22401 "TARGET_SSE2"
22402 "cvtsd2ss\t{%2, %0|%0, %2}"
22403 [(set_attr "type" "ssecvt")
22404 (set_attr "athlon_decode" "vector,double")
22405 (set_attr "mode" "SF")])
22406
22407 (define_insn "cvtss2sd"
22408 [(set (match_operand:V2DF 0 "register_operand" "=x")
22409 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22410 (float_extend:V2DF
22411 (vec_select:V2SF
22412 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22413 (parallel [(const_int 0)
22414 (const_int 1)])))
22415 (const_int 2)))]
22416 "TARGET_SSE2"
22417 "cvtss2sd\t{%2, %0|%0, %2}"
22418 [(set_attr "type" "ssecvt")
22419 (set_attr "mode" "DF")])
22420
22421 (define_insn "cvtpd2ps"
22422 [(set (match_operand:V4SF 0 "register_operand" "=x")
22423 (subreg:V4SF
22424 (vec_concat:V4SI
22425 (subreg:V2SI (float_truncate:V2SF
22426 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22427 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22428 "TARGET_SSE2"
22429 "cvtpd2ps\t{%1, %0|%0, %1}"
22430 [(set_attr "type" "ssecvt")
22431 (set_attr "mode" "V4SF")])
22432
22433 (define_insn "cvtps2pd"
22434 [(set (match_operand:V2DF 0 "register_operand" "=x")
22435 (float_extend:V2DF
22436 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22437 (parallel [(const_int 0)
22438 (const_int 1)]))))]
22439 "TARGET_SSE2"
22440 "cvtps2pd\t{%1, %0|%0, %1}"
22441 [(set_attr "type" "ssecvt")
22442 (set_attr "mode" "V2DF")])
22443
22444 ;; SSE2 variants of MMX insns
22445
22446 ;; MMX arithmetic
22447
22448 (define_insn "addv16qi3"
22449 [(set (match_operand:V16QI 0 "register_operand" "=x")
22450 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22451 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22452 "TARGET_SSE2"
22453 "paddb\t{%2, %0|%0, %2}"
22454 [(set_attr "type" "sseiadd")
22455 (set_attr "mode" "TI")])
22456
22457 (define_insn "addv8hi3"
22458 [(set (match_operand:V8HI 0 "register_operand" "=x")
22459 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22460 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22461 "TARGET_SSE2"
22462 "paddw\t{%2, %0|%0, %2}"
22463 [(set_attr "type" "sseiadd")
22464 (set_attr "mode" "TI")])
22465
22466 (define_insn "addv4si3"
22467 [(set (match_operand:V4SI 0 "register_operand" "=x")
22468 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22469 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22470 "TARGET_SSE2"
22471 "paddd\t{%2, %0|%0, %2}"
22472 [(set_attr "type" "sseiadd")
22473 (set_attr "mode" "TI")])
22474
22475 (define_insn "addv2di3"
22476 [(set (match_operand:V2DI 0 "register_operand" "=x")
22477 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22478 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22479 "TARGET_SSE2"
22480 "paddq\t{%2, %0|%0, %2}"
22481 [(set_attr "type" "sseiadd")
22482 (set_attr "mode" "TI")])
22483
22484 (define_insn "ssaddv16qi3"
22485 [(set (match_operand:V16QI 0 "register_operand" "=x")
22486 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22487 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22488 "TARGET_SSE2"
22489 "paddsb\t{%2, %0|%0, %2}"
22490 [(set_attr "type" "sseiadd")
22491 (set_attr "mode" "TI")])
22492
22493 (define_insn "ssaddv8hi3"
22494 [(set (match_operand:V8HI 0 "register_operand" "=x")
22495 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22496 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22497 "TARGET_SSE2"
22498 "paddsw\t{%2, %0|%0, %2}"
22499 [(set_attr "type" "sseiadd")
22500 (set_attr "mode" "TI")])
22501
22502 (define_insn "usaddv16qi3"
22503 [(set (match_operand:V16QI 0 "register_operand" "=x")
22504 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22505 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22506 "TARGET_SSE2"
22507 "paddusb\t{%2, %0|%0, %2}"
22508 [(set_attr "type" "sseiadd")
22509 (set_attr "mode" "TI")])
22510
22511 (define_insn "usaddv8hi3"
22512 [(set (match_operand:V8HI 0 "register_operand" "=x")
22513 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22514 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22515 "TARGET_SSE2"
22516 "paddusw\t{%2, %0|%0, %2}"
22517 [(set_attr "type" "sseiadd")
22518 (set_attr "mode" "TI")])
22519
22520 (define_insn "subv16qi3"
22521 [(set (match_operand:V16QI 0 "register_operand" "=x")
22522 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22523 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22524 "TARGET_SSE2"
22525 "psubb\t{%2, %0|%0, %2}"
22526 [(set_attr "type" "sseiadd")
22527 (set_attr "mode" "TI")])
22528
22529 (define_insn "subv8hi3"
22530 [(set (match_operand:V8HI 0 "register_operand" "=x")
22531 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22532 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22533 "TARGET_SSE2"
22534 "psubw\t{%2, %0|%0, %2}"
22535 [(set_attr "type" "sseiadd")
22536 (set_attr "mode" "TI")])
22537
22538 (define_insn "subv4si3"
22539 [(set (match_operand:V4SI 0 "register_operand" "=x")
22540 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22541 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22542 "TARGET_SSE2"
22543 "psubd\t{%2, %0|%0, %2}"
22544 [(set_attr "type" "sseiadd")
22545 (set_attr "mode" "TI")])
22546
22547 (define_insn "subv2di3"
22548 [(set (match_operand:V2DI 0 "register_operand" "=x")
22549 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22550 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22551 "TARGET_SSE2"
22552 "psubq\t{%2, %0|%0, %2}"
22553 [(set_attr "type" "sseiadd")
22554 (set_attr "mode" "TI")])
22555
22556 (define_insn "sssubv16qi3"
22557 [(set (match_operand:V16QI 0 "register_operand" "=x")
22558 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22559 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22560 "TARGET_SSE2"
22561 "psubsb\t{%2, %0|%0, %2}"
22562 [(set_attr "type" "sseiadd")
22563 (set_attr "mode" "TI")])
22564
22565 (define_insn "sssubv8hi3"
22566 [(set (match_operand:V8HI 0 "register_operand" "=x")
22567 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22568 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22569 "TARGET_SSE2"
22570 "psubsw\t{%2, %0|%0, %2}"
22571 [(set_attr "type" "sseiadd")
22572 (set_attr "mode" "TI")])
22573
22574 (define_insn "ussubv16qi3"
22575 [(set (match_operand:V16QI 0 "register_operand" "=x")
22576 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22577 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22578 "TARGET_SSE2"
22579 "psubusb\t{%2, %0|%0, %2}"
22580 [(set_attr "type" "sseiadd")
22581 (set_attr "mode" "TI")])
22582
22583 (define_insn "ussubv8hi3"
22584 [(set (match_operand:V8HI 0 "register_operand" "=x")
22585 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22586 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22587 "TARGET_SSE2"
22588 "psubusw\t{%2, %0|%0, %2}"
22589 [(set_attr "type" "sseiadd")
22590 (set_attr "mode" "TI")])
22591
22592 (define_insn "mulv8hi3"
22593 [(set (match_operand:V8HI 0 "register_operand" "=x")
22594 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22595 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22596 "TARGET_SSE2"
22597 "pmullw\t{%2, %0|%0, %2}"
22598 [(set_attr "type" "sseimul")
22599 (set_attr "mode" "TI")])
22600
22601 (define_insn "smulv8hi3_highpart"
22602 [(set (match_operand:V8HI 0 "register_operand" "=x")
22603 (truncate:V8HI
22604 (lshiftrt:V8SI
22605 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22606 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22607 (const_int 16))))]
22608 "TARGET_SSE2"
22609 "pmulhw\t{%2, %0|%0, %2}"
22610 [(set_attr "type" "sseimul")
22611 (set_attr "mode" "TI")])
22612
22613 (define_insn "umulv8hi3_highpart"
22614 [(set (match_operand:V8HI 0 "register_operand" "=x")
22615 (truncate:V8HI
22616 (lshiftrt:V8SI
22617 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22618 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22619 (const_int 16))))]
22620 "TARGET_SSE2"
22621 "pmulhuw\t{%2, %0|%0, %2}"
22622 [(set_attr "type" "sseimul")
22623 (set_attr "mode" "TI")])
22624
22625 (define_insn "sse2_umulsidi3"
22626 [(set (match_operand:DI 0 "register_operand" "=y")
22627 (mult:DI (zero_extend:DI (vec_select:SI
22628 (match_operand:V2SI 1 "register_operand" "0")
22629 (parallel [(const_int 0)])))
22630 (zero_extend:DI (vec_select:SI
22631 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22632 (parallel [(const_int 0)])))))]
22633 "TARGET_SSE2"
22634 "pmuludq\t{%2, %0|%0, %2}"
22635 [(set_attr "type" "sseimul")
22636 (set_attr "mode" "TI")])
22637
22638 (define_insn "sse2_umulv2siv2di3"
22639 [(set (match_operand:V2DI 0 "register_operand" "=x")
22640 (mult:V2DI (zero_extend:V2DI
22641 (vec_select:V2SI
22642 (match_operand:V4SI 1 "register_operand" "0")
22643 (parallel [(const_int 0) (const_int 2)])))
22644 (zero_extend:V2DI
22645 (vec_select:V2SI
22646 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22647 (parallel [(const_int 0) (const_int 2)])))))]
22648 "TARGET_SSE2"
22649 "pmuludq\t{%2, %0|%0, %2}"
22650 [(set_attr "type" "sseimul")
22651 (set_attr "mode" "TI")])
22652
22653 (define_insn "sse2_pmaddwd"
22654 [(set (match_operand:V4SI 0 "register_operand" "=x")
22655 (plus:V4SI
22656 (mult:V4SI
22657 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22658 (parallel [(const_int 0)
22659 (const_int 2)
22660 (const_int 4)
22661 (const_int 6)])))
22662 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22663 (parallel [(const_int 0)
22664 (const_int 2)
22665 (const_int 4)
22666 (const_int 6)]))))
22667 (mult:V4SI
22668 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22669 (parallel [(const_int 1)
22670 (const_int 3)
22671 (const_int 5)
22672 (const_int 7)])))
22673 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22674 (parallel [(const_int 1)
22675 (const_int 3)
22676 (const_int 5)
22677 (const_int 7)]))))))]
22678 "TARGET_SSE2"
22679 "pmaddwd\t{%2, %0|%0, %2}"
22680 [(set_attr "type" "sseiadd")
22681 (set_attr "mode" "TI")])
22682
22683 ;; Same as pxor, but don't show input operands so that we don't think
22684 ;; they are live.
22685 (define_insn "sse2_clrti"
22686 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22687 "TARGET_SSE2"
22688 {
22689 if (get_attr_mode (insn) == MODE_TI)
22690 return "pxor\t%0, %0";
22691 else
22692 return "xorps\t%0, %0";
22693 }
22694 [(set_attr "type" "ssemov")
22695 (set_attr "memory" "none")
22696 (set (attr "mode")
22697 (if_then_else
22698 (ne (symbol_ref "optimize_size")
22699 (const_int 0))
22700 (const_string "V4SF")
22701 (const_string "TI")))])
22702
22703 ;; MMX unsigned averages/sum of absolute differences
22704
22705 (define_insn "sse2_uavgv16qi3"
22706 [(set (match_operand:V16QI 0 "register_operand" "=x")
22707 (ashiftrt:V16QI
22708 (plus:V16QI (plus:V16QI
22709 (match_operand:V16QI 1 "register_operand" "0")
22710 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22711 (const_vector:V16QI [(const_int 1) (const_int 1)
22712 (const_int 1) (const_int 1)
22713 (const_int 1) (const_int 1)
22714 (const_int 1) (const_int 1)
22715 (const_int 1) (const_int 1)
22716 (const_int 1) (const_int 1)
22717 (const_int 1) (const_int 1)
22718 (const_int 1) (const_int 1)]))
22719 (const_int 1)))]
22720 "TARGET_SSE2"
22721 "pavgb\t{%2, %0|%0, %2}"
22722 [(set_attr "type" "sseiadd")
22723 (set_attr "mode" "TI")])
22724
22725 (define_insn "sse2_uavgv8hi3"
22726 [(set (match_operand:V8HI 0 "register_operand" "=x")
22727 (ashiftrt:V8HI
22728 (plus:V8HI (plus:V8HI
22729 (match_operand:V8HI 1 "register_operand" "0")
22730 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22731 (const_vector:V8HI [(const_int 1) (const_int 1)
22732 (const_int 1) (const_int 1)
22733 (const_int 1) (const_int 1)
22734 (const_int 1) (const_int 1)]))
22735 (const_int 1)))]
22736 "TARGET_SSE2"
22737 "pavgw\t{%2, %0|%0, %2}"
22738 [(set_attr "type" "sseiadd")
22739 (set_attr "mode" "TI")])
22740
22741 ;; @@@ this isn't the right representation.
22742 (define_insn "sse2_psadbw"
22743 [(set (match_operand:V2DI 0 "register_operand" "=x")
22744 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22745 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22746 UNSPEC_PSADBW))]
22747 "TARGET_SSE2"
22748 "psadbw\t{%2, %0|%0, %2}"
22749 [(set_attr "type" "sseiadd")
22750 (set_attr "mode" "TI")])
22751
22752
22753 ;; MMX insert/extract/shuffle
22754
22755 (define_insn "sse2_pinsrw"
22756 [(set (match_operand:V8HI 0 "register_operand" "=x")
22757 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22758 (vec_duplicate:V8HI
22759 (truncate:HI
22760 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22761 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22762 "TARGET_SSE2"
22763 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22764 [(set_attr "type" "ssecvt")
22765 (set_attr "mode" "TI")])
22766
22767 (define_insn "sse2_pextrw"
22768 [(set (match_operand:SI 0 "register_operand" "=r")
22769 (zero_extend:SI
22770 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22771 (parallel
22772 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22773 "TARGET_SSE2"
22774 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22775 [(set_attr "type" "ssecvt")
22776 (set_attr "mode" "TI")])
22777
22778 (define_insn "sse2_pshufd"
22779 [(set (match_operand:V4SI 0 "register_operand" "=x")
22780 (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
22781 (match_operand:SI 2 "immediate_operand" "i")]
22782 UNSPEC_SHUFFLE))]
22783 "TARGET_SSE2"
22784 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22785 [(set_attr "type" "ssecvt")
22786 (set_attr "mode" "TI")])
22787
22788 (define_insn "sse2_pshuflw"
22789 [(set (match_operand:V8HI 0 "register_operand" "=x")
22790 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
22791 (match_operand:SI 2 "immediate_operand" "i")]
22792 UNSPEC_PSHUFLW))]
22793 "TARGET_SSE2"
22794 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22795 [(set_attr "type" "ssecvt")
22796 (set_attr "mode" "TI")])
22797
22798 (define_insn "sse2_pshufhw"
22799 [(set (match_operand:V8HI 0 "register_operand" "=x")
22800 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
22801 (match_operand:SI 2 "immediate_operand" "i")]
22802 UNSPEC_PSHUFHW))]
22803 "TARGET_SSE2"
22804 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22805 [(set_attr "type" "ssecvt")
22806 (set_attr "mode" "TI")])
22807
22808 ;; MMX mask-generating comparisons
22809
22810 (define_insn "eqv16qi3"
22811 [(set (match_operand:V16QI 0 "register_operand" "=x")
22812 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22813 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22814 "TARGET_SSE2"
22815 "pcmpeqb\t{%2, %0|%0, %2}"
22816 [(set_attr "type" "ssecmp")
22817 (set_attr "mode" "TI")])
22818
22819 (define_insn "eqv8hi3"
22820 [(set (match_operand:V8HI 0 "register_operand" "=x")
22821 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22822 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22823 "TARGET_SSE2"
22824 "pcmpeqw\t{%2, %0|%0, %2}"
22825 [(set_attr "type" "ssecmp")
22826 (set_attr "mode" "TI")])
22827
22828 (define_insn "eqv4si3"
22829 [(set (match_operand:V4SI 0 "register_operand" "=x")
22830 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22831 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22832 "TARGET_SSE2"
22833 "pcmpeqd\t{%2, %0|%0, %2}"
22834 [(set_attr "type" "ssecmp")
22835 (set_attr "mode" "TI")])
22836
22837 (define_insn "gtv16qi3"
22838 [(set (match_operand:V16QI 0 "register_operand" "=x")
22839 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22840 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22841 "TARGET_SSE2"
22842 "pcmpgtb\t{%2, %0|%0, %2}"
22843 [(set_attr "type" "ssecmp")
22844 (set_attr "mode" "TI")])
22845
22846 (define_insn "gtv8hi3"
22847 [(set (match_operand:V8HI 0 "register_operand" "=x")
22848 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22849 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22850 "TARGET_SSE2"
22851 "pcmpgtw\t{%2, %0|%0, %2}"
22852 [(set_attr "type" "ssecmp")
22853 (set_attr "mode" "TI")])
22854
22855 (define_insn "gtv4si3"
22856 [(set (match_operand:V4SI 0 "register_operand" "=x")
22857 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22858 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22859 "TARGET_SSE2"
22860 "pcmpgtd\t{%2, %0|%0, %2}"
22861 [(set_attr "type" "ssecmp")
22862 (set_attr "mode" "TI")])
22863
22864
22865 ;; MMX max/min insns
22866
22867 (define_insn "umaxv16qi3"
22868 [(set (match_operand:V16QI 0 "register_operand" "=x")
22869 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22870 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22871 "TARGET_SSE2"
22872 "pmaxub\t{%2, %0|%0, %2}"
22873 [(set_attr "type" "sseiadd")
22874 (set_attr "mode" "TI")])
22875
22876 (define_insn "smaxv8hi3"
22877 [(set (match_operand:V8HI 0 "register_operand" "=x")
22878 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22879 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22880 "TARGET_SSE2"
22881 "pmaxsw\t{%2, %0|%0, %2}"
22882 [(set_attr "type" "sseiadd")
22883 (set_attr "mode" "TI")])
22884
22885 (define_insn "uminv16qi3"
22886 [(set (match_operand:V16QI 0 "register_operand" "=x")
22887 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22888 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22889 "TARGET_SSE2"
22890 "pminub\t{%2, %0|%0, %2}"
22891 [(set_attr "type" "sseiadd")
22892 (set_attr "mode" "TI")])
22893
22894 (define_insn "sminv8hi3"
22895 [(set (match_operand:V8HI 0 "register_operand" "=x")
22896 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22897 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22898 "TARGET_SSE2"
22899 "pminsw\t{%2, %0|%0, %2}"
22900 [(set_attr "type" "sseiadd")
22901 (set_attr "mode" "TI")])
22902
22903
22904 ;; MMX shifts
22905
22906 (define_insn "ashrv8hi3"
22907 [(set (match_operand:V8HI 0 "register_operand" "=x")
22908 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22909 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22910 "TARGET_SSE2"
22911 "psraw\t{%2, %0|%0, %2}"
22912 [(set_attr "type" "sseishft")
22913 (set_attr "mode" "TI")])
22914
22915 (define_insn "ashrv4si3"
22916 [(set (match_operand:V4SI 0 "register_operand" "=x")
22917 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22918 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22919 "TARGET_SSE2"
22920 "psrad\t{%2, %0|%0, %2}"
22921 [(set_attr "type" "sseishft")
22922 (set_attr "mode" "TI")])
22923
22924 (define_insn "lshrv8hi3"
22925 [(set (match_operand:V8HI 0 "register_operand" "=x")
22926 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22927 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22928 "TARGET_SSE2"
22929 "psrlw\t{%2, %0|%0, %2}"
22930 [(set_attr "type" "sseishft")
22931 (set_attr "mode" "TI")])
22932
22933 (define_insn "lshrv4si3"
22934 [(set (match_operand:V4SI 0 "register_operand" "=x")
22935 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22936 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22937 "TARGET_SSE2"
22938 "psrld\t{%2, %0|%0, %2}"
22939 [(set_attr "type" "sseishft")
22940 (set_attr "mode" "TI")])
22941
22942 (define_insn "lshrv2di3"
22943 [(set (match_operand:V2DI 0 "register_operand" "=x")
22944 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22945 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22946 "TARGET_SSE2"
22947 "psrlq\t{%2, %0|%0, %2}"
22948 [(set_attr "type" "sseishft")
22949 (set_attr "mode" "TI")])
22950
22951 (define_insn "ashlv8hi3"
22952 [(set (match_operand:V8HI 0 "register_operand" "=x")
22953 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22954 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22955 "TARGET_SSE2"
22956 "psllw\t{%2, %0|%0, %2}"
22957 [(set_attr "type" "sseishft")
22958 (set_attr "mode" "TI")])
22959
22960 (define_insn "ashlv4si3"
22961 [(set (match_operand:V4SI 0 "register_operand" "=x")
22962 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22963 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22964 "TARGET_SSE2"
22965 "pslld\t{%2, %0|%0, %2}"
22966 [(set_attr "type" "sseishft")
22967 (set_attr "mode" "TI")])
22968
22969 (define_insn "ashlv2di3"
22970 [(set (match_operand:V2DI 0 "register_operand" "=x")
22971 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22972 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22973 "TARGET_SSE2"
22974 "psllq\t{%2, %0|%0, %2}"
22975 [(set_attr "type" "sseishft")
22976 (set_attr "mode" "TI")])
22977
22978 (define_insn "ashrv8hi3_ti"
22979 [(set (match_operand:V8HI 0 "register_operand" "=x")
22980 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22981 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22982 "TARGET_SSE2"
22983 "psraw\t{%2, %0|%0, %2}"
22984 [(set_attr "type" "sseishft")
22985 (set_attr "mode" "TI")])
22986
22987 (define_insn "ashrv4si3_ti"
22988 [(set (match_operand:V4SI 0 "register_operand" "=x")
22989 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22990 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22991 "TARGET_SSE2"
22992 "psrad\t{%2, %0|%0, %2}"
22993 [(set_attr "type" "sseishft")
22994 (set_attr "mode" "TI")])
22995
22996 (define_insn "lshrv8hi3_ti"
22997 [(set (match_operand:V8HI 0 "register_operand" "=x")
22998 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22999 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23000 "TARGET_SSE2"
23001 "psrlw\t{%2, %0|%0, %2}"
23002 [(set_attr "type" "sseishft")
23003 (set_attr "mode" "TI")])
23004
23005 (define_insn "lshrv4si3_ti"
23006 [(set (match_operand:V4SI 0 "register_operand" "=x")
23007 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23008 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23009 "TARGET_SSE2"
23010 "psrld\t{%2, %0|%0, %2}"
23011 [(set_attr "type" "sseishft")
23012 (set_attr "mode" "TI")])
23013
23014 (define_insn "lshrv2di3_ti"
23015 [(set (match_operand:V2DI 0 "register_operand" "=x")
23016 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23017 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23018 "TARGET_SSE2"
23019 "psrlq\t{%2, %0|%0, %2}"
23020 [(set_attr "type" "sseishft")
23021 (set_attr "mode" "TI")])
23022
23023 (define_insn "ashlv8hi3_ti"
23024 [(set (match_operand:V8HI 0 "register_operand" "=x")
23025 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23026 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23027 "TARGET_SSE2"
23028 "psllw\t{%2, %0|%0, %2}"
23029 [(set_attr "type" "sseishft")
23030 (set_attr "mode" "TI")])
23031
23032 (define_insn "ashlv4si3_ti"
23033 [(set (match_operand:V4SI 0 "register_operand" "=x")
23034 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23035 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23036 "TARGET_SSE2"
23037 "pslld\t{%2, %0|%0, %2}"
23038 [(set_attr "type" "sseishft")
23039 (set_attr "mode" "TI")])
23040
23041 (define_insn "ashlv2di3_ti"
23042 [(set (match_operand:V2DI 0 "register_operand" "=x")
23043 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23044 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23045 "TARGET_SSE2"
23046 "psllq\t{%2, %0|%0, %2}"
23047 [(set_attr "type" "sseishft")
23048 (set_attr "mode" "TI")])
23049
23050 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23051 ;; we wouldn't need here it since we never generate TImode arithmetic.
23052
23053 ;; There has to be some kind of prize for the weirdest new instruction...
23054 (define_insn "sse2_ashlti3"
23055 [(set (match_operand:TI 0 "register_operand" "=x")
23056 (unspec:TI
23057 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23058 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23059 (const_int 8)))] UNSPEC_NOP))]
23060 "TARGET_SSE2"
23061 "pslldq\t{%2, %0|%0, %2}"
23062 [(set_attr "type" "sseishft")
23063 (set_attr "mode" "TI")])
23064
23065 (define_insn "sse2_lshrti3"
23066 [(set (match_operand:TI 0 "register_operand" "=x")
23067 (unspec:TI
23068 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23069 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23070 (const_int 8)))] UNSPEC_NOP))]
23071 "TARGET_SSE2"
23072 "psrldq\t{%2, %0|%0, %2}"
23073 [(set_attr "type" "sseishft")
23074 (set_attr "mode" "TI")])
23075
23076 ;; SSE unpack
23077
23078 (define_insn "sse2_unpckhpd"
23079 [(set (match_operand:V2DF 0 "register_operand" "=x")
23080 (vec_concat:V2DF
23081 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23082 (parallel [(const_int 1)]))
23083 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23084 (parallel [(const_int 1)]))))]
23085 "TARGET_SSE2"
23086 "unpckhpd\t{%2, %0|%0, %2}"
23087 [(set_attr "type" "ssecvt")
23088 (set_attr "mode" "V2DF")])
23089
23090 (define_insn "sse2_unpcklpd"
23091 [(set (match_operand:V2DF 0 "register_operand" "=x")
23092 (vec_concat:V2DF
23093 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23094 (parallel [(const_int 0)]))
23095 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23096 (parallel [(const_int 0)]))))]
23097 "TARGET_SSE2"
23098 "unpcklpd\t{%2, %0|%0, %2}"
23099 [(set_attr "type" "ssecvt")
23100 (set_attr "mode" "V2DF")])
23101
23102 ;; MMX pack/unpack insns.
23103
23104 (define_insn "sse2_packsswb"
23105 [(set (match_operand:V16QI 0 "register_operand" "=x")
23106 (vec_concat:V16QI
23107 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23108 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23109 "TARGET_SSE2"
23110 "packsswb\t{%2, %0|%0, %2}"
23111 [(set_attr "type" "ssecvt")
23112 (set_attr "mode" "TI")])
23113
23114 (define_insn "sse2_packssdw"
23115 [(set (match_operand:V8HI 0 "register_operand" "=x")
23116 (vec_concat:V8HI
23117 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23118 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23119 "TARGET_SSE2"
23120 "packssdw\t{%2, %0|%0, %2}"
23121 [(set_attr "type" "ssecvt")
23122 (set_attr "mode" "TI")])
23123
23124 (define_insn "sse2_packuswb"
23125 [(set (match_operand:V16QI 0 "register_operand" "=x")
23126 (vec_concat:V16QI
23127 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23128 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23129 "TARGET_SSE2"
23130 "packuswb\t{%2, %0|%0, %2}"
23131 [(set_attr "type" "ssecvt")
23132 (set_attr "mode" "TI")])
23133
23134 (define_insn "sse2_punpckhbw"
23135 [(set (match_operand:V16QI 0 "register_operand" "=x")
23136 (vec_merge:V16QI
23137 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23138 (parallel [(const_int 8) (const_int 0)
23139 (const_int 9) (const_int 1)
23140 (const_int 10) (const_int 2)
23141 (const_int 11) (const_int 3)
23142 (const_int 12) (const_int 4)
23143 (const_int 13) (const_int 5)
23144 (const_int 14) (const_int 6)
23145 (const_int 15) (const_int 7)]))
23146 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23147 (parallel [(const_int 0) (const_int 8)
23148 (const_int 1) (const_int 9)
23149 (const_int 2) (const_int 10)
23150 (const_int 3) (const_int 11)
23151 (const_int 4) (const_int 12)
23152 (const_int 5) (const_int 13)
23153 (const_int 6) (const_int 14)
23154 (const_int 7) (const_int 15)]))
23155 (const_int 21845)))]
23156 "TARGET_SSE2"
23157 "punpckhbw\t{%2, %0|%0, %2}"
23158 [(set_attr "type" "ssecvt")
23159 (set_attr "mode" "TI")])
23160
23161 (define_insn "sse2_punpckhwd"
23162 [(set (match_operand:V8HI 0 "register_operand" "=x")
23163 (vec_merge:V8HI
23164 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23165 (parallel [(const_int 4) (const_int 0)
23166 (const_int 5) (const_int 1)
23167 (const_int 6) (const_int 2)
23168 (const_int 7) (const_int 3)]))
23169 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23170 (parallel [(const_int 0) (const_int 4)
23171 (const_int 1) (const_int 5)
23172 (const_int 2) (const_int 6)
23173 (const_int 3) (const_int 7)]))
23174 (const_int 85)))]
23175 "TARGET_SSE2"
23176 "punpckhwd\t{%2, %0|%0, %2}"
23177 [(set_attr "type" "ssecvt")
23178 (set_attr "mode" "TI")])
23179
23180 (define_insn "sse2_punpckhdq"
23181 [(set (match_operand:V4SI 0 "register_operand" "=x")
23182 (vec_merge:V4SI
23183 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23184 (parallel [(const_int 2) (const_int 0)
23185 (const_int 3) (const_int 1)]))
23186 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23187 (parallel [(const_int 0) (const_int 2)
23188 (const_int 1) (const_int 3)]))
23189 (const_int 5)))]
23190 "TARGET_SSE2"
23191 "punpckhdq\t{%2, %0|%0, %2}"
23192 [(set_attr "type" "ssecvt")
23193 (set_attr "mode" "TI")])
23194
23195 (define_insn "sse2_punpcklbw"
23196 [(set (match_operand:V16QI 0 "register_operand" "=x")
23197 (vec_merge:V16QI
23198 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23199 (parallel [(const_int 0) (const_int 8)
23200 (const_int 1) (const_int 9)
23201 (const_int 2) (const_int 10)
23202 (const_int 3) (const_int 11)
23203 (const_int 4) (const_int 12)
23204 (const_int 5) (const_int 13)
23205 (const_int 6) (const_int 14)
23206 (const_int 7) (const_int 15)]))
23207 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23208 (parallel [(const_int 8) (const_int 0)
23209 (const_int 9) (const_int 1)
23210 (const_int 10) (const_int 2)
23211 (const_int 11) (const_int 3)
23212 (const_int 12) (const_int 4)
23213 (const_int 13) (const_int 5)
23214 (const_int 14) (const_int 6)
23215 (const_int 15) (const_int 7)]))
23216 (const_int 21845)))]
23217 "TARGET_SSE2"
23218 "punpcklbw\t{%2, %0|%0, %2}"
23219 [(set_attr "type" "ssecvt")
23220 (set_attr "mode" "TI")])
23221
23222 (define_insn "sse2_punpcklwd"
23223 [(set (match_operand:V8HI 0 "register_operand" "=x")
23224 (vec_merge:V8HI
23225 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23226 (parallel [(const_int 0) (const_int 4)
23227 (const_int 1) (const_int 5)
23228 (const_int 2) (const_int 6)
23229 (const_int 3) (const_int 7)]))
23230 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23231 (parallel [(const_int 4) (const_int 0)
23232 (const_int 5) (const_int 1)
23233 (const_int 6) (const_int 2)
23234 (const_int 7) (const_int 3)]))
23235 (const_int 85)))]
23236 "TARGET_SSE2"
23237 "punpcklwd\t{%2, %0|%0, %2}"
23238 [(set_attr "type" "ssecvt")
23239 (set_attr "mode" "TI")])
23240
23241 (define_insn "sse2_punpckldq"
23242 [(set (match_operand:V4SI 0 "register_operand" "=x")
23243 (vec_merge:V4SI
23244 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23245 (parallel [(const_int 0) (const_int 2)
23246 (const_int 1) (const_int 3)]))
23247 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23248 (parallel [(const_int 2) (const_int 0)
23249 (const_int 3) (const_int 1)]))
23250 (const_int 5)))]
23251 "TARGET_SSE2"
23252 "punpckldq\t{%2, %0|%0, %2}"
23253 [(set_attr "type" "ssecvt")
23254 (set_attr "mode" "TI")])
23255
23256 (define_insn "sse2_punpcklqdq"
23257 [(set (match_operand:V2DI 0 "register_operand" "=x")
23258 (vec_merge:V2DI
23259 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23260 (parallel [(const_int 1)
23261 (const_int 0)]))
23262 (match_operand:V2DI 1 "register_operand" "0")
23263 (const_int 1)))]
23264 "TARGET_SSE2"
23265 "punpcklqdq\t{%2, %0|%0, %2}"
23266 [(set_attr "type" "ssecvt")
23267 (set_attr "mode" "TI")])
23268
23269 (define_insn "sse2_punpckhqdq"
23270 [(set (match_operand:V2DI 0 "register_operand" "=x")
23271 (vec_merge:V2DI
23272 (match_operand:V2DI 1 "register_operand" "0")
23273 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23274 (parallel [(const_int 1)
23275 (const_int 0)]))
23276 (const_int 1)))]
23277 "TARGET_SSE2"
23278 "punpckhqdq\t{%2, %0|%0, %2}"
23279 [(set_attr "type" "ssecvt")
23280 (set_attr "mode" "TI")])
23281
23282 ;; SSE2 moves
23283
23284 (define_insn "sse2_movapd"
23285 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23286 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23287 UNSPEC_MOVA))]
23288 "TARGET_SSE2
23289 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23290 "movapd\t{%1, %0|%0, %1}"
23291 [(set_attr "type" "ssemov")
23292 (set_attr "mode" "V2DF")])
23293
23294 (define_insn "sse2_movupd"
23295 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23296 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23297 UNSPEC_MOVU))]
23298 "TARGET_SSE2
23299 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23300 "movupd\t{%1, %0|%0, %1}"
23301 [(set_attr "type" "ssecvt")
23302 (set_attr "mode" "V2DF")])
23303
23304 (define_insn "sse2_movdqa"
23305 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23306 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23307 UNSPEC_MOVA))]
23308 "TARGET_SSE2
23309 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23310 "movdqa\t{%1, %0|%0, %1}"
23311 [(set_attr "type" "ssemov")
23312 (set_attr "mode" "TI")])
23313
23314 (define_insn "sse2_movdqu"
23315 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23316 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23317 UNSPEC_MOVU))]
23318 "TARGET_SSE2
23319 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23320 "movdqu\t{%1, %0|%0, %1}"
23321 [(set_attr "type" "ssecvt")
23322 (set_attr "mode" "TI")])
23323
23324 (define_insn "sse2_movdq2q"
23325 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23326 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23327 (parallel [(const_int 0)])))]
23328 "TARGET_SSE2 && !TARGET_64BIT"
23329 "@
23330 movq\t{%1, %0|%0, %1}
23331 movdq2q\t{%1, %0|%0, %1}"
23332 [(set_attr "type" "ssecvt")
23333 (set_attr "mode" "TI")])
23334
23335 (define_insn "sse2_movdq2q_rex64"
23336 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23337 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23338 (parallel [(const_int 0)])))]
23339 "TARGET_SSE2 && TARGET_64BIT"
23340 "@
23341 movq\t{%1, %0|%0, %1}
23342 movdq2q\t{%1, %0|%0, %1}
23343 movd\t{%1, %0|%0, %1}"
23344 [(set_attr "type" "ssecvt")
23345 (set_attr "mode" "TI")])
23346
23347 (define_insn "sse2_movq2dq"
23348 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23349 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23350 (const_int 0)))]
23351 "TARGET_SSE2 && !TARGET_64BIT"
23352 "@
23353 movq\t{%1, %0|%0, %1}
23354 movq2dq\t{%1, %0|%0, %1}"
23355 [(set_attr "type" "ssecvt,ssemov")
23356 (set_attr "mode" "TI")])
23357
23358 (define_insn "sse2_movq2dq_rex64"
23359 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23360 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23361 (const_int 0)))]
23362 "TARGET_SSE2 && TARGET_64BIT"
23363 "@
23364 movq\t{%1, %0|%0, %1}
23365 movq2dq\t{%1, %0|%0, %1}
23366 movd\t{%1, %0|%0, %1}"
23367 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23368 (set_attr "mode" "TI")])
23369
23370 (define_insn "sse2_movq"
23371 [(set (match_operand:V2DI 0 "register_operand" "=x")
23372 (vec_concat:V2DI (vec_select:DI
23373 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23374 (parallel [(const_int 0)]))
23375 (const_int 0)))]
23376 "TARGET_SSE2"
23377 "movq\t{%1, %0|%0, %1}"
23378 [(set_attr "type" "ssemov")
23379 (set_attr "mode" "TI")])
23380
23381 (define_insn "sse2_loadd"
23382 [(set (match_operand:V4SI 0 "register_operand" "=x")
23383 (vec_merge:V4SI
23384 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23385 (const_vector:V4SI [(const_int 0)
23386 (const_int 0)
23387 (const_int 0)
23388 (const_int 0)])
23389 (const_int 1)))]
23390 "TARGET_SSE2"
23391 "movd\t{%1, %0|%0, %1}"
23392 [(set_attr "type" "ssemov")
23393 (set_attr "mode" "TI")])
23394
23395 (define_insn "sse2_stored"
23396 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23397 (vec_select:SI
23398 (match_operand:V4SI 1 "register_operand" "x")
23399 (parallel [(const_int 0)])))]
23400 "TARGET_SSE2"
23401 "movd\t{%1, %0|%0, %1}"
23402 [(set_attr "type" "ssemov")
23403 (set_attr "mode" "TI")])
23404
23405 (define_insn "sse2_movhpd"
23406 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23407 (vec_merge:V2DF
23408 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23409 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23410 (const_int 2)))]
23411 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23412 "movhpd\t{%2, %0|%0, %2}"
23413 [(set_attr "type" "ssecvt")
23414 (set_attr "mode" "V2DF")])
23415
23416 (define_expand "sse2_loadsd"
23417 [(match_operand:V2DF 0 "register_operand" "")
23418 (match_operand:DF 1 "memory_operand" "")]
23419 "TARGET_SSE2"
23420 {
23421 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23422 CONST0_RTX (V2DFmode)));
23423 DONE;
23424 })
23425
23426 (define_insn "sse2_loadsd_1"
23427 [(set (match_operand:V2DF 0 "register_operand" "=x")
23428 (vec_merge:V2DF
23429 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23430 (match_operand:V2DF 2 "const0_operand" "X")
23431 (const_int 1)))]
23432 "TARGET_SSE2"
23433 "movsd\t{%1, %0|%0, %1}"
23434 [(set_attr "type" "ssecvt")
23435 (set_attr "mode" "DF")])
23436
23437 (define_insn "sse2_movsd"
23438 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
23439 (vec_merge:V2DF
23440 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23441 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
23442 (const_int 1)))]
23443 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
23444 "@movsd\t{%2, %0|%0, %2}
23445 movlpd\t{%2, %0|%0, %2}
23446 movlpd\t{%2, %0|%0, %2}"
23447 [(set_attr "type" "ssecvt")
23448 (set_attr "mode" "DF,V2DF,V2DF")])
23449
23450 (define_insn "sse2_storesd"
23451 [(set (match_operand:DF 0 "memory_operand" "=m")
23452 (vec_select:DF
23453 (match_operand:V2DF 1 "register_operand" "x")
23454 (parallel [(const_int 0)])))]
23455 "TARGET_SSE2"
23456 "movsd\t{%1, %0|%0, %1}"
23457 [(set_attr "type" "ssecvt")
23458 (set_attr "mode" "DF")])
23459
23460 (define_insn "sse2_shufpd"
23461 [(set (match_operand:V2DF 0 "register_operand" "=x")
23462 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23463 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23464 (match_operand:SI 3 "immediate_operand" "i")]
23465 UNSPEC_SHUFFLE))]
23466 "TARGET_SSE2"
23467 ;; @@@ check operand order for intel/nonintel syntax
23468 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23469 [(set_attr "type" "ssecvt")
23470 (set_attr "mode" "V2DF")])
23471
23472 (define_insn "sse2_clflush"
23473 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23474 UNSPECV_CLFLUSH)]
23475 "TARGET_SSE2"
23476 "clflush %0"
23477 [(set_attr "type" "sse")
23478 (set_attr "memory" "unknown")])
23479
23480 (define_expand "sse2_mfence"
23481 [(set (match_dup 0)
23482 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23483 "TARGET_SSE2"
23484 {
23485 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23486 MEM_VOLATILE_P (operands[0]) = 1;
23487 })
23488
23489 (define_insn "*mfence_insn"
23490 [(set (match_operand:BLK 0 "" "")
23491 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23492 "TARGET_SSE2"
23493 "mfence"
23494 [(set_attr "type" "sse")
23495 (set_attr "memory" "unknown")])
23496
23497 (define_expand "sse2_lfence"
23498 [(set (match_dup 0)
23499 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23500 "TARGET_SSE2"
23501 {
23502 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23503 MEM_VOLATILE_P (operands[0]) = 1;
23504 })
23505
23506 (define_insn "*lfence_insn"
23507 [(set (match_operand:BLK 0 "" "")
23508 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23509 "TARGET_SSE2"
23510 "lfence"
23511 [(set_attr "type" "sse")
23512 (set_attr "memory" "unknown")])
23513
23514 ;; SSE3
23515
23516 (define_insn "mwait"
23517 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23518 (match_operand:SI 1 "register_operand" "c")]
23519 UNSPECV_MWAIT)]
23520 "TARGET_SSE3"
23521 "mwait\t%0, %1"
23522 [(set_attr "length" "3")])
23523
23524 (define_insn "monitor"
23525 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23526 (match_operand:SI 1 "register_operand" "c")
23527 (match_operand:SI 2 "register_operand" "d")]
23528 UNSPECV_MONITOR)]
23529 "TARGET_SSE3"
23530 "monitor\t%0, %1, %2"
23531 [(set_attr "length" "3")])
23532
23533 ;; SSE3 arithmetic
23534
23535 (define_insn "addsubv4sf3"
23536 [(set (match_operand:V4SF 0 "register_operand" "=x")
23537 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23538 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23539 UNSPEC_ADDSUB))]
23540 "TARGET_SSE3"
23541 "addsubps\t{%2, %0|%0, %2}"
23542 [(set_attr "type" "sseadd")
23543 (set_attr "mode" "V4SF")])
23544
23545 (define_insn "addsubv2df3"
23546 [(set (match_operand:V2DF 0 "register_operand" "=x")
23547 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23548 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23549 UNSPEC_ADDSUB))]
23550 "TARGET_SSE3"
23551 "addsubpd\t{%2, %0|%0, %2}"
23552 [(set_attr "type" "sseadd")
23553 (set_attr "mode" "V2DF")])
23554
23555 (define_insn "haddv4sf3"
23556 [(set (match_operand:V4SF 0 "register_operand" "=x")
23557 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23558 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23559 UNSPEC_HADD))]
23560 "TARGET_SSE3"
23561 "haddps\t{%2, %0|%0, %2}"
23562 [(set_attr "type" "sseadd")
23563 (set_attr "mode" "V4SF")])
23564
23565 (define_insn "haddv2df3"
23566 [(set (match_operand:V2DF 0 "register_operand" "=x")
23567 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23568 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23569 UNSPEC_HADD))]
23570 "TARGET_SSE3"
23571 "haddpd\t{%2, %0|%0, %2}"
23572 [(set_attr "type" "sseadd")
23573 (set_attr "mode" "V2DF")])
23574
23575 (define_insn "hsubv4sf3"
23576 [(set (match_operand:V4SF 0 "register_operand" "=x")
23577 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23578 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23579 UNSPEC_HSUB))]
23580 "TARGET_SSE3"
23581 "hsubps\t{%2, %0|%0, %2}"
23582 [(set_attr "type" "sseadd")
23583 (set_attr "mode" "V4SF")])
23584
23585 (define_insn "hsubv2df3"
23586 [(set (match_operand:V2DF 0 "register_operand" "=x")
23587 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23588 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23589 UNSPEC_HSUB))]
23590 "TARGET_SSE3"
23591 "hsubpd\t{%2, %0|%0, %2}"
23592 [(set_attr "type" "sseadd")
23593 (set_attr "mode" "V2DF")])
23594
23595 (define_insn "movshdup"
23596 [(set (match_operand:V4SF 0 "register_operand" "=x")
23597 (unspec:V4SF
23598 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23599 "TARGET_SSE3"
23600 "movshdup\t{%1, %0|%0, %1}"
23601 [(set_attr "type" "sse")
23602 (set_attr "mode" "V4SF")])
23603
23604 (define_insn "movsldup"
23605 [(set (match_operand:V4SF 0 "register_operand" "=x")
23606 (unspec:V4SF
23607 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23608 "TARGET_SSE3"
23609 "movsldup\t{%1, %0|%0, %1}"
23610 [(set_attr "type" "sse")
23611 (set_attr "mode" "V4SF")])
23612
23613 (define_insn "lddqu"
23614 [(set (match_operand:V16QI 0 "register_operand" "=x")
23615 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23616 UNSPEC_LDQQU))]
23617 "TARGET_SSE3"
23618 "lddqu\t{%1, %0|%0, %1}"
23619 [(set_attr "type" "ssecvt")
23620 (set_attr "mode" "TI")])
23621
23622 (define_insn "loadddup"
23623 [(set (match_operand:V2DF 0 "register_operand" "=x")
23624 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23625 "TARGET_SSE3"
23626 "movddup\t{%1, %0|%0, %1}"
23627 [(set_attr "type" "ssecvt")
23628 (set_attr "mode" "DF")])
23629
23630 (define_insn "movddup"
23631 [(set (match_operand:V2DF 0 "register_operand" "=x")
23632 (vec_duplicate:V2DF
23633 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23634 (parallel [(const_int 0)]))))]
23635 "TARGET_SSE3"
23636 "movddup\t{%1, %0|%0, %1}"
23637 [(set_attr "type" "ssecvt")
23638 (set_attr "mode" "DF")])
This page took 1.193594 seconds and 5 git commands to generate.