* config/i386/i386.md: Correct check-in of incorrect version.
[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
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 GNU CC.
9 ;;
10 ;; GNU CC 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 ;; GNU CC 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 GNU CC; 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 #define NOTICE_UPDATE_CC in file i386.h handles condition code
31 ;; updates for most instructions.
32 ;;
33 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
34 ;; constraint letters.
35 ;;
36 ;; The special asm out single letter directives following a '%' are:
37 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
38 ;; operands[1].
39 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
40 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
41 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
42 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
43 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
44 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
45 ;; 'J' Print the appropriate jump operand.
46 ;;
47 ;; 'b' Print the QImode name of the register for the indicated operand.
48 ;; %b0 would print %al if operands[0] is reg 0.
49 ;; 'w' Likewise, print the HImode name of the register.
50 ;; 'k' Likewise, print the SImode name of the register.
51 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; 'y' Print "st(0)" instead of "st" as a register.
53
54 ;; UNSPEC usage:
55
56 (define_constants
57 [; Relocation specifiers
58 (UNSPEC_GOT 0)
59 (UNSPEC_GOTOFF 1)
60 (UNSPEC_GOTPCREL 2)
61 (UNSPEC_GOTTPOFF 3)
62 (UNSPEC_TPOFF 4)
63 (UNSPEC_NTPOFF 5)
64 (UNSPEC_DTPOFF 6)
65 (UNSPEC_GOTNTPOFF 7)
66 (UNSPEC_INDNTPOFF 8)
67
68 ; Prologue support
69 (UNSPEC_STACK_PROBE 10)
70 (UNSPEC_STACK_ALLOC 11)
71 (UNSPEC_SET_GOT 12)
72 (UNSPEC_SSE_PROLOGUE_SAVE 13)
73
74 ; TLS support
75 (UNSPEC_TP 15)
76 (UNSPEC_TLS_GD 16)
77 (UNSPEC_TLS_LD_BASE 17)
78
79 ; Other random patterns
80 (UNSPEC_SCAS 20)
81 (UNSPEC_SIN 21)
82 (UNSPEC_COS 22)
83 (UNSPEC_FNSTSW 24)
84 (UNSPEC_SAHF 25)
85 (UNSPEC_FSTCW 26)
86 (UNSPEC_ADD_CARRY 27)
87 (UNSPEC_FLDCW 28)
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX 30)
91 (UNSPEC_MASKMOV 32)
92 (UNSPEC_MOVMSK 33)
93 (UNSPEC_MOVNT 34)
94 (UNSPEC_MOVA 38)
95 (UNSPEC_MOVU 39)
96 (UNSPEC_SHUFFLE 41)
97 (UNSPEC_RCP 42)
98 (UNSPEC_RSQRT 43)
99 (UNSPEC_SFENCE 44)
100 (UNSPEC_NOP 45) ; prevents combiner cleverness
101 (UNSPEC_PAVGUSB 49)
102 (UNSPEC_PFRCP 50)
103 (UNSPEC_PFRCPIT1 51)
104 (UNSPEC_PFRCPIT2 52)
105 (UNSPEC_PFRSQRT 53)
106 (UNSPEC_PFRSQIT1 54)
107 (UNSPEC_PSHUFLW 55)
108 (UNSPEC_PSHUFHW 56)
109 (UNSPEC_MFENCE 59)
110 (UNSPEC_LFENCE 60)
111 (UNSPEC_PSADBW 61)
112 (UNSPEC_ADDSUB 71)
113 (UNSPEC_HADD 72)
114 (UNSPEC_HSUB 73)
115 (UNSPEC_MOVSHDUP 74)
116 (UNSPEC_MOVSLDUP 75)
117 (UNSPEC_LDQQU 76)
118 (UNSPEC_MOVDDUP 77)
119
120 ; x87 Floating point
121 (UNSPEC_FPATAN 65)
122 (UNSPEC_FYL2X 66)
123 (UNSPEC_FSCALE 67)
124 (UNSPEC_FRNDINT 68)
125 (UNSPEC_F2XM1 69)
126
127 ; REP instruction
128 (UNSPEC_REP 75)
129 ])
130
131 (define_constants
132 [(UNSPECV_BLOCKAGE 0)
133 (UNSPECV_EH_RETURN 13)
134 (UNSPECV_EMMS 31)
135 (UNSPECV_LDMXCSR 37)
136 (UNSPECV_STMXCSR 40)
137 (UNSPECV_FEMMS 46)
138 (UNSPECV_CLFLUSH 57)
139 (UNSPECV_ALIGN 68)
140 (UNSPECV_MONITOR 69)
141 (UNSPECV_MWAIT 70)
142 ])
143
144 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
145 ;; from i386.c.
146
147 ;; In C guard expressions, put expressions which may be compile-time
148 ;; constants first. This allows for better optimization. For
149 ;; example, write "TARGET_64BIT && reload_completed", not
150 ;; "reload_completed && TARGET_64BIT".
151
152 \f
153 ;; Processor type. This attribute must exactly match the processor_type
154 ;; enumeration in i386.h.
155 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
156 (const (symbol_ref "ix86_tune")))
157
158 ;; A basic instruction type. Refinements due to arguments to be
159 ;; provided in other attributes.
160 (define_attr "type"
161 "other,multi,
162 alu,alu1,negnot,imov,imovx,lea,
163 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
164 icmp,test,ibr,setcc,icmov,
165 push,pop,call,callv,leave,
166 str,cld,
167 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
168 sselog,sseiadd,sseishft,sseimul,
169 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
170 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
171 (const_string "other"))
172
173 ;; Main data type used by the insn
174 (define_attr "mode"
175 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
176 (const_string "unknown"))
177
178 ;; The CPU unit operations uses.
179 (define_attr "unit" "integer,i387,sse,mmx,unknown"
180 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
181 (const_string "i387")
182 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
183 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
184 (const_string "sse")
185 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
186 (const_string "mmx")
187 (eq_attr "type" "other")
188 (const_string "unknown")]
189 (const_string "integer")))
190
191 ;; The (bounding maximum) length of an instruction immediate.
192 (define_attr "length_immediate" ""
193 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
194 (const_int 0)
195 (eq_attr "unit" "i387,sse,mmx")
196 (const_int 0)
197 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
198 imul,icmp,push,pop")
199 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
200 (eq_attr "type" "imov,test")
201 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
202 (eq_attr "type" "call")
203 (if_then_else (match_operand 0 "constant_call_address_operand" "")
204 (const_int 4)
205 (const_int 0))
206 (eq_attr "type" "callv")
207 (if_then_else (match_operand 1 "constant_call_address_operand" "")
208 (const_int 4)
209 (const_int 0))
210 ;; We don't know the size before shorten_branches. Expect
211 ;; the instruction to fit for better scheduling.
212 (eq_attr "type" "ibr")
213 (const_int 1)
214 ]
215 (symbol_ref "/* Update immediate_length and other attributes! */
216 abort(),1")))
217
218 ;; The (bounding maximum) length of an instruction address.
219 (define_attr "length_address" ""
220 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
221 (const_int 0)
222 (and (eq_attr "type" "call")
223 (match_operand 0 "constant_call_address_operand" ""))
224 (const_int 0)
225 (and (eq_attr "type" "callv")
226 (match_operand 1 "constant_call_address_operand" ""))
227 (const_int 0)
228 ]
229 (symbol_ref "ix86_attr_length_address_default (insn)")))
230
231 ;; Set when length prefix is used.
232 (define_attr "prefix_data16" ""
233 (if_then_else (ior (eq_attr "mode" "HI")
234 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
235 (const_int 1)
236 (const_int 0)))
237
238 ;; Set when string REP prefix is used.
239 (define_attr "prefix_rep" ""
240 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
241 (const_int 1)
242 (const_int 0)))
243
244 ;; Set when 0f opcode prefix is used.
245 (define_attr "prefix_0f" ""
246 (if_then_else
247 (ior (eq_attr "type" "imovx,setcc,icmov")
248 (eq_attr "unit" "sse,mmx"))
249 (const_int 1)
250 (const_int 0)))
251
252 ;; Set when 0f opcode prefix is used.
253 (define_attr "prefix_rex" ""
254 (cond [(and (eq_attr "mode" "DI")
255 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
256 (const_int 1)
257 (and (eq_attr "mode" "QI")
258 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
259 (const_int 0)))
260 (const_int 1)
261 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
262 (const_int 0))
263 (const_int 1)
264 ]
265 (const_int 0)))
266
267 ;; Set when modrm byte is used.
268 (define_attr "modrm" ""
269 (cond [(eq_attr "type" "str,cld,leave")
270 (const_int 0)
271 (eq_attr "unit" "i387")
272 (const_int 0)
273 (and (eq_attr "type" "incdec")
274 (ior (match_operand:SI 1 "register_operand" "")
275 (match_operand:HI 1 "register_operand" "")))
276 (const_int 0)
277 (and (eq_attr "type" "push")
278 (not (match_operand 1 "memory_operand" "")))
279 (const_int 0)
280 (and (eq_attr "type" "pop")
281 (not (match_operand 0 "memory_operand" "")))
282 (const_int 0)
283 (and (eq_attr "type" "imov")
284 (and (match_operand 0 "register_operand" "")
285 (match_operand 1 "immediate_operand" "")))
286 (const_int 0)
287 (and (eq_attr "type" "call")
288 (match_operand 0 "constant_call_address_operand" ""))
289 (const_int 0)
290 (and (eq_attr "type" "callv")
291 (match_operand 1 "constant_call_address_operand" ""))
292 (const_int 0)
293 ]
294 (const_int 1)))
295
296 ;; The (bounding maximum) length of an instruction in bytes.
297 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
298 ;; to split it and compute proper length as for other insns.
299 (define_attr "length" ""
300 (cond [(eq_attr "type" "other,multi,fistp")
301 (const_int 16)
302 (eq_attr "type" "fcmp")
303 (const_int 4)
304 (eq_attr "unit" "i387")
305 (plus (const_int 2)
306 (plus (attr "prefix_data16")
307 (attr "length_address")))]
308 (plus (plus (attr "modrm")
309 (plus (attr "prefix_0f")
310 (plus (attr "prefix_rex")
311 (const_int 1))))
312 (plus (attr "prefix_rep")
313 (plus (attr "prefix_data16")
314 (plus (attr "length_immediate")
315 (attr "length_address")))))))
316
317 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
318 ;; `store' if there is a simple memory reference therein, or `unknown'
319 ;; if the instruction is complex.
320
321 (define_attr "memory" "none,load,store,both,unknown"
322 (cond [(eq_attr "type" "other,multi,str")
323 (const_string "unknown")
324 (eq_attr "type" "lea,fcmov,fpspc,cld")
325 (const_string "none")
326 (eq_attr "type" "fistp,leave")
327 (const_string "both")
328 (eq_attr "type" "push")
329 (if_then_else (match_operand 1 "memory_operand" "")
330 (const_string "both")
331 (const_string "store"))
332 (eq_attr "type" "pop")
333 (if_then_else (match_operand 0 "memory_operand" "")
334 (const_string "both")
335 (const_string "load"))
336 (eq_attr "type" "setcc")
337 (if_then_else (match_operand 0 "memory_operand" "")
338 (const_string "store")
339 (const_string "none"))
340 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
341 (if_then_else (ior (match_operand 0 "memory_operand" "")
342 (match_operand 1 "memory_operand" ""))
343 (const_string "load")
344 (const_string "none"))
345 (eq_attr "type" "ibr")
346 (if_then_else (match_operand 0 "memory_operand" "")
347 (const_string "load")
348 (const_string "none"))
349 (eq_attr "type" "call")
350 (if_then_else (match_operand 0 "constant_call_address_operand" "")
351 (const_string "none")
352 (const_string "load"))
353 (eq_attr "type" "callv")
354 (if_then_else (match_operand 1 "constant_call_address_operand" "")
355 (const_string "none")
356 (const_string "load"))
357 (and (eq_attr "type" "alu1,negnot")
358 (match_operand 1 "memory_operand" ""))
359 (const_string "both")
360 (and (match_operand 0 "memory_operand" "")
361 (match_operand 1 "memory_operand" ""))
362 (const_string "both")
363 (match_operand 0 "memory_operand" "")
364 (const_string "store")
365 (match_operand 1 "memory_operand" "")
366 (const_string "load")
367 (and (eq_attr "type"
368 "!alu1,negnot,
369 imov,imovx,icmp,test,
370 fmov,fcmp,fsgn,
371 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
372 mmx,mmxmov,mmxcmp,mmxcvt")
373 (match_operand 2 "memory_operand" ""))
374 (const_string "load")
375 (and (eq_attr "type" "icmov")
376 (match_operand 3 "memory_operand" ""))
377 (const_string "load")
378 ]
379 (const_string "none")))
380
381 ;; Indicates if an instruction has both an immediate and a displacement.
382
383 (define_attr "imm_disp" "false,true,unknown"
384 (cond [(eq_attr "type" "other,multi")
385 (const_string "unknown")
386 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
387 (and (match_operand 0 "memory_displacement_operand" "")
388 (match_operand 1 "immediate_operand" "")))
389 (const_string "true")
390 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
391 (and (match_operand 0 "memory_displacement_operand" "")
392 (match_operand 2 "immediate_operand" "")))
393 (const_string "true")
394 ]
395 (const_string "false")))
396
397 ;; Indicates if an FP operation has an integer source.
398
399 (define_attr "fp_int_src" "false,true"
400 (const_string "false"))
401
402 ;; Describe a user's asm statement.
403 (define_asm_attributes
404 [(set_attr "length" "128")
405 (set_attr "type" "multi")])
406 \f
407 (include "pentium.md")
408 (include "ppro.md")
409 (include "k6.md")
410 (include "athlon.md")
411 \f
412 ;; Compare instructions.
413
414 ;; All compare insns have expanders that save the operands away without
415 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
416 ;; after the cmp) will actually emit the cmpM.
417
418 (define_expand "cmpdi"
419 [(set (reg:CC 17)
420 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
421 (match_operand:DI 1 "x86_64_general_operand" "")))]
422 ""
423 {
424 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
425 operands[0] = force_reg (DImode, operands[0]);
426 ix86_compare_op0 = operands[0];
427 ix86_compare_op1 = operands[1];
428 DONE;
429 })
430
431 (define_expand "cmpsi"
432 [(set (reg:CC 17)
433 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
434 (match_operand:SI 1 "general_operand" "")))]
435 ""
436 {
437 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
438 operands[0] = force_reg (SImode, operands[0]);
439 ix86_compare_op0 = operands[0];
440 ix86_compare_op1 = operands[1];
441 DONE;
442 })
443
444 (define_expand "cmphi"
445 [(set (reg:CC 17)
446 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
447 (match_operand:HI 1 "general_operand" "")))]
448 ""
449 {
450 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
451 operands[0] = force_reg (HImode, operands[0]);
452 ix86_compare_op0 = operands[0];
453 ix86_compare_op1 = operands[1];
454 DONE;
455 })
456
457 (define_expand "cmpqi"
458 [(set (reg:CC 17)
459 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
460 (match_operand:QI 1 "general_operand" "")))]
461 "TARGET_QIMODE_MATH"
462 {
463 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
464 operands[0] = force_reg (QImode, operands[0]);
465 ix86_compare_op0 = operands[0];
466 ix86_compare_op1 = operands[1];
467 DONE;
468 })
469
470 (define_insn "cmpdi_ccno_1_rex64"
471 [(set (reg 17)
472 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
473 (match_operand:DI 1 "const0_operand" "n,n")))]
474 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
475 "@
476 test{q}\t{%0, %0|%0, %0}
477 cmp{q}\t{%1, %0|%0, %1}"
478 [(set_attr "type" "test,icmp")
479 (set_attr "length_immediate" "0,1")
480 (set_attr "mode" "DI")])
481
482 (define_insn "*cmpdi_minus_1_rex64"
483 [(set (reg 17)
484 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
485 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
486 (const_int 0)))]
487 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
488 "cmp{q}\t{%1, %0|%0, %1}"
489 [(set_attr "type" "icmp")
490 (set_attr "mode" "DI")])
491
492 (define_expand "cmpdi_1_rex64"
493 [(set (reg:CC 17)
494 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
495 (match_operand:DI 1 "general_operand" "")))]
496 "TARGET_64BIT"
497 "")
498
499 (define_insn "cmpdi_1_insn_rex64"
500 [(set (reg 17)
501 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
502 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
503 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
504 "cmp{q}\t{%1, %0|%0, %1}"
505 [(set_attr "type" "icmp")
506 (set_attr "mode" "DI")])
507
508
509 (define_insn "*cmpsi_ccno_1"
510 [(set (reg 17)
511 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
512 (match_operand:SI 1 "const0_operand" "n,n")))]
513 "ix86_match_ccmode (insn, CCNOmode)"
514 "@
515 test{l}\t{%0, %0|%0, %0}
516 cmp{l}\t{%1, %0|%0, %1}"
517 [(set_attr "type" "test,icmp")
518 (set_attr "length_immediate" "0,1")
519 (set_attr "mode" "SI")])
520
521 (define_insn "*cmpsi_minus_1"
522 [(set (reg 17)
523 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
524 (match_operand:SI 1 "general_operand" "ri,mr"))
525 (const_int 0)))]
526 "ix86_match_ccmode (insn, CCGOCmode)"
527 "cmp{l}\t{%1, %0|%0, %1}"
528 [(set_attr "type" "icmp")
529 (set_attr "mode" "SI")])
530
531 (define_expand "cmpsi_1"
532 [(set (reg:CC 17)
533 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
534 (match_operand:SI 1 "general_operand" "ri,mr")))]
535 ""
536 "")
537
538 (define_insn "*cmpsi_1_insn"
539 [(set (reg 17)
540 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
541 (match_operand:SI 1 "general_operand" "ri,mr")))]
542 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
543 && ix86_match_ccmode (insn, CCmode)"
544 "cmp{l}\t{%1, %0|%0, %1}"
545 [(set_attr "type" "icmp")
546 (set_attr "mode" "SI")])
547
548 (define_insn "*cmphi_ccno_1"
549 [(set (reg 17)
550 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
551 (match_operand:HI 1 "const0_operand" "n,n")))]
552 "ix86_match_ccmode (insn, CCNOmode)"
553 "@
554 test{w}\t{%0, %0|%0, %0}
555 cmp{w}\t{%1, %0|%0, %1}"
556 [(set_attr "type" "test,icmp")
557 (set_attr "length_immediate" "0,1")
558 (set_attr "mode" "HI")])
559
560 (define_insn "*cmphi_minus_1"
561 [(set (reg 17)
562 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
563 (match_operand:HI 1 "general_operand" "ri,mr"))
564 (const_int 0)))]
565 "ix86_match_ccmode (insn, CCGOCmode)"
566 "cmp{w}\t{%1, %0|%0, %1}"
567 [(set_attr "type" "icmp")
568 (set_attr "mode" "HI")])
569
570 (define_insn "*cmphi_1"
571 [(set (reg 17)
572 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
573 (match_operand:HI 1 "general_operand" "ri,mr")))]
574 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
575 && ix86_match_ccmode (insn, CCmode)"
576 "cmp{w}\t{%1, %0|%0, %1}"
577 [(set_attr "type" "icmp")
578 (set_attr "mode" "HI")])
579
580 (define_insn "*cmpqi_ccno_1"
581 [(set (reg 17)
582 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
583 (match_operand:QI 1 "const0_operand" "n,n")))]
584 "ix86_match_ccmode (insn, CCNOmode)"
585 "@
586 test{b}\t{%0, %0|%0, %0}
587 cmp{b}\t{$0, %0|%0, 0}"
588 [(set_attr "type" "test,icmp")
589 (set_attr "length_immediate" "0,1")
590 (set_attr "mode" "QI")])
591
592 (define_insn "*cmpqi_1"
593 [(set (reg 17)
594 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
595 (match_operand:QI 1 "general_operand" "qi,mq")))]
596 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
597 && ix86_match_ccmode (insn, CCmode)"
598 "cmp{b}\t{%1, %0|%0, %1}"
599 [(set_attr "type" "icmp")
600 (set_attr "mode" "QI")])
601
602 (define_insn "*cmpqi_minus_1"
603 [(set (reg 17)
604 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
605 (match_operand:QI 1 "general_operand" "qi,mq"))
606 (const_int 0)))]
607 "ix86_match_ccmode (insn, CCGOCmode)"
608 "cmp{b}\t{%1, %0|%0, %1}"
609 [(set_attr "type" "icmp")
610 (set_attr "mode" "QI")])
611
612 (define_insn "*cmpqi_ext_1"
613 [(set (reg 17)
614 (compare
615 (match_operand:QI 0 "general_operand" "Qm")
616 (subreg:QI
617 (zero_extract:SI
618 (match_operand 1 "ext_register_operand" "Q")
619 (const_int 8)
620 (const_int 8)) 0)))]
621 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
622 "cmp{b}\t{%h1, %0|%0, %h1}"
623 [(set_attr "type" "icmp")
624 (set_attr "mode" "QI")])
625
626 (define_insn "*cmpqi_ext_1_rex64"
627 [(set (reg 17)
628 (compare
629 (match_operand:QI 0 "register_operand" "Q")
630 (subreg:QI
631 (zero_extract:SI
632 (match_operand 1 "ext_register_operand" "Q")
633 (const_int 8)
634 (const_int 8)) 0)))]
635 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
636 "cmp{b}\t{%h1, %0|%0, %h1}"
637 [(set_attr "type" "icmp")
638 (set_attr "mode" "QI")])
639
640 (define_insn "*cmpqi_ext_2"
641 [(set (reg 17)
642 (compare
643 (subreg:QI
644 (zero_extract:SI
645 (match_operand 0 "ext_register_operand" "Q")
646 (const_int 8)
647 (const_int 8)) 0)
648 (match_operand:QI 1 "const0_operand" "n")))]
649 "ix86_match_ccmode (insn, CCNOmode)"
650 "test{b}\t%h0, %h0"
651 [(set_attr "type" "test")
652 (set_attr "length_immediate" "0")
653 (set_attr "mode" "QI")])
654
655 (define_expand "cmpqi_ext_3"
656 [(set (reg:CC 17)
657 (compare:CC
658 (subreg:QI
659 (zero_extract:SI
660 (match_operand 0 "ext_register_operand" "")
661 (const_int 8)
662 (const_int 8)) 0)
663 (match_operand:QI 1 "general_operand" "")))]
664 ""
665 "")
666
667 (define_insn "cmpqi_ext_3_insn"
668 [(set (reg 17)
669 (compare
670 (subreg:QI
671 (zero_extract:SI
672 (match_operand 0 "ext_register_operand" "Q")
673 (const_int 8)
674 (const_int 8)) 0)
675 (match_operand:QI 1 "general_operand" "Qmn")))]
676 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
677 "cmp{b}\t{%1, %h0|%h0, %1}"
678 [(set_attr "type" "icmp")
679 (set_attr "mode" "QI")])
680
681 (define_insn "cmpqi_ext_3_insn_rex64"
682 [(set (reg 17)
683 (compare
684 (subreg:QI
685 (zero_extract:SI
686 (match_operand 0 "ext_register_operand" "Q")
687 (const_int 8)
688 (const_int 8)) 0)
689 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
690 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
691 "cmp{b}\t{%1, %h0|%h0, %1}"
692 [(set_attr "type" "icmp")
693 (set_attr "mode" "QI")])
694
695 (define_insn "*cmpqi_ext_4"
696 [(set (reg 17)
697 (compare
698 (subreg:QI
699 (zero_extract:SI
700 (match_operand 0 "ext_register_operand" "Q")
701 (const_int 8)
702 (const_int 8)) 0)
703 (subreg:QI
704 (zero_extract:SI
705 (match_operand 1 "ext_register_operand" "Q")
706 (const_int 8)
707 (const_int 8)) 0)))]
708 "ix86_match_ccmode (insn, CCmode)"
709 "cmp{b}\t{%h1, %h0|%h0, %h1}"
710 [(set_attr "type" "icmp")
711 (set_attr "mode" "QI")])
712
713 ;; These implement float point compares.
714 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
715 ;; which would allow mix and match FP modes on the compares. Which is what
716 ;; the old patterns did, but with many more of them.
717
718 (define_expand "cmpxf"
719 [(set (reg:CC 17)
720 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
721 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
722 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
723 {
724 ix86_compare_op0 = operands[0];
725 ix86_compare_op1 = operands[1];
726 DONE;
727 })
728
729 (define_expand "cmptf"
730 [(set (reg:CC 17)
731 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
732 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
733 "TARGET_80387"
734 {
735 ix86_compare_op0 = operands[0];
736 ix86_compare_op1 = operands[1];
737 DONE;
738 })
739
740 (define_expand "cmpdf"
741 [(set (reg:CC 17)
742 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
743 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
744 "TARGET_80387 || TARGET_SSE2"
745 {
746 ix86_compare_op0 = operands[0];
747 ix86_compare_op1 = operands[1];
748 DONE;
749 })
750
751 (define_expand "cmpsf"
752 [(set (reg:CC 17)
753 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
754 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
755 "TARGET_80387 || TARGET_SSE"
756 {
757 ix86_compare_op0 = operands[0];
758 ix86_compare_op1 = operands[1];
759 DONE;
760 })
761
762 ;; FP compares, step 1:
763 ;; Set the FP condition codes.
764 ;;
765 ;; CCFPmode compare with exceptions
766 ;; CCFPUmode compare with no exceptions
767
768 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
769 ;; and that fp moves clobber the condition codes, and that there is
770 ;; currently no way to describe this fact to reg-stack. So there are
771 ;; no splitters yet for this.
772
773 ;; %%% YIKES! This scheme does not retain a strong connection between
774 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
775 ;; work! Only allow tos/mem with tos in op 0.
776 ;;
777 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
778 ;; things aren't as bad as they sound...
779
780 (define_insn "*cmpfp_0"
781 [(set (match_operand:HI 0 "register_operand" "=a")
782 (unspec:HI
783 [(compare:CCFP (match_operand 1 "register_operand" "f")
784 (match_operand 2 "const0_operand" "X"))]
785 UNSPEC_FNSTSW))]
786 "TARGET_80387
787 && FLOAT_MODE_P (GET_MODE (operands[1]))
788 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
789 {
790 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
791 return "ftst\;fnstsw\t%0\;fstp\t%y0";
792 else
793 return "ftst\;fnstsw\t%0";
794 }
795 [(set_attr "type" "multi")
796 (set (attr "mode")
797 (cond [(match_operand:SF 1 "" "")
798 (const_string "SF")
799 (match_operand:DF 1 "" "")
800 (const_string "DF")
801 ]
802 (const_string "XF")))])
803
804 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
805 ;; used to manage the reg stack popping would not be preserved.
806
807 (define_insn "*cmpfp_2_sf"
808 [(set (reg:CCFP 18)
809 (compare:CCFP
810 (match_operand:SF 0 "register_operand" "f")
811 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
812 "TARGET_80387"
813 "* return output_fp_compare (insn, operands, 0, 0);"
814 [(set_attr "type" "fcmp")
815 (set_attr "mode" "SF")])
816
817 (define_insn "*cmpfp_2_sf_1"
818 [(set (match_operand:HI 0 "register_operand" "=a")
819 (unspec:HI
820 [(compare:CCFP
821 (match_operand:SF 1 "register_operand" "f")
822 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
823 UNSPEC_FNSTSW))]
824 "TARGET_80387"
825 "* return output_fp_compare (insn, operands, 2, 0);"
826 [(set_attr "type" "fcmp")
827 (set_attr "mode" "SF")])
828
829 (define_insn "*cmpfp_2_df"
830 [(set (reg:CCFP 18)
831 (compare:CCFP
832 (match_operand:DF 0 "register_operand" "f")
833 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
834 "TARGET_80387"
835 "* return output_fp_compare (insn, operands, 0, 0);"
836 [(set_attr "type" "fcmp")
837 (set_attr "mode" "DF")])
838
839 (define_insn "*cmpfp_2_df_1"
840 [(set (match_operand:HI 0 "register_operand" "=a")
841 (unspec:HI
842 [(compare:CCFP
843 (match_operand:DF 1 "register_operand" "f")
844 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
845 UNSPEC_FNSTSW))]
846 "TARGET_80387"
847 "* return output_fp_compare (insn, operands, 2, 0);"
848 [(set_attr "type" "multi")
849 (set_attr "mode" "DF")])
850
851 (define_insn "*cmpfp_2_xf"
852 [(set (reg:CCFP 18)
853 (compare:CCFP
854 (match_operand:XF 0 "register_operand" "f")
855 (match_operand:XF 1 "register_operand" "f")))]
856 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
857 "* return output_fp_compare (insn, operands, 0, 0);"
858 [(set_attr "type" "fcmp")
859 (set_attr "mode" "XF")])
860
861 (define_insn "*cmpfp_2_tf"
862 [(set (reg:CCFP 18)
863 (compare:CCFP
864 (match_operand:TF 0 "register_operand" "f")
865 (match_operand:TF 1 "register_operand" "f")))]
866 "TARGET_80387"
867 "* return output_fp_compare (insn, operands, 0, 0);"
868 [(set_attr "type" "fcmp")
869 (set_attr "mode" "XF")])
870
871 (define_insn "*cmpfp_2_xf_1"
872 [(set (match_operand:HI 0 "register_operand" "=a")
873 (unspec:HI
874 [(compare:CCFP
875 (match_operand:XF 1 "register_operand" "f")
876 (match_operand:XF 2 "register_operand" "f"))]
877 UNSPEC_FNSTSW))]
878 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
879 "* return output_fp_compare (insn, operands, 2, 0);"
880 [(set_attr "type" "multi")
881 (set_attr "mode" "XF")])
882
883 (define_insn "*cmpfp_2_tf_1"
884 [(set (match_operand:HI 0 "register_operand" "=a")
885 (unspec:HI
886 [(compare:CCFP
887 (match_operand:TF 1 "register_operand" "f")
888 (match_operand:TF 2 "register_operand" "f"))]
889 UNSPEC_FNSTSW))]
890 "TARGET_80387"
891 "* return output_fp_compare (insn, operands, 2, 0);"
892 [(set_attr "type" "multi")
893 (set_attr "mode" "XF")])
894
895 (define_insn "*cmpfp_2u"
896 [(set (reg:CCFPU 18)
897 (compare:CCFPU
898 (match_operand 0 "register_operand" "f")
899 (match_operand 1 "register_operand" "f")))]
900 "TARGET_80387
901 && FLOAT_MODE_P (GET_MODE (operands[0]))
902 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
903 "* return output_fp_compare (insn, operands, 0, 1);"
904 [(set_attr "type" "fcmp")
905 (set (attr "mode")
906 (cond [(match_operand:SF 1 "" "")
907 (const_string "SF")
908 (match_operand:DF 1 "" "")
909 (const_string "DF")
910 ]
911 (const_string "XF")))])
912
913 (define_insn "*cmpfp_2u_1"
914 [(set (match_operand:HI 0 "register_operand" "=a")
915 (unspec:HI
916 [(compare:CCFPU
917 (match_operand 1 "register_operand" "f")
918 (match_operand 2 "register_operand" "f"))]
919 UNSPEC_FNSTSW))]
920 "TARGET_80387
921 && FLOAT_MODE_P (GET_MODE (operands[1]))
922 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
923 "* return output_fp_compare (insn, operands, 2, 1);"
924 [(set_attr "type" "multi")
925 (set (attr "mode")
926 (cond [(match_operand:SF 1 "" "")
927 (const_string "SF")
928 (match_operand:DF 1 "" "")
929 (const_string "DF")
930 ]
931 (const_string "XF")))])
932
933 ;; Patterns to match the SImode-in-memory ficom instructions.
934 ;;
935 ;; %%% Play games with accepting gp registers, as otherwise we have to
936 ;; force them to memory during rtl generation, which is no good. We
937 ;; can get rid of this once we teach reload to do memory input reloads
938 ;; via pushes.
939
940 (define_insn "*ficom_1"
941 [(set (reg:CCFP 18)
942 (compare:CCFP
943 (match_operand 0 "register_operand" "f,f")
944 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
945 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
946 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
947 "#")
948
949 ;; Split the not-really-implemented gp register case into a
950 ;; push-op-pop sequence.
951 ;;
952 ;; %%% This is most efficient, but am I gonna get in trouble
953 ;; for separating cc0_setter and cc0_user?
954
955 (define_split
956 [(set (reg:CCFP 18)
957 (compare:CCFP
958 (match_operand:SF 0 "register_operand" "")
959 (float (match_operand:SI 1 "register_operand" ""))))]
960 "0 && TARGET_80387 && reload_completed"
961 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
962 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
963 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
964 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
965 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
966 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
967
968 ;; FP compares, step 2
969 ;; Move the fpsw to ax.
970
971 (define_insn "*x86_fnstsw_1"
972 [(set (match_operand:HI 0 "register_operand" "=a")
973 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
974 "TARGET_80387"
975 "fnstsw\t%0"
976 [(set_attr "length" "2")
977 (set_attr "mode" "SI")
978 (set_attr "unit" "i387")
979 (set_attr "ppro_uops" "few")])
980
981 ;; FP compares, step 3
982 ;; Get ax into flags, general case.
983
984 (define_insn "x86_sahf_1"
985 [(set (reg:CC 17)
986 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
987 "!TARGET_64BIT"
988 "sahf"
989 [(set_attr "length" "1")
990 (set_attr "athlon_decode" "vector")
991 (set_attr "mode" "SI")
992 (set_attr "ppro_uops" "one")])
993
994 ;; Pentium Pro can do steps 1 through 3 in one go.
995
996 (define_insn "*cmpfp_i"
997 [(set (reg:CCFP 17)
998 (compare:CCFP (match_operand 0 "register_operand" "f")
999 (match_operand 1 "register_operand" "f")))]
1000 "TARGET_80387 && TARGET_CMOVE
1001 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002 && FLOAT_MODE_P (GET_MODE (operands[0]))
1003 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1004 "* return output_fp_compare (insn, operands, 1, 0);"
1005 [(set_attr "type" "fcmp")
1006 (set (attr "mode")
1007 (cond [(match_operand:SF 1 "" "")
1008 (const_string "SF")
1009 (match_operand:DF 1 "" "")
1010 (const_string "DF")
1011 ]
1012 (const_string "XF")))
1013 (set_attr "athlon_decode" "vector")])
1014
1015 (define_insn "*cmpfp_i_sse"
1016 [(set (reg:CCFP 17)
1017 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1018 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1019 "TARGET_80387
1020 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1022 "* return output_fp_compare (insn, operands, 1, 0);"
1023 [(set_attr "type" "fcmp,ssecomi")
1024 (set (attr "mode")
1025 (if_then_else (match_operand:SF 1 "" "")
1026 (const_string "SF")
1027 (const_string "DF")))
1028 (set_attr "athlon_decode" "vector")])
1029
1030 (define_insn "*cmpfp_i_sse_only"
1031 [(set (reg:CCFP 17)
1032 (compare:CCFP (match_operand 0 "register_operand" "x")
1033 (match_operand 1 "nonimmediate_operand" "xm")))]
1034 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1035 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1036 "* return output_fp_compare (insn, operands, 1, 0);"
1037 [(set_attr "type" "ssecomi")
1038 (set (attr "mode")
1039 (if_then_else (match_operand:SF 1 "" "")
1040 (const_string "SF")
1041 (const_string "DF")))
1042 (set_attr "athlon_decode" "vector")])
1043
1044 (define_insn "*cmpfp_iu"
1045 [(set (reg:CCFPU 17)
1046 (compare:CCFPU (match_operand 0 "register_operand" "f")
1047 (match_operand 1 "register_operand" "f")))]
1048 "TARGET_80387 && TARGET_CMOVE
1049 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1050 && FLOAT_MODE_P (GET_MODE (operands[0]))
1051 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052 "* return output_fp_compare (insn, operands, 1, 1);"
1053 [(set_attr "type" "fcmp")
1054 (set (attr "mode")
1055 (cond [(match_operand:SF 1 "" "")
1056 (const_string "SF")
1057 (match_operand:DF 1 "" "")
1058 (const_string "DF")
1059 ]
1060 (const_string "XF")))
1061 (set_attr "athlon_decode" "vector")])
1062
1063 (define_insn "*cmpfp_iu_sse"
1064 [(set (reg:CCFPU 17)
1065 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1066 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1067 "TARGET_80387
1068 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1069 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1070 "* return output_fp_compare (insn, operands, 1, 1);"
1071 [(set_attr "type" "fcmp,ssecomi")
1072 (set (attr "mode")
1073 (if_then_else (match_operand:SF 1 "" "")
1074 (const_string "SF")
1075 (const_string "DF")))
1076 (set_attr "athlon_decode" "vector")])
1077
1078 (define_insn "*cmpfp_iu_sse_only"
1079 [(set (reg:CCFPU 17)
1080 (compare:CCFPU (match_operand 0 "register_operand" "x")
1081 (match_operand 1 "nonimmediate_operand" "xm")))]
1082 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1083 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1084 "* return output_fp_compare (insn, operands, 1, 1);"
1085 [(set_attr "type" "ssecomi")
1086 (set (attr "mode")
1087 (if_then_else (match_operand:SF 1 "" "")
1088 (const_string "SF")
1089 (const_string "DF")))
1090 (set_attr "athlon_decode" "vector")])
1091 \f
1092 ;; Move instructions.
1093
1094 ;; General case of fullword move.
1095
1096 (define_expand "movsi"
1097 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1098 (match_operand:SI 1 "general_operand" ""))]
1099 ""
1100 "ix86_expand_move (SImode, operands); DONE;")
1101
1102 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1103 ;; general_operand.
1104 ;;
1105 ;; %%% We don't use a post-inc memory reference because x86 is not a
1106 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1107 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1108 ;; targets without our curiosities, and it is just as easy to represent
1109 ;; this differently.
1110
1111 (define_insn "*pushsi2"
1112 [(set (match_operand:SI 0 "push_operand" "=<")
1113 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1114 "!TARGET_64BIT"
1115 "push{l}\t%1"
1116 [(set_attr "type" "push")
1117 (set_attr "mode" "SI")])
1118
1119 ;; For 64BIT abi we always round up to 8 bytes.
1120 (define_insn "*pushsi2_rex64"
1121 [(set (match_operand:SI 0 "push_operand" "=X")
1122 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1123 "TARGET_64BIT"
1124 "push{q}\t%q1"
1125 [(set_attr "type" "push")
1126 (set_attr "mode" "SI")])
1127
1128 (define_insn "*pushsi2_prologue"
1129 [(set (match_operand:SI 0 "push_operand" "=<")
1130 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1131 (clobber (mem:BLK (scratch)))]
1132 "!TARGET_64BIT"
1133 "push{l}\t%1"
1134 [(set_attr "type" "push")
1135 (set_attr "mode" "SI")])
1136
1137 (define_insn "*popsi1_epilogue"
1138 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1139 (mem:SI (reg:SI 7)))
1140 (set (reg:SI 7)
1141 (plus:SI (reg:SI 7) (const_int 4)))
1142 (clobber (mem:BLK (scratch)))]
1143 "!TARGET_64BIT"
1144 "pop{l}\t%0"
1145 [(set_attr "type" "pop")
1146 (set_attr "mode" "SI")])
1147
1148 (define_insn "popsi1"
1149 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1150 (mem:SI (reg:SI 7)))
1151 (set (reg:SI 7)
1152 (plus:SI (reg:SI 7) (const_int 4)))]
1153 "!TARGET_64BIT"
1154 "pop{l}\t%0"
1155 [(set_attr "type" "pop")
1156 (set_attr "mode" "SI")])
1157
1158 (define_insn "*movsi_xor"
1159 [(set (match_operand:SI 0 "register_operand" "=r")
1160 (match_operand:SI 1 "const0_operand" "i"))
1161 (clobber (reg:CC 17))]
1162 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1163 "xor{l}\t{%0, %0|%0, %0}"
1164 [(set_attr "type" "alu1")
1165 (set_attr "mode" "SI")
1166 (set_attr "length_immediate" "0")])
1167
1168 (define_insn "*movsi_or"
1169 [(set (match_operand:SI 0 "register_operand" "=r")
1170 (match_operand:SI 1 "immediate_operand" "i"))
1171 (clobber (reg:CC 17))]
1172 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1173 && INTVAL (operands[1]) == -1
1174 && (TARGET_PENTIUM || optimize_size)"
1175 {
1176 operands[1] = constm1_rtx;
1177 return "or{l}\t{%1, %0|%0, %1}";
1178 }
1179 [(set_attr "type" "alu1")
1180 (set_attr "mode" "SI")
1181 (set_attr "length_immediate" "1")])
1182
1183 (define_insn "*movsi_1"
1184 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1185 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1186 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1187 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1188 {
1189 switch (get_attr_type (insn))
1190 {
1191 case TYPE_SSEMOV:
1192 if (get_attr_mode (insn) == MODE_TI)
1193 return "movdqa\t{%1, %0|%0, %1}";
1194 return "movd\t{%1, %0|%0, %1}";
1195
1196 case TYPE_MMXMOV:
1197 if (get_attr_mode (insn) == MODE_DI)
1198 return "movq\t{%1, %0|%0, %1}";
1199 return "movd\t{%1, %0|%0, %1}";
1200
1201 case TYPE_LEA:
1202 return "lea{l}\t{%1, %0|%0, %1}";
1203
1204 default:
1205 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1206 abort();
1207 return "mov{l}\t{%1, %0|%0, %1}";
1208 }
1209 }
1210 [(set (attr "type")
1211 (cond [(eq_attr "alternative" "2,3,4")
1212 (const_string "mmxmov")
1213 (eq_attr "alternative" "5,6,7")
1214 (const_string "ssemov")
1215 (and (ne (symbol_ref "flag_pic") (const_int 0))
1216 (match_operand:SI 1 "symbolic_operand" ""))
1217 (const_string "lea")
1218 ]
1219 (const_string "imov")))
1220 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1221
1222 (define_insn "*movsi_1_nointernunit"
1223 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1224 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1225 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1226 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1227 {
1228 switch (get_attr_type (insn))
1229 {
1230 case TYPE_SSEMOV:
1231 if (get_attr_mode (insn) == MODE_TI)
1232 return "movdqa\t{%1, %0|%0, %1}";
1233 return "movd\t{%1, %0|%0, %1}";
1234
1235 case TYPE_MMXMOV:
1236 if (get_attr_mode (insn) == MODE_DI)
1237 return "movq\t{%1, %0|%0, %1}";
1238 return "movd\t{%1, %0|%0, %1}";
1239
1240 case TYPE_LEA:
1241 return "lea{l}\t{%1, %0|%0, %1}";
1242
1243 default:
1244 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1245 abort();
1246 return "mov{l}\t{%1, %0|%0, %1}";
1247 }
1248 }
1249 [(set (attr "type")
1250 (cond [(eq_attr "alternative" "2,3,4")
1251 (const_string "mmxmov")
1252 (eq_attr "alternative" "5,6,7")
1253 (const_string "ssemov")
1254 (and (ne (symbol_ref "flag_pic") (const_int 0))
1255 (match_operand:SI 1 "symbolic_operand" ""))
1256 (const_string "lea")
1257 ]
1258 (const_string "imov")))
1259 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1260
1261 ;; Stores and loads of ax to arbitrary constant address.
1262 ;; We fake an second form of instruction to force reload to load address
1263 ;; into register when rax is not available
1264 (define_insn "*movabssi_1_rex64"
1265 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1266 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1267 "TARGET_64BIT"
1268 "@
1269 movabs{l}\t{%1, %P0|%P0, %1}
1270 mov{l}\t{%1, %a0|%a0, %1}
1271 movabs{l}\t{%1, %a0|%a0, %1}"
1272 [(set_attr "type" "imov")
1273 (set_attr "modrm" "0,*,*")
1274 (set_attr "length_address" "8,0,0")
1275 (set_attr "length_immediate" "0,*,*")
1276 (set_attr "memory" "store")
1277 (set_attr "mode" "SI")])
1278
1279 (define_insn "*movabssi_2_rex64"
1280 [(set (match_operand:SI 0 "register_operand" "=a,r")
1281 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1282 "TARGET_64BIT"
1283 "@
1284 movabs{l}\t{%P1, %0|%0, %P1}
1285 mov{l}\t{%a1, %0|%0, %a1}"
1286 [(set_attr "type" "imov")
1287 (set_attr "modrm" "0,*")
1288 (set_attr "length_address" "8,0")
1289 (set_attr "length_immediate" "0")
1290 (set_attr "memory" "load")
1291 (set_attr "mode" "SI")])
1292
1293 (define_insn "*swapsi"
1294 [(set (match_operand:SI 0 "register_operand" "+r")
1295 (match_operand:SI 1 "register_operand" "+r"))
1296 (set (match_dup 1)
1297 (match_dup 0))]
1298 ""
1299 "xchg{l}\t%1, %0"
1300 [(set_attr "type" "imov")
1301 (set_attr "pent_pair" "np")
1302 (set_attr "athlon_decode" "vector")
1303 (set_attr "mode" "SI")
1304 (set_attr "modrm" "0")
1305 (set_attr "ppro_uops" "few")])
1306
1307 (define_expand "movhi"
1308 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1309 (match_operand:HI 1 "general_operand" ""))]
1310 ""
1311 "ix86_expand_move (HImode, operands); DONE;")
1312
1313 (define_insn "*pushhi2"
1314 [(set (match_operand:HI 0 "push_operand" "=<,<")
1315 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1316 "!TARGET_64BIT"
1317 "@
1318 push{w}\t{|WORD PTR }%1
1319 push{w}\t%1"
1320 [(set_attr "type" "push")
1321 (set_attr "mode" "HI")])
1322
1323 ;; For 64BIT abi we always round up to 8 bytes.
1324 (define_insn "*pushhi2_rex64"
1325 [(set (match_operand:HI 0 "push_operand" "=X")
1326 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1327 "TARGET_64BIT"
1328 "push{q}\t%q1"
1329 [(set_attr "type" "push")
1330 (set_attr "mode" "QI")])
1331
1332 (define_insn "*movhi_1"
1333 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1334 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1335 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1336 {
1337 switch (get_attr_type (insn))
1338 {
1339 case TYPE_IMOVX:
1340 /* movzwl is faster than movw on p2 due to partial word stalls,
1341 though not as fast as an aligned movl. */
1342 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1343 default:
1344 if (get_attr_mode (insn) == MODE_SI)
1345 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1346 else
1347 return "mov{w}\t{%1, %0|%0, %1}";
1348 }
1349 }
1350 [(set (attr "type")
1351 (cond [(and (eq_attr "alternative" "0")
1352 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1353 (const_int 0))
1354 (eq (symbol_ref "TARGET_HIMODE_MATH")
1355 (const_int 0))))
1356 (const_string "imov")
1357 (and (eq_attr "alternative" "1,2")
1358 (match_operand:HI 1 "aligned_operand" ""))
1359 (const_string "imov")
1360 (and (ne (symbol_ref "TARGET_MOVX")
1361 (const_int 0))
1362 (eq_attr "alternative" "0,2"))
1363 (const_string "imovx")
1364 ]
1365 (const_string "imov")))
1366 (set (attr "mode")
1367 (cond [(eq_attr "type" "imovx")
1368 (const_string "SI")
1369 (and (eq_attr "alternative" "1,2")
1370 (match_operand:HI 1 "aligned_operand" ""))
1371 (const_string "SI")
1372 (and (eq_attr "alternative" "0")
1373 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1374 (const_int 0))
1375 (eq (symbol_ref "TARGET_HIMODE_MATH")
1376 (const_int 0))))
1377 (const_string "SI")
1378 ]
1379 (const_string "HI")))])
1380
1381 ;; Stores and loads of ax to arbitrary constant address.
1382 ;; We fake an second form of instruction to force reload to load address
1383 ;; into register when rax is not available
1384 (define_insn "*movabshi_1_rex64"
1385 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1386 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1387 "TARGET_64BIT"
1388 "@
1389 movabs{w}\t{%1, %P0|%P0, %1}
1390 mov{w}\t{%1, %a0|%a0, %1}
1391 movabs{w}\t{%1, %a0|%a0, %1}"
1392 [(set_attr "type" "imov")
1393 (set_attr "modrm" "0,*,*")
1394 (set_attr "length_address" "8,0,0")
1395 (set_attr "length_immediate" "0,*,*")
1396 (set_attr "memory" "store")
1397 (set_attr "mode" "HI")])
1398
1399 (define_insn "*movabshi_2_rex64"
1400 [(set (match_operand:HI 0 "register_operand" "=a,r")
1401 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1402 "TARGET_64BIT"
1403 "@
1404 movabs{w}\t{%P1, %0|%0, %P1}
1405 mov{w}\t{%a1, %0|%0, %a1}"
1406 [(set_attr "type" "imov")
1407 (set_attr "modrm" "0,*")
1408 (set_attr "length_address" "8,0")
1409 (set_attr "length_immediate" "0")
1410 (set_attr "memory" "load")
1411 (set_attr "mode" "HI")])
1412
1413 (define_insn "*swaphi_1"
1414 [(set (match_operand:HI 0 "register_operand" "+r")
1415 (match_operand:HI 1 "register_operand" "+r"))
1416 (set (match_dup 1)
1417 (match_dup 0))]
1418 "TARGET_PARTIAL_REG_STALL"
1419 "xchg{w}\t%1, %0"
1420 [(set_attr "type" "imov")
1421 (set_attr "pent_pair" "np")
1422 (set_attr "mode" "HI")
1423 (set_attr "modrm" "0")
1424 (set_attr "ppro_uops" "few")])
1425
1426 (define_insn "*swaphi_2"
1427 [(set (match_operand:HI 0 "register_operand" "+r")
1428 (match_operand:HI 1 "register_operand" "+r"))
1429 (set (match_dup 1)
1430 (match_dup 0))]
1431 "! TARGET_PARTIAL_REG_STALL"
1432 "xchg{l}\t%k1, %k0"
1433 [(set_attr "type" "imov")
1434 (set_attr "pent_pair" "np")
1435 (set_attr "mode" "SI")
1436 (set_attr "modrm" "0")
1437 (set_attr "ppro_uops" "few")])
1438
1439 (define_expand "movstricthi"
1440 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1441 (match_operand:HI 1 "general_operand" ""))]
1442 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1443 {
1444 /* Don't generate memory->memory moves, go through a register */
1445 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1446 operands[1] = force_reg (HImode, operands[1]);
1447 })
1448
1449 (define_insn "*movstricthi_1"
1450 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1451 (match_operand:HI 1 "general_operand" "rn,m"))]
1452 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1453 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1454 "mov{w}\t{%1, %0|%0, %1}"
1455 [(set_attr "type" "imov")
1456 (set_attr "mode" "HI")])
1457
1458 (define_insn "*movstricthi_xor"
1459 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1460 (match_operand:HI 1 "const0_operand" "i"))
1461 (clobber (reg:CC 17))]
1462 "reload_completed
1463 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1464 "xor{w}\t{%0, %0|%0, %0}"
1465 [(set_attr "type" "alu1")
1466 (set_attr "mode" "HI")
1467 (set_attr "length_immediate" "0")])
1468
1469 (define_expand "movqi"
1470 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1471 (match_operand:QI 1 "general_operand" ""))]
1472 ""
1473 "ix86_expand_move (QImode, operands); DONE;")
1474
1475 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1476 ;; "push a byte". But actually we use pushw, which has the effect
1477 ;; of rounding the amount pushed up to a halfword.
1478
1479 (define_insn "*pushqi2"
1480 [(set (match_operand:QI 0 "push_operand" "=X,X")
1481 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1482 "!TARGET_64BIT"
1483 "@
1484 push{w}\t{|word ptr }%1
1485 push{w}\t%w1"
1486 [(set_attr "type" "push")
1487 (set_attr "mode" "HI")])
1488
1489 ;; For 64BIT abi we always round up to 8 bytes.
1490 (define_insn "*pushqi2_rex64"
1491 [(set (match_operand:QI 0 "push_operand" "=X")
1492 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1493 "TARGET_64BIT"
1494 "push{q}\t%q1"
1495 [(set_attr "type" "push")
1496 (set_attr "mode" "QI")])
1497
1498 ;; Situation is quite tricky about when to choose full sized (SImode) move
1499 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1500 ;; partial register dependency machines (such as AMD Athlon), where QImode
1501 ;; moves issue extra dependency and for partial register stalls machines
1502 ;; that don't use QImode patterns (and QImode move cause stall on the next
1503 ;; instruction).
1504 ;;
1505 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1506 ;; register stall machines with, where we use QImode instructions, since
1507 ;; partial register stall can be caused there. Then we use movzx.
1508 (define_insn "*movqi_1"
1509 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1510 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1511 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1512 {
1513 switch (get_attr_type (insn))
1514 {
1515 case TYPE_IMOVX:
1516 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1517 abort ();
1518 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1519 default:
1520 if (get_attr_mode (insn) == MODE_SI)
1521 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1522 else
1523 return "mov{b}\t{%1, %0|%0, %1}";
1524 }
1525 }
1526 [(set (attr "type")
1527 (cond [(and (eq_attr "alternative" "3")
1528 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1529 (const_int 0))
1530 (eq (symbol_ref "TARGET_QIMODE_MATH")
1531 (const_int 0))))
1532 (const_string "imov")
1533 (eq_attr "alternative" "3,5")
1534 (const_string "imovx")
1535 (and (ne (symbol_ref "TARGET_MOVX")
1536 (const_int 0))
1537 (eq_attr "alternative" "2"))
1538 (const_string "imovx")
1539 ]
1540 (const_string "imov")))
1541 (set (attr "mode")
1542 (cond [(eq_attr "alternative" "3,4,5")
1543 (const_string "SI")
1544 (eq_attr "alternative" "6")
1545 (const_string "QI")
1546 (eq_attr "type" "imovx")
1547 (const_string "SI")
1548 (and (eq_attr "type" "imov")
1549 (and (eq_attr "alternative" "0,1,2")
1550 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1551 (const_int 0))))
1552 (const_string "SI")
1553 ;; Avoid partial register stalls when not using QImode arithmetic
1554 (and (eq_attr "type" "imov")
1555 (and (eq_attr "alternative" "0,1,2")
1556 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1557 (const_int 0))
1558 (eq (symbol_ref "TARGET_QIMODE_MATH")
1559 (const_int 0)))))
1560 (const_string "SI")
1561 ]
1562 (const_string "QI")))])
1563
1564 (define_expand "reload_outqi"
1565 [(parallel [(match_operand:QI 0 "" "=m")
1566 (match_operand:QI 1 "register_operand" "r")
1567 (match_operand:QI 2 "register_operand" "=&q")])]
1568 ""
1569 {
1570 rtx op0, op1, op2;
1571 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1572
1573 if (reg_overlap_mentioned_p (op2, op0))
1574 abort ();
1575 if (! q_regs_operand (op1, QImode))
1576 {
1577 emit_insn (gen_movqi (op2, op1));
1578 op1 = op2;
1579 }
1580 emit_insn (gen_movqi (op0, op1));
1581 DONE;
1582 })
1583
1584 (define_insn "*swapqi"
1585 [(set (match_operand:QI 0 "register_operand" "+r")
1586 (match_operand:QI 1 "register_operand" "+r"))
1587 (set (match_dup 1)
1588 (match_dup 0))]
1589 ""
1590 "xchg{b}\t%1, %0"
1591 [(set_attr "type" "imov")
1592 (set_attr "pent_pair" "np")
1593 (set_attr "mode" "QI")
1594 (set_attr "modrm" "0")
1595 (set_attr "ppro_uops" "few")])
1596
1597 (define_expand "movstrictqi"
1598 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1599 (match_operand:QI 1 "general_operand" ""))]
1600 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1601 {
1602 /* Don't generate memory->memory moves, go through a register. */
1603 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1604 operands[1] = force_reg (QImode, operands[1]);
1605 })
1606
1607 (define_insn "*movstrictqi_1"
1608 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1609 (match_operand:QI 1 "general_operand" "*qn,m"))]
1610 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1611 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1612 "mov{b}\t{%1, %0|%0, %1}"
1613 [(set_attr "type" "imov")
1614 (set_attr "mode" "QI")])
1615
1616 (define_insn "*movstrictqi_xor"
1617 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1618 (match_operand:QI 1 "const0_operand" "i"))
1619 (clobber (reg:CC 17))]
1620 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1621 "xor{b}\t{%0, %0|%0, %0}"
1622 [(set_attr "type" "alu1")
1623 (set_attr "mode" "QI")
1624 (set_attr "length_immediate" "0")])
1625
1626 (define_insn "*movsi_extv_1"
1627 [(set (match_operand:SI 0 "register_operand" "=R")
1628 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1629 (const_int 8)
1630 (const_int 8)))]
1631 ""
1632 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1633 [(set_attr "type" "imovx")
1634 (set_attr "mode" "SI")])
1635
1636 (define_insn "*movhi_extv_1"
1637 [(set (match_operand:HI 0 "register_operand" "=R")
1638 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1639 (const_int 8)
1640 (const_int 8)))]
1641 ""
1642 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1643 [(set_attr "type" "imovx")
1644 (set_attr "mode" "SI")])
1645
1646 (define_insn "*movqi_extv_1"
1647 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1648 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1649 (const_int 8)
1650 (const_int 8)))]
1651 "!TARGET_64BIT"
1652 {
1653 switch (get_attr_type (insn))
1654 {
1655 case TYPE_IMOVX:
1656 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1657 default:
1658 return "mov{b}\t{%h1, %0|%0, %h1}";
1659 }
1660 }
1661 [(set (attr "type")
1662 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1663 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1664 (ne (symbol_ref "TARGET_MOVX")
1665 (const_int 0))))
1666 (const_string "imovx")
1667 (const_string "imov")))
1668 (set (attr "mode")
1669 (if_then_else (eq_attr "type" "imovx")
1670 (const_string "SI")
1671 (const_string "QI")))])
1672
1673 (define_insn "*movqi_extv_1_rex64"
1674 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1675 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1676 (const_int 8)
1677 (const_int 8)))]
1678 "TARGET_64BIT"
1679 {
1680 switch (get_attr_type (insn))
1681 {
1682 case TYPE_IMOVX:
1683 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1684 default:
1685 return "mov{b}\t{%h1, %0|%0, %h1}";
1686 }
1687 }
1688 [(set (attr "type")
1689 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1690 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1691 (ne (symbol_ref "TARGET_MOVX")
1692 (const_int 0))))
1693 (const_string "imovx")
1694 (const_string "imov")))
1695 (set (attr "mode")
1696 (if_then_else (eq_attr "type" "imovx")
1697 (const_string "SI")
1698 (const_string "QI")))])
1699
1700 ;; Stores and loads of ax to arbitrary constant address.
1701 ;; We fake an second form of instruction to force reload to load address
1702 ;; into register when rax is not available
1703 (define_insn "*movabsqi_1_rex64"
1704 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1705 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1706 "TARGET_64BIT"
1707 "@
1708 movabs{b}\t{%1, %P0|%P0, %1}
1709 mov{b}\t{%1, %a0|%a0, %1}
1710 movabs{b}\t{%1, %a0|%a0, %1}"
1711 [(set_attr "type" "imov")
1712 (set_attr "modrm" "0,*,*")
1713 (set_attr "length_address" "8,0,0")
1714 (set_attr "length_immediate" "0,*,*")
1715 (set_attr "memory" "store")
1716 (set_attr "mode" "QI")])
1717
1718 (define_insn "*movabsqi_2_rex64"
1719 [(set (match_operand:QI 0 "register_operand" "=a,r")
1720 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1721 "TARGET_64BIT"
1722 "@
1723 movabs{b}\t{%P1, %0|%0, %P1}
1724 mov{b}\t{%a1, %0|%0, %a1}"
1725 [(set_attr "type" "imov")
1726 (set_attr "modrm" "0,*")
1727 (set_attr "length_address" "8,0")
1728 (set_attr "length_immediate" "0")
1729 (set_attr "memory" "load")
1730 (set_attr "mode" "QI")])
1731
1732 (define_insn "*movsi_extzv_1"
1733 [(set (match_operand:SI 0 "register_operand" "=R")
1734 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1735 (const_int 8)
1736 (const_int 8)))]
1737 ""
1738 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1739 [(set_attr "type" "imovx")
1740 (set_attr "mode" "SI")])
1741
1742 (define_insn "*movqi_extzv_2"
1743 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1744 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1745 (const_int 8)
1746 (const_int 8)) 0))]
1747 "!TARGET_64BIT"
1748 {
1749 switch (get_attr_type (insn))
1750 {
1751 case TYPE_IMOVX:
1752 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1753 default:
1754 return "mov{b}\t{%h1, %0|%0, %h1}";
1755 }
1756 }
1757 [(set (attr "type")
1758 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1759 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1760 (ne (symbol_ref "TARGET_MOVX")
1761 (const_int 0))))
1762 (const_string "imovx")
1763 (const_string "imov")))
1764 (set (attr "mode")
1765 (if_then_else (eq_attr "type" "imovx")
1766 (const_string "SI")
1767 (const_string "QI")))])
1768
1769 (define_insn "*movqi_extzv_2_rex64"
1770 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1771 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1772 (const_int 8)
1773 (const_int 8)) 0))]
1774 "TARGET_64BIT"
1775 {
1776 switch (get_attr_type (insn))
1777 {
1778 case TYPE_IMOVX:
1779 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1780 default:
1781 return "mov{b}\t{%h1, %0|%0, %h1}";
1782 }
1783 }
1784 [(set (attr "type")
1785 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1786 (ne (symbol_ref "TARGET_MOVX")
1787 (const_int 0)))
1788 (const_string "imovx")
1789 (const_string "imov")))
1790 (set (attr "mode")
1791 (if_then_else (eq_attr "type" "imovx")
1792 (const_string "SI")
1793 (const_string "QI")))])
1794
1795 (define_insn "movsi_insv_1"
1796 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1797 (const_int 8)
1798 (const_int 8))
1799 (match_operand:SI 1 "general_operand" "Qmn"))]
1800 "!TARGET_64BIT"
1801 "mov{b}\t{%b1, %h0|%h0, %b1}"
1802 [(set_attr "type" "imov")
1803 (set_attr "mode" "QI")])
1804
1805 (define_insn "*movsi_insv_1_rex64"
1806 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1807 (const_int 8)
1808 (const_int 8))
1809 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1810 "TARGET_64BIT"
1811 "mov{b}\t{%b1, %h0|%h0, %b1}"
1812 [(set_attr "type" "imov")
1813 (set_attr "mode" "QI")])
1814
1815 (define_insn "*movqi_insv_2"
1816 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1817 (const_int 8)
1818 (const_int 8))
1819 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1820 (const_int 8))
1821 (const_int 255)))]
1822 ""
1823 "mov{b}\t{%h1, %h0|%h0, %h1}"
1824 [(set_attr "type" "imov")
1825 (set_attr "mode" "QI")])
1826
1827 (define_expand "movdi"
1828 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1829 (match_operand:DI 1 "general_operand" ""))]
1830 ""
1831 "ix86_expand_move (DImode, operands); DONE;")
1832
1833 (define_insn "*pushdi"
1834 [(set (match_operand:DI 0 "push_operand" "=<")
1835 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1836 "!TARGET_64BIT"
1837 "#")
1838
1839 (define_insn "pushdi2_rex64"
1840 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1841 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1842 "TARGET_64BIT"
1843 "@
1844 push{q}\t%1
1845 #"
1846 [(set_attr "type" "push,multi")
1847 (set_attr "mode" "DI")])
1848
1849 ;; Convert impossible pushes of immediate to existing instructions.
1850 ;; First try to get scratch register and go through it. In case this
1851 ;; fails, push sign extended lower part first and then overwrite
1852 ;; upper part by 32bit move.
1853 (define_peephole2
1854 [(match_scratch:DI 2 "r")
1855 (set (match_operand:DI 0 "push_operand" "")
1856 (match_operand:DI 1 "immediate_operand" ""))]
1857 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1858 && !x86_64_immediate_operand (operands[1], DImode)"
1859 [(set (match_dup 2) (match_dup 1))
1860 (set (match_dup 0) (match_dup 2))]
1861 "")
1862
1863 ;; We need to define this as both peepholer and splitter for case
1864 ;; peephole2 pass is not run.
1865 (define_peephole2
1866 [(set (match_operand:DI 0 "push_operand" "")
1867 (match_operand:DI 1 "immediate_operand" ""))]
1868 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1869 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1870 [(set (match_dup 0) (match_dup 1))
1871 (set (match_dup 2) (match_dup 3))]
1872 "split_di (operands + 1, 1, operands + 2, operands + 3);
1873 operands[1] = gen_lowpart (DImode, operands[2]);
1874 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1875 GEN_INT (4)));
1876 ")
1877
1878 (define_split
1879 [(set (match_operand:DI 0 "push_operand" "")
1880 (match_operand:DI 1 "immediate_operand" ""))]
1881 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1882 && !symbolic_operand (operands[1], DImode)
1883 && !x86_64_immediate_operand (operands[1], DImode)"
1884 [(set (match_dup 0) (match_dup 1))
1885 (set (match_dup 2) (match_dup 3))]
1886 "split_di (operands + 1, 1, operands + 2, operands + 3);
1887 operands[1] = gen_lowpart (DImode, operands[2]);
1888 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1889 GEN_INT (4)));
1890 ")
1891
1892 (define_insn "*pushdi2_prologue_rex64"
1893 [(set (match_operand:DI 0 "push_operand" "=<")
1894 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1895 (clobber (mem:BLK (scratch)))]
1896 "TARGET_64BIT"
1897 "push{q}\t%1"
1898 [(set_attr "type" "push")
1899 (set_attr "mode" "DI")])
1900
1901 (define_insn "*popdi1_epilogue_rex64"
1902 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903 (mem:DI (reg:DI 7)))
1904 (set (reg:DI 7)
1905 (plus:DI (reg:DI 7) (const_int 8)))
1906 (clobber (mem:BLK (scratch)))]
1907 "TARGET_64BIT"
1908 "pop{q}\t%0"
1909 [(set_attr "type" "pop")
1910 (set_attr "mode" "DI")])
1911
1912 (define_insn "popdi1"
1913 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1914 (mem:DI (reg:DI 7)))
1915 (set (reg:DI 7)
1916 (plus:DI (reg:DI 7) (const_int 8)))]
1917 "TARGET_64BIT"
1918 "pop{q}\t%0"
1919 [(set_attr "type" "pop")
1920 (set_attr "mode" "DI")])
1921
1922 (define_insn "*movdi_xor_rex64"
1923 [(set (match_operand:DI 0 "register_operand" "=r")
1924 (match_operand:DI 1 "const0_operand" "i"))
1925 (clobber (reg:CC 17))]
1926 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1927 && reload_completed"
1928 "xor{l}\t{%k0, %k0|%k0, %k0}"
1929 [(set_attr "type" "alu1")
1930 (set_attr "mode" "SI")
1931 (set_attr "length_immediate" "0")])
1932
1933 (define_insn "*movdi_or_rex64"
1934 [(set (match_operand:DI 0 "register_operand" "=r")
1935 (match_operand:DI 1 "const_int_operand" "i"))
1936 (clobber (reg:CC 17))]
1937 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1938 && reload_completed
1939 && GET_CODE (operands[1]) == CONST_INT
1940 && INTVAL (operands[1]) == -1"
1941 {
1942 operands[1] = constm1_rtx;
1943 return "or{q}\t{%1, %0|%0, %1}";
1944 }
1945 [(set_attr "type" "alu1")
1946 (set_attr "mode" "DI")
1947 (set_attr "length_immediate" "1")])
1948
1949 (define_insn "*movdi_2"
1950 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1951 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1952 "!TARGET_64BIT
1953 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1954 "@
1955 #
1956 #
1957 movq\t{%1, %0|%0, %1}
1958 movq\t{%1, %0|%0, %1}
1959 movq\t{%1, %0|%0, %1}
1960 movdqa\t{%1, %0|%0, %1}
1961 movq\t{%1, %0|%0, %1}"
1962 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1963 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1964
1965 (define_split
1966 [(set (match_operand:DI 0 "push_operand" "")
1967 (match_operand:DI 1 "general_operand" ""))]
1968 "!TARGET_64BIT && reload_completed
1969 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1970 [(const_int 0)]
1971 "ix86_split_long_move (operands); DONE;")
1972
1973 ;; %%% This multiword shite has got to go.
1974 (define_split
1975 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1976 (match_operand:DI 1 "general_operand" ""))]
1977 "!TARGET_64BIT && reload_completed
1978 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1979 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1980 [(const_int 0)]
1981 "ix86_split_long_move (operands); DONE;")
1982
1983 (define_insn "*movdi_1_rex64"
1984 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1985 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1986 "TARGET_64BIT
1987 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1988 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1989 {
1990 switch (get_attr_type (insn))
1991 {
1992 case TYPE_SSEMOV:
1993 if (get_attr_mode (insn) == MODE_TI)
1994 return "movdqa\t{%1, %0|%0, %1}";
1995 /* FALLTHRU */
1996 case TYPE_MMXMOV:
1997 /* Moves from and into integer register is done using movd opcode with
1998 REX prefix. */
1999 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000 return "movd\t{%1, %0|%0, %1}";
2001 return "movq\t{%1, %0|%0, %1}";
2002 case TYPE_MULTI:
2003 return "#";
2004 case TYPE_LEA:
2005 return "lea{q}\t{%a1, %0|%0, %a1}";
2006 default:
2007 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2008 abort ();
2009 if (get_attr_mode (insn) == MODE_SI)
2010 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2011 else if (which_alternative == 2)
2012 return "movabs{q}\t{%1, %0|%0, %1}";
2013 else
2014 return "mov{q}\t{%1, %0|%0, %1}";
2015 }
2016 }
2017 [(set (attr "type")
2018 (cond [(eq_attr "alternative" "5,6,7")
2019 (const_string "mmxmov")
2020 (eq_attr "alternative" "8,9,10")
2021 (const_string "ssemov")
2022 (eq_attr "alternative" "4")
2023 (const_string "multi")
2024 (and (ne (symbol_ref "flag_pic") (const_int 0))
2025 (match_operand:DI 1 "symbolic_operand" ""))
2026 (const_string "lea")
2027 ]
2028 (const_string "imov")))
2029 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2030 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2031 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2032
2033 (define_insn "*movdi_1_rex64_nointerunit"
2034 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2035 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2036 "TARGET_64BIT
2037 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2038 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2039 {
2040 switch (get_attr_type (insn))
2041 {
2042 case TYPE_SSEMOV:
2043 if (get_attr_mode (insn) == MODE_TI)
2044 return "movdqa\t{%1, %0|%0, %1}";
2045 /* FALLTHRU */
2046 case TYPE_MMXMOV:
2047 return "movq\t{%1, %0|%0, %1}";
2048 case TYPE_MULTI:
2049 return "#";
2050 case TYPE_LEA:
2051 return "lea{q}\t{%a1, %0|%0, %a1}";
2052 default:
2053 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2054 abort ();
2055 if (get_attr_mode (insn) == MODE_SI)
2056 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2057 else if (which_alternative == 2)
2058 return "movabs{q}\t{%1, %0|%0, %1}";
2059 else
2060 return "mov{q}\t{%1, %0|%0, %1}";
2061 }
2062 }
2063 [(set (attr "type")
2064 (cond [(eq_attr "alternative" "5,6,7")
2065 (const_string "mmxmov")
2066 (eq_attr "alternative" "8,9,10")
2067 (const_string "ssemov")
2068 (eq_attr "alternative" "4")
2069 (const_string "multi")
2070 (and (ne (symbol_ref "flag_pic") (const_int 0))
2071 (match_operand:DI 1 "symbolic_operand" ""))
2072 (const_string "lea")
2073 ]
2074 (const_string "imov")))
2075 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2076 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2077 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2078
2079 ;; Stores and loads of ax to arbitrary constant address.
2080 ;; We fake an second form of instruction to force reload to load address
2081 ;; into register when rax is not available
2082 (define_insn "*movabsdi_1_rex64"
2083 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2084 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2085 "TARGET_64BIT"
2086 "@
2087 movabs{q}\t{%1, %P0|%P0, %1}
2088 mov{q}\t{%1, %a0|%a0, %1}
2089 movabs{q}\t{%1, %a0|%a0, %1}"
2090 [(set_attr "type" "imov")
2091 (set_attr "modrm" "0,*,*")
2092 (set_attr "length_address" "8,0,0")
2093 (set_attr "length_immediate" "0,*,*")
2094 (set_attr "memory" "store")
2095 (set_attr "mode" "DI")])
2096
2097 (define_insn "*movabsdi_2_rex64"
2098 [(set (match_operand:DI 0 "register_operand" "=a,r")
2099 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2100 "TARGET_64BIT"
2101 "@
2102 movabs{q}\t{%P1, %0|%0, %P1}
2103 mov{q}\t{%a1, %0|%0, %a1}"
2104 [(set_attr "type" "imov")
2105 (set_attr "modrm" "0,*")
2106 (set_attr "length_address" "8,0")
2107 (set_attr "length_immediate" "0")
2108 (set_attr "memory" "load")
2109 (set_attr "mode" "DI")])
2110
2111 ;; Convert impossible stores of immediate to existing instructions.
2112 ;; First try to get scratch register and go through it. In case this
2113 ;; fails, move by 32bit parts.
2114 (define_peephole2
2115 [(match_scratch:DI 2 "r")
2116 (set (match_operand:DI 0 "memory_operand" "")
2117 (match_operand:DI 1 "immediate_operand" ""))]
2118 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2119 && !x86_64_immediate_operand (operands[1], DImode)"
2120 [(set (match_dup 2) (match_dup 1))
2121 (set (match_dup 0) (match_dup 2))]
2122 "")
2123
2124 ;; We need to define this as both peepholer and splitter for case
2125 ;; peephole2 pass is not run.
2126 (define_peephole2
2127 [(set (match_operand:DI 0 "memory_operand" "")
2128 (match_operand:DI 1 "immediate_operand" ""))]
2129 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2131 [(set (match_dup 2) (match_dup 3))
2132 (set (match_dup 4) (match_dup 5))]
2133 "split_di (operands, 2, operands + 2, operands + 4);")
2134
2135 (define_split
2136 [(set (match_operand:DI 0 "memory_operand" "")
2137 (match_operand:DI 1 "immediate_operand" ""))]
2138 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2139 && !symbolic_operand (operands[1], DImode)
2140 && !x86_64_immediate_operand (operands[1], DImode)"
2141 [(set (match_dup 2) (match_dup 3))
2142 (set (match_dup 4) (match_dup 5))]
2143 "split_di (operands, 2, operands + 2, operands + 4);")
2144
2145 (define_insn "*swapdi_rex64"
2146 [(set (match_operand:DI 0 "register_operand" "+r")
2147 (match_operand:DI 1 "register_operand" "+r"))
2148 (set (match_dup 1)
2149 (match_dup 0))]
2150 "TARGET_64BIT"
2151 "xchg{q}\t%1, %0"
2152 [(set_attr "type" "imov")
2153 (set_attr "pent_pair" "np")
2154 (set_attr "athlon_decode" "vector")
2155 (set_attr "mode" "DI")
2156 (set_attr "modrm" "0")
2157 (set_attr "ppro_uops" "few")])
2158
2159
2160 (define_expand "movsf"
2161 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2162 (match_operand:SF 1 "general_operand" ""))]
2163 ""
2164 "ix86_expand_move (SFmode, operands); DONE;")
2165
2166 (define_insn "*pushsf"
2167 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2168 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2169 "!TARGET_64BIT"
2170 {
2171 switch (which_alternative)
2172 {
2173 case 1:
2174 return "push{l}\t%1";
2175
2176 default:
2177 /* This insn should be already splitted before reg-stack. */
2178 abort ();
2179 }
2180 }
2181 [(set_attr "type" "multi,push,multi")
2182 (set_attr "mode" "SF,SI,SF")])
2183
2184 (define_insn "*pushsf_rex64"
2185 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2186 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2187 "TARGET_64BIT"
2188 {
2189 switch (which_alternative)
2190 {
2191 case 1:
2192 return "push{q}\t%q1";
2193
2194 default:
2195 /* This insn should be already splitted before reg-stack. */
2196 abort ();
2197 }
2198 }
2199 [(set_attr "type" "multi,push,multi")
2200 (set_attr "mode" "SF,DI,SF")])
2201
2202 (define_split
2203 [(set (match_operand:SF 0 "push_operand" "")
2204 (match_operand:SF 1 "memory_operand" ""))]
2205 "reload_completed
2206 && GET_CODE (operands[1]) == MEM
2207 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2208 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2209 [(set (match_dup 0)
2210 (match_dup 1))]
2211 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2212
2213
2214 ;; %%% Kill this when call knows how to work this out.
2215 (define_split
2216 [(set (match_operand:SF 0 "push_operand" "")
2217 (match_operand:SF 1 "any_fp_register_operand" ""))]
2218 "!TARGET_64BIT"
2219 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2220 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2221
2222 (define_split
2223 [(set (match_operand:SF 0 "push_operand" "")
2224 (match_operand:SF 1 "any_fp_register_operand" ""))]
2225 "TARGET_64BIT"
2226 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2227 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2228
2229 (define_insn "*movsf_1"
2230 [(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")
2231 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2232 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2233 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2234 && (reload_in_progress || reload_completed
2235 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2236 || GET_CODE (operands[1]) != CONST_DOUBLE
2237 || memory_operand (operands[0], SFmode))"
2238 {
2239 switch (which_alternative)
2240 {
2241 case 0:
2242 if (REG_P (operands[1])
2243 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2244 return "fstp\t%y0";
2245 else if (STACK_TOP_P (operands[0]))
2246 return "fld%z1\t%y1";
2247 else
2248 return "fst\t%y0";
2249
2250 case 1:
2251 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2252 return "fstp%z0\t%y0";
2253 else
2254 return "fst%z0\t%y0";
2255
2256 case 2:
2257 return standard_80387_constant_opcode (operands[1]);
2258
2259 case 3:
2260 case 4:
2261 return "mov{l}\t{%1, %0|%0, %1}";
2262 case 5:
2263 if (get_attr_mode (insn) == MODE_TI)
2264 return "pxor\t%0, %0";
2265 else
2266 return "xorps\t%0, %0";
2267 case 6:
2268 if (get_attr_mode (insn) == MODE_V4SF)
2269 return "movaps\t{%1, %0|%0, %1}";
2270 else
2271 return "movss\t{%1, %0|%0, %1}";
2272 case 7:
2273 case 8:
2274 return "movss\t{%1, %0|%0, %1}";
2275
2276 case 9:
2277 case 10:
2278 return "movd\t{%1, %0|%0, %1}";
2279
2280 case 11:
2281 return "movq\t{%1, %0|%0, %1}";
2282
2283 default:
2284 abort();
2285 }
2286 }
2287 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2288 (set (attr "mode")
2289 (cond [(eq_attr "alternative" "3,4,9,10")
2290 (const_string "SI")
2291 (eq_attr "alternative" "5")
2292 (if_then_else
2293 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2294 (const_int 0))
2295 (ne (symbol_ref "TARGET_SSE2")
2296 (const_int 0)))
2297 (eq (symbol_ref "optimize_size")
2298 (const_int 0)))
2299 (const_string "TI")
2300 (const_string "V4SF"))
2301 /* For architectures resolving dependencies on
2302 whole SSE registers use APS move to break dependency
2303 chains, otherwise use short move to avoid extra work.
2304
2305 Do the same for architectures resolving dependencies on
2306 the parts. While in DF mode it is better to always handle
2307 just register parts, the SF mode is different due to lack
2308 of instructions to load just part of the register. It is
2309 better to maintain the whole registers in single format
2310 to avoid problems on using packed logical operations. */
2311 (eq_attr "alternative" "6")
2312 (if_then_else
2313 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2314 (const_int 0))
2315 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2316 (const_int 0)))
2317 (const_string "V4SF")
2318 (const_string "SF"))
2319 (eq_attr "alternative" "11")
2320 (const_string "DI")]
2321 (const_string "SF")))])
2322
2323 (define_insn "*movsf_1_nointerunit"
2324 [(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")
2325 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2326 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2327 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2328 && (reload_in_progress || reload_completed
2329 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2330 || GET_CODE (operands[1]) != CONST_DOUBLE
2331 || memory_operand (operands[0], SFmode))"
2332 {
2333 switch (which_alternative)
2334 {
2335 case 0:
2336 if (REG_P (operands[1])
2337 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2338 {
2339 if (REGNO (operands[0]) == FIRST_STACK_REG
2340 && TARGET_USE_FFREEP)
2341 return "ffreep\t%y0";
2342 return "fstp\t%y0";
2343 }
2344 else if (STACK_TOP_P (operands[0]))
2345 return "fld%z1\t%y1";
2346 else
2347 return "fst\t%y0";
2348
2349 case 1:
2350 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2351 return "fstp%z0\t%y0";
2352 else
2353 return "fst%z0\t%y0";
2354
2355 case 2:
2356 return standard_80387_constant_opcode (operands[1]);
2357
2358 case 3:
2359 case 4:
2360 return "mov{l}\t{%1, %0|%0, %1}";
2361 case 5:
2362 if (get_attr_mode (insn) == MODE_TI)
2363 return "pxor\t%0, %0";
2364 else
2365 return "xorps\t%0, %0";
2366 case 6:
2367 if (get_attr_mode (insn) == MODE_V4SF)
2368 return "movaps\t{%1, %0|%0, %1}";
2369 else
2370 return "movss\t{%1, %0|%0, %1}";
2371 case 7:
2372 case 8:
2373 return "movss\t{%1, %0|%0, %1}";
2374
2375 case 9:
2376 case 10:
2377 return "movd\t{%1, %0|%0, %1}";
2378
2379 case 11:
2380 return "movq\t{%1, %0|%0, %1}";
2381
2382 default:
2383 abort();
2384 }
2385 }
2386 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2387 (set (attr "mode")
2388 (cond [(eq_attr "alternative" "3,4,9,10")
2389 (const_string "SI")
2390 (eq_attr "alternative" "5")
2391 (if_then_else
2392 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2393 (const_int 0))
2394 (ne (symbol_ref "TARGET_SSE2")
2395 (const_int 0)))
2396 (eq (symbol_ref "optimize_size")
2397 (const_int 0)))
2398 (const_string "TI")
2399 (const_string "V4SF"))
2400 /* For architectures resolving dependencies on
2401 whole SSE registers use APS move to break dependency
2402 chains, otherwise use short move to avoid extra work.
2403
2404 Do the same for architectures resolving dependencies on
2405 the parts. While in DF mode it is better to always handle
2406 just register parts, the SF mode is different due to lack
2407 of instructions to load just part of the register. It is
2408 better to maintain the whole registers in single format
2409 to avoid problems on using packed logical operations. */
2410 (eq_attr "alternative" "6")
2411 (if_then_else
2412 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2413 (const_int 0))
2414 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2415 (const_int 0)))
2416 (const_string "V4SF")
2417 (const_string "SF"))
2418 (eq_attr "alternative" "11")
2419 (const_string "DI")]
2420 (const_string "SF")))])
2421
2422 (define_insn "*swapsf"
2423 [(set (match_operand:SF 0 "register_operand" "+f")
2424 (match_operand:SF 1 "register_operand" "+f"))
2425 (set (match_dup 1)
2426 (match_dup 0))]
2427 "reload_completed || !TARGET_SSE"
2428 {
2429 if (STACK_TOP_P (operands[0]))
2430 return "fxch\t%1";
2431 else
2432 return "fxch\t%0";
2433 }
2434 [(set_attr "type" "fxch")
2435 (set_attr "mode" "SF")])
2436
2437 (define_expand "movdf"
2438 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2439 (match_operand:DF 1 "general_operand" ""))]
2440 ""
2441 "ix86_expand_move (DFmode, operands); DONE;")
2442
2443 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2444 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2445 ;; On the average, pushdf using integers can be still shorter. Allow this
2446 ;; pattern for optimize_size too.
2447
2448 (define_insn "*pushdf_nointeger"
2449 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2450 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2451 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2452 {
2453 /* This insn should be already splitted before reg-stack. */
2454 abort ();
2455 }
2456 [(set_attr "type" "multi")
2457 (set_attr "mode" "DF,SI,SI,DF")])
2458
2459 (define_insn "*pushdf_integer"
2460 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2461 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2462 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2463 {
2464 /* This insn should be already splitted before reg-stack. */
2465 abort ();
2466 }
2467 [(set_attr "type" "multi")
2468 (set_attr "mode" "DF,SI,DF")])
2469
2470 ;; %%% Kill this when call knows how to work this out.
2471 (define_split
2472 [(set (match_operand:DF 0 "push_operand" "")
2473 (match_operand:DF 1 "any_fp_register_operand" ""))]
2474 "!TARGET_64BIT && reload_completed"
2475 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2476 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2477 "")
2478
2479 (define_split
2480 [(set (match_operand:DF 0 "push_operand" "")
2481 (match_operand:DF 1 "any_fp_register_operand" ""))]
2482 "TARGET_64BIT && reload_completed"
2483 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2484 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2485 "")
2486
2487 (define_split
2488 [(set (match_operand:DF 0 "push_operand" "")
2489 (match_operand:DF 1 "general_operand" ""))]
2490 "reload_completed"
2491 [(const_int 0)]
2492 "ix86_split_long_move (operands); DONE;")
2493
2494 ;; Moving is usually shorter when only FP registers are used. This separate
2495 ;; movdf pattern avoids the use of integer registers for FP operations
2496 ;; when optimizing for size.
2497
2498 (define_insn "*movdf_nointeger"
2499 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2500 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2501 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2502 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2503 && (reload_in_progress || reload_completed
2504 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2505 || GET_CODE (operands[1]) != CONST_DOUBLE
2506 || memory_operand (operands[0], DFmode))"
2507 {
2508 switch (which_alternative)
2509 {
2510 case 0:
2511 if (REG_P (operands[1])
2512 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2513 {
2514 if (REGNO (operands[0]) == FIRST_STACK_REG
2515 && TARGET_USE_FFREEP)
2516 return "ffreep\t%y0";
2517 return "fstp\t%y0";
2518 }
2519 else if (STACK_TOP_P (operands[0]))
2520 return "fld%z1\t%y1";
2521 else
2522 return "fst\t%y0";
2523
2524 case 1:
2525 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2526 return "fstp%z0\t%y0";
2527 else
2528 return "fst%z0\t%y0";
2529
2530 case 2:
2531 return standard_80387_constant_opcode (operands[1]);
2532
2533 case 3:
2534 case 4:
2535 return "#";
2536 case 5:
2537 switch (get_attr_mode (insn))
2538 {
2539 case MODE_V4SF:
2540 return "xorps\t%0, %0";
2541 case MODE_V2DF:
2542 return "xorpd\t%0, %0";
2543 case MODE_TI:
2544 return "pxor\t%0, %0";
2545 default:
2546 abort ();
2547 }
2548 case 6:
2549 switch (get_attr_mode (insn))
2550 {
2551 case MODE_V4SF:
2552 return "movaps\t{%1, %0|%0, %1}";
2553 case MODE_V2DF:
2554 return "movapd\t{%1, %0|%0, %1}";
2555 case MODE_DF:
2556 return "movsd\t{%1, %0|%0, %1}";
2557 default:
2558 abort ();
2559 }
2560 case 7:
2561 if (get_attr_mode (insn) == MODE_V2DF)
2562 return "movlpd\t{%1, %0|%0, %1}";
2563 else
2564 return "movsd\t{%1, %0|%0, %1}";
2565 case 8:
2566 return "movsd\t{%1, %0|%0, %1}";
2567
2568 default:
2569 abort();
2570 }
2571 }
2572 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2573 (set (attr "mode")
2574 (cond [(eq_attr "alternative" "3,4")
2575 (const_string "SI")
2576 /* xorps is one byte shorter. */
2577 (eq_attr "alternative" "5")
2578 (cond [(ne (symbol_ref "optimize_size")
2579 (const_int 0))
2580 (const_string "V4SF")
2581 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2582 (const_int 0))
2583 (const_string "TI")]
2584 (const_string "V2DF"))
2585 /* For architectures resolving dependencies on
2586 whole SSE registers use APD move to break dependency
2587 chains, otherwise use short move to avoid extra work.
2588
2589 movaps encodes one byte shorter. */
2590 (eq_attr "alternative" "6")
2591 (cond
2592 [(ne (symbol_ref "optimize_size")
2593 (const_int 0))
2594 (const_string "V4SF")
2595 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2596 (const_int 0))
2597 (const_string "V2DF")]
2598 (const_string "DF"))
2599 /* For architectures resolving dependencies on register
2600 parts we may avoid extra work to zero out upper part
2601 of register. */
2602 (eq_attr "alternative" "7")
2603 (if_then_else
2604 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2605 (const_int 0))
2606 (const_string "V2DF")
2607 (const_string "DF"))]
2608 (const_string "DF")))])
2609
2610 (define_insn "*movdf_integer"
2611 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2612 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2613 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2614 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2615 && (reload_in_progress || reload_completed
2616 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2617 || GET_CODE (operands[1]) != CONST_DOUBLE
2618 || memory_operand (operands[0], DFmode))"
2619 {
2620 switch (which_alternative)
2621 {
2622 case 0:
2623 if (REG_P (operands[1])
2624 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2625 {
2626 if (REGNO (operands[0]) == FIRST_STACK_REG
2627 && TARGET_USE_FFREEP)
2628 return "ffreep\t%y0";
2629 return "fstp\t%y0";
2630 }
2631 else if (STACK_TOP_P (operands[0]))
2632 return "fld%z1\t%y1";
2633 else
2634 return "fst\t%y0";
2635
2636 case 1:
2637 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2638 return "fstp%z0\t%y0";
2639 else
2640 return "fst%z0\t%y0";
2641
2642 case 2:
2643 return standard_80387_constant_opcode (operands[1]);
2644
2645 case 3:
2646 case 4:
2647 return "#";
2648
2649 case 5:
2650 switch (get_attr_mode (insn))
2651 {
2652 case MODE_V4SF:
2653 return "xorps\t%0, %0";
2654 case MODE_V2DF:
2655 return "xorpd\t%0, %0";
2656 case MODE_TI:
2657 return "pxor\t%0, %0";
2658 default:
2659 abort ();
2660 }
2661 case 6:
2662 switch (get_attr_mode (insn))
2663 {
2664 case MODE_V4SF:
2665 return "movaps\t{%1, %0|%0, %1}";
2666 case MODE_V2DF:
2667 return "movapd\t{%1, %0|%0, %1}";
2668 case MODE_DF:
2669 return "movsd\t{%1, %0|%0, %1}";
2670 default:
2671 abort ();
2672 }
2673 case 7:
2674 if (get_attr_mode (insn) == MODE_V2DF)
2675 return "movlpd\t{%1, %0|%0, %1}";
2676 else
2677 return "movsd\t{%1, %0|%0, %1}";
2678 case 8:
2679 return "movsd\t{%1, %0|%0, %1}";
2680
2681 default:
2682 abort();
2683 }
2684 }
2685 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2686 (set (attr "mode")
2687 (cond [(eq_attr "alternative" "3,4")
2688 (const_string "SI")
2689 /* xorps is one byte shorter. */
2690 (eq_attr "alternative" "5")
2691 (cond [(ne (symbol_ref "optimize_size")
2692 (const_int 0))
2693 (const_string "V4SF")
2694 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2695 (const_int 0))
2696 (const_string "TI")]
2697 (const_string "V2DF"))
2698 /* For architectures resolving dependencies on
2699 whole SSE registers use APD move to break dependency
2700 chains, otherwise use short move to avoid extra work.
2701
2702 movaps encodes one byte shorter. */
2703 (eq_attr "alternative" "6")
2704 (cond
2705 [(ne (symbol_ref "optimize_size")
2706 (const_int 0))
2707 (const_string "V4SF")
2708 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2709 (const_int 0))
2710 (const_string "V2DF")]
2711 (const_string "DF"))
2712 /* For architectures resolving dependencies on register
2713 parts we may avoid extra work to zero out upper part
2714 of register. */
2715 (eq_attr "alternative" "7")
2716 (if_then_else
2717 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2718 (const_int 0))
2719 (const_string "V2DF")
2720 (const_string "DF"))]
2721 (const_string "DF")))])
2722
2723 (define_split
2724 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2725 (match_operand:DF 1 "general_operand" ""))]
2726 "reload_completed
2727 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2728 && ! (ANY_FP_REG_P (operands[0]) ||
2729 (GET_CODE (operands[0]) == SUBREG
2730 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2731 && ! (ANY_FP_REG_P (operands[1]) ||
2732 (GET_CODE (operands[1]) == SUBREG
2733 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2734 [(const_int 0)]
2735 "ix86_split_long_move (operands); DONE;")
2736
2737 (define_insn "*swapdf"
2738 [(set (match_operand:DF 0 "register_operand" "+f")
2739 (match_operand:DF 1 "register_operand" "+f"))
2740 (set (match_dup 1)
2741 (match_dup 0))]
2742 "reload_completed || !TARGET_SSE2"
2743 {
2744 if (STACK_TOP_P (operands[0]))
2745 return "fxch\t%1";
2746 else
2747 return "fxch\t%0";
2748 }
2749 [(set_attr "type" "fxch")
2750 (set_attr "mode" "DF")])
2751
2752 (define_expand "movxf"
2753 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2754 (match_operand:XF 1 "general_operand" ""))]
2755 "!TARGET_128BIT_LONG_DOUBLE"
2756 "ix86_expand_move (XFmode, operands); DONE;")
2757
2758 (define_expand "movtf"
2759 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2760 (match_operand:TF 1 "general_operand" ""))]
2761 ""
2762 "ix86_expand_move (TFmode, operands); DONE;")
2763
2764 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2765 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2766 ;; Pushing using integer instructions is longer except for constants
2767 ;; and direct memory references.
2768 ;; (assuming that any given constant is pushed only once, but this ought to be
2769 ;; handled elsewhere).
2770
2771 (define_insn "*pushxf_nointeger"
2772 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2773 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2774 "!TARGET_128BIT_LONG_DOUBLE && optimize_size"
2775 {
2776 /* This insn should be already splitted before reg-stack. */
2777 abort ();
2778 }
2779 [(set_attr "type" "multi")
2780 (set_attr "mode" "XF,SI,SI")])
2781
2782 (define_insn "*pushtf_nointeger"
2783 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2784 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2785 "optimize_size"
2786 {
2787 /* This insn should be already splitted before reg-stack. */
2788 abort ();
2789 }
2790 [(set_attr "type" "multi")
2791 (set_attr "mode" "XF,SI,SI")])
2792
2793 (define_insn "*pushxf_integer"
2794 [(set (match_operand:XF 0 "push_operand" "=<,<")
2795 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2796 "!TARGET_128BIT_LONG_DOUBLE && !optimize_size"
2797 {
2798 /* This insn should be already splitted before reg-stack. */
2799 abort ();
2800 }
2801 [(set_attr "type" "multi")
2802 (set_attr "mode" "XF,SI")])
2803
2804 (define_insn "*pushtf_integer"
2805 [(set (match_operand:TF 0 "push_operand" "=<,<")
2806 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2807 "!optimize_size"
2808 {
2809 /* This insn should be already splitted before reg-stack. */
2810 abort ();
2811 }
2812 [(set_attr "type" "multi")
2813 (set_attr "mode" "XF,SI")])
2814
2815 (define_split
2816 [(set (match_operand 0 "push_operand" "")
2817 (match_operand 1 "general_operand" ""))]
2818 "reload_completed
2819 && (GET_MODE (operands[0]) == XFmode
2820 || GET_MODE (operands[0]) == TFmode
2821 || GET_MODE (operands[0]) == DFmode)
2822 && !ANY_FP_REG_P (operands[1])"
2823 [(const_int 0)]
2824 "ix86_split_long_move (operands); DONE;")
2825
2826 (define_split
2827 [(set (match_operand:XF 0 "push_operand" "")
2828 (match_operand:XF 1 "any_fp_register_operand" ""))]
2829 "!TARGET_128BIT_LONG_DOUBLE"
2830 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2831 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2832
2833 (define_split
2834 [(set (match_operand:TF 0 "push_operand" "")
2835 (match_operand:TF 1 "any_fp_register_operand" ""))]
2836 "!TARGET_64BIT"
2837 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2838 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2839
2840 (define_split
2841 [(set (match_operand:TF 0 "push_operand" "")
2842 (match_operand:TF 1 "any_fp_register_operand" ""))]
2843 "TARGET_64BIT"
2844 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2845 (set (mem:TF (reg:DI 7)) (match_dup 1))])
2846
2847 ;; Do not use integer registers when optimizing for size
2848 (define_insn "*movxf_nointeger"
2849 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2850 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2851 "!TARGET_128BIT_LONG_DOUBLE
2852 && optimize_size
2853 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2854 && (reload_in_progress || reload_completed
2855 || GET_CODE (operands[1]) != CONST_DOUBLE
2856 || memory_operand (operands[0], XFmode))"
2857 {
2858 switch (which_alternative)
2859 {
2860 case 0:
2861 if (REG_P (operands[1])
2862 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2863 {
2864 if (REGNO (operands[0]) == FIRST_STACK_REG
2865 && TARGET_USE_FFREEP)
2866 return "ffreep\t%y0";
2867 return "fstp\t%y0";
2868 }
2869 else if (STACK_TOP_P (operands[0]))
2870 return "fld%z1\t%y1";
2871 else
2872 return "fst\t%y0";
2873
2874 case 1:
2875 /* There is no non-popping store to memory for XFmode. So if
2876 we need one, follow the store with a load. */
2877 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2878 return "fstp%z0\t%y0\;fld%z0\t%y0";
2879 else
2880 return "fstp%z0\t%y0";
2881
2882 case 2:
2883 return standard_80387_constant_opcode (operands[1]);
2884
2885 case 3: case 4:
2886 return "#";
2887 }
2888 abort();
2889 }
2890 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891 (set_attr "mode" "XF,XF,XF,SI,SI")])
2892
2893 (define_insn "*movtf_nointeger"
2894 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2895 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2896 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2897 && optimize_size
2898 && (reload_in_progress || reload_completed
2899 || GET_CODE (operands[1]) != CONST_DOUBLE
2900 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901 || memory_operand (operands[0], TFmode))"
2902 {
2903 switch (which_alternative)
2904 {
2905 case 0:
2906 if (REG_P (operands[1])
2907 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2908 {
2909 if (REGNO (operands[0]) == FIRST_STACK_REG
2910 && TARGET_USE_FFREEP)
2911 return "ffreep\t%y0";
2912 return "fstp\t%y0";
2913 }
2914 else if (STACK_TOP_P (operands[0]))
2915 return "fld%z1\t%y1";
2916 else
2917 return "fst\t%y0";
2918
2919 case 1:
2920 /* There is no non-popping store to memory for XFmode. So if
2921 we need one, follow the store with a load. */
2922 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2923 return "fstp%z0\t%y0\;fld%z0\t%y0";
2924 else
2925 return "fstp%z0\t%y0";
2926
2927 case 2:
2928 return standard_80387_constant_opcode (operands[1]);
2929
2930 case 3: case 4:
2931 return "#";
2932 }
2933 abort();
2934 }
2935 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2936 (set_attr "mode" "XF,XF,XF,SI,SI")])
2937
2938 (define_insn "*movxf_integer"
2939 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2940 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2941 "!TARGET_128BIT_LONG_DOUBLE
2942 && !optimize_size
2943 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2944 && (reload_in_progress || reload_completed
2945 || GET_CODE (operands[1]) != CONST_DOUBLE
2946 || memory_operand (operands[0], XFmode))"
2947 {
2948 switch (which_alternative)
2949 {
2950 case 0:
2951 if (REG_P (operands[1])
2952 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2953 {
2954 if (REGNO (operands[0]) == FIRST_STACK_REG
2955 && TARGET_USE_FFREEP)
2956 return "ffreep\t%y0";
2957 return "fstp\t%y0";
2958 }
2959 else if (STACK_TOP_P (operands[0]))
2960 return "fld%z1\t%y1";
2961 else
2962 return "fst\t%y0";
2963
2964 case 1:
2965 /* There is no non-popping store to memory for XFmode. So if
2966 we need one, follow the store with a load. */
2967 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2968 return "fstp%z0\t%y0\;fld%z0\t%y0";
2969 else
2970 return "fstp%z0\t%y0";
2971
2972 case 2:
2973 return standard_80387_constant_opcode (operands[1]);
2974
2975 case 3: case 4:
2976 return "#";
2977 }
2978 abort();
2979 }
2980 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2981 (set_attr "mode" "XF,XF,XF,SI,SI")])
2982
2983 (define_insn "*movtf_integer"
2984 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2985 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2986 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2987 && !optimize_size
2988 && (reload_in_progress || reload_completed
2989 || GET_CODE (operands[1]) != CONST_DOUBLE
2990 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2991 || memory_operand (operands[0], TFmode))"
2992 {
2993 switch (which_alternative)
2994 {
2995 case 0:
2996 if (REG_P (operands[1])
2997 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2998 {
2999 if (REGNO (operands[0]) == FIRST_STACK_REG
3000 && TARGET_USE_FFREEP)
3001 return "ffreep\t%y0";
3002 return "fstp\t%y0";
3003 }
3004 else if (STACK_TOP_P (operands[0]))
3005 return "fld%z1\t%y1";
3006 else
3007 return "fst\t%y0";
3008
3009 case 1:
3010 /* There is no non-popping store to memory for XFmode. So if
3011 we need one, follow the store with a load. */
3012 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013 return "fstp%z0\t%y0\;fld%z0\t%y0";
3014 else
3015 return "fstp%z0\t%y0";
3016
3017 case 2:
3018 return standard_80387_constant_opcode (operands[1]);
3019
3020 case 3: case 4:
3021 return "#";
3022 }
3023 abort();
3024 }
3025 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3026 (set_attr "mode" "XF,XF,XF,SI,SI")])
3027
3028 (define_split
3029 [(set (match_operand 0 "nonimmediate_operand" "")
3030 (match_operand 1 "general_operand" ""))]
3031 "reload_completed
3032 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3033 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3034 && ! (ANY_FP_REG_P (operands[0]) ||
3035 (GET_CODE (operands[0]) == SUBREG
3036 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3037 && ! (ANY_FP_REG_P (operands[1]) ||
3038 (GET_CODE (operands[1]) == SUBREG
3039 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3040 [(const_int 0)]
3041 "ix86_split_long_move (operands); DONE;")
3042
3043 (define_split
3044 [(set (match_operand 0 "register_operand" "")
3045 (match_operand 1 "memory_operand" ""))]
3046 "reload_completed
3047 && GET_CODE (operands[1]) == MEM
3048 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3049 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3050 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3051 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3052 && (!(SSE_REG_P (operands[0]) ||
3053 (GET_CODE (operands[0]) == SUBREG
3054 && SSE_REG_P (SUBREG_REG (operands[0]))))
3055 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3056 && (!(FP_REG_P (operands[0]) ||
3057 (GET_CODE (operands[0]) == SUBREG
3058 && FP_REG_P (SUBREG_REG (operands[0]))))
3059 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3060 [(set (match_dup 0)
3061 (match_dup 1))]
3062 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3063
3064 (define_insn "swapxf"
3065 [(set (match_operand:XF 0 "register_operand" "+f")
3066 (match_operand:XF 1 "register_operand" "+f"))
3067 (set (match_dup 1)
3068 (match_dup 0))]
3069 ""
3070 {
3071 if (STACK_TOP_P (operands[0]))
3072 return "fxch\t%1";
3073 else
3074 return "fxch\t%0";
3075 }
3076 [(set_attr "type" "fxch")
3077 (set_attr "mode" "XF")])
3078
3079 (define_insn "swaptf"
3080 [(set (match_operand:TF 0 "register_operand" "+f")
3081 (match_operand:TF 1 "register_operand" "+f"))
3082 (set (match_dup 1)
3083 (match_dup 0))]
3084 ""
3085 {
3086 if (STACK_TOP_P (operands[0]))
3087 return "fxch\t%1";
3088 else
3089 return "fxch\t%0";
3090 }
3091 [(set_attr "type" "fxch")
3092 (set_attr "mode" "XF")])
3093 \f
3094 ;; Zero extension instructions
3095
3096 (define_expand "zero_extendhisi2"
3097 [(set (match_operand:SI 0 "register_operand" "")
3098 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3099 ""
3100 {
3101 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3102 {
3103 operands[1] = force_reg (HImode, operands[1]);
3104 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3105 DONE;
3106 }
3107 })
3108
3109 (define_insn "zero_extendhisi2_and"
3110 [(set (match_operand:SI 0 "register_operand" "=r")
3111 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3112 (clobber (reg:CC 17))]
3113 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3114 "#"
3115 [(set_attr "type" "alu1")
3116 (set_attr "mode" "SI")])
3117
3118 (define_split
3119 [(set (match_operand:SI 0 "register_operand" "")
3120 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3121 (clobber (reg:CC 17))]
3122 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3123 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3124 (clobber (reg:CC 17))])]
3125 "")
3126
3127 (define_insn "*zero_extendhisi2_movzwl"
3128 [(set (match_operand:SI 0 "register_operand" "=r")
3129 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3130 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3131 "movz{wl|x}\t{%1, %0|%0, %1}"
3132 [(set_attr "type" "imovx")
3133 (set_attr "mode" "SI")])
3134
3135 (define_expand "zero_extendqihi2"
3136 [(parallel
3137 [(set (match_operand:HI 0 "register_operand" "")
3138 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3139 (clobber (reg:CC 17))])]
3140 ""
3141 "")
3142
3143 (define_insn "*zero_extendqihi2_and"
3144 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3145 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3146 (clobber (reg:CC 17))]
3147 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3148 "#"
3149 [(set_attr "type" "alu1")
3150 (set_attr "mode" "HI")])
3151
3152 (define_insn "*zero_extendqihi2_movzbw_and"
3153 [(set (match_operand:HI 0 "register_operand" "=r,r")
3154 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3155 (clobber (reg:CC 17))]
3156 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3157 "#"
3158 [(set_attr "type" "imovx,alu1")
3159 (set_attr "mode" "HI")])
3160
3161 (define_insn "*zero_extendqihi2_movzbw"
3162 [(set (match_operand:HI 0 "register_operand" "=r")
3163 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3164 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3165 "movz{bw|x}\t{%1, %0|%0, %1}"
3166 [(set_attr "type" "imovx")
3167 (set_attr "mode" "HI")])
3168
3169 ;; For the movzbw case strip only the clobber
3170 (define_split
3171 [(set (match_operand:HI 0 "register_operand" "")
3172 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3173 (clobber (reg:CC 17))]
3174 "reload_completed
3175 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3176 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3177 [(set (match_operand:HI 0 "register_operand" "")
3178 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3179
3180 ;; When source and destination does not overlap, clear destination
3181 ;; first and then do the movb
3182 (define_split
3183 [(set (match_operand:HI 0 "register_operand" "")
3184 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3185 (clobber (reg:CC 17))]
3186 "reload_completed
3187 && ANY_QI_REG_P (operands[0])
3188 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3189 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3190 [(set (match_dup 0) (const_int 0))
3191 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3192 "operands[2] = gen_lowpart (QImode, operands[0]);")
3193
3194 ;; Rest is handled by single and.
3195 (define_split
3196 [(set (match_operand:HI 0 "register_operand" "")
3197 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3198 (clobber (reg:CC 17))]
3199 "reload_completed
3200 && true_regnum (operands[0]) == true_regnum (operands[1])"
3201 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3202 (clobber (reg:CC 17))])]
3203 "")
3204
3205 (define_expand "zero_extendqisi2"
3206 [(parallel
3207 [(set (match_operand:SI 0 "register_operand" "")
3208 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3209 (clobber (reg:CC 17))])]
3210 ""
3211 "")
3212
3213 (define_insn "*zero_extendqisi2_and"
3214 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3215 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3216 (clobber (reg:CC 17))]
3217 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3218 "#"
3219 [(set_attr "type" "alu1")
3220 (set_attr "mode" "SI")])
3221
3222 (define_insn "*zero_extendqisi2_movzbw_and"
3223 [(set (match_operand:SI 0 "register_operand" "=r,r")
3224 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3225 (clobber (reg:CC 17))]
3226 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3227 "#"
3228 [(set_attr "type" "imovx,alu1")
3229 (set_attr "mode" "SI")])
3230
3231 (define_insn "*zero_extendqisi2_movzbw"
3232 [(set (match_operand:SI 0 "register_operand" "=r")
3233 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3234 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3235 "movz{bl|x}\t{%1, %0|%0, %1}"
3236 [(set_attr "type" "imovx")
3237 (set_attr "mode" "SI")])
3238
3239 ;; For the movzbl case strip only the clobber
3240 (define_split
3241 [(set (match_operand:SI 0 "register_operand" "")
3242 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3243 (clobber (reg:CC 17))]
3244 "reload_completed
3245 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3246 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3247 [(set (match_dup 0)
3248 (zero_extend:SI (match_dup 1)))])
3249
3250 ;; When source and destination does not overlap, clear destination
3251 ;; first and then do the movb
3252 (define_split
3253 [(set (match_operand:SI 0 "register_operand" "")
3254 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3255 (clobber (reg:CC 17))]
3256 "reload_completed
3257 && ANY_QI_REG_P (operands[0])
3258 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3259 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3260 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3261 [(set (match_dup 0) (const_int 0))
3262 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3263 "operands[2] = gen_lowpart (QImode, operands[0]);")
3264
3265 ;; Rest is handled by single and.
3266 (define_split
3267 [(set (match_operand:SI 0 "register_operand" "")
3268 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3269 (clobber (reg:CC 17))]
3270 "reload_completed
3271 && true_regnum (operands[0]) == true_regnum (operands[1])"
3272 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3273 (clobber (reg:CC 17))])]
3274 "")
3275
3276 ;; %%% Kill me once multi-word ops are sane.
3277 (define_expand "zero_extendsidi2"
3278 [(set (match_operand:DI 0 "register_operand" "=r")
3279 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3280 ""
3281 "if (!TARGET_64BIT)
3282 {
3283 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3284 DONE;
3285 }
3286 ")
3287
3288 (define_insn "zero_extendsidi2_32"
3289 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3290 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3291 (clobber (reg:CC 17))]
3292 "!TARGET_64BIT"
3293 "#"
3294 [(set_attr "mode" "SI")])
3295
3296 (define_insn "zero_extendsidi2_rex64"
3297 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3298 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3299 "TARGET_64BIT"
3300 "@
3301 mov\t{%k1, %k0|%k0, %k1}
3302 #"
3303 [(set_attr "type" "imovx,imov")
3304 (set_attr "mode" "SI,DI")])
3305
3306 (define_split
3307 [(set (match_operand:DI 0 "memory_operand" "")
3308 (zero_extend:DI (match_dup 0)))]
3309 "TARGET_64BIT"
3310 [(set (match_dup 4) (const_int 0))]
3311 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3312
3313 (define_split
3314 [(set (match_operand:DI 0 "register_operand" "")
3315 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3316 (clobber (reg:CC 17))]
3317 "!TARGET_64BIT && reload_completed
3318 && true_regnum (operands[0]) == true_regnum (operands[1])"
3319 [(set (match_dup 4) (const_int 0))]
3320 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3321
3322 (define_split
3323 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3324 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3325 (clobber (reg:CC 17))]
3326 "!TARGET_64BIT && reload_completed"
3327 [(set (match_dup 3) (match_dup 1))
3328 (set (match_dup 4) (const_int 0))]
3329 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3330
3331 (define_insn "zero_extendhidi2"
3332 [(set (match_operand:DI 0 "register_operand" "=r,r")
3333 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3334 "TARGET_64BIT"
3335 "@
3336 movz{wl|x}\t{%1, %k0|%k0, %1}
3337 movz{wq|x}\t{%1, %0|%0, %1}"
3338 [(set_attr "type" "imovx")
3339 (set_attr "mode" "SI,DI")])
3340
3341 (define_insn "zero_extendqidi2"
3342 [(set (match_operand:DI 0 "register_operand" "=r,r")
3343 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3344 "TARGET_64BIT"
3345 "@
3346 movz{bl|x}\t{%1, %k0|%k0, %1}
3347 movz{bq|x}\t{%1, %0|%0, %1}"
3348 [(set_attr "type" "imovx")
3349 (set_attr "mode" "SI,DI")])
3350 \f
3351 ;; Sign extension instructions
3352
3353 (define_expand "extendsidi2"
3354 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3355 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3356 (clobber (reg:CC 17))
3357 (clobber (match_scratch:SI 2 ""))])]
3358 ""
3359 {
3360 if (TARGET_64BIT)
3361 {
3362 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3363 DONE;
3364 }
3365 })
3366
3367 (define_insn "*extendsidi2_1"
3368 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3369 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3370 (clobber (reg:CC 17))
3371 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3372 "!TARGET_64BIT"
3373 "#")
3374
3375 (define_insn "extendsidi2_rex64"
3376 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3377 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3378 "TARGET_64BIT"
3379 "@
3380 {cltq|cdqe}
3381 movs{lq|x}\t{%1,%0|%0, %1}"
3382 [(set_attr "type" "imovx")
3383 (set_attr "mode" "DI")
3384 (set_attr "prefix_0f" "0")
3385 (set_attr "modrm" "0,1")])
3386
3387 (define_insn "extendhidi2"
3388 [(set (match_operand:DI 0 "register_operand" "=r")
3389 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3390 "TARGET_64BIT"
3391 "movs{wq|x}\t{%1,%0|%0, %1}"
3392 [(set_attr "type" "imovx")
3393 (set_attr "mode" "DI")])
3394
3395 (define_insn "extendqidi2"
3396 [(set (match_operand:DI 0 "register_operand" "=r")
3397 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3398 "TARGET_64BIT"
3399 "movs{bq|x}\t{%1,%0|%0, %1}"
3400 [(set_attr "type" "imovx")
3401 (set_attr "mode" "DI")])
3402
3403 ;; Extend to memory case when source register does die.
3404 (define_split
3405 [(set (match_operand:DI 0 "memory_operand" "")
3406 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3407 (clobber (reg:CC 17))
3408 (clobber (match_operand:SI 2 "register_operand" ""))]
3409 "(reload_completed
3410 && dead_or_set_p (insn, operands[1])
3411 && !reg_mentioned_p (operands[1], operands[0]))"
3412 [(set (match_dup 3) (match_dup 1))
3413 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3414 (clobber (reg:CC 17))])
3415 (set (match_dup 4) (match_dup 1))]
3416 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3417
3418 ;; Extend to memory case when source register does not die.
3419 (define_split
3420 [(set (match_operand:DI 0 "memory_operand" "")
3421 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3422 (clobber (reg:CC 17))
3423 (clobber (match_operand:SI 2 "register_operand" ""))]
3424 "reload_completed"
3425 [(const_int 0)]
3426 {
3427 split_di (&operands[0], 1, &operands[3], &operands[4]);
3428
3429 emit_move_insn (operands[3], operands[1]);
3430
3431 /* Generate a cltd if possible and doing so it profitable. */
3432 if (true_regnum (operands[1]) == 0
3433 && true_regnum (operands[2]) == 1
3434 && (optimize_size || TARGET_USE_CLTD))
3435 {
3436 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3437 }
3438 else
3439 {
3440 emit_move_insn (operands[2], operands[1]);
3441 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3442 }
3443 emit_move_insn (operands[4], operands[2]);
3444 DONE;
3445 })
3446
3447 ;; Extend to register case. Optimize case where source and destination
3448 ;; registers match and cases where we can use cltd.
3449 (define_split
3450 [(set (match_operand:DI 0 "register_operand" "")
3451 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3452 (clobber (reg:CC 17))
3453 (clobber (match_scratch:SI 2 ""))]
3454 "reload_completed"
3455 [(const_int 0)]
3456 {
3457 split_di (&operands[0], 1, &operands[3], &operands[4]);
3458
3459 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3460 emit_move_insn (operands[3], operands[1]);
3461
3462 /* Generate a cltd if possible and doing so it profitable. */
3463 if (true_regnum (operands[3]) == 0
3464 && (optimize_size || TARGET_USE_CLTD))
3465 {
3466 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3467 DONE;
3468 }
3469
3470 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3471 emit_move_insn (operands[4], operands[1]);
3472
3473 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3474 DONE;
3475 })
3476
3477 (define_insn "extendhisi2"
3478 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3479 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3480 ""
3481 {
3482 switch (get_attr_prefix_0f (insn))
3483 {
3484 case 0:
3485 return "{cwtl|cwde}";
3486 default:
3487 return "movs{wl|x}\t{%1,%0|%0, %1}";
3488 }
3489 }
3490 [(set_attr "type" "imovx")
3491 (set_attr "mode" "SI")
3492 (set (attr "prefix_0f")
3493 ;; movsx is short decodable while cwtl is vector decoded.
3494 (if_then_else (and (eq_attr "cpu" "!k6")
3495 (eq_attr "alternative" "0"))
3496 (const_string "0")
3497 (const_string "1")))
3498 (set (attr "modrm")
3499 (if_then_else (eq_attr "prefix_0f" "0")
3500 (const_string "0")
3501 (const_string "1")))])
3502
3503 (define_insn "*extendhisi2_zext"
3504 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3505 (zero_extend:DI
3506 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3507 "TARGET_64BIT"
3508 {
3509 switch (get_attr_prefix_0f (insn))
3510 {
3511 case 0:
3512 return "{cwtl|cwde}";
3513 default:
3514 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3515 }
3516 }
3517 [(set_attr "type" "imovx")
3518 (set_attr "mode" "SI")
3519 (set (attr "prefix_0f")
3520 ;; movsx is short decodable while cwtl is vector decoded.
3521 (if_then_else (and (eq_attr "cpu" "!k6")
3522 (eq_attr "alternative" "0"))
3523 (const_string "0")
3524 (const_string "1")))
3525 (set (attr "modrm")
3526 (if_then_else (eq_attr "prefix_0f" "0")
3527 (const_string "0")
3528 (const_string "1")))])
3529
3530 (define_insn "extendqihi2"
3531 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3532 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3533 ""
3534 {
3535 switch (get_attr_prefix_0f (insn))
3536 {
3537 case 0:
3538 return "{cbtw|cbw}";
3539 default:
3540 return "movs{bw|x}\t{%1,%0|%0, %1}";
3541 }
3542 }
3543 [(set_attr "type" "imovx")
3544 (set_attr "mode" "HI")
3545 (set (attr "prefix_0f")
3546 ;; movsx is short decodable while cwtl is vector decoded.
3547 (if_then_else (and (eq_attr "cpu" "!k6")
3548 (eq_attr "alternative" "0"))
3549 (const_string "0")
3550 (const_string "1")))
3551 (set (attr "modrm")
3552 (if_then_else (eq_attr "prefix_0f" "0")
3553 (const_string "0")
3554 (const_string "1")))])
3555
3556 (define_insn "extendqisi2"
3557 [(set (match_operand:SI 0 "register_operand" "=r")
3558 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3559 ""
3560 "movs{bl|x}\t{%1,%0|%0, %1}"
3561 [(set_attr "type" "imovx")
3562 (set_attr "mode" "SI")])
3563
3564 (define_insn "*extendqisi2_zext"
3565 [(set (match_operand:DI 0 "register_operand" "=r")
3566 (zero_extend:DI
3567 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3568 "TARGET_64BIT"
3569 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3570 [(set_attr "type" "imovx")
3571 (set_attr "mode" "SI")])
3572 \f
3573 ;; Conversions between float and double.
3574
3575 ;; These are all no-ops in the model used for the 80387. So just
3576 ;; emit moves.
3577
3578 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3579 (define_insn "*dummy_extendsfdf2"
3580 [(set (match_operand:DF 0 "push_operand" "=<")
3581 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3582 "0"
3583 "#")
3584
3585 (define_split
3586 [(set (match_operand:DF 0 "push_operand" "")
3587 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3588 "!TARGET_64BIT"
3589 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3590 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3591
3592 (define_split
3593 [(set (match_operand:DF 0 "push_operand" "")
3594 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3595 "TARGET_64BIT"
3596 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3597 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3598
3599 (define_insn "*dummy_extendsfxf2"
3600 [(set (match_operand:XF 0 "push_operand" "=<")
3601 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3602 "0"
3603 "#")
3604
3605 (define_split
3606 [(set (match_operand:XF 0 "push_operand" "")
3607 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3608 "!TARGET_128BIT_LONG_DOUBLE"
3609 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3610 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3611
3612 (define_insn "*dummy_extendsftf2"
3613 [(set (match_operand:TF 0 "push_operand" "=<")
3614 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3615 "0"
3616 "#")
3617
3618 (define_split
3619 [(set (match_operand:TF 0 "push_operand" "")
3620 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3621 "!TARGET_64BIT"
3622 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3623 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3624
3625 (define_split
3626 [(set (match_operand:TF 0 "push_operand" "")
3627 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3628 "TARGET_64BIT"
3629 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3630 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3631
3632 (define_insn "*dummy_extenddfxf2"
3633 [(set (match_operand:XF 0 "push_operand" "=<")
3634 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3635 "0"
3636 "#")
3637
3638 (define_split
3639 [(set (match_operand:XF 0 "push_operand" "")
3640 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3641 "!TARGET_128BIT_LONG_DOUBLE"
3642 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3643 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3644
3645 (define_insn "*dummy_extenddftf2"
3646 [(set (match_operand:TF 0 "push_operand" "=<")
3647 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3648 "0"
3649 "#")
3650
3651 (define_split
3652 [(set (match_operand:TF 0 "push_operand" "")
3653 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3654 "!TARGET_64BIT"
3655 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3656 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3657
3658 (define_split
3659 [(set (match_operand:TF 0 "push_operand" "")
3660 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3661 "TARGET_64BIT"
3662 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3663 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3664
3665 (define_expand "extendsfdf2"
3666 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3667 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3668 "TARGET_80387 || TARGET_SSE2"
3669 {
3670 /* ??? Needed for compress_float_constant since all fp constants
3671 are LEGITIMATE_CONSTANT_P. */
3672 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3673 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3674 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3675 operands[1] = force_reg (SFmode, operands[1]);
3676 })
3677
3678 (define_insn "*extendsfdf2_1"
3679 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3680 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3681 "(TARGET_80387 || TARGET_SSE2)
3682 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3683 {
3684 switch (which_alternative)
3685 {
3686 case 0:
3687 if (REG_P (operands[1])
3688 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689 return "fstp\t%y0";
3690 else if (STACK_TOP_P (operands[0]))
3691 return "fld%z1\t%y1";
3692 else
3693 return "fst\t%y0";
3694
3695 case 1:
3696 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697 return "fstp%z0\t%y0";
3698
3699 else
3700 return "fst%z0\t%y0";
3701 case 2:
3702 return "cvtss2sd\t{%1, %0|%0, %1}";
3703
3704 default:
3705 abort ();
3706 }
3707 }
3708 [(set_attr "type" "fmov,fmov,ssecvt")
3709 (set_attr "mode" "SF,XF,DF")])
3710
3711 (define_insn "*extendsfdf2_1_sse_only"
3712 [(set (match_operand:DF 0 "register_operand" "=Y")
3713 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3714 "!TARGET_80387 && TARGET_SSE2
3715 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3716 "cvtss2sd\t{%1, %0|%0, %1}"
3717 [(set_attr "type" "ssecvt")
3718 (set_attr "mode" "DF")])
3719
3720 (define_expand "extendsfxf2"
3721 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3722 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3723 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3724 {
3725 /* ??? Needed for compress_float_constant since all fp constants
3726 are LEGITIMATE_CONSTANT_P. */
3727 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3728 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3729 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3730 operands[1] = force_reg (SFmode, operands[1]);
3731 })
3732
3733 (define_insn "*extendsfxf2_1"
3734 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3735 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3736 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3737 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3738 {
3739 switch (which_alternative)
3740 {
3741 case 0:
3742 if (REG_P (operands[1])
3743 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3744 return "fstp\t%y0";
3745 else if (STACK_TOP_P (operands[0]))
3746 return "fld%z1\t%y1";
3747 else
3748 return "fst\t%y0";
3749
3750 case 1:
3751 /* There is no non-popping store to memory for XFmode. So if
3752 we need one, follow the store with a load. */
3753 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3754 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3755 else
3756 return "fstp%z0\t%y0";
3757
3758 default:
3759 abort ();
3760 }
3761 }
3762 [(set_attr "type" "fmov")
3763 (set_attr "mode" "SF,XF")])
3764
3765 (define_expand "extendsftf2"
3766 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3767 (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3768 "TARGET_80387"
3769 {
3770 /* ??? Needed for compress_float_constant since all fp constants
3771 are LEGITIMATE_CONSTANT_P. */
3772 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3773 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3774 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3775 operands[1] = force_reg (SFmode, operands[1]);
3776 })
3777
3778 (define_insn "*extendsftf2_1"
3779 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3780 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3781 "TARGET_80387
3782 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3783 {
3784 switch (which_alternative)
3785 {
3786 case 0:
3787 if (REG_P (operands[1])
3788 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3789 return "fstp\t%y0";
3790 else if (STACK_TOP_P (operands[0]))
3791 return "fld%z1\t%y1";
3792 else
3793 return "fst\t%y0";
3794
3795 case 1:
3796 /* There is no non-popping store to memory for XFmode. So if
3797 we need one, follow the store with a load. */
3798 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3799 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3800 else
3801 return "fstp%z0\t%y0";
3802
3803 default:
3804 abort ();
3805 }
3806 }
3807 [(set_attr "type" "fmov")
3808 (set_attr "mode" "SF,XF")])
3809
3810 (define_expand "extenddfxf2"
3811 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3812 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3813 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3814 {
3815 /* ??? Needed for compress_float_constant since all fp constants
3816 are LEGITIMATE_CONSTANT_P. */
3817 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3818 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3819 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3820 operands[1] = force_reg (DFmode, operands[1]);
3821 })
3822
3823 (define_insn "*extenddfxf2_1"
3824 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3825 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3826 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3827 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3828 {
3829 switch (which_alternative)
3830 {
3831 case 0:
3832 if (REG_P (operands[1])
3833 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834 return "fstp\t%y0";
3835 else if (STACK_TOP_P (operands[0]))
3836 return "fld%z1\t%y1";
3837 else
3838 return "fst\t%y0";
3839
3840 case 1:
3841 /* There is no non-popping store to memory for XFmode. So if
3842 we need one, follow the store with a load. */
3843 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3844 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3845 else
3846 return "fstp%z0\t%y0";
3847
3848 default:
3849 abort ();
3850 }
3851 }
3852 [(set_attr "type" "fmov")
3853 (set_attr "mode" "DF,XF")])
3854
3855 (define_expand "extenddftf2"
3856 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3857 (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3858 "TARGET_80387"
3859 {
3860 /* ??? Needed for compress_float_constant since all fp constants
3861 are LEGITIMATE_CONSTANT_P. */
3862 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3863 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3864 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3865 operands[1] = force_reg (DFmode, operands[1]);
3866 })
3867
3868 (define_insn "*extenddftf2_1"
3869 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3870 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3871 "TARGET_80387
3872 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3873 {
3874 switch (which_alternative)
3875 {
3876 case 0:
3877 if (REG_P (operands[1])
3878 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3879 return "fstp\t%y0";
3880 else if (STACK_TOP_P (operands[0]))
3881 return "fld%z1\t%y1";
3882 else
3883 return "fst\t%y0";
3884
3885 case 1:
3886 /* There is no non-popping store to memory for XFmode. So if
3887 we need one, follow the store with a load. */
3888 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3889 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3890 else
3891 return "fstp%z0\t%y0";
3892
3893 default:
3894 abort ();
3895 }
3896 }
3897 [(set_attr "type" "fmov")
3898 (set_attr "mode" "DF,XF")])
3899
3900 ;; %%% This seems bad bad news.
3901 ;; This cannot output into an f-reg because there is no way to be sure
3902 ;; of truncating in that case. Otherwise this is just like a simple move
3903 ;; insn. So we pretend we can output to a reg in order to get better
3904 ;; register preferencing, but we really use a stack slot.
3905
3906 (define_expand "truncdfsf2"
3907 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3908 (float_truncate:SF
3909 (match_operand:DF 1 "register_operand" "")))
3910 (clobber (match_dup 2))])]
3911 "TARGET_80387 || TARGET_SSE2"
3912 "
3913 if (TARGET_80387)
3914 operands[2] = assign_386_stack_local (SFmode, 0);
3915 else
3916 {
3917 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3918 DONE;
3919 }
3920 ")
3921
3922 (define_insn "*truncdfsf2_1"
3923 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3924 (float_truncate:SF
3925 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3926 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3927 "TARGET_80387 && !TARGET_SSE2"
3928 {
3929 switch (which_alternative)
3930 {
3931 case 0:
3932 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933 return "fstp%z0\t%y0";
3934 else
3935 return "fst%z0\t%y0";
3936 default:
3937 abort ();
3938 }
3939 }
3940 [(set_attr "type" "fmov,multi,multi,multi")
3941 (set_attr "mode" "SF,SF,SF,SF")])
3942
3943 (define_insn "*truncdfsf2_1_sse"
3944 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3945 (float_truncate:SF
3946 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3947 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3948 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
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 case 4:
3958 return "#";
3959 default:
3960 abort ();
3961 }
3962 }
3963 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3964 (set_attr "mode" "SF,SF,SF,SF,DF")])
3965
3966 (define_insn "*truncdfsf2_1_sse_nooverlap"
3967 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3968 (float_truncate:SF
3969 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3970 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3971 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3972 {
3973 switch (which_alternative)
3974 {
3975 case 0:
3976 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977 return "fstp%z0\t%y0";
3978 else
3979 return "fst%z0\t%y0";
3980 case 4:
3981 return "#";
3982 default:
3983 abort ();
3984 }
3985 }
3986 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3987 (set_attr "mode" "SF,SF,SF,SF,DF")])
3988
3989 (define_insn "*truncdfsf2_2"
3990 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3991 (float_truncate:SF
3992 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3993 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3994 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3995 {
3996 switch (which_alternative)
3997 {
3998 case 0:
3999 case 1:
4000 return "cvtsd2ss\t{%1, %0|%0, %1}";
4001 case 2:
4002 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4003 return "fstp%z0\t%y0";
4004 else
4005 return "fst%z0\t%y0";
4006 default:
4007 abort ();
4008 }
4009 }
4010 [(set_attr "type" "ssecvt,ssecvt,fmov")
4011 (set_attr "athlon_decode" "vector,double,*")
4012 (set_attr "mode" "SF,SF,SF")])
4013
4014 (define_insn "*truncdfsf2_2_nooverlap"
4015 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
4016 (float_truncate:SF
4017 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4018 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
4019 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4020 {
4021 switch (which_alternative)
4022 {
4023 case 0:
4024 return "#";
4025 case 1:
4026 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4027 return "fstp%z0\t%y0";
4028 else
4029 return "fst%z0\t%y0";
4030 default:
4031 abort ();
4032 }
4033 }
4034 [(set_attr "type" "ssecvt,fmov")
4035 (set_attr "mode" "DF,SF")])
4036
4037 (define_insn "*truncdfsf2_3"
4038 [(set (match_operand:SF 0 "memory_operand" "=m")
4039 (float_truncate:SF
4040 (match_operand:DF 1 "register_operand" "f")))]
4041 "TARGET_80387"
4042 {
4043 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4044 return "fstp%z0\t%y0";
4045 else
4046 return "fst%z0\t%y0";
4047 }
4048 [(set_attr "type" "fmov")
4049 (set_attr "mode" "SF")])
4050
4051 (define_insn "truncdfsf2_sse_only"
4052 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
4053 (float_truncate:SF
4054 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
4055 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4056 "cvtsd2ss\t{%1, %0|%0, %1}"
4057 [(set_attr "type" "ssecvt")
4058 (set_attr "athlon_decode" "vector,double")
4059 (set_attr "mode" "SF")])
4060
4061 (define_insn "*truncdfsf2_sse_only_nooverlap"
4062 [(set (match_operand:SF 0 "register_operand" "=&Y")
4063 (float_truncate:SF
4064 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4065 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4066 "#"
4067 [(set_attr "type" "ssecvt")
4068 (set_attr "mode" "DF")])
4069
4070 (define_split
4071 [(set (match_operand:SF 0 "memory_operand" "")
4072 (float_truncate:SF
4073 (match_operand:DF 1 "register_operand" "")))
4074 (clobber (match_operand:SF 2 "memory_operand" ""))]
4075 "TARGET_80387"
4076 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4077 "")
4078
4079 ; Avoid possible reformatting penalty on the destination by first
4080 ; zeroing it out
4081 (define_split
4082 [(set (match_operand:SF 0 "register_operand" "")
4083 (float_truncate:SF
4084 (match_operand:DF 1 "nonimmediate_operand" "")))
4085 (clobber (match_operand 2 "" ""))]
4086 "TARGET_80387 && reload_completed
4087 && SSE_REG_P (operands[0])
4088 && !STACK_REG_P (operands[1])"
4089 [(const_int 0)]
4090 {
4091 rtx src, dest;
4092 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
4093 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4094 else
4095 {
4096 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4097 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4098 /* simplify_gen_subreg refuses to widen memory references. */
4099 if (GET_CODE (src) == SUBREG)
4100 alter_subreg (&src);
4101 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4102 abort ();
4103 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4104 emit_insn (gen_cvtsd2ss (dest, dest, src));
4105 }
4106 DONE;
4107 })
4108
4109 (define_split
4110 [(set (match_operand:SF 0 "register_operand" "")
4111 (float_truncate:SF
4112 (match_operand:DF 1 "nonimmediate_operand" "")))]
4113 "TARGET_80387 && reload_completed
4114 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4115 [(const_int 0)]
4116 {
4117 rtx src, dest;
4118 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4119 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4120 /* simplify_gen_subreg refuses to widen memory references. */
4121 if (GET_CODE (src) == SUBREG)
4122 alter_subreg (&src);
4123 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4124 abort ();
4125 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4126 emit_insn (gen_cvtsd2ss (dest, dest, src));
4127 DONE;
4128 })
4129
4130 (define_split
4131 [(set (match_operand:SF 0 "register_operand" "")
4132 (float_truncate:SF
4133 (match_operand:DF 1 "fp_register_operand" "")))
4134 (clobber (match_operand:SF 2 "memory_operand" ""))]
4135 "TARGET_80387 && reload_completed"
4136 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4137 (set (match_dup 0) (match_dup 2))]
4138 "")
4139
4140 (define_expand "truncxfsf2"
4141 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4142 (float_truncate:SF
4143 (match_operand:XF 1 "register_operand" "")))
4144 (clobber (match_dup 2))])]
4145 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4146 "operands[2] = assign_386_stack_local (SFmode, 0);")
4147
4148 (define_insn "*truncxfsf2_1"
4149 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4150 (float_truncate:SF
4151 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4152 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4153 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4154 {
4155 switch (which_alternative)
4156 {
4157 case 0:
4158 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4159 return "fstp%z0\t%y0";
4160 else
4161 return "fst%z0\t%y0";
4162 default:
4163 abort();
4164 }
4165 }
4166 [(set_attr "type" "fmov,multi,multi,multi")
4167 (set_attr "mode" "SF")])
4168
4169 (define_insn "*truncxfsf2_2"
4170 [(set (match_operand:SF 0 "memory_operand" "=m")
4171 (float_truncate:SF
4172 (match_operand:XF 1 "register_operand" "f")))]
4173 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4174 {
4175 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4176 return "fstp%z0\t%y0";
4177 else
4178 return "fst%z0\t%y0";
4179 }
4180 [(set_attr "type" "fmov")
4181 (set_attr "mode" "SF")])
4182
4183 (define_split
4184 [(set (match_operand:SF 0 "memory_operand" "")
4185 (float_truncate:SF
4186 (match_operand:XF 1 "register_operand" "")))
4187 (clobber (match_operand:SF 2 "memory_operand" ""))]
4188 "TARGET_80387"
4189 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4190 "")
4191
4192 (define_split
4193 [(set (match_operand:SF 0 "register_operand" "")
4194 (float_truncate:SF
4195 (match_operand:XF 1 "register_operand" "")))
4196 (clobber (match_operand:SF 2 "memory_operand" ""))]
4197 "TARGET_80387 && reload_completed"
4198 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4199 (set (match_dup 0) (match_dup 2))]
4200 "")
4201
4202 (define_expand "trunctfsf2"
4203 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4204 (float_truncate:SF
4205 (match_operand:TF 1 "register_operand" "")))
4206 (clobber (match_dup 2))])]
4207 "TARGET_80387"
4208 "operands[2] = assign_386_stack_local (SFmode, 0);")
4209
4210 (define_insn "*trunctfsf2_1"
4211 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4212 (float_truncate:SF
4213 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4214 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4215 "TARGET_80387"
4216 {
4217 switch (which_alternative)
4218 {
4219 case 0:
4220 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4221 return "fstp%z0\t%y0";
4222 else
4223 return "fst%z0\t%y0";
4224 default:
4225 abort();
4226 }
4227 }
4228 [(set_attr "type" "fmov,multi,multi,multi")
4229 (set_attr "mode" "SF")])
4230
4231 (define_insn "*trunctfsf2_2"
4232 [(set (match_operand:SF 0 "memory_operand" "=m")
4233 (float_truncate:SF
4234 (match_operand:TF 1 "register_operand" "f")))]
4235 "TARGET_80387"
4236 {
4237 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4238 return "fstp%z0\t%y0";
4239 else
4240 return "fst%z0\t%y0";
4241 }
4242 [(set_attr "type" "fmov")
4243 (set_attr "mode" "SF")])
4244
4245 (define_split
4246 [(set (match_operand:SF 0 "memory_operand" "")
4247 (float_truncate:SF
4248 (match_operand:TF 1 "register_operand" "")))
4249 (clobber (match_operand:SF 2 "memory_operand" ""))]
4250 "TARGET_80387"
4251 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4252 "")
4253
4254 (define_split
4255 [(set (match_operand:SF 0 "register_operand" "")
4256 (float_truncate:SF
4257 (match_operand:TF 1 "register_operand" "")))
4258 (clobber (match_operand:SF 2 "memory_operand" ""))]
4259 "TARGET_80387 && reload_completed"
4260 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4261 (set (match_dup 0) (match_dup 2))]
4262 "")
4263
4264
4265 (define_expand "truncxfdf2"
4266 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4267 (float_truncate:DF
4268 (match_operand:XF 1 "register_operand" "")))
4269 (clobber (match_dup 2))])]
4270 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4271 "operands[2] = assign_386_stack_local (DFmode, 0);")
4272
4273 (define_insn "*truncxfdf2_1"
4274 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4275 (float_truncate:DF
4276 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4277 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4278 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4279 {
4280 switch (which_alternative)
4281 {
4282 case 0:
4283 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4284 return "fstp%z0\t%y0";
4285 else
4286 return "fst%z0\t%y0";
4287 default:
4288 abort();
4289 }
4290 abort ();
4291 }
4292 [(set_attr "type" "fmov,multi,multi,multi")
4293 (set_attr "mode" "DF")])
4294
4295 (define_insn "*truncxfdf2_2"
4296 [(set (match_operand:DF 0 "memory_operand" "=m")
4297 (float_truncate:DF
4298 (match_operand:XF 1 "register_operand" "f")))]
4299 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4300 {
4301 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4302 return "fstp%z0\t%y0";
4303 else
4304 return "fst%z0\t%y0";
4305 }
4306 [(set_attr "type" "fmov")
4307 (set_attr "mode" "DF")])
4308
4309 (define_split
4310 [(set (match_operand:DF 0 "memory_operand" "")
4311 (float_truncate:DF
4312 (match_operand:XF 1 "register_operand" "")))
4313 (clobber (match_operand:DF 2 "memory_operand" ""))]
4314 "TARGET_80387"
4315 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4316 "")
4317
4318 (define_split
4319 [(set (match_operand:DF 0 "register_operand" "")
4320 (float_truncate:DF
4321 (match_operand:XF 1 "register_operand" "")))
4322 (clobber (match_operand:DF 2 "memory_operand" ""))]
4323 "TARGET_80387 && reload_completed"
4324 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4325 (set (match_dup 0) (match_dup 2))]
4326 "")
4327
4328 (define_expand "trunctfdf2"
4329 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4330 (float_truncate:DF
4331 (match_operand:TF 1 "register_operand" "")))
4332 (clobber (match_dup 2))])]
4333 "TARGET_80387"
4334 "operands[2] = assign_386_stack_local (DFmode, 0);")
4335
4336 (define_insn "*trunctfdf2_1"
4337 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4338 (float_truncate:DF
4339 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4340 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4341 "TARGET_80387"
4342 {
4343 switch (which_alternative)
4344 {
4345 case 0:
4346 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4347 return "fstp%z0\t%y0";
4348 else
4349 return "fst%z0\t%y0";
4350 default:
4351 abort();
4352 }
4353 abort ();
4354 }
4355 [(set_attr "type" "fmov,multi,multi,multi")
4356 (set_attr "mode" "DF")])
4357
4358 (define_insn "*trunctfdf2_2"
4359 [(set (match_operand:DF 0 "memory_operand" "=m")
4360 (float_truncate:DF
4361 (match_operand:TF 1 "register_operand" "f")))]
4362 "TARGET_80387"
4363 {
4364 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4365 return "fstp%z0\t%y0";
4366 else
4367 return "fst%z0\t%y0";
4368 }
4369 [(set_attr "type" "fmov")
4370 (set_attr "mode" "DF")])
4371
4372 (define_split
4373 [(set (match_operand:DF 0 "memory_operand" "")
4374 (float_truncate:DF
4375 (match_operand:TF 1 "register_operand" "")))
4376 (clobber (match_operand:DF 2 "memory_operand" ""))]
4377 "TARGET_80387"
4378 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4379 "")
4380
4381 (define_split
4382 [(set (match_operand:DF 0 "register_operand" "")
4383 (float_truncate:DF
4384 (match_operand:TF 1 "register_operand" "")))
4385 (clobber (match_operand:DF 2 "memory_operand" ""))]
4386 "TARGET_80387 && reload_completed"
4387 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4388 (set (match_dup 0) (match_dup 2))]
4389 "")
4390
4391 \f
4392 ;; %%% Break up all these bad boys.
4393
4394 ;; Signed conversion to DImode.
4395
4396 (define_expand "fix_truncxfdi2"
4397 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4398 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4399 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4400 "")
4401
4402 (define_expand "fix_trunctfdi2"
4403 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4404 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4405 "TARGET_80387"
4406 "")
4407
4408 (define_expand "fix_truncdfdi2"
4409 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4410 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4411 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4412 {
4413 if (TARGET_64BIT && TARGET_SSE2)
4414 {
4415 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4416 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4417 if (out != operands[0])
4418 emit_move_insn (operands[0], out);
4419 DONE;
4420 }
4421 })
4422
4423 (define_expand "fix_truncsfdi2"
4424 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4425 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4426 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4427 {
4428 if (TARGET_SSE && TARGET_64BIT)
4429 {
4430 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4431 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4432 if (out != operands[0])
4433 emit_move_insn (operands[0], out);
4434 DONE;
4435 }
4436 })
4437
4438 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4439 ;; of the machinery.
4440 (define_insn_and_split "*fix_truncdi_1"
4441 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4442 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4443 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && !reload_completed && !reload_in_progress
4445 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4446 "#"
4447 "&& 1"
4448 [(const_int 0)]
4449 {
4450 ix86_optimize_mode_switching = 1;
4451 operands[2] = assign_386_stack_local (HImode, 1);
4452 operands[3] = assign_386_stack_local (HImode, 2);
4453 if (memory_operand (operands[0], VOIDmode))
4454 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4455 operands[2], operands[3]));
4456 else
4457 {
4458 operands[4] = assign_386_stack_local (DImode, 0);
4459 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4460 operands[2], operands[3],
4461 operands[4]));
4462 }
4463 DONE;
4464 }
4465 [(set_attr "type" "fistp")
4466 (set_attr "mode" "DI")])
4467
4468 (define_insn "fix_truncdi_nomemory"
4469 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4470 (fix:DI (match_operand 1 "register_operand" "f,f")))
4471 (use (match_operand:HI 2 "memory_operand" "m,m"))
4472 (use (match_operand:HI 3 "memory_operand" "m,m"))
4473 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4474 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4475 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4476 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4477 "#"
4478 [(set_attr "type" "fistp")
4479 (set_attr "mode" "DI")])
4480
4481 (define_insn "fix_truncdi_memory"
4482 [(set (match_operand:DI 0 "memory_operand" "=m")
4483 (fix:DI (match_operand 1 "register_operand" "f")))
4484 (use (match_operand:HI 2 "memory_operand" "m"))
4485 (use (match_operand:HI 3 "memory_operand" "m"))
4486 (clobber (match_scratch:DF 4 "=&1f"))]
4487 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4488 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4489 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4490 [(set_attr "type" "fistp")
4491 (set_attr "mode" "DI")])
4492
4493 (define_split
4494 [(set (match_operand:DI 0 "register_operand" "")
4495 (fix:DI (match_operand 1 "register_operand" "")))
4496 (use (match_operand:HI 2 "memory_operand" ""))
4497 (use (match_operand:HI 3 "memory_operand" ""))
4498 (clobber (match_operand:DI 4 "memory_operand" ""))
4499 (clobber (match_scratch 5 ""))]
4500 "reload_completed"
4501 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4502 (use (match_dup 2))
4503 (use (match_dup 3))
4504 (clobber (match_dup 5))])
4505 (set (match_dup 0) (match_dup 4))]
4506 "")
4507
4508 (define_split
4509 [(set (match_operand:DI 0 "memory_operand" "")
4510 (fix:DI (match_operand 1 "register_operand" "")))
4511 (use (match_operand:HI 2 "memory_operand" ""))
4512 (use (match_operand:HI 3 "memory_operand" ""))
4513 (clobber (match_operand:DI 4 "memory_operand" ""))
4514 (clobber (match_scratch 5 ""))]
4515 "reload_completed"
4516 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4517 (use (match_dup 2))
4518 (use (match_dup 3))
4519 (clobber (match_dup 5))])]
4520 "")
4521
4522 ;; When SSE available, it is always faster to use it!
4523 (define_insn "fix_truncsfdi_sse"
4524 [(set (match_operand:DI 0 "register_operand" "=r,r")
4525 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4526 "TARGET_64BIT && TARGET_SSE"
4527 "cvttss2si{q}\t{%1, %0|%0, %1}"
4528 [(set_attr "type" "sseicvt")
4529 (set_attr "mode" "SF")
4530 (set_attr "athlon_decode" "double,vector")])
4531
4532 ;; Avoid vector decoded form of the instruction.
4533 (define_peephole2
4534 [(match_scratch:SF 2 "x")
4535 (set (match_operand:DI 0 "register_operand" "")
4536 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4537 "TARGET_K8 && !optimize_size"
4538 [(set (match_dup 2) (match_dup 1))
4539 (set (match_dup 0) (fix:DI (match_dup 2)))]
4540 "")
4541
4542 (define_insn "fix_truncdfdi_sse"
4543 [(set (match_operand:DI 0 "register_operand" "=r,r")
4544 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4545 "TARGET_64BIT && TARGET_SSE2"
4546 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4547 [(set_attr "type" "sseicvt,sseicvt")
4548 (set_attr "mode" "DF")
4549 (set_attr "athlon_decode" "double,vector")])
4550
4551 ;; Avoid vector decoded form of the instruction.
4552 (define_peephole2
4553 [(match_scratch:DF 2 "Y")
4554 (set (match_operand:DI 0 "register_operand" "")
4555 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4556 "TARGET_K8 && !optimize_size"
4557 [(set (match_dup 2) (match_dup 1))
4558 (set (match_dup 0) (fix:DI (match_dup 2)))]
4559 "")
4560
4561 ;; Signed conversion to SImode.
4562
4563 (define_expand "fix_truncxfsi2"
4564 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4565 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4566 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4567 "")
4568
4569 (define_expand "fix_trunctfsi2"
4570 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4571 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4572 "TARGET_80387"
4573 "")
4574
4575 (define_expand "fix_truncdfsi2"
4576 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4577 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4578 "TARGET_80387 || TARGET_SSE2"
4579 {
4580 if (TARGET_SSE2)
4581 {
4582 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4583 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4584 if (out != operands[0])
4585 emit_move_insn (operands[0], out);
4586 DONE;
4587 }
4588 })
4589
4590 (define_expand "fix_truncsfsi2"
4591 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4592 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4593 "TARGET_80387 || TARGET_SSE"
4594 {
4595 if (TARGET_SSE)
4596 {
4597 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4598 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4599 if (out != operands[0])
4600 emit_move_insn (operands[0], out);
4601 DONE;
4602 }
4603 })
4604
4605 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4606 ;; of the machinery.
4607 (define_insn_and_split "*fix_truncsi_1"
4608 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4609 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4610 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4611 && !reload_completed && !reload_in_progress
4612 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4613 "#"
4614 "&& 1"
4615 [(const_int 0)]
4616 {
4617 ix86_optimize_mode_switching = 1;
4618 operands[2] = assign_386_stack_local (HImode, 1);
4619 operands[3] = assign_386_stack_local (HImode, 2);
4620 if (memory_operand (operands[0], VOIDmode))
4621 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4622 operands[2], operands[3]));
4623 else
4624 {
4625 operands[4] = assign_386_stack_local (SImode, 0);
4626 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4627 operands[2], operands[3],
4628 operands[4]));
4629 }
4630 DONE;
4631 }
4632 [(set_attr "type" "fistp")
4633 (set_attr "mode" "SI")])
4634
4635 (define_insn "fix_truncsi_nomemory"
4636 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4637 (fix:SI (match_operand 1 "register_operand" "f,f")))
4638 (use (match_operand:HI 2 "memory_operand" "m,m"))
4639 (use (match_operand:HI 3 "memory_operand" "m,m"))
4640 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4641 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4642 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4643 "#"
4644 [(set_attr "type" "fistp")
4645 (set_attr "mode" "SI")])
4646
4647 (define_insn "fix_truncsi_memory"
4648 [(set (match_operand:SI 0 "memory_operand" "=m")
4649 (fix:SI (match_operand 1 "register_operand" "f")))
4650 (use (match_operand:HI 2 "memory_operand" "m"))
4651 (use (match_operand:HI 3 "memory_operand" "m"))]
4652 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4653 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4654 "* return output_fix_trunc (insn, operands);"
4655 [(set_attr "type" "fistp")
4656 (set_attr "mode" "SI")])
4657
4658 ;; When SSE available, it is always faster to use it!
4659 (define_insn "fix_truncsfsi_sse"
4660 [(set (match_operand:SI 0 "register_operand" "=r,r")
4661 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4662 "TARGET_SSE"
4663 "cvttss2si\t{%1, %0|%0, %1}"
4664 [(set_attr "type" "sseicvt")
4665 (set_attr "mode" "DF")
4666 (set_attr "athlon_decode" "double,vector")])
4667
4668 ;; Avoid vector decoded form of the instruction.
4669 (define_peephole2
4670 [(match_scratch:SF 2 "x")
4671 (set (match_operand:SI 0 "register_operand" "")
4672 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4673 "TARGET_K8 && !optimize_size"
4674 [(set (match_dup 2) (match_dup 1))
4675 (set (match_dup 0) (fix:SI (match_dup 2)))]
4676 "")
4677
4678 (define_insn "fix_truncdfsi_sse"
4679 [(set (match_operand:SI 0 "register_operand" "=r,r")
4680 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4681 "TARGET_SSE2"
4682 "cvttsd2si\t{%1, %0|%0, %1}"
4683 [(set_attr "type" "sseicvt")
4684 (set_attr "mode" "DF")
4685 (set_attr "athlon_decode" "double,vector")])
4686
4687 ;; Avoid vector decoded form of the instruction.
4688 (define_peephole2
4689 [(match_scratch:DF 2 "Y")
4690 (set (match_operand:SI 0 "register_operand" "")
4691 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4692 "TARGET_K8 && !optimize_size"
4693 [(set (match_dup 2) (match_dup 1))
4694 (set (match_dup 0) (fix:SI (match_dup 2)))]
4695 "")
4696
4697 (define_split
4698 [(set (match_operand:SI 0 "register_operand" "")
4699 (fix:SI (match_operand 1 "register_operand" "")))
4700 (use (match_operand:HI 2 "memory_operand" ""))
4701 (use (match_operand:HI 3 "memory_operand" ""))
4702 (clobber (match_operand:SI 4 "memory_operand" ""))]
4703 "reload_completed"
4704 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4705 (use (match_dup 2))
4706 (use (match_dup 3))])
4707 (set (match_dup 0) (match_dup 4))]
4708 "")
4709
4710 (define_split
4711 [(set (match_operand:SI 0 "memory_operand" "")
4712 (fix:SI (match_operand 1 "register_operand" "")))
4713 (use (match_operand:HI 2 "memory_operand" ""))
4714 (use (match_operand:HI 3 "memory_operand" ""))
4715 (clobber (match_operand:SI 4 "memory_operand" ""))]
4716 "reload_completed"
4717 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4718 (use (match_dup 2))
4719 (use (match_dup 3))])]
4720 "")
4721
4722 ;; Signed conversion to HImode.
4723
4724 (define_expand "fix_truncxfhi2"
4725 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4726 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4727 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4728 "")
4729
4730 (define_expand "fix_trunctfhi2"
4731 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4732 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4733 "TARGET_80387"
4734 "")
4735
4736 (define_expand "fix_truncdfhi2"
4737 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4738 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4739 "TARGET_80387 && !TARGET_SSE2"
4740 "")
4741
4742 (define_expand "fix_truncsfhi2"
4743 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4744 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4745 "TARGET_80387 && !TARGET_SSE"
4746 "")
4747
4748 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4749 ;; of the machinery.
4750 (define_insn_and_split "*fix_trunchi_1"
4751 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4752 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4753 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4754 && !reload_completed && !reload_in_progress
4755 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4756 "#"
4757 ""
4758 [(const_int 0)]
4759 {
4760 ix86_optimize_mode_switching = 1;
4761 operands[2] = assign_386_stack_local (HImode, 1);
4762 operands[3] = assign_386_stack_local (HImode, 2);
4763 if (memory_operand (operands[0], VOIDmode))
4764 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4765 operands[2], operands[3]));
4766 else
4767 {
4768 operands[4] = assign_386_stack_local (HImode, 0);
4769 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4770 operands[2], operands[3],
4771 operands[4]));
4772 }
4773 DONE;
4774 }
4775 [(set_attr "type" "fistp")
4776 (set_attr "mode" "HI")])
4777
4778 (define_insn "fix_trunchi_nomemory"
4779 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4780 (fix:HI (match_operand 1 "register_operand" "f,f")))
4781 (use (match_operand:HI 2 "memory_operand" "m,m"))
4782 (use (match_operand:HI 3 "memory_operand" "m,m"))
4783 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4784 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4785 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4786 "#"
4787 [(set_attr "type" "fistp")
4788 (set_attr "mode" "HI")])
4789
4790 (define_insn "fix_trunchi_memory"
4791 [(set (match_operand:HI 0 "memory_operand" "=m")
4792 (fix:HI (match_operand 1 "register_operand" "f")))
4793 (use (match_operand:HI 2 "memory_operand" "m"))
4794 (use (match_operand:HI 3 "memory_operand" "m"))]
4795 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4796 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4797 "* return output_fix_trunc (insn, operands);"
4798 [(set_attr "type" "fistp")
4799 (set_attr "mode" "HI")])
4800
4801 (define_split
4802 [(set (match_operand:HI 0 "memory_operand" "")
4803 (fix:HI (match_operand 1 "register_operand" "")))
4804 (use (match_operand:HI 2 "memory_operand" ""))
4805 (use (match_operand:HI 3 "memory_operand" ""))
4806 (clobber (match_operand:HI 4 "memory_operand" ""))]
4807 "reload_completed"
4808 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4809 (use (match_dup 2))
4810 (use (match_dup 3))])]
4811 "")
4812
4813 (define_split
4814 [(set (match_operand:HI 0 "register_operand" "")
4815 (fix:HI (match_operand 1 "register_operand" "")))
4816 (use (match_operand:HI 2 "memory_operand" ""))
4817 (use (match_operand:HI 3 "memory_operand" ""))
4818 (clobber (match_operand:HI 4 "memory_operand" ""))]
4819 "reload_completed"
4820 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4821 (use (match_dup 2))
4822 (use (match_dup 3))
4823 (clobber (match_dup 4))])
4824 (set (match_dup 0) (match_dup 4))]
4825 "")
4826
4827 ;; %% Not used yet.
4828 (define_insn "x86_fnstcw_1"
4829 [(set (match_operand:HI 0 "memory_operand" "=m")
4830 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4831 "TARGET_80387"
4832 "fnstcw\t%0"
4833 [(set_attr "length" "2")
4834 (set_attr "mode" "HI")
4835 (set_attr "unit" "i387")
4836 (set_attr "ppro_uops" "few")])
4837
4838 (define_insn "x86_fldcw_1"
4839 [(set (reg:HI 18)
4840 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4841 "TARGET_80387"
4842 "fldcw\t%0"
4843 [(set_attr "length" "2")
4844 (set_attr "mode" "HI")
4845 (set_attr "unit" "i387")
4846 (set_attr "athlon_decode" "vector")
4847 (set_attr "ppro_uops" "few")])
4848 \f
4849 ;; Conversion between fixed point and floating point.
4850
4851 ;; Even though we only accept memory inputs, the backend _really_
4852 ;; wants to be able to do this between registers.
4853
4854 (define_expand "floathisf2"
4855 [(set (match_operand:SF 0 "register_operand" "")
4856 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4857 "TARGET_SSE || TARGET_80387"
4858 {
4859 if (TARGET_SSE && TARGET_SSE_MATH)
4860 {
4861 emit_insn (gen_floatsisf2 (operands[0],
4862 convert_to_mode (SImode, operands[1], 0)));
4863 DONE;
4864 }
4865 })
4866
4867 (define_insn "*floathisf2_1"
4868 [(set (match_operand:SF 0 "register_operand" "=f,f")
4869 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4870 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4871 "@
4872 fild%z1\t%1
4873 #"
4874 [(set_attr "type" "fmov,multi")
4875 (set_attr "mode" "SF")
4876 (set_attr "fp_int_src" "true")])
4877
4878 (define_expand "floatsisf2"
4879 [(set (match_operand:SF 0 "register_operand" "")
4880 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4881 "TARGET_SSE || TARGET_80387"
4882 "")
4883
4884 (define_insn "*floatsisf2_i387"
4885 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4886 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4887 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4888 "@
4889 fild%z1\t%1
4890 #
4891 cvtsi2ss\t{%1, %0|%0, %1}
4892 cvtsi2ss\t{%1, %0|%0, %1}"
4893 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4894 (set_attr "mode" "SF")
4895 (set_attr "athlon_decode" "*,*,vector,double")
4896 (set_attr "fp_int_src" "true")])
4897
4898 (define_insn "*floatsisf2_sse"
4899 [(set (match_operand:SF 0 "register_operand" "=x,x")
4900 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4901 "TARGET_SSE"
4902 "cvtsi2ss\t{%1, %0|%0, %1}"
4903 [(set_attr "type" "sseicvt")
4904 (set_attr "mode" "SF")
4905 (set_attr "athlon_decode" "vector,double")
4906 (set_attr "fp_int_src" "true")])
4907
4908 ; Avoid possible reformatting penalty on the destination by first
4909 ; zeroing it out
4910 (define_split
4911 [(set (match_operand:SF 0 "register_operand" "")
4912 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4913 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4914 && SSE_REG_P (operands[0])"
4915 [(const_int 0)]
4916 {
4917 rtx dest;
4918 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4919 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4920 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4921 DONE;
4922 })
4923
4924 (define_expand "floatdisf2"
4925 [(set (match_operand:SF 0 "register_operand" "")
4926 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4927 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4928 "")
4929
4930 (define_insn "*floatdisf2_i387_only"
4931 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4932 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4933 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4934 "@
4935 fild%z1\t%1
4936 #"
4937 [(set_attr "type" "fmov,multi")
4938 (set_attr "mode" "SF")
4939 (set_attr "fp_int_src" "true")])
4940
4941 (define_insn "*floatdisf2_i387"
4942 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4943 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4944 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4945 "@
4946 fild%z1\t%1
4947 #
4948 cvtsi2ss{q}\t{%1, %0|%0, %1}
4949 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4950 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4951 (set_attr "mode" "SF")
4952 (set_attr "athlon_decode" "*,*,vector,double")
4953 (set_attr "fp_int_src" "true")])
4954
4955 (define_insn "*floatdisf2_sse"
4956 [(set (match_operand:SF 0 "register_operand" "=x,x")
4957 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4958 "TARGET_64BIT && TARGET_SSE"
4959 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4960 [(set_attr "type" "sseicvt")
4961 (set_attr "mode" "SF")
4962 (set_attr "athlon_decode" "vector,double")
4963 (set_attr "fp_int_src" "true")])
4964
4965 ; Avoid possible reformatting penalty on the destination by first
4966 ; zeroing it out
4967 (define_split
4968 [(set (match_operand:SF 0 "register_operand" "")
4969 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4970 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4971 && SSE_REG_P (operands[0])"
4972 [(const_int 0)]
4973 {
4974 rtx dest;
4975 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4976 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4977 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4978 DONE;
4979 })
4980
4981 (define_expand "floathidf2"
4982 [(set (match_operand:DF 0 "register_operand" "")
4983 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4984 "TARGET_SSE2 || TARGET_80387"
4985 {
4986 if (TARGET_SSE && TARGET_SSE_MATH)
4987 {
4988 emit_insn (gen_floatsidf2 (operands[0],
4989 convert_to_mode (SImode, operands[1], 0)));
4990 DONE;
4991 }
4992 })
4993
4994 (define_insn "*floathidf2_1"
4995 [(set (match_operand:DF 0 "register_operand" "=f,f")
4996 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4997 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4998 "@
4999 fild%z1\t%1
5000 #"
5001 [(set_attr "type" "fmov,multi")
5002 (set_attr "mode" "DF")
5003 (set_attr "fp_int_src" "true")])
5004
5005 (define_expand "floatsidf2"
5006 [(set (match_operand:DF 0 "register_operand" "")
5007 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
5008 "TARGET_80387 || TARGET_SSE2"
5009 "")
5010
5011 (define_insn "*floatsidf2_i387"
5012 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5013 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
5014 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5015 "@
5016 fild%z1\t%1
5017 #
5018 cvtsi2sd\t{%1, %0|%0, %1}
5019 cvtsi2sd\t{%1, %0|%0, %1}"
5020 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5021 (set_attr "mode" "DF")
5022 (set_attr "athlon_decode" "*,*,double,direct")
5023 (set_attr "fp_int_src" "true")])
5024
5025 (define_insn "*floatsidf2_sse"
5026 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5027 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
5028 "TARGET_SSE2"
5029 "cvtsi2sd\t{%1, %0|%0, %1}"
5030 [(set_attr "type" "sseicvt")
5031 (set_attr "mode" "DF")
5032 (set_attr "athlon_decode" "double,direct")
5033 (set_attr "fp_int_src" "true")])
5034
5035 (define_expand "floatdidf2"
5036 [(set (match_operand:DF 0 "register_operand" "")
5037 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5038 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5039 "")
5040
5041 (define_insn "*floatdidf2_i387_only"
5042 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5043 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5044 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5045 "@
5046 fild%z1\t%1
5047 #"
5048 [(set_attr "type" "fmov,multi")
5049 (set_attr "mode" "DF")
5050 (set_attr "fp_int_src" "true")])
5051
5052 (define_insn "*floatdidf2_i387"
5053 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5054 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
5055 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5056 "@
5057 fild%z1\t%1
5058 #
5059 cvtsi2sd{q}\t{%1, %0|%0, %1}
5060 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5061 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5062 (set_attr "mode" "DF")
5063 (set_attr "athlon_decode" "*,*,double,direct")
5064 (set_attr "fp_int_src" "true")])
5065
5066 (define_insn "*floatdidf2_sse"
5067 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5068 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
5069 "TARGET_SSE2"
5070 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5071 [(set_attr "type" "sseicvt")
5072 (set_attr "mode" "DF")
5073 (set_attr "athlon_decode" "double,direct")
5074 (set_attr "fp_int_src" "true")])
5075
5076 (define_insn "floathixf2"
5077 [(set (match_operand:XF 0 "register_operand" "=f,f")
5078 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5079 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5080 "@
5081 fild%z1\t%1
5082 #"
5083 [(set_attr "type" "fmov,multi")
5084 (set_attr "mode" "XF")
5085 (set_attr "fp_int_src" "true")])
5086
5087 (define_insn "floathitf2"
5088 [(set (match_operand:TF 0 "register_operand" "=f,f")
5089 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5090 "TARGET_80387"
5091 "@
5092 fild%z1\t%1
5093 #"
5094 [(set_attr "type" "fmov,multi")
5095 (set_attr "mode" "XF")
5096 (set_attr "fp_int_src" "true")])
5097
5098 (define_insn "floatsixf2"
5099 [(set (match_operand:XF 0 "register_operand" "=f,f")
5100 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5101 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5102 "@
5103 fild%z1\t%1
5104 #"
5105 [(set_attr "type" "fmov,multi")
5106 (set_attr "mode" "XF")
5107 (set_attr "fp_int_src" "true")])
5108
5109 (define_insn "floatsitf2"
5110 [(set (match_operand:TF 0 "register_operand" "=f,f")
5111 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5112 "TARGET_80387"
5113 "@
5114 fild%z1\t%1
5115 #"
5116 [(set_attr "type" "fmov,multi")
5117 (set_attr "mode" "XF")
5118 (set_attr "fp_int_src" "true")])
5119
5120 (define_insn "floatdixf2"
5121 [(set (match_operand:XF 0 "register_operand" "=f,f")
5122 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5123 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5124 "@
5125 fild%z1\t%1
5126 #"
5127 [(set_attr "type" "fmov,multi")
5128 (set_attr "mode" "XF")
5129 (set_attr "fp_int_src" "true")])
5130
5131 (define_insn "floatditf2"
5132 [(set (match_operand:TF 0 "register_operand" "=f,f")
5133 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5134 "TARGET_80387"
5135 "@
5136 fild%z1\t%1
5137 #"
5138 [(set_attr "type" "fmov,multi")
5139 (set_attr "mode" "XF")
5140 (set_attr "fp_int_src" "true")])
5141
5142 ;; %%% Kill these when reload knows how to do it.
5143 (define_split
5144 [(set (match_operand 0 "fp_register_operand" "")
5145 (float (match_operand 1 "register_operand" "")))]
5146 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5147 [(const_int 0)]
5148 {
5149 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5150 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5151 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5152 ix86_free_from_memory (GET_MODE (operands[1]));
5153 DONE;
5154 })
5155
5156 (define_expand "floatunssisf2"
5157 [(use (match_operand:SF 0 "register_operand" ""))
5158 (use (match_operand:SI 1 "register_operand" ""))]
5159 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
5160 "x86_emit_floatuns (operands); DONE;")
5161
5162 (define_expand "floatunsdisf2"
5163 [(use (match_operand:SF 0 "register_operand" ""))
5164 (use (match_operand:DI 1 "register_operand" ""))]
5165 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
5166 "x86_emit_floatuns (operands); DONE;")
5167
5168 (define_expand "floatunsdidf2"
5169 [(use (match_operand:DF 0 "register_operand" ""))
5170 (use (match_operand:DI 1 "register_operand" ""))]
5171 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
5172 "x86_emit_floatuns (operands); DONE;")
5173 \f
5174 ;; Add instructions
5175
5176 ;; %%% splits for addsidi3
5177 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5178 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5179 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5180
5181 (define_expand "adddi3"
5182 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5183 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5184 (match_operand:DI 2 "x86_64_general_operand" "")))
5185 (clobber (reg:CC 17))]
5186 ""
5187 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5188
5189 (define_insn "*adddi3_1"
5190 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5191 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5192 (match_operand:DI 2 "general_operand" "roiF,riF")))
5193 (clobber (reg:CC 17))]
5194 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5195 "#")
5196
5197 (define_split
5198 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5199 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5200 (match_operand:DI 2 "general_operand" "")))
5201 (clobber (reg:CC 17))]
5202 "!TARGET_64BIT && reload_completed"
5203 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
5204 UNSPEC_ADD_CARRY))
5205 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5206 (parallel [(set (match_dup 3)
5207 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5208 (match_dup 4))
5209 (match_dup 5)))
5210 (clobber (reg:CC 17))])]
5211 "split_di (operands+0, 1, operands+0, operands+3);
5212 split_di (operands+1, 1, operands+1, operands+4);
5213 split_di (operands+2, 1, operands+2, operands+5);")
5214
5215 (define_insn "adddi3_carry_rex64"
5216 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5217 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5218 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5219 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5220 (clobber (reg:CC 17))]
5221 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5222 "adc{q}\t{%2, %0|%0, %2}"
5223 [(set_attr "type" "alu")
5224 (set_attr "pent_pair" "pu")
5225 (set_attr "mode" "DI")
5226 (set_attr "ppro_uops" "few")])
5227
5228 (define_insn "*adddi3_cc_rex64"
5229 [(set (reg:CC 17)
5230 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5231 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5232 UNSPEC_ADD_CARRY))
5233 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5234 (plus:DI (match_dup 1) (match_dup 2)))]
5235 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5236 "add{q}\t{%2, %0|%0, %2}"
5237 [(set_attr "type" "alu")
5238 (set_attr "mode" "DI")])
5239
5240 (define_insn "addqi3_carry"
5241 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
5242 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5243 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5244 (match_operand:QI 2 "general_operand" "ri,rm")))
5245 (clobber (reg:CC 17))]
5246 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5247 "adc{b}\t{%2, %0|%0, %2}"
5248 [(set_attr "type" "alu")
5249 (set_attr "pent_pair" "pu")
5250 (set_attr "mode" "QI")
5251 (set_attr "ppro_uops" "few")])
5252
5253 (define_insn "addhi3_carry"
5254 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5255 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5256 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5257 (match_operand:HI 2 "general_operand" "ri,rm")))
5258 (clobber (reg:CC 17))]
5259 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5260 "adc{w}\t{%2, %0|%0, %2}"
5261 [(set_attr "type" "alu")
5262 (set_attr "pent_pair" "pu")
5263 (set_attr "mode" "HI")
5264 (set_attr "ppro_uops" "few")])
5265
5266 (define_insn "addsi3_carry"
5267 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5268 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5269 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5270 (match_operand:SI 2 "general_operand" "ri,rm")))
5271 (clobber (reg:CC 17))]
5272 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5273 "adc{l}\t{%2, %0|%0, %2}"
5274 [(set_attr "type" "alu")
5275 (set_attr "pent_pair" "pu")
5276 (set_attr "mode" "SI")
5277 (set_attr "ppro_uops" "few")])
5278
5279 (define_insn "*addsi3_carry_zext"
5280 [(set (match_operand:DI 0 "register_operand" "=r")
5281 (zero_extend:DI
5282 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5283 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5284 (match_operand:SI 2 "general_operand" "rim"))))
5285 (clobber (reg:CC 17))]
5286 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5287 "adc{l}\t{%2, %k0|%k0, %2}"
5288 [(set_attr "type" "alu")
5289 (set_attr "pent_pair" "pu")
5290 (set_attr "mode" "SI")
5291 (set_attr "ppro_uops" "few")])
5292
5293 (define_insn "*addsi3_cc"
5294 [(set (reg:CC 17)
5295 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5296 (match_operand:SI 2 "general_operand" "ri,rm")]
5297 UNSPEC_ADD_CARRY))
5298 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5299 (plus:SI (match_dup 1) (match_dup 2)))]
5300 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5301 "add{l}\t{%2, %0|%0, %2}"
5302 [(set_attr "type" "alu")
5303 (set_attr "mode" "SI")])
5304
5305 (define_insn "addqi3_cc"
5306 [(set (reg:CC 17)
5307 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5308 (match_operand:QI 2 "general_operand" "qi,qm")]
5309 UNSPEC_ADD_CARRY))
5310 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5311 (plus:QI (match_dup 1) (match_dup 2)))]
5312 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5313 "add{b}\t{%2, %0|%0, %2}"
5314 [(set_attr "type" "alu")
5315 (set_attr "mode" "QI")])
5316
5317 (define_expand "addsi3"
5318 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5319 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5320 (match_operand:SI 2 "general_operand" "")))
5321 (clobber (reg:CC 17))])]
5322 ""
5323 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5324
5325 (define_insn "*lea_1"
5326 [(set (match_operand:SI 0 "register_operand" "=r")
5327 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5328 "!TARGET_64BIT"
5329 "lea{l}\t{%a1, %0|%0, %a1}"
5330 [(set_attr "type" "lea")
5331 (set_attr "mode" "SI")])
5332
5333 (define_insn "*lea_1_rex64"
5334 [(set (match_operand:SI 0 "register_operand" "=r")
5335 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5336 "TARGET_64BIT"
5337 "lea{l}\t{%a1, %0|%0, %a1}"
5338 [(set_attr "type" "lea")
5339 (set_attr "mode" "SI")])
5340
5341 (define_insn "*lea_1_zext"
5342 [(set (match_operand:DI 0 "register_operand" "=r")
5343 (zero_extend:DI
5344 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5345 "TARGET_64BIT"
5346 "lea{l}\t{%a1, %k0|%k0, %a1}"
5347 [(set_attr "type" "lea")
5348 (set_attr "mode" "SI")])
5349
5350 (define_insn "*lea_2_rex64"
5351 [(set (match_operand:DI 0 "register_operand" "=r")
5352 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5353 "TARGET_64BIT"
5354 "lea{q}\t{%a1, %0|%0, %a1}"
5355 [(set_attr "type" "lea")
5356 (set_attr "mode" "DI")])
5357
5358 ;; The lea patterns for non-Pmodes needs to be matched by several
5359 ;; insns converted to real lea by splitters.
5360
5361 (define_insn_and_split "*lea_general_1"
5362 [(set (match_operand 0 "register_operand" "=r")
5363 (plus (plus (match_operand 1 "index_register_operand" "r")
5364 (match_operand 2 "register_operand" "r"))
5365 (match_operand 3 "immediate_operand" "i")))]
5366 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5367 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5368 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5369 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5370 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5371 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5372 || GET_MODE (operands[3]) == VOIDmode)"
5373 "#"
5374 "&& reload_completed"
5375 [(const_int 0)]
5376 {
5377 rtx pat;
5378 operands[0] = gen_lowpart (SImode, operands[0]);
5379 operands[1] = gen_lowpart (Pmode, operands[1]);
5380 operands[2] = gen_lowpart (Pmode, operands[2]);
5381 operands[3] = gen_lowpart (Pmode, operands[3]);
5382 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5383 operands[3]);
5384 if (Pmode != SImode)
5385 pat = gen_rtx_SUBREG (SImode, pat, 0);
5386 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5387 DONE;
5388 }
5389 [(set_attr "type" "lea")
5390 (set_attr "mode" "SI")])
5391
5392 (define_insn_and_split "*lea_general_1_zext"
5393 [(set (match_operand:DI 0 "register_operand" "=r")
5394 (zero_extend:DI
5395 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5396 (match_operand:SI 2 "register_operand" "r"))
5397 (match_operand:SI 3 "immediate_operand" "i"))))]
5398 "TARGET_64BIT"
5399 "#"
5400 "&& reload_completed"
5401 [(set (match_dup 0)
5402 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5403 (match_dup 2))
5404 (match_dup 3)) 0)))]
5405 {
5406 operands[1] = gen_lowpart (Pmode, operands[1]);
5407 operands[2] = gen_lowpart (Pmode, operands[2]);
5408 operands[3] = gen_lowpart (Pmode, operands[3]);
5409 }
5410 [(set_attr "type" "lea")
5411 (set_attr "mode" "SI")])
5412
5413 (define_insn_and_split "*lea_general_2"
5414 [(set (match_operand 0 "register_operand" "=r")
5415 (plus (mult (match_operand 1 "index_register_operand" "r")
5416 (match_operand 2 "const248_operand" "i"))
5417 (match_operand 3 "nonmemory_operand" "ri")))]
5418 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5419 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5420 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5421 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5422 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5423 || GET_MODE (operands[3]) == VOIDmode)"
5424 "#"
5425 "&& reload_completed"
5426 [(const_int 0)]
5427 {
5428 rtx pat;
5429 operands[0] = gen_lowpart (SImode, operands[0]);
5430 operands[1] = gen_lowpart (Pmode, operands[1]);
5431 operands[3] = gen_lowpart (Pmode, operands[3]);
5432 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5433 operands[3]);
5434 if (Pmode != SImode)
5435 pat = gen_rtx_SUBREG (SImode, pat, 0);
5436 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5437 DONE;
5438 }
5439 [(set_attr "type" "lea")
5440 (set_attr "mode" "SI")])
5441
5442 (define_insn_and_split "*lea_general_2_zext"
5443 [(set (match_operand:DI 0 "register_operand" "=r")
5444 (zero_extend:DI
5445 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5446 (match_operand:SI 2 "const248_operand" "n"))
5447 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5448 "TARGET_64BIT"
5449 "#"
5450 "&& reload_completed"
5451 [(set (match_dup 0)
5452 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5453 (match_dup 2))
5454 (match_dup 3)) 0)))]
5455 {
5456 operands[1] = gen_lowpart (Pmode, operands[1]);
5457 operands[3] = gen_lowpart (Pmode, operands[3]);
5458 }
5459 [(set_attr "type" "lea")
5460 (set_attr "mode" "SI")])
5461
5462 (define_insn_and_split "*lea_general_3"
5463 [(set (match_operand 0 "register_operand" "=r")
5464 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5465 (match_operand 2 "const248_operand" "i"))
5466 (match_operand 3 "register_operand" "r"))
5467 (match_operand 4 "immediate_operand" "i")))]
5468 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5469 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5470 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5471 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5472 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5473 "#"
5474 "&& reload_completed"
5475 [(const_int 0)]
5476 {
5477 rtx pat;
5478 operands[0] = gen_lowpart (SImode, operands[0]);
5479 operands[1] = gen_lowpart (Pmode, operands[1]);
5480 operands[3] = gen_lowpart (Pmode, operands[3]);
5481 operands[4] = gen_lowpart (Pmode, operands[4]);
5482 pat = gen_rtx_PLUS (Pmode,
5483 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5484 operands[2]),
5485 operands[3]),
5486 operands[4]);
5487 if (Pmode != SImode)
5488 pat = gen_rtx_SUBREG (SImode, pat, 0);
5489 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5490 DONE;
5491 }
5492 [(set_attr "type" "lea")
5493 (set_attr "mode" "SI")])
5494
5495 (define_insn_and_split "*lea_general_3_zext"
5496 [(set (match_operand:DI 0 "register_operand" "=r")
5497 (zero_extend:DI
5498 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5499 (match_operand:SI 2 "const248_operand" "n"))
5500 (match_operand:SI 3 "register_operand" "r"))
5501 (match_operand:SI 4 "immediate_operand" "i"))))]
5502 "TARGET_64BIT"
5503 "#"
5504 "&& reload_completed"
5505 [(set (match_dup 0)
5506 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5507 (match_dup 2))
5508 (match_dup 3))
5509 (match_dup 4)) 0)))]
5510 {
5511 operands[1] = gen_lowpart (Pmode, operands[1]);
5512 operands[3] = gen_lowpart (Pmode, operands[3]);
5513 operands[4] = gen_lowpart (Pmode, operands[4]);
5514 }
5515 [(set_attr "type" "lea")
5516 (set_attr "mode" "SI")])
5517
5518 (define_insn "*adddi_1_rex64"
5519 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5520 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5521 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5522 (clobber (reg:CC 17))]
5523 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5524 {
5525 switch (get_attr_type (insn))
5526 {
5527 case TYPE_LEA:
5528 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5529 return "lea{q}\t{%a2, %0|%0, %a2}";
5530
5531 case TYPE_INCDEC:
5532 if (! rtx_equal_p (operands[0], operands[1]))
5533 abort ();
5534 if (operands[2] == const1_rtx)
5535 return "inc{q}\t%0";
5536 else if (operands[2] == constm1_rtx)
5537 return "dec{q}\t%0";
5538 else
5539 abort ();
5540
5541 default:
5542 if (! rtx_equal_p (operands[0], operands[1]))
5543 abort ();
5544
5545 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5546 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5547 if (GET_CODE (operands[2]) == CONST_INT
5548 /* Avoid overflows. */
5549 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5550 && (INTVAL (operands[2]) == 128
5551 || (INTVAL (operands[2]) < 0
5552 && INTVAL (operands[2]) != -128)))
5553 {
5554 operands[2] = GEN_INT (-INTVAL (operands[2]));
5555 return "sub{q}\t{%2, %0|%0, %2}";
5556 }
5557 return "add{q}\t{%2, %0|%0, %2}";
5558 }
5559 }
5560 [(set (attr "type")
5561 (cond [(eq_attr "alternative" "2")
5562 (const_string "lea")
5563 ; Current assemblers are broken and do not allow @GOTOFF in
5564 ; ought but a memory context.
5565 (match_operand:DI 2 "pic_symbolic_operand" "")
5566 (const_string "lea")
5567 (match_operand:DI 2 "incdec_operand" "")
5568 (const_string "incdec")
5569 ]
5570 (const_string "alu")))
5571 (set_attr "mode" "DI")])
5572
5573 ;; Convert lea to the lea pattern to avoid flags dependency.
5574 (define_split
5575 [(set (match_operand:DI 0 "register_operand" "")
5576 (plus:DI (match_operand:DI 1 "register_operand" "")
5577 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5578 (clobber (reg:CC 17))]
5579 "TARGET_64BIT && reload_completed
5580 && true_regnum (operands[0]) != true_regnum (operands[1])"
5581 [(set (match_dup 0)
5582 (plus:DI (match_dup 1)
5583 (match_dup 2)))]
5584 "")
5585
5586 (define_insn "*adddi_2_rex64"
5587 [(set (reg 17)
5588 (compare
5589 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5590 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5591 (const_int 0)))
5592 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5593 (plus:DI (match_dup 1) (match_dup 2)))]
5594 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5595 && ix86_binary_operator_ok (PLUS, DImode, operands)
5596 /* Current assemblers are broken and do not allow @GOTOFF in
5597 ought but a memory context. */
5598 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5599 {
5600 switch (get_attr_type (insn))
5601 {
5602 case TYPE_INCDEC:
5603 if (! rtx_equal_p (operands[0], operands[1]))
5604 abort ();
5605 if (operands[2] == const1_rtx)
5606 return "inc{q}\t%0";
5607 else if (operands[2] == constm1_rtx)
5608 return "dec{q}\t%0";
5609 else
5610 abort ();
5611
5612 default:
5613 if (! rtx_equal_p (operands[0], operands[1]))
5614 abort ();
5615 /* ???? We ought to handle there the 32bit case too
5616 - do we need new constraint? */
5617 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5618 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5619 if (GET_CODE (operands[2]) == CONST_INT
5620 /* Avoid overflows. */
5621 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
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{q}\t{%2, %0|%0, %2}";
5628 }
5629 return "add{q}\t{%2, %0|%0, %2}";
5630 }
5631 }
5632 [(set (attr "type")
5633 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5634 (const_string "incdec")
5635 (const_string "alu")))
5636 (set_attr "mode" "DI")])
5637
5638 (define_insn "*adddi_3_rex64"
5639 [(set (reg 17)
5640 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5641 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5642 (clobber (match_scratch:DI 0 "=r"))]
5643 "TARGET_64BIT
5644 && ix86_match_ccmode (insn, CCZmode)
5645 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5646 /* Current assemblers are broken and do not allow @GOTOFF in
5647 ought but a memory context. */
5648 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5649 {
5650 switch (get_attr_type (insn))
5651 {
5652 case TYPE_INCDEC:
5653 if (! rtx_equal_p (operands[0], operands[1]))
5654 abort ();
5655 if (operands[2] == const1_rtx)
5656 return "inc{q}\t%0";
5657 else if (operands[2] == constm1_rtx)
5658 return "dec{q}\t%0";
5659 else
5660 abort ();
5661
5662 default:
5663 if (! rtx_equal_p (operands[0], operands[1]))
5664 abort ();
5665 /* ???? We ought to handle there the 32bit case too
5666 - do we need new constraint? */
5667 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5668 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5669 if (GET_CODE (operands[2]) == CONST_INT
5670 /* Avoid overflows. */
5671 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5672 && (INTVAL (operands[2]) == 128
5673 || (INTVAL (operands[2]) < 0
5674 && INTVAL (operands[2]) != -128)))
5675 {
5676 operands[2] = GEN_INT (-INTVAL (operands[2]));
5677 return "sub{q}\t{%2, %0|%0, %2}";
5678 }
5679 return "add{q}\t{%2, %0|%0, %2}";
5680 }
5681 }
5682 [(set (attr "type")
5683 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5684 (const_string "incdec")
5685 (const_string "alu")))
5686 (set_attr "mode" "DI")])
5687
5688 ; For comparisons against 1, -1 and 128, we may generate better code
5689 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5690 ; is matched then. We can't accept general immediate, because for
5691 ; case of overflows, the result is messed up.
5692 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5693 ; when negated.
5694 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5695 ; only for comparisons not depending on it.
5696 (define_insn "*adddi_4_rex64"
5697 [(set (reg 17)
5698 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5699 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5700 (clobber (match_scratch:DI 0 "=rm"))]
5701 "TARGET_64BIT
5702 && ix86_match_ccmode (insn, CCGCmode)"
5703 {
5704 switch (get_attr_type (insn))
5705 {
5706 case TYPE_INCDEC:
5707 if (operands[2] == constm1_rtx)
5708 return "inc{q}\t%0";
5709 else if (operands[2] == const1_rtx)
5710 return "dec{q}\t%0";
5711 else
5712 abort();
5713
5714 default:
5715 if (! rtx_equal_p (operands[0], operands[1]))
5716 abort ();
5717 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5718 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5719 if ((INTVAL (operands[2]) == -128
5720 || (INTVAL (operands[2]) > 0
5721 && INTVAL (operands[2]) != 128))
5722 /* Avoid overflows. */
5723 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5724 return "sub{q}\t{%2, %0|%0, %2}";
5725 operands[2] = GEN_INT (-INTVAL (operands[2]));
5726 return "add{q}\t{%2, %0|%0, %2}";
5727 }
5728 }
5729 [(set (attr "type")
5730 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5731 (const_string "incdec")
5732 (const_string "alu")))
5733 (set_attr "mode" "DI")])
5734
5735 (define_insn "*adddi_5_rex64"
5736 [(set (reg 17)
5737 (compare
5738 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5739 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5740 (const_int 0)))
5741 (clobber (match_scratch:DI 0 "=r"))]
5742 "TARGET_64BIT
5743 && ix86_match_ccmode (insn, CCGOCmode)
5744 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5745 /* Current assemblers are broken and do not allow @GOTOFF in
5746 ought but a memory context. */
5747 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5748 {
5749 switch (get_attr_type (insn))
5750 {
5751 case TYPE_INCDEC:
5752 if (! rtx_equal_p (operands[0], operands[1]))
5753 abort ();
5754 if (operands[2] == const1_rtx)
5755 return "inc{q}\t%0";
5756 else if (operands[2] == constm1_rtx)
5757 return "dec{q}\t%0";
5758 else
5759 abort();
5760
5761 default:
5762 if (! rtx_equal_p (operands[0], operands[1]))
5763 abort ();
5764 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5765 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5766 if (GET_CODE (operands[2]) == CONST_INT
5767 /* Avoid overflows. */
5768 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5769 && (INTVAL (operands[2]) == 128
5770 || (INTVAL (operands[2]) < 0
5771 && INTVAL (operands[2]) != -128)))
5772 {
5773 operands[2] = GEN_INT (-INTVAL (operands[2]));
5774 return "sub{q}\t{%2, %0|%0, %2}";
5775 }
5776 return "add{q}\t{%2, %0|%0, %2}";
5777 }
5778 }
5779 [(set (attr "type")
5780 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5781 (const_string "incdec")
5782 (const_string "alu")))
5783 (set_attr "mode" "DI")])
5784
5785
5786 (define_insn "*addsi_1"
5787 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5788 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5789 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5790 (clobber (reg:CC 17))]
5791 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5792 {
5793 switch (get_attr_type (insn))
5794 {
5795 case TYPE_LEA:
5796 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5797 return "lea{l}\t{%a2, %0|%0, %a2}";
5798
5799 case TYPE_INCDEC:
5800 if (! rtx_equal_p (operands[0], operands[1]))
5801 abort ();
5802 if (operands[2] == const1_rtx)
5803 return "inc{l}\t%0";
5804 else if (operands[2] == constm1_rtx)
5805 return "dec{l}\t%0";
5806 else
5807 abort();
5808
5809 default:
5810 if (! rtx_equal_p (operands[0], operands[1]))
5811 abort ();
5812
5813 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5814 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5815 if (GET_CODE (operands[2]) == CONST_INT
5816 && (INTVAL (operands[2]) == 128
5817 || (INTVAL (operands[2]) < 0
5818 && INTVAL (operands[2]) != -128)))
5819 {
5820 operands[2] = GEN_INT (-INTVAL (operands[2]));
5821 return "sub{l}\t{%2, %0|%0, %2}";
5822 }
5823 return "add{l}\t{%2, %0|%0, %2}";
5824 }
5825 }
5826 [(set (attr "type")
5827 (cond [(eq_attr "alternative" "2")
5828 (const_string "lea")
5829 ; Current assemblers are broken and do not allow @GOTOFF in
5830 ; ought but a memory context.
5831 (match_operand:SI 2 "pic_symbolic_operand" "")
5832 (const_string "lea")
5833 (match_operand:SI 2 "incdec_operand" "")
5834 (const_string "incdec")
5835 ]
5836 (const_string "alu")))
5837 (set_attr "mode" "SI")])
5838
5839 ;; Convert lea to the lea pattern to avoid flags dependency.
5840 (define_split
5841 [(set (match_operand 0 "register_operand" "")
5842 (plus (match_operand 1 "register_operand" "")
5843 (match_operand 2 "nonmemory_operand" "")))
5844 (clobber (reg:CC 17))]
5845 "reload_completed
5846 && true_regnum (operands[0]) != true_regnum (operands[1])"
5847 [(const_int 0)]
5848 {
5849 rtx pat;
5850 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5851 may confuse gen_lowpart. */
5852 if (GET_MODE (operands[0]) != Pmode)
5853 {
5854 operands[1] = gen_lowpart (Pmode, operands[1]);
5855 operands[2] = gen_lowpart (Pmode, operands[2]);
5856 }
5857 operands[0] = gen_lowpart (SImode, operands[0]);
5858 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5859 if (Pmode != SImode)
5860 pat = gen_rtx_SUBREG (SImode, pat, 0);
5861 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5862 DONE;
5863 })
5864
5865 ;; It may seem that nonimmediate operand is proper one for operand 1.
5866 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5867 ;; we take care in ix86_binary_operator_ok to not allow two memory
5868 ;; operands so proper swapping will be done in reload. This allow
5869 ;; patterns constructed from addsi_1 to match.
5870 (define_insn "addsi_1_zext"
5871 [(set (match_operand:DI 0 "register_operand" "=r,r")
5872 (zero_extend:DI
5873 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5874 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5875 (clobber (reg:CC 17))]
5876 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5877 {
5878 switch (get_attr_type (insn))
5879 {
5880 case TYPE_LEA:
5881 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5882 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5883
5884 case TYPE_INCDEC:
5885 if (operands[2] == const1_rtx)
5886 return "inc{l}\t%k0";
5887 else if (operands[2] == constm1_rtx)
5888 return "dec{l}\t%k0";
5889 else
5890 abort();
5891
5892 default:
5893 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5894 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5895 if (GET_CODE (operands[2]) == CONST_INT
5896 && (INTVAL (operands[2]) == 128
5897 || (INTVAL (operands[2]) < 0
5898 && INTVAL (operands[2]) != -128)))
5899 {
5900 operands[2] = GEN_INT (-INTVAL (operands[2]));
5901 return "sub{l}\t{%2, %k0|%k0, %2}";
5902 }
5903 return "add{l}\t{%2, %k0|%k0, %2}";
5904 }
5905 }
5906 [(set (attr "type")
5907 (cond [(eq_attr "alternative" "1")
5908 (const_string "lea")
5909 ; Current assemblers are broken and do not allow @GOTOFF in
5910 ; ought but a memory context.
5911 (match_operand:SI 2 "pic_symbolic_operand" "")
5912 (const_string "lea")
5913 (match_operand:SI 2 "incdec_operand" "")
5914 (const_string "incdec")
5915 ]
5916 (const_string "alu")))
5917 (set_attr "mode" "SI")])
5918
5919 ;; Convert lea to the lea pattern to avoid flags dependency.
5920 (define_split
5921 [(set (match_operand:DI 0 "register_operand" "")
5922 (zero_extend:DI
5923 (plus:SI (match_operand:SI 1 "register_operand" "")
5924 (match_operand:SI 2 "nonmemory_operand" ""))))
5925 (clobber (reg:CC 17))]
5926 "TARGET_64BIT && reload_completed
5927 && true_regnum (operands[0]) != true_regnum (operands[1])"
5928 [(set (match_dup 0)
5929 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5930 {
5931 operands[1] = gen_lowpart (Pmode, operands[1]);
5932 operands[2] = gen_lowpart (Pmode, operands[2]);
5933 })
5934
5935 (define_insn "*addsi_2"
5936 [(set (reg 17)
5937 (compare
5938 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5939 (match_operand:SI 2 "general_operand" "rmni,rni"))
5940 (const_int 0)))
5941 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5942 (plus:SI (match_dup 1) (match_dup 2)))]
5943 "ix86_match_ccmode (insn, CCGOCmode)
5944 && ix86_binary_operator_ok (PLUS, SImode, operands)
5945 /* Current assemblers are broken and do not allow @GOTOFF in
5946 ought but a memory context. */
5947 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5948 {
5949 switch (get_attr_type (insn))
5950 {
5951 case TYPE_INCDEC:
5952 if (! rtx_equal_p (operands[0], operands[1]))
5953 abort ();
5954 if (operands[2] == const1_rtx)
5955 return "inc{l}\t%0";
5956 else if (operands[2] == constm1_rtx)
5957 return "dec{l}\t%0";
5958 else
5959 abort();
5960
5961 default:
5962 if (! rtx_equal_p (operands[0], operands[1]))
5963 abort ();
5964 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5965 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5966 if (GET_CODE (operands[2]) == CONST_INT
5967 && (INTVAL (operands[2]) == 128
5968 || (INTVAL (operands[2]) < 0
5969 && INTVAL (operands[2]) != -128)))
5970 {
5971 operands[2] = GEN_INT (-INTVAL (operands[2]));
5972 return "sub{l}\t{%2, %0|%0, %2}";
5973 }
5974 return "add{l}\t{%2, %0|%0, %2}";
5975 }
5976 }
5977 [(set (attr "type")
5978 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5979 (const_string "incdec")
5980 (const_string "alu")))
5981 (set_attr "mode" "SI")])
5982
5983 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5984 (define_insn "*addsi_2_zext"
5985 [(set (reg 17)
5986 (compare
5987 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5988 (match_operand:SI 2 "general_operand" "rmni"))
5989 (const_int 0)))
5990 (set (match_operand:DI 0 "register_operand" "=r")
5991 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5992 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5993 && ix86_binary_operator_ok (PLUS, SImode, operands)
5994 /* Current assemblers are broken and do not allow @GOTOFF in
5995 ought but a memory context. */
5996 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5997 {
5998 switch (get_attr_type (insn))
5999 {
6000 case TYPE_INCDEC:
6001 if (operands[2] == const1_rtx)
6002 return "inc{l}\t%k0";
6003 else if (operands[2] == constm1_rtx)
6004 return "dec{l}\t%k0";
6005 else
6006 abort();
6007
6008 default:
6009 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6011 if (GET_CODE (operands[2]) == CONST_INT
6012 && (INTVAL (operands[2]) == 128
6013 || (INTVAL (operands[2]) < 0
6014 && INTVAL (operands[2]) != -128)))
6015 {
6016 operands[2] = GEN_INT (-INTVAL (operands[2]));
6017 return "sub{l}\t{%2, %k0|%k0, %2}";
6018 }
6019 return "add{l}\t{%2, %k0|%k0, %2}";
6020 }
6021 }
6022 [(set (attr "type")
6023 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6024 (const_string "incdec")
6025 (const_string "alu")))
6026 (set_attr "mode" "SI")])
6027
6028 (define_insn "*addsi_3"
6029 [(set (reg 17)
6030 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6031 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6032 (clobber (match_scratch:SI 0 "=r"))]
6033 "ix86_match_ccmode (insn, CCZmode)
6034 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6035 /* Current assemblers are broken and do not allow @GOTOFF in
6036 ought but a memory context. */
6037 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6038 {
6039 switch (get_attr_type (insn))
6040 {
6041 case TYPE_INCDEC:
6042 if (! rtx_equal_p (operands[0], operands[1]))
6043 abort ();
6044 if (operands[2] == const1_rtx)
6045 return "inc{l}\t%0";
6046 else if (operands[2] == constm1_rtx)
6047 return "dec{l}\t%0";
6048 else
6049 abort();
6050
6051 default:
6052 if (! rtx_equal_p (operands[0], operands[1]))
6053 abort ();
6054 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6055 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6056 if (GET_CODE (operands[2]) == CONST_INT
6057 && (INTVAL (operands[2]) == 128
6058 || (INTVAL (operands[2]) < 0
6059 && INTVAL (operands[2]) != -128)))
6060 {
6061 operands[2] = GEN_INT (-INTVAL (operands[2]));
6062 return "sub{l}\t{%2, %0|%0, %2}";
6063 }
6064 return "add{l}\t{%2, %0|%0, %2}";
6065 }
6066 }
6067 [(set (attr "type")
6068 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6069 (const_string "incdec")
6070 (const_string "alu")))
6071 (set_attr "mode" "SI")])
6072
6073 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6074 (define_insn "*addsi_3_zext"
6075 [(set (reg 17)
6076 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6077 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6078 (set (match_operand:DI 0 "register_operand" "=r")
6079 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6080 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6081 && ix86_binary_operator_ok (PLUS, SImode, operands)
6082 /* Current assemblers are broken and do not allow @GOTOFF in
6083 ought but a memory context. */
6084 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6085 {
6086 switch (get_attr_type (insn))
6087 {
6088 case TYPE_INCDEC:
6089 if (operands[2] == const1_rtx)
6090 return "inc{l}\t%k0";
6091 else if (operands[2] == constm1_rtx)
6092 return "dec{l}\t%k0";
6093 else
6094 abort();
6095
6096 default:
6097 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6098 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6099 if (GET_CODE (operands[2]) == CONST_INT
6100 && (INTVAL (operands[2]) == 128
6101 || (INTVAL (operands[2]) < 0
6102 && INTVAL (operands[2]) != -128)))
6103 {
6104 operands[2] = GEN_INT (-INTVAL (operands[2]));
6105 return "sub{l}\t{%2, %k0|%k0, %2}";
6106 }
6107 return "add{l}\t{%2, %k0|%k0, %2}";
6108 }
6109 }
6110 [(set (attr "type")
6111 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6112 (const_string "incdec")
6113 (const_string "alu")))
6114 (set_attr "mode" "SI")])
6115
6116 ; For comparisons against 1, -1 and 128, we may generate better code
6117 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6118 ; is matched then. We can't accept general immediate, because for
6119 ; case of overflows, the result is messed up.
6120 ; This pattern also don't hold of 0x80000000, since the value overflows
6121 ; when negated.
6122 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6123 ; only for comparisons not depending on it.
6124 (define_insn "*addsi_4"
6125 [(set (reg 17)
6126 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6127 (match_operand:SI 2 "const_int_operand" "n")))
6128 (clobber (match_scratch:SI 0 "=rm"))]
6129 "ix86_match_ccmode (insn, CCGCmode)
6130 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6131 {
6132 switch (get_attr_type (insn))
6133 {
6134 case TYPE_INCDEC:
6135 if (operands[2] == constm1_rtx)
6136 return "inc{l}\t%0";
6137 else if (operands[2] == const1_rtx)
6138 return "dec{l}\t%0";
6139 else
6140 abort();
6141
6142 default:
6143 if (! rtx_equal_p (operands[0], operands[1]))
6144 abort ();
6145 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6146 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6147 if ((INTVAL (operands[2]) == -128
6148 || (INTVAL (operands[2]) > 0
6149 && INTVAL (operands[2]) != 128)))
6150 return "sub{l}\t{%2, %0|%0, %2}";
6151 operands[2] = GEN_INT (-INTVAL (operands[2]));
6152 return "add{l}\t{%2, %0|%0, %2}";
6153 }
6154 }
6155 [(set (attr "type")
6156 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6157 (const_string "incdec")
6158 (const_string "alu")))
6159 (set_attr "mode" "SI")])
6160
6161 (define_insn "*addsi_5"
6162 [(set (reg 17)
6163 (compare
6164 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6165 (match_operand:SI 2 "general_operand" "rmni"))
6166 (const_int 0)))
6167 (clobber (match_scratch:SI 0 "=r"))]
6168 "ix86_match_ccmode (insn, CCGOCmode)
6169 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6170 /* Current assemblers are broken and do not allow @GOTOFF in
6171 ought but a memory context. */
6172 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6173 {
6174 switch (get_attr_type (insn))
6175 {
6176 case TYPE_INCDEC:
6177 if (! rtx_equal_p (operands[0], operands[1]))
6178 abort ();
6179 if (operands[2] == const1_rtx)
6180 return "inc{l}\t%0";
6181 else if (operands[2] == constm1_rtx)
6182 return "dec{l}\t%0";
6183 else
6184 abort();
6185
6186 default:
6187 if (! rtx_equal_p (operands[0], operands[1]))
6188 abort ();
6189 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6190 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6191 if (GET_CODE (operands[2]) == CONST_INT
6192 && (INTVAL (operands[2]) == 128
6193 || (INTVAL (operands[2]) < 0
6194 && INTVAL (operands[2]) != -128)))
6195 {
6196 operands[2] = GEN_INT (-INTVAL (operands[2]));
6197 return "sub{l}\t{%2, %0|%0, %2}";
6198 }
6199 return "add{l}\t{%2, %0|%0, %2}";
6200 }
6201 }
6202 [(set (attr "type")
6203 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6204 (const_string "incdec")
6205 (const_string "alu")))
6206 (set_attr "mode" "SI")])
6207
6208 (define_expand "addhi3"
6209 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6210 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6211 (match_operand:HI 2 "general_operand" "")))
6212 (clobber (reg:CC 17))])]
6213 "TARGET_HIMODE_MATH"
6214 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6215
6216 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6217 ;; type optimizations enabled by define-splits. This is not important
6218 ;; for PII, and in fact harmful because of partial register stalls.
6219
6220 (define_insn "*addhi_1_lea"
6221 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6222 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6223 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6224 (clobber (reg:CC 17))]
6225 "!TARGET_PARTIAL_REG_STALL
6226 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6227 {
6228 switch (get_attr_type (insn))
6229 {
6230 case TYPE_LEA:
6231 return "#";
6232 case TYPE_INCDEC:
6233 if (operands[2] == const1_rtx)
6234 return "inc{w}\t%0";
6235 else if (operands[2] == constm1_rtx)
6236 return "dec{w}\t%0";
6237 abort();
6238
6239 default:
6240 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6241 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6242 if (GET_CODE (operands[2]) == CONST_INT
6243 && (INTVAL (operands[2]) == 128
6244 || (INTVAL (operands[2]) < 0
6245 && INTVAL (operands[2]) != -128)))
6246 {
6247 operands[2] = GEN_INT (-INTVAL (operands[2]));
6248 return "sub{w}\t{%2, %0|%0, %2}";
6249 }
6250 return "add{w}\t{%2, %0|%0, %2}";
6251 }
6252 }
6253 [(set (attr "type")
6254 (if_then_else (eq_attr "alternative" "2")
6255 (const_string "lea")
6256 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6257 (const_string "incdec")
6258 (const_string "alu"))))
6259 (set_attr "mode" "HI,HI,SI")])
6260
6261 (define_insn "*addhi_1"
6262 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6263 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6264 (match_operand:HI 2 "general_operand" "ri,rm")))
6265 (clobber (reg:CC 17))]
6266 "TARGET_PARTIAL_REG_STALL
6267 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6268 {
6269 switch (get_attr_type (insn))
6270 {
6271 case TYPE_INCDEC:
6272 if (operands[2] == const1_rtx)
6273 return "inc{w}\t%0";
6274 else if (operands[2] == constm1_rtx)
6275 return "dec{w}\t%0";
6276 abort();
6277
6278 default:
6279 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6280 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6281 if (GET_CODE (operands[2]) == CONST_INT
6282 && (INTVAL (operands[2]) == 128
6283 || (INTVAL (operands[2]) < 0
6284 && INTVAL (operands[2]) != -128)))
6285 {
6286 operands[2] = GEN_INT (-INTVAL (operands[2]));
6287 return "sub{w}\t{%2, %0|%0, %2}";
6288 }
6289 return "add{w}\t{%2, %0|%0, %2}";
6290 }
6291 }
6292 [(set (attr "type")
6293 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6294 (const_string "incdec")
6295 (const_string "alu")))
6296 (set_attr "mode" "HI")])
6297
6298 (define_insn "*addhi_2"
6299 [(set (reg 17)
6300 (compare
6301 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6302 (match_operand:HI 2 "general_operand" "rmni,rni"))
6303 (const_int 0)))
6304 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6305 (plus:HI (match_dup 1) (match_dup 2)))]
6306 "ix86_match_ccmode (insn, CCGOCmode)
6307 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6308 {
6309 switch (get_attr_type (insn))
6310 {
6311 case TYPE_INCDEC:
6312 if (operands[2] == const1_rtx)
6313 return "inc{w}\t%0";
6314 else if (operands[2] == constm1_rtx)
6315 return "dec{w}\t%0";
6316 abort();
6317
6318 default:
6319 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6320 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6321 if (GET_CODE (operands[2]) == CONST_INT
6322 && (INTVAL (operands[2]) == 128
6323 || (INTVAL (operands[2]) < 0
6324 && INTVAL (operands[2]) != -128)))
6325 {
6326 operands[2] = GEN_INT (-INTVAL (operands[2]));
6327 return "sub{w}\t{%2, %0|%0, %2}";
6328 }
6329 return "add{w}\t{%2, %0|%0, %2}";
6330 }
6331 }
6332 [(set (attr "type")
6333 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6334 (const_string "incdec")
6335 (const_string "alu")))
6336 (set_attr "mode" "HI")])
6337
6338 (define_insn "*addhi_3"
6339 [(set (reg 17)
6340 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6341 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6342 (clobber (match_scratch:HI 0 "=r"))]
6343 "ix86_match_ccmode (insn, CCZmode)
6344 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6345 {
6346 switch (get_attr_type (insn))
6347 {
6348 case TYPE_INCDEC:
6349 if (operands[2] == const1_rtx)
6350 return "inc{w}\t%0";
6351 else if (operands[2] == constm1_rtx)
6352 return "dec{w}\t%0";
6353 abort();
6354
6355 default:
6356 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6357 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6358 if (GET_CODE (operands[2]) == CONST_INT
6359 && (INTVAL (operands[2]) == 128
6360 || (INTVAL (operands[2]) < 0
6361 && INTVAL (operands[2]) != -128)))
6362 {
6363 operands[2] = GEN_INT (-INTVAL (operands[2]));
6364 return "sub{w}\t{%2, %0|%0, %2}";
6365 }
6366 return "add{w}\t{%2, %0|%0, %2}";
6367 }
6368 }
6369 [(set (attr "type")
6370 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6371 (const_string "incdec")
6372 (const_string "alu")))
6373 (set_attr "mode" "HI")])
6374
6375 ; See comments above addsi_3_imm for details.
6376 (define_insn "*addhi_4"
6377 [(set (reg 17)
6378 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6379 (match_operand:HI 2 "const_int_operand" "n")))
6380 (clobber (match_scratch:HI 0 "=rm"))]
6381 "ix86_match_ccmode (insn, CCGCmode)
6382 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6383 {
6384 switch (get_attr_type (insn))
6385 {
6386 case TYPE_INCDEC:
6387 if (operands[2] == constm1_rtx)
6388 return "inc{w}\t%0";
6389 else if (operands[2] == const1_rtx)
6390 return "dec{w}\t%0";
6391 else
6392 abort();
6393
6394 default:
6395 if (! rtx_equal_p (operands[0], operands[1]))
6396 abort ();
6397 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6398 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6399 if ((INTVAL (operands[2]) == -128
6400 || (INTVAL (operands[2]) > 0
6401 && INTVAL (operands[2]) != 128)))
6402 return "sub{w}\t{%2, %0|%0, %2}";
6403 operands[2] = GEN_INT (-INTVAL (operands[2]));
6404 return "add{w}\t{%2, %0|%0, %2}";
6405 }
6406 }
6407 [(set (attr "type")
6408 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6409 (const_string "incdec")
6410 (const_string "alu")))
6411 (set_attr "mode" "SI")])
6412
6413
6414 (define_insn "*addhi_5"
6415 [(set (reg 17)
6416 (compare
6417 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6418 (match_operand:HI 2 "general_operand" "rmni"))
6419 (const_int 0)))
6420 (clobber (match_scratch:HI 0 "=r"))]
6421 "ix86_match_ccmode (insn, CCGOCmode)
6422 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6423 {
6424 switch (get_attr_type (insn))
6425 {
6426 case TYPE_INCDEC:
6427 if (operands[2] == const1_rtx)
6428 return "inc{w}\t%0";
6429 else if (operands[2] == constm1_rtx)
6430 return "dec{w}\t%0";
6431 abort();
6432
6433 default:
6434 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6435 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6436 if (GET_CODE (operands[2]) == CONST_INT
6437 && (INTVAL (operands[2]) == 128
6438 || (INTVAL (operands[2]) < 0
6439 && INTVAL (operands[2]) != -128)))
6440 {
6441 operands[2] = GEN_INT (-INTVAL (operands[2]));
6442 return "sub{w}\t{%2, %0|%0, %2}";
6443 }
6444 return "add{w}\t{%2, %0|%0, %2}";
6445 }
6446 }
6447 [(set (attr "type")
6448 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6449 (const_string "incdec")
6450 (const_string "alu")))
6451 (set_attr "mode" "HI")])
6452
6453 (define_expand "addqi3"
6454 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6455 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6456 (match_operand:QI 2 "general_operand" "")))
6457 (clobber (reg:CC 17))])]
6458 "TARGET_QIMODE_MATH"
6459 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6460
6461 ;; %%% Potential partial reg stall on alternative 2. What to do?
6462 (define_insn "*addqi_1_lea"
6463 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6464 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6465 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6466 (clobber (reg:CC 17))]
6467 "!TARGET_PARTIAL_REG_STALL
6468 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6469 {
6470 int widen = (which_alternative == 2);
6471 switch (get_attr_type (insn))
6472 {
6473 case TYPE_LEA:
6474 return "#";
6475 case TYPE_INCDEC:
6476 if (operands[2] == const1_rtx)
6477 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6478 else if (operands[2] == constm1_rtx)
6479 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6480 abort();
6481
6482 default:
6483 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6484 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6485 if (GET_CODE (operands[2]) == CONST_INT
6486 && (INTVAL (operands[2]) == 128
6487 || (INTVAL (operands[2]) < 0
6488 && INTVAL (operands[2]) != -128)))
6489 {
6490 operands[2] = GEN_INT (-INTVAL (operands[2]));
6491 if (widen)
6492 return "sub{l}\t{%2, %k0|%k0, %2}";
6493 else
6494 return "sub{b}\t{%2, %0|%0, %2}";
6495 }
6496 if (widen)
6497 return "add{l}\t{%k2, %k0|%k0, %k2}";
6498 else
6499 return "add{b}\t{%2, %0|%0, %2}";
6500 }
6501 }
6502 [(set (attr "type")
6503 (if_then_else (eq_attr "alternative" "3")
6504 (const_string "lea")
6505 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6506 (const_string "incdec")
6507 (const_string "alu"))))
6508 (set_attr "mode" "QI,QI,SI,SI")])
6509
6510 (define_insn "*addqi_1"
6511 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6512 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6513 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6514 (clobber (reg:CC 17))]
6515 "TARGET_PARTIAL_REG_STALL
6516 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6517 {
6518 int widen = (which_alternative == 2);
6519 switch (get_attr_type (insn))
6520 {
6521 case TYPE_INCDEC:
6522 if (operands[2] == const1_rtx)
6523 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6524 else if (operands[2] == constm1_rtx)
6525 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6526 abort();
6527
6528 default:
6529 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6530 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6531 if (GET_CODE (operands[2]) == CONST_INT
6532 && (INTVAL (operands[2]) == 128
6533 || (INTVAL (operands[2]) < 0
6534 && INTVAL (operands[2]) != -128)))
6535 {
6536 operands[2] = GEN_INT (-INTVAL (operands[2]));
6537 if (widen)
6538 return "sub{l}\t{%2, %k0|%k0, %2}";
6539 else
6540 return "sub{b}\t{%2, %0|%0, %2}";
6541 }
6542 if (widen)
6543 return "add{l}\t{%k2, %k0|%k0, %k2}";
6544 else
6545 return "add{b}\t{%2, %0|%0, %2}";
6546 }
6547 }
6548 [(set (attr "type")
6549 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6550 (const_string "incdec")
6551 (const_string "alu")))
6552 (set_attr "mode" "QI,QI,SI")])
6553
6554 (define_insn "*addqi_1_slp"
6555 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6556 (plus:QI (match_dup 0)
6557 (match_operand:QI 1 "general_operand" "qn,qnm")))
6558 (clobber (reg:CC 17))]
6559 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6560 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6561 {
6562 switch (get_attr_type (insn))
6563 {
6564 case TYPE_INCDEC:
6565 if (operands[1] == const1_rtx)
6566 return "inc{b}\t%0";
6567 else if (operands[1] == constm1_rtx)
6568 return "dec{b}\t%0";
6569 abort();
6570
6571 default:
6572 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6573 if (GET_CODE (operands[1]) == CONST_INT
6574 && INTVAL (operands[1]) < 0)
6575 {
6576 operands[2] = GEN_INT (-INTVAL (operands[2]));
6577 return "sub{b}\t{%1, %0|%0, %1}";
6578 }
6579 return "add{b}\t{%1, %0|%0, %1}";
6580 }
6581 }
6582 [(set (attr "type")
6583 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6584 (const_string "incdec")
6585 (const_string "alu1")))
6586 (set_attr "mode" "QI")])
6587
6588 (define_insn "*addqi_2"
6589 [(set (reg 17)
6590 (compare
6591 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6592 (match_operand:QI 2 "general_operand" "qmni,qni"))
6593 (const_int 0)))
6594 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6595 (plus:QI (match_dup 1) (match_dup 2)))]
6596 "ix86_match_ccmode (insn, CCGOCmode)
6597 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6598 {
6599 switch (get_attr_type (insn))
6600 {
6601 case TYPE_INCDEC:
6602 if (operands[2] == const1_rtx)
6603 return "inc{b}\t%0";
6604 else if (operands[2] == constm1_rtx
6605 || (GET_CODE (operands[2]) == CONST_INT
6606 && INTVAL (operands[2]) == 255))
6607 return "dec{b}\t%0";
6608 abort();
6609
6610 default:
6611 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6612 if (GET_CODE (operands[2]) == CONST_INT
6613 && INTVAL (operands[2]) < 0)
6614 {
6615 operands[2] = GEN_INT (-INTVAL (operands[2]));
6616 return "sub{b}\t{%2, %0|%0, %2}";
6617 }
6618 return "add{b}\t{%2, %0|%0, %2}";
6619 }
6620 }
6621 [(set (attr "type")
6622 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6623 (const_string "incdec")
6624 (const_string "alu")))
6625 (set_attr "mode" "QI")])
6626
6627 (define_insn "*addqi_3"
6628 [(set (reg 17)
6629 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6630 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6631 (clobber (match_scratch:QI 0 "=q"))]
6632 "ix86_match_ccmode (insn, CCZmode)
6633 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6634 {
6635 switch (get_attr_type (insn))
6636 {
6637 case TYPE_INCDEC:
6638 if (operands[2] == const1_rtx)
6639 return "inc{b}\t%0";
6640 else if (operands[2] == constm1_rtx
6641 || (GET_CODE (operands[2]) == CONST_INT
6642 && INTVAL (operands[2]) == 255))
6643 return "dec{b}\t%0";
6644 abort();
6645
6646 default:
6647 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6648 if (GET_CODE (operands[2]) == CONST_INT
6649 && INTVAL (operands[2]) < 0)
6650 {
6651 operands[2] = GEN_INT (-INTVAL (operands[2]));
6652 return "sub{b}\t{%2, %0|%0, %2}";
6653 }
6654 return "add{b}\t{%2, %0|%0, %2}";
6655 }
6656 }
6657 [(set (attr "type")
6658 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6659 (const_string "incdec")
6660 (const_string "alu")))
6661 (set_attr "mode" "QI")])
6662
6663 ; See comments above addsi_3_imm for details.
6664 (define_insn "*addqi_4"
6665 [(set (reg 17)
6666 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6667 (match_operand:QI 2 "const_int_operand" "n")))
6668 (clobber (match_scratch:QI 0 "=qm"))]
6669 "ix86_match_ccmode (insn, CCGCmode)
6670 && (INTVAL (operands[2]) & 0xff) != 0x80"
6671 {
6672 switch (get_attr_type (insn))
6673 {
6674 case TYPE_INCDEC:
6675 if (operands[2] == constm1_rtx
6676 || (GET_CODE (operands[2]) == CONST_INT
6677 && INTVAL (operands[2]) == 255))
6678 return "inc{b}\t%0";
6679 else if (operands[2] == const1_rtx)
6680 return "dec{b}\t%0";
6681 else
6682 abort();
6683
6684 default:
6685 if (! rtx_equal_p (operands[0], operands[1]))
6686 abort ();
6687 if (INTVAL (operands[2]) < 0)
6688 {
6689 operands[2] = GEN_INT (-INTVAL (operands[2]));
6690 return "add{b}\t{%2, %0|%0, %2}";
6691 }
6692 return "sub{b}\t{%2, %0|%0, %2}";
6693 }
6694 }
6695 [(set (attr "type")
6696 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6697 (const_string "incdec")
6698 (const_string "alu")))
6699 (set_attr "mode" "QI")])
6700
6701
6702 (define_insn "*addqi_5"
6703 [(set (reg 17)
6704 (compare
6705 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6706 (match_operand:QI 2 "general_operand" "qmni"))
6707 (const_int 0)))
6708 (clobber (match_scratch:QI 0 "=q"))]
6709 "ix86_match_ccmode (insn, CCGOCmode)
6710 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6711 {
6712 switch (get_attr_type (insn))
6713 {
6714 case TYPE_INCDEC:
6715 if (operands[2] == const1_rtx)
6716 return "inc{b}\t%0";
6717 else if (operands[2] == constm1_rtx
6718 || (GET_CODE (operands[2]) == CONST_INT
6719 && INTVAL (operands[2]) == 255))
6720 return "dec{b}\t%0";
6721 abort();
6722
6723 default:
6724 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6725 if (GET_CODE (operands[2]) == CONST_INT
6726 && INTVAL (operands[2]) < 0)
6727 {
6728 operands[2] = GEN_INT (-INTVAL (operands[2]));
6729 return "sub{b}\t{%2, %0|%0, %2}";
6730 }
6731 return "add{b}\t{%2, %0|%0, %2}";
6732 }
6733 }
6734 [(set (attr "type")
6735 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6736 (const_string "incdec")
6737 (const_string "alu")))
6738 (set_attr "mode" "QI")])
6739
6740
6741 (define_insn "addqi_ext_1"
6742 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6743 (const_int 8)
6744 (const_int 8))
6745 (plus:SI
6746 (zero_extract:SI
6747 (match_operand 1 "ext_register_operand" "0")
6748 (const_int 8)
6749 (const_int 8))
6750 (match_operand:QI 2 "general_operand" "Qmn")))
6751 (clobber (reg:CC 17))]
6752 "!TARGET_64BIT"
6753 {
6754 switch (get_attr_type (insn))
6755 {
6756 case TYPE_INCDEC:
6757 if (operands[2] == const1_rtx)
6758 return "inc{b}\t%h0";
6759 else if (operands[2] == constm1_rtx
6760 || (GET_CODE (operands[2]) == CONST_INT
6761 && INTVAL (operands[2]) == 255))
6762 return "dec{b}\t%h0";
6763 abort();
6764
6765 default:
6766 return "add{b}\t{%2, %h0|%h0, %2}";
6767 }
6768 }
6769 [(set (attr "type")
6770 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6771 (const_string "incdec")
6772 (const_string "alu")))
6773 (set_attr "mode" "QI")])
6774
6775 (define_insn "*addqi_ext_1_rex64"
6776 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6777 (const_int 8)
6778 (const_int 8))
6779 (plus:SI
6780 (zero_extract:SI
6781 (match_operand 1 "ext_register_operand" "0")
6782 (const_int 8)
6783 (const_int 8))
6784 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6785 (clobber (reg:CC 17))]
6786 "TARGET_64BIT"
6787 {
6788 switch (get_attr_type (insn))
6789 {
6790 case TYPE_INCDEC:
6791 if (operands[2] == const1_rtx)
6792 return "inc{b}\t%h0";
6793 else if (operands[2] == constm1_rtx
6794 || (GET_CODE (operands[2]) == CONST_INT
6795 && INTVAL (operands[2]) == 255))
6796 return "dec{b}\t%h0";
6797 abort();
6798
6799 default:
6800 return "add{b}\t{%2, %h0|%h0, %2}";
6801 }
6802 }
6803 [(set (attr "type")
6804 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6805 (const_string "incdec")
6806 (const_string "alu")))
6807 (set_attr "mode" "QI")])
6808
6809 (define_insn "*addqi_ext_2"
6810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6811 (const_int 8)
6812 (const_int 8))
6813 (plus:SI
6814 (zero_extract:SI
6815 (match_operand 1 "ext_register_operand" "%0")
6816 (const_int 8)
6817 (const_int 8))
6818 (zero_extract:SI
6819 (match_operand 2 "ext_register_operand" "Q")
6820 (const_int 8)
6821 (const_int 8))))
6822 (clobber (reg:CC 17))]
6823 ""
6824 "add{b}\t{%h2, %h0|%h0, %h2}"
6825 [(set_attr "type" "alu")
6826 (set_attr "mode" "QI")])
6827
6828 ;; The patterns that match these are at the end of this file.
6829
6830 (define_expand "addxf3"
6831 [(set (match_operand:XF 0 "register_operand" "")
6832 (plus:XF (match_operand:XF 1 "register_operand" "")
6833 (match_operand:XF 2 "register_operand" "")))]
6834 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
6835 "")
6836
6837 (define_expand "addtf3"
6838 [(set (match_operand:TF 0 "register_operand" "")
6839 (plus:TF (match_operand:TF 1 "register_operand" "")
6840 (match_operand:TF 2 "register_operand" "")))]
6841 "TARGET_80387"
6842 "")
6843
6844 (define_expand "adddf3"
6845 [(set (match_operand:DF 0 "register_operand" "")
6846 (plus:DF (match_operand:DF 1 "register_operand" "")
6847 (match_operand:DF 2 "nonimmediate_operand" "")))]
6848 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6849 "")
6850
6851 (define_expand "addsf3"
6852 [(set (match_operand:SF 0 "register_operand" "")
6853 (plus:SF (match_operand:SF 1 "register_operand" "")
6854 (match_operand:SF 2 "nonimmediate_operand" "")))]
6855 "TARGET_80387 || TARGET_SSE_MATH"
6856 "")
6857 \f
6858 ;; Subtract instructions
6859
6860 ;; %%% splits for subsidi3
6861
6862 (define_expand "subdi3"
6863 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6864 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6865 (match_operand:DI 2 "x86_64_general_operand" "")))
6866 (clobber (reg:CC 17))])]
6867 ""
6868 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6869
6870 (define_insn "*subdi3_1"
6871 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6872 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6873 (match_operand:DI 2 "general_operand" "roiF,riF")))
6874 (clobber (reg:CC 17))]
6875 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6876 "#")
6877
6878 (define_split
6879 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6880 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6881 (match_operand:DI 2 "general_operand" "")))
6882 (clobber (reg:CC 17))]
6883 "!TARGET_64BIT && reload_completed"
6884 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6885 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6886 (parallel [(set (match_dup 3)
6887 (minus:SI (match_dup 4)
6888 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6889 (match_dup 5))))
6890 (clobber (reg:CC 17))])]
6891 "split_di (operands+0, 1, operands+0, operands+3);
6892 split_di (operands+1, 1, operands+1, operands+4);
6893 split_di (operands+2, 1, operands+2, operands+5);")
6894
6895 (define_insn "subdi3_carry_rex64"
6896 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6897 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6898 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6899 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6900 (clobber (reg:CC 17))]
6901 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6902 "sbb{q}\t{%2, %0|%0, %2}"
6903 [(set_attr "type" "alu")
6904 (set_attr "pent_pair" "pu")
6905 (set_attr "ppro_uops" "few")
6906 (set_attr "mode" "DI")])
6907
6908 (define_insn "*subdi_1_rex64"
6909 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6910 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6911 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6912 (clobber (reg:CC 17))]
6913 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6914 "sub{q}\t{%2, %0|%0, %2}"
6915 [(set_attr "type" "alu")
6916 (set_attr "mode" "DI")])
6917
6918 (define_insn "*subdi_2_rex64"
6919 [(set (reg 17)
6920 (compare
6921 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6922 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6923 (const_int 0)))
6924 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6925 (minus:DI (match_dup 1) (match_dup 2)))]
6926 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6927 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6928 "sub{q}\t{%2, %0|%0, %2}"
6929 [(set_attr "type" "alu")
6930 (set_attr "mode" "DI")])
6931
6932 (define_insn "*subdi_3_rex63"
6933 [(set (reg 17)
6934 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6935 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6936 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6937 (minus:DI (match_dup 1) (match_dup 2)))]
6938 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6939 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6940 "sub{q}\t{%2, %0|%0, %2}"
6941 [(set_attr "type" "alu")
6942 (set_attr "mode" "DI")])
6943
6944 (define_insn "subqi3_carry"
6945 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
6946 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6947 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6948 (match_operand:QI 2 "general_operand" "ri,rm"))))
6949 (clobber (reg:CC 17))]
6950 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6951 "sbb{b}\t{%2, %0|%0, %2}"
6952 [(set_attr "type" "alu")
6953 (set_attr "pent_pair" "pu")
6954 (set_attr "ppro_uops" "few")
6955 (set_attr "mode" "QI")])
6956
6957 (define_insn "subhi3_carry"
6958 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6959 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6960 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6961 (match_operand:HI 2 "general_operand" "ri,rm"))))
6962 (clobber (reg:CC 17))]
6963 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6964 "sbb{w}\t{%2, %0|%0, %2}"
6965 [(set_attr "type" "alu")
6966 (set_attr "pent_pair" "pu")
6967 (set_attr "ppro_uops" "few")
6968 (set_attr "mode" "HI")])
6969
6970 (define_insn "subsi3_carry"
6971 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6972 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6973 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6974 (match_operand:SI 2 "general_operand" "ri,rm"))))
6975 (clobber (reg:CC 17))]
6976 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6977 "sbb{l}\t{%2, %0|%0, %2}"
6978 [(set_attr "type" "alu")
6979 (set_attr "pent_pair" "pu")
6980 (set_attr "ppro_uops" "few")
6981 (set_attr "mode" "SI")])
6982
6983 (define_insn "subsi3_carry_zext"
6984 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6985 (zero_extend:DI
6986 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6987 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6988 (match_operand:SI 2 "general_operand" "ri,rm")))))
6989 (clobber (reg:CC 17))]
6990 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6991 "sbb{l}\t{%2, %k0|%k0, %2}"
6992 [(set_attr "type" "alu")
6993 (set_attr "pent_pair" "pu")
6994 (set_attr "ppro_uops" "few")
6995 (set_attr "mode" "SI")])
6996
6997 (define_expand "subsi3"
6998 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6999 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7000 (match_operand:SI 2 "general_operand" "")))
7001 (clobber (reg:CC 17))])]
7002 ""
7003 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7004
7005 (define_insn "*subsi_1"
7006 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7007 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7008 (match_operand:SI 2 "general_operand" "ri,rm")))
7009 (clobber (reg:CC 17))]
7010 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7011 "sub{l}\t{%2, %0|%0, %2}"
7012 [(set_attr "type" "alu")
7013 (set_attr "mode" "SI")])
7014
7015 (define_insn "*subsi_1_zext"
7016 [(set (match_operand:DI 0 "register_operand" "=r")
7017 (zero_extend:DI
7018 (minus:SI (match_operand:SI 1 "register_operand" "0")
7019 (match_operand:SI 2 "general_operand" "rim"))))
7020 (clobber (reg:CC 17))]
7021 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7022 "sub{l}\t{%2, %k0|%k0, %2}"
7023 [(set_attr "type" "alu")
7024 (set_attr "mode" "SI")])
7025
7026 (define_insn "*subsi_2"
7027 [(set (reg 17)
7028 (compare
7029 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7030 (match_operand:SI 2 "general_operand" "ri,rm"))
7031 (const_int 0)))
7032 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7033 (minus:SI (match_dup 1) (match_dup 2)))]
7034 "ix86_match_ccmode (insn, CCGOCmode)
7035 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7036 "sub{l}\t{%2, %0|%0, %2}"
7037 [(set_attr "type" "alu")
7038 (set_attr "mode" "SI")])
7039
7040 (define_insn "*subsi_2_zext"
7041 [(set (reg 17)
7042 (compare
7043 (minus:SI (match_operand:SI 1 "register_operand" "0")
7044 (match_operand:SI 2 "general_operand" "rim"))
7045 (const_int 0)))
7046 (set (match_operand:DI 0 "register_operand" "=r")
7047 (zero_extend:DI
7048 (minus:SI (match_dup 1)
7049 (match_dup 2))))]
7050 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7051 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7052 "sub{l}\t{%2, %k0|%k0, %2}"
7053 [(set_attr "type" "alu")
7054 (set_attr "mode" "SI")])
7055
7056 (define_insn "*subsi_3"
7057 [(set (reg 17)
7058 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7059 (match_operand:SI 2 "general_operand" "ri,rm")))
7060 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7061 (minus:SI (match_dup 1) (match_dup 2)))]
7062 "ix86_match_ccmode (insn, CCmode)
7063 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7064 "sub{l}\t{%2, %0|%0, %2}"
7065 [(set_attr "type" "alu")
7066 (set_attr "mode" "SI")])
7067
7068 (define_insn "*subsi_3_zext"
7069 [(set (reg 17)
7070 (compare (match_operand:SI 1 "register_operand" "0")
7071 (match_operand:SI 2 "general_operand" "rim")))
7072 (set (match_operand:DI 0 "register_operand" "=r")
7073 (zero_extend:DI
7074 (minus:SI (match_dup 1)
7075 (match_dup 2))))]
7076 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7077 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7078 "sub{q}\t{%2, %0|%0, %2}"
7079 [(set_attr "type" "alu")
7080 (set_attr "mode" "DI")])
7081
7082 (define_expand "subhi3"
7083 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7084 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7085 (match_operand:HI 2 "general_operand" "")))
7086 (clobber (reg:CC 17))])]
7087 "TARGET_HIMODE_MATH"
7088 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7089
7090 (define_insn "*subhi_1"
7091 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7092 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7093 (match_operand:HI 2 "general_operand" "ri,rm")))
7094 (clobber (reg:CC 17))]
7095 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7096 "sub{w}\t{%2, %0|%0, %2}"
7097 [(set_attr "type" "alu")
7098 (set_attr "mode" "HI")])
7099
7100 (define_insn "*subhi_2"
7101 [(set (reg 17)
7102 (compare
7103 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7104 (match_operand:HI 2 "general_operand" "ri,rm"))
7105 (const_int 0)))
7106 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7107 (minus:HI (match_dup 1) (match_dup 2)))]
7108 "ix86_match_ccmode (insn, CCGOCmode)
7109 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7110 "sub{w}\t{%2, %0|%0, %2}"
7111 [(set_attr "type" "alu")
7112 (set_attr "mode" "HI")])
7113
7114 (define_insn "*subhi_3"
7115 [(set (reg 17)
7116 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7117 (match_operand:HI 2 "general_operand" "ri,rm")))
7118 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7119 (minus:HI (match_dup 1) (match_dup 2)))]
7120 "ix86_match_ccmode (insn, CCmode)
7121 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7122 "sub{w}\t{%2, %0|%0, %2}"
7123 [(set_attr "type" "alu")
7124 (set_attr "mode" "HI")])
7125
7126 (define_expand "subqi3"
7127 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7128 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7129 (match_operand:QI 2 "general_operand" "")))
7130 (clobber (reg:CC 17))])]
7131 "TARGET_QIMODE_MATH"
7132 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7133
7134 (define_insn "*subqi_1"
7135 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7136 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7137 (match_operand:QI 2 "general_operand" "qn,qmn")))
7138 (clobber (reg:CC 17))]
7139 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7140 "sub{b}\t{%2, %0|%0, %2}"
7141 [(set_attr "type" "alu")
7142 (set_attr "mode" "QI")])
7143
7144 (define_insn "*subqi_1_slp"
7145 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7146 (minus:QI (match_dup 0)
7147 (match_operand:QI 1 "general_operand" "qn,qmn")))
7148 (clobber (reg:CC 17))]
7149 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7150 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7151 "sub{b}\t{%1, %0|%0, %1}"
7152 [(set_attr "type" "alu1")
7153 (set_attr "mode" "QI")])
7154
7155 (define_insn "*subqi_2"
7156 [(set (reg 17)
7157 (compare
7158 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7159 (match_operand:QI 2 "general_operand" "qi,qm"))
7160 (const_int 0)))
7161 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7162 (minus:HI (match_dup 1) (match_dup 2)))]
7163 "ix86_match_ccmode (insn, CCGOCmode)
7164 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7165 "sub{b}\t{%2, %0|%0, %2}"
7166 [(set_attr "type" "alu")
7167 (set_attr "mode" "QI")])
7168
7169 (define_insn "*subqi_3"
7170 [(set (reg 17)
7171 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7172 (match_operand:QI 2 "general_operand" "qi,qm")))
7173 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7174 (minus:HI (match_dup 1) (match_dup 2)))]
7175 "ix86_match_ccmode (insn, CCmode)
7176 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7177 "sub{b}\t{%2, %0|%0, %2}"
7178 [(set_attr "type" "alu")
7179 (set_attr "mode" "QI")])
7180
7181 ;; The patterns that match these are at the end of this file.
7182
7183 (define_expand "subxf3"
7184 [(set (match_operand:XF 0 "register_operand" "")
7185 (minus:XF (match_operand:XF 1 "register_operand" "")
7186 (match_operand:XF 2 "register_operand" "")))]
7187 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7188 "")
7189
7190 (define_expand "subtf3"
7191 [(set (match_operand:TF 0 "register_operand" "")
7192 (minus:TF (match_operand:TF 1 "register_operand" "")
7193 (match_operand:TF 2 "register_operand" "")))]
7194 "TARGET_80387"
7195 "")
7196
7197 (define_expand "subdf3"
7198 [(set (match_operand:DF 0 "register_operand" "")
7199 (minus:DF (match_operand:DF 1 "register_operand" "")
7200 (match_operand:DF 2 "nonimmediate_operand" "")))]
7201 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7202 "")
7203
7204 (define_expand "subsf3"
7205 [(set (match_operand:SF 0 "register_operand" "")
7206 (minus:SF (match_operand:SF 1 "register_operand" "")
7207 (match_operand:SF 2 "nonimmediate_operand" "")))]
7208 "TARGET_80387 || TARGET_SSE_MATH"
7209 "")
7210 \f
7211 ;; Multiply instructions
7212
7213 (define_expand "muldi3"
7214 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7215 (mult:DI (match_operand:DI 1 "register_operand" "")
7216 (match_operand:DI 2 "x86_64_general_operand" "")))
7217 (clobber (reg:CC 17))])]
7218 "TARGET_64BIT"
7219 "")
7220
7221 (define_insn "*muldi3_1_rex64"
7222 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7223 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7224 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7225 (clobber (reg:CC 17))]
7226 "TARGET_64BIT
7227 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7228 "@
7229 imul{q}\t{%2, %1, %0|%0, %1, %2}
7230 imul{q}\t{%2, %1, %0|%0, %1, %2}
7231 imul{q}\t{%2, %0|%0, %2}"
7232 [(set_attr "type" "imul")
7233 (set_attr "prefix_0f" "0,0,1")
7234 (set (attr "athlon_decode")
7235 (cond [(eq_attr "cpu" "athlon")
7236 (const_string "vector")
7237 (eq_attr "alternative" "1")
7238 (const_string "vector")
7239 (and (eq_attr "alternative" "2")
7240 (match_operand 1 "memory_operand" ""))
7241 (const_string "vector")]
7242 (const_string "direct")))
7243 (set_attr "mode" "DI")])
7244
7245 (define_expand "mulsi3"
7246 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7247 (mult:SI (match_operand:SI 1 "register_operand" "")
7248 (match_operand:SI 2 "general_operand" "")))
7249 (clobber (reg:CC 17))])]
7250 ""
7251 "")
7252
7253 (define_insn "*mulsi3_1"
7254 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7255 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7256 (match_operand:SI 2 "general_operand" "K,i,mr")))
7257 (clobber (reg:CC 17))]
7258 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7259 "@
7260 imul{l}\t{%2, %1, %0|%0, %1, %2}
7261 imul{l}\t{%2, %1, %0|%0, %1, %2}
7262 imul{l}\t{%2, %0|%0, %2}"
7263 [(set_attr "type" "imul")
7264 (set_attr "prefix_0f" "0,0,1")
7265 (set (attr "athlon_decode")
7266 (cond [(eq_attr "cpu" "athlon")
7267 (const_string "vector")
7268 (eq_attr "alternative" "1")
7269 (const_string "vector")
7270 (and (eq_attr "alternative" "2")
7271 (match_operand 1 "memory_operand" ""))
7272 (const_string "vector")]
7273 (const_string "direct")))
7274 (set_attr "mode" "SI")])
7275
7276 (define_insn "*mulsi3_1_zext"
7277 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7278 (zero_extend:DI
7279 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7280 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7281 (clobber (reg:CC 17))]
7282 "TARGET_64BIT
7283 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7284 "@
7285 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7286 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7287 imul{l}\t{%2, %k0|%k0, %2}"
7288 [(set_attr "type" "imul")
7289 (set_attr "prefix_0f" "0,0,1")
7290 (set (attr "athlon_decode")
7291 (cond [(eq_attr "cpu" "athlon")
7292 (const_string "vector")
7293 (eq_attr "alternative" "1")
7294 (const_string "vector")
7295 (and (eq_attr "alternative" "2")
7296 (match_operand 1 "memory_operand" ""))
7297 (const_string "vector")]
7298 (const_string "direct")))
7299 (set_attr "mode" "SI")])
7300
7301 (define_expand "mulhi3"
7302 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7303 (mult:HI (match_operand:HI 1 "register_operand" "")
7304 (match_operand:HI 2 "general_operand" "")))
7305 (clobber (reg:CC 17))])]
7306 "TARGET_HIMODE_MATH"
7307 "")
7308
7309 (define_insn "*mulhi3_1"
7310 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7311 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7312 (match_operand:HI 2 "general_operand" "K,i,mr")))
7313 (clobber (reg:CC 17))]
7314 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7315 "@
7316 imul{w}\t{%2, %1, %0|%0, %1, %2}
7317 imul{w}\t{%2, %1, %0|%0, %1, %2}
7318 imul{w}\t{%2, %0|%0, %2}"
7319 [(set_attr "type" "imul")
7320 (set_attr "prefix_0f" "0,0,1")
7321 (set (attr "athlon_decode")
7322 (cond [(eq_attr "cpu" "athlon")
7323 (const_string "vector")
7324 (eq_attr "alternative" "1,2")
7325 (const_string "vector")]
7326 (const_string "direct")))
7327 (set_attr "mode" "HI")])
7328
7329 (define_expand "mulqi3"
7330 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7331 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7332 (match_operand:QI 2 "register_operand" "")))
7333 (clobber (reg:CC 17))])]
7334 "TARGET_QIMODE_MATH"
7335 "")
7336
7337 (define_insn "*mulqi3_1"
7338 [(set (match_operand:QI 0 "register_operand" "=a")
7339 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7340 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7341 (clobber (reg:CC 17))]
7342 "TARGET_QIMODE_MATH
7343 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7344 "mul{b}\t%2"
7345 [(set_attr "type" "imul")
7346 (set_attr "length_immediate" "0")
7347 (set (attr "athlon_decode")
7348 (if_then_else (eq_attr "cpu" "athlon")
7349 (const_string "vector")
7350 (const_string "direct")))
7351 (set_attr "mode" "QI")])
7352
7353 (define_expand "umulqihi3"
7354 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7355 (mult:HI (zero_extend:HI
7356 (match_operand:QI 1 "nonimmediate_operand" ""))
7357 (zero_extend:HI
7358 (match_operand:QI 2 "register_operand" ""))))
7359 (clobber (reg:CC 17))])]
7360 "TARGET_QIMODE_MATH"
7361 "")
7362
7363 (define_insn "*umulqihi3_1"
7364 [(set (match_operand:HI 0 "register_operand" "=a")
7365 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7366 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7367 (clobber (reg:CC 17))]
7368 "TARGET_QIMODE_MATH
7369 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7370 "mul{b}\t%2"
7371 [(set_attr "type" "imul")
7372 (set_attr "length_immediate" "0")
7373 (set (attr "athlon_decode")
7374 (if_then_else (eq_attr "cpu" "athlon")
7375 (const_string "vector")
7376 (const_string "direct")))
7377 (set_attr "mode" "QI")])
7378
7379 (define_expand "mulqihi3"
7380 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7381 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7382 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7383 (clobber (reg:CC 17))])]
7384 "TARGET_QIMODE_MATH"
7385 "")
7386
7387 (define_insn "*mulqihi3_insn"
7388 [(set (match_operand:HI 0 "register_operand" "=a")
7389 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7390 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7391 (clobber (reg:CC 17))]
7392 "TARGET_QIMODE_MATH
7393 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7394 "imul{b}\t%2"
7395 [(set_attr "type" "imul")
7396 (set_attr "length_immediate" "0")
7397 (set (attr "athlon_decode")
7398 (if_then_else (eq_attr "cpu" "athlon")
7399 (const_string "vector")
7400 (const_string "direct")))
7401 (set_attr "mode" "QI")])
7402
7403 (define_expand "umulditi3"
7404 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7405 (mult:TI (zero_extend:TI
7406 (match_operand:DI 1 "nonimmediate_operand" ""))
7407 (zero_extend:TI
7408 (match_operand:DI 2 "register_operand" ""))))
7409 (clobber (reg:CC 17))])]
7410 "TARGET_64BIT"
7411 "")
7412
7413 (define_insn "*umulditi3_insn"
7414 [(set (match_operand:TI 0 "register_operand" "=A")
7415 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7416 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7417 (clobber (reg:CC 17))]
7418 "TARGET_64BIT
7419 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7420 "mul{q}\t%2"
7421 [(set_attr "type" "imul")
7422 (set_attr "ppro_uops" "few")
7423 (set_attr "length_immediate" "0")
7424 (set (attr "athlon_decode")
7425 (if_then_else (eq_attr "cpu" "athlon")
7426 (const_string "vector")
7427 (const_string "double")))
7428 (set_attr "mode" "DI")])
7429
7430 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7431 (define_expand "umulsidi3"
7432 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7433 (mult:DI (zero_extend:DI
7434 (match_operand:SI 1 "nonimmediate_operand" ""))
7435 (zero_extend:DI
7436 (match_operand:SI 2 "register_operand" ""))))
7437 (clobber (reg:CC 17))])]
7438 "!TARGET_64BIT"
7439 "")
7440
7441 (define_insn "*umulsidi3_insn"
7442 [(set (match_operand:DI 0 "register_operand" "=A")
7443 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7444 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7445 (clobber (reg:CC 17))]
7446 "!TARGET_64BIT
7447 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7448 "mul{l}\t%2"
7449 [(set_attr "type" "imul")
7450 (set_attr "ppro_uops" "few")
7451 (set_attr "length_immediate" "0")
7452 (set (attr "athlon_decode")
7453 (if_then_else (eq_attr "cpu" "athlon")
7454 (const_string "vector")
7455 (const_string "double")))
7456 (set_attr "mode" "SI")])
7457
7458 (define_expand "mulditi3"
7459 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7460 (mult:TI (sign_extend:TI
7461 (match_operand:DI 1 "nonimmediate_operand" ""))
7462 (sign_extend:TI
7463 (match_operand:DI 2 "register_operand" ""))))
7464 (clobber (reg:CC 17))])]
7465 "TARGET_64BIT"
7466 "")
7467
7468 (define_insn "*mulditi3_insn"
7469 [(set (match_operand:TI 0 "register_operand" "=A")
7470 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7471 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7472 (clobber (reg:CC 17))]
7473 "TARGET_64BIT
7474 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7475 "imul{q}\t%2"
7476 [(set_attr "type" "imul")
7477 (set_attr "length_immediate" "0")
7478 (set (attr "athlon_decode")
7479 (if_then_else (eq_attr "cpu" "athlon")
7480 (const_string "vector")
7481 (const_string "double")))
7482 (set_attr "mode" "DI")])
7483
7484 (define_expand "mulsidi3"
7485 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7486 (mult:DI (sign_extend:DI
7487 (match_operand:SI 1 "nonimmediate_operand" ""))
7488 (sign_extend:DI
7489 (match_operand:SI 2 "register_operand" ""))))
7490 (clobber (reg:CC 17))])]
7491 "!TARGET_64BIT"
7492 "")
7493
7494 (define_insn "*mulsidi3_insn"
7495 [(set (match_operand:DI 0 "register_operand" "=A")
7496 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7497 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7498 (clobber (reg:CC 17))]
7499 "!TARGET_64BIT
7500 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7501 "imul{l}\t%2"
7502 [(set_attr "type" "imul")
7503 (set_attr "length_immediate" "0")
7504 (set (attr "athlon_decode")
7505 (if_then_else (eq_attr "cpu" "athlon")
7506 (const_string "vector")
7507 (const_string "double")))
7508 (set_attr "mode" "SI")])
7509
7510 (define_expand "umuldi3_highpart"
7511 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7512 (truncate:DI
7513 (lshiftrt:TI
7514 (mult:TI (zero_extend:TI
7515 (match_operand:DI 1 "nonimmediate_operand" ""))
7516 (zero_extend:TI
7517 (match_operand:DI 2 "register_operand" "")))
7518 (const_int 64))))
7519 (clobber (match_scratch:DI 3 ""))
7520 (clobber (reg:CC 17))])]
7521 "TARGET_64BIT"
7522 "")
7523
7524 (define_insn "*umuldi3_highpart_rex64"
7525 [(set (match_operand:DI 0 "register_operand" "=d")
7526 (truncate:DI
7527 (lshiftrt:TI
7528 (mult:TI (zero_extend:TI
7529 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7530 (zero_extend:TI
7531 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7532 (const_int 64))))
7533 (clobber (match_scratch:DI 3 "=1"))
7534 (clobber (reg:CC 17))]
7535 "TARGET_64BIT
7536 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7537 "mul{q}\t%2"
7538 [(set_attr "type" "imul")
7539 (set_attr "ppro_uops" "few")
7540 (set_attr "length_immediate" "0")
7541 (set (attr "athlon_decode")
7542 (if_then_else (eq_attr "cpu" "athlon")
7543 (const_string "vector")
7544 (const_string "double")))
7545 (set_attr "mode" "DI")])
7546
7547 (define_expand "umulsi3_highpart"
7548 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7549 (truncate:SI
7550 (lshiftrt:DI
7551 (mult:DI (zero_extend:DI
7552 (match_operand:SI 1 "nonimmediate_operand" ""))
7553 (zero_extend:DI
7554 (match_operand:SI 2 "register_operand" "")))
7555 (const_int 32))))
7556 (clobber (match_scratch:SI 3 ""))
7557 (clobber (reg:CC 17))])]
7558 ""
7559 "")
7560
7561 (define_insn "*umulsi3_highpart_insn"
7562 [(set (match_operand:SI 0 "register_operand" "=d")
7563 (truncate:SI
7564 (lshiftrt:DI
7565 (mult:DI (zero_extend:DI
7566 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7567 (zero_extend:DI
7568 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7569 (const_int 32))))
7570 (clobber (match_scratch:SI 3 "=1"))
7571 (clobber (reg:CC 17))]
7572 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7573 "mul{l}\t%2"
7574 [(set_attr "type" "imul")
7575 (set_attr "ppro_uops" "few")
7576 (set_attr "length_immediate" "0")
7577 (set (attr "athlon_decode")
7578 (if_then_else (eq_attr "cpu" "athlon")
7579 (const_string "vector")
7580 (const_string "double")))
7581 (set_attr "mode" "SI")])
7582
7583 (define_insn "*umulsi3_highpart_zext"
7584 [(set (match_operand:DI 0 "register_operand" "=d")
7585 (zero_extend:DI (truncate:SI
7586 (lshiftrt:DI
7587 (mult:DI (zero_extend:DI
7588 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7589 (zero_extend:DI
7590 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7591 (const_int 32)))))
7592 (clobber (match_scratch:SI 3 "=1"))
7593 (clobber (reg:CC 17))]
7594 "TARGET_64BIT
7595 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7596 "mul{l}\t%2"
7597 [(set_attr "type" "imul")
7598 (set_attr "ppro_uops" "few")
7599 (set_attr "length_immediate" "0")
7600 (set (attr "athlon_decode")
7601 (if_then_else (eq_attr "cpu" "athlon")
7602 (const_string "vector")
7603 (const_string "double")))
7604 (set_attr "mode" "SI")])
7605
7606 (define_expand "smuldi3_highpart"
7607 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7608 (truncate:DI
7609 (lshiftrt:TI
7610 (mult:TI (sign_extend:TI
7611 (match_operand:DI 1 "nonimmediate_operand" ""))
7612 (sign_extend:TI
7613 (match_operand:DI 2 "register_operand" "")))
7614 (const_int 64))))
7615 (clobber (match_scratch:DI 3 ""))
7616 (clobber (reg:CC 17))])]
7617 "TARGET_64BIT"
7618 "")
7619
7620 (define_insn "*smuldi3_highpart_rex64"
7621 [(set (match_operand:DI 0 "register_operand" "=d")
7622 (truncate:DI
7623 (lshiftrt:TI
7624 (mult:TI (sign_extend:TI
7625 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7626 (sign_extend:TI
7627 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7628 (const_int 64))))
7629 (clobber (match_scratch:DI 3 "=1"))
7630 (clobber (reg:CC 17))]
7631 "TARGET_64BIT
7632 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7633 "imul{q}\t%2"
7634 [(set_attr "type" "imul")
7635 (set_attr "ppro_uops" "few")
7636 (set (attr "athlon_decode")
7637 (if_then_else (eq_attr "cpu" "athlon")
7638 (const_string "vector")
7639 (const_string "double")))
7640 (set_attr "mode" "DI")])
7641
7642 (define_expand "smulsi3_highpart"
7643 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7644 (truncate:SI
7645 (lshiftrt:DI
7646 (mult:DI (sign_extend:DI
7647 (match_operand:SI 1 "nonimmediate_operand" ""))
7648 (sign_extend:DI
7649 (match_operand:SI 2 "register_operand" "")))
7650 (const_int 32))))
7651 (clobber (match_scratch:SI 3 ""))
7652 (clobber (reg:CC 17))])]
7653 ""
7654 "")
7655
7656 (define_insn "*smulsi3_highpart_insn"
7657 [(set (match_operand:SI 0 "register_operand" "=d")
7658 (truncate:SI
7659 (lshiftrt:DI
7660 (mult:DI (sign_extend:DI
7661 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7662 (sign_extend:DI
7663 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7664 (const_int 32))))
7665 (clobber (match_scratch:SI 3 "=1"))
7666 (clobber (reg:CC 17))]
7667 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7668 "imul{l}\t%2"
7669 [(set_attr "type" "imul")
7670 (set_attr "ppro_uops" "few")
7671 (set (attr "athlon_decode")
7672 (if_then_else (eq_attr "cpu" "athlon")
7673 (const_string "vector")
7674 (const_string "double")))
7675 (set_attr "mode" "SI")])
7676
7677 (define_insn "*smulsi3_highpart_zext"
7678 [(set (match_operand:DI 0 "register_operand" "=d")
7679 (zero_extend:DI (truncate:SI
7680 (lshiftrt:DI
7681 (mult:DI (sign_extend:DI
7682 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7683 (sign_extend:DI
7684 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7685 (const_int 32)))))
7686 (clobber (match_scratch:SI 3 "=1"))
7687 (clobber (reg:CC 17))]
7688 "TARGET_64BIT
7689 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7690 "imul{l}\t%2"
7691 [(set_attr "type" "imul")
7692 (set_attr "ppro_uops" "few")
7693 (set (attr "athlon_decode")
7694 (if_then_else (eq_attr "cpu" "athlon")
7695 (const_string "vector")
7696 (const_string "double")))
7697 (set_attr "mode" "SI")])
7698
7699 ;; The patterns that match these are at the end of this file.
7700
7701 (define_expand "mulxf3"
7702 [(set (match_operand:XF 0 "register_operand" "")
7703 (mult:XF (match_operand:XF 1 "register_operand" "")
7704 (match_operand:XF 2 "register_operand" "")))]
7705 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7706 "")
7707
7708 (define_expand "multf3"
7709 [(set (match_operand:TF 0 "register_operand" "")
7710 (mult:TF (match_operand:TF 1 "register_operand" "")
7711 (match_operand:TF 2 "register_operand" "")))]
7712 "TARGET_80387"
7713 "")
7714
7715 (define_expand "muldf3"
7716 [(set (match_operand:DF 0 "register_operand" "")
7717 (mult:DF (match_operand:DF 1 "register_operand" "")
7718 (match_operand:DF 2 "nonimmediate_operand" "")))]
7719 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7720 "")
7721
7722 (define_expand "mulsf3"
7723 [(set (match_operand:SF 0 "register_operand" "")
7724 (mult:SF (match_operand:SF 1 "register_operand" "")
7725 (match_operand:SF 2 "nonimmediate_operand" "")))]
7726 "TARGET_80387 || TARGET_SSE_MATH"
7727 "")
7728 \f
7729 ;; Divide instructions
7730
7731 (define_insn "divqi3"
7732 [(set (match_operand:QI 0 "register_operand" "=a")
7733 (div:QI (match_operand:HI 1 "register_operand" "0")
7734 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7735 (clobber (reg:CC 17))]
7736 "TARGET_QIMODE_MATH"
7737 "idiv{b}\t%2"
7738 [(set_attr "type" "idiv")
7739 (set_attr "mode" "QI")
7740 (set_attr "ppro_uops" "few")])
7741
7742 (define_insn "udivqi3"
7743 [(set (match_operand:QI 0 "register_operand" "=a")
7744 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7745 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7746 (clobber (reg:CC 17))]
7747 "TARGET_QIMODE_MATH"
7748 "div{b}\t%2"
7749 [(set_attr "type" "idiv")
7750 (set_attr "mode" "QI")
7751 (set_attr "ppro_uops" "few")])
7752
7753 ;; The patterns that match these are at the end of this file.
7754
7755 (define_expand "divxf3"
7756 [(set (match_operand:XF 0 "register_operand" "")
7757 (div:XF (match_operand:XF 1 "register_operand" "")
7758 (match_operand:XF 2 "register_operand" "")))]
7759 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7760 "")
7761
7762 (define_expand "divtf3"
7763 [(set (match_operand:TF 0 "register_operand" "")
7764 (div:TF (match_operand:TF 1 "register_operand" "")
7765 (match_operand:TF 2 "register_operand" "")))]
7766 "TARGET_80387"
7767 "")
7768
7769 (define_expand "divdf3"
7770 [(set (match_operand:DF 0 "register_operand" "")
7771 (div:DF (match_operand:DF 1 "register_operand" "")
7772 (match_operand:DF 2 "nonimmediate_operand" "")))]
7773 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7774 "")
7775
7776 (define_expand "divsf3"
7777 [(set (match_operand:SF 0 "register_operand" "")
7778 (div:SF (match_operand:SF 1 "register_operand" "")
7779 (match_operand:SF 2 "nonimmediate_operand" "")))]
7780 "TARGET_80387 || TARGET_SSE_MATH"
7781 "")
7782 \f
7783 ;; Remainder instructions.
7784
7785 (define_expand "divmoddi4"
7786 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7787 (div:DI (match_operand:DI 1 "register_operand" "")
7788 (match_operand:DI 2 "nonimmediate_operand" "")))
7789 (set (match_operand:DI 3 "register_operand" "")
7790 (mod:DI (match_dup 1) (match_dup 2)))
7791 (clobber (reg:CC 17))])]
7792 "TARGET_64BIT"
7793 "")
7794
7795 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7796 ;; Penalize eax case slightly because it results in worse scheduling
7797 ;; of code.
7798 (define_insn "*divmoddi4_nocltd_rex64"
7799 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7800 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7801 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7802 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7803 (mod:DI (match_dup 2) (match_dup 3)))
7804 (clobber (reg:CC 17))]
7805 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7806 "#"
7807 [(set_attr "type" "multi")])
7808
7809 (define_insn "*divmoddi4_cltd_rex64"
7810 [(set (match_operand:DI 0 "register_operand" "=a")
7811 (div:DI (match_operand:DI 2 "register_operand" "a")
7812 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7813 (set (match_operand:DI 1 "register_operand" "=&d")
7814 (mod:DI (match_dup 2) (match_dup 3)))
7815 (clobber (reg:CC 17))]
7816 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7817 "#"
7818 [(set_attr "type" "multi")])
7819
7820 (define_insn "*divmoddi_noext_rex64"
7821 [(set (match_operand:DI 0 "register_operand" "=a")
7822 (div:DI (match_operand:DI 1 "register_operand" "0")
7823 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7824 (set (match_operand:DI 3 "register_operand" "=d")
7825 (mod:DI (match_dup 1) (match_dup 2)))
7826 (use (match_operand:DI 4 "register_operand" "3"))
7827 (clobber (reg:CC 17))]
7828 "TARGET_64BIT"
7829 "idiv{q}\t%2"
7830 [(set_attr "type" "idiv")
7831 (set_attr "mode" "DI")
7832 (set_attr "ppro_uops" "few")])
7833
7834 (define_split
7835 [(set (match_operand:DI 0 "register_operand" "")
7836 (div:DI (match_operand:DI 1 "register_operand" "")
7837 (match_operand:DI 2 "nonimmediate_operand" "")))
7838 (set (match_operand:DI 3 "register_operand" "")
7839 (mod:DI (match_dup 1) (match_dup 2)))
7840 (clobber (reg:CC 17))]
7841 "TARGET_64BIT && reload_completed"
7842 [(parallel [(set (match_dup 3)
7843 (ashiftrt:DI (match_dup 4) (const_int 63)))
7844 (clobber (reg:CC 17))])
7845 (parallel [(set (match_dup 0)
7846 (div:DI (reg:DI 0) (match_dup 2)))
7847 (set (match_dup 3)
7848 (mod:DI (reg:DI 0) (match_dup 2)))
7849 (use (match_dup 3))
7850 (clobber (reg:CC 17))])]
7851 {
7852 /* Avoid use of cltd in favor of a mov+shift. */
7853 if (!TARGET_USE_CLTD && !optimize_size)
7854 {
7855 if (true_regnum (operands[1]))
7856 emit_move_insn (operands[0], operands[1]);
7857 else
7858 emit_move_insn (operands[3], operands[1]);
7859 operands[4] = operands[3];
7860 }
7861 else
7862 {
7863 if (true_regnum (operands[1]))
7864 abort();
7865 operands[4] = operands[1];
7866 }
7867 })
7868
7869
7870 (define_expand "divmodsi4"
7871 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7872 (div:SI (match_operand:SI 1 "register_operand" "")
7873 (match_operand:SI 2 "nonimmediate_operand" "")))
7874 (set (match_operand:SI 3 "register_operand" "")
7875 (mod:SI (match_dup 1) (match_dup 2)))
7876 (clobber (reg:CC 17))])]
7877 ""
7878 "")
7879
7880 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7881 ;; Penalize eax case slightly because it results in worse scheduling
7882 ;; of code.
7883 (define_insn "*divmodsi4_nocltd"
7884 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7885 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7886 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7887 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7888 (mod:SI (match_dup 2) (match_dup 3)))
7889 (clobber (reg:CC 17))]
7890 "!optimize_size && !TARGET_USE_CLTD"
7891 "#"
7892 [(set_attr "type" "multi")])
7893
7894 (define_insn "*divmodsi4_cltd"
7895 [(set (match_operand:SI 0 "register_operand" "=a")
7896 (div:SI (match_operand:SI 2 "register_operand" "a")
7897 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7898 (set (match_operand:SI 1 "register_operand" "=&d")
7899 (mod:SI (match_dup 2) (match_dup 3)))
7900 (clobber (reg:CC 17))]
7901 "optimize_size || TARGET_USE_CLTD"
7902 "#"
7903 [(set_attr "type" "multi")])
7904
7905 (define_insn "*divmodsi_noext"
7906 [(set (match_operand:SI 0 "register_operand" "=a")
7907 (div:SI (match_operand:SI 1 "register_operand" "0")
7908 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7909 (set (match_operand:SI 3 "register_operand" "=d")
7910 (mod:SI (match_dup 1) (match_dup 2)))
7911 (use (match_operand:SI 4 "register_operand" "3"))
7912 (clobber (reg:CC 17))]
7913 ""
7914 "idiv{l}\t%2"
7915 [(set_attr "type" "idiv")
7916 (set_attr "mode" "SI")
7917 (set_attr "ppro_uops" "few")])
7918
7919 (define_split
7920 [(set (match_operand:SI 0 "register_operand" "")
7921 (div:SI (match_operand:SI 1 "register_operand" "")
7922 (match_operand:SI 2 "nonimmediate_operand" "")))
7923 (set (match_operand:SI 3 "register_operand" "")
7924 (mod:SI (match_dup 1) (match_dup 2)))
7925 (clobber (reg:CC 17))]
7926 "reload_completed"
7927 [(parallel [(set (match_dup 3)
7928 (ashiftrt:SI (match_dup 4) (const_int 31)))
7929 (clobber (reg:CC 17))])
7930 (parallel [(set (match_dup 0)
7931 (div:SI (reg:SI 0) (match_dup 2)))
7932 (set (match_dup 3)
7933 (mod:SI (reg:SI 0) (match_dup 2)))
7934 (use (match_dup 3))
7935 (clobber (reg:CC 17))])]
7936 {
7937 /* Avoid use of cltd in favor of a mov+shift. */
7938 if (!TARGET_USE_CLTD && !optimize_size)
7939 {
7940 if (true_regnum (operands[1]))
7941 emit_move_insn (operands[0], operands[1]);
7942 else
7943 emit_move_insn (operands[3], operands[1]);
7944 operands[4] = operands[3];
7945 }
7946 else
7947 {
7948 if (true_regnum (operands[1]))
7949 abort();
7950 operands[4] = operands[1];
7951 }
7952 })
7953 ;; %%% Split me.
7954 (define_insn "divmodhi4"
7955 [(set (match_operand:HI 0 "register_operand" "=a")
7956 (div:HI (match_operand:HI 1 "register_operand" "0")
7957 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7958 (set (match_operand:HI 3 "register_operand" "=&d")
7959 (mod:HI (match_dup 1) (match_dup 2)))
7960 (clobber (reg:CC 17))]
7961 "TARGET_HIMODE_MATH"
7962 "cwtd\;idiv{w}\t%2"
7963 [(set_attr "type" "multi")
7964 (set_attr "length_immediate" "0")
7965 (set_attr "mode" "SI")])
7966
7967 (define_insn "udivmoddi4"
7968 [(set (match_operand:DI 0 "register_operand" "=a")
7969 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7970 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7971 (set (match_operand:DI 3 "register_operand" "=&d")
7972 (umod:DI (match_dup 1) (match_dup 2)))
7973 (clobber (reg:CC 17))]
7974 "TARGET_64BIT"
7975 "xor{q}\t%3, %3\;div{q}\t%2"
7976 [(set_attr "type" "multi")
7977 (set_attr "length_immediate" "0")
7978 (set_attr "mode" "DI")])
7979
7980 (define_insn "*udivmoddi4_noext"
7981 [(set (match_operand:DI 0 "register_operand" "=a")
7982 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7983 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7984 (set (match_operand:DI 3 "register_operand" "=d")
7985 (umod:DI (match_dup 1) (match_dup 2)))
7986 (use (match_dup 3))
7987 (clobber (reg:CC 17))]
7988 "TARGET_64BIT"
7989 "div{q}\t%2"
7990 [(set_attr "type" "idiv")
7991 (set_attr "ppro_uops" "few")
7992 (set_attr "mode" "DI")])
7993
7994 (define_split
7995 [(set (match_operand:DI 0 "register_operand" "")
7996 (udiv:DI (match_operand:DI 1 "register_operand" "")
7997 (match_operand:DI 2 "nonimmediate_operand" "")))
7998 (set (match_operand:DI 3 "register_operand" "")
7999 (umod:DI (match_dup 1) (match_dup 2)))
8000 (clobber (reg:CC 17))]
8001 "TARGET_64BIT && reload_completed"
8002 [(set (match_dup 3) (const_int 0))
8003 (parallel [(set (match_dup 0)
8004 (udiv:DI (match_dup 1) (match_dup 2)))
8005 (set (match_dup 3)
8006 (umod:DI (match_dup 1) (match_dup 2)))
8007 (use (match_dup 3))
8008 (clobber (reg:CC 17))])]
8009 "")
8010
8011 (define_insn "udivmodsi4"
8012 [(set (match_operand:SI 0 "register_operand" "=a")
8013 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8014 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8015 (set (match_operand:SI 3 "register_operand" "=&d")
8016 (umod:SI (match_dup 1) (match_dup 2)))
8017 (clobber (reg:CC 17))]
8018 ""
8019 "xor{l}\t%3, %3\;div{l}\t%2"
8020 [(set_attr "type" "multi")
8021 (set_attr "length_immediate" "0")
8022 (set_attr "mode" "SI")])
8023
8024 (define_insn "*udivmodsi4_noext"
8025 [(set (match_operand:SI 0 "register_operand" "=a")
8026 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8027 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8028 (set (match_operand:SI 3 "register_operand" "=d")
8029 (umod:SI (match_dup 1) (match_dup 2)))
8030 (use (match_dup 3))
8031 (clobber (reg:CC 17))]
8032 ""
8033 "div{l}\t%2"
8034 [(set_attr "type" "idiv")
8035 (set_attr "ppro_uops" "few")
8036 (set_attr "mode" "SI")])
8037
8038 (define_split
8039 [(set (match_operand:SI 0 "register_operand" "")
8040 (udiv:SI (match_operand:SI 1 "register_operand" "")
8041 (match_operand:SI 2 "nonimmediate_operand" "")))
8042 (set (match_operand:SI 3 "register_operand" "")
8043 (umod:SI (match_dup 1) (match_dup 2)))
8044 (clobber (reg:CC 17))]
8045 "reload_completed"
8046 [(set (match_dup 3) (const_int 0))
8047 (parallel [(set (match_dup 0)
8048 (udiv:SI (match_dup 1) (match_dup 2)))
8049 (set (match_dup 3)
8050 (umod:SI (match_dup 1) (match_dup 2)))
8051 (use (match_dup 3))
8052 (clobber (reg:CC 17))])]
8053 "")
8054
8055 (define_expand "udivmodhi4"
8056 [(set (match_dup 4) (const_int 0))
8057 (parallel [(set (match_operand:HI 0 "register_operand" "")
8058 (udiv:HI (match_operand:HI 1 "register_operand" "")
8059 (match_operand:HI 2 "nonimmediate_operand" "")))
8060 (set (match_operand:HI 3 "register_operand" "")
8061 (umod:HI (match_dup 1) (match_dup 2)))
8062 (use (match_dup 4))
8063 (clobber (reg:CC 17))])]
8064 "TARGET_HIMODE_MATH"
8065 "operands[4] = gen_reg_rtx (HImode);")
8066
8067 (define_insn "*udivmodhi_noext"
8068 [(set (match_operand:HI 0 "register_operand" "=a")
8069 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8070 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8071 (set (match_operand:HI 3 "register_operand" "=d")
8072 (umod:HI (match_dup 1) (match_dup 2)))
8073 (use (match_operand:HI 4 "register_operand" "3"))
8074 (clobber (reg:CC 17))]
8075 ""
8076 "div{w}\t%2"
8077 [(set_attr "type" "idiv")
8078 (set_attr "mode" "HI")
8079 (set_attr "ppro_uops" "few")])
8080
8081 ;; We can not use div/idiv for double division, because it causes
8082 ;; "division by zero" on the overflow and that's not what we expect
8083 ;; from truncate. Because true (non truncating) double division is
8084 ;; never generated, we can't create this insn anyway.
8085 ;
8086 ;(define_insn ""
8087 ; [(set (match_operand:SI 0 "register_operand" "=a")
8088 ; (truncate:SI
8089 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8090 ; (zero_extend:DI
8091 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8092 ; (set (match_operand:SI 3 "register_operand" "=d")
8093 ; (truncate:SI
8094 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8095 ; (clobber (reg:CC 17))]
8096 ; ""
8097 ; "div{l}\t{%2, %0|%0, %2}"
8098 ; [(set_attr "type" "idiv")
8099 ; (set_attr "ppro_uops" "few")])
8100 \f
8101 ;;- Logical AND instructions
8102
8103 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8104 ;; Note that this excludes ah.
8105
8106 (define_insn "*testdi_1_rex64"
8107 [(set (reg 17)
8108 (compare
8109 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8110 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8111 (const_int 0)))]
8112 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8113 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8114 "@
8115 test{l}\t{%k1, %k0|%k0, %k1}
8116 test{l}\t{%k1, %k0|%k0, %k1}
8117 test{q}\t{%1, %0|%0, %1}
8118 test{q}\t{%1, %0|%0, %1}
8119 test{q}\t{%1, %0|%0, %1}"
8120 [(set_attr "type" "test")
8121 (set_attr "modrm" "0,1,0,1,1")
8122 (set_attr "mode" "SI,SI,DI,DI,DI")
8123 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8124
8125 (define_insn "testsi_1"
8126 [(set (reg 17)
8127 (compare
8128 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8129 (match_operand:SI 1 "general_operand" "in,in,rin"))
8130 (const_int 0)))]
8131 "ix86_match_ccmode (insn, CCNOmode)
8132 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8133 "test{l}\t{%1, %0|%0, %1}"
8134 [(set_attr "type" "test")
8135 (set_attr "modrm" "0,1,1")
8136 (set_attr "mode" "SI")
8137 (set_attr "pent_pair" "uv,np,uv")])
8138
8139 (define_expand "testsi_ccno_1"
8140 [(set (reg:CCNO 17)
8141 (compare:CCNO
8142 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8143 (match_operand:SI 1 "nonmemory_operand" ""))
8144 (const_int 0)))]
8145 ""
8146 "")
8147
8148 (define_insn "*testhi_1"
8149 [(set (reg 17)
8150 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8151 (match_operand:HI 1 "general_operand" "n,n,rn"))
8152 (const_int 0)))]
8153 "ix86_match_ccmode (insn, CCNOmode)
8154 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8155 "test{w}\t{%1, %0|%0, %1}"
8156 [(set_attr "type" "test")
8157 (set_attr "modrm" "0,1,1")
8158 (set_attr "mode" "HI")
8159 (set_attr "pent_pair" "uv,np,uv")])
8160
8161 (define_expand "testqi_ccz_1"
8162 [(set (reg:CCZ 17)
8163 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8164 (match_operand:QI 1 "nonmemory_operand" ""))
8165 (const_int 0)))]
8166 ""
8167 "")
8168
8169 (define_insn "*testqi_1"
8170 [(set (reg 17)
8171 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8172 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8173 (const_int 0)))]
8174 "ix86_match_ccmode (insn, CCNOmode)
8175 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8176 {
8177 if (which_alternative == 3)
8178 {
8179 if (GET_CODE (operands[1]) == CONST_INT
8180 && (INTVAL (operands[1]) & 0xffffff00))
8181 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8182 return "test{l}\t{%1, %k0|%k0, %1}";
8183 }
8184 return "test{b}\t{%1, %0|%0, %1}";
8185 }
8186 [(set_attr "type" "test")
8187 (set_attr "modrm" "0,1,1,1")
8188 (set_attr "mode" "QI,QI,QI,SI")
8189 (set_attr "pent_pair" "uv,np,uv,np")])
8190
8191 (define_expand "testqi_ext_ccno_0"
8192 [(set (reg:CCNO 17)
8193 (compare:CCNO
8194 (and:SI
8195 (zero_extract:SI
8196 (match_operand 0 "ext_register_operand" "")
8197 (const_int 8)
8198 (const_int 8))
8199 (match_operand 1 "const_int_operand" ""))
8200 (const_int 0)))]
8201 ""
8202 "")
8203
8204 (define_insn "*testqi_ext_0"
8205 [(set (reg 17)
8206 (compare
8207 (and:SI
8208 (zero_extract:SI
8209 (match_operand 0 "ext_register_operand" "Q")
8210 (const_int 8)
8211 (const_int 8))
8212 (match_operand 1 "const_int_operand" "n"))
8213 (const_int 0)))]
8214 "ix86_match_ccmode (insn, CCNOmode)"
8215 "test{b}\t{%1, %h0|%h0, %1}"
8216 [(set_attr "type" "test")
8217 (set_attr "mode" "QI")
8218 (set_attr "length_immediate" "1")
8219 (set_attr "pent_pair" "np")])
8220
8221 (define_insn "*testqi_ext_1"
8222 [(set (reg 17)
8223 (compare
8224 (and:SI
8225 (zero_extract:SI
8226 (match_operand 0 "ext_register_operand" "Q")
8227 (const_int 8)
8228 (const_int 8))
8229 (zero_extend:SI
8230 (match_operand:QI 1 "general_operand" "Qm")))
8231 (const_int 0)))]
8232 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8233 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8234 "test{b}\t{%1, %h0|%h0, %1}"
8235 [(set_attr "type" "test")
8236 (set_attr "mode" "QI")])
8237
8238 (define_insn "*testqi_ext_1_rex64"
8239 [(set (reg 17)
8240 (compare
8241 (and:SI
8242 (zero_extract:SI
8243 (match_operand 0 "ext_register_operand" "Q")
8244 (const_int 8)
8245 (const_int 8))
8246 (zero_extend:SI
8247 (match_operand:QI 1 "register_operand" "Q")))
8248 (const_int 0)))]
8249 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8250 "test{b}\t{%1, %h0|%h0, %1}"
8251 [(set_attr "type" "test")
8252 (set_attr "mode" "QI")])
8253
8254 (define_insn "*testqi_ext_2"
8255 [(set (reg 17)
8256 (compare
8257 (and:SI
8258 (zero_extract:SI
8259 (match_operand 0 "ext_register_operand" "Q")
8260 (const_int 8)
8261 (const_int 8))
8262 (zero_extract:SI
8263 (match_operand 1 "ext_register_operand" "Q")
8264 (const_int 8)
8265 (const_int 8)))
8266 (const_int 0)))]
8267 "ix86_match_ccmode (insn, CCNOmode)"
8268 "test{b}\t{%h1, %h0|%h0, %h1}"
8269 [(set_attr "type" "test")
8270 (set_attr "mode" "QI")])
8271
8272 ;; Combine likes to form bit extractions for some tests. Humor it.
8273 (define_insn "*testqi_ext_3"
8274 [(set (reg 17)
8275 (compare (zero_extract:SI
8276 (match_operand 0 "nonimmediate_operand" "rm")
8277 (match_operand:SI 1 "const_int_operand" "")
8278 (match_operand:SI 2 "const_int_operand" ""))
8279 (const_int 0)))]
8280 "ix86_match_ccmode (insn, CCNOmode)
8281 && (GET_MODE (operands[0]) == SImode
8282 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8283 || GET_MODE (operands[0]) == HImode
8284 || GET_MODE (operands[0]) == QImode)"
8285 "#")
8286
8287 (define_insn "*testqi_ext_3_rex64"
8288 [(set (reg 17)
8289 (compare (zero_extract:DI
8290 (match_operand 0 "nonimmediate_operand" "rm")
8291 (match_operand:DI 1 "const_int_operand" "")
8292 (match_operand:DI 2 "const_int_operand" ""))
8293 (const_int 0)))]
8294 "TARGET_64BIT
8295 && ix86_match_ccmode (insn, CCNOmode)
8296 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8297 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8298 /* Ensure that resulting mask is zero or sign extended operand. */
8299 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8300 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8301 && INTVAL (operands[1]) > 32))
8302 && (GET_MODE (operands[0]) == SImode
8303 || GET_MODE (operands[0]) == DImode
8304 || GET_MODE (operands[0]) == HImode
8305 || GET_MODE (operands[0]) == QImode)"
8306 "#")
8307
8308 (define_split
8309 [(set (reg 17)
8310 (compare (zero_extract
8311 (match_operand 0 "nonimmediate_operand" "")
8312 (match_operand 1 "const_int_operand" "")
8313 (match_operand 2 "const_int_operand" ""))
8314 (const_int 0)))]
8315 "ix86_match_ccmode (insn, CCNOmode)"
8316 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8317 {
8318 HOST_WIDE_INT len = INTVAL (operands[1]);
8319 HOST_WIDE_INT pos = INTVAL (operands[2]);
8320 HOST_WIDE_INT mask;
8321 enum machine_mode mode, submode;
8322
8323 mode = GET_MODE (operands[0]);
8324 if (GET_CODE (operands[0]) == MEM)
8325 {
8326 /* ??? Combine likes to put non-volatile mem extractions in QImode
8327 no matter the size of the test. So find a mode that works. */
8328 if (! MEM_VOLATILE_P (operands[0]))
8329 {
8330 mode = smallest_mode_for_size (pos + len, MODE_INT);
8331 operands[0] = adjust_address (operands[0], mode, 0);
8332 }
8333 }
8334 else if (GET_CODE (operands[0]) == SUBREG
8335 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8336 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8337 && pos + len <= GET_MODE_BITSIZE (submode))
8338 {
8339 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8340 mode = submode;
8341 operands[0] = SUBREG_REG (operands[0]);
8342 }
8343 else if (mode == HImode && pos + len <= 8)
8344 {
8345 /* Small HImode tests can be converted to QImode. */
8346 mode = QImode;
8347 operands[0] = gen_lowpart (QImode, operands[0]);
8348 }
8349
8350 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8351 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8352
8353 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8354 })
8355
8356 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8357 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8358 ;; this is relatively important trick.
8359 ;; Do the conversion only post-reload to avoid limiting of the register class
8360 ;; to QI regs.
8361 (define_split
8362 [(set (reg 17)
8363 (compare
8364 (and (match_operand 0 "register_operand" "")
8365 (match_operand 1 "const_int_operand" ""))
8366 (const_int 0)))]
8367 "reload_completed
8368 && QI_REG_P (operands[0])
8369 && ((ix86_match_ccmode (insn, CCZmode)
8370 && !(INTVAL (operands[1]) & ~(255 << 8)))
8371 || (ix86_match_ccmode (insn, CCNOmode)
8372 && !(INTVAL (operands[1]) & ~(127 << 8))))
8373 && GET_MODE (operands[0]) != QImode"
8374 [(set (reg:CCNO 17)
8375 (compare:CCNO
8376 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8377 (match_dup 1))
8378 (const_int 0)))]
8379 "operands[0] = gen_lowpart (SImode, operands[0]);
8380 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8381
8382 (define_split
8383 [(set (reg 17)
8384 (compare
8385 (and (match_operand 0 "nonimmediate_operand" "")
8386 (match_operand 1 "const_int_operand" ""))
8387 (const_int 0)))]
8388 "reload_completed
8389 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8390 && ((ix86_match_ccmode (insn, CCZmode)
8391 && !(INTVAL (operands[1]) & ~255))
8392 || (ix86_match_ccmode (insn, CCNOmode)
8393 && !(INTVAL (operands[1]) & ~127)))
8394 && GET_MODE (operands[0]) != QImode"
8395 [(set (reg:CCNO 17)
8396 (compare:CCNO
8397 (and:QI (match_dup 0)
8398 (match_dup 1))
8399 (const_int 0)))]
8400 "operands[0] = gen_lowpart (QImode, operands[0]);
8401 operands[1] = gen_lowpart (QImode, operands[1]);")
8402
8403
8404 ;; %%% This used to optimize known byte-wide and operations to memory,
8405 ;; and sometimes to QImode registers. If this is considered useful,
8406 ;; it should be done with splitters.
8407
8408 (define_expand "anddi3"
8409 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8410 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8411 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8412 (clobber (reg:CC 17))]
8413 "TARGET_64BIT"
8414 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8415
8416 (define_insn "*anddi_1_rex64"
8417 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8418 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8419 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8420 (clobber (reg:CC 17))]
8421 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8422 {
8423 switch (get_attr_type (insn))
8424 {
8425 case TYPE_IMOVX:
8426 {
8427 enum machine_mode mode;
8428
8429 if (GET_CODE (operands[2]) != CONST_INT)
8430 abort ();
8431 if (INTVAL (operands[2]) == 0xff)
8432 mode = QImode;
8433 else if (INTVAL (operands[2]) == 0xffff)
8434 mode = HImode;
8435 else
8436 abort ();
8437
8438 operands[1] = gen_lowpart (mode, operands[1]);
8439 if (mode == QImode)
8440 return "movz{bq|x}\t{%1,%0|%0, %1}";
8441 else
8442 return "movz{wq|x}\t{%1,%0|%0, %1}";
8443 }
8444
8445 default:
8446 if (! rtx_equal_p (operands[0], operands[1]))
8447 abort ();
8448 if (get_attr_mode (insn) == MODE_SI)
8449 return "and{l}\t{%k2, %k0|%k0, %k2}";
8450 else
8451 return "and{q}\t{%2, %0|%0, %2}";
8452 }
8453 }
8454 [(set_attr "type" "alu,alu,alu,imovx")
8455 (set_attr "length_immediate" "*,*,*,0")
8456 (set_attr "mode" "SI,DI,DI,DI")])
8457
8458 (define_insn "*anddi_2"
8459 [(set (reg 17)
8460 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8461 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8462 (const_int 0)))
8463 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8464 (and:DI (match_dup 1) (match_dup 2)))]
8465 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8466 && ix86_binary_operator_ok (AND, DImode, operands)"
8467 "@
8468 and{l}\t{%k2, %k0|%k0, %k2}
8469 and{q}\t{%2, %0|%0, %2}
8470 and{q}\t{%2, %0|%0, %2}"
8471 [(set_attr "type" "alu")
8472 (set_attr "mode" "SI,DI,DI")])
8473
8474 (define_expand "andsi3"
8475 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8476 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8477 (match_operand:SI 2 "general_operand" "")))
8478 (clobber (reg:CC 17))]
8479 ""
8480 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8481
8482 (define_insn "*andsi_1"
8483 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8484 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8485 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8486 (clobber (reg:CC 17))]
8487 "ix86_binary_operator_ok (AND, SImode, operands)"
8488 {
8489 switch (get_attr_type (insn))
8490 {
8491 case TYPE_IMOVX:
8492 {
8493 enum machine_mode mode;
8494
8495 if (GET_CODE (operands[2]) != CONST_INT)
8496 abort ();
8497 if (INTVAL (operands[2]) == 0xff)
8498 mode = QImode;
8499 else if (INTVAL (operands[2]) == 0xffff)
8500 mode = HImode;
8501 else
8502 abort ();
8503
8504 operands[1] = gen_lowpart (mode, operands[1]);
8505 if (mode == QImode)
8506 return "movz{bl|x}\t{%1,%0|%0, %1}";
8507 else
8508 return "movz{wl|x}\t{%1,%0|%0, %1}";
8509 }
8510
8511 default:
8512 if (! rtx_equal_p (operands[0], operands[1]))
8513 abort ();
8514 return "and{l}\t{%2, %0|%0, %2}";
8515 }
8516 }
8517 [(set_attr "type" "alu,alu,imovx")
8518 (set_attr "length_immediate" "*,*,0")
8519 (set_attr "mode" "SI")])
8520
8521 (define_split
8522 [(set (match_operand 0 "register_operand" "")
8523 (and (match_dup 0)
8524 (const_int -65536)))
8525 (clobber (reg:CC 17))]
8526 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8527 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8528 "operands[1] = gen_lowpart (HImode, operands[0]);")
8529
8530 (define_split
8531 [(set (match_operand 0 "ext_register_operand" "")
8532 (and (match_dup 0)
8533 (const_int -256)))
8534 (clobber (reg:CC 17))]
8535 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8536 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8537 "operands[1] = gen_lowpart (QImode, operands[0]);")
8538
8539 (define_split
8540 [(set (match_operand 0 "ext_register_operand" "")
8541 (and (match_dup 0)
8542 (const_int -65281)))
8543 (clobber (reg:CC 17))]
8544 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8545 [(parallel [(set (zero_extract:SI (match_dup 0)
8546 (const_int 8)
8547 (const_int 8))
8548 (xor:SI
8549 (zero_extract:SI (match_dup 0)
8550 (const_int 8)
8551 (const_int 8))
8552 (zero_extract:SI (match_dup 0)
8553 (const_int 8)
8554 (const_int 8))))
8555 (clobber (reg:CC 17))])]
8556 "operands[0] = gen_lowpart (SImode, operands[0]);")
8557
8558 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8559 (define_insn "*andsi_1_zext"
8560 [(set (match_operand:DI 0 "register_operand" "=r")
8561 (zero_extend:DI
8562 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8563 (match_operand:SI 2 "general_operand" "rim"))))
8564 (clobber (reg:CC 17))]
8565 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8566 "and{l}\t{%2, %k0|%k0, %2}"
8567 [(set_attr "type" "alu")
8568 (set_attr "mode" "SI")])
8569
8570 (define_insn "*andsi_2"
8571 [(set (reg 17)
8572 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8573 (match_operand:SI 2 "general_operand" "rim,ri"))
8574 (const_int 0)))
8575 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8576 (and:SI (match_dup 1) (match_dup 2)))]
8577 "ix86_match_ccmode (insn, CCNOmode)
8578 && ix86_binary_operator_ok (AND, SImode, operands)"
8579 "and{l}\t{%2, %0|%0, %2}"
8580 [(set_attr "type" "alu")
8581 (set_attr "mode" "SI")])
8582
8583 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8584 (define_insn "*andsi_2_zext"
8585 [(set (reg 17)
8586 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8587 (match_operand:SI 2 "general_operand" "rim"))
8588 (const_int 0)))
8589 (set (match_operand:DI 0 "register_operand" "=r")
8590 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8591 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8592 && ix86_binary_operator_ok (AND, SImode, operands)"
8593 "and{l}\t{%2, %k0|%k0, %2}"
8594 [(set_attr "type" "alu")
8595 (set_attr "mode" "SI")])
8596
8597 (define_expand "andhi3"
8598 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8599 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8600 (match_operand:HI 2 "general_operand" "")))
8601 (clobber (reg:CC 17))]
8602 "TARGET_HIMODE_MATH"
8603 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8604
8605 (define_insn "*andhi_1"
8606 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8607 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8608 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8609 (clobber (reg:CC 17))]
8610 "ix86_binary_operator_ok (AND, HImode, operands)"
8611 {
8612 switch (get_attr_type (insn))
8613 {
8614 case TYPE_IMOVX:
8615 if (GET_CODE (operands[2]) != CONST_INT)
8616 abort ();
8617 if (INTVAL (operands[2]) == 0xff)
8618 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8619 abort ();
8620
8621 default:
8622 if (! rtx_equal_p (operands[0], operands[1]))
8623 abort ();
8624
8625 return "and{w}\t{%2, %0|%0, %2}";
8626 }
8627 }
8628 [(set_attr "type" "alu,alu,imovx")
8629 (set_attr "length_immediate" "*,*,0")
8630 (set_attr "mode" "HI,HI,SI")])
8631
8632 (define_insn "*andhi_2"
8633 [(set (reg 17)
8634 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8635 (match_operand:HI 2 "general_operand" "rim,ri"))
8636 (const_int 0)))
8637 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8638 (and:HI (match_dup 1) (match_dup 2)))]
8639 "ix86_match_ccmode (insn, CCNOmode)
8640 && ix86_binary_operator_ok (AND, HImode, operands)"
8641 "and{w}\t{%2, %0|%0, %2}"
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "HI")])
8644
8645 (define_expand "andqi3"
8646 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8647 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8648 (match_operand:QI 2 "general_operand" "")))
8649 (clobber (reg:CC 17))]
8650 "TARGET_QIMODE_MATH"
8651 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8652
8653 ;; %%% Potential partial reg stall on alternative 2. What to do?
8654 (define_insn "*andqi_1"
8655 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8656 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8657 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8658 (clobber (reg:CC 17))]
8659 "ix86_binary_operator_ok (AND, QImode, operands)"
8660 "@
8661 and{b}\t{%2, %0|%0, %2}
8662 and{b}\t{%2, %0|%0, %2}
8663 and{l}\t{%k2, %k0|%k0, %k2}"
8664 [(set_attr "type" "alu")
8665 (set_attr "mode" "QI,QI,SI")])
8666
8667 (define_insn "*andqi_1_slp"
8668 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8669 (and:QI (match_dup 0)
8670 (match_operand:QI 1 "general_operand" "qi,qmi")))
8671 (clobber (reg:CC 17))]
8672 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8673 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8674 "and{b}\t{%1, %0|%0, %1}"
8675 [(set_attr "type" "alu1")
8676 (set_attr "mode" "QI")])
8677
8678 (define_insn "*andqi_2"
8679 [(set (reg 17)
8680 (compare (and:QI
8681 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8682 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8683 (const_int 0)))
8684 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8685 (and:QI (match_dup 1) (match_dup 2)))]
8686 "ix86_match_ccmode (insn, CCNOmode)
8687 && ix86_binary_operator_ok (AND, QImode, operands)"
8688 {
8689 if (which_alternative == 2)
8690 {
8691 if (GET_CODE (operands[2]) == CONST_INT
8692 && (INTVAL (operands[2]) & 0xffffff00))
8693 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8694 return "and{l}\t{%2, %k0|%k0, %2}";
8695 }
8696 return "and{b}\t{%2, %0|%0, %2}";
8697 }
8698 [(set_attr "type" "alu")
8699 (set_attr "mode" "QI,QI,SI")])
8700
8701 (define_insn "*andqi_2_slp"
8702 [(set (reg 17)
8703 (compare (and:QI
8704 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8705 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8706 (const_int 0)))
8707 (set (strict_low_part (match_dup 0))
8708 (and:QI (match_dup 0) (match_dup 1)))]
8709 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8710 && ix86_match_ccmode (insn, CCNOmode)
8711 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8712 "and{b}\t{%1, %0|%0, %1}"
8713 [(set_attr "type" "alu1")
8714 (set_attr "mode" "QI")])
8715
8716 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8717 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8718 ;; for a QImode operand, which of course failed.
8719
8720 (define_insn "andqi_ext_0"
8721 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8722 (const_int 8)
8723 (const_int 8))
8724 (and:SI
8725 (zero_extract:SI
8726 (match_operand 1 "ext_register_operand" "0")
8727 (const_int 8)
8728 (const_int 8))
8729 (match_operand 2 "const_int_operand" "n")))
8730 (clobber (reg:CC 17))]
8731 ""
8732 "and{b}\t{%2, %h0|%h0, %2}"
8733 [(set_attr "type" "alu")
8734 (set_attr "length_immediate" "1")
8735 (set_attr "mode" "QI")])
8736
8737 ;; Generated by peephole translating test to and. This shows up
8738 ;; often in fp comparisons.
8739
8740 (define_insn "*andqi_ext_0_cc"
8741 [(set (reg 17)
8742 (compare
8743 (and:SI
8744 (zero_extract:SI
8745 (match_operand 1 "ext_register_operand" "0")
8746 (const_int 8)
8747 (const_int 8))
8748 (match_operand 2 "const_int_operand" "n"))
8749 (const_int 0)))
8750 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8751 (const_int 8)
8752 (const_int 8))
8753 (and:SI
8754 (zero_extract:SI
8755 (match_dup 1)
8756 (const_int 8)
8757 (const_int 8))
8758 (match_dup 2)))]
8759 "ix86_match_ccmode (insn, CCNOmode)"
8760 "and{b}\t{%2, %h0|%h0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "length_immediate" "1")
8763 (set_attr "mode" "QI")])
8764
8765 (define_insn "*andqi_ext_1"
8766 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8767 (const_int 8)
8768 (const_int 8))
8769 (and:SI
8770 (zero_extract:SI
8771 (match_operand 1 "ext_register_operand" "0")
8772 (const_int 8)
8773 (const_int 8))
8774 (zero_extend:SI
8775 (match_operand:QI 2 "general_operand" "Qm"))))
8776 (clobber (reg:CC 17))]
8777 "!TARGET_64BIT"
8778 "and{b}\t{%2, %h0|%h0, %2}"
8779 [(set_attr "type" "alu")
8780 (set_attr "length_immediate" "0")
8781 (set_attr "mode" "QI")])
8782
8783 (define_insn "*andqi_ext_1_rex64"
8784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8785 (const_int 8)
8786 (const_int 8))
8787 (and:SI
8788 (zero_extract:SI
8789 (match_operand 1 "ext_register_operand" "0")
8790 (const_int 8)
8791 (const_int 8))
8792 (zero_extend:SI
8793 (match_operand 2 "ext_register_operand" "Q"))))
8794 (clobber (reg:CC 17))]
8795 "TARGET_64BIT"
8796 "and{b}\t{%2, %h0|%h0, %2}"
8797 [(set_attr "type" "alu")
8798 (set_attr "length_immediate" "0")
8799 (set_attr "mode" "QI")])
8800
8801 (define_insn "*andqi_ext_2"
8802 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8803 (const_int 8)
8804 (const_int 8))
8805 (and:SI
8806 (zero_extract:SI
8807 (match_operand 1 "ext_register_operand" "%0")
8808 (const_int 8)
8809 (const_int 8))
8810 (zero_extract:SI
8811 (match_operand 2 "ext_register_operand" "Q")
8812 (const_int 8)
8813 (const_int 8))))
8814 (clobber (reg:CC 17))]
8815 ""
8816 "and{b}\t{%h2, %h0|%h0, %h2}"
8817 [(set_attr "type" "alu")
8818 (set_attr "length_immediate" "0")
8819 (set_attr "mode" "QI")])
8820
8821 ;; Convert wide AND instructions with immediate operand to shorter QImode
8822 ;; equivalents when possible.
8823 ;; Don't do the splitting with memory operands, since it introduces risk
8824 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8825 ;; for size, but that can (should?) be handled by generic code instead.
8826 (define_split
8827 [(set (match_operand 0 "register_operand" "")
8828 (and (match_operand 1 "register_operand" "")
8829 (match_operand 2 "const_int_operand" "")))
8830 (clobber (reg:CC 17))]
8831 "reload_completed
8832 && QI_REG_P (operands[0])
8833 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8834 && !(~INTVAL (operands[2]) & ~(255 << 8))
8835 && GET_MODE (operands[0]) != QImode"
8836 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8837 (and:SI (zero_extract:SI (match_dup 1)
8838 (const_int 8) (const_int 8))
8839 (match_dup 2)))
8840 (clobber (reg:CC 17))])]
8841 "operands[0] = gen_lowpart (SImode, operands[0]);
8842 operands[1] = gen_lowpart (SImode, operands[1]);
8843 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8844
8845 ;; Since AND can be encoded with sign extended immediate, this is only
8846 ;; profitable when 7th bit is not set.
8847 (define_split
8848 [(set (match_operand 0 "register_operand" "")
8849 (and (match_operand 1 "general_operand" "")
8850 (match_operand 2 "const_int_operand" "")))
8851 (clobber (reg:CC 17))]
8852 "reload_completed
8853 && ANY_QI_REG_P (operands[0])
8854 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8855 && !(~INTVAL (operands[2]) & ~255)
8856 && !(INTVAL (operands[2]) & 128)
8857 && GET_MODE (operands[0]) != QImode"
8858 [(parallel [(set (strict_low_part (match_dup 0))
8859 (and:QI (match_dup 1)
8860 (match_dup 2)))
8861 (clobber (reg:CC 17))])]
8862 "operands[0] = gen_lowpart (QImode, operands[0]);
8863 operands[1] = gen_lowpart (QImode, operands[1]);
8864 operands[2] = gen_lowpart (QImode, operands[2]);")
8865 \f
8866 ;; Logical inclusive OR instructions
8867
8868 ;; %%% This used to optimize known byte-wide and operations to memory.
8869 ;; If this is considered useful, it should be done with splitters.
8870
8871 (define_expand "iordi3"
8872 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8873 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8874 (match_operand:DI 2 "x86_64_general_operand" "")))
8875 (clobber (reg:CC 17))]
8876 "TARGET_64BIT"
8877 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8878
8879 (define_insn "*iordi_1_rex64"
8880 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8881 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8882 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8883 (clobber (reg:CC 17))]
8884 "TARGET_64BIT
8885 && ix86_binary_operator_ok (IOR, DImode, operands)"
8886 "or{q}\t{%2, %0|%0, %2}"
8887 [(set_attr "type" "alu")
8888 (set_attr "mode" "DI")])
8889
8890 (define_insn "*iordi_2_rex64"
8891 [(set (reg 17)
8892 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8893 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8894 (const_int 0)))
8895 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8896 (ior:DI (match_dup 1) (match_dup 2)))]
8897 "TARGET_64BIT
8898 && ix86_match_ccmode (insn, CCNOmode)
8899 && ix86_binary_operator_ok (IOR, DImode, operands)"
8900 "or{q}\t{%2, %0|%0, %2}"
8901 [(set_attr "type" "alu")
8902 (set_attr "mode" "DI")])
8903
8904 (define_insn "*iordi_3_rex64"
8905 [(set (reg 17)
8906 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8907 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8908 (const_int 0)))
8909 (clobber (match_scratch:DI 0 "=r"))]
8910 "TARGET_64BIT
8911 && ix86_match_ccmode (insn, CCNOmode)
8912 && ix86_binary_operator_ok (IOR, DImode, operands)"
8913 "or{q}\t{%2, %0|%0, %2}"
8914 [(set_attr "type" "alu")
8915 (set_attr "mode" "DI")])
8916
8917
8918 (define_expand "iorsi3"
8919 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8920 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8921 (match_operand:SI 2 "general_operand" "")))
8922 (clobber (reg:CC 17))]
8923 ""
8924 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8925
8926 (define_insn "*iorsi_1"
8927 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8928 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8929 (match_operand:SI 2 "general_operand" "ri,rmi")))
8930 (clobber (reg:CC 17))]
8931 "ix86_binary_operator_ok (IOR, SImode, operands)"
8932 "or{l}\t{%2, %0|%0, %2}"
8933 [(set_attr "type" "alu")
8934 (set_attr "mode" "SI")])
8935
8936 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8937 (define_insn "*iorsi_1_zext"
8938 [(set (match_operand:DI 0 "register_operand" "=rm")
8939 (zero_extend:DI
8940 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8941 (match_operand:SI 2 "general_operand" "rim"))))
8942 (clobber (reg:CC 17))]
8943 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8944 "or{l}\t{%2, %k0|%k0, %2}"
8945 [(set_attr "type" "alu")
8946 (set_attr "mode" "SI")])
8947
8948 (define_insn "*iorsi_1_zext_imm"
8949 [(set (match_operand:DI 0 "register_operand" "=rm")
8950 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8951 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8952 (clobber (reg:CC 17))]
8953 "TARGET_64BIT"
8954 "or{l}\t{%2, %k0|%k0, %2}"
8955 [(set_attr "type" "alu")
8956 (set_attr "mode" "SI")])
8957
8958 (define_insn "*iorsi_2"
8959 [(set (reg 17)
8960 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8961 (match_operand:SI 2 "general_operand" "rim,ri"))
8962 (const_int 0)))
8963 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8964 (ior:SI (match_dup 1) (match_dup 2)))]
8965 "ix86_match_ccmode (insn, CCNOmode)
8966 && ix86_binary_operator_ok (IOR, SImode, operands)"
8967 "or{l}\t{%2, %0|%0, %2}"
8968 [(set_attr "type" "alu")
8969 (set_attr "mode" "SI")])
8970
8971 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8972 ;; ??? Special case for immediate operand is missing - it is tricky.
8973 (define_insn "*iorsi_2_zext"
8974 [(set (reg 17)
8975 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8976 (match_operand:SI 2 "general_operand" "rim"))
8977 (const_int 0)))
8978 (set (match_operand:DI 0 "register_operand" "=r")
8979 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8980 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8981 && ix86_binary_operator_ok (IOR, SImode, operands)"
8982 "or{l}\t{%2, %k0|%k0, %2}"
8983 [(set_attr "type" "alu")
8984 (set_attr "mode" "SI")])
8985
8986 (define_insn "*iorsi_2_zext_imm"
8987 [(set (reg 17)
8988 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8989 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8990 (const_int 0)))
8991 (set (match_operand:DI 0 "register_operand" "=r")
8992 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8993 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8994 && ix86_binary_operator_ok (IOR, SImode, operands)"
8995 "or{l}\t{%2, %k0|%k0, %2}"
8996 [(set_attr "type" "alu")
8997 (set_attr "mode" "SI")])
8998
8999 (define_insn "*iorsi_3"
9000 [(set (reg 17)
9001 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9002 (match_operand:SI 2 "general_operand" "rim"))
9003 (const_int 0)))
9004 (clobber (match_scratch:SI 0 "=r"))]
9005 "ix86_match_ccmode (insn, CCNOmode)
9006 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9007 "or{l}\t{%2, %0|%0, %2}"
9008 [(set_attr "type" "alu")
9009 (set_attr "mode" "SI")])
9010
9011 (define_expand "iorhi3"
9012 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9013 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9014 (match_operand:HI 2 "general_operand" "")))
9015 (clobber (reg:CC 17))]
9016 "TARGET_HIMODE_MATH"
9017 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9018
9019 (define_insn "*iorhi_1"
9020 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9021 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9022 (match_operand:HI 2 "general_operand" "rmi,ri")))
9023 (clobber (reg:CC 17))]
9024 "ix86_binary_operator_ok (IOR, HImode, operands)"
9025 "or{w}\t{%2, %0|%0, %2}"
9026 [(set_attr "type" "alu")
9027 (set_attr "mode" "HI")])
9028
9029 (define_insn "*iorhi_2"
9030 [(set (reg 17)
9031 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9032 (match_operand:HI 2 "general_operand" "rim,ri"))
9033 (const_int 0)))
9034 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9035 (ior:HI (match_dup 1) (match_dup 2)))]
9036 "ix86_match_ccmode (insn, CCNOmode)
9037 && ix86_binary_operator_ok (IOR, HImode, operands)"
9038 "or{w}\t{%2, %0|%0, %2}"
9039 [(set_attr "type" "alu")
9040 (set_attr "mode" "HI")])
9041
9042 (define_insn "*iorhi_3"
9043 [(set (reg 17)
9044 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9045 (match_operand:HI 2 "general_operand" "rim"))
9046 (const_int 0)))
9047 (clobber (match_scratch:HI 0 "=r"))]
9048 "ix86_match_ccmode (insn, CCNOmode)
9049 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9050 "or{w}\t{%2, %0|%0, %2}"
9051 [(set_attr "type" "alu")
9052 (set_attr "mode" "HI")])
9053
9054 (define_expand "iorqi3"
9055 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9056 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9057 (match_operand:QI 2 "general_operand" "")))
9058 (clobber (reg:CC 17))]
9059 "TARGET_QIMODE_MATH"
9060 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9061
9062 ;; %%% Potential partial reg stall on alternative 2. What to do?
9063 (define_insn "*iorqi_1"
9064 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9065 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9066 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9067 (clobber (reg:CC 17))]
9068 "ix86_binary_operator_ok (IOR, QImode, operands)"
9069 "@
9070 or{b}\t{%2, %0|%0, %2}
9071 or{b}\t{%2, %0|%0, %2}
9072 or{l}\t{%k2, %k0|%k0, %k2}"
9073 [(set_attr "type" "alu")
9074 (set_attr "mode" "QI,QI,SI")])
9075
9076 (define_insn "*iorqi_1_slp"
9077 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9078 (ior:QI (match_dup 0)
9079 (match_operand:QI 1 "general_operand" "qmi,qi")))
9080 (clobber (reg:CC 17))]
9081 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9082 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9083 "or{b}\t{%1, %0|%0, %1}"
9084 [(set_attr "type" "alu1")
9085 (set_attr "mode" "QI")])
9086
9087 (define_insn "*iorqi_2"
9088 [(set (reg 17)
9089 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9090 (match_operand:QI 2 "general_operand" "qim,qi"))
9091 (const_int 0)))
9092 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9093 (ior:QI (match_dup 1) (match_dup 2)))]
9094 "ix86_match_ccmode (insn, CCNOmode)
9095 && ix86_binary_operator_ok (IOR, QImode, operands)"
9096 "or{b}\t{%2, %0|%0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "QI")])
9099
9100 (define_insn "*iorqi_2_slp"
9101 [(set (reg 17)
9102 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9103 (match_operand:QI 1 "general_operand" "qim,qi"))
9104 (const_int 0)))
9105 (set (strict_low_part (match_dup 0))
9106 (ior:QI (match_dup 0) (match_dup 1)))]
9107 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9108 && ix86_match_ccmode (insn, CCNOmode)
9109 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9110 "or{b}\t{%1, %0|%0, %1}"
9111 [(set_attr "type" "alu1")
9112 (set_attr "mode" "QI")])
9113
9114 (define_insn "*iorqi_3"
9115 [(set (reg 17)
9116 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9117 (match_operand:QI 2 "general_operand" "qim"))
9118 (const_int 0)))
9119 (clobber (match_scratch:QI 0 "=q"))]
9120 "ix86_match_ccmode (insn, CCNOmode)
9121 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9122 "or{b}\t{%2, %0|%0, %2}"
9123 [(set_attr "type" "alu")
9124 (set_attr "mode" "QI")])
9125
9126 (define_insn "iorqi_ext_0"
9127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128 (const_int 8)
9129 (const_int 8))
9130 (ior:SI
9131 (zero_extract:SI
9132 (match_operand 1 "ext_register_operand" "0")
9133 (const_int 8)
9134 (const_int 8))
9135 (match_operand 2 "const_int_operand" "n")))
9136 (clobber (reg:CC 17))]
9137 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9138 "or{b}\t{%2, %h0|%h0, %2}"
9139 [(set_attr "type" "alu")
9140 (set_attr "length_immediate" "1")
9141 (set_attr "mode" "QI")])
9142
9143 (define_insn "*iorqi_ext_1"
9144 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9145 (const_int 8)
9146 (const_int 8))
9147 (ior:SI
9148 (zero_extract:SI
9149 (match_operand 1 "ext_register_operand" "0")
9150 (const_int 8)
9151 (const_int 8))
9152 (zero_extend:SI
9153 (match_operand:QI 2 "general_operand" "Qm"))))
9154 (clobber (reg:CC 17))]
9155 "!TARGET_64BIT
9156 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9157 "or{b}\t{%2, %h0|%h0, %2}"
9158 [(set_attr "type" "alu")
9159 (set_attr "length_immediate" "0")
9160 (set_attr "mode" "QI")])
9161
9162 (define_insn "*iorqi_ext_1_rex64"
9163 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9164 (const_int 8)
9165 (const_int 8))
9166 (ior:SI
9167 (zero_extract:SI
9168 (match_operand 1 "ext_register_operand" "0")
9169 (const_int 8)
9170 (const_int 8))
9171 (zero_extend:SI
9172 (match_operand 2 "ext_register_operand" "Q"))))
9173 (clobber (reg:CC 17))]
9174 "TARGET_64BIT
9175 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9176 "or{b}\t{%2, %h0|%h0, %2}"
9177 [(set_attr "type" "alu")
9178 (set_attr "length_immediate" "0")
9179 (set_attr "mode" "QI")])
9180
9181 (define_insn "*iorqi_ext_2"
9182 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9183 (const_int 8)
9184 (const_int 8))
9185 (ior:SI
9186 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9187 (const_int 8)
9188 (const_int 8))
9189 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9190 (const_int 8)
9191 (const_int 8))))
9192 (clobber (reg:CC 17))]
9193 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9194 "ior{b}\t{%h2, %h0|%h0, %h2}"
9195 [(set_attr "type" "alu")
9196 (set_attr "length_immediate" "0")
9197 (set_attr "mode" "QI")])
9198
9199 (define_split
9200 [(set (match_operand 0 "register_operand" "")
9201 (ior (match_operand 1 "register_operand" "")
9202 (match_operand 2 "const_int_operand" "")))
9203 (clobber (reg:CC 17))]
9204 "reload_completed
9205 && QI_REG_P (operands[0])
9206 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9207 && !(INTVAL (operands[2]) & ~(255 << 8))
9208 && GET_MODE (operands[0]) != QImode"
9209 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9210 (ior:SI (zero_extract:SI (match_dup 1)
9211 (const_int 8) (const_int 8))
9212 (match_dup 2)))
9213 (clobber (reg:CC 17))])]
9214 "operands[0] = gen_lowpart (SImode, operands[0]);
9215 operands[1] = gen_lowpart (SImode, operands[1]);
9216 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9217
9218 ;; Since OR can be encoded with sign extended immediate, this is only
9219 ;; profitable when 7th bit is set.
9220 (define_split
9221 [(set (match_operand 0 "register_operand" "")
9222 (ior (match_operand 1 "general_operand" "")
9223 (match_operand 2 "const_int_operand" "")))
9224 (clobber (reg:CC 17))]
9225 "reload_completed
9226 && ANY_QI_REG_P (operands[0])
9227 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9228 && !(INTVAL (operands[2]) & ~255)
9229 && (INTVAL (operands[2]) & 128)
9230 && GET_MODE (operands[0]) != QImode"
9231 [(parallel [(set (strict_low_part (match_dup 0))
9232 (ior:QI (match_dup 1)
9233 (match_dup 2)))
9234 (clobber (reg:CC 17))])]
9235 "operands[0] = gen_lowpart (QImode, operands[0]);
9236 operands[1] = gen_lowpart (QImode, operands[1]);
9237 operands[2] = gen_lowpart (QImode, operands[2]);")
9238 \f
9239 ;; Logical XOR instructions
9240
9241 ;; %%% This used to optimize known byte-wide and operations to memory.
9242 ;; If this is considered useful, it should be done with splitters.
9243
9244 (define_expand "xordi3"
9245 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9246 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9247 (match_operand:DI 2 "x86_64_general_operand" "")))
9248 (clobber (reg:CC 17))]
9249 "TARGET_64BIT"
9250 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9251
9252 (define_insn "*xordi_1_rex64"
9253 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9254 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9255 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9256 (clobber (reg:CC 17))]
9257 "TARGET_64BIT
9258 && ix86_binary_operator_ok (XOR, DImode, operands)"
9259 "@
9260 xor{q}\t{%2, %0|%0, %2}
9261 xor{q}\t{%2, %0|%0, %2}"
9262 [(set_attr "type" "alu")
9263 (set_attr "mode" "DI,DI")])
9264
9265 (define_insn "*xordi_2_rex64"
9266 [(set (reg 17)
9267 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9268 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9269 (const_int 0)))
9270 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9271 (xor:DI (match_dup 1) (match_dup 2)))]
9272 "TARGET_64BIT
9273 && ix86_match_ccmode (insn, CCNOmode)
9274 && ix86_binary_operator_ok (XOR, DImode, operands)"
9275 "@
9276 xor{q}\t{%2, %0|%0, %2}
9277 xor{q}\t{%2, %0|%0, %2}"
9278 [(set_attr "type" "alu")
9279 (set_attr "mode" "DI,DI")])
9280
9281 (define_insn "*xordi_3_rex64"
9282 [(set (reg 17)
9283 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9284 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9285 (const_int 0)))
9286 (clobber (match_scratch:DI 0 "=r"))]
9287 "TARGET_64BIT
9288 && ix86_match_ccmode (insn, CCNOmode)
9289 && ix86_binary_operator_ok (XOR, DImode, operands)"
9290 "xor{q}\t{%2, %0|%0, %2}"
9291 [(set_attr "type" "alu")
9292 (set_attr "mode" "DI")])
9293
9294 (define_expand "xorsi3"
9295 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9296 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9297 (match_operand:SI 2 "general_operand" "")))
9298 (clobber (reg:CC 17))]
9299 ""
9300 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9301
9302 (define_insn "*xorsi_1"
9303 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9304 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9305 (match_operand:SI 2 "general_operand" "ri,rm")))
9306 (clobber (reg:CC 17))]
9307 "ix86_binary_operator_ok (XOR, SImode, operands)"
9308 "xor{l}\t{%2, %0|%0, %2}"
9309 [(set_attr "type" "alu")
9310 (set_attr "mode" "SI")])
9311
9312 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9313 ;; Add speccase for immediates
9314 (define_insn "*xorsi_1_zext"
9315 [(set (match_operand:DI 0 "register_operand" "=r")
9316 (zero_extend:DI
9317 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9318 (match_operand:SI 2 "general_operand" "rim"))))
9319 (clobber (reg:CC 17))]
9320 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9321 "xor{l}\t{%2, %k0|%k0, %2}"
9322 [(set_attr "type" "alu")
9323 (set_attr "mode" "SI")])
9324
9325 (define_insn "*xorsi_1_zext_imm"
9326 [(set (match_operand:DI 0 "register_operand" "=r")
9327 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9328 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9329 (clobber (reg:CC 17))]
9330 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9331 "xor{l}\t{%2, %k0|%k0, %2}"
9332 [(set_attr "type" "alu")
9333 (set_attr "mode" "SI")])
9334
9335 (define_insn "*xorsi_2"
9336 [(set (reg 17)
9337 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9338 (match_operand:SI 2 "general_operand" "rim,ri"))
9339 (const_int 0)))
9340 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9341 (xor:SI (match_dup 1) (match_dup 2)))]
9342 "ix86_match_ccmode (insn, CCNOmode)
9343 && ix86_binary_operator_ok (XOR, SImode, operands)"
9344 "xor{l}\t{%2, %0|%0, %2}"
9345 [(set_attr "type" "alu")
9346 (set_attr "mode" "SI")])
9347
9348 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9349 ;; ??? Special case for immediate operand is missing - it is tricky.
9350 (define_insn "*xorsi_2_zext"
9351 [(set (reg 17)
9352 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9353 (match_operand:SI 2 "general_operand" "rim"))
9354 (const_int 0)))
9355 (set (match_operand:DI 0 "register_operand" "=r")
9356 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9357 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9358 && ix86_binary_operator_ok (XOR, SImode, operands)"
9359 "xor{l}\t{%2, %k0|%k0, %2}"
9360 [(set_attr "type" "alu")
9361 (set_attr "mode" "SI")])
9362
9363 (define_insn "*xorsi_2_zext_imm"
9364 [(set (reg 17)
9365 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9366 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9367 (const_int 0)))
9368 (set (match_operand:DI 0 "register_operand" "=r")
9369 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9370 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9371 && ix86_binary_operator_ok (XOR, SImode, operands)"
9372 "xor{l}\t{%2, %k0|%k0, %2}"
9373 [(set_attr "type" "alu")
9374 (set_attr "mode" "SI")])
9375
9376 (define_insn "*xorsi_3"
9377 [(set (reg 17)
9378 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9379 (match_operand:SI 2 "general_operand" "rim"))
9380 (const_int 0)))
9381 (clobber (match_scratch:SI 0 "=r"))]
9382 "ix86_match_ccmode (insn, CCNOmode)
9383 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9384 "xor{l}\t{%2, %0|%0, %2}"
9385 [(set_attr "type" "alu")
9386 (set_attr "mode" "SI")])
9387
9388 (define_expand "xorhi3"
9389 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9390 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9391 (match_operand:HI 2 "general_operand" "")))
9392 (clobber (reg:CC 17))]
9393 "TARGET_HIMODE_MATH"
9394 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9395
9396 (define_insn "*xorhi_1"
9397 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9398 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9399 (match_operand:HI 2 "general_operand" "rmi,ri")))
9400 (clobber (reg:CC 17))]
9401 "ix86_binary_operator_ok (XOR, HImode, operands)"
9402 "xor{w}\t{%2, %0|%0, %2}"
9403 [(set_attr "type" "alu")
9404 (set_attr "mode" "HI")])
9405
9406 (define_insn "*xorhi_2"
9407 [(set (reg 17)
9408 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9409 (match_operand:HI 2 "general_operand" "rim,ri"))
9410 (const_int 0)))
9411 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9412 (xor:HI (match_dup 1) (match_dup 2)))]
9413 "ix86_match_ccmode (insn, CCNOmode)
9414 && ix86_binary_operator_ok (XOR, HImode, operands)"
9415 "xor{w}\t{%2, %0|%0, %2}"
9416 [(set_attr "type" "alu")
9417 (set_attr "mode" "HI")])
9418
9419 (define_insn "*xorhi_3"
9420 [(set (reg 17)
9421 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9422 (match_operand:HI 2 "general_operand" "rim"))
9423 (const_int 0)))
9424 (clobber (match_scratch:HI 0 "=r"))]
9425 "ix86_match_ccmode (insn, CCNOmode)
9426 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9427 "xor{w}\t{%2, %0|%0, %2}"
9428 [(set_attr "type" "alu")
9429 (set_attr "mode" "HI")])
9430
9431 (define_expand "xorqi3"
9432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9433 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9434 (match_operand:QI 2 "general_operand" "")))
9435 (clobber (reg:CC 17))]
9436 "TARGET_QIMODE_MATH"
9437 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9438
9439 ;; %%% Potential partial reg stall on alternative 2. What to do?
9440 (define_insn "*xorqi_1"
9441 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9442 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9443 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9444 (clobber (reg:CC 17))]
9445 "ix86_binary_operator_ok (XOR, QImode, operands)"
9446 "@
9447 xor{b}\t{%2, %0|%0, %2}
9448 xor{b}\t{%2, %0|%0, %2}
9449 xor{l}\t{%k2, %k0|%k0, %k2}"
9450 [(set_attr "type" "alu")
9451 (set_attr "mode" "QI,QI,SI")])
9452
9453 (define_insn "*xorqi_1_slp"
9454 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9455 (xor:QI (match_dup 0)
9456 (match_operand:QI 1 "general_operand" "qi,qmi")))
9457 (clobber (reg:CC 17))]
9458 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9459 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9460 "xor{b}\t{%1, %0|%0, %1}"
9461 [(set_attr "type" "alu1")
9462 (set_attr "mode" "QI")])
9463
9464 (define_insn "xorqi_ext_0"
9465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9466 (const_int 8)
9467 (const_int 8))
9468 (xor:SI
9469 (zero_extract:SI
9470 (match_operand 1 "ext_register_operand" "0")
9471 (const_int 8)
9472 (const_int 8))
9473 (match_operand 2 "const_int_operand" "n")))
9474 (clobber (reg:CC 17))]
9475 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9476 "xor{b}\t{%2, %h0|%h0, %2}"
9477 [(set_attr "type" "alu")
9478 (set_attr "length_immediate" "1")
9479 (set_attr "mode" "QI")])
9480
9481 (define_insn "*xorqi_ext_1"
9482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9483 (const_int 8)
9484 (const_int 8))
9485 (xor:SI
9486 (zero_extract:SI
9487 (match_operand 1 "ext_register_operand" "0")
9488 (const_int 8)
9489 (const_int 8))
9490 (zero_extend:SI
9491 (match_operand:QI 2 "general_operand" "Qm"))))
9492 (clobber (reg:CC 17))]
9493 "!TARGET_64BIT
9494 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9495 "xor{b}\t{%2, %h0|%h0, %2}"
9496 [(set_attr "type" "alu")
9497 (set_attr "length_immediate" "0")
9498 (set_attr "mode" "QI")])
9499
9500 (define_insn "*xorqi_ext_1_rex64"
9501 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9502 (const_int 8)
9503 (const_int 8))
9504 (xor:SI
9505 (zero_extract:SI
9506 (match_operand 1 "ext_register_operand" "0")
9507 (const_int 8)
9508 (const_int 8))
9509 (zero_extend:SI
9510 (match_operand 2 "ext_register_operand" "Q"))))
9511 (clobber (reg:CC 17))]
9512 "TARGET_64BIT
9513 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9514 "xor{b}\t{%2, %h0|%h0, %2}"
9515 [(set_attr "type" "alu")
9516 (set_attr "length_immediate" "0")
9517 (set_attr "mode" "QI")])
9518
9519 (define_insn "*xorqi_ext_2"
9520 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9521 (const_int 8)
9522 (const_int 8))
9523 (xor:SI
9524 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9525 (const_int 8)
9526 (const_int 8))
9527 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9528 (const_int 8)
9529 (const_int 8))))
9530 (clobber (reg:CC 17))]
9531 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9532 "xor{b}\t{%h2, %h0|%h0, %h2}"
9533 [(set_attr "type" "alu")
9534 (set_attr "length_immediate" "0")
9535 (set_attr "mode" "QI")])
9536
9537 (define_insn "*xorqi_cc_1"
9538 [(set (reg 17)
9539 (compare
9540 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9541 (match_operand:QI 2 "general_operand" "qim,qi"))
9542 (const_int 0)))
9543 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9544 (xor:QI (match_dup 1) (match_dup 2)))]
9545 "ix86_match_ccmode (insn, CCNOmode)
9546 && ix86_binary_operator_ok (XOR, QImode, operands)"
9547 "xor{b}\t{%2, %0|%0, %2}"
9548 [(set_attr "type" "alu")
9549 (set_attr "mode" "QI")])
9550
9551 (define_insn "*xorqi_2_slp"
9552 [(set (reg 17)
9553 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9554 (match_operand:QI 1 "general_operand" "qim,qi"))
9555 (const_int 0)))
9556 (set (strict_low_part (match_dup 0))
9557 (xor:QI (match_dup 0) (match_dup 1)))]
9558 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9559 && ix86_match_ccmode (insn, CCNOmode)
9560 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9561 "xor{b}\t{%1, %0|%0, %1}"
9562 [(set_attr "type" "alu1")
9563 (set_attr "mode" "QI")])
9564
9565 (define_insn "*xorqi_cc_2"
9566 [(set (reg 17)
9567 (compare
9568 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9569 (match_operand:QI 2 "general_operand" "qim"))
9570 (const_int 0)))
9571 (clobber (match_scratch:QI 0 "=q"))]
9572 "ix86_match_ccmode (insn, CCNOmode)
9573 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9574 "xor{b}\t{%2, %0|%0, %2}"
9575 [(set_attr "type" "alu")
9576 (set_attr "mode" "QI")])
9577
9578 (define_insn "*xorqi_cc_ext_1"
9579 [(set (reg 17)
9580 (compare
9581 (xor:SI
9582 (zero_extract:SI
9583 (match_operand 1 "ext_register_operand" "0")
9584 (const_int 8)
9585 (const_int 8))
9586 (match_operand:QI 2 "general_operand" "qmn"))
9587 (const_int 0)))
9588 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9589 (const_int 8)
9590 (const_int 8))
9591 (xor:SI
9592 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9593 (match_dup 2)))]
9594 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9595 "xor{b}\t{%2, %h0|%h0, %2}"
9596 [(set_attr "type" "alu")
9597 (set_attr "mode" "QI")])
9598
9599 (define_insn "*xorqi_cc_ext_1_rex64"
9600 [(set (reg 17)
9601 (compare
9602 (xor:SI
9603 (zero_extract:SI
9604 (match_operand 1 "ext_register_operand" "0")
9605 (const_int 8)
9606 (const_int 8))
9607 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9608 (const_int 0)))
9609 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9610 (const_int 8)
9611 (const_int 8))
9612 (xor:SI
9613 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9614 (match_dup 2)))]
9615 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9616 "xor{b}\t{%2, %h0|%h0, %2}"
9617 [(set_attr "type" "alu")
9618 (set_attr "mode" "QI")])
9619
9620 (define_expand "xorqi_cc_ext_1"
9621 [(parallel [
9622 (set (reg:CCNO 17)
9623 (compare:CCNO
9624 (xor:SI
9625 (zero_extract:SI
9626 (match_operand 1 "ext_register_operand" "")
9627 (const_int 8)
9628 (const_int 8))
9629 (match_operand:QI 2 "general_operand" ""))
9630 (const_int 0)))
9631 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9632 (const_int 8)
9633 (const_int 8))
9634 (xor:SI
9635 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9636 (match_dup 2)))])]
9637 ""
9638 "")
9639
9640 (define_split
9641 [(set (match_operand 0 "register_operand" "")
9642 (xor (match_operand 1 "register_operand" "")
9643 (match_operand 2 "const_int_operand" "")))
9644 (clobber (reg:CC 17))]
9645 "reload_completed
9646 && QI_REG_P (operands[0])
9647 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9648 && !(INTVAL (operands[2]) & ~(255 << 8))
9649 && GET_MODE (operands[0]) != QImode"
9650 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9651 (xor:SI (zero_extract:SI (match_dup 1)
9652 (const_int 8) (const_int 8))
9653 (match_dup 2)))
9654 (clobber (reg:CC 17))])]
9655 "operands[0] = gen_lowpart (SImode, operands[0]);
9656 operands[1] = gen_lowpart (SImode, operands[1]);
9657 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9658
9659 ;; Since XOR can be encoded with sign extended immediate, this is only
9660 ;; profitable when 7th bit is set.
9661 (define_split
9662 [(set (match_operand 0 "register_operand" "")
9663 (xor (match_operand 1 "general_operand" "")
9664 (match_operand 2 "const_int_operand" "")))
9665 (clobber (reg:CC 17))]
9666 "reload_completed
9667 && ANY_QI_REG_P (operands[0])
9668 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9669 && !(INTVAL (operands[2]) & ~255)
9670 && (INTVAL (operands[2]) & 128)
9671 && GET_MODE (operands[0]) != QImode"
9672 [(parallel [(set (strict_low_part (match_dup 0))
9673 (xor:QI (match_dup 1)
9674 (match_dup 2)))
9675 (clobber (reg:CC 17))])]
9676 "operands[0] = gen_lowpart (QImode, operands[0]);
9677 operands[1] = gen_lowpart (QImode, operands[1]);
9678 operands[2] = gen_lowpart (QImode, operands[2]);")
9679 \f
9680 ;; Negation instructions
9681
9682 (define_expand "negdi2"
9683 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9684 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9685 (clobber (reg:CC 17))])]
9686 ""
9687 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9688
9689 (define_insn "*negdi2_1"
9690 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9691 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9692 (clobber (reg:CC 17))]
9693 "!TARGET_64BIT
9694 && ix86_unary_operator_ok (NEG, DImode, operands)"
9695 "#")
9696
9697 (define_split
9698 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9699 (neg:DI (match_operand:DI 1 "general_operand" "")))
9700 (clobber (reg:CC 17))]
9701 "!TARGET_64BIT && reload_completed"
9702 [(parallel
9703 [(set (reg:CCZ 17)
9704 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9705 (set (match_dup 0) (neg:SI (match_dup 2)))])
9706 (parallel
9707 [(set (match_dup 1)
9708 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9709 (match_dup 3))
9710 (const_int 0)))
9711 (clobber (reg:CC 17))])
9712 (parallel
9713 [(set (match_dup 1)
9714 (neg:SI (match_dup 1)))
9715 (clobber (reg:CC 17))])]
9716 "split_di (operands+1, 1, operands+2, operands+3);
9717 split_di (operands+0, 1, operands+0, operands+1);")
9718
9719 (define_insn "*negdi2_1_rex64"
9720 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9721 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9722 (clobber (reg:CC 17))]
9723 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9724 "neg{q}\t%0"
9725 [(set_attr "type" "negnot")
9726 (set_attr "mode" "DI")])
9727
9728 ;; The problem with neg is that it does not perform (compare x 0),
9729 ;; it really performs (compare 0 x), which leaves us with the zero
9730 ;; flag being the only useful item.
9731
9732 (define_insn "*negdi2_cmpz_rex64"
9733 [(set (reg:CCZ 17)
9734 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9735 (const_int 0)))
9736 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9737 (neg:DI (match_dup 1)))]
9738 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9739 "neg{q}\t%0"
9740 [(set_attr "type" "negnot")
9741 (set_attr "mode" "DI")])
9742
9743
9744 (define_expand "negsi2"
9745 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9746 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9747 (clobber (reg:CC 17))])]
9748 ""
9749 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9750
9751 (define_insn "*negsi2_1"
9752 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9753 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9754 (clobber (reg:CC 17))]
9755 "ix86_unary_operator_ok (NEG, SImode, operands)"
9756 "neg{l}\t%0"
9757 [(set_attr "type" "negnot")
9758 (set_attr "mode" "SI")])
9759
9760 ;; Combine is quite creative about this pattern.
9761 (define_insn "*negsi2_1_zext"
9762 [(set (match_operand:DI 0 "register_operand" "=r")
9763 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9764 (const_int 32)))
9765 (const_int 32)))
9766 (clobber (reg:CC 17))]
9767 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9768 "neg{l}\t%k0"
9769 [(set_attr "type" "negnot")
9770 (set_attr "mode" "SI")])
9771
9772 ;; The problem with neg is that it does not perform (compare x 0),
9773 ;; it really performs (compare 0 x), which leaves us with the zero
9774 ;; flag being the only useful item.
9775
9776 (define_insn "*negsi2_cmpz"
9777 [(set (reg:CCZ 17)
9778 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9779 (const_int 0)))
9780 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9781 (neg:SI (match_dup 1)))]
9782 "ix86_unary_operator_ok (NEG, SImode, operands)"
9783 "neg{l}\t%0"
9784 [(set_attr "type" "negnot")
9785 (set_attr "mode" "SI")])
9786
9787 (define_insn "*negsi2_cmpz_zext"
9788 [(set (reg:CCZ 17)
9789 (compare:CCZ (lshiftrt:DI
9790 (neg:DI (ashift:DI
9791 (match_operand:DI 1 "register_operand" "0")
9792 (const_int 32)))
9793 (const_int 32))
9794 (const_int 0)))
9795 (set (match_operand:DI 0 "register_operand" "=r")
9796 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9797 (const_int 32)))
9798 (const_int 32)))]
9799 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9800 "neg{l}\t%k0"
9801 [(set_attr "type" "negnot")
9802 (set_attr "mode" "SI")])
9803
9804 (define_expand "neghi2"
9805 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9806 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9807 (clobber (reg:CC 17))])]
9808 "TARGET_HIMODE_MATH"
9809 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9810
9811 (define_insn "*neghi2_1"
9812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9813 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9814 (clobber (reg:CC 17))]
9815 "ix86_unary_operator_ok (NEG, HImode, operands)"
9816 "neg{w}\t%0"
9817 [(set_attr "type" "negnot")
9818 (set_attr "mode" "HI")])
9819
9820 (define_insn "*neghi2_cmpz"
9821 [(set (reg:CCZ 17)
9822 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9823 (const_int 0)))
9824 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9825 (neg:HI (match_dup 1)))]
9826 "ix86_unary_operator_ok (NEG, HImode, operands)"
9827 "neg{w}\t%0"
9828 [(set_attr "type" "negnot")
9829 (set_attr "mode" "HI")])
9830
9831 (define_expand "negqi2"
9832 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9833 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9834 (clobber (reg:CC 17))])]
9835 "TARGET_QIMODE_MATH"
9836 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9837
9838 (define_insn "*negqi2_1"
9839 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9840 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9841 (clobber (reg:CC 17))]
9842 "ix86_unary_operator_ok (NEG, QImode, operands)"
9843 "neg{b}\t%0"
9844 [(set_attr "type" "negnot")
9845 (set_attr "mode" "QI")])
9846
9847 (define_insn "*negqi2_cmpz"
9848 [(set (reg:CCZ 17)
9849 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9850 (const_int 0)))
9851 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9852 (neg:QI (match_dup 1)))]
9853 "ix86_unary_operator_ok (NEG, QImode, operands)"
9854 "neg{b}\t%0"
9855 [(set_attr "type" "negnot")
9856 (set_attr "mode" "QI")])
9857
9858 ;; Changing of sign for FP values is doable using integer unit too.
9859
9860 (define_expand "negsf2"
9861 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9862 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9863 (clobber (reg:CC 17))])]
9864 "TARGET_80387"
9865 "if (TARGET_SSE)
9866 {
9867 /* In case operand is in memory, we will not use SSE. */
9868 if (memory_operand (operands[0], VOIDmode)
9869 && rtx_equal_p (operands[0], operands[1]))
9870 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9871 else
9872 {
9873 /* Using SSE is tricky, since we need bitwise negation of -0
9874 in register. */
9875 rtx reg = gen_reg_rtx (SFmode);
9876 rtx dest = operands[0];
9877 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9878
9879 operands[1] = force_reg (SFmode, operands[1]);
9880 operands[0] = force_reg (SFmode, operands[0]);
9881 reg = force_reg (V4SFmode,
9882 gen_rtx_CONST_VECTOR (V4SFmode,
9883 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9884 CONST0_RTX (SFmode),
9885 CONST0_RTX (SFmode))));
9886 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9887 if (dest != operands[0])
9888 emit_move_insn (dest, operands[0]);
9889 }
9890 DONE;
9891 }
9892 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9893
9894 (define_insn "negsf2_memory"
9895 [(set (match_operand:SF 0 "memory_operand" "=m")
9896 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9897 (clobber (reg:CC 17))]
9898 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9899 "#")
9900
9901 (define_insn "negsf2_ifs"
9902 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9903 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9904 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9905 (clobber (reg:CC 17))]
9906 "TARGET_SSE
9907 && (reload_in_progress || reload_completed
9908 || (register_operand (operands[0], VOIDmode)
9909 && register_operand (operands[1], VOIDmode)))"
9910 "#")
9911
9912 (define_split
9913 [(set (match_operand:SF 0 "memory_operand" "")
9914 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9915 (use (match_operand:SF 2 "" ""))
9916 (clobber (reg:CC 17))]
9917 ""
9918 [(parallel [(set (match_dup 0)
9919 (neg:SF (match_dup 1)))
9920 (clobber (reg:CC 17))])])
9921
9922 (define_split
9923 [(set (match_operand:SF 0 "register_operand" "")
9924 (neg:SF (match_operand:SF 1 "register_operand" "")))
9925 (use (match_operand:V4SF 2 "" ""))
9926 (clobber (reg:CC 17))]
9927 "reload_completed && !SSE_REG_P (operands[0])"
9928 [(parallel [(set (match_dup 0)
9929 (neg:SF (match_dup 1)))
9930 (clobber (reg:CC 17))])])
9931
9932 (define_split
9933 [(set (match_operand:SF 0 "register_operand" "")
9934 (neg:SF (match_operand:SF 1 "register_operand" "")))
9935 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9936 (clobber (reg:CC 17))]
9937 "reload_completed && SSE_REG_P (operands[0])"
9938 [(set (subreg:TI (match_dup 0) 0)
9939 (xor:TI (match_dup 1)
9940 (match_dup 2)))]
9941 {
9942 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9943 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9944 if (operands_match_p (operands[0], operands[2]))
9945 {
9946 rtx tmp;
9947 tmp = operands[1];
9948 operands[1] = operands[2];
9949 operands[2] = tmp;
9950 }
9951 })
9952
9953
9954 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9955 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9956 ;; to itself.
9957 (define_insn "*negsf2_if"
9958 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9959 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9960 (clobber (reg:CC 17))]
9961 "TARGET_80387 && !TARGET_SSE
9962 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9963 "#")
9964
9965 (define_split
9966 [(set (match_operand:SF 0 "fp_register_operand" "")
9967 (neg:SF (match_operand:SF 1 "register_operand" "")))
9968 (clobber (reg:CC 17))]
9969 "TARGET_80387 && reload_completed"
9970 [(set (match_dup 0)
9971 (neg:SF (match_dup 1)))]
9972 "")
9973
9974 (define_split
9975 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9976 (neg:SF (match_operand:SF 1 "register_operand" "")))
9977 (clobber (reg:CC 17))]
9978 "TARGET_80387 && reload_completed"
9979 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9980 (clobber (reg:CC 17))])]
9981 "operands[1] = gen_int_mode (0x80000000, SImode);
9982 operands[0] = gen_lowpart (SImode, operands[0]);")
9983
9984 (define_split
9985 [(set (match_operand 0 "memory_operand" "")
9986 (neg (match_operand 1 "memory_operand" "")))
9987 (clobber (reg:CC 17))]
9988 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9989 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9990 (clobber (reg:CC 17))])]
9991 {
9992 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9993
9994 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9995 if (size >= 12)
9996 size = 10;
9997 operands[0] = adjust_address (operands[0], QImode, size - 1);
9998 operands[1] = gen_int_mode (0x80, QImode);
9999 })
10000
10001 (define_expand "negdf2"
10002 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10003 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10004 (clobber (reg:CC 17))])]
10005 "TARGET_80387"
10006 "if (TARGET_SSE2)
10007 {
10008 /* In case operand is in memory, we will not use SSE. */
10009 if (memory_operand (operands[0], VOIDmode)
10010 && rtx_equal_p (operands[0], operands[1]))
10011 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
10012 else
10013 {
10014 /* Using SSE is tricky, since we need bitwise negation of -0
10015 in register. */
10016 rtx reg;
10017 #if HOST_BITS_PER_WIDE_INT >= 64
10018 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
10019 #else
10020 rtx imm = immed_double_const (0, 0x80000000, DImode);
10021 #endif
10022 rtx dest = operands[0];
10023
10024 operands[1] = force_reg (DFmode, operands[1]);
10025 operands[0] = force_reg (DFmode, operands[0]);
10026 imm = gen_lowpart (DFmode, imm);
10027 reg = force_reg (V2DFmode,
10028 gen_rtx_CONST_VECTOR (V2DFmode,
10029 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10030 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
10031 if (dest != operands[0])
10032 emit_move_insn (dest, operands[0]);
10033 }
10034 DONE;
10035 }
10036 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
10037
10038 (define_insn "negdf2_memory"
10039 [(set (match_operand:DF 0 "memory_operand" "=m")
10040 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
10041 (clobber (reg:CC 17))]
10042 "ix86_unary_operator_ok (NEG, DFmode, operands)"
10043 "#")
10044
10045 (define_insn "negdf2_ifs"
10046 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
10047 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10048 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10049 (clobber (reg:CC 17))]
10050 "!TARGET_64BIT && TARGET_SSE2
10051 && (reload_in_progress || reload_completed
10052 || (register_operand (operands[0], VOIDmode)
10053 && register_operand (operands[1], VOIDmode)))"
10054 "#")
10055
10056 (define_insn "*negdf2_ifs_rex64"
10057 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
10058 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10059 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10060 (clobber (reg:CC 17))]
10061 "TARGET_64BIT && TARGET_SSE2
10062 && (reload_in_progress || reload_completed
10063 || (register_operand (operands[0], VOIDmode)
10064 && register_operand (operands[1], VOIDmode)))"
10065 "#")
10066
10067 (define_split
10068 [(set (match_operand:DF 0 "memory_operand" "")
10069 (neg:DF (match_operand:DF 1 "memory_operand" "")))
10070 (use (match_operand:V2DF 2 "" ""))
10071 (clobber (reg:CC 17))]
10072 ""
10073 [(parallel [(set (match_dup 0)
10074 (neg:DF (match_dup 1)))
10075 (clobber (reg:CC 17))])])
10076
10077 (define_split
10078 [(set (match_operand:DF 0 "register_operand" "")
10079 (neg:DF (match_operand:DF 1 "register_operand" "")))
10080 (use (match_operand:V2DF 2 "" ""))
10081 (clobber (reg:CC 17))]
10082 "reload_completed && !SSE_REG_P (operands[0])
10083 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
10084 [(parallel [(set (match_dup 0)
10085 (neg:DF (match_dup 1)))
10086 (clobber (reg:CC 17))])])
10087
10088 (define_split
10089 [(set (match_operand:DF 0 "register_operand" "")
10090 (neg:DF (match_operand:DF 1 "register_operand" "")))
10091 (use (match_operand:V2DF 2 "" ""))
10092 (clobber (reg:CC 17))]
10093 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
10094 [(parallel [(set (match_dup 0)
10095 (xor:DI (match_dup 1) (match_dup 2)))
10096 (clobber (reg:CC 17))])]
10097 "operands[0] = gen_lowpart (DImode, operands[0]);
10098 operands[1] = gen_lowpart (DImode, operands[1]);
10099 operands[2] = gen_lowpart (DImode, operands[2]);")
10100
10101 (define_split
10102 [(set (match_operand:DF 0 "register_operand" "")
10103 (neg:DF (match_operand:DF 1 "register_operand" "")))
10104 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10105 (clobber (reg:CC 17))]
10106 "reload_completed && SSE_REG_P (operands[0])"
10107 [(set (subreg:TI (match_dup 0) 0)
10108 (xor:TI (match_dup 1)
10109 (match_dup 2)))]
10110 {
10111 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10112 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10113 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10114 /* Avoid possible reformatting on the operands. */
10115 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10116 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10117 if (operands_match_p (operands[0], operands[2]))
10118 {
10119 rtx tmp;
10120 tmp = operands[1];
10121 operands[1] = operands[2];
10122 operands[2] = tmp;
10123 }
10124 })
10125
10126 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10127 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10128 ;; to itself.
10129 (define_insn "*negdf2_if"
10130 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10131 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10132 (clobber (reg:CC 17))]
10133 "!TARGET_64BIT && TARGET_80387
10134 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10135 "#")
10136
10137 ;; FIXME: We should to allow integer registers here. Problem is that
10138 ;; we need another scratch register to get constant from.
10139 ;; Forcing constant to mem if no register available in peep2 should be
10140 ;; safe even for PIC mode, because of RIP relative addressing.
10141 (define_insn "*negdf2_if_rex64"
10142 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10143 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10144 (clobber (reg:CC 17))]
10145 "TARGET_64BIT && TARGET_80387
10146 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10147 "#")
10148
10149 (define_split
10150 [(set (match_operand:DF 0 "fp_register_operand" "")
10151 (neg:DF (match_operand:DF 1 "register_operand" "")))
10152 (clobber (reg:CC 17))]
10153 "TARGET_80387 && reload_completed"
10154 [(set (match_dup 0)
10155 (neg:DF (match_dup 1)))]
10156 "")
10157
10158 (define_split
10159 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10160 (neg:DF (match_operand:DF 1 "register_operand" "")))
10161 (clobber (reg:CC 17))]
10162 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10163 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
10164 (clobber (reg:CC 17))])]
10165 "operands[4] = gen_int_mode (0x80000000, SImode);
10166 split_di (operands+0, 1, operands+2, operands+3);")
10167
10168 (define_expand "negxf2"
10169 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10170 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10171 (clobber (reg:CC 17))])]
10172 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10173 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
10174
10175 (define_expand "negtf2"
10176 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10177 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10178 (clobber (reg:CC 17))])]
10179 "TARGET_80387"
10180 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
10181
10182 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10183 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10184 ;; to itself.
10185 (define_insn "*negxf2_if"
10186 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10187 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10188 (clobber (reg:CC 17))]
10189 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10190 && ix86_unary_operator_ok (NEG, XFmode, operands)"
10191 "#")
10192
10193 (define_split
10194 [(set (match_operand:XF 0 "fp_register_operand" "")
10195 (neg:XF (match_operand:XF 1 "register_operand" "")))
10196 (clobber (reg:CC 17))]
10197 "TARGET_80387 && reload_completed"
10198 [(set (match_dup 0)
10199 (neg:XF (match_dup 1)))]
10200 "")
10201
10202 (define_split
10203 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10204 (neg:XF (match_operand:XF 1 "register_operand" "")))
10205 (clobber (reg:CC 17))]
10206 "TARGET_80387 && reload_completed"
10207 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10208 (clobber (reg:CC 17))])]
10209 "operands[1] = GEN_INT (0x8000);
10210 operands[0] = gen_rtx_REG (SImode,
10211 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10212
10213 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10214 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10215 ;; to itself.
10216 (define_insn "*negtf2_if"
10217 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10218 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10219 (clobber (reg:CC 17))]
10220 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
10221 "#")
10222
10223 (define_split
10224 [(set (match_operand:TF 0 "fp_register_operand" "")
10225 (neg:TF (match_operand:TF 1 "register_operand" "")))
10226 (clobber (reg:CC 17))]
10227 "TARGET_80387 && reload_completed"
10228 [(set (match_dup 0)
10229 (neg:TF (match_dup 1)))]
10230 "")
10231
10232 (define_split
10233 [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
10234 (neg:TF (match_operand:TF 1 "register_operand" "")))
10235 (clobber (reg:CC 17))]
10236 "TARGET_80387 && reload_completed"
10237 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10238 (clobber (reg:CC 17))])]
10239 "operands[1] = GEN_INT (0x8000);
10240 operands[0] = gen_rtx_REG (SImode,
10241 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10242
10243 ;; Conditionalize these after reload. If they matches before reload, we
10244 ;; lose the clobber and ability to use integer instructions.
10245
10246 (define_insn "*negsf2_1"
10247 [(set (match_operand:SF 0 "register_operand" "=f")
10248 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10249 "TARGET_80387 && reload_completed"
10250 "fchs"
10251 [(set_attr "type" "fsgn")
10252 (set_attr "mode" "SF")
10253 (set_attr "ppro_uops" "few")])
10254
10255 (define_insn "*negdf2_1"
10256 [(set (match_operand:DF 0 "register_operand" "=f")
10257 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10258 "TARGET_80387 && reload_completed"
10259 "fchs"
10260 [(set_attr "type" "fsgn")
10261 (set_attr "mode" "DF")
10262 (set_attr "ppro_uops" "few")])
10263
10264 (define_insn "*negextendsfdf2"
10265 [(set (match_operand:DF 0 "register_operand" "=f")
10266 (neg:DF (float_extend:DF
10267 (match_operand:SF 1 "register_operand" "0"))))]
10268 "TARGET_80387"
10269 "fchs"
10270 [(set_attr "type" "fsgn")
10271 (set_attr "mode" "DF")
10272 (set_attr "ppro_uops" "few")])
10273
10274 (define_insn "*negxf2_1"
10275 [(set (match_operand:XF 0 "register_operand" "=f")
10276 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10277 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10278 "fchs"
10279 [(set_attr "type" "fsgn")
10280 (set_attr "mode" "XF")
10281 (set_attr "ppro_uops" "few")])
10282
10283 (define_insn "*negextenddfxf2"
10284 [(set (match_operand:XF 0 "register_operand" "=f")
10285 (neg:XF (float_extend:XF
10286 (match_operand:DF 1 "register_operand" "0"))))]
10287 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10288 "fchs"
10289 [(set_attr "type" "fsgn")
10290 (set_attr "mode" "XF")
10291 (set_attr "ppro_uops" "few")])
10292
10293 (define_insn "*negextendsfxf2"
10294 [(set (match_operand:XF 0 "register_operand" "=f")
10295 (neg:XF (float_extend:XF
10296 (match_operand:SF 1 "register_operand" "0"))))]
10297 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10298 "fchs"
10299 [(set_attr "type" "fsgn")
10300 (set_attr "mode" "XF")
10301 (set_attr "ppro_uops" "few")])
10302
10303 (define_insn "*negtf2_1"
10304 [(set (match_operand:TF 0 "register_operand" "=f")
10305 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
10306 "TARGET_80387 && reload_completed"
10307 "fchs"
10308 [(set_attr "type" "fsgn")
10309 (set_attr "mode" "XF")
10310 (set_attr "ppro_uops" "few")])
10311
10312 (define_insn "*negextenddftf2"
10313 [(set (match_operand:TF 0 "register_operand" "=f")
10314 (neg:TF (float_extend:TF
10315 (match_operand:DF 1 "register_operand" "0"))))]
10316 "TARGET_80387"
10317 "fchs"
10318 [(set_attr "type" "fsgn")
10319 (set_attr "mode" "XF")
10320 (set_attr "ppro_uops" "few")])
10321
10322 (define_insn "*negextendsftf2"
10323 [(set (match_operand:TF 0 "register_operand" "=f")
10324 (neg:TF (float_extend:TF
10325 (match_operand:SF 1 "register_operand" "0"))))]
10326 "TARGET_80387"
10327 "fchs"
10328 [(set_attr "type" "fsgn")
10329 (set_attr "mode" "XF")
10330 (set_attr "ppro_uops" "few")])
10331 \f
10332 ;; Absolute value instructions
10333
10334 (define_expand "abssf2"
10335 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10336 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10337 (clobber (reg:CC 17))])]
10338 "TARGET_80387"
10339 "if (TARGET_SSE)
10340 {
10341 /* In case operand is in memory, we will not use SSE. */
10342 if (memory_operand (operands[0], VOIDmode)
10343 && rtx_equal_p (operands[0], operands[1]))
10344 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10345 else
10346 {
10347 /* Using SSE is tricky, since we need bitwise negation of -0
10348 in register. */
10349 rtx reg = gen_reg_rtx (V4SFmode);
10350 rtx dest = operands[0];
10351 rtx imm;
10352
10353 operands[1] = force_reg (SFmode, operands[1]);
10354 operands[0] = force_reg (SFmode, operands[0]);
10355 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10356 reg = force_reg (V4SFmode,
10357 gen_rtx_CONST_VECTOR (V4SFmode,
10358 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10359 CONST0_RTX (SFmode),
10360 CONST0_RTX (SFmode))));
10361 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10362 if (dest != operands[0])
10363 emit_move_insn (dest, operands[0]);
10364 }
10365 DONE;
10366 }
10367 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10368
10369 (define_insn "abssf2_memory"
10370 [(set (match_operand:SF 0 "memory_operand" "=m")
10371 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10372 (clobber (reg:CC 17))]
10373 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10374 "#")
10375
10376 (define_insn "abssf2_ifs"
10377 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10378 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10379 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10380 (clobber (reg:CC 17))]
10381 "TARGET_SSE
10382 && (reload_in_progress || reload_completed
10383 || (register_operand (operands[0], VOIDmode)
10384 && register_operand (operands[1], VOIDmode)))"
10385 "#")
10386
10387 (define_split
10388 [(set (match_operand:SF 0 "memory_operand" "")
10389 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10390 (use (match_operand:V4SF 2 "" ""))
10391 (clobber (reg:CC 17))]
10392 ""
10393 [(parallel [(set (match_dup 0)
10394 (abs:SF (match_dup 1)))
10395 (clobber (reg:CC 17))])])
10396
10397 (define_split
10398 [(set (match_operand:SF 0 "register_operand" "")
10399 (abs:SF (match_operand:SF 1 "register_operand" "")))
10400 (use (match_operand:V4SF 2 "" ""))
10401 (clobber (reg:CC 17))]
10402 "reload_completed && !SSE_REG_P (operands[0])"
10403 [(parallel [(set (match_dup 0)
10404 (abs:SF (match_dup 1)))
10405 (clobber (reg:CC 17))])])
10406
10407 (define_split
10408 [(set (match_operand:SF 0 "register_operand" "")
10409 (abs:SF (match_operand:SF 1 "register_operand" "")))
10410 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10411 (clobber (reg:CC 17))]
10412 "reload_completed && SSE_REG_P (operands[0])"
10413 [(set (subreg:TI (match_dup 0) 0)
10414 (and:TI (match_dup 1)
10415 (match_dup 2)))]
10416 {
10417 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10418 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10419 if (operands_match_p (operands[0], operands[2]))
10420 {
10421 rtx tmp;
10422 tmp = operands[1];
10423 operands[1] = operands[2];
10424 operands[2] = tmp;
10425 }
10426 })
10427
10428 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10429 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10430 ;; to itself.
10431 (define_insn "*abssf2_if"
10432 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10433 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10434 (clobber (reg:CC 17))]
10435 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10436 "#")
10437
10438 (define_split
10439 [(set (match_operand:SF 0 "fp_register_operand" "")
10440 (abs:SF (match_operand:SF 1 "register_operand" "")))
10441 (clobber (reg:CC 17))]
10442 "TARGET_80387 && reload_completed"
10443 [(set (match_dup 0)
10444 (abs:SF (match_dup 1)))]
10445 "")
10446
10447 (define_split
10448 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10449 (abs:SF (match_operand:SF 1 "register_operand" "")))
10450 (clobber (reg:CC 17))]
10451 "TARGET_80387 && reload_completed"
10452 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10453 (clobber (reg:CC 17))])]
10454 "operands[1] = gen_int_mode (~0x80000000, SImode);
10455 operands[0] = gen_lowpart (SImode, operands[0]);")
10456
10457 (define_split
10458 [(set (match_operand 0 "memory_operand" "")
10459 (abs (match_operand 1 "memory_operand" "")))
10460 (clobber (reg:CC 17))]
10461 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10462 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10463 (clobber (reg:CC 17))])]
10464 {
10465 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10466
10467 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10468 if (size >= 12)
10469 size = 10;
10470 operands[0] = adjust_address (operands[0], QImode, size - 1);
10471 operands[1] = gen_int_mode (~0x80, QImode);
10472 })
10473
10474 (define_expand "absdf2"
10475 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10476 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10477 (clobber (reg:CC 17))])]
10478 "TARGET_80387"
10479 "if (TARGET_SSE2)
10480 {
10481 /* In case operand is in memory, we will not use SSE. */
10482 if (memory_operand (operands[0], VOIDmode)
10483 && rtx_equal_p (operands[0], operands[1]))
10484 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10485 else
10486 {
10487 /* Using SSE is tricky, since we need bitwise negation of -0
10488 in register. */
10489 rtx reg = gen_reg_rtx (V2DFmode);
10490 #if HOST_BITS_PER_WIDE_INT >= 64
10491 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10492 #else
10493 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10494 #endif
10495 rtx dest = operands[0];
10496
10497 operands[1] = force_reg (DFmode, operands[1]);
10498 operands[0] = force_reg (DFmode, operands[0]);
10499
10500 /* Produce LONG_DOUBLE with the proper immediate argument. */
10501 imm = gen_lowpart (DFmode, imm);
10502 reg = force_reg (V2DFmode,
10503 gen_rtx_CONST_VECTOR (V2DFmode,
10504 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10505 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10506 if (dest != operands[0])
10507 emit_move_insn (dest, operands[0]);
10508 }
10509 DONE;
10510 }
10511 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10512
10513 (define_insn "absdf2_memory"
10514 [(set (match_operand:DF 0 "memory_operand" "=m")
10515 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10516 (clobber (reg:CC 17))]
10517 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10518 "#")
10519
10520 (define_insn "absdf2_ifs"
10521 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10522 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10523 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10524 (clobber (reg:CC 17))]
10525 "!TARGET_64BIT && TARGET_SSE2
10526 && (reload_in_progress || reload_completed
10527 || (register_operand (operands[0], VOIDmode)
10528 && register_operand (operands[1], VOIDmode)))"
10529 "#")
10530
10531 (define_insn "*absdf2_ifs_rex64"
10532 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10533 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10534 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10535 (clobber (reg:CC 17))]
10536 "TARGET_64BIT && TARGET_SSE2
10537 && (reload_in_progress || reload_completed
10538 || (register_operand (operands[0], VOIDmode)
10539 && register_operand (operands[1], VOIDmode)))"
10540 "#")
10541
10542 (define_split
10543 [(set (match_operand:DF 0 "memory_operand" "")
10544 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10545 (use (match_operand:V2DF 2 "" ""))
10546 (clobber (reg:CC 17))]
10547 ""
10548 [(parallel [(set (match_dup 0)
10549 (abs:DF (match_dup 1)))
10550 (clobber (reg:CC 17))])])
10551
10552 (define_split
10553 [(set (match_operand:DF 0 "register_operand" "")
10554 (abs:DF (match_operand:DF 1 "register_operand" "")))
10555 (use (match_operand:V2DF 2 "" ""))
10556 (clobber (reg:CC 17))]
10557 "reload_completed && !SSE_REG_P (operands[0])"
10558 [(parallel [(set (match_dup 0)
10559 (abs:DF (match_dup 1)))
10560 (clobber (reg:CC 17))])])
10561
10562 (define_split
10563 [(set (match_operand:DF 0 "register_operand" "")
10564 (abs:DF (match_operand:DF 1 "register_operand" "")))
10565 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10566 (clobber (reg:CC 17))]
10567 "reload_completed && SSE_REG_P (operands[0])"
10568 [(set (subreg:TI (match_dup 0) 0)
10569 (and:TI (match_dup 1)
10570 (match_dup 2)))]
10571 {
10572 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10573 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10574 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10575 /* Avoid possible reformatting on the operands. */
10576 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10577 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10578 if (operands_match_p (operands[0], operands[2]))
10579 {
10580 rtx tmp;
10581 tmp = operands[1];
10582 operands[1] = operands[2];
10583 operands[2] = tmp;
10584 }
10585 })
10586
10587
10588 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10589 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10590 ;; to itself.
10591 (define_insn "*absdf2_if"
10592 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10593 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10594 (clobber (reg:CC 17))]
10595 "!TARGET_64BIT && TARGET_80387
10596 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10597 "#")
10598
10599 ;; FIXME: We should to allow integer registers here. Problem is that
10600 ;; we need another scratch register to get constant from.
10601 ;; Forcing constant to mem if no register available in peep2 should be
10602 ;; safe even for PIC mode, because of RIP relative addressing.
10603 (define_insn "*absdf2_if_rex64"
10604 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10605 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10606 (clobber (reg:CC 17))]
10607 "TARGET_64BIT && TARGET_80387
10608 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10609 "#")
10610
10611 (define_split
10612 [(set (match_operand:DF 0 "fp_register_operand" "")
10613 (abs:DF (match_operand:DF 1 "register_operand" "")))
10614 (clobber (reg:CC 17))]
10615 "TARGET_80387 && reload_completed"
10616 [(set (match_dup 0)
10617 (abs:DF (match_dup 1)))]
10618 "")
10619
10620 (define_split
10621 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10622 (abs:DF (match_operand:DF 1 "register_operand" "")))
10623 (clobber (reg:CC 17))]
10624 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10625 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10626 (clobber (reg:CC 17))])]
10627 "operands[4] = gen_int_mode (~0x80000000, SImode);
10628 split_di (operands+0, 1, operands+2, operands+3);")
10629
10630 (define_expand "absxf2"
10631 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10632 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10633 (clobber (reg:CC 17))])]
10634 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10635 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10636
10637 (define_expand "abstf2"
10638 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10639 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10640 (clobber (reg:CC 17))])]
10641 "TARGET_80387"
10642 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10643
10644 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10645 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10646 ;; to itself.
10647 (define_insn "*absxf2_if"
10648 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10649 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10650 (clobber (reg:CC 17))]
10651 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10652 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10653 "#")
10654
10655 (define_split
10656 [(set (match_operand:XF 0 "fp_register_operand" "")
10657 (abs:XF (match_operand:XF 1 "register_operand" "")))
10658 (clobber (reg:CC 17))]
10659 "TARGET_80387 && reload_completed"
10660 [(set (match_dup 0)
10661 (abs:XF (match_dup 1)))]
10662 "")
10663
10664 (define_split
10665 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10666 (abs:XF (match_operand:XF 1 "register_operand" "")))
10667 (clobber (reg:CC 17))]
10668 "TARGET_80387 && reload_completed"
10669 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10670 (clobber (reg:CC 17))])]
10671 "operands[1] = GEN_INT (~0x8000);
10672 operands[0] = gen_rtx_REG (SImode,
10673 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10674
10675 (define_insn "*abstf2_if"
10676 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10677 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10678 (clobber (reg:CC 17))]
10679 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10680 "#")
10681
10682 (define_split
10683 [(set (match_operand:TF 0 "fp_register_operand" "")
10684 (abs:TF (match_operand:TF 1 "register_operand" "")))
10685 (clobber (reg:CC 17))]
10686 "TARGET_80387 && reload_completed"
10687 [(set (match_dup 0)
10688 (abs:TF (match_dup 1)))]
10689 "")
10690
10691 (define_split
10692 [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
10693 (abs:TF (match_operand:TF 1 "register_operand" "")))
10694 (clobber (reg:CC 17))]
10695 "TARGET_80387 && reload_completed"
10696 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10697 (clobber (reg:CC 17))])]
10698 "operands[1] = GEN_INT (~0x8000);
10699 operands[0] = gen_rtx_REG (SImode,
10700 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10701
10702 (define_insn "*abssf2_1"
10703 [(set (match_operand:SF 0 "register_operand" "=f")
10704 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10705 "TARGET_80387 && reload_completed"
10706 "fabs"
10707 [(set_attr "type" "fsgn")
10708 (set_attr "mode" "SF")])
10709
10710 (define_insn "*absdf2_1"
10711 [(set (match_operand:DF 0 "register_operand" "=f")
10712 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10713 "TARGET_80387 && reload_completed"
10714 "fabs"
10715 [(set_attr "type" "fsgn")
10716 (set_attr "mode" "DF")])
10717
10718 (define_insn "*absextendsfdf2"
10719 [(set (match_operand:DF 0 "register_operand" "=f")
10720 (abs:DF (float_extend:DF
10721 (match_operand:SF 1 "register_operand" "0"))))]
10722 "TARGET_80387"
10723 "fabs"
10724 [(set_attr "type" "fsgn")
10725 (set_attr "mode" "DF")])
10726
10727 (define_insn "*absxf2_1"
10728 [(set (match_operand:XF 0 "register_operand" "=f")
10729 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10730 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10731 "fabs"
10732 [(set_attr "type" "fsgn")
10733 (set_attr "mode" "DF")])
10734
10735 (define_insn "*absextenddfxf2"
10736 [(set (match_operand:XF 0 "register_operand" "=f")
10737 (abs:XF (float_extend:XF
10738 (match_operand:DF 1 "register_operand" "0"))))]
10739 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10740 "fabs"
10741 [(set_attr "type" "fsgn")
10742 (set_attr "mode" "XF")])
10743
10744 (define_insn "*absextendsfxf2"
10745 [(set (match_operand:XF 0 "register_operand" "=f")
10746 (abs:XF (float_extend:XF
10747 (match_operand:SF 1 "register_operand" "0"))))]
10748 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10749 "fabs"
10750 [(set_attr "type" "fsgn")
10751 (set_attr "mode" "XF")])
10752
10753 (define_insn "*abstf2_1"
10754 [(set (match_operand:TF 0 "register_operand" "=f")
10755 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10756 "TARGET_80387 && reload_completed"
10757 "fabs"
10758 [(set_attr "type" "fsgn")
10759 (set_attr "mode" "DF")])
10760
10761 (define_insn "*absextenddftf2"
10762 [(set (match_operand:TF 0 "register_operand" "=f")
10763 (abs:TF (float_extend:TF
10764 (match_operand:DF 1 "register_operand" "0"))))]
10765 "TARGET_80387"
10766 "fabs"
10767 [(set_attr "type" "fsgn")
10768 (set_attr "mode" "XF")])
10769
10770 (define_insn "*absextendsftf2"
10771 [(set (match_operand:TF 0 "register_operand" "=f")
10772 (abs:TF (float_extend:TF
10773 (match_operand:SF 1 "register_operand" "0"))))]
10774 "TARGET_80387"
10775 "fabs"
10776 [(set_attr "type" "fsgn")
10777 (set_attr "mode" "XF")])
10778 \f
10779 ;; One complement instructions
10780
10781 (define_expand "one_cmpldi2"
10782 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10783 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10784 "TARGET_64BIT"
10785 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10786
10787 (define_insn "*one_cmpldi2_1_rex64"
10788 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10789 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10790 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10791 "not{q}\t%0"
10792 [(set_attr "type" "negnot")
10793 (set_attr "mode" "DI")])
10794
10795 (define_insn "*one_cmpldi2_2_rex64"
10796 [(set (reg 17)
10797 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10798 (const_int 0)))
10799 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10800 (not:DI (match_dup 1)))]
10801 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10802 && ix86_unary_operator_ok (NOT, DImode, operands)"
10803 "#"
10804 [(set_attr "type" "alu1")
10805 (set_attr "mode" "DI")])
10806
10807 (define_split
10808 [(set (reg 17)
10809 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10810 (const_int 0)))
10811 (set (match_operand:DI 0 "nonimmediate_operand" "")
10812 (not:DI (match_dup 1)))]
10813 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10814 [(parallel [(set (reg:CCNO 17)
10815 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10816 (const_int 0)))
10817 (set (match_dup 0)
10818 (xor:DI (match_dup 1) (const_int -1)))])]
10819 "")
10820
10821 (define_expand "one_cmplsi2"
10822 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10823 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10824 ""
10825 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10826
10827 (define_insn "*one_cmplsi2_1"
10828 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10829 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10830 "ix86_unary_operator_ok (NOT, SImode, operands)"
10831 "not{l}\t%0"
10832 [(set_attr "type" "negnot")
10833 (set_attr "mode" "SI")])
10834
10835 ;; ??? Currently never generated - xor is used instead.
10836 (define_insn "*one_cmplsi2_1_zext"
10837 [(set (match_operand:DI 0 "register_operand" "=r")
10838 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10839 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10840 "not{l}\t%k0"
10841 [(set_attr "type" "negnot")
10842 (set_attr "mode" "SI")])
10843
10844 (define_insn "*one_cmplsi2_2"
10845 [(set (reg 17)
10846 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10847 (const_int 0)))
10848 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10849 (not:SI (match_dup 1)))]
10850 "ix86_match_ccmode (insn, CCNOmode)
10851 && ix86_unary_operator_ok (NOT, SImode, operands)"
10852 "#"
10853 [(set_attr "type" "alu1")
10854 (set_attr "mode" "SI")])
10855
10856 (define_split
10857 [(set (reg 17)
10858 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10859 (const_int 0)))
10860 (set (match_operand:SI 0 "nonimmediate_operand" "")
10861 (not:SI (match_dup 1)))]
10862 "ix86_match_ccmode (insn, CCNOmode)"
10863 [(parallel [(set (reg:CCNO 17)
10864 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10865 (const_int 0)))
10866 (set (match_dup 0)
10867 (xor:SI (match_dup 1) (const_int -1)))])]
10868 "")
10869
10870 ;; ??? Currently never generated - xor is used instead.
10871 (define_insn "*one_cmplsi2_2_zext"
10872 [(set (reg 17)
10873 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10874 (const_int 0)))
10875 (set (match_operand:DI 0 "register_operand" "=r")
10876 (zero_extend:DI (not:SI (match_dup 1))))]
10877 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10878 && ix86_unary_operator_ok (NOT, SImode, operands)"
10879 "#"
10880 [(set_attr "type" "alu1")
10881 (set_attr "mode" "SI")])
10882
10883 (define_split
10884 [(set (reg 17)
10885 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10886 (const_int 0)))
10887 (set (match_operand:DI 0 "register_operand" "")
10888 (zero_extend:DI (not:SI (match_dup 1))))]
10889 "ix86_match_ccmode (insn, CCNOmode)"
10890 [(parallel [(set (reg:CCNO 17)
10891 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10892 (const_int 0)))
10893 (set (match_dup 0)
10894 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10895 "")
10896
10897 (define_expand "one_cmplhi2"
10898 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10899 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10900 "TARGET_HIMODE_MATH"
10901 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10902
10903 (define_insn "*one_cmplhi2_1"
10904 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10905 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10906 "ix86_unary_operator_ok (NOT, HImode, operands)"
10907 "not{w}\t%0"
10908 [(set_attr "type" "negnot")
10909 (set_attr "mode" "HI")])
10910
10911 (define_insn "*one_cmplhi2_2"
10912 [(set (reg 17)
10913 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10914 (const_int 0)))
10915 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10916 (not:HI (match_dup 1)))]
10917 "ix86_match_ccmode (insn, CCNOmode)
10918 && ix86_unary_operator_ok (NEG, HImode, operands)"
10919 "#"
10920 [(set_attr "type" "alu1")
10921 (set_attr "mode" "HI")])
10922
10923 (define_split
10924 [(set (reg 17)
10925 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10926 (const_int 0)))
10927 (set (match_operand:HI 0 "nonimmediate_operand" "")
10928 (not:HI (match_dup 1)))]
10929 "ix86_match_ccmode (insn, CCNOmode)"
10930 [(parallel [(set (reg:CCNO 17)
10931 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10932 (const_int 0)))
10933 (set (match_dup 0)
10934 (xor:HI (match_dup 1) (const_int -1)))])]
10935 "")
10936
10937 ;; %%% Potential partial reg stall on alternative 1. What to do?
10938 (define_expand "one_cmplqi2"
10939 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10940 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10941 "TARGET_QIMODE_MATH"
10942 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10943
10944 (define_insn "*one_cmplqi2_1"
10945 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10946 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10947 "ix86_unary_operator_ok (NOT, QImode, operands)"
10948 "@
10949 not{b}\t%0
10950 not{l}\t%k0"
10951 [(set_attr "type" "negnot")
10952 (set_attr "mode" "QI,SI")])
10953
10954 (define_insn "*one_cmplqi2_2"
10955 [(set (reg 17)
10956 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10957 (const_int 0)))
10958 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10959 (not:QI (match_dup 1)))]
10960 "ix86_match_ccmode (insn, CCNOmode)
10961 && ix86_unary_operator_ok (NOT, QImode, operands)"
10962 "#"
10963 [(set_attr "type" "alu1")
10964 (set_attr "mode" "QI")])
10965
10966 (define_split
10967 [(set (reg 17)
10968 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10969 (const_int 0)))
10970 (set (match_operand:QI 0 "nonimmediate_operand" "")
10971 (not:QI (match_dup 1)))]
10972 "ix86_match_ccmode (insn, CCNOmode)"
10973 [(parallel [(set (reg:CCNO 17)
10974 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10975 (const_int 0)))
10976 (set (match_dup 0)
10977 (xor:QI (match_dup 1) (const_int -1)))])]
10978 "")
10979 \f
10980 ;; Arithmetic shift instructions
10981
10982 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10983 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10984 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10985 ;; from the assembler input.
10986 ;;
10987 ;; This instruction shifts the target reg/mem as usual, but instead of
10988 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10989 ;; is a left shift double, bits are taken from the high order bits of
10990 ;; reg, else if the insn is a shift right double, bits are taken from the
10991 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10992 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10993 ;;
10994 ;; Since sh[lr]d does not change the `reg' operand, that is done
10995 ;; separately, making all shifts emit pairs of shift double and normal
10996 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10997 ;; support a 63 bit shift, each shift where the count is in a reg expands
10998 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10999 ;;
11000 ;; If the shift count is a constant, we need never emit more than one
11001 ;; shift pair, instead using moves and sign extension for counts greater
11002 ;; than 31.
11003
11004 (define_expand "ashldi3"
11005 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11006 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
11007 (match_operand:QI 2 "nonmemory_operand" "")))
11008 (clobber (reg:CC 17))])]
11009 ""
11010 {
11011 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11012 {
11013 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
11014 DONE;
11015 }
11016 ix86_expand_binary_operator (ASHIFT, DImode, operands);
11017 DONE;
11018 })
11019
11020 (define_insn "*ashldi3_1_rex64"
11021 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11022 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
11023 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11024 (clobber (reg:CC 17))]
11025 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11026 {
11027 switch (get_attr_type (insn))
11028 {
11029 case TYPE_ALU:
11030 if (operands[2] != const1_rtx)
11031 abort ();
11032 if (!rtx_equal_p (operands[0], operands[1]))
11033 abort ();
11034 return "add{q}\t{%0, %0|%0, %0}";
11035
11036 case TYPE_LEA:
11037 if (GET_CODE (operands[2]) != CONST_INT
11038 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
11039 abort ();
11040 operands[1] = gen_rtx_MULT (DImode, operands[1],
11041 GEN_INT (1 << INTVAL (operands[2])));
11042 return "lea{q}\t{%a1, %0|%0, %a1}";
11043
11044 default:
11045 if (REG_P (operands[2]))
11046 return "sal{q}\t{%b2, %0|%0, %b2}";
11047 else if (GET_CODE (operands[2]) == CONST_INT
11048 && INTVAL (operands[2]) == 1
11049 && (TARGET_SHIFT1 || optimize_size))
11050 return "sal{q}\t%0";
11051 else
11052 return "sal{q}\t{%2, %0|%0, %2}";
11053 }
11054 }
11055 [(set (attr "type")
11056 (cond [(eq_attr "alternative" "1")
11057 (const_string "lea")
11058 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11059 (const_int 0))
11060 (match_operand 0 "register_operand" ""))
11061 (match_operand 2 "const1_operand" ""))
11062 (const_string "alu")
11063 ]
11064 (const_string "ishift")))
11065 (set_attr "mode" "DI")])
11066
11067 ;; Convert lea to the lea pattern to avoid flags dependency.
11068 (define_split
11069 [(set (match_operand:DI 0 "register_operand" "")
11070 (ashift:DI (match_operand:DI 1 "register_operand" "")
11071 (match_operand:QI 2 "immediate_operand" "")))
11072 (clobber (reg:CC 17))]
11073 "TARGET_64BIT && reload_completed
11074 && true_regnum (operands[0]) != true_regnum (operands[1])"
11075 [(set (match_dup 0)
11076 (mult:DI (match_dup 1)
11077 (match_dup 2)))]
11078 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11079
11080 ;; This pattern can't accept a variable shift count, since shifts by
11081 ;; zero don't affect the flags. We assume that shifts by constant
11082 ;; zero are optimized away.
11083 (define_insn "*ashldi3_cmp_rex64"
11084 [(set (reg 17)
11085 (compare
11086 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11087 (match_operand:QI 2 "immediate_operand" "e"))
11088 (const_int 0)))
11089 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11090 (ashift:DI (match_dup 1) (match_dup 2)))]
11091 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11092 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11093 {
11094 switch (get_attr_type (insn))
11095 {
11096 case TYPE_ALU:
11097 if (operands[2] != const1_rtx)
11098 abort ();
11099 return "add{q}\t{%0, %0|%0, %0}";
11100
11101 default:
11102 if (REG_P (operands[2]))
11103 return "sal{q}\t{%b2, %0|%0, %b2}";
11104 else if (GET_CODE (operands[2]) == CONST_INT
11105 && INTVAL (operands[2]) == 1
11106 && (TARGET_SHIFT1 || optimize_size))
11107 return "sal{q}\t%0";
11108 else
11109 return "sal{q}\t{%2, %0|%0, %2}";
11110 }
11111 }
11112 [(set (attr "type")
11113 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11114 (const_int 0))
11115 (match_operand 0 "register_operand" ""))
11116 (match_operand 2 "const1_operand" ""))
11117 (const_string "alu")
11118 ]
11119 (const_string "ishift")))
11120 (set_attr "mode" "DI")])
11121
11122 (define_insn "ashldi3_1"
11123 [(set (match_operand:DI 0 "register_operand" "=r")
11124 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11125 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11126 (clobber (match_scratch:SI 3 "=&r"))
11127 (clobber (reg:CC 17))]
11128 "!TARGET_64BIT && TARGET_CMOVE"
11129 "#"
11130 [(set_attr "type" "multi")])
11131
11132 (define_insn "*ashldi3_2"
11133 [(set (match_operand:DI 0 "register_operand" "=r")
11134 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11135 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11136 (clobber (reg:CC 17))]
11137 "!TARGET_64BIT"
11138 "#"
11139 [(set_attr "type" "multi")])
11140
11141 (define_split
11142 [(set (match_operand:DI 0 "register_operand" "")
11143 (ashift:DI (match_operand:DI 1 "register_operand" "")
11144 (match_operand:QI 2 "nonmemory_operand" "")))
11145 (clobber (match_scratch:SI 3 ""))
11146 (clobber (reg:CC 17))]
11147 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11148 [(const_int 0)]
11149 "ix86_split_ashldi (operands, operands[3]); DONE;")
11150
11151 (define_split
11152 [(set (match_operand:DI 0 "register_operand" "")
11153 (ashift:DI (match_operand:DI 1 "register_operand" "")
11154 (match_operand:QI 2 "nonmemory_operand" "")))
11155 (clobber (reg:CC 17))]
11156 "!TARGET_64BIT && reload_completed"
11157 [(const_int 0)]
11158 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
11159
11160 (define_insn "x86_shld_1"
11161 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11162 (ior:SI (ashift:SI (match_dup 0)
11163 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11164 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11165 (minus:QI (const_int 32) (match_dup 2)))))
11166 (clobber (reg:CC 17))]
11167 ""
11168 "@
11169 shld{l}\t{%2, %1, %0|%0, %1, %2}
11170 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11171 [(set_attr "type" "ishift")
11172 (set_attr "prefix_0f" "1")
11173 (set_attr "mode" "SI")
11174 (set_attr "pent_pair" "np")
11175 (set_attr "athlon_decode" "vector")
11176 (set_attr "ppro_uops" "few")])
11177
11178 (define_expand "x86_shift_adj_1"
11179 [(set (reg:CCZ 17)
11180 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11181 (const_int 32))
11182 (const_int 0)))
11183 (set (match_operand:SI 0 "register_operand" "")
11184 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11185 (match_operand:SI 1 "register_operand" "")
11186 (match_dup 0)))
11187 (set (match_dup 1)
11188 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11189 (match_operand:SI 3 "register_operand" "r")
11190 (match_dup 1)))]
11191 "TARGET_CMOVE"
11192 "")
11193
11194 (define_expand "x86_shift_adj_2"
11195 [(use (match_operand:SI 0 "register_operand" ""))
11196 (use (match_operand:SI 1 "register_operand" ""))
11197 (use (match_operand:QI 2 "register_operand" ""))]
11198 ""
11199 {
11200 rtx label = gen_label_rtx ();
11201 rtx tmp;
11202
11203 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11204
11205 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11206 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11207 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11208 gen_rtx_LABEL_REF (VOIDmode, label),
11209 pc_rtx);
11210 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11211 JUMP_LABEL (tmp) = label;
11212
11213 emit_move_insn (operands[0], operands[1]);
11214 emit_move_insn (operands[1], const0_rtx);
11215
11216 emit_label (label);
11217 LABEL_NUSES (label) = 1;
11218
11219 DONE;
11220 })
11221
11222 (define_expand "ashlsi3"
11223 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11224 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11225 (match_operand:QI 2 "nonmemory_operand" "")))
11226 (clobber (reg:CC 17))]
11227 ""
11228 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11229
11230 (define_insn "*ashlsi3_1"
11231 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11232 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
11233 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11234 (clobber (reg:CC 17))]
11235 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11236 {
11237 switch (get_attr_type (insn))
11238 {
11239 case TYPE_ALU:
11240 if (operands[2] != const1_rtx)
11241 abort ();
11242 if (!rtx_equal_p (operands[0], operands[1]))
11243 abort ();
11244 return "add{l}\t{%0, %0|%0, %0}";
11245
11246 case TYPE_LEA:
11247 return "#";
11248
11249 default:
11250 if (REG_P (operands[2]))
11251 return "sal{l}\t{%b2, %0|%0, %b2}";
11252 else if (GET_CODE (operands[2]) == CONST_INT
11253 && INTVAL (operands[2]) == 1
11254 && (TARGET_SHIFT1 || optimize_size))
11255 return "sal{l}\t%0";
11256 else
11257 return "sal{l}\t{%2, %0|%0, %2}";
11258 }
11259 }
11260 [(set (attr "type")
11261 (cond [(eq_attr "alternative" "1")
11262 (const_string "lea")
11263 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11264 (const_int 0))
11265 (match_operand 0 "register_operand" ""))
11266 (match_operand 2 "const1_operand" ""))
11267 (const_string "alu")
11268 ]
11269 (const_string "ishift")))
11270 (set_attr "mode" "SI")])
11271
11272 ;; Convert lea to the lea pattern to avoid flags dependency.
11273 (define_split
11274 [(set (match_operand 0 "register_operand" "")
11275 (ashift (match_operand 1 "index_register_operand" "")
11276 (match_operand:QI 2 "const_int_operand" "")))
11277 (clobber (reg:CC 17))]
11278 "reload_completed
11279 && true_regnum (operands[0]) != true_regnum (operands[1])"
11280 [(const_int 0)]
11281 {
11282 rtx pat;
11283 operands[0] = gen_lowpart (SImode, operands[0]);
11284 operands[1] = gen_lowpart (Pmode, operands[1]);
11285 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11286 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11287 if (Pmode != SImode)
11288 pat = gen_rtx_SUBREG (SImode, pat, 0);
11289 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11290 DONE;
11291 })
11292
11293 ;; Rare case of shifting RSP is handled by generating move and shift
11294 (define_split
11295 [(set (match_operand 0 "register_operand" "")
11296 (ashift (match_operand 1 "register_operand" "")
11297 (match_operand:QI 2 "const_int_operand" "")))
11298 (clobber (reg:CC 17))]
11299 "reload_completed
11300 && true_regnum (operands[0]) != true_regnum (operands[1])"
11301 [(const_int 0)]
11302 {
11303 rtx pat, clob;
11304 emit_move_insn (operands[1], operands[0]);
11305 pat = gen_rtx_SET (VOIDmode, operands[0],
11306 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11307 operands[0], operands[2]));
11308 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11309 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11310 DONE;
11311 })
11312
11313 (define_insn "*ashlsi3_1_zext"
11314 [(set (match_operand:DI 0 "register_operand" "=r,r")
11315 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
11316 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11317 (clobber (reg:CC 17))]
11318 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11319 {
11320 switch (get_attr_type (insn))
11321 {
11322 case TYPE_ALU:
11323 if (operands[2] != const1_rtx)
11324 abort ();
11325 return "add{l}\t{%k0, %k0|%k0, %k0}";
11326
11327 case TYPE_LEA:
11328 return "#";
11329
11330 default:
11331 if (REG_P (operands[2]))
11332 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11333 else if (GET_CODE (operands[2]) == CONST_INT
11334 && INTVAL (operands[2]) == 1
11335 && (TARGET_SHIFT1 || optimize_size))
11336 return "sal{l}\t%k0";
11337 else
11338 return "sal{l}\t{%2, %k0|%k0, %2}";
11339 }
11340 }
11341 [(set (attr "type")
11342 (cond [(eq_attr "alternative" "1")
11343 (const_string "lea")
11344 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11345 (const_int 0))
11346 (match_operand 2 "const1_operand" ""))
11347 (const_string "alu")
11348 ]
11349 (const_string "ishift")))
11350 (set_attr "mode" "SI")])
11351
11352 ;; Convert lea to the lea pattern to avoid flags dependency.
11353 (define_split
11354 [(set (match_operand:DI 0 "register_operand" "")
11355 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11356 (match_operand:QI 2 "const_int_operand" ""))))
11357 (clobber (reg:CC 17))]
11358 "TARGET_64BIT && reload_completed
11359 && true_regnum (operands[0]) != true_regnum (operands[1])"
11360 [(set (match_dup 0) (zero_extend:DI
11361 (subreg:SI (mult:SI (match_dup 1)
11362 (match_dup 2)) 0)))]
11363 {
11364 operands[1] = gen_lowpart (Pmode, operands[1]);
11365 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11366 })
11367
11368 ;; This pattern can't accept a variable shift count, since shifts by
11369 ;; zero don't affect the flags. We assume that shifts by constant
11370 ;; zero are optimized away.
11371 (define_insn "*ashlsi3_cmp"
11372 [(set (reg 17)
11373 (compare
11374 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11375 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11376 (const_int 0)))
11377 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11378 (ashift:SI (match_dup 1) (match_dup 2)))]
11379 "ix86_match_ccmode (insn, CCGOCmode)
11380 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11381 {
11382 switch (get_attr_type (insn))
11383 {
11384 case TYPE_ALU:
11385 if (operands[2] != const1_rtx)
11386 abort ();
11387 return "add{l}\t{%0, %0|%0, %0}";
11388
11389 default:
11390 if (REG_P (operands[2]))
11391 return "sal{l}\t{%b2, %0|%0, %b2}";
11392 else if (GET_CODE (operands[2]) == CONST_INT
11393 && INTVAL (operands[2]) == 1
11394 && (TARGET_SHIFT1 || optimize_size))
11395 return "sal{l}\t%0";
11396 else
11397 return "sal{l}\t{%2, %0|%0, %2}";
11398 }
11399 }
11400 [(set (attr "type")
11401 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11402 (const_int 0))
11403 (match_operand 0 "register_operand" ""))
11404 (match_operand 2 "const1_operand" ""))
11405 (const_string "alu")
11406 ]
11407 (const_string "ishift")))
11408 (set_attr "mode" "SI")])
11409
11410 (define_insn "*ashlsi3_cmp_zext"
11411 [(set (reg 17)
11412 (compare
11413 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11414 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11415 (const_int 0)))
11416 (set (match_operand:DI 0 "register_operand" "=r")
11417 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11418 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11419 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11420 {
11421 switch (get_attr_type (insn))
11422 {
11423 case TYPE_ALU:
11424 if (operands[2] != const1_rtx)
11425 abort ();
11426 return "add{l}\t{%k0, %k0|%k0, %k0}";
11427
11428 default:
11429 if (REG_P (operands[2]))
11430 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11431 else if (GET_CODE (operands[2]) == CONST_INT
11432 && INTVAL (operands[2]) == 1
11433 && (TARGET_SHIFT1 || optimize_size))
11434 return "sal{l}\t%k0";
11435 else
11436 return "sal{l}\t{%2, %k0|%k0, %2}";
11437 }
11438 }
11439 [(set (attr "type")
11440 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11441 (const_int 0))
11442 (match_operand 2 "const1_operand" ""))
11443 (const_string "alu")
11444 ]
11445 (const_string "ishift")))
11446 (set_attr "mode" "SI")])
11447
11448 (define_expand "ashlhi3"
11449 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11450 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11451 (match_operand:QI 2 "nonmemory_operand" "")))
11452 (clobber (reg:CC 17))]
11453 "TARGET_HIMODE_MATH"
11454 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11455
11456 (define_insn "*ashlhi3_1_lea"
11457 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11458 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11459 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11460 (clobber (reg:CC 17))]
11461 "!TARGET_PARTIAL_REG_STALL
11462 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11463 {
11464 switch (get_attr_type (insn))
11465 {
11466 case TYPE_LEA:
11467 return "#";
11468 case TYPE_ALU:
11469 if (operands[2] != const1_rtx)
11470 abort ();
11471 return "add{w}\t{%0, %0|%0, %0}";
11472
11473 default:
11474 if (REG_P (operands[2]))
11475 return "sal{w}\t{%b2, %0|%0, %b2}";
11476 else if (GET_CODE (operands[2]) == CONST_INT
11477 && INTVAL (operands[2]) == 1
11478 && (TARGET_SHIFT1 || optimize_size))
11479 return "sal{w}\t%0";
11480 else
11481 return "sal{w}\t{%2, %0|%0, %2}";
11482 }
11483 }
11484 [(set (attr "type")
11485 (cond [(eq_attr "alternative" "1")
11486 (const_string "lea")
11487 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11488 (const_int 0))
11489 (match_operand 0 "register_operand" ""))
11490 (match_operand 2 "const1_operand" ""))
11491 (const_string "alu")
11492 ]
11493 (const_string "ishift")))
11494 (set_attr "mode" "HI,SI")])
11495
11496 (define_insn "*ashlhi3_1"
11497 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11498 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11499 (match_operand:QI 2 "nonmemory_operand" "cI")))
11500 (clobber (reg:CC 17))]
11501 "TARGET_PARTIAL_REG_STALL
11502 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11503 {
11504 switch (get_attr_type (insn))
11505 {
11506 case TYPE_ALU:
11507 if (operands[2] != const1_rtx)
11508 abort ();
11509 return "add{w}\t{%0, %0|%0, %0}";
11510
11511 default:
11512 if (REG_P (operands[2]))
11513 return "sal{w}\t{%b2, %0|%0, %b2}";
11514 else if (GET_CODE (operands[2]) == CONST_INT
11515 && INTVAL (operands[2]) == 1
11516 && (TARGET_SHIFT1 || optimize_size))
11517 return "sal{w}\t%0";
11518 else
11519 return "sal{w}\t{%2, %0|%0, %2}";
11520 }
11521 }
11522 [(set (attr "type")
11523 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11524 (const_int 0))
11525 (match_operand 0 "register_operand" ""))
11526 (match_operand 2 "const1_operand" ""))
11527 (const_string "alu")
11528 ]
11529 (const_string "ishift")))
11530 (set_attr "mode" "HI")])
11531
11532 ;; This pattern can't accept a variable shift count, since shifts by
11533 ;; zero don't affect the flags. We assume that shifts by constant
11534 ;; zero are optimized away.
11535 (define_insn "*ashlhi3_cmp"
11536 [(set (reg 17)
11537 (compare
11538 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11539 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11540 (const_int 0)))
11541 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11542 (ashift:HI (match_dup 1) (match_dup 2)))]
11543 "ix86_match_ccmode (insn, CCGOCmode)
11544 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11545 {
11546 switch (get_attr_type (insn))
11547 {
11548 case TYPE_ALU:
11549 if (operands[2] != const1_rtx)
11550 abort ();
11551 return "add{w}\t{%0, %0|%0, %0}";
11552
11553 default:
11554 if (REG_P (operands[2]))
11555 return "sal{w}\t{%b2, %0|%0, %b2}";
11556 else if (GET_CODE (operands[2]) == CONST_INT
11557 && INTVAL (operands[2]) == 1
11558 && (TARGET_SHIFT1 || optimize_size))
11559 return "sal{w}\t%0";
11560 else
11561 return "sal{w}\t{%2, %0|%0, %2}";
11562 }
11563 }
11564 [(set (attr "type")
11565 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11566 (const_int 0))
11567 (match_operand 0 "register_operand" ""))
11568 (match_operand 2 "const1_operand" ""))
11569 (const_string "alu")
11570 ]
11571 (const_string "ishift")))
11572 (set_attr "mode" "HI")])
11573
11574 (define_expand "ashlqi3"
11575 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11576 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11577 (match_operand:QI 2 "nonmemory_operand" "")))
11578 (clobber (reg:CC 17))]
11579 "TARGET_QIMODE_MATH"
11580 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11581
11582 ;; %%% Potential partial reg stall on alternative 2. What to do?
11583
11584 (define_insn "*ashlqi3_1_lea"
11585 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11586 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11587 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11588 (clobber (reg:CC 17))]
11589 "!TARGET_PARTIAL_REG_STALL
11590 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11591 {
11592 switch (get_attr_type (insn))
11593 {
11594 case TYPE_LEA:
11595 return "#";
11596 case TYPE_ALU:
11597 if (operands[2] != const1_rtx)
11598 abort ();
11599 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11600 return "add{l}\t{%k0, %k0|%k0, %k0}";
11601 else
11602 return "add{b}\t{%0, %0|%0, %0}";
11603
11604 default:
11605 if (REG_P (operands[2]))
11606 {
11607 if (get_attr_mode (insn) == MODE_SI)
11608 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11609 else
11610 return "sal{b}\t{%b2, %0|%0, %b2}";
11611 }
11612 else if (GET_CODE (operands[2]) == CONST_INT
11613 && INTVAL (operands[2]) == 1
11614 && (TARGET_SHIFT1 || optimize_size))
11615 {
11616 if (get_attr_mode (insn) == MODE_SI)
11617 return "sal{l}\t%0";
11618 else
11619 return "sal{b}\t%0";
11620 }
11621 else
11622 {
11623 if (get_attr_mode (insn) == MODE_SI)
11624 return "sal{l}\t{%2, %k0|%k0, %2}";
11625 else
11626 return "sal{b}\t{%2, %0|%0, %2}";
11627 }
11628 }
11629 }
11630 [(set (attr "type")
11631 (cond [(eq_attr "alternative" "2")
11632 (const_string "lea")
11633 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11634 (const_int 0))
11635 (match_operand 0 "register_operand" ""))
11636 (match_operand 2 "const1_operand" ""))
11637 (const_string "alu")
11638 ]
11639 (const_string "ishift")))
11640 (set_attr "mode" "QI,SI,SI")])
11641
11642 (define_insn "*ashlqi3_1"
11643 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11644 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11645 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11646 (clobber (reg:CC 17))]
11647 "TARGET_PARTIAL_REG_STALL
11648 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11649 {
11650 switch (get_attr_type (insn))
11651 {
11652 case TYPE_ALU:
11653 if (operands[2] != const1_rtx)
11654 abort ();
11655 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11656 return "add{l}\t{%k0, %k0|%k0, %k0}";
11657 else
11658 return "add{b}\t{%0, %0|%0, %0}";
11659
11660 default:
11661 if (REG_P (operands[2]))
11662 {
11663 if (get_attr_mode (insn) == MODE_SI)
11664 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11665 else
11666 return "sal{b}\t{%b2, %0|%0, %b2}";
11667 }
11668 else if (GET_CODE (operands[2]) == CONST_INT
11669 && INTVAL (operands[2]) == 1
11670 && (TARGET_SHIFT1 || optimize_size))
11671 {
11672 if (get_attr_mode (insn) == MODE_SI)
11673 return "sal{l}\t%0";
11674 else
11675 return "sal{b}\t%0";
11676 }
11677 else
11678 {
11679 if (get_attr_mode (insn) == MODE_SI)
11680 return "sal{l}\t{%2, %k0|%k0, %2}";
11681 else
11682 return "sal{b}\t{%2, %0|%0, %2}";
11683 }
11684 }
11685 }
11686 [(set (attr "type")
11687 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11688 (const_int 0))
11689 (match_operand 0 "register_operand" ""))
11690 (match_operand 2 "const1_operand" ""))
11691 (const_string "alu")
11692 ]
11693 (const_string "ishift")))
11694 (set_attr "mode" "QI,SI")])
11695
11696 ;; This pattern can't accept a variable shift count, since shifts by
11697 ;; zero don't affect the flags. We assume that shifts by constant
11698 ;; zero are optimized away.
11699 (define_insn "*ashlqi3_cmp"
11700 [(set (reg 17)
11701 (compare
11702 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11703 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11704 (const_int 0)))
11705 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11706 (ashift:QI (match_dup 1) (match_dup 2)))]
11707 "ix86_match_ccmode (insn, CCGOCmode)
11708 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11709 {
11710 switch (get_attr_type (insn))
11711 {
11712 case TYPE_ALU:
11713 if (operands[2] != const1_rtx)
11714 abort ();
11715 return "add{b}\t{%0, %0|%0, %0}";
11716
11717 default:
11718 if (REG_P (operands[2]))
11719 return "sal{b}\t{%b2, %0|%0, %b2}";
11720 else if (GET_CODE (operands[2]) == CONST_INT
11721 && INTVAL (operands[2]) == 1
11722 && (TARGET_SHIFT1 || optimize_size))
11723 return "sal{b}\t%0";
11724 else
11725 return "sal{b}\t{%2, %0|%0, %2}";
11726 }
11727 }
11728 [(set (attr "type")
11729 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11730 (const_int 0))
11731 (match_operand 0 "register_operand" ""))
11732 (match_operand 2 "const1_operand" ""))
11733 (const_string "alu")
11734 ]
11735 (const_string "ishift")))
11736 (set_attr "mode" "QI")])
11737
11738 ;; See comment above `ashldi3' about how this works.
11739
11740 (define_expand "ashrdi3"
11741 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11742 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11743 (match_operand:QI 2 "nonmemory_operand" "")))
11744 (clobber (reg:CC 17))])]
11745 ""
11746 {
11747 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11748 {
11749 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11750 DONE;
11751 }
11752 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11753 DONE;
11754 })
11755
11756 (define_insn "ashrdi3_63_rex64"
11757 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11758 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11759 (match_operand:DI 2 "const_int_operand" "i,i")))
11760 (clobber (reg:CC 17))]
11761 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11762 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11763 "@
11764 {cqto|cqo}
11765 sar{q}\t{%2, %0|%0, %2}"
11766 [(set_attr "type" "imovx,ishift")
11767 (set_attr "prefix_0f" "0,*")
11768 (set_attr "length_immediate" "0,*")
11769 (set_attr "modrm" "0,1")
11770 (set_attr "mode" "DI")])
11771
11772 (define_insn "*ashrdi3_1_one_bit_rex64"
11773 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11774 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11775 (match_operand:QI 2 "const_int_1_operand" "")))
11776 (clobber (reg:CC 17))]
11777 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11778 && (TARGET_SHIFT1 || optimize_size)"
11779 "sar{q}\t%0"
11780 [(set_attr "type" "ishift")
11781 (set (attr "length")
11782 (if_then_else (match_operand:DI 0 "register_operand" "")
11783 (const_string "2")
11784 (const_string "*")))])
11785
11786 (define_insn "*ashrdi3_1_rex64"
11787 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11788 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11789 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11790 (clobber (reg:CC 17))]
11791 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11792 "@
11793 sar{q}\t{%2, %0|%0, %2}
11794 sar{q}\t{%b2, %0|%0, %b2}"
11795 [(set_attr "type" "ishift")
11796 (set_attr "mode" "DI")])
11797
11798 ;; This pattern can't accept a variable shift count, since shifts by
11799 ;; zero don't affect the flags. We assume that shifts by constant
11800 ;; zero are optimized away.
11801 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11802 [(set (reg 17)
11803 (compare
11804 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11805 (match_operand:QI 2 "const_int_1_operand" ""))
11806 (const_int 0)))
11807 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11808 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11809 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11810 && (TARGET_SHIFT1 || optimize_size)
11811 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11812 "sar{q}\t%0"
11813 [(set_attr "type" "ishift")
11814 (set (attr "length")
11815 (if_then_else (match_operand:DI 0 "register_operand" "")
11816 (const_string "2")
11817 (const_string "*")))])
11818
11819 ;; This pattern can't accept a variable shift count, since shifts by
11820 ;; zero don't affect the flags. We assume that shifts by constant
11821 ;; zero are optimized away.
11822 (define_insn "*ashrdi3_cmp_rex64"
11823 [(set (reg 17)
11824 (compare
11825 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11826 (match_operand:QI 2 "const_int_operand" "n"))
11827 (const_int 0)))
11828 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11829 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11830 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11831 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11832 "sar{q}\t{%2, %0|%0, %2}"
11833 [(set_attr "type" "ishift")
11834 (set_attr "mode" "DI")])
11835
11836
11837 (define_insn "ashrdi3_1"
11838 [(set (match_operand:DI 0 "register_operand" "=r")
11839 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11840 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11841 (clobber (match_scratch:SI 3 "=&r"))
11842 (clobber (reg:CC 17))]
11843 "!TARGET_64BIT && TARGET_CMOVE"
11844 "#"
11845 [(set_attr "type" "multi")])
11846
11847 (define_insn "*ashrdi3_2"
11848 [(set (match_operand:DI 0 "register_operand" "=r")
11849 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11850 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11851 (clobber (reg:CC 17))]
11852 "!TARGET_64BIT"
11853 "#"
11854 [(set_attr "type" "multi")])
11855
11856 (define_split
11857 [(set (match_operand:DI 0 "register_operand" "")
11858 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11859 (match_operand:QI 2 "nonmemory_operand" "")))
11860 (clobber (match_scratch:SI 3 ""))
11861 (clobber (reg:CC 17))]
11862 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11863 [(const_int 0)]
11864 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11865
11866 (define_split
11867 [(set (match_operand:DI 0 "register_operand" "")
11868 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11869 (match_operand:QI 2 "nonmemory_operand" "")))
11870 (clobber (reg:CC 17))]
11871 "!TARGET_64BIT && reload_completed"
11872 [(const_int 0)]
11873 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11874
11875 (define_insn "x86_shrd_1"
11876 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11877 (ior:SI (ashiftrt:SI (match_dup 0)
11878 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11879 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11880 (minus:QI (const_int 32) (match_dup 2)))))
11881 (clobber (reg:CC 17))]
11882 ""
11883 "@
11884 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11885 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11886 [(set_attr "type" "ishift")
11887 (set_attr "prefix_0f" "1")
11888 (set_attr "pent_pair" "np")
11889 (set_attr "ppro_uops" "few")
11890 (set_attr "mode" "SI")])
11891
11892 (define_expand "x86_shift_adj_3"
11893 [(use (match_operand:SI 0 "register_operand" ""))
11894 (use (match_operand:SI 1 "register_operand" ""))
11895 (use (match_operand:QI 2 "register_operand" ""))]
11896 ""
11897 {
11898 rtx label = gen_label_rtx ();
11899 rtx tmp;
11900
11901 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11902
11903 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11904 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11905 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11906 gen_rtx_LABEL_REF (VOIDmode, label),
11907 pc_rtx);
11908 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11909 JUMP_LABEL (tmp) = label;
11910
11911 emit_move_insn (operands[0], operands[1]);
11912 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11913
11914 emit_label (label);
11915 LABEL_NUSES (label) = 1;
11916
11917 DONE;
11918 })
11919
11920 (define_insn "ashrsi3_31"
11921 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11922 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11923 (match_operand:SI 2 "const_int_operand" "i,i")))
11924 (clobber (reg:CC 17))]
11925 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11926 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11927 "@
11928 {cltd|cdq}
11929 sar{l}\t{%2, %0|%0, %2}"
11930 [(set_attr "type" "imovx,ishift")
11931 (set_attr "prefix_0f" "0,*")
11932 (set_attr "length_immediate" "0,*")
11933 (set_attr "modrm" "0,1")
11934 (set_attr "mode" "SI")])
11935
11936 (define_insn "*ashrsi3_31_zext"
11937 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11938 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11939 (match_operand:SI 2 "const_int_operand" "i,i"))))
11940 (clobber (reg:CC 17))]
11941 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11942 && INTVAL (operands[2]) == 31
11943 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11944 "@
11945 {cltd|cdq}
11946 sar{l}\t{%2, %k0|%k0, %2}"
11947 [(set_attr "type" "imovx,ishift")
11948 (set_attr "prefix_0f" "0,*")
11949 (set_attr "length_immediate" "0,*")
11950 (set_attr "modrm" "0,1")
11951 (set_attr "mode" "SI")])
11952
11953 (define_expand "ashrsi3"
11954 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11955 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11956 (match_operand:QI 2 "nonmemory_operand" "")))
11957 (clobber (reg:CC 17))]
11958 ""
11959 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11960
11961 (define_insn "*ashrsi3_1_one_bit"
11962 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11963 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11964 (match_operand:QI 2 "const_int_1_operand" "")))
11965 (clobber (reg:CC 17))]
11966 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11967 && (TARGET_SHIFT1 || optimize_size)"
11968 "sar{l}\t%0"
11969 [(set_attr "type" "ishift")
11970 (set (attr "length")
11971 (if_then_else (match_operand:SI 0 "register_operand" "")
11972 (const_string "2")
11973 (const_string "*")))])
11974
11975 (define_insn "*ashrsi3_1_one_bit_zext"
11976 [(set (match_operand:DI 0 "register_operand" "=r")
11977 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11978 (match_operand:QI 2 "const_int_1_operand" ""))))
11979 (clobber (reg:CC 17))]
11980 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11981 && (TARGET_SHIFT1 || optimize_size)"
11982 "sar{l}\t%k0"
11983 [(set_attr "type" "ishift")
11984 (set_attr "length" "2")])
11985
11986 (define_insn "*ashrsi3_1"
11987 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11988 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11989 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11990 (clobber (reg:CC 17))]
11991 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11992 "@
11993 sar{l}\t{%2, %0|%0, %2}
11994 sar{l}\t{%b2, %0|%0, %b2}"
11995 [(set_attr "type" "ishift")
11996 (set_attr "mode" "SI")])
11997
11998 (define_insn "*ashrsi3_1_zext"
11999 [(set (match_operand:DI 0 "register_operand" "=r,r")
12000 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12001 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12002 (clobber (reg:CC 17))]
12003 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12004 "@
12005 sar{l}\t{%2, %k0|%k0, %2}
12006 sar{l}\t{%b2, %k0|%k0, %b2}"
12007 [(set_attr "type" "ishift")
12008 (set_attr "mode" "SI")])
12009
12010 ;; This pattern can't accept a variable shift count, since shifts by
12011 ;; zero don't affect the flags. We assume that shifts by constant
12012 ;; zero are optimized away.
12013 (define_insn "*ashrsi3_one_bit_cmp"
12014 [(set (reg 17)
12015 (compare
12016 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12017 (match_operand:QI 2 "const_int_1_operand" ""))
12018 (const_int 0)))
12019 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12020 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12021 "ix86_match_ccmode (insn, CCGOCmode)
12022 && (TARGET_SHIFT1 || optimize_size)
12023 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12024 "sar{l}\t%0"
12025 [(set_attr "type" "ishift")
12026 (set (attr "length")
12027 (if_then_else (match_operand:SI 0 "register_operand" "")
12028 (const_string "2")
12029 (const_string "*")))])
12030
12031 (define_insn "*ashrsi3_one_bit_cmp_zext"
12032 [(set (reg 17)
12033 (compare
12034 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12035 (match_operand:QI 2 "const_int_1_operand" ""))
12036 (const_int 0)))
12037 (set (match_operand:DI 0 "register_operand" "=r")
12038 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12039 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
12040 && (TARGET_SHIFT1 || optimize_size)
12041 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12042 "sar{l}\t%k0"
12043 [(set_attr "type" "ishift")
12044 (set_attr "length" "2")])
12045
12046 ;; This pattern can't accept a variable shift count, since shifts by
12047 ;; zero don't affect the flags. We assume that shifts by constant
12048 ;; zero are optimized away.
12049 (define_insn "*ashrsi3_cmp"
12050 [(set (reg 17)
12051 (compare
12052 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12053 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12054 (const_int 0)))
12055 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12056 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12057 "ix86_match_ccmode (insn, CCGOCmode)
12058 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12059 "sar{l}\t{%2, %0|%0, %2}"
12060 [(set_attr "type" "ishift")
12061 (set_attr "mode" "SI")])
12062
12063 (define_insn "*ashrsi3_cmp_zext"
12064 [(set (reg 17)
12065 (compare
12066 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12067 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12068 (const_int 0)))
12069 (set (match_operand:DI 0 "register_operand" "=r")
12070 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12071 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12072 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12073 "sar{l}\t{%2, %k0|%k0, %2}"
12074 [(set_attr "type" "ishift")
12075 (set_attr "mode" "SI")])
12076
12077 (define_expand "ashrhi3"
12078 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12079 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12080 (match_operand:QI 2 "nonmemory_operand" "")))
12081 (clobber (reg:CC 17))]
12082 "TARGET_HIMODE_MATH"
12083 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12084
12085 (define_insn "*ashrhi3_1_one_bit"
12086 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12087 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12088 (match_operand:QI 2 "const_int_1_operand" "")))
12089 (clobber (reg:CC 17))]
12090 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12091 && (TARGET_SHIFT1 || optimize_size)"
12092 "sar{w}\t%0"
12093 [(set_attr "type" "ishift")
12094 (set (attr "length")
12095 (if_then_else (match_operand 0 "register_operand" "")
12096 (const_string "2")
12097 (const_string "*")))])
12098
12099 (define_insn "*ashrhi3_1"
12100 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12101 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12102 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12103 (clobber (reg:CC 17))]
12104 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12105 "@
12106 sar{w}\t{%2, %0|%0, %2}
12107 sar{w}\t{%b2, %0|%0, %b2}"
12108 [(set_attr "type" "ishift")
12109 (set_attr "mode" "HI")])
12110
12111 ;; This pattern can't accept a variable shift count, since shifts by
12112 ;; zero don't affect the flags. We assume that shifts by constant
12113 ;; zero are optimized away.
12114 (define_insn "*ashrhi3_one_bit_cmp"
12115 [(set (reg 17)
12116 (compare
12117 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12118 (match_operand:QI 2 "const_int_1_operand" ""))
12119 (const_int 0)))
12120 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12121 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12122 "ix86_match_ccmode (insn, CCGOCmode)
12123 && (TARGET_SHIFT1 || optimize_size)
12124 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12125 "sar{w}\t%0"
12126 [(set_attr "type" "ishift")
12127 (set (attr "length")
12128 (if_then_else (match_operand 0 "register_operand" "")
12129 (const_string "2")
12130 (const_string "*")))])
12131
12132 ;; This pattern can't accept a variable shift count, since shifts by
12133 ;; zero don't affect the flags. We assume that shifts by constant
12134 ;; zero are optimized away.
12135 (define_insn "*ashrhi3_cmp"
12136 [(set (reg 17)
12137 (compare
12138 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12139 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12140 (const_int 0)))
12141 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12142 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12143 "ix86_match_ccmode (insn, CCGOCmode)
12144 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12145 "sar{w}\t{%2, %0|%0, %2}"
12146 [(set_attr "type" "ishift")
12147 (set_attr "mode" "HI")])
12148
12149 (define_expand "ashrqi3"
12150 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12151 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12152 (match_operand:QI 2 "nonmemory_operand" "")))
12153 (clobber (reg:CC 17))]
12154 "TARGET_QIMODE_MATH"
12155 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12156
12157 (define_insn "*ashrqi3_1_one_bit"
12158 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12159 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12160 (match_operand:QI 2 "const_int_1_operand" "")))
12161 (clobber (reg:CC 17))]
12162 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12163 && (TARGET_SHIFT1 || optimize_size)"
12164 "sar{b}\t%0"
12165 [(set_attr "type" "ishift")
12166 (set (attr "length")
12167 (if_then_else (match_operand 0 "register_operand" "")
12168 (const_string "2")
12169 (const_string "*")))])
12170
12171 (define_insn "*ashrqi3_1_one_bit_slp"
12172 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12173 (ashiftrt:QI (match_dup 0)
12174 (match_operand:QI 1 "const_int_1_operand" "")))
12175 (clobber (reg:CC 17))]
12176 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12177 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12178 && (TARGET_SHIFT1 || optimize_size)"
12179 "sar{b}\t%0"
12180 [(set_attr "type" "ishift1")
12181 (set (attr "length")
12182 (if_then_else (match_operand 0 "register_operand" "")
12183 (const_string "2")
12184 (const_string "*")))])
12185
12186 (define_insn "*ashrqi3_1"
12187 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12188 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12189 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12190 (clobber (reg:CC 17))]
12191 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12192 "@
12193 sar{b}\t{%2, %0|%0, %2}
12194 sar{b}\t{%b2, %0|%0, %b2}"
12195 [(set_attr "type" "ishift")
12196 (set_attr "mode" "QI")])
12197
12198 (define_insn "*ashrqi3_1_slp"
12199 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12200 (ashiftrt:QI (match_dup 0)
12201 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12202 (clobber (reg:CC 17))]
12203 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12205 "@
12206 sar{b}\t{%1, %0|%0, %1}
12207 sar{b}\t{%b1, %0|%0, %b1}"
12208 [(set_attr "type" "ishift1")
12209 (set_attr "mode" "QI")])
12210
12211 ;; This pattern can't accept a variable shift count, since shifts by
12212 ;; zero don't affect the flags. We assume that shifts by constant
12213 ;; zero are optimized away.
12214 (define_insn "*ashrqi3_one_bit_cmp"
12215 [(set (reg 17)
12216 (compare
12217 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12218 (match_operand:QI 2 "const_int_1_operand" "I"))
12219 (const_int 0)))
12220 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12221 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12222 "ix86_match_ccmode (insn, CCGOCmode)
12223 && (TARGET_SHIFT1 || optimize_size)
12224 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12225 "sar{b}\t%0"
12226 [(set_attr "type" "ishift")
12227 (set (attr "length")
12228 (if_then_else (match_operand 0 "register_operand" "")
12229 (const_string "2")
12230 (const_string "*")))])
12231
12232 ;; This pattern can't accept a variable shift count, since shifts by
12233 ;; zero don't affect the flags. We assume that shifts by constant
12234 ;; zero are optimized away.
12235 (define_insn "*ashrqi3_cmp"
12236 [(set (reg 17)
12237 (compare
12238 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12239 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12240 (const_int 0)))
12241 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12242 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12243 "ix86_match_ccmode (insn, CCGOCmode)
12244 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12245 "sar{b}\t{%2, %0|%0, %2}"
12246 [(set_attr "type" "ishift")
12247 (set_attr "mode" "QI")])
12248 \f
12249 ;; Logical shift instructions
12250
12251 ;; See comment above `ashldi3' about how this works.
12252
12253 (define_expand "lshrdi3"
12254 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
12255 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12256 (match_operand:QI 2 "nonmemory_operand" "")))
12257 (clobber (reg:CC 17))])]
12258 ""
12259 {
12260 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
12261 {
12262 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
12263 DONE;
12264 }
12265 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
12266 DONE;
12267 })
12268
12269 (define_insn "*lshrdi3_1_one_bit_rex64"
12270 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12271 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12272 (match_operand:QI 2 "const_int_1_operand" "")))
12273 (clobber (reg:CC 17))]
12274 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12275 && (TARGET_SHIFT1 || optimize_size)"
12276 "shr{q}\t%0"
12277 [(set_attr "type" "ishift")
12278 (set (attr "length")
12279 (if_then_else (match_operand:DI 0 "register_operand" "")
12280 (const_string "2")
12281 (const_string "*")))])
12282
12283 (define_insn "*lshrdi3_1_rex64"
12284 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12285 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12286 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12287 (clobber (reg:CC 17))]
12288 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12289 "@
12290 shr{q}\t{%2, %0|%0, %2}
12291 shr{q}\t{%b2, %0|%0, %b2}"
12292 [(set_attr "type" "ishift")
12293 (set_attr "mode" "DI")])
12294
12295 ;; This pattern can't accept a variable shift count, since shifts by
12296 ;; zero don't affect the flags. We assume that shifts by constant
12297 ;; zero are optimized away.
12298 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12299 [(set (reg 17)
12300 (compare
12301 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12302 (match_operand:QI 2 "const_int_1_operand" ""))
12303 (const_int 0)))
12304 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12305 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12306 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12307 && (TARGET_SHIFT1 || optimize_size)
12308 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12309 "shr{q}\t%0"
12310 [(set_attr "type" "ishift")
12311 (set (attr "length")
12312 (if_then_else (match_operand:DI 0 "register_operand" "")
12313 (const_string "2")
12314 (const_string "*")))])
12315
12316 ;; This pattern can't accept a variable shift count, since shifts by
12317 ;; zero don't affect the flags. We assume that shifts by constant
12318 ;; zero are optimized away.
12319 (define_insn "*lshrdi3_cmp_rex64"
12320 [(set (reg 17)
12321 (compare
12322 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12323 (match_operand:QI 2 "const_int_operand" "e"))
12324 (const_int 0)))
12325 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12326 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12327 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12328 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12329 "shr{q}\t{%2, %0|%0, %2}"
12330 [(set_attr "type" "ishift")
12331 (set_attr "mode" "DI")])
12332
12333 (define_insn "lshrdi3_1"
12334 [(set (match_operand:DI 0 "register_operand" "=r")
12335 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12336 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12337 (clobber (match_scratch:SI 3 "=&r"))
12338 (clobber (reg:CC 17))]
12339 "!TARGET_64BIT && TARGET_CMOVE"
12340 "#"
12341 [(set_attr "type" "multi")])
12342
12343 (define_insn "*lshrdi3_2"
12344 [(set (match_operand:DI 0 "register_operand" "=r")
12345 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12346 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12347 (clobber (reg:CC 17))]
12348 "!TARGET_64BIT"
12349 "#"
12350 [(set_attr "type" "multi")])
12351
12352 (define_split
12353 [(set (match_operand:DI 0 "register_operand" "")
12354 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12355 (match_operand:QI 2 "nonmemory_operand" "")))
12356 (clobber (match_scratch:SI 3 ""))
12357 (clobber (reg:CC 17))]
12358 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
12359 [(const_int 0)]
12360 "ix86_split_lshrdi (operands, operands[3]); DONE;")
12361
12362 (define_split
12363 [(set (match_operand:DI 0 "register_operand" "")
12364 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12365 (match_operand:QI 2 "nonmemory_operand" "")))
12366 (clobber (reg:CC 17))]
12367 "!TARGET_64BIT && reload_completed"
12368 [(const_int 0)]
12369 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
12370
12371 (define_expand "lshrsi3"
12372 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12373 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12374 (match_operand:QI 2 "nonmemory_operand" "")))
12375 (clobber (reg:CC 17))]
12376 ""
12377 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12378
12379 (define_insn "*lshrsi3_1_one_bit"
12380 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12381 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12382 (match_operand:QI 2 "const_int_1_operand" "")))
12383 (clobber (reg:CC 17))]
12384 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12385 && (TARGET_SHIFT1 || optimize_size)"
12386 "shr{l}\t%0"
12387 [(set_attr "type" "ishift")
12388 (set (attr "length")
12389 (if_then_else (match_operand:SI 0 "register_operand" "")
12390 (const_string "2")
12391 (const_string "*")))])
12392
12393 (define_insn "*lshrsi3_1_one_bit_zext"
12394 [(set (match_operand:DI 0 "register_operand" "=r")
12395 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12396 (match_operand:QI 2 "const_int_1_operand" "")))
12397 (clobber (reg:CC 17))]
12398 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12399 && (TARGET_SHIFT1 || optimize_size)"
12400 "shr{l}\t%k0"
12401 [(set_attr "type" "ishift")
12402 (set_attr "length" "2")])
12403
12404 (define_insn "*lshrsi3_1"
12405 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12406 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12407 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12408 (clobber (reg:CC 17))]
12409 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12410 "@
12411 shr{l}\t{%2, %0|%0, %2}
12412 shr{l}\t{%b2, %0|%0, %b2}"
12413 [(set_attr "type" "ishift")
12414 (set_attr "mode" "SI")])
12415
12416 (define_insn "*lshrsi3_1_zext"
12417 [(set (match_operand:DI 0 "register_operand" "=r,r")
12418 (zero_extend:DI
12419 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12420 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12421 (clobber (reg:CC 17))]
12422 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12423 "@
12424 shr{l}\t{%2, %k0|%k0, %2}
12425 shr{l}\t{%b2, %k0|%k0, %b2}"
12426 [(set_attr "type" "ishift")
12427 (set_attr "mode" "SI")])
12428
12429 ;; This pattern can't accept a variable shift count, since shifts by
12430 ;; zero don't affect the flags. We assume that shifts by constant
12431 ;; zero are optimized away.
12432 (define_insn "*lshrsi3_one_bit_cmp"
12433 [(set (reg 17)
12434 (compare
12435 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12436 (match_operand:QI 2 "const_int_1_operand" ""))
12437 (const_int 0)))
12438 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12439 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12440 "ix86_match_ccmode (insn, CCGOCmode)
12441 && (TARGET_SHIFT1 || optimize_size)
12442 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12443 "shr{l}\t%0"
12444 [(set_attr "type" "ishift")
12445 (set (attr "length")
12446 (if_then_else (match_operand:SI 0 "register_operand" "")
12447 (const_string "2")
12448 (const_string "*")))])
12449
12450 (define_insn "*lshrsi3_cmp_one_bit_zext"
12451 [(set (reg 17)
12452 (compare
12453 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12454 (match_operand:QI 2 "const_int_1_operand" ""))
12455 (const_int 0)))
12456 (set (match_operand:DI 0 "register_operand" "=r")
12457 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12458 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12459 && (TARGET_SHIFT1 || optimize_size)
12460 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12461 "shr{l}\t%k0"
12462 [(set_attr "type" "ishift")
12463 (set_attr "length" "2")])
12464
12465 ;; This pattern can't accept a variable shift count, since shifts by
12466 ;; zero don't affect the flags. We assume that shifts by constant
12467 ;; zero are optimized away.
12468 (define_insn "*lshrsi3_cmp"
12469 [(set (reg 17)
12470 (compare
12471 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12472 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12473 (const_int 0)))
12474 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12475 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12476 "ix86_match_ccmode (insn, CCGOCmode)
12477 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12478 "shr{l}\t{%2, %0|%0, %2}"
12479 [(set_attr "type" "ishift")
12480 (set_attr "mode" "SI")])
12481
12482 (define_insn "*lshrsi3_cmp_zext"
12483 [(set (reg 17)
12484 (compare
12485 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12486 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12487 (const_int 0)))
12488 (set (match_operand:DI 0 "register_operand" "=r")
12489 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12490 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12491 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12492 "shr{l}\t{%2, %k0|%k0, %2}"
12493 [(set_attr "type" "ishift")
12494 (set_attr "mode" "SI")])
12495
12496 (define_expand "lshrhi3"
12497 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12498 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12499 (match_operand:QI 2 "nonmemory_operand" "")))
12500 (clobber (reg:CC 17))]
12501 "TARGET_HIMODE_MATH"
12502 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12503
12504 (define_insn "*lshrhi3_1_one_bit"
12505 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12506 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12507 (match_operand:QI 2 "const_int_1_operand" "")))
12508 (clobber (reg:CC 17))]
12509 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12510 && (TARGET_SHIFT1 || optimize_size)"
12511 "shr{w}\t%0"
12512 [(set_attr "type" "ishift")
12513 (set (attr "length")
12514 (if_then_else (match_operand 0 "register_operand" "")
12515 (const_string "2")
12516 (const_string "*")))])
12517
12518 (define_insn "*lshrhi3_1"
12519 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12520 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12521 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12522 (clobber (reg:CC 17))]
12523 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12524 "@
12525 shr{w}\t{%2, %0|%0, %2}
12526 shr{w}\t{%b2, %0|%0, %b2}"
12527 [(set_attr "type" "ishift")
12528 (set_attr "mode" "HI")])
12529
12530 ;; This pattern can't accept a variable shift count, since shifts by
12531 ;; zero don't affect the flags. We assume that shifts by constant
12532 ;; zero are optimized away.
12533 (define_insn "*lshrhi3_one_bit_cmp"
12534 [(set (reg 17)
12535 (compare
12536 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12537 (match_operand:QI 2 "const_int_1_operand" ""))
12538 (const_int 0)))
12539 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12540 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12541 "ix86_match_ccmode (insn, CCGOCmode)
12542 && (TARGET_SHIFT1 || optimize_size)
12543 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12544 "shr{w}\t%0"
12545 [(set_attr "type" "ishift")
12546 (set (attr "length")
12547 (if_then_else (match_operand:SI 0 "register_operand" "")
12548 (const_string "2")
12549 (const_string "*")))])
12550
12551 ;; This pattern can't accept a variable shift count, since shifts by
12552 ;; zero don't affect the flags. We assume that shifts by constant
12553 ;; zero are optimized away.
12554 (define_insn "*lshrhi3_cmp"
12555 [(set (reg 17)
12556 (compare
12557 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12558 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12559 (const_int 0)))
12560 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12561 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12562 "ix86_match_ccmode (insn, CCGOCmode)
12563 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12564 "shr{w}\t{%2, %0|%0, %2}"
12565 [(set_attr "type" "ishift")
12566 (set_attr "mode" "HI")])
12567
12568 (define_expand "lshrqi3"
12569 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12570 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12571 (match_operand:QI 2 "nonmemory_operand" "")))
12572 (clobber (reg:CC 17))]
12573 "TARGET_QIMODE_MATH"
12574 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12575
12576 (define_insn "*lshrqi3_1_one_bit"
12577 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12578 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12579 (match_operand:QI 2 "const_int_1_operand" "")))
12580 (clobber (reg:CC 17))]
12581 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12582 && (TARGET_SHIFT1 || optimize_size)"
12583 "shr{b}\t%0"
12584 [(set_attr "type" "ishift")
12585 (set (attr "length")
12586 (if_then_else (match_operand 0 "register_operand" "")
12587 (const_string "2")
12588 (const_string "*")))])
12589
12590 (define_insn "*lshrqi3_1_one_bit_slp"
12591 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12592 (lshiftrt:QI (match_dup 0)
12593 (match_operand:QI 1 "const_int_1_operand" "")))
12594 (clobber (reg:CC 17))]
12595 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12596 && (TARGET_SHIFT1 || optimize_size)"
12597 "shr{b}\t%0"
12598 [(set_attr "type" "ishift1")
12599 (set (attr "length")
12600 (if_then_else (match_operand 0 "register_operand" "")
12601 (const_string "2")
12602 (const_string "*")))])
12603
12604 (define_insn "*lshrqi3_1"
12605 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12606 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12607 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12608 (clobber (reg:CC 17))]
12609 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12610 "@
12611 shr{b}\t{%2, %0|%0, %2}
12612 shr{b}\t{%b2, %0|%0, %b2}"
12613 [(set_attr "type" "ishift")
12614 (set_attr "mode" "QI")])
12615
12616 (define_insn "*lshrqi3_1_slp"
12617 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12618 (lshiftrt:QI (match_dup 0)
12619 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12620 (clobber (reg:CC 17))]
12621 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12622 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12623 "@
12624 shr{b}\t{%1, %0|%0, %1}
12625 shr{b}\t{%b1, %0|%0, %b1}"
12626 [(set_attr "type" "ishift1")
12627 (set_attr "mode" "QI")])
12628
12629 ;; This pattern can't accept a variable shift count, since shifts by
12630 ;; zero don't affect the flags. We assume that shifts by constant
12631 ;; zero are optimized away.
12632 (define_insn "*lshrqi2_one_bit_cmp"
12633 [(set (reg 17)
12634 (compare
12635 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12636 (match_operand:QI 2 "const_int_1_operand" ""))
12637 (const_int 0)))
12638 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12639 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12640 "ix86_match_ccmode (insn, CCGOCmode)
12641 && (TARGET_SHIFT1 || optimize_size)
12642 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12643 "shr{b}\t%0"
12644 [(set_attr "type" "ishift")
12645 (set (attr "length")
12646 (if_then_else (match_operand:SI 0 "register_operand" "")
12647 (const_string "2")
12648 (const_string "*")))])
12649
12650 ;; This pattern can't accept a variable shift count, since shifts by
12651 ;; zero don't affect the flags. We assume that shifts by constant
12652 ;; zero are optimized away.
12653 (define_insn "*lshrqi2_cmp"
12654 [(set (reg 17)
12655 (compare
12656 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12657 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12658 (const_int 0)))
12659 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12660 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12661 "ix86_match_ccmode (insn, CCGOCmode)
12662 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12663 "shr{b}\t{%2, %0|%0, %2}"
12664 [(set_attr "type" "ishift")
12665 (set_attr "mode" "QI")])
12666 \f
12667 ;; Rotate instructions
12668
12669 (define_expand "rotldi3"
12670 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12671 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12672 (match_operand:QI 2 "nonmemory_operand" "")))
12673 (clobber (reg:CC 17))]
12674 "TARGET_64BIT"
12675 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12676
12677 (define_insn "*rotlsi3_1_one_bit_rex64"
12678 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12679 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12680 (match_operand:QI 2 "const_int_1_operand" "")))
12681 (clobber (reg:CC 17))]
12682 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12683 && (TARGET_SHIFT1 || optimize_size)"
12684 "rol{q}\t%0"
12685 [(set_attr "type" "rotate")
12686 (set (attr "length")
12687 (if_then_else (match_operand:DI 0 "register_operand" "")
12688 (const_string "2")
12689 (const_string "*")))])
12690
12691 (define_insn "*rotldi3_1_rex64"
12692 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12693 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12694 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12695 (clobber (reg:CC 17))]
12696 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12697 "@
12698 rol{q}\t{%2, %0|%0, %2}
12699 rol{q}\t{%b2, %0|%0, %b2}"
12700 [(set_attr "type" "rotate")
12701 (set_attr "mode" "DI")])
12702
12703 (define_expand "rotlsi3"
12704 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12705 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12706 (match_operand:QI 2 "nonmemory_operand" "")))
12707 (clobber (reg:CC 17))]
12708 ""
12709 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12710
12711 (define_insn "*rotlsi3_1_one_bit"
12712 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12713 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12714 (match_operand:QI 2 "const_int_1_operand" "")))
12715 (clobber (reg:CC 17))]
12716 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12717 && (TARGET_SHIFT1 || optimize_size)"
12718 "rol{l}\t%0"
12719 [(set_attr "type" "rotate")
12720 (set (attr "length")
12721 (if_then_else (match_operand:SI 0 "register_operand" "")
12722 (const_string "2")
12723 (const_string "*")))])
12724
12725 (define_insn "*rotlsi3_1_one_bit_zext"
12726 [(set (match_operand:DI 0 "register_operand" "=r")
12727 (zero_extend:DI
12728 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12729 (match_operand:QI 2 "const_int_1_operand" ""))))
12730 (clobber (reg:CC 17))]
12731 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12732 && (TARGET_SHIFT1 || optimize_size)"
12733 "rol{l}\t%k0"
12734 [(set_attr "type" "rotate")
12735 (set_attr "length" "2")])
12736
12737 (define_insn "*rotlsi3_1"
12738 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12739 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12740 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12741 (clobber (reg:CC 17))]
12742 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12743 "@
12744 rol{l}\t{%2, %0|%0, %2}
12745 rol{l}\t{%b2, %0|%0, %b2}"
12746 [(set_attr "type" "rotate")
12747 (set_attr "mode" "SI")])
12748
12749 (define_insn "*rotlsi3_1_zext"
12750 [(set (match_operand:DI 0 "register_operand" "=r,r")
12751 (zero_extend:DI
12752 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12753 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12754 (clobber (reg:CC 17))]
12755 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12756 "@
12757 rol{l}\t{%2, %k0|%k0, %2}
12758 rol{l}\t{%b2, %k0|%k0, %b2}"
12759 [(set_attr "type" "rotate")
12760 (set_attr "mode" "SI")])
12761
12762 (define_expand "rotlhi3"
12763 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12764 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12765 (match_operand:QI 2 "nonmemory_operand" "")))
12766 (clobber (reg:CC 17))]
12767 "TARGET_HIMODE_MATH"
12768 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12769
12770 (define_insn "*rotlhi3_1_one_bit"
12771 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12772 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12773 (match_operand:QI 2 "const_int_1_operand" "")))
12774 (clobber (reg:CC 17))]
12775 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12776 && (TARGET_SHIFT1 || optimize_size)"
12777 "rol{w}\t%0"
12778 [(set_attr "type" "rotate")
12779 (set (attr "length")
12780 (if_then_else (match_operand 0 "register_operand" "")
12781 (const_string "2")
12782 (const_string "*")))])
12783
12784 (define_insn "*rotlhi3_1"
12785 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12786 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12787 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12788 (clobber (reg:CC 17))]
12789 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12790 "@
12791 rol{w}\t{%2, %0|%0, %2}
12792 rol{w}\t{%b2, %0|%0, %b2}"
12793 [(set_attr "type" "rotate")
12794 (set_attr "mode" "HI")])
12795
12796 (define_expand "rotlqi3"
12797 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12798 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12799 (match_operand:QI 2 "nonmemory_operand" "")))
12800 (clobber (reg:CC 17))]
12801 "TARGET_QIMODE_MATH"
12802 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12803
12804 (define_insn "*rotlqi3_1_one_bit_slp"
12805 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12806 (rotate:QI (match_dup 0)
12807 (match_operand:QI 1 "const_int_1_operand" "")))
12808 (clobber (reg:CC 17))]
12809 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12810 && (TARGET_SHIFT1 || optimize_size)"
12811 "rol{b}\t%0"
12812 [(set_attr "type" "rotate1")
12813 (set (attr "length")
12814 (if_then_else (match_operand 0 "register_operand" "")
12815 (const_string "2")
12816 (const_string "*")))])
12817
12818 (define_insn "*rotlqi3_1_one_bit"
12819 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12820 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12821 (match_operand:QI 2 "const_int_1_operand" "")))
12822 (clobber (reg:CC 17))]
12823 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12824 && (TARGET_SHIFT1 || optimize_size)"
12825 "rol{b}\t%0"
12826 [(set_attr "type" "rotate")
12827 (set (attr "length")
12828 (if_then_else (match_operand 0 "register_operand" "")
12829 (const_string "2")
12830 (const_string "*")))])
12831
12832 (define_insn "*rotlqi3_1_slp"
12833 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12834 (rotate:QI (match_dup 0)
12835 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12836 (clobber (reg:CC 17))]
12837 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12838 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12839 "@
12840 rol{b}\t{%1, %0|%0, %1}
12841 rol{b}\t{%b1, %0|%0, %b1}"
12842 [(set_attr "type" "rotate1")
12843 (set_attr "mode" "QI")])
12844
12845 (define_insn "*rotlqi3_1"
12846 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12847 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12848 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12849 (clobber (reg:CC 17))]
12850 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12851 "@
12852 rol{b}\t{%2, %0|%0, %2}
12853 rol{b}\t{%b2, %0|%0, %b2}"
12854 [(set_attr "type" "rotate")
12855 (set_attr "mode" "QI")])
12856
12857 (define_expand "rotrdi3"
12858 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12859 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12860 (match_operand:QI 2 "nonmemory_operand" "")))
12861 (clobber (reg:CC 17))]
12862 "TARGET_64BIT"
12863 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12864
12865 (define_insn "*rotrdi3_1_one_bit_rex64"
12866 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12867 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12868 (match_operand:QI 2 "const_int_1_operand" "")))
12869 (clobber (reg:CC 17))]
12870 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12871 && (TARGET_SHIFT1 || optimize_size)"
12872 "ror{q}\t%0"
12873 [(set_attr "type" "rotate")
12874 (set (attr "length")
12875 (if_then_else (match_operand:DI 0 "register_operand" "")
12876 (const_string "2")
12877 (const_string "*")))])
12878
12879 (define_insn "*rotrdi3_1_rex64"
12880 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12881 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12882 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12883 (clobber (reg:CC 17))]
12884 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12885 "@
12886 ror{q}\t{%2, %0|%0, %2}
12887 ror{q}\t{%b2, %0|%0, %b2}"
12888 [(set_attr "type" "rotate")
12889 (set_attr "mode" "DI")])
12890
12891 (define_expand "rotrsi3"
12892 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12893 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12894 (match_operand:QI 2 "nonmemory_operand" "")))
12895 (clobber (reg:CC 17))]
12896 ""
12897 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12898
12899 (define_insn "*rotrsi3_1_one_bit"
12900 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12901 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12902 (match_operand:QI 2 "const_int_1_operand" "")))
12903 (clobber (reg:CC 17))]
12904 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12905 && (TARGET_SHIFT1 || optimize_size)"
12906 "ror{l}\t%0"
12907 [(set_attr "type" "rotate")
12908 (set (attr "length")
12909 (if_then_else (match_operand:SI 0 "register_operand" "")
12910 (const_string "2")
12911 (const_string "*")))])
12912
12913 (define_insn "*rotrsi3_1_one_bit_zext"
12914 [(set (match_operand:DI 0 "register_operand" "=r")
12915 (zero_extend:DI
12916 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12917 (match_operand:QI 2 "const_int_1_operand" ""))))
12918 (clobber (reg:CC 17))]
12919 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12920 && (TARGET_SHIFT1 || optimize_size)"
12921 "ror{l}\t%k0"
12922 [(set_attr "type" "rotate")
12923 (set (attr "length")
12924 (if_then_else (match_operand:SI 0 "register_operand" "")
12925 (const_string "2")
12926 (const_string "*")))])
12927
12928 (define_insn "*rotrsi3_1"
12929 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12930 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12931 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12932 (clobber (reg:CC 17))]
12933 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12934 "@
12935 ror{l}\t{%2, %0|%0, %2}
12936 ror{l}\t{%b2, %0|%0, %b2}"
12937 [(set_attr "type" "rotate")
12938 (set_attr "mode" "SI")])
12939
12940 (define_insn "*rotrsi3_1_zext"
12941 [(set (match_operand:DI 0 "register_operand" "=r,r")
12942 (zero_extend:DI
12943 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12944 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12945 (clobber (reg:CC 17))]
12946 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12947 "@
12948 ror{l}\t{%2, %k0|%k0, %2}
12949 ror{l}\t{%b2, %k0|%k0, %b2}"
12950 [(set_attr "type" "rotate")
12951 (set_attr "mode" "SI")])
12952
12953 (define_expand "rotrhi3"
12954 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12955 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12956 (match_operand:QI 2 "nonmemory_operand" "")))
12957 (clobber (reg:CC 17))]
12958 "TARGET_HIMODE_MATH"
12959 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12960
12961 (define_insn "*rotrhi3_one_bit"
12962 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12963 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12964 (match_operand:QI 2 "const_int_1_operand" "")))
12965 (clobber (reg:CC 17))]
12966 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12967 && (TARGET_SHIFT1 || optimize_size)"
12968 "ror{w}\t%0"
12969 [(set_attr "type" "rotate")
12970 (set (attr "length")
12971 (if_then_else (match_operand 0 "register_operand" "")
12972 (const_string "2")
12973 (const_string "*")))])
12974
12975 (define_insn "*rotrhi3"
12976 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12977 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12978 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12979 (clobber (reg:CC 17))]
12980 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12981 "@
12982 ror{w}\t{%2, %0|%0, %2}
12983 ror{w}\t{%b2, %0|%0, %b2}"
12984 [(set_attr "type" "rotate")
12985 (set_attr "mode" "HI")])
12986
12987 (define_expand "rotrqi3"
12988 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12989 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12990 (match_operand:QI 2 "nonmemory_operand" "")))
12991 (clobber (reg:CC 17))]
12992 "TARGET_QIMODE_MATH"
12993 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12994
12995 (define_insn "*rotrqi3_1_one_bit"
12996 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12997 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12998 (match_operand:QI 2 "const_int_1_operand" "")))
12999 (clobber (reg:CC 17))]
13000 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13001 && (TARGET_SHIFT1 || optimize_size)"
13002 "ror{b}\t%0"
13003 [(set_attr "type" "rotate")
13004 (set (attr "length")
13005 (if_then_else (match_operand 0 "register_operand" "")
13006 (const_string "2")
13007 (const_string "*")))])
13008
13009 (define_insn "*rotrqi3_1_one_bit_slp"
13010 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13011 (rotatert:QI (match_dup 0)
13012 (match_operand:QI 1 "const_int_1_operand" "")))
13013 (clobber (reg:CC 17))]
13014 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13015 && (TARGET_SHIFT1 || optimize_size)"
13016 "ror{b}\t%0"
13017 [(set_attr "type" "rotate1")
13018 (set (attr "length")
13019 (if_then_else (match_operand 0 "register_operand" "")
13020 (const_string "2")
13021 (const_string "*")))])
13022
13023 (define_insn "*rotrqi3_1"
13024 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13025 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13026 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13027 (clobber (reg:CC 17))]
13028 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13029 "@
13030 ror{b}\t{%2, %0|%0, %2}
13031 ror{b}\t{%b2, %0|%0, %b2}"
13032 [(set_attr "type" "rotate")
13033 (set_attr "mode" "QI")])
13034
13035 (define_insn "*rotrqi3_1_slp"
13036 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13037 (rotatert:QI (match_dup 0)
13038 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13039 (clobber (reg:CC 17))]
13040 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13041 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13042 "@
13043 ror{b}\t{%1, %0|%0, %1}
13044 ror{b}\t{%b1, %0|%0, %b1}"
13045 [(set_attr "type" "rotate1")
13046 (set_attr "mode" "QI")])
13047 \f
13048 ;; Bit set / bit test instructions
13049
13050 (define_expand "extv"
13051 [(set (match_operand:SI 0 "register_operand" "")
13052 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13053 (match_operand:SI 2 "immediate_operand" "")
13054 (match_operand:SI 3 "immediate_operand" "")))]
13055 ""
13056 {
13057 /* Handle extractions from %ah et al. */
13058 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13059 FAIL;
13060
13061 /* From mips.md: extract_bit_field doesn't verify that our source
13062 matches the predicate, so check it again here. */
13063 if (! register_operand (operands[1], VOIDmode))
13064 FAIL;
13065 })
13066
13067 (define_expand "extzv"
13068 [(set (match_operand:SI 0 "register_operand" "")
13069 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13070 (match_operand:SI 2 "immediate_operand" "")
13071 (match_operand:SI 3 "immediate_operand" "")))]
13072 ""
13073 {
13074 /* Handle extractions from %ah et al. */
13075 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13076 FAIL;
13077
13078 /* From mips.md: extract_bit_field doesn't verify that our source
13079 matches the predicate, so check it again here. */
13080 if (! register_operand (operands[1], VOIDmode))
13081 FAIL;
13082 })
13083
13084 (define_expand "insv"
13085 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
13086 (match_operand:SI 1 "immediate_operand" "")
13087 (match_operand:SI 2 "immediate_operand" ""))
13088 (match_operand:SI 3 "register_operand" ""))]
13089 ""
13090 {
13091 /* Handle extractions from %ah et al. */
13092 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13093 FAIL;
13094
13095 /* From mips.md: insert_bit_field doesn't verify that our source
13096 matches the predicate, so check it again here. */
13097 if (! register_operand (operands[0], VOIDmode))
13098 FAIL;
13099 })
13100
13101 ;; %%% bts, btr, btc, bt.
13102 \f
13103 ;; Store-flag instructions.
13104
13105 ;; For all sCOND expanders, also expand the compare or test insn that
13106 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13107
13108 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13109 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13110 ;; way, which can later delete the movzx if only QImode is needed.
13111
13112 (define_expand "seq"
13113 [(set (match_operand:QI 0 "register_operand" "")
13114 (eq:QI (reg:CC 17) (const_int 0)))]
13115 ""
13116 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13117
13118 (define_expand "sne"
13119 [(set (match_operand:QI 0 "register_operand" "")
13120 (ne:QI (reg:CC 17) (const_int 0)))]
13121 ""
13122 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13123
13124 (define_expand "sgt"
13125 [(set (match_operand:QI 0 "register_operand" "")
13126 (gt:QI (reg:CC 17) (const_int 0)))]
13127 ""
13128 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13129
13130 (define_expand "sgtu"
13131 [(set (match_operand:QI 0 "register_operand" "")
13132 (gtu:QI (reg:CC 17) (const_int 0)))]
13133 ""
13134 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13135
13136 (define_expand "slt"
13137 [(set (match_operand:QI 0 "register_operand" "")
13138 (lt:QI (reg:CC 17) (const_int 0)))]
13139 ""
13140 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13141
13142 (define_expand "sltu"
13143 [(set (match_operand:QI 0 "register_operand" "")
13144 (ltu:QI (reg:CC 17) (const_int 0)))]
13145 ""
13146 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13147
13148 (define_expand "sge"
13149 [(set (match_operand:QI 0 "register_operand" "")
13150 (ge:QI (reg:CC 17) (const_int 0)))]
13151 ""
13152 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13153
13154 (define_expand "sgeu"
13155 [(set (match_operand:QI 0 "register_operand" "")
13156 (geu:QI (reg:CC 17) (const_int 0)))]
13157 ""
13158 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13159
13160 (define_expand "sle"
13161 [(set (match_operand:QI 0 "register_operand" "")
13162 (le:QI (reg:CC 17) (const_int 0)))]
13163 ""
13164 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13165
13166 (define_expand "sleu"
13167 [(set (match_operand:QI 0 "register_operand" "")
13168 (leu:QI (reg:CC 17) (const_int 0)))]
13169 ""
13170 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13171
13172 (define_expand "sunordered"
13173 [(set (match_operand:QI 0 "register_operand" "")
13174 (unordered:QI (reg:CC 17) (const_int 0)))]
13175 "TARGET_80387 || TARGET_SSE"
13176 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13177
13178 (define_expand "sordered"
13179 [(set (match_operand:QI 0 "register_operand" "")
13180 (ordered:QI (reg:CC 17) (const_int 0)))]
13181 "TARGET_80387"
13182 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13183
13184 (define_expand "suneq"
13185 [(set (match_operand:QI 0 "register_operand" "")
13186 (uneq:QI (reg:CC 17) (const_int 0)))]
13187 "TARGET_80387 || TARGET_SSE"
13188 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13189
13190 (define_expand "sunge"
13191 [(set (match_operand:QI 0 "register_operand" "")
13192 (unge:QI (reg:CC 17) (const_int 0)))]
13193 "TARGET_80387 || TARGET_SSE"
13194 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13195
13196 (define_expand "sungt"
13197 [(set (match_operand:QI 0 "register_operand" "")
13198 (ungt:QI (reg:CC 17) (const_int 0)))]
13199 "TARGET_80387 || TARGET_SSE"
13200 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13201
13202 (define_expand "sunle"
13203 [(set (match_operand:QI 0 "register_operand" "")
13204 (unle:QI (reg:CC 17) (const_int 0)))]
13205 "TARGET_80387 || TARGET_SSE"
13206 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13207
13208 (define_expand "sunlt"
13209 [(set (match_operand:QI 0 "register_operand" "")
13210 (unlt:QI (reg:CC 17) (const_int 0)))]
13211 "TARGET_80387 || TARGET_SSE"
13212 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13213
13214 (define_expand "sltgt"
13215 [(set (match_operand:QI 0 "register_operand" "")
13216 (ltgt:QI (reg:CC 17) (const_int 0)))]
13217 "TARGET_80387 || TARGET_SSE"
13218 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13219
13220 (define_insn "*setcc_1"
13221 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13222 (match_operator:QI 1 "ix86_comparison_operator"
13223 [(reg 17) (const_int 0)]))]
13224 ""
13225 "set%C1\t%0"
13226 [(set_attr "type" "setcc")
13227 (set_attr "mode" "QI")])
13228
13229 (define_insn "setcc_2"
13230 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13231 (match_operator:QI 1 "ix86_comparison_operator"
13232 [(reg 17) (const_int 0)]))]
13233 ""
13234 "set%C1\t%0"
13235 [(set_attr "type" "setcc")
13236 (set_attr "mode" "QI")])
13237
13238 ;; In general it is not safe to assume too much about CCmode registers,
13239 ;; so simplify-rtx stops when it sees a second one. Under certain
13240 ;; conditions this is safe on x86, so help combine not create
13241 ;;
13242 ;; seta %al
13243 ;; testb %al, %al
13244 ;; sete %al
13245
13246 (define_split
13247 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13248 (ne:QI (match_operator 1 "ix86_comparison_operator"
13249 [(reg 17) (const_int 0)])
13250 (const_int 0)))]
13251 ""
13252 [(set (match_dup 0) (match_dup 1))]
13253 {
13254 PUT_MODE (operands[1], QImode);
13255 })
13256
13257 (define_split
13258 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13259 (ne:QI (match_operator 1 "ix86_comparison_operator"
13260 [(reg 17) (const_int 0)])
13261 (const_int 0)))]
13262 ""
13263 [(set (match_dup 0) (match_dup 1))]
13264 {
13265 PUT_MODE (operands[1], QImode);
13266 })
13267
13268 (define_split
13269 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13270 (eq:QI (match_operator 1 "ix86_comparison_operator"
13271 [(reg 17) (const_int 0)])
13272 (const_int 0)))]
13273 ""
13274 [(set (match_dup 0) (match_dup 1))]
13275 {
13276 rtx new_op1 = copy_rtx (operands[1]);
13277 operands[1] = new_op1;
13278 PUT_MODE (new_op1, QImode);
13279 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13280 GET_MODE (XEXP (new_op1, 0))));
13281
13282 /* Make sure that (a) the CCmode we have for the flags is strong
13283 enough for the reversed compare or (b) we have a valid FP compare. */
13284 if (! ix86_comparison_operator (new_op1, VOIDmode))
13285 FAIL;
13286 })
13287
13288 (define_split
13289 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13290 (eq:QI (match_operator 1 "ix86_comparison_operator"
13291 [(reg 17) (const_int 0)])
13292 (const_int 0)))]
13293 ""
13294 [(set (match_dup 0) (match_dup 1))]
13295 {
13296 rtx new_op1 = copy_rtx (operands[1]);
13297 operands[1] = new_op1;
13298 PUT_MODE (new_op1, QImode);
13299 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13300 GET_MODE (XEXP (new_op1, 0))));
13301
13302 /* Make sure that (a) the CCmode we have for the flags is strong
13303 enough for the reversed compare or (b) we have a valid FP compare. */
13304 if (! ix86_comparison_operator (new_op1, VOIDmode))
13305 FAIL;
13306 })
13307
13308 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13309 ;; subsequent logical operations are used to imitate conditional moves.
13310 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13311 ;; it directly. Further holding this value in pseudo register might bring
13312 ;; problem in implicit normalization in spill code.
13313 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
13314 ;; instructions after reload by splitting the conditional move patterns.
13315
13316 (define_insn "*sse_setccsf"
13317 [(set (match_operand:SF 0 "register_operand" "=x")
13318 (match_operator:SF 1 "sse_comparison_operator"
13319 [(match_operand:SF 2 "register_operand" "0")
13320 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13321 "TARGET_SSE && reload_completed"
13322 "cmp%D1ss\t{%3, %0|%0, %3}"
13323 [(set_attr "type" "ssecmp")
13324 (set_attr "mode" "SF")])
13325
13326 (define_insn "*sse_setccdf"
13327 [(set (match_operand:DF 0 "register_operand" "=Y")
13328 (match_operator:DF 1 "sse_comparison_operator"
13329 [(match_operand:DF 2 "register_operand" "0")
13330 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13331 "TARGET_SSE2 && reload_completed"
13332 "cmp%D1sd\t{%3, %0|%0, %3}"
13333 [(set_attr "type" "ssecmp")
13334 (set_attr "mode" "DF")])
13335 \f
13336 ;; Basic conditional jump instructions.
13337 ;; We ignore the overflow flag for signed branch instructions.
13338
13339 ;; For all bCOND expanders, also expand the compare or test insn that
13340 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
13341
13342 (define_expand "beq"
13343 [(set (pc)
13344 (if_then_else (match_dup 1)
13345 (label_ref (match_operand 0 "" ""))
13346 (pc)))]
13347 ""
13348 "ix86_expand_branch (EQ, operands[0]); DONE;")
13349
13350 (define_expand "bne"
13351 [(set (pc)
13352 (if_then_else (match_dup 1)
13353 (label_ref (match_operand 0 "" ""))
13354 (pc)))]
13355 ""
13356 "ix86_expand_branch (NE, operands[0]); DONE;")
13357
13358 (define_expand "bgt"
13359 [(set (pc)
13360 (if_then_else (match_dup 1)
13361 (label_ref (match_operand 0 "" ""))
13362 (pc)))]
13363 ""
13364 "ix86_expand_branch (GT, operands[0]); DONE;")
13365
13366 (define_expand "bgtu"
13367 [(set (pc)
13368 (if_then_else (match_dup 1)
13369 (label_ref (match_operand 0 "" ""))
13370 (pc)))]
13371 ""
13372 "ix86_expand_branch (GTU, operands[0]); DONE;")
13373
13374 (define_expand "blt"
13375 [(set (pc)
13376 (if_then_else (match_dup 1)
13377 (label_ref (match_operand 0 "" ""))
13378 (pc)))]
13379 ""
13380 "ix86_expand_branch (LT, operands[0]); DONE;")
13381
13382 (define_expand "bltu"
13383 [(set (pc)
13384 (if_then_else (match_dup 1)
13385 (label_ref (match_operand 0 "" ""))
13386 (pc)))]
13387 ""
13388 "ix86_expand_branch (LTU, operands[0]); DONE;")
13389
13390 (define_expand "bge"
13391 [(set (pc)
13392 (if_then_else (match_dup 1)
13393 (label_ref (match_operand 0 "" ""))
13394 (pc)))]
13395 ""
13396 "ix86_expand_branch (GE, operands[0]); DONE;")
13397
13398 (define_expand "bgeu"
13399 [(set (pc)
13400 (if_then_else (match_dup 1)
13401 (label_ref (match_operand 0 "" ""))
13402 (pc)))]
13403 ""
13404 "ix86_expand_branch (GEU, operands[0]); DONE;")
13405
13406 (define_expand "ble"
13407 [(set (pc)
13408 (if_then_else (match_dup 1)
13409 (label_ref (match_operand 0 "" ""))
13410 (pc)))]
13411 ""
13412 "ix86_expand_branch (LE, operands[0]); DONE;")
13413
13414 (define_expand "bleu"
13415 [(set (pc)
13416 (if_then_else (match_dup 1)
13417 (label_ref (match_operand 0 "" ""))
13418 (pc)))]
13419 ""
13420 "ix86_expand_branch (LEU, operands[0]); DONE;")
13421
13422 (define_expand "bunordered"
13423 [(set (pc)
13424 (if_then_else (match_dup 1)
13425 (label_ref (match_operand 0 "" ""))
13426 (pc)))]
13427 "TARGET_80387 || TARGET_SSE"
13428 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13429
13430 (define_expand "bordered"
13431 [(set (pc)
13432 (if_then_else (match_dup 1)
13433 (label_ref (match_operand 0 "" ""))
13434 (pc)))]
13435 "TARGET_80387 || TARGET_SSE"
13436 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13437
13438 (define_expand "buneq"
13439 [(set (pc)
13440 (if_then_else (match_dup 1)
13441 (label_ref (match_operand 0 "" ""))
13442 (pc)))]
13443 "TARGET_80387 || TARGET_SSE"
13444 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13445
13446 (define_expand "bunge"
13447 [(set (pc)
13448 (if_then_else (match_dup 1)
13449 (label_ref (match_operand 0 "" ""))
13450 (pc)))]
13451 "TARGET_80387 || TARGET_SSE"
13452 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13453
13454 (define_expand "bungt"
13455 [(set (pc)
13456 (if_then_else (match_dup 1)
13457 (label_ref (match_operand 0 "" ""))
13458 (pc)))]
13459 "TARGET_80387 || TARGET_SSE"
13460 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13461
13462 (define_expand "bunle"
13463 [(set (pc)
13464 (if_then_else (match_dup 1)
13465 (label_ref (match_operand 0 "" ""))
13466 (pc)))]
13467 "TARGET_80387 || TARGET_SSE"
13468 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13469
13470 (define_expand "bunlt"
13471 [(set (pc)
13472 (if_then_else (match_dup 1)
13473 (label_ref (match_operand 0 "" ""))
13474 (pc)))]
13475 "TARGET_80387 || TARGET_SSE"
13476 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13477
13478 (define_expand "bltgt"
13479 [(set (pc)
13480 (if_then_else (match_dup 1)
13481 (label_ref (match_operand 0 "" ""))
13482 (pc)))]
13483 "TARGET_80387 || TARGET_SSE"
13484 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13485
13486 (define_insn "*jcc_1"
13487 [(set (pc)
13488 (if_then_else (match_operator 1 "ix86_comparison_operator"
13489 [(reg 17) (const_int 0)])
13490 (label_ref (match_operand 0 "" ""))
13491 (pc)))]
13492 ""
13493 "%+j%C1\t%l0"
13494 [(set_attr "type" "ibr")
13495 (set_attr "modrm" "0")
13496 (set (attr "length")
13497 (if_then_else (and (ge (minus (match_dup 0) (pc))
13498 (const_int -126))
13499 (lt (minus (match_dup 0) (pc))
13500 (const_int 128)))
13501 (const_int 2)
13502 (const_int 6)))])
13503
13504 (define_insn "*jcc_2"
13505 [(set (pc)
13506 (if_then_else (match_operator 1 "ix86_comparison_operator"
13507 [(reg 17) (const_int 0)])
13508 (pc)
13509 (label_ref (match_operand 0 "" ""))))]
13510 ""
13511 "%+j%c1\t%l0"
13512 [(set_attr "type" "ibr")
13513 (set_attr "modrm" "0")
13514 (set (attr "length")
13515 (if_then_else (and (ge (minus (match_dup 0) (pc))
13516 (const_int -126))
13517 (lt (minus (match_dup 0) (pc))
13518 (const_int 128)))
13519 (const_int 2)
13520 (const_int 6)))])
13521
13522 ;; In general it is not safe to assume too much about CCmode registers,
13523 ;; so simplify-rtx stops when it sees a second one. Under certain
13524 ;; conditions this is safe on x86, so help combine not create
13525 ;;
13526 ;; seta %al
13527 ;; testb %al, %al
13528 ;; je Lfoo
13529
13530 (define_split
13531 [(set (pc)
13532 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13533 [(reg 17) (const_int 0)])
13534 (const_int 0))
13535 (label_ref (match_operand 1 "" ""))
13536 (pc)))]
13537 ""
13538 [(set (pc)
13539 (if_then_else (match_dup 0)
13540 (label_ref (match_dup 1))
13541 (pc)))]
13542 {
13543 PUT_MODE (operands[0], VOIDmode);
13544 })
13545
13546 (define_split
13547 [(set (pc)
13548 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13549 [(reg 17) (const_int 0)])
13550 (const_int 0))
13551 (label_ref (match_operand 1 "" ""))
13552 (pc)))]
13553 ""
13554 [(set (pc)
13555 (if_then_else (match_dup 0)
13556 (label_ref (match_dup 1))
13557 (pc)))]
13558 {
13559 rtx new_op0 = copy_rtx (operands[0]);
13560 operands[0] = new_op0;
13561 PUT_MODE (new_op0, VOIDmode);
13562 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13563 GET_MODE (XEXP (new_op0, 0))));
13564
13565 /* Make sure that (a) the CCmode we have for the flags is strong
13566 enough for the reversed compare or (b) we have a valid FP compare. */
13567 if (! ix86_comparison_operator (new_op0, VOIDmode))
13568 FAIL;
13569 })
13570
13571 ;; Define combination compare-and-branch fp compare instructions to use
13572 ;; during early optimization. Splitting the operation apart early makes
13573 ;; for bad code when we want to reverse the operation.
13574
13575 (define_insn "*fp_jcc_1"
13576 [(set (pc)
13577 (if_then_else (match_operator 0 "comparison_operator"
13578 [(match_operand 1 "register_operand" "f")
13579 (match_operand 2 "register_operand" "f")])
13580 (label_ref (match_operand 3 "" ""))
13581 (pc)))
13582 (clobber (reg:CCFP 18))
13583 (clobber (reg:CCFP 17))]
13584 "TARGET_CMOVE && TARGET_80387
13585 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13586 && FLOAT_MODE_P (GET_MODE (operands[1]))
13587 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13588 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13589 "#")
13590
13591 (define_insn "*fp_jcc_1_sse"
13592 [(set (pc)
13593 (if_then_else (match_operator 0 "comparison_operator"
13594 [(match_operand 1 "register_operand" "f#x,x#f")
13595 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13596 (label_ref (match_operand 3 "" ""))
13597 (pc)))
13598 (clobber (reg:CCFP 18))
13599 (clobber (reg:CCFP 17))]
13600 "TARGET_80387
13601 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13602 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13603 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13604 "#")
13605
13606 (define_insn "*fp_jcc_1_sse_only"
13607 [(set (pc)
13608 (if_then_else (match_operator 0 "comparison_operator"
13609 [(match_operand 1 "register_operand" "x")
13610 (match_operand 2 "nonimmediate_operand" "xm")])
13611 (label_ref (match_operand 3 "" ""))
13612 (pc)))
13613 (clobber (reg:CCFP 18))
13614 (clobber (reg:CCFP 17))]
13615 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13616 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13617 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13618 "#")
13619
13620 (define_insn "*fp_jcc_2"
13621 [(set (pc)
13622 (if_then_else (match_operator 0 "comparison_operator"
13623 [(match_operand 1 "register_operand" "f")
13624 (match_operand 2 "register_operand" "f")])
13625 (pc)
13626 (label_ref (match_operand 3 "" ""))))
13627 (clobber (reg:CCFP 18))
13628 (clobber (reg:CCFP 17))]
13629 "TARGET_CMOVE && TARGET_80387
13630 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13631 && FLOAT_MODE_P (GET_MODE (operands[1]))
13632 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13633 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13634 "#")
13635
13636 (define_insn "*fp_jcc_2_sse"
13637 [(set (pc)
13638 (if_then_else (match_operator 0 "comparison_operator"
13639 [(match_operand 1 "register_operand" "f#x,x#f")
13640 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13641 (pc)
13642 (label_ref (match_operand 3 "" ""))))
13643 (clobber (reg:CCFP 18))
13644 (clobber (reg:CCFP 17))]
13645 "TARGET_80387
13646 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13647 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13648 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13649 "#")
13650
13651 (define_insn "*fp_jcc_2_sse_only"
13652 [(set (pc)
13653 (if_then_else (match_operator 0 "comparison_operator"
13654 [(match_operand 1 "register_operand" "x")
13655 (match_operand 2 "nonimmediate_operand" "xm")])
13656 (pc)
13657 (label_ref (match_operand 3 "" ""))))
13658 (clobber (reg:CCFP 18))
13659 (clobber (reg:CCFP 17))]
13660 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13661 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13662 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13663 "#")
13664
13665 (define_insn "*fp_jcc_3"
13666 [(set (pc)
13667 (if_then_else (match_operator 0 "comparison_operator"
13668 [(match_operand 1 "register_operand" "f")
13669 (match_operand 2 "nonimmediate_operand" "fm")])
13670 (label_ref (match_operand 3 "" ""))
13671 (pc)))
13672 (clobber (reg:CCFP 18))
13673 (clobber (reg:CCFP 17))
13674 (clobber (match_scratch:HI 4 "=a"))]
13675 "TARGET_80387
13676 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13677 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13678 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13679 && SELECT_CC_MODE (GET_CODE (operands[0]),
13680 operands[1], operands[2]) == CCFPmode
13681 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13682 "#")
13683
13684 (define_insn "*fp_jcc_4"
13685 [(set (pc)
13686 (if_then_else (match_operator 0 "comparison_operator"
13687 [(match_operand 1 "register_operand" "f")
13688 (match_operand 2 "nonimmediate_operand" "fm")])
13689 (pc)
13690 (label_ref (match_operand 3 "" ""))))
13691 (clobber (reg:CCFP 18))
13692 (clobber (reg:CCFP 17))
13693 (clobber (match_scratch:HI 4 "=a"))]
13694 "TARGET_80387
13695 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13696 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13697 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13698 && SELECT_CC_MODE (GET_CODE (operands[0]),
13699 operands[1], operands[2]) == CCFPmode
13700 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13701 "#")
13702
13703 (define_insn "*fp_jcc_5"
13704 [(set (pc)
13705 (if_then_else (match_operator 0 "comparison_operator"
13706 [(match_operand 1 "register_operand" "f")
13707 (match_operand 2 "register_operand" "f")])
13708 (label_ref (match_operand 3 "" ""))
13709 (pc)))
13710 (clobber (reg:CCFP 18))
13711 (clobber (reg:CCFP 17))
13712 (clobber (match_scratch:HI 4 "=a"))]
13713 "TARGET_80387
13714 && FLOAT_MODE_P (GET_MODE (operands[1]))
13715 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13716 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13717 "#")
13718
13719 (define_insn "*fp_jcc_6"
13720 [(set (pc)
13721 (if_then_else (match_operator 0 "comparison_operator"
13722 [(match_operand 1 "register_operand" "f")
13723 (match_operand 2 "register_operand" "f")])
13724 (pc)
13725 (label_ref (match_operand 3 "" ""))))
13726 (clobber (reg:CCFP 18))
13727 (clobber (reg:CCFP 17))
13728 (clobber (match_scratch:HI 4 "=a"))]
13729 "TARGET_80387
13730 && FLOAT_MODE_P (GET_MODE (operands[1]))
13731 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13732 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13733 "#")
13734
13735 (define_split
13736 [(set (pc)
13737 (if_then_else (match_operator 0 "comparison_operator"
13738 [(match_operand 1 "register_operand" "")
13739 (match_operand 2 "nonimmediate_operand" "")])
13740 (match_operand 3 "" "")
13741 (match_operand 4 "" "")))
13742 (clobber (reg:CCFP 18))
13743 (clobber (reg:CCFP 17))]
13744 "reload_completed"
13745 [(const_int 0)]
13746 {
13747 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13748 operands[3], operands[4], NULL_RTX);
13749 DONE;
13750 })
13751
13752 (define_split
13753 [(set (pc)
13754 (if_then_else (match_operator 0 "comparison_operator"
13755 [(match_operand 1 "register_operand" "")
13756 (match_operand 2 "nonimmediate_operand" "")])
13757 (match_operand 3 "" "")
13758 (match_operand 4 "" "")))
13759 (clobber (reg:CCFP 18))
13760 (clobber (reg:CCFP 17))
13761 (clobber (match_scratch:HI 5 "=a"))]
13762 "reload_completed"
13763 [(set (pc)
13764 (if_then_else (match_dup 6)
13765 (match_dup 3)
13766 (match_dup 4)))]
13767 {
13768 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13769 operands[3], operands[4], operands[5]);
13770 DONE;
13771 })
13772 \f
13773 ;; Unconditional and other jump instructions
13774
13775 (define_insn "jump"
13776 [(set (pc)
13777 (label_ref (match_operand 0 "" "")))]
13778 ""
13779 "jmp\t%l0"
13780 [(set_attr "type" "ibr")
13781 (set (attr "length")
13782 (if_then_else (and (ge (minus (match_dup 0) (pc))
13783 (const_int -126))
13784 (lt (minus (match_dup 0) (pc))
13785 (const_int 128)))
13786 (const_int 2)
13787 (const_int 5)))
13788 (set_attr "modrm" "0")])
13789
13790 (define_expand "indirect_jump"
13791 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13792 ""
13793 "")
13794
13795 (define_insn "*indirect_jump"
13796 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13797 "!TARGET_64BIT"
13798 "jmp\t%A0"
13799 [(set_attr "type" "ibr")
13800 (set_attr "length_immediate" "0")])
13801
13802 (define_insn "*indirect_jump_rtx64"
13803 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13804 "TARGET_64BIT"
13805 "jmp\t%A0"
13806 [(set_attr "type" "ibr")
13807 (set_attr "length_immediate" "0")])
13808
13809 (define_expand "tablejump"
13810 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13811 (use (label_ref (match_operand 1 "" "")))])]
13812 ""
13813 {
13814 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13815 relative. Convert the relative address to an absolute address. */
13816 if (flag_pic)
13817 {
13818 rtx op0, op1;
13819 enum rtx_code code;
13820
13821 if (TARGET_64BIT)
13822 {
13823 code = PLUS;
13824 op0 = operands[0];
13825 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13826 }
13827 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13828 {
13829 code = PLUS;
13830 op0 = operands[0];
13831 op1 = pic_offset_table_rtx;
13832 }
13833 else
13834 {
13835 code = MINUS;
13836 op0 = pic_offset_table_rtx;
13837 op1 = operands[0];
13838 }
13839
13840 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13841 OPTAB_DIRECT);
13842 }
13843 })
13844
13845 (define_insn "*tablejump_1"
13846 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13847 (use (label_ref (match_operand 1 "" "")))]
13848 "!TARGET_64BIT"
13849 "jmp\t%A0"
13850 [(set_attr "type" "ibr")
13851 (set_attr "length_immediate" "0")])
13852
13853 (define_insn "*tablejump_1_rtx64"
13854 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13855 (use (label_ref (match_operand 1 "" "")))]
13856 "TARGET_64BIT"
13857 "jmp\t%A0"
13858 [(set_attr "type" "ibr")
13859 (set_attr "length_immediate" "0")])
13860 \f
13861 ;; Loop instruction
13862 ;;
13863 ;; This is all complicated by the fact that since this is a jump insn
13864 ;; we must handle our own reloads.
13865
13866 (define_expand "doloop_end"
13867 [(use (match_operand 0 "" "")) ; loop pseudo
13868 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13869 (use (match_operand 2 "" "")) ; max iterations
13870 (use (match_operand 3 "" "")) ; loop level
13871 (use (match_operand 4 "" ""))] ; label
13872 "!TARGET_64BIT && TARGET_USE_LOOP"
13873 "
13874 {
13875 /* Only use cloop on innermost loops. */
13876 if (INTVAL (operands[3]) > 1)
13877 FAIL;
13878 if (GET_MODE (operands[0]) != SImode)
13879 FAIL;
13880 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13881 operands[0]));
13882 DONE;
13883 }")
13884
13885 (define_insn "doloop_end_internal"
13886 [(set (pc)
13887 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13888 (const_int 1))
13889 (label_ref (match_operand 0 "" ""))
13890 (pc)))
13891 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13892 (plus:SI (match_dup 1)
13893 (const_int -1)))
13894 (clobber (match_scratch:SI 3 "=X,X,r"))
13895 (clobber (reg:CC 17))]
13896 "!TARGET_64BIT && TARGET_USE_LOOP"
13897 {
13898 if (which_alternative != 0)
13899 return "#";
13900 if (get_attr_length (insn) == 2)
13901 return "%+loop\t%l0";
13902 else
13903 return "dec{l}\t%1\;%+jne\t%l0";
13904 }
13905 [(set_attr "ppro_uops" "many")
13906 (set (attr "length")
13907 (if_then_else (and (eq_attr "alternative" "0")
13908 (and (ge (minus (match_dup 0) (pc))
13909 (const_int -126))
13910 (lt (minus (match_dup 0) (pc))
13911 (const_int 128))))
13912 (const_int 2)
13913 (const_int 16)))
13914 ;; We don't know the type before shorten branches. Optimistically expect
13915 ;; the loop instruction to match.
13916 (set (attr "type") (const_string "ibr"))])
13917
13918 (define_split
13919 [(set (pc)
13920 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13921 (const_int 1))
13922 (match_operand 0 "" "")
13923 (pc)))
13924 (set (match_dup 1)
13925 (plus:SI (match_dup 1)
13926 (const_int -1)))
13927 (clobber (match_scratch:SI 2 ""))
13928 (clobber (reg:CC 17))]
13929 "!TARGET_64BIT && TARGET_USE_LOOP
13930 && reload_completed
13931 && REGNO (operands[1]) != 2"
13932 [(parallel [(set (reg:CCZ 17)
13933 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13934 (const_int 0)))
13935 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13936 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13937 (match_dup 0)
13938 (pc)))]
13939 "")
13940
13941 (define_split
13942 [(set (pc)
13943 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13944 (const_int 1))
13945 (match_operand 0 "" "")
13946 (pc)))
13947 (set (match_operand:SI 2 "nonimmediate_operand" "")
13948 (plus:SI (match_dup 1)
13949 (const_int -1)))
13950 (clobber (match_scratch:SI 3 ""))
13951 (clobber (reg:CC 17))]
13952 "!TARGET_64BIT && TARGET_USE_LOOP
13953 && reload_completed
13954 && (! REG_P (operands[2])
13955 || ! rtx_equal_p (operands[1], operands[2]))"
13956 [(set (match_dup 3) (match_dup 1))
13957 (parallel [(set (reg:CCZ 17)
13958 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13959 (const_int 0)))
13960 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13961 (set (match_dup 2) (match_dup 3))
13962 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13963 (match_dup 0)
13964 (pc)))]
13965 "")
13966
13967 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13968
13969 (define_peephole2
13970 [(set (reg 17) (match_operand 0 "" ""))
13971 (set (match_operand:QI 1 "register_operand" "")
13972 (match_operator:QI 2 "ix86_comparison_operator"
13973 [(reg 17) (const_int 0)]))
13974 (set (match_operand 3 "q_regs_operand" "")
13975 (zero_extend (match_dup 1)))]
13976 "(peep2_reg_dead_p (3, operands[1])
13977 || operands_match_p (operands[1], operands[3]))
13978 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13979 [(set (match_dup 4) (match_dup 0))
13980 (set (strict_low_part (match_dup 5))
13981 (match_dup 2))]
13982 {
13983 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13984 operands[5] = gen_lowpart (QImode, operands[3]);
13985 ix86_expand_clear (operands[3]);
13986 })
13987
13988 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13989
13990 (define_peephole2
13991 [(set (reg 17) (match_operand 0 "" ""))
13992 (set (match_operand:QI 1 "register_operand" "")
13993 (match_operator:QI 2 "ix86_comparison_operator"
13994 [(reg 17) (const_int 0)]))
13995 (parallel [(set (match_operand 3 "q_regs_operand" "")
13996 (zero_extend (match_dup 1)))
13997 (clobber (reg:CC 17))])]
13998 "(peep2_reg_dead_p (3, operands[1])
13999 || operands_match_p (operands[1], operands[3]))
14000 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14001 [(set (match_dup 4) (match_dup 0))
14002 (set (strict_low_part (match_dup 5))
14003 (match_dup 2))]
14004 {
14005 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
14006 operands[5] = gen_lowpart (QImode, operands[3]);
14007 ix86_expand_clear (operands[3]);
14008 })
14009 \f
14010 ;; Call instructions.
14011
14012 ;; The predicates normally associated with named expanders are not properly
14013 ;; checked for calls. This is a bug in the generic code, but it isn't that
14014 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14015
14016 ;; Call subroutine returning no value.
14017
14018 (define_expand "call_pop"
14019 [(parallel [(call (match_operand:QI 0 "" "")
14020 (match_operand:SI 1 "" ""))
14021 (set (reg:SI 7)
14022 (plus:SI (reg:SI 7)
14023 (match_operand:SI 3 "" "")))])]
14024 "!TARGET_64BIT"
14025 {
14026 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14027 DONE;
14028 })
14029
14030 (define_insn "*call_pop_0"
14031 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14032 (match_operand:SI 1 "" ""))
14033 (set (reg:SI 7) (plus:SI (reg:SI 7)
14034 (match_operand:SI 2 "immediate_operand" "")))]
14035 "!TARGET_64BIT"
14036 {
14037 if (SIBLING_CALL_P (insn))
14038 return "jmp\t%P0";
14039 else
14040 return "call\t%P0";
14041 }
14042 [(set_attr "type" "call")])
14043
14044 (define_insn "*call_pop_1"
14045 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14046 (match_operand:SI 1 "" ""))
14047 (set (reg:SI 7) (plus:SI (reg:SI 7)
14048 (match_operand:SI 2 "immediate_operand" "i")))]
14049 "!TARGET_64BIT"
14050 {
14051 if (constant_call_address_operand (operands[0], Pmode))
14052 {
14053 if (SIBLING_CALL_P (insn))
14054 return "jmp\t%P0";
14055 else
14056 return "call\t%P0";
14057 }
14058 if (SIBLING_CALL_P (insn))
14059 return "jmp\t%A0";
14060 else
14061 return "call\t%A0";
14062 }
14063 [(set_attr "type" "call")])
14064
14065 (define_expand "call"
14066 [(call (match_operand:QI 0 "" "")
14067 (match_operand 1 "" ""))
14068 (use (match_operand 2 "" ""))]
14069 ""
14070 {
14071 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14072 DONE;
14073 })
14074
14075 (define_expand "sibcall"
14076 [(call (match_operand:QI 0 "" "")
14077 (match_operand 1 "" ""))
14078 (use (match_operand 2 "" ""))]
14079 ""
14080 {
14081 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14082 DONE;
14083 })
14084
14085 (define_insn "*call_0"
14086 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14087 (match_operand 1 "" ""))]
14088 ""
14089 {
14090 if (SIBLING_CALL_P (insn))
14091 return "jmp\t%P0";
14092 else
14093 return "call\t%P0";
14094 }
14095 [(set_attr "type" "call")])
14096
14097 (define_insn "*call_1"
14098 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14099 (match_operand 1 "" ""))]
14100 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14101 {
14102 if (constant_call_address_operand (operands[0], QImode))
14103 return "call\t%P0";
14104 return "call\t%A0";
14105 }
14106 [(set_attr "type" "call")])
14107
14108 (define_insn "*sibcall_1"
14109 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14110 (match_operand 1 "" ""))]
14111 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14112 {
14113 if (constant_call_address_operand (operands[0], QImode))
14114 return "jmp\t%P0";
14115 return "jmp\t%A0";
14116 }
14117 [(set_attr "type" "call")])
14118
14119 (define_insn "*call_1_rex64"
14120 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14121 (match_operand 1 "" ""))]
14122 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14123 {
14124 if (constant_call_address_operand (operands[0], QImode))
14125 return "call\t%P0";
14126 return "call\t%A0";
14127 }
14128 [(set_attr "type" "call")])
14129
14130 (define_insn "*sibcall_1_rex64"
14131 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14132 (match_operand 1 "" ""))]
14133 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14134 "jmp\t%P0"
14135 [(set_attr "type" "call")])
14136
14137 (define_insn "*sibcall_1_rex64_v"
14138 [(call (mem:QI (reg:DI 40))
14139 (match_operand 0 "" ""))]
14140 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14141 "jmp\t*%%r11"
14142 [(set_attr "type" "call")])
14143
14144
14145 ;; Call subroutine, returning value in operand 0
14146
14147 (define_expand "call_value_pop"
14148 [(parallel [(set (match_operand 0 "" "")
14149 (call (match_operand:QI 1 "" "")
14150 (match_operand:SI 2 "" "")))
14151 (set (reg:SI 7)
14152 (plus:SI (reg:SI 7)
14153 (match_operand:SI 4 "" "")))])]
14154 "!TARGET_64BIT"
14155 {
14156 ix86_expand_call (operands[0], operands[1], operands[2],
14157 operands[3], operands[4], 0);
14158 DONE;
14159 })
14160
14161 (define_expand "call_value"
14162 [(set (match_operand 0 "" "")
14163 (call (match_operand:QI 1 "" "")
14164 (match_operand:SI 2 "" "")))
14165 (use (match_operand:SI 3 "" ""))]
14166 ;; Operand 2 not used on the i386.
14167 ""
14168 {
14169 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14170 DONE;
14171 })
14172
14173 (define_expand "sibcall_value"
14174 [(set (match_operand 0 "" "")
14175 (call (match_operand:QI 1 "" "")
14176 (match_operand:SI 2 "" "")))
14177 (use (match_operand:SI 3 "" ""))]
14178 ;; Operand 2 not used on the i386.
14179 ""
14180 {
14181 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14182 DONE;
14183 })
14184
14185 ;; Call subroutine returning any type.
14186
14187 (define_expand "untyped_call"
14188 [(parallel [(call (match_operand 0 "" "")
14189 (const_int 0))
14190 (match_operand 1 "" "")
14191 (match_operand 2 "" "")])]
14192 ""
14193 {
14194 int i;
14195
14196 /* In order to give reg-stack an easier job in validating two
14197 coprocessor registers as containing a possible return value,
14198 simply pretend the untyped call returns a complex long double
14199 value. */
14200
14201 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14202 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14203 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14204 NULL, 0);
14205
14206 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14207 {
14208 rtx set = XVECEXP (operands[2], 0, i);
14209 emit_move_insn (SET_DEST (set), SET_SRC (set));
14210 }
14211
14212 /* The optimizer does not know that the call sets the function value
14213 registers we stored in the result block. We avoid problems by
14214 claiming that all hard registers are used and clobbered at this
14215 point. */
14216 emit_insn (gen_blockage (const0_rtx));
14217
14218 DONE;
14219 })
14220 \f
14221 ;; Prologue and epilogue instructions
14222
14223 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14224 ;; all of memory. This blocks insns from being moved across this point.
14225
14226 (define_insn "blockage"
14227 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14228 ""
14229 ""
14230 [(set_attr "length" "0")])
14231
14232 ;; Insn emitted into the body of a function to return from a function.
14233 ;; This is only done if the function's epilogue is known to be simple.
14234 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14235
14236 (define_expand "return"
14237 [(return)]
14238 "ix86_can_use_return_insn_p ()"
14239 {
14240 if (current_function_pops_args)
14241 {
14242 rtx popc = GEN_INT (current_function_pops_args);
14243 emit_jump_insn (gen_return_pop_internal (popc));
14244 DONE;
14245 }
14246 })
14247
14248 (define_insn "return_internal"
14249 [(return)]
14250 "reload_completed"
14251 "ret"
14252 [(set_attr "length" "1")
14253 (set_attr "length_immediate" "0")
14254 (set_attr "modrm" "0")])
14255
14256 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14257 ;; instruction Athlon and K8 have.
14258
14259 (define_insn "return_internal_long"
14260 [(return)
14261 (unspec [(const_int 0)] UNSPEC_REP)]
14262 "reload_completed"
14263 "rep {;} ret"
14264 [(set_attr "length" "1")
14265 (set_attr "length_immediate" "0")
14266 (set_attr "prefix_rep" "1")
14267 (set_attr "modrm" "0")])
14268
14269 (define_insn "return_pop_internal"
14270 [(return)
14271 (use (match_operand:SI 0 "const_int_operand" ""))]
14272 "reload_completed"
14273 "ret\t%0"
14274 [(set_attr "length" "3")
14275 (set_attr "length_immediate" "2")
14276 (set_attr "modrm" "0")])
14277
14278 (define_insn "return_indirect_internal"
14279 [(return)
14280 (use (match_operand:SI 0 "register_operand" "r"))]
14281 "reload_completed"
14282 "jmp\t%A0"
14283 [(set_attr "type" "ibr")
14284 (set_attr "length_immediate" "0")])
14285
14286 (define_insn "nop"
14287 [(const_int 0)]
14288 ""
14289 "nop"
14290 [(set_attr "length" "1")
14291 (set_attr "length_immediate" "0")
14292 (set_attr "modrm" "0")
14293 (set_attr "ppro_uops" "one")])
14294
14295 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14296 ;; branch prediction penalty for the third jump in a 16-byte
14297 ;; block on K8.
14298
14299 (define_insn "align"
14300 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14301 ""
14302 {
14303 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14304 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14305 #else
14306 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14307 The align insn is used to avoid 3 jump instructions in the row to improve
14308 branch prediction and the benefits hardly outweight the cost of extra 8
14309 nops on the average inserted by full alignment pseudo operation. */
14310 #endif
14311 return "";
14312 }
14313 [(set_attr "length" "16")])
14314
14315 (define_expand "prologue"
14316 [(const_int 1)]
14317 ""
14318 "ix86_expand_prologue (); DONE;")
14319
14320 (define_insn "set_got"
14321 [(set (match_operand:SI 0 "register_operand" "=r")
14322 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14323 (clobber (reg:CC 17))]
14324 "!TARGET_64BIT"
14325 { return output_set_got (operands[0]); }
14326 [(set_attr "type" "multi")
14327 (set_attr "length" "12")])
14328
14329 (define_expand "epilogue"
14330 [(const_int 1)]
14331 ""
14332 "ix86_expand_epilogue (1); DONE;")
14333
14334 (define_expand "sibcall_epilogue"
14335 [(const_int 1)]
14336 ""
14337 "ix86_expand_epilogue (0); DONE;")
14338
14339 (define_expand "eh_return"
14340 [(use (match_operand 0 "register_operand" ""))]
14341 ""
14342 {
14343 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14344
14345 /* Tricky bit: we write the address of the handler to which we will
14346 be returning into someone else's stack frame, one word below the
14347 stack address we wish to restore. */
14348 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14349 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14350 tmp = gen_rtx_MEM (Pmode, tmp);
14351 emit_move_insn (tmp, ra);
14352
14353 if (Pmode == SImode)
14354 emit_insn (gen_eh_return_si (sa));
14355 else
14356 emit_insn (gen_eh_return_di (sa));
14357 emit_barrier ();
14358 DONE;
14359 })
14360
14361 (define_insn_and_split "eh_return_si"
14362 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
14363 UNSPECV_EH_RETURN)]
14364 "!TARGET_64BIT"
14365 "#"
14366 "reload_completed"
14367 [(const_int 1)]
14368 "ix86_expand_epilogue (2); DONE;")
14369
14370 (define_insn_and_split "eh_return_di"
14371 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14372 UNSPECV_EH_RETURN)]
14373 "TARGET_64BIT"
14374 "#"
14375 "reload_completed"
14376 [(const_int 1)]
14377 "ix86_expand_epilogue (2); DONE;")
14378
14379 (define_insn "leave"
14380 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14381 (set (reg:SI 6) (mem:SI (reg:SI 6)))
14382 (clobber (mem:BLK (scratch)))]
14383 "!TARGET_64BIT"
14384 "leave"
14385 [(set_attr "type" "leave")])
14386
14387 (define_insn "leave_rex64"
14388 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14389 (set (reg:DI 6) (mem:DI (reg:DI 6)))
14390 (clobber (mem:BLK (scratch)))]
14391 "TARGET_64BIT"
14392 "leave"
14393 [(set_attr "type" "leave")])
14394 \f
14395 (define_expand "ffssi2"
14396 [(parallel
14397 [(set (match_operand:SI 0 "register_operand" "")
14398 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14399 (clobber (match_scratch:SI 2 ""))
14400 (clobber (reg:CC 17))])]
14401 ""
14402 "")
14403
14404 (define_insn_and_split "*ffs_cmove"
14405 [(set (match_operand:SI 0 "register_operand" "=r")
14406 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14407 (clobber (match_scratch:SI 2 "=&r"))
14408 (clobber (reg:CC 17))]
14409 "TARGET_CMOVE"
14410 "#"
14411 "&& reload_completed"
14412 [(set (match_dup 2) (const_int -1))
14413 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14414 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14415 (set (match_dup 0) (if_then_else:SI
14416 (eq (reg:CCZ 17) (const_int 0))
14417 (match_dup 2)
14418 (match_dup 0)))
14419 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14420 (clobber (reg:CC 17))])]
14421 "")
14422
14423 (define_insn_and_split "*ffs_no_cmove"
14424 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14425 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14426 (clobber (match_scratch:SI 2 "=&r"))
14427 (clobber (reg:CC 17))]
14428 ""
14429 "#"
14430 "reload_completed"
14431 [(parallel [(set (match_dup 2) (const_int 0))
14432 (clobber (reg:CC 17))])
14433 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14434 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14435 (set (strict_low_part (match_dup 3))
14436 (eq:QI (reg:CCZ 17) (const_int 0)))
14437 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14438 (clobber (reg:CC 17))])
14439 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14440 (clobber (reg:CC 17))])
14441 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14442 (clobber (reg:CC 17))])]
14443 {
14444 operands[3] = gen_lowpart (QImode, operands[2]);
14445 })
14446
14447 (define_insn "*ffssi_1"
14448 [(set (reg:CCZ 17)
14449 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14450 (const_int 0)))
14451 (set (match_operand:SI 0 "register_operand" "=r")
14452 (ctz:SI (match_dup 1)))]
14453 ""
14454 "bsf{l}\t{%1, %0|%0, %1}"
14455 [(set_attr "prefix_0f" "1")
14456 (set_attr "ppro_uops" "few")])
14457
14458 (define_insn "ctzsi2"
14459 [(set (match_operand:SI 0 "register_operand" "=r")
14460 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14461 (clobber (reg:CC 17))]
14462 ""
14463 "bsf{l}\t{%1, %0|%0, %1}"
14464 [(set_attr "prefix_0f" "1")
14465 (set_attr "ppro_uops" "few")])
14466
14467 (define_expand "clzsi2"
14468 [(parallel
14469 [(set (match_operand:SI 0 "register_operand" "")
14470 (minus:SI (const_int 31)
14471 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14472 (clobber (reg:CC 17))])
14473 (parallel
14474 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14475 (clobber (reg:CC 17))])]
14476 ""
14477 "")
14478
14479 (define_insn "*bsr"
14480 [(set (match_operand:SI 0 "register_operand" "=r")
14481 (minus:SI (const_int 31)
14482 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14483 (clobber (reg:CC 17))]
14484 ""
14485 "bsr{l}\t{%1, %0|%0, %1}"
14486 [(set_attr "prefix_0f" "1")
14487 (set_attr "ppro_uops" "few")])
14488 \f
14489 ;; Thread-local storage patterns for ELF.
14490 ;;
14491 ;; Note that these code sequences must appear exactly as shown
14492 ;; in order to allow linker relaxation.
14493
14494 (define_insn "*tls_global_dynamic_32_gnu"
14495 [(set (match_operand:SI 0 "register_operand" "=a")
14496 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14497 (match_operand:SI 2 "tls_symbolic_operand" "")
14498 (match_operand:SI 3 "call_insn_operand" "")]
14499 UNSPEC_TLS_GD))
14500 (clobber (match_scratch:SI 4 "=d"))
14501 (clobber (match_scratch:SI 5 "=c"))
14502 (clobber (reg:CC 17))]
14503 "!TARGET_64BIT && TARGET_GNU_TLS"
14504 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14505 [(set_attr "type" "multi")
14506 (set_attr "length" "12")])
14507
14508 (define_insn "*tls_global_dynamic_32_sun"
14509 [(set (match_operand:SI 0 "register_operand" "=a")
14510 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14511 (match_operand:SI 2 "tls_symbolic_operand" "")
14512 (match_operand:SI 3 "call_insn_operand" "")]
14513 UNSPEC_TLS_GD))
14514 (clobber (match_scratch:SI 4 "=d"))
14515 (clobber (match_scratch:SI 5 "=c"))
14516 (clobber (reg:CC 17))]
14517 "!TARGET_64BIT && TARGET_SUN_TLS"
14518 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14519 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14520 [(set_attr "type" "multi")
14521 (set_attr "length" "14")])
14522
14523 (define_expand "tls_global_dynamic_32"
14524 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14525 (unspec:SI
14526 [(match_dup 2)
14527 (match_operand:SI 1 "tls_symbolic_operand" "")
14528 (match_dup 3)]
14529 UNSPEC_TLS_GD))
14530 (clobber (match_scratch:SI 4 ""))
14531 (clobber (match_scratch:SI 5 ""))
14532 (clobber (reg:CC 17))])]
14533 ""
14534 {
14535 if (flag_pic)
14536 operands[2] = pic_offset_table_rtx;
14537 else
14538 {
14539 operands[2] = gen_reg_rtx (Pmode);
14540 emit_insn (gen_set_got (operands[2]));
14541 }
14542 operands[3] = ix86_tls_get_addr ();
14543 })
14544
14545 (define_insn "*tls_global_dynamic_64"
14546 [(set (match_operand:DI 0 "register_operand" "=a")
14547 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14548 (match_operand:DI 3 "" "")))
14549 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14550 UNSPEC_TLS_GD)]
14551 "TARGET_64BIT"
14552 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14553 [(set_attr "type" "multi")
14554 (set_attr "length" "16")])
14555
14556 (define_expand "tls_global_dynamic_64"
14557 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14558 (call (mem:QI (match_dup 2)) (const_int 0)))
14559 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14560 UNSPEC_TLS_GD)])]
14561 ""
14562 {
14563 operands[2] = ix86_tls_get_addr ();
14564 })
14565
14566 (define_insn "*tls_local_dynamic_base_32_gnu"
14567 [(set (match_operand:SI 0 "register_operand" "=a")
14568 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14569 (match_operand:SI 2 "call_insn_operand" "")]
14570 UNSPEC_TLS_LD_BASE))
14571 (clobber (match_scratch:SI 3 "=d"))
14572 (clobber (match_scratch:SI 4 "=c"))
14573 (clobber (reg:CC 17))]
14574 "!TARGET_64BIT && TARGET_GNU_TLS"
14575 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14576 [(set_attr "type" "multi")
14577 (set_attr "length" "11")])
14578
14579 (define_insn "*tls_local_dynamic_base_32_sun"
14580 [(set (match_operand:SI 0 "register_operand" "=a")
14581 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14582 (match_operand:SI 2 "call_insn_operand" "")]
14583 UNSPEC_TLS_LD_BASE))
14584 (clobber (match_scratch:SI 3 "=d"))
14585 (clobber (match_scratch:SI 4 "=c"))
14586 (clobber (reg:CC 17))]
14587 "!TARGET_64BIT && TARGET_SUN_TLS"
14588 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14589 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14590 [(set_attr "type" "multi")
14591 (set_attr "length" "13")])
14592
14593 (define_expand "tls_local_dynamic_base_32"
14594 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14595 (unspec:SI [(match_dup 1) (match_dup 2)]
14596 UNSPEC_TLS_LD_BASE))
14597 (clobber (match_scratch:SI 3 ""))
14598 (clobber (match_scratch:SI 4 ""))
14599 (clobber (reg:CC 17))])]
14600 ""
14601 {
14602 if (flag_pic)
14603 operands[1] = pic_offset_table_rtx;
14604 else
14605 {
14606 operands[1] = gen_reg_rtx (Pmode);
14607 emit_insn (gen_set_got (operands[1]));
14608 }
14609 operands[2] = ix86_tls_get_addr ();
14610 })
14611
14612 (define_insn "*tls_local_dynamic_base_64"
14613 [(set (match_operand:DI 0 "register_operand" "=a")
14614 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14615 (match_operand:DI 2 "" "")))
14616 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14617 "TARGET_64BIT"
14618 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14619 [(set_attr "type" "multi")
14620 (set_attr "length" "12")])
14621
14622 (define_expand "tls_local_dynamic_base_64"
14623 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14624 (call (mem:QI (match_dup 1)) (const_int 0)))
14625 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14626 ""
14627 {
14628 operands[1] = ix86_tls_get_addr ();
14629 })
14630
14631 ;; Local dynamic of a single variable is a lose. Show combine how
14632 ;; to convert that back to global dynamic.
14633
14634 (define_insn_and_split "*tls_local_dynamic_32_once"
14635 [(set (match_operand:SI 0 "register_operand" "=a")
14636 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14637 (match_operand:SI 2 "call_insn_operand" "")]
14638 UNSPEC_TLS_LD_BASE)
14639 (const:SI (unspec:SI
14640 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14641 UNSPEC_DTPOFF))))
14642 (clobber (match_scratch:SI 4 "=d"))
14643 (clobber (match_scratch:SI 5 "=c"))
14644 (clobber (reg:CC 17))]
14645 ""
14646 "#"
14647 ""
14648 [(parallel [(set (match_dup 0)
14649 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14650 UNSPEC_TLS_GD))
14651 (clobber (match_dup 4))
14652 (clobber (match_dup 5))
14653 (clobber (reg:CC 17))])]
14654 "")
14655
14656 ;; Load and add the thread base pointer from %gs:0.
14657
14658 (define_insn "*load_tp_si"
14659 [(set (match_operand:SI 0 "register_operand" "=r")
14660 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14661 "!TARGET_64BIT"
14662 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14663 [(set_attr "type" "imov")
14664 (set_attr "modrm" "0")
14665 (set_attr "length" "7")
14666 (set_attr "memory" "load")
14667 (set_attr "imm_disp" "false")])
14668
14669 (define_insn "*add_tp_si"
14670 [(set (match_operand:SI 0 "register_operand" "=r")
14671 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14672 (match_operand:SI 1 "register_operand" "0")))
14673 (clobber (reg:CC 17))]
14674 "!TARGET_64BIT"
14675 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14676 [(set_attr "type" "alu")
14677 (set_attr "modrm" "0")
14678 (set_attr "length" "7")
14679 (set_attr "memory" "load")
14680 (set_attr "imm_disp" "false")])
14681
14682 (define_insn "*load_tp_di"
14683 [(set (match_operand:DI 0 "register_operand" "=r")
14684 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14685 "TARGET_64BIT"
14686 "mov{l}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14687 [(set_attr "type" "imov")
14688 (set_attr "modrm" "0")
14689 (set_attr "length" "7")
14690 (set_attr "memory" "load")
14691 (set_attr "imm_disp" "false")])
14692
14693 (define_insn "*add_tp_di"
14694 [(set (match_operand:DI 0 "register_operand" "=r")
14695 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14696 (match_operand:DI 1 "register_operand" "0")))
14697 (clobber (reg:CC 17))]
14698 "TARGET_64BIT"
14699 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14700 [(set_attr "type" "alu")
14701 (set_attr "modrm" "0")
14702 (set_attr "length" "7")
14703 (set_attr "memory" "load")
14704 (set_attr "imm_disp" "false")])
14705 \f
14706 ;; These patterns match the binary 387 instructions for addM3, subM3,
14707 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14708 ;; SFmode. The first is the normal insn, the second the same insn but
14709 ;; with one operand a conversion, and the third the same insn but with
14710 ;; the other operand a conversion. The conversion may be SFmode or
14711 ;; SImode if the target mode DFmode, but only SImode if the target mode
14712 ;; is SFmode.
14713
14714 ;; Gcc is slightly more smart about handling normal two address instructions
14715 ;; so use special patterns for add and mull.
14716 (define_insn "*fop_sf_comm_nosse"
14717 [(set (match_operand:SF 0 "register_operand" "=f")
14718 (match_operator:SF 3 "binary_fp_operator"
14719 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14720 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14721 "TARGET_80387 && !TARGET_SSE_MATH
14722 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14723 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14724 "* return output_387_binary_op (insn, operands);"
14725 [(set (attr "type")
14726 (if_then_else (match_operand:SF 3 "mult_operator" "")
14727 (const_string "fmul")
14728 (const_string "fop")))
14729 (set_attr "mode" "SF")])
14730
14731 (define_insn "*fop_sf_comm"
14732 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14733 (match_operator:SF 3 "binary_fp_operator"
14734 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14735 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14736 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14737 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14738 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14739 "* return output_387_binary_op (insn, operands);"
14740 [(set (attr "type")
14741 (if_then_else (eq_attr "alternative" "1")
14742 (if_then_else (match_operand:SF 3 "mult_operator" "")
14743 (const_string "ssemul")
14744 (const_string "sseadd"))
14745 (if_then_else (match_operand:SF 3 "mult_operator" "")
14746 (const_string "fmul")
14747 (const_string "fop"))))
14748 (set_attr "mode" "SF")])
14749
14750 (define_insn "*fop_sf_comm_sse"
14751 [(set (match_operand:SF 0 "register_operand" "=x")
14752 (match_operator:SF 3 "binary_fp_operator"
14753 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14754 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14755 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14756 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14757 "* return output_387_binary_op (insn, operands);"
14758 [(set (attr "type")
14759 (if_then_else (match_operand:SF 3 "mult_operator" "")
14760 (const_string "ssemul")
14761 (const_string "sseadd")))
14762 (set_attr "mode" "SF")])
14763
14764 (define_insn "*fop_df_comm_nosse"
14765 [(set (match_operand:DF 0 "register_operand" "=f")
14766 (match_operator:DF 3 "binary_fp_operator"
14767 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14768 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14769 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14770 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14771 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14772 "* return output_387_binary_op (insn, operands);"
14773 [(set (attr "type")
14774 (if_then_else (match_operand:SF 3 "mult_operator" "")
14775 (const_string "fmul")
14776 (const_string "fop")))
14777 (set_attr "mode" "DF")])
14778
14779 (define_insn "*fop_df_comm"
14780 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14781 (match_operator:DF 3 "binary_fp_operator"
14782 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14783 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14784 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14785 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14786 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14787 "* return output_387_binary_op (insn, operands);"
14788 [(set (attr "type")
14789 (if_then_else (eq_attr "alternative" "1")
14790 (if_then_else (match_operand:SF 3 "mult_operator" "")
14791 (const_string "ssemul")
14792 (const_string "sseadd"))
14793 (if_then_else (match_operand:SF 3 "mult_operator" "")
14794 (const_string "fmul")
14795 (const_string "fop"))))
14796 (set_attr "mode" "DF")])
14797
14798 (define_insn "*fop_df_comm_sse"
14799 [(set (match_operand:DF 0 "register_operand" "=Y")
14800 (match_operator:DF 3 "binary_fp_operator"
14801 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14802 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14803 "TARGET_SSE2 && TARGET_SSE_MATH
14804 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14805 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14806 "* return output_387_binary_op (insn, operands);"
14807 [(set (attr "type")
14808 (if_then_else (match_operand:SF 3 "mult_operator" "")
14809 (const_string "ssemul")
14810 (const_string "sseadd")))
14811 (set_attr "mode" "DF")])
14812
14813 (define_insn "*fop_xf_comm"
14814 [(set (match_operand:XF 0 "register_operand" "=f")
14815 (match_operator:XF 3 "binary_fp_operator"
14816 [(match_operand:XF 1 "register_operand" "%0")
14817 (match_operand:XF 2 "register_operand" "f")]))]
14818 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
14819 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14820 "* return output_387_binary_op (insn, operands);"
14821 [(set (attr "type")
14822 (if_then_else (match_operand:XF 3 "mult_operator" "")
14823 (const_string "fmul")
14824 (const_string "fop")))
14825 (set_attr "mode" "XF")])
14826
14827 (define_insn "*fop_tf_comm"
14828 [(set (match_operand:TF 0 "register_operand" "=f")
14829 (match_operator:TF 3 "binary_fp_operator"
14830 [(match_operand:TF 1 "register_operand" "%0")
14831 (match_operand:TF 2 "register_operand" "f")]))]
14832 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14833 "* return output_387_binary_op (insn, operands);"
14834 [(set (attr "type")
14835 (if_then_else (match_operand:TF 3 "mult_operator" "")
14836 (const_string "fmul")
14837 (const_string "fop")))
14838 (set_attr "mode" "XF")])
14839
14840 (define_insn "*fop_sf_1_nosse"
14841 [(set (match_operand:SF 0 "register_operand" "=f,f")
14842 (match_operator:SF 3 "binary_fp_operator"
14843 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14844 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14845 "TARGET_80387 && !TARGET_SSE_MATH
14846 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14847 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14848 "* return output_387_binary_op (insn, operands);"
14849 [(set (attr "type")
14850 (cond [(match_operand:SF 3 "mult_operator" "")
14851 (const_string "fmul")
14852 (match_operand:SF 3 "div_operator" "")
14853 (const_string "fdiv")
14854 ]
14855 (const_string "fop")))
14856 (set_attr "mode" "SF")])
14857
14858 (define_insn "*fop_sf_1"
14859 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14860 (match_operator:SF 3 "binary_fp_operator"
14861 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14862 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14863 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14864 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14865 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14866 "* return output_387_binary_op (insn, operands);"
14867 [(set (attr "type")
14868 (cond [(and (eq_attr "alternative" "2")
14869 (match_operand:SF 3 "mult_operator" ""))
14870 (const_string "ssemul")
14871 (and (eq_attr "alternative" "2")
14872 (match_operand:SF 3 "div_operator" ""))
14873 (const_string "ssediv")
14874 (eq_attr "alternative" "2")
14875 (const_string "sseadd")
14876 (match_operand:SF 3 "mult_operator" "")
14877 (const_string "fmul")
14878 (match_operand:SF 3 "div_operator" "")
14879 (const_string "fdiv")
14880 ]
14881 (const_string "fop")))
14882 (set_attr "mode" "SF")])
14883
14884 (define_insn "*fop_sf_1_sse"
14885 [(set (match_operand:SF 0 "register_operand" "=x")
14886 (match_operator:SF 3 "binary_fp_operator"
14887 [(match_operand:SF 1 "register_operand" "0")
14888 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14889 "TARGET_SSE_MATH
14890 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14891 "* return output_387_binary_op (insn, operands);"
14892 [(set (attr "type")
14893 (cond [(match_operand:SF 3 "mult_operator" "")
14894 (const_string "ssemul")
14895 (match_operand:SF 3 "div_operator" "")
14896 (const_string "ssediv")
14897 ]
14898 (const_string "sseadd")))
14899 (set_attr "mode" "SF")])
14900
14901 ;; ??? Add SSE splitters for these!
14902 (define_insn "*fop_sf_2"
14903 [(set (match_operand:SF 0 "register_operand" "=f,f")
14904 (match_operator:SF 3 "binary_fp_operator"
14905 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14906 (match_operand:SF 2 "register_operand" "0,0")]))]
14907 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14908 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14909 [(set (attr "type")
14910 (cond [(match_operand:SF 3 "mult_operator" "")
14911 (const_string "fmul")
14912 (match_operand:SF 3 "div_operator" "")
14913 (const_string "fdiv")
14914 ]
14915 (const_string "fop")))
14916 (set_attr "fp_int_src" "true")
14917 (set_attr "ppro_uops" "many")
14918 (set_attr "mode" "SI")])
14919
14920 (define_insn "*fop_sf_3"
14921 [(set (match_operand:SF 0 "register_operand" "=f,f")
14922 (match_operator:SF 3 "binary_fp_operator"
14923 [(match_operand:SF 1 "register_operand" "0,0")
14924 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14925 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14926 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14927 [(set (attr "type")
14928 (cond [(match_operand:SF 3 "mult_operator" "")
14929 (const_string "fmul")
14930 (match_operand:SF 3 "div_operator" "")
14931 (const_string "fdiv")
14932 ]
14933 (const_string "fop")))
14934 (set_attr "fp_int_src" "true")
14935 (set_attr "ppro_uops" "many")
14936 (set_attr "mode" "SI")])
14937
14938 (define_insn "*fop_df_1_nosse"
14939 [(set (match_operand:DF 0 "register_operand" "=f,f")
14940 (match_operator:DF 3 "binary_fp_operator"
14941 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14942 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14943 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14944 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14945 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14946 "* return output_387_binary_op (insn, operands);"
14947 [(set (attr "type")
14948 (cond [(match_operand:DF 3 "mult_operator" "")
14949 (const_string "fmul")
14950 (match_operand:DF 3 "div_operator" "")
14951 (const_string "fdiv")
14952 ]
14953 (const_string "fop")))
14954 (set_attr "mode" "DF")])
14955
14956
14957 (define_insn "*fop_df_1"
14958 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14959 (match_operator:DF 3 "binary_fp_operator"
14960 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14961 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14962 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14963 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14964 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14965 "* return output_387_binary_op (insn, operands);"
14966 [(set (attr "type")
14967 (cond [(and (eq_attr "alternative" "2")
14968 (match_operand:SF 3 "mult_operator" ""))
14969 (const_string "ssemul")
14970 (and (eq_attr "alternative" "2")
14971 (match_operand:SF 3 "div_operator" ""))
14972 (const_string "ssediv")
14973 (eq_attr "alternative" "2")
14974 (const_string "sseadd")
14975 (match_operand:DF 3 "mult_operator" "")
14976 (const_string "fmul")
14977 (match_operand:DF 3 "div_operator" "")
14978 (const_string "fdiv")
14979 ]
14980 (const_string "fop")))
14981 (set_attr "mode" "DF")])
14982
14983 (define_insn "*fop_df_1_sse"
14984 [(set (match_operand:DF 0 "register_operand" "=Y")
14985 (match_operator:DF 3 "binary_fp_operator"
14986 [(match_operand:DF 1 "register_operand" "0")
14987 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14988 "TARGET_SSE2 && TARGET_SSE_MATH
14989 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14990 "* return output_387_binary_op (insn, operands);"
14991 [(set_attr "mode" "DF")
14992 (set (attr "type")
14993 (cond [(match_operand:SF 3 "mult_operator" "")
14994 (const_string "ssemul")
14995 (match_operand:SF 3 "div_operator" "")
14996 (const_string "ssediv")
14997 ]
14998 (const_string "sseadd")))])
14999
15000 ;; ??? Add SSE splitters for these!
15001 (define_insn "*fop_df_2"
15002 [(set (match_operand:DF 0 "register_operand" "=f,f")
15003 (match_operator:DF 3 "binary_fp_operator"
15004 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15005 (match_operand:DF 2 "register_operand" "0,0")]))]
15006 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15007 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15008 [(set (attr "type")
15009 (cond [(match_operand:DF 3 "mult_operator" "")
15010 (const_string "fmul")
15011 (match_operand:DF 3 "div_operator" "")
15012 (const_string "fdiv")
15013 ]
15014 (const_string "fop")))
15015 (set_attr "fp_int_src" "true")
15016 (set_attr "ppro_uops" "many")
15017 (set_attr "mode" "SI")])
15018
15019 (define_insn "*fop_df_3"
15020 [(set (match_operand:DF 0 "register_operand" "=f,f")
15021 (match_operator:DF 3 "binary_fp_operator"
15022 [(match_operand:DF 1 "register_operand" "0,0")
15023 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15024 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15025 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15026 [(set (attr "type")
15027 (cond [(match_operand:DF 3 "mult_operator" "")
15028 (const_string "fmul")
15029 (match_operand:DF 3 "div_operator" "")
15030 (const_string "fdiv")
15031 ]
15032 (const_string "fop")))
15033 (set_attr "fp_int_src" "true")
15034 (set_attr "ppro_uops" "many")
15035 (set_attr "mode" "SI")])
15036
15037 (define_insn "*fop_df_4"
15038 [(set (match_operand:DF 0 "register_operand" "=f,f")
15039 (match_operator:DF 3 "binary_fp_operator"
15040 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15041 (match_operand:DF 2 "register_operand" "0,f")]))]
15042 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
15043 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15044 "* return output_387_binary_op (insn, operands);"
15045 [(set (attr "type")
15046 (cond [(match_operand:DF 3 "mult_operator" "")
15047 (const_string "fmul")
15048 (match_operand:DF 3 "div_operator" "")
15049 (const_string "fdiv")
15050 ]
15051 (const_string "fop")))
15052 (set_attr "mode" "SF")])
15053
15054 (define_insn "*fop_df_5"
15055 [(set (match_operand:DF 0 "register_operand" "=f,f")
15056 (match_operator:DF 3 "binary_fp_operator"
15057 [(match_operand:DF 1 "register_operand" "0,f")
15058 (float_extend:DF
15059 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15060 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15061 "* return output_387_binary_op (insn, operands);"
15062 [(set (attr "type")
15063 (cond [(match_operand:DF 3 "mult_operator" "")
15064 (const_string "fmul")
15065 (match_operand:DF 3 "div_operator" "")
15066 (const_string "fdiv")
15067 ]
15068 (const_string "fop")))
15069 (set_attr "mode" "SF")])
15070
15071 (define_insn "*fop_df_6"
15072 [(set (match_operand:DF 0 "register_operand" "=f,f")
15073 (match_operator:DF 3 "binary_fp_operator"
15074 [(float_extend:DF
15075 (match_operand:SF 1 "register_operand" "0,f"))
15076 (float_extend:DF
15077 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15078 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15079 "* return output_387_binary_op (insn, operands);"
15080 [(set (attr "type")
15081 (cond [(match_operand:DF 3 "mult_operator" "")
15082 (const_string "fmul")
15083 (match_operand:DF 3 "div_operator" "")
15084 (const_string "fdiv")
15085 ]
15086 (const_string "fop")))
15087 (set_attr "mode" "SF")])
15088
15089 (define_insn "*fop_xf_1"
15090 [(set (match_operand:XF 0 "register_operand" "=f,f")
15091 (match_operator:XF 3 "binary_fp_operator"
15092 [(match_operand:XF 1 "register_operand" "0,f")
15093 (match_operand:XF 2 "register_operand" "f,0")]))]
15094 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
15095 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15096 "* return output_387_binary_op (insn, operands);"
15097 [(set (attr "type")
15098 (cond [(match_operand:XF 3 "mult_operator" "")
15099 (const_string "fmul")
15100 (match_operand:XF 3 "div_operator" "")
15101 (const_string "fdiv")
15102 ]
15103 (const_string "fop")))
15104 (set_attr "mode" "XF")])
15105
15106 (define_insn "*fop_tf_1"
15107 [(set (match_operand:TF 0 "register_operand" "=f,f")
15108 (match_operator:TF 3 "binary_fp_operator"
15109 [(match_operand:TF 1 "register_operand" "0,f")
15110 (match_operand:TF 2 "register_operand" "f,0")]))]
15111 "TARGET_80387
15112 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15113 "* return output_387_binary_op (insn, operands);"
15114 [(set (attr "type")
15115 (cond [(match_operand:TF 3 "mult_operator" "")
15116 (const_string "fmul")
15117 (match_operand:TF 3 "div_operator" "")
15118 (const_string "fdiv")
15119 ]
15120 (const_string "fop")))
15121 (set_attr "mode" "XF")])
15122
15123 (define_insn "*fop_xf_2"
15124 [(set (match_operand:XF 0 "register_operand" "=f,f")
15125 (match_operator:XF 3 "binary_fp_operator"
15126 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15127 (match_operand:XF 2 "register_operand" "0,0")]))]
15128 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15129 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15130 [(set (attr "type")
15131 (cond [(match_operand:XF 3 "mult_operator" "")
15132 (const_string "fmul")
15133 (match_operand:XF 3 "div_operator" "")
15134 (const_string "fdiv")
15135 ]
15136 (const_string "fop")))
15137 (set_attr "fp_int_src" "true")
15138 (set_attr "mode" "SI")
15139 (set_attr "ppro_uops" "many")])
15140
15141 (define_insn "*fop_tf_2"
15142 [(set (match_operand:TF 0 "register_operand" "=f,f")
15143 (match_operator:TF 3 "binary_fp_operator"
15144 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15145 (match_operand:TF 2 "register_operand" "0,0")]))]
15146 "TARGET_80387 && TARGET_USE_FIOP"
15147 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15148 [(set (attr "type")
15149 (cond [(match_operand:TF 3 "mult_operator" "")
15150 (const_string "fmul")
15151 (match_operand:TF 3 "div_operator" "")
15152 (const_string "fdiv")
15153 ]
15154 (const_string "fop")))
15155 (set_attr "fp_int_src" "true")
15156 (set_attr "mode" "SI")
15157 (set_attr "ppro_uops" "many")])
15158
15159 (define_insn "*fop_xf_3"
15160 [(set (match_operand:XF 0 "register_operand" "=f,f")
15161 (match_operator:XF 3 "binary_fp_operator"
15162 [(match_operand:XF 1 "register_operand" "0,0")
15163 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15164 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15165 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15166 [(set (attr "type")
15167 (cond [(match_operand:XF 3 "mult_operator" "")
15168 (const_string "fmul")
15169 (match_operand:XF 3 "div_operator" "")
15170 (const_string "fdiv")
15171 ]
15172 (const_string "fop")))
15173 (set_attr "fp_int_src" "true")
15174 (set_attr "mode" "SI")
15175 (set_attr "ppro_uops" "many")])
15176
15177 (define_insn "*fop_tf_3"
15178 [(set (match_operand:TF 0 "register_operand" "=f,f")
15179 (match_operator:TF 3 "binary_fp_operator"
15180 [(match_operand:TF 1 "register_operand" "0,0")
15181 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15182 "TARGET_80387 && TARGET_USE_FIOP"
15183 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15184 [(set (attr "type")
15185 (cond [(match_operand:TF 3 "mult_operator" "")
15186 (const_string "fmul")
15187 (match_operand:TF 3 "div_operator" "")
15188 (const_string "fdiv")
15189 ]
15190 (const_string "fop")))
15191 (set_attr "fp_int_src" "true")
15192 (set_attr "mode" "SI")
15193 (set_attr "ppro_uops" "many")])
15194
15195 (define_insn "*fop_xf_4"
15196 [(set (match_operand:XF 0 "register_operand" "=f,f")
15197 (match_operator:XF 3 "binary_fp_operator"
15198 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15199 (match_operand:XF 2 "register_operand" "0,f")]))]
15200 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15201 "* return output_387_binary_op (insn, operands);"
15202 [(set (attr "type")
15203 (cond [(match_operand:XF 3 "mult_operator" "")
15204 (const_string "fmul")
15205 (match_operand:XF 3 "div_operator" "")
15206 (const_string "fdiv")
15207 ]
15208 (const_string "fop")))
15209 (set_attr "mode" "SF")])
15210
15211 (define_insn "*fop_tf_4"
15212 [(set (match_operand:TF 0 "register_operand" "=f,f")
15213 (match_operator:TF 3 "binary_fp_operator"
15214 [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
15215 (match_operand:TF 2 "register_operand" "0,f")]))]
15216 "TARGET_80387"
15217 "* return output_387_binary_op (insn, operands);"
15218 [(set (attr "type")
15219 (cond [(match_operand:TF 3 "mult_operator" "")
15220 (const_string "fmul")
15221 (match_operand:TF 3 "div_operator" "")
15222 (const_string "fdiv")
15223 ]
15224 (const_string "fop")))
15225 (set_attr "mode" "SF")])
15226
15227 (define_insn "*fop_xf_5"
15228 [(set (match_operand:XF 0 "register_operand" "=f,f")
15229 (match_operator:XF 3 "binary_fp_operator"
15230 [(match_operand:XF 1 "register_operand" "0,f")
15231 (float_extend:XF
15232 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15233 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15234 "* return output_387_binary_op (insn, operands);"
15235 [(set (attr "type")
15236 (cond [(match_operand:XF 3 "mult_operator" "")
15237 (const_string "fmul")
15238 (match_operand:XF 3 "div_operator" "")
15239 (const_string "fdiv")
15240 ]
15241 (const_string "fop")))
15242 (set_attr "mode" "SF")])
15243
15244 (define_insn "*fop_tf_5"
15245 [(set (match_operand:TF 0 "register_operand" "=f,f")
15246 (match_operator:TF 3 "binary_fp_operator"
15247 [(match_operand:TF 1 "register_operand" "0,f")
15248 (float_extend:TF
15249 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15250 "TARGET_80387"
15251 "* return output_387_binary_op (insn, operands);"
15252 [(set (attr "type")
15253 (cond [(match_operand:TF 3 "mult_operator" "")
15254 (const_string "fmul")
15255 (match_operand:TF 3 "div_operator" "")
15256 (const_string "fdiv")
15257 ]
15258 (const_string "fop")))
15259 (set_attr "mode" "SF")])
15260
15261 (define_insn "*fop_xf_6"
15262 [(set (match_operand:XF 0 "register_operand" "=f,f")
15263 (match_operator:XF 3 "binary_fp_operator"
15264 [(float_extend:XF
15265 (match_operand 1 "register_operand" "0,f"))
15266 (float_extend:XF
15267 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15268 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15269 "* return output_387_binary_op (insn, operands);"
15270 [(set (attr "type")
15271 (cond [(match_operand:XF 3 "mult_operator" "")
15272 (const_string "fmul")
15273 (match_operand:XF 3 "div_operator" "")
15274 (const_string "fdiv")
15275 ]
15276 (const_string "fop")))
15277 (set_attr "mode" "SF")])
15278
15279 (define_insn "*fop_tf_6"
15280 [(set (match_operand:TF 0 "register_operand" "=f,f")
15281 (match_operator:TF 3 "binary_fp_operator"
15282 [(float_extend:TF
15283 (match_operand 1 "register_operand" "0,f"))
15284 (float_extend:TF
15285 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15286 "TARGET_80387"
15287 "* return output_387_binary_op (insn, operands);"
15288 [(set (attr "type")
15289 (cond [(match_operand:TF 3 "mult_operator" "")
15290 (const_string "fmul")
15291 (match_operand:TF 3 "div_operator" "")
15292 (const_string "fdiv")
15293 ]
15294 (const_string "fop")))
15295 (set_attr "mode" "SF")])
15296
15297 (define_split
15298 [(set (match_operand 0 "register_operand" "")
15299 (match_operator 3 "binary_fp_operator"
15300 [(float (match_operand:SI 1 "register_operand" ""))
15301 (match_operand 2 "register_operand" "")]))]
15302 "TARGET_80387 && reload_completed
15303 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15304 [(const_int 0)]
15305 {
15306 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15307 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15308 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15309 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15310 GET_MODE (operands[3]),
15311 operands[4],
15312 operands[2])));
15313 ix86_free_from_memory (GET_MODE (operands[1]));
15314 DONE;
15315 })
15316
15317 (define_split
15318 [(set (match_operand 0 "register_operand" "")
15319 (match_operator 3 "binary_fp_operator"
15320 [(match_operand 1 "register_operand" "")
15321 (float (match_operand:SI 2 "register_operand" ""))]))]
15322 "TARGET_80387 && reload_completed
15323 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15324 [(const_int 0)]
15325 {
15326 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15327 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15328 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15329 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15330 GET_MODE (operands[3]),
15331 operands[1],
15332 operands[4])));
15333 ix86_free_from_memory (GET_MODE (operands[2]));
15334 DONE;
15335 })
15336 \f
15337 ;; FPU special functions.
15338
15339 (define_expand "sqrtsf2"
15340 [(set (match_operand:SF 0 "register_operand" "")
15341 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15342 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
15343 {
15344 if (!TARGET_SSE_MATH)
15345 operands[1] = force_reg (SFmode, operands[1]);
15346 })
15347
15348 (define_insn "sqrtsf2_1"
15349 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15350 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15351 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15352 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15353 "@
15354 fsqrt
15355 sqrtss\t{%1, %0|%0, %1}"
15356 [(set_attr "type" "fpspc,sse")
15357 (set_attr "mode" "SF,SF")
15358 (set_attr "athlon_decode" "direct,*")])
15359
15360 (define_insn "sqrtsf2_1_sse_only"
15361 [(set (match_operand:SF 0 "register_operand" "=x")
15362 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15363 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15364 "sqrtss\t{%1, %0|%0, %1}"
15365 [(set_attr "type" "sse")
15366 (set_attr "mode" "SF")
15367 (set_attr "athlon_decode" "*")])
15368
15369 (define_insn "sqrtsf2_i387"
15370 [(set (match_operand:SF 0 "register_operand" "=f")
15371 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15372 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15373 && !TARGET_SSE_MATH"
15374 "fsqrt"
15375 [(set_attr "type" "fpspc")
15376 (set_attr "mode" "SF")
15377 (set_attr "athlon_decode" "direct")])
15378
15379 (define_expand "sqrtdf2"
15380 [(set (match_operand:DF 0 "register_operand" "")
15381 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15382 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
15383 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15384 {
15385 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
15386 operands[1] = force_reg (DFmode, operands[1]);
15387 })
15388
15389 (define_insn "sqrtdf2_1"
15390 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15391 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15392 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15393 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15394 "@
15395 fsqrt
15396 sqrtsd\t{%1, %0|%0, %1}"
15397 [(set_attr "type" "fpspc,sse")
15398 (set_attr "mode" "DF,DF")
15399 (set_attr "athlon_decode" "direct,*")])
15400
15401 (define_insn "sqrtdf2_1_sse_only"
15402 [(set (match_operand:DF 0 "register_operand" "=Y")
15403 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15404 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15405 "sqrtsd\t{%1, %0|%0, %1}"
15406 [(set_attr "type" "sse")
15407 (set_attr "mode" "DF")
15408 (set_attr "athlon_decode" "*")])
15409
15410 (define_insn "sqrtdf2_i387"
15411 [(set (match_operand:DF 0 "register_operand" "=f")
15412 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15413 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15414 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
15415 "fsqrt"
15416 [(set_attr "type" "fpspc")
15417 (set_attr "mode" "DF")
15418 (set_attr "athlon_decode" "direct")])
15419
15420 (define_insn "*sqrtextendsfdf2"
15421 [(set (match_operand:DF 0 "register_operand" "=f")
15422 (sqrt:DF (float_extend:DF
15423 (match_operand:SF 1 "register_operand" "0"))))]
15424 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15425 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15426 "fsqrt"
15427 [(set_attr "type" "fpspc")
15428 (set_attr "mode" "DF")
15429 (set_attr "athlon_decode" "direct")])
15430
15431 (define_insn "sqrtxf2"
15432 [(set (match_operand:XF 0 "register_operand" "=f")
15433 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15434 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15435 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15436 "fsqrt"
15437 [(set_attr "type" "fpspc")
15438 (set_attr "mode" "XF")
15439 (set_attr "athlon_decode" "direct")])
15440
15441 (define_insn "sqrttf2"
15442 [(set (match_operand:TF 0 "register_operand" "=f")
15443 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
15444 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15445 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15446 "fsqrt"
15447 [(set_attr "type" "fpspc")
15448 (set_attr "mode" "XF")
15449 (set_attr "athlon_decode" "direct")])
15450
15451 (define_insn "*sqrtextenddfxf2"
15452 [(set (match_operand:XF 0 "register_operand" "=f")
15453 (sqrt:XF (float_extend:XF
15454 (match_operand:DF 1 "register_operand" "0"))))]
15455 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15456 "fsqrt"
15457 [(set_attr "type" "fpspc")
15458 (set_attr "mode" "XF")
15459 (set_attr "athlon_decode" "direct")])
15460
15461 (define_insn "*sqrtextenddftf2"
15462 [(set (match_operand:TF 0 "register_operand" "=f")
15463 (sqrt:TF (float_extend:TF
15464 (match_operand:DF 1 "register_operand" "0"))))]
15465 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15466 "fsqrt"
15467 [(set_attr "type" "fpspc")
15468 (set_attr "mode" "XF")
15469 (set_attr "athlon_decode" "direct")])
15470
15471 (define_insn "*sqrtextendsfxf2"
15472 [(set (match_operand:XF 0 "register_operand" "=f")
15473 (sqrt:XF (float_extend:XF
15474 (match_operand:SF 1 "register_operand" "0"))))]
15475 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15476 "fsqrt"
15477 [(set_attr "type" "fpspc")
15478 (set_attr "mode" "XF")
15479 (set_attr "athlon_decode" "direct")])
15480
15481 (define_insn "*sqrtextendsftf2"
15482 [(set (match_operand:TF 0 "register_operand" "=f")
15483 (sqrt:TF (float_extend:TF
15484 (match_operand:SF 1 "register_operand" "0"))))]
15485 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15486 "fsqrt"
15487 [(set_attr "type" "fpspc")
15488 (set_attr "mode" "XF")
15489 (set_attr "athlon_decode" "direct")])
15490
15491 (define_insn "sindf2"
15492 [(set (match_operand:DF 0 "register_operand" "=f")
15493 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15494 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15495 && flag_unsafe_math_optimizations"
15496 "fsin"
15497 [(set_attr "type" "fpspc")
15498 (set_attr "mode" "DF")])
15499
15500 (define_insn "sinsf2"
15501 [(set (match_operand:SF 0 "register_operand" "=f")
15502 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15503 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15504 && flag_unsafe_math_optimizations"
15505 "fsin"
15506 [(set_attr "type" "fpspc")
15507 (set_attr "mode" "SF")])
15508
15509 (define_insn "*sinextendsfdf2"
15510 [(set (match_operand:DF 0 "register_operand" "=f")
15511 (unspec:DF [(float_extend:DF
15512 (match_operand:SF 1 "register_operand" "0"))]
15513 UNSPEC_SIN))]
15514 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15515 && flag_unsafe_math_optimizations"
15516 "fsin"
15517 [(set_attr "type" "fpspc")
15518 (set_attr "mode" "DF")])
15519
15520 (define_insn "sinxf2"
15521 [(set (match_operand:XF 0 "register_operand" "=f")
15522 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15523 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15524 && flag_unsafe_math_optimizations"
15525 "fsin"
15526 [(set_attr "type" "fpspc")
15527 (set_attr "mode" "XF")])
15528
15529 (define_insn "sintf2"
15530 [(set (match_operand:TF 0 "register_operand" "=f")
15531 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15532 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15533 && flag_unsafe_math_optimizations"
15534 "fsin"
15535 [(set_attr "type" "fpspc")
15536 (set_attr "mode" "XF")])
15537
15538 (define_insn "cosdf2"
15539 [(set (match_operand:DF 0 "register_operand" "=f")
15540 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15541 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15542 && flag_unsafe_math_optimizations"
15543 "fcos"
15544 [(set_attr "type" "fpspc")
15545 (set_attr "mode" "DF")])
15546
15547 (define_insn "cossf2"
15548 [(set (match_operand:SF 0 "register_operand" "=f")
15549 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15550 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15551 && flag_unsafe_math_optimizations"
15552 "fcos"
15553 [(set_attr "type" "fpspc")
15554 (set_attr "mode" "SF")])
15555
15556 (define_insn "*cosextendsfdf2"
15557 [(set (match_operand:DF 0 "register_operand" "=f")
15558 (unspec:DF [(float_extend:DF
15559 (match_operand:SF 1 "register_operand" "0"))]
15560 UNSPEC_COS))]
15561 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15562 && flag_unsafe_math_optimizations"
15563 "fcos"
15564 [(set_attr "type" "fpspc")
15565 (set_attr "mode" "DF")])
15566
15567 (define_insn "cosxf2"
15568 [(set (match_operand:XF 0 "register_operand" "=f")
15569 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15570 "!TARGET_128BIT_LONG_DOUBLE && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15571 && flag_unsafe_math_optimizations"
15572 "fcos"
15573 [(set_attr "type" "fpspc")
15574 (set_attr "mode" "XF")])
15575
15576 (define_insn "costf2"
15577 [(set (match_operand:TF 0 "register_operand" "=f")
15578 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15579 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15580 && flag_unsafe_math_optimizations"
15581 "fcos"
15582 [(set_attr "type" "fpspc")
15583 (set_attr "mode" "XF")])
15584
15585 (define_insn "atan2df3_1"
15586 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15587 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15588 (match_operand:DF 1 "register_operand" "u")]
15589 UNSPEC_FPATAN))
15590 (clobber (match_dup 1))])]
15591 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15592 && flag_unsafe_math_optimizations"
15593 "fpatan"
15594 [(set_attr "type" "fpspc")
15595 (set_attr "mode" "DF")])
15596
15597 (define_expand "atan2df3"
15598 [(use (match_operand:DF 0 "register_operand" "=f"))
15599 (use (match_operand:DF 2 "register_operand" "0"))
15600 (use (match_operand:DF 1 "register_operand" "u"))]
15601 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15602 && flag_unsafe_math_optimizations"
15603 {
15604 rtx copy = gen_reg_rtx (DFmode);
15605 emit_move_insn (copy, operands[1]);
15606 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15607 DONE;
15608 })
15609
15610 (define_insn "atan2sf3_1"
15611 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15612 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15613 (match_operand:SF 1 "register_operand" "u")]
15614 UNSPEC_FPATAN))
15615 (clobber (match_dup 1))])]
15616 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15617 && flag_unsafe_math_optimizations"
15618 "fpatan"
15619 [(set_attr "type" "fpspc")
15620 (set_attr "mode" "SF")])
15621
15622 (define_expand "atan2sf3"
15623 [(use (match_operand:SF 0 "register_operand" "=f"))
15624 (use (match_operand:SF 2 "register_operand" "0"))
15625 (use (match_operand:SF 1 "register_operand" "u"))]
15626 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15627 && flag_unsafe_math_optimizations"
15628 {
15629 rtx copy = gen_reg_rtx (SFmode);
15630 emit_move_insn (copy, operands[1]);
15631 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15632 DONE;
15633 })
15634
15635 (define_insn "atan2xf3_1"
15636 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15637 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15638 (match_operand:XF 1 "register_operand" "u")]
15639 UNSPEC_FPATAN))
15640 (clobber (match_dup 1))])]
15641 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15642 && flag_unsafe_math_optimizations && ! TARGET_128BIT_LONG_DOUBLE"
15643 "fpatan"
15644 [(set_attr "type" "fpspc")
15645 (set_attr "mode" "XF")])
15646
15647 (define_expand "atan2xf3"
15648 [(use (match_operand:XF 0 "register_operand" "=f"))
15649 (use (match_operand:XF 2 "register_operand" "0"))
15650 (use (match_operand:XF 1 "register_operand" "u"))]
15651 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15652 && flag_unsafe_math_optimizations && ! TARGET_128BIT_LONG_DOUBLE"
15653 {
15654 rtx copy = gen_reg_rtx (XFmode);
15655 emit_move_insn (copy, operands[1]);
15656 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15657 DONE;
15658 })
15659
15660 (define_insn "atan2tf3_1"
15661 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15662 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15663 (match_operand:TF 1 "register_operand" "u")]
15664 UNSPEC_FPATAN))
15665 (clobber (match_dup 1))])]
15666 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15667 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15668 "fpatan"
15669 [(set_attr "type" "fpspc")
15670 (set_attr "mode" "XF")])
15671
15672 (define_expand "atan2tf3"
15673 [(use (match_operand:TF 0 "register_operand" "=f"))
15674 (use (match_operand:TF 2 "register_operand" "0"))
15675 (use (match_operand:TF 1 "register_operand" "u"))]
15676 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15677 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15678 {
15679 rtx copy = gen_reg_rtx (TFmode);
15680 emit_move_insn (copy, operands[1]);
15681 emit_insn (gen_atan2tf3_1 (operands[0], copy, operands[2]));
15682 DONE;
15683 })
15684
15685 (define_insn "*fyl2x_sfxf3"
15686 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15687 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15688 (match_operand 1 "register_operand" "u")]
15689 UNSPEC_FYL2X))
15690 (clobber (match_dup 1))])]
15691 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15692 && flag_unsafe_math_optimizations
15693 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15694 "fyl2x"
15695 [(set_attr "type" "fpspc")
15696 (set_attr "mode" "SF")])
15697
15698 (define_insn "*fyl2x_dfxf3"
15699 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15700 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15701 (match_operand 1 "register_operand" "u")]
15702 UNSPEC_FYL2X))
15703 (clobber (match_dup 1))])]
15704 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15705 && flag_unsafe_math_optimizations
15706 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15707 "fyl2x"
15708 [(set_attr "type" "fpspc")
15709 (set_attr "mode" "DF")])
15710
15711 (define_insn "*fyl2x_xf3"
15712 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15713 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15714 (match_operand:XF 1 "register_operand" "u")]
15715 UNSPEC_FYL2X))
15716 (clobber (match_dup 1))])]
15717 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15718 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15719 "fyl2x"
15720 [(set_attr "type" "fpspc")
15721 (set_attr "mode" "XF")])
15722
15723 (define_insn "*fyl2x_tfxf3"
15724 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15725 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15726 (match_operand:TF 1 "register_operand" "u")]
15727 UNSPEC_FYL2X))
15728 (clobber (match_dup 1))])]
15729 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15730 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15731 "fyl2x"
15732 [(set_attr "type" "fpspc")
15733 (set_attr "mode" "XF")])
15734
15735 (define_expand "logsf2"
15736 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15737 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15738 (match_dup 2)] UNSPEC_FYL2X))
15739 (clobber (match_dup 2))])]
15740 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15741 && flag_unsafe_math_optimizations"
15742 {
15743 rtx temp;
15744
15745 operands[2] = gen_reg_rtx (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode);
15746 temp = standard_80387_constant_rtx (4); /* fldln2 */
15747 emit_move_insn (operands[2], temp);
15748 })
15749
15750 (define_expand "logdf2"
15751 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15752 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15753 (match_dup 2)] UNSPEC_FYL2X))
15754 (clobber (match_dup 2))])]
15755 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15756 && flag_unsafe_math_optimizations"
15757 {
15758 rtx temp;
15759
15760 operands[2] = gen_reg_rtx (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode);
15761 temp = standard_80387_constant_rtx (4); /* fldln2 */
15762 emit_move_insn (operands[2], temp);
15763 })
15764
15765 (define_expand "logxf2"
15766 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15767 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15768 (match_dup 2)] UNSPEC_FYL2X))
15769 (clobber (match_dup 2))])]
15770 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15771 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15772 {
15773 rtx temp;
15774
15775 operands[2] = gen_reg_rtx (XFmode);
15776 temp = standard_80387_constant_rtx (4); /* fldln2 */
15777 emit_move_insn (operands[2], temp);
15778 })
15779
15780 (define_expand "logtf2"
15781 [(parallel [(set (match_operand:TF 0 "register_operand" "")
15782 (unspec:TF [(match_operand:TF 1 "register_operand" "")
15783 (match_dup 2)] UNSPEC_FYL2X))
15784 (clobber (match_dup 2))])]
15785 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15786 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15787 {
15788 rtx temp;
15789
15790 operands[2] = gen_reg_rtx (TFmode);
15791 temp = standard_80387_constant_rtx (4); /* fldln2 */
15792 emit_move_insn (operands[2], temp);
15793 })
15794
15795 (define_insn "*fscale_sfxf3"
15796 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15797 (unspec:SF [(match_operand 2 "register_operand" "0")
15798 (match_operand 1 "register_operand" "u")]
15799 UNSPEC_FSCALE))
15800 (clobber (match_dup 1))])]
15801 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15802 && flag_unsafe_math_optimizations
15803 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)
15804 && GET_MODE (operands[2]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15805 "fscale\;fstp\t%y1"
15806 [(set_attr "type" "fpspc")
15807 (set_attr "mode" "SF")])
15808
15809 (define_insn "*fscale_dfxf3"
15810 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15811 (unspec:DF [(match_operand 2 "register_operand" "0")
15812 (match_operand 1 "register_operand" "u")]
15813 UNSPEC_FSCALE))
15814 (clobber (match_dup 1))])]
15815 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15816 && flag_unsafe_math_optimizations
15817 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)
15818 && GET_MODE (operands[2]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15819 "fscale\;fstp\t%y1"
15820 [(set_attr "type" "fpspc")
15821 (set_attr "mode" "DF")])
15822
15823 (define_insn "*fscale_xf3"
15824 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15825 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15826 (match_operand:XF 1 "register_operand" "u")]
15827 UNSPEC_FSCALE))
15828 (clobber (match_dup 1))])]
15829 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15830 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15831 "fscale\;fstp\t%y1"
15832 [(set_attr "type" "fpspc")
15833 (set_attr "mode" "XF")])
15834
15835 (define_insn "*fscale_tf3"
15836 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15837 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15838 (match_operand:TF 1 "register_operand" "u")]
15839 UNSPEC_FSCALE))
15840 (clobber (match_dup 1))])]
15841 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15842 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15843 "fscale\;fstp\t%y1"
15844 [(set_attr "type" "fpspc")
15845 (set_attr "mode" "XF")])
15846
15847 (define_insn "*frndintxf2"
15848 [(set (match_operand:XF 0 "register_operand" "=f")
15849 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15850 UNSPEC_FRNDINT))]
15851 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15852 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15853 "frndint"
15854 [(set_attr "type" "fpspc")
15855 (set_attr "mode" "XF")])
15856
15857 (define_insn "*frndinttf2"
15858 [(set (match_operand:TF 0 "register_operand" "=f")
15859 (unspec:TF [(match_operand:TF 1 "register_operand" "0")]
15860 UNSPEC_FRNDINT))]
15861 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15862 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15863 "frndint"
15864 [(set_attr "type" "fpspc")
15865 (set_attr "mode" "XF")])
15866
15867 (define_insn "*f2xm1xf2"
15868 [(set (match_operand:XF 0 "register_operand" "=f")
15869 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15870 UNSPEC_F2XM1))]
15871 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15872 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15873 "f2xm1"
15874 [(set_attr "type" "fpspc")
15875 (set_attr "mode" "XF")])
15876
15877 (define_insn "*f2xm1tf2"
15878 [(set (match_operand:TF 0 "register_operand" "=f")
15879 (unspec:TF [(match_operand:TF 1 "register_operand" "0")]
15880 UNSPEC_F2XM1))]
15881 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15882 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15883 "f2xm1"
15884 [(set_attr "type" "fpspc")
15885 (set_attr "mode" "XF")])
15886
15887 (define_expand "expsf2"
15888 [(set (match_dup 2)
15889 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15890 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15891 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15892 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15893 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15894 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15895 (parallel [(set (match_operand:SF 0 "register_operand" "")
15896 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15897 (clobber (match_dup 5))])]
15898 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15899 && flag_unsafe_math_optimizations"
15900 {
15901 rtx temp;
15902 int i;
15903
15904 if (TARGET_128BIT_LONG_DOUBLE)
15905 {
15906 emit_insn (gen_expsf2_tf (operands[0], operands[1]));
15907 DONE;
15908 }
15909
15910 for (i=2; i<10; i++)
15911 operands[i] = gen_reg_rtx (XFmode);
15912 temp = standard_80387_constant_rtx (5); /* fldl2e */
15913 emit_move_insn (operands[3], temp);
15914 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15915 })
15916
15917 (define_expand "expsf2_tf"
15918 [(set (match_dup 2)
15919 (float_extend:TF (match_operand:SF 1 "register_operand" "")))
15920 (set (match_dup 4) (mult:TF (match_dup 2) (match_dup 3)))
15921 (set (match_dup 5) (unspec:TF [(match_dup 4)] UNSPEC_FRNDINT))
15922 (set (match_dup 6) (minus:TF (match_dup 4) (match_dup 5)))
15923 (set (match_dup 7) (unspec:TF [(match_dup 6)] UNSPEC_F2XM1))
15924 (set (match_dup 9) (plus:TF (match_dup 7) (match_dup 8)))
15925 (parallel [(set (match_operand:SF 0 "register_operand" "")
15926 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15927 (clobber (match_dup 5))])]
15928 ""
15929 {
15930 rtx temp;
15931 int i;
15932
15933 for (i=2; i<10; i++)
15934 operands[i] = gen_reg_rtx (TFmode);
15935 temp = standard_80387_constant_rtx (5); /* fldl2e */
15936 emit_move_insn (operands[3], temp);
15937 emit_move_insn (operands[8], CONST1_RTX (TFmode)); /* fld1 */
15938 })
15939
15940 (define_expand "expdf2"
15941 [(set (match_dup 2)
15942 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15943 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15944 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15945 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15946 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15947 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15948 (parallel [(set (match_operand:DF 0 "register_operand" "")
15949 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15950 (clobber (match_dup 5))])]
15951 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15952 && flag_unsafe_math_optimizations"
15953 {
15954 rtx temp;
15955 int i;
15956
15957 if (TARGET_128BIT_LONG_DOUBLE)
15958 {
15959 emit_insn (gen_expdf2_tf (operands[0], operands[1]));
15960 DONE;
15961 }
15962
15963 for (i=2; i<10; i++)
15964 operands[i] = gen_reg_rtx (XFmode);
15965 temp = standard_80387_constant_rtx (5); /* fldl2e */
15966 emit_move_insn (operands[3], temp);
15967 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15968 })
15969
15970
15971 (define_expand "expdf2_tf"
15972 [(set (match_dup 2)
15973 (float_extend:TF (match_operand:DF 1 "register_operand" "")))
15974 (set (match_dup 4) (mult:TF (match_dup 2) (match_dup 3)))
15975 (set (match_dup 5) (unspec:TF [(match_dup 4)] UNSPEC_FRNDINT))
15976 (set (match_dup 6) (minus:TF (match_dup 4) (match_dup 5)))
15977 (set (match_dup 7) (unspec:TF [(match_dup 6)] UNSPEC_F2XM1))
15978 (set (match_dup 9) (plus:TF (match_dup 7) (match_dup 8)))
15979 (parallel [(set (match_operand:DF 0 "register_operand" "")
15980 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15981 (clobber (match_dup 5))])]
15982 ""
15983 {
15984 rtx temp;
15985 int i;
15986
15987 for (i=2; i<10; i++)
15988 operands[i] = gen_reg_rtx (TFmode);
15989 temp = standard_80387_constant_rtx (5); /* fldl2e */
15990 emit_move_insn (operands[3], temp);
15991 emit_move_insn (operands[8], CONST1_RTX (TFmode)); /* fld1 */
15992 })
15993
15994 (define_expand "expxf2"
15995 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15996 (match_dup 2)))
15997 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15998 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15999 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16000 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16001 (parallel [(set (match_operand:XF 0 "register_operand" "")
16002 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
16003 (clobber (match_dup 4))])]
16004 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16005 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
16006 {
16007 rtx temp;
16008 int i;
16009
16010 for (i=2; i<9; i++)
16011 operands[i] = gen_reg_rtx (XFmode);
16012 temp = standard_80387_constant_rtx (5); /* fldl2e */
16013 emit_move_insn (operands[2], temp);
16014 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16015 })
16016
16017 (define_expand "atansf2"
16018 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16019 (unspec:SF [(match_dup 2)
16020 (match_operand:SF 1 "register_operand" "")]
16021 UNSPEC_FPATAN))
16022 (clobber (match_dup 1))])]
16023 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16024 && flag_unsafe_math_optimizations"
16025 {
16026 operands[2] = gen_reg_rtx (SFmode);
16027 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16028 })
16029
16030 (define_expand "exptf2"
16031 [(set (match_dup 3) (mult:TF (match_operand:TF 1 "register_operand" "")
16032 (match_dup 2)))
16033 (set (match_dup 4) (unspec:TF [(match_dup 3)] UNSPEC_FRNDINT))
16034 (set (match_dup 5) (minus:TF (match_dup 3) (match_dup 4)))
16035 (set (match_dup 6) (unspec:TF [(match_dup 5)] UNSPEC_F2XM1))
16036 (set (match_dup 8) (plus:TF (match_dup 6) (match_dup 7)))
16037 (parallel [(set (match_operand:TF 0 "register_operand" "")
16038 (unspec:TF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
16039 (clobber (match_dup 4))])]
16040 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16041 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
16042 {
16043 rtx temp;
16044 int i;
16045
16046 for (i=2; i<9; i++)
16047 operands[i] = gen_reg_rtx (TFmode);
16048 temp = standard_80387_constant_rtx (5); /* fldl2e */
16049 emit_move_insn (operands[2], temp);
16050 emit_move_insn (operands[7], CONST1_RTX (TFmode)); /* fld1 */
16051 })
16052
16053 (define_expand "atandf2"
16054 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16055 (unspec:DF [(match_dup 2)
16056 (match_operand:DF 1 "register_operand" "")]
16057 UNSPEC_FPATAN))
16058 (clobber (match_dup 1))])]
16059 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16060 && flag_unsafe_math_optimizations"
16061 {
16062 operands[2] = gen_reg_rtx (DFmode);
16063 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16064 })
16065
16066 (define_expand "atanxf2"
16067 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16068 (unspec:XF [(match_dup 2)
16069 (match_operand:XF 1 "register_operand" "")]
16070 UNSPEC_FPATAN))
16071 (clobber (match_dup 1))])]
16072 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16073 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
16074 {
16075 operands[2] = gen_reg_rtx (XFmode);
16076 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16077 })
16078
16079 (define_expand "atantf2"
16080 [(parallel [(set (match_operand:TF 0 "register_operand" "")
16081 (unspec:TF [(match_dup 2)
16082 (match_operand:TF 1 "register_operand" "")]
16083 UNSPEC_FPATAN))
16084 (clobber (match_dup 1))])]
16085 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16086 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
16087 {
16088 operands[2] = gen_reg_rtx (TFmode);
16089 emit_move_insn (operands[2], CONST1_RTX (TFmode)); /* fld1 */
16090 })
16091 \f
16092 ;; Block operation instructions
16093
16094 (define_insn "cld"
16095 [(set (reg:SI 19) (const_int 0))]
16096 ""
16097 "cld"
16098 [(set_attr "type" "cld")])
16099
16100 (define_expand "movstrsi"
16101 [(use (match_operand:BLK 0 "memory_operand" ""))
16102 (use (match_operand:BLK 1 "memory_operand" ""))
16103 (use (match_operand:SI 2 "nonmemory_operand" ""))
16104 (use (match_operand:SI 3 "const_int_operand" ""))]
16105 ""
16106 {
16107 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16108 DONE;
16109 else
16110 FAIL;
16111 })
16112
16113 (define_expand "movstrdi"
16114 [(use (match_operand:BLK 0 "memory_operand" ""))
16115 (use (match_operand:BLK 1 "memory_operand" ""))
16116 (use (match_operand:DI 2 "nonmemory_operand" ""))
16117 (use (match_operand:DI 3 "const_int_operand" ""))]
16118 "TARGET_64BIT"
16119 {
16120 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16121 DONE;
16122 else
16123 FAIL;
16124 })
16125
16126 ;; Most CPUs don't like single string operations
16127 ;; Handle this case here to simplify previous expander.
16128
16129 (define_expand "strmovdi_rex64"
16130 [(set (match_dup 2)
16131 (mem:DI (match_operand:DI 1 "register_operand" "")))
16132 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
16133 (match_dup 2))
16134 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16135 (clobber (reg:CC 17))])
16136 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
16137 (clobber (reg:CC 17))])]
16138 "TARGET_64BIT"
16139 {
16140 if (TARGET_SINGLE_STRINGOP || optimize_size)
16141 {
16142 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
16143 operands[1]));
16144 DONE;
16145 }
16146 else
16147 operands[2] = gen_reg_rtx (DImode);
16148 })
16149
16150
16151 (define_expand "strmovsi"
16152 [(set (match_dup 2)
16153 (mem:SI (match_operand:SI 1 "register_operand" "")))
16154 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
16155 (match_dup 2))
16156 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16157 (clobber (reg:CC 17))])
16158 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
16159 (clobber (reg:CC 17))])]
16160 ""
16161 {
16162 if (TARGET_64BIT)
16163 {
16164 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
16165 DONE;
16166 }
16167 if (TARGET_SINGLE_STRINGOP || optimize_size)
16168 {
16169 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
16170 operands[1]));
16171 DONE;
16172 }
16173 else
16174 operands[2] = gen_reg_rtx (SImode);
16175 })
16176
16177 (define_expand "strmovsi_rex64"
16178 [(set (match_dup 2)
16179 (mem:SI (match_operand:DI 1 "register_operand" "")))
16180 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
16181 (match_dup 2))
16182 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16183 (clobber (reg:CC 17))])
16184 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
16185 (clobber (reg:CC 17))])]
16186 "TARGET_64BIT"
16187 {
16188 if (TARGET_SINGLE_STRINGOP || optimize_size)
16189 {
16190 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
16191 operands[1]));
16192 DONE;
16193 }
16194 else
16195 operands[2] = gen_reg_rtx (SImode);
16196 })
16197
16198 (define_expand "strmovhi"
16199 [(set (match_dup 2)
16200 (mem:HI (match_operand:SI 1 "register_operand" "")))
16201 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
16202 (match_dup 2))
16203 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16204 (clobber (reg:CC 17))])
16205 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
16206 (clobber (reg:CC 17))])]
16207 ""
16208 {
16209 if (TARGET_64BIT)
16210 {
16211 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
16212 DONE;
16213 }
16214 if (TARGET_SINGLE_STRINGOP || optimize_size)
16215 {
16216 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
16217 operands[1]));
16218 DONE;
16219 }
16220 else
16221 operands[2] = gen_reg_rtx (HImode);
16222 })
16223
16224 (define_expand "strmovhi_rex64"
16225 [(set (match_dup 2)
16226 (mem:HI (match_operand:DI 1 "register_operand" "")))
16227 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
16228 (match_dup 2))
16229 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16230 (clobber (reg:CC 17))])
16231 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
16232 (clobber (reg:CC 17))])]
16233 "TARGET_64BIT"
16234 {
16235 if (TARGET_SINGLE_STRINGOP || optimize_size)
16236 {
16237 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
16238 operands[1]));
16239 DONE;
16240 }
16241 else
16242 operands[2] = gen_reg_rtx (HImode);
16243 })
16244
16245 (define_expand "strmovqi"
16246 [(set (match_dup 2)
16247 (mem:QI (match_operand:SI 1 "register_operand" "")))
16248 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
16249 (match_dup 2))
16250 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16251 (clobber (reg:CC 17))])
16252 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
16253 (clobber (reg:CC 17))])]
16254 ""
16255 {
16256 if (TARGET_64BIT)
16257 {
16258 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
16259 DONE;
16260 }
16261 if (TARGET_SINGLE_STRINGOP || optimize_size)
16262 {
16263 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
16264 operands[1]));
16265 DONE;
16266 }
16267 else
16268 operands[2] = gen_reg_rtx (QImode);
16269 })
16270
16271 (define_expand "strmovqi_rex64"
16272 [(set (match_dup 2)
16273 (mem:QI (match_operand:DI 1 "register_operand" "")))
16274 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
16275 (match_dup 2))
16276 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16277 (clobber (reg:CC 17))])
16278 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
16279 (clobber (reg:CC 17))])]
16280 "TARGET_64BIT"
16281 {
16282 if (TARGET_SINGLE_STRINGOP || optimize_size)
16283 {
16284 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
16285 operands[1]));
16286 DONE;
16287 }
16288 else
16289 operands[2] = gen_reg_rtx (QImode);
16290 })
16291
16292 (define_insn "strmovdi_rex_1"
16293 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16294 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16295 (set (match_operand:DI 0 "register_operand" "=D")
16296 (plus:DI (match_dup 2)
16297 (const_int 8)))
16298 (set (match_operand:DI 1 "register_operand" "=S")
16299 (plus:DI (match_dup 3)
16300 (const_int 8)))
16301 (use (reg:SI 19))]
16302 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16303 "movsq"
16304 [(set_attr "type" "str")
16305 (set_attr "mode" "DI")
16306 (set_attr "memory" "both")])
16307
16308 (define_insn "strmovsi_1"
16309 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16310 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16311 (set (match_operand:SI 0 "register_operand" "=D")
16312 (plus:SI (match_dup 2)
16313 (const_int 4)))
16314 (set (match_operand:SI 1 "register_operand" "=S")
16315 (plus:SI (match_dup 3)
16316 (const_int 4)))
16317 (use (reg:SI 19))]
16318 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16319 "{movsl|movsd}"
16320 [(set_attr "type" "str")
16321 (set_attr "mode" "SI")
16322 (set_attr "memory" "both")])
16323
16324 (define_insn "strmovsi_rex_1"
16325 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16326 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16327 (set (match_operand:DI 0 "register_operand" "=D")
16328 (plus:DI (match_dup 2)
16329 (const_int 4)))
16330 (set (match_operand:DI 1 "register_operand" "=S")
16331 (plus:DI (match_dup 3)
16332 (const_int 4)))
16333 (use (reg:SI 19))]
16334 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16335 "{movsl|movsd}"
16336 [(set_attr "type" "str")
16337 (set_attr "mode" "SI")
16338 (set_attr "memory" "both")])
16339
16340 (define_insn "strmovhi_1"
16341 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16342 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16343 (set (match_operand:SI 0 "register_operand" "=D")
16344 (plus:SI (match_dup 2)
16345 (const_int 2)))
16346 (set (match_operand:SI 1 "register_operand" "=S")
16347 (plus:SI (match_dup 3)
16348 (const_int 2)))
16349 (use (reg:SI 19))]
16350 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16351 "movsw"
16352 [(set_attr "type" "str")
16353 (set_attr "memory" "both")
16354 (set_attr "mode" "HI")])
16355
16356 (define_insn "strmovhi_rex_1"
16357 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16358 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16359 (set (match_operand:DI 0 "register_operand" "=D")
16360 (plus:DI (match_dup 2)
16361 (const_int 2)))
16362 (set (match_operand:DI 1 "register_operand" "=S")
16363 (plus:DI (match_dup 3)
16364 (const_int 2)))
16365 (use (reg:SI 19))]
16366 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16367 "movsw"
16368 [(set_attr "type" "str")
16369 (set_attr "memory" "both")
16370 (set_attr "mode" "HI")])
16371
16372 (define_insn "strmovqi_1"
16373 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16374 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16375 (set (match_operand:SI 0 "register_operand" "=D")
16376 (plus:SI (match_dup 2)
16377 (const_int 1)))
16378 (set (match_operand:SI 1 "register_operand" "=S")
16379 (plus:SI (match_dup 3)
16380 (const_int 1)))
16381 (use (reg:SI 19))]
16382 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16383 "movsb"
16384 [(set_attr "type" "str")
16385 (set_attr "memory" "both")
16386 (set_attr "mode" "QI")])
16387
16388 (define_insn "strmovqi_rex_1"
16389 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16390 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16391 (set (match_operand:DI 0 "register_operand" "=D")
16392 (plus:DI (match_dup 2)
16393 (const_int 1)))
16394 (set (match_operand:DI 1 "register_operand" "=S")
16395 (plus:DI (match_dup 3)
16396 (const_int 1)))
16397 (use (reg:SI 19))]
16398 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16399 "movsb"
16400 [(set_attr "type" "str")
16401 (set_attr "memory" "both")
16402 (set_attr "mode" "QI")])
16403
16404 (define_insn "rep_movdi_rex64"
16405 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16406 (set (match_operand:DI 0 "register_operand" "=D")
16407 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16408 (const_int 3))
16409 (match_operand:DI 3 "register_operand" "0")))
16410 (set (match_operand:DI 1 "register_operand" "=S")
16411 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16412 (match_operand:DI 4 "register_operand" "1")))
16413 (set (mem:BLK (match_dup 3))
16414 (mem:BLK (match_dup 4)))
16415 (use (match_dup 5))
16416 (use (reg:SI 19))]
16417 "TARGET_64BIT"
16418 "{rep\;movsq|rep movsq}"
16419 [(set_attr "type" "str")
16420 (set_attr "prefix_rep" "1")
16421 (set_attr "memory" "both")
16422 (set_attr "mode" "DI")])
16423
16424 (define_insn "rep_movsi"
16425 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16426 (set (match_operand:SI 0 "register_operand" "=D")
16427 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16428 (const_int 2))
16429 (match_operand:SI 3 "register_operand" "0")))
16430 (set (match_operand:SI 1 "register_operand" "=S")
16431 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16432 (match_operand:SI 4 "register_operand" "1")))
16433 (set (mem:BLK (match_dup 3))
16434 (mem:BLK (match_dup 4)))
16435 (use (match_dup 5))
16436 (use (reg:SI 19))]
16437 "!TARGET_64BIT"
16438 "{rep\;movsl|rep movsd}"
16439 [(set_attr "type" "str")
16440 (set_attr "prefix_rep" "1")
16441 (set_attr "memory" "both")
16442 (set_attr "mode" "SI")])
16443
16444 (define_insn "rep_movsi_rex64"
16445 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16446 (set (match_operand:DI 0 "register_operand" "=D")
16447 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16448 (const_int 2))
16449 (match_operand:DI 3 "register_operand" "0")))
16450 (set (match_operand:DI 1 "register_operand" "=S")
16451 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16452 (match_operand:DI 4 "register_operand" "1")))
16453 (set (mem:BLK (match_dup 3))
16454 (mem:BLK (match_dup 4)))
16455 (use (match_dup 5))
16456 (use (reg:SI 19))]
16457 "TARGET_64BIT"
16458 "{rep\;movsl|rep movsd}"
16459 [(set_attr "type" "str")
16460 (set_attr "prefix_rep" "1")
16461 (set_attr "memory" "both")
16462 (set_attr "mode" "SI")])
16463
16464 (define_insn "rep_movqi"
16465 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16466 (set (match_operand:SI 0 "register_operand" "=D")
16467 (plus:SI (match_operand:SI 3 "register_operand" "0")
16468 (match_operand:SI 5 "register_operand" "2")))
16469 (set (match_operand:SI 1 "register_operand" "=S")
16470 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16471 (set (mem:BLK (match_dup 3))
16472 (mem:BLK (match_dup 4)))
16473 (use (match_dup 5))
16474 (use (reg:SI 19))]
16475 "!TARGET_64BIT"
16476 "{rep\;movsb|rep movsb}"
16477 [(set_attr "type" "str")
16478 (set_attr "prefix_rep" "1")
16479 (set_attr "memory" "both")
16480 (set_attr "mode" "SI")])
16481
16482 (define_insn "rep_movqi_rex64"
16483 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16484 (set (match_operand:DI 0 "register_operand" "=D")
16485 (plus:DI (match_operand:DI 3 "register_operand" "0")
16486 (match_operand:DI 5 "register_operand" "2")))
16487 (set (match_operand:DI 1 "register_operand" "=S")
16488 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16489 (set (mem:BLK (match_dup 3))
16490 (mem:BLK (match_dup 4)))
16491 (use (match_dup 5))
16492 (use (reg:SI 19))]
16493 "TARGET_64BIT"
16494 "{rep\;movsb|rep movsb}"
16495 [(set_attr "type" "str")
16496 (set_attr "prefix_rep" "1")
16497 (set_attr "memory" "both")
16498 (set_attr "mode" "SI")])
16499
16500 (define_expand "clrstrsi"
16501 [(use (match_operand:BLK 0 "memory_operand" ""))
16502 (use (match_operand:SI 1 "nonmemory_operand" ""))
16503 (use (match_operand 2 "const_int_operand" ""))]
16504 ""
16505 {
16506 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16507 DONE;
16508 else
16509 FAIL;
16510 })
16511
16512 (define_expand "clrstrdi"
16513 [(use (match_operand:BLK 0 "memory_operand" ""))
16514 (use (match_operand:DI 1 "nonmemory_operand" ""))
16515 (use (match_operand 2 "const_int_operand" ""))]
16516 "TARGET_64BIT"
16517 {
16518 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16519 DONE;
16520 else
16521 FAIL;
16522 })
16523
16524 ;; Most CPUs don't like single string operations
16525 ;; Handle this case here to simplify previous expander.
16526
16527 (define_expand "strsetdi_rex64"
16528 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
16529 (match_operand:DI 1 "register_operand" ""))
16530 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16531 (clobber (reg:CC 17))])]
16532 "TARGET_64BIT"
16533 {
16534 if (TARGET_SINGLE_STRINGOP || optimize_size)
16535 {
16536 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
16537 DONE;
16538 }
16539 })
16540
16541 (define_expand "strsetsi"
16542 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
16543 (match_operand:SI 1 "register_operand" ""))
16544 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16545 (clobber (reg:CC 17))])]
16546 ""
16547 {
16548 if (TARGET_64BIT)
16549 {
16550 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
16551 DONE;
16552 }
16553 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16554 {
16555 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
16556 DONE;
16557 }
16558 })
16559
16560 (define_expand "strsetsi_rex64"
16561 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
16562 (match_operand:SI 1 "register_operand" ""))
16563 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16564 (clobber (reg:CC 17))])]
16565 "TARGET_64BIT"
16566 {
16567 if (TARGET_SINGLE_STRINGOP || optimize_size)
16568 {
16569 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
16570 DONE;
16571 }
16572 })
16573
16574 (define_expand "strsethi"
16575 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
16576 (match_operand:HI 1 "register_operand" ""))
16577 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16578 (clobber (reg:CC 17))])]
16579 ""
16580 {
16581 if (TARGET_64BIT)
16582 {
16583 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
16584 DONE;
16585 }
16586 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16587 {
16588 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
16589 DONE;
16590 }
16591 })
16592
16593 (define_expand "strsethi_rex64"
16594 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
16595 (match_operand:HI 1 "register_operand" ""))
16596 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16597 (clobber (reg:CC 17))])]
16598 "TARGET_64BIT"
16599 {
16600 if (TARGET_SINGLE_STRINGOP || optimize_size)
16601 {
16602 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
16603 DONE;
16604 }
16605 })
16606
16607 (define_expand "strsetqi"
16608 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
16609 (match_operand:QI 1 "register_operand" ""))
16610 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16611 (clobber (reg:CC 17))])]
16612 ""
16613 {
16614 if (TARGET_64BIT)
16615 {
16616 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
16617 DONE;
16618 }
16619 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16620 {
16621 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
16622 DONE;
16623 }
16624 })
16625
16626 (define_expand "strsetqi_rex64"
16627 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
16628 (match_operand:QI 1 "register_operand" ""))
16629 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16630 (clobber (reg:CC 17))])]
16631 "TARGET_64BIT"
16632 {
16633 if (TARGET_SINGLE_STRINGOP || optimize_size)
16634 {
16635 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
16636 DONE;
16637 }
16638 })
16639
16640 (define_insn "strsetdi_rex_1"
16641 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16642 (match_operand:SI 2 "register_operand" "a"))
16643 (set (match_operand:DI 0 "register_operand" "=D")
16644 (plus:DI (match_dup 1)
16645 (const_int 8)))
16646 (use (reg:SI 19))]
16647 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16648 "stosq"
16649 [(set_attr "type" "str")
16650 (set_attr "memory" "store")
16651 (set_attr "mode" "DI")])
16652
16653 (define_insn "strsetsi_1"
16654 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16655 (match_operand:SI 2 "register_operand" "a"))
16656 (set (match_operand:SI 0 "register_operand" "=D")
16657 (plus:SI (match_dup 1)
16658 (const_int 4)))
16659 (use (reg:SI 19))]
16660 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16661 "{stosl|stosd}"
16662 [(set_attr "type" "str")
16663 (set_attr "memory" "store")
16664 (set_attr "mode" "SI")])
16665
16666 (define_insn "strsetsi_rex_1"
16667 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16668 (match_operand:SI 2 "register_operand" "a"))
16669 (set (match_operand:DI 0 "register_operand" "=D")
16670 (plus:DI (match_dup 1)
16671 (const_int 4)))
16672 (use (reg:SI 19))]
16673 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16674 "{stosl|stosd}"
16675 [(set_attr "type" "str")
16676 (set_attr "memory" "store")
16677 (set_attr "mode" "SI")])
16678
16679 (define_insn "strsethi_1"
16680 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16681 (match_operand:HI 2 "register_operand" "a"))
16682 (set (match_operand:SI 0 "register_operand" "=D")
16683 (plus:SI (match_dup 1)
16684 (const_int 2)))
16685 (use (reg:SI 19))]
16686 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16687 "stosw"
16688 [(set_attr "type" "str")
16689 (set_attr "memory" "store")
16690 (set_attr "mode" "HI")])
16691
16692 (define_insn "strsethi_rex_1"
16693 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16694 (match_operand:HI 2 "register_operand" "a"))
16695 (set (match_operand:DI 0 "register_operand" "=D")
16696 (plus:DI (match_dup 1)
16697 (const_int 2)))
16698 (use (reg:SI 19))]
16699 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16700 "stosw"
16701 [(set_attr "type" "str")
16702 (set_attr "memory" "store")
16703 (set_attr "mode" "HI")])
16704
16705 (define_insn "strsetqi_1"
16706 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16707 (match_operand:QI 2 "register_operand" "a"))
16708 (set (match_operand:SI 0 "register_operand" "=D")
16709 (plus:SI (match_dup 1)
16710 (const_int 1)))
16711 (use (reg:SI 19))]
16712 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16713 "stosb"
16714 [(set_attr "type" "str")
16715 (set_attr "memory" "store")
16716 (set_attr "mode" "QI")])
16717
16718 (define_insn "strsetqi_rex_1"
16719 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16720 (match_operand:QI 2 "register_operand" "a"))
16721 (set (match_operand:DI 0 "register_operand" "=D")
16722 (plus:DI (match_dup 1)
16723 (const_int 1)))
16724 (use (reg:SI 19))]
16725 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16726 "stosb"
16727 [(set_attr "type" "str")
16728 (set_attr "memory" "store")
16729 (set_attr "mode" "QI")])
16730
16731 (define_insn "rep_stosdi_rex64"
16732 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16733 (set (match_operand:DI 0 "register_operand" "=D")
16734 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16735 (const_int 3))
16736 (match_operand:DI 3 "register_operand" "0")))
16737 (set (mem:BLK (match_dup 3))
16738 (const_int 0))
16739 (use (match_operand:DI 2 "register_operand" "a"))
16740 (use (match_dup 4))
16741 (use (reg:SI 19))]
16742 "TARGET_64BIT"
16743 "{rep\;stosq|rep stosq}"
16744 [(set_attr "type" "str")
16745 (set_attr "prefix_rep" "1")
16746 (set_attr "memory" "store")
16747 (set_attr "mode" "DI")])
16748
16749 (define_insn "rep_stossi"
16750 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16751 (set (match_operand:SI 0 "register_operand" "=D")
16752 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16753 (const_int 2))
16754 (match_operand:SI 3 "register_operand" "0")))
16755 (set (mem:BLK (match_dup 3))
16756 (const_int 0))
16757 (use (match_operand:SI 2 "register_operand" "a"))
16758 (use (match_dup 4))
16759 (use (reg:SI 19))]
16760 "!TARGET_64BIT"
16761 "{rep\;stosl|rep stosd}"
16762 [(set_attr "type" "str")
16763 (set_attr "prefix_rep" "1")
16764 (set_attr "memory" "store")
16765 (set_attr "mode" "SI")])
16766
16767 (define_insn "rep_stossi_rex64"
16768 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16769 (set (match_operand:DI 0 "register_operand" "=D")
16770 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16771 (const_int 2))
16772 (match_operand:DI 3 "register_operand" "0")))
16773 (set (mem:BLK (match_dup 3))
16774 (const_int 0))
16775 (use (match_operand:SI 2 "register_operand" "a"))
16776 (use (match_dup 4))
16777 (use (reg:SI 19))]
16778 "TARGET_64BIT"
16779 "{rep\;stosl|rep stosd}"
16780 [(set_attr "type" "str")
16781 (set_attr "prefix_rep" "1")
16782 (set_attr "memory" "store")
16783 (set_attr "mode" "SI")])
16784
16785 (define_insn "rep_stosqi"
16786 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16787 (set (match_operand:SI 0 "register_operand" "=D")
16788 (plus:SI (match_operand:SI 3 "register_operand" "0")
16789 (match_operand:SI 4 "register_operand" "1")))
16790 (set (mem:BLK (match_dup 3))
16791 (const_int 0))
16792 (use (match_operand:QI 2 "register_operand" "a"))
16793 (use (match_dup 4))
16794 (use (reg:SI 19))]
16795 "!TARGET_64BIT"
16796 "{rep\;stosb|rep stosb}"
16797 [(set_attr "type" "str")
16798 (set_attr "prefix_rep" "1")
16799 (set_attr "memory" "store")
16800 (set_attr "mode" "QI")])
16801
16802 (define_insn "rep_stosqi_rex64"
16803 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16804 (set (match_operand:DI 0 "register_operand" "=D")
16805 (plus:DI (match_operand:DI 3 "register_operand" "0")
16806 (match_operand:DI 4 "register_operand" "1")))
16807 (set (mem:BLK (match_dup 3))
16808 (const_int 0))
16809 (use (match_operand:QI 2 "register_operand" "a"))
16810 (use (match_dup 4))
16811 (use (reg:DI 19))]
16812 "TARGET_64BIT"
16813 "{rep\;stosb|rep stosb}"
16814 [(set_attr "type" "str")
16815 (set_attr "prefix_rep" "1")
16816 (set_attr "memory" "store")
16817 (set_attr "mode" "QI")])
16818
16819 (define_expand "cmpstrsi"
16820 [(set (match_operand:SI 0 "register_operand" "")
16821 (compare:SI (match_operand:BLK 1 "general_operand" "")
16822 (match_operand:BLK 2 "general_operand" "")))
16823 (use (match_operand 3 "general_operand" ""))
16824 (use (match_operand 4 "immediate_operand" ""))]
16825 ""
16826 {
16827 rtx addr1, addr2, out, outlow, count, countreg, align;
16828
16829 /* Can't use this if the user has appropriated esi or edi. */
16830 if (global_regs[4] || global_regs[5])
16831 FAIL;
16832
16833 out = operands[0];
16834 if (GET_CODE (out) != REG)
16835 out = gen_reg_rtx (SImode);
16836
16837 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16838 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16839
16840 count = operands[3];
16841 countreg = ix86_zero_extend_to_Pmode (count);
16842
16843 /* %%% Iff we are testing strict equality, we can use known alignment
16844 to good advantage. This may be possible with combine, particularly
16845 once cc0 is dead. */
16846 align = operands[4];
16847
16848 emit_insn (gen_cld ());
16849 if (GET_CODE (count) == CONST_INT)
16850 {
16851 if (INTVAL (count) == 0)
16852 {
16853 emit_move_insn (operands[0], const0_rtx);
16854 DONE;
16855 }
16856 if (TARGET_64BIT)
16857 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16858 addr1, addr2, countreg));
16859 else
16860 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16861 addr1, addr2, countreg));
16862 }
16863 else
16864 {
16865 if (TARGET_64BIT)
16866 {
16867 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16868 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16869 addr1, addr2, countreg));
16870 }
16871 else
16872 {
16873 emit_insn (gen_cmpsi_1 (countreg, countreg));
16874 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16875 addr1, addr2, countreg));
16876 }
16877 }
16878
16879 outlow = gen_lowpart (QImode, out);
16880 emit_insn (gen_cmpintqi (outlow));
16881 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16882
16883 if (operands[0] != out)
16884 emit_move_insn (operands[0], out);
16885
16886 DONE;
16887 })
16888
16889 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16890
16891 (define_expand "cmpintqi"
16892 [(set (match_dup 1)
16893 (gtu:QI (reg:CC 17) (const_int 0)))
16894 (set (match_dup 2)
16895 (ltu:QI (reg:CC 17) (const_int 0)))
16896 (parallel [(set (match_operand:QI 0 "register_operand" "")
16897 (minus:QI (match_dup 1)
16898 (match_dup 2)))
16899 (clobber (reg:CC 17))])]
16900 ""
16901 "operands[1] = gen_reg_rtx (QImode);
16902 operands[2] = gen_reg_rtx (QImode);")
16903
16904 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16905 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16906
16907 (define_insn "cmpstrqi_nz_1"
16908 [(set (reg:CC 17)
16909 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16910 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16911 (use (match_operand:SI 6 "register_operand" "2"))
16912 (use (match_operand:SI 3 "immediate_operand" "i"))
16913 (use (reg:SI 19))
16914 (clobber (match_operand:SI 0 "register_operand" "=S"))
16915 (clobber (match_operand:SI 1 "register_operand" "=D"))
16916 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16917 "!TARGET_64BIT"
16918 "repz{\;| }cmpsb"
16919 [(set_attr "type" "str")
16920 (set_attr "mode" "QI")
16921 (set_attr "prefix_rep" "1")])
16922
16923 (define_insn "cmpstrqi_nz_rex_1"
16924 [(set (reg:CC 17)
16925 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16926 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16927 (use (match_operand:DI 6 "register_operand" "2"))
16928 (use (match_operand:SI 3 "immediate_operand" "i"))
16929 (use (reg:SI 19))
16930 (clobber (match_operand:DI 0 "register_operand" "=S"))
16931 (clobber (match_operand:DI 1 "register_operand" "=D"))
16932 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16933 "TARGET_64BIT"
16934 "repz{\;| }cmpsb"
16935 [(set_attr "type" "str")
16936 (set_attr "mode" "QI")
16937 (set_attr "prefix_rep" "1")])
16938
16939 ;; The same, but the count is not known to not be zero.
16940
16941 (define_insn "cmpstrqi_1"
16942 [(set (reg:CC 17)
16943 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16944 (const_int 0))
16945 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16946 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16947 (const_int 0)))
16948 (use (match_operand:SI 3 "immediate_operand" "i"))
16949 (use (reg:CC 17))
16950 (use (reg:SI 19))
16951 (clobber (match_operand:SI 0 "register_operand" "=S"))
16952 (clobber (match_operand:SI 1 "register_operand" "=D"))
16953 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16954 "!TARGET_64BIT"
16955 "repz{\;| }cmpsb"
16956 [(set_attr "type" "str")
16957 (set_attr "mode" "QI")
16958 (set_attr "prefix_rep" "1")])
16959
16960 (define_insn "cmpstrqi_rex_1"
16961 [(set (reg:CC 17)
16962 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16963 (const_int 0))
16964 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16965 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16966 (const_int 0)))
16967 (use (match_operand:SI 3 "immediate_operand" "i"))
16968 (use (reg:CC 17))
16969 (use (reg:SI 19))
16970 (clobber (match_operand:DI 0 "register_operand" "=S"))
16971 (clobber (match_operand:DI 1 "register_operand" "=D"))
16972 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16973 "TARGET_64BIT"
16974 "repz{\;| }cmpsb"
16975 [(set_attr "type" "str")
16976 (set_attr "mode" "QI")
16977 (set_attr "prefix_rep" "1")])
16978
16979 (define_expand "strlensi"
16980 [(set (match_operand:SI 0 "register_operand" "")
16981 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16982 (match_operand:QI 2 "immediate_operand" "")
16983 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16984 ""
16985 {
16986 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16987 DONE;
16988 else
16989 FAIL;
16990 })
16991
16992 (define_expand "strlendi"
16993 [(set (match_operand:DI 0 "register_operand" "")
16994 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16995 (match_operand:QI 2 "immediate_operand" "")
16996 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16997 ""
16998 {
16999 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17000 DONE;
17001 else
17002 FAIL;
17003 })
17004
17005 (define_insn "strlenqi_1"
17006 [(set (match_operand:SI 0 "register_operand" "=&c")
17007 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17008 (match_operand:QI 2 "register_operand" "a")
17009 (match_operand:SI 3 "immediate_operand" "i")
17010 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17011 (use (reg:SI 19))
17012 (clobber (match_operand:SI 1 "register_operand" "=D"))
17013 (clobber (reg:CC 17))]
17014 "!TARGET_64BIT"
17015 "repnz{\;| }scasb"
17016 [(set_attr "type" "str")
17017 (set_attr "mode" "QI")
17018 (set_attr "prefix_rep" "1")])
17019
17020 (define_insn "strlenqi_rex_1"
17021 [(set (match_operand:DI 0 "register_operand" "=&c")
17022 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17023 (match_operand:QI 2 "register_operand" "a")
17024 (match_operand:DI 3 "immediate_operand" "i")
17025 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17026 (use (reg:SI 19))
17027 (clobber (match_operand:DI 1 "register_operand" "=D"))
17028 (clobber (reg:CC 17))]
17029 "TARGET_64BIT"
17030 "repnz{\;| }scasb"
17031 [(set_attr "type" "str")
17032 (set_attr "mode" "QI")
17033 (set_attr "prefix_rep" "1")])
17034
17035 ;; Peephole optimizations to clean up after cmpstr*. This should be
17036 ;; handled in combine, but it is not currently up to the task.
17037 ;; When used for their truth value, the cmpstr* expanders generate
17038 ;; code like this:
17039 ;;
17040 ;; repz cmpsb
17041 ;; seta %al
17042 ;; setb %dl
17043 ;; cmpb %al, %dl
17044 ;; jcc label
17045 ;;
17046 ;; The intermediate three instructions are unnecessary.
17047
17048 ;; This one handles cmpstr*_nz_1...
17049 (define_peephole2
17050 [(parallel[
17051 (set (reg:CC 17)
17052 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17053 (mem:BLK (match_operand 5 "register_operand" ""))))
17054 (use (match_operand 6 "register_operand" ""))
17055 (use (match_operand:SI 3 "immediate_operand" ""))
17056 (use (reg:SI 19))
17057 (clobber (match_operand 0 "register_operand" ""))
17058 (clobber (match_operand 1 "register_operand" ""))
17059 (clobber (match_operand 2 "register_operand" ""))])
17060 (set (match_operand:QI 7 "register_operand" "")
17061 (gtu:QI (reg:CC 17) (const_int 0)))
17062 (set (match_operand:QI 8 "register_operand" "")
17063 (ltu:QI (reg:CC 17) (const_int 0)))
17064 (set (reg 17)
17065 (compare (match_dup 7) (match_dup 8)))
17066 ]
17067 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17068 [(parallel[
17069 (set (reg:CC 17)
17070 (compare:CC (mem:BLK (match_dup 4))
17071 (mem:BLK (match_dup 5))))
17072 (use (match_dup 6))
17073 (use (match_dup 3))
17074 (use (reg:SI 19))
17075 (clobber (match_dup 0))
17076 (clobber (match_dup 1))
17077 (clobber (match_dup 2))])]
17078 "")
17079
17080 ;; ...and this one handles cmpstr*_1.
17081 (define_peephole2
17082 [(parallel[
17083 (set (reg:CC 17)
17084 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17085 (const_int 0))
17086 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17087 (mem:BLK (match_operand 5 "register_operand" "")))
17088 (const_int 0)))
17089 (use (match_operand:SI 3 "immediate_operand" ""))
17090 (use (reg:CC 17))
17091 (use (reg:SI 19))
17092 (clobber (match_operand 0 "register_operand" ""))
17093 (clobber (match_operand 1 "register_operand" ""))
17094 (clobber (match_operand 2 "register_operand" ""))])
17095 (set (match_operand:QI 7 "register_operand" "")
17096 (gtu:QI (reg:CC 17) (const_int 0)))
17097 (set (match_operand:QI 8 "register_operand" "")
17098 (ltu:QI (reg:CC 17) (const_int 0)))
17099 (set (reg 17)
17100 (compare (match_dup 7) (match_dup 8)))
17101 ]
17102 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17103 [(parallel[
17104 (set (reg:CC 17)
17105 (if_then_else:CC (ne (match_dup 6)
17106 (const_int 0))
17107 (compare:CC (mem:BLK (match_dup 4))
17108 (mem:BLK (match_dup 5)))
17109 (const_int 0)))
17110 (use (match_dup 3))
17111 (use (reg:CC 17))
17112 (use (reg:SI 19))
17113 (clobber (match_dup 0))
17114 (clobber (match_dup 1))
17115 (clobber (match_dup 2))])]
17116 "")
17117
17118
17119 \f
17120 ;; Conditional move instructions.
17121
17122 (define_expand "movdicc"
17123 [(set (match_operand:DI 0 "register_operand" "")
17124 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17125 (match_operand:DI 2 "general_operand" "")
17126 (match_operand:DI 3 "general_operand" "")))]
17127 "TARGET_64BIT"
17128 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17129
17130 (define_insn "x86_movdicc_0_m1_rex64"
17131 [(set (match_operand:DI 0 "register_operand" "=r")
17132 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17133 (const_int -1)
17134 (const_int 0)))
17135 (clobber (reg:CC 17))]
17136 "TARGET_64BIT"
17137 "sbb{q}\t%0, %0"
17138 ; Since we don't have the proper number of operands for an alu insn,
17139 ; fill in all the blanks.
17140 [(set_attr "type" "alu")
17141 (set_attr "pent_pair" "pu")
17142 (set_attr "memory" "none")
17143 (set_attr "imm_disp" "false")
17144 (set_attr "mode" "DI")
17145 (set_attr "length_immediate" "0")])
17146
17147 (define_insn "movdicc_c_rex64"
17148 [(set (match_operand:DI 0 "register_operand" "=r,r")
17149 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17150 [(reg 17) (const_int 0)])
17151 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17152 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17153 "TARGET_64BIT && TARGET_CMOVE
17154 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17155 "@
17156 cmov%O2%C1\t{%2, %0|%0, %2}
17157 cmov%O2%c1\t{%3, %0|%0, %3}"
17158 [(set_attr "type" "icmov")
17159 (set_attr "mode" "DI")])
17160
17161 (define_expand "movsicc"
17162 [(set (match_operand:SI 0 "register_operand" "")
17163 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17164 (match_operand:SI 2 "general_operand" "")
17165 (match_operand:SI 3 "general_operand" "")))]
17166 ""
17167 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17168
17169 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17170 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17171 ;; So just document what we're doing explicitly.
17172
17173 (define_insn "x86_movsicc_0_m1"
17174 [(set (match_operand:SI 0 "register_operand" "=r")
17175 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17176 (const_int -1)
17177 (const_int 0)))
17178 (clobber (reg:CC 17))]
17179 ""
17180 "sbb{l}\t%0, %0"
17181 ; Since we don't have the proper number of operands for an alu insn,
17182 ; fill in all the blanks.
17183 [(set_attr "type" "alu")
17184 (set_attr "pent_pair" "pu")
17185 (set_attr "memory" "none")
17186 (set_attr "imm_disp" "false")
17187 (set_attr "mode" "SI")
17188 (set_attr "length_immediate" "0")])
17189
17190 (define_insn "*movsicc_noc"
17191 [(set (match_operand:SI 0 "register_operand" "=r,r")
17192 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17193 [(reg 17) (const_int 0)])
17194 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17195 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17196 "TARGET_CMOVE
17197 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17198 "@
17199 cmov%O2%C1\t{%2, %0|%0, %2}
17200 cmov%O2%c1\t{%3, %0|%0, %3}"
17201 [(set_attr "type" "icmov")
17202 (set_attr "mode" "SI")])
17203
17204 (define_expand "movhicc"
17205 [(set (match_operand:HI 0 "register_operand" "")
17206 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17207 (match_operand:HI 2 "general_operand" "")
17208 (match_operand:HI 3 "general_operand" "")))]
17209 "TARGET_HIMODE_MATH"
17210 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17211
17212 (define_insn "*movhicc_noc"
17213 [(set (match_operand:HI 0 "register_operand" "=r,r")
17214 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17215 [(reg 17) (const_int 0)])
17216 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17217 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17218 "TARGET_CMOVE
17219 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17220 "@
17221 cmov%O2%C1\t{%2, %0|%0, %2}
17222 cmov%O2%c1\t{%3, %0|%0, %3}"
17223 [(set_attr "type" "icmov")
17224 (set_attr "mode" "HI")])
17225
17226 (define_expand "movqicc"
17227 [(set (match_operand:QI 0 "register_operand" "")
17228 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17229 (match_operand:QI 2 "general_operand" "")
17230 (match_operand:QI 3 "general_operand" "")))]
17231 "TARGET_QIMODE_MATH"
17232 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17233
17234 (define_insn_and_split "*movqicc_noc"
17235 [(set (match_operand:QI 0 "register_operand" "=r,r")
17236 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17237 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17238 (match_operand:QI 2 "register_operand" "r,0")
17239 (match_operand:QI 3 "register_operand" "0,r")))]
17240 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17241 "#"
17242 "&& reload_completed"
17243 [(set (match_dup 0)
17244 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17245 (match_dup 2)
17246 (match_dup 3)))]
17247 "operands[0] = gen_lowpart (SImode, operands[0]);
17248 operands[2] = gen_lowpart (SImode, operands[2]);
17249 operands[3] = gen_lowpart (SImode, operands[3]);"
17250 [(set_attr "type" "icmov")
17251 (set_attr "mode" "SI")])
17252
17253 (define_expand "movsfcc"
17254 [(set (match_operand:SF 0 "register_operand" "")
17255 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17256 (match_operand:SF 2 "register_operand" "")
17257 (match_operand:SF 3 "register_operand" "")))]
17258 "TARGET_CMOVE"
17259 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17260
17261 (define_insn "*movsfcc_1"
17262 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17263 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17264 [(reg 17) (const_int 0)])
17265 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17266 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17267 "TARGET_CMOVE
17268 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17269 "@
17270 fcmov%F1\t{%2, %0|%0, %2}
17271 fcmov%f1\t{%3, %0|%0, %3}
17272 cmov%O2%C1\t{%2, %0|%0, %2}
17273 cmov%O2%c1\t{%3, %0|%0, %3}"
17274 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17275 (set_attr "mode" "SF,SF,SI,SI")])
17276
17277 (define_expand "movdfcc"
17278 [(set (match_operand:DF 0 "register_operand" "")
17279 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17280 (match_operand:DF 2 "register_operand" "")
17281 (match_operand:DF 3 "register_operand" "")))]
17282 "TARGET_CMOVE"
17283 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17284
17285 (define_insn "*movdfcc_1"
17286 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17287 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17288 [(reg 17) (const_int 0)])
17289 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17290 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17291 "!TARGET_64BIT && TARGET_CMOVE
17292 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17293 "@
17294 fcmov%F1\t{%2, %0|%0, %2}
17295 fcmov%f1\t{%3, %0|%0, %3}
17296 #
17297 #"
17298 [(set_attr "type" "fcmov,fcmov,multi,multi")
17299 (set_attr "mode" "DF")])
17300
17301 (define_insn "*movdfcc_1_rex64"
17302 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17303 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17304 [(reg 17) (const_int 0)])
17305 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17306 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17307 "TARGET_64BIT && TARGET_CMOVE
17308 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17309 "@
17310 fcmov%F1\t{%2, %0|%0, %2}
17311 fcmov%f1\t{%3, %0|%0, %3}
17312 cmov%O2%C1\t{%2, %0|%0, %2}
17313 cmov%O2%c1\t{%3, %0|%0, %3}"
17314 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17315 (set_attr "mode" "DF")])
17316
17317 (define_split
17318 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17319 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17320 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17321 (match_operand:DF 2 "nonimmediate_operand" "")
17322 (match_operand:DF 3 "nonimmediate_operand" "")))]
17323 "!TARGET_64BIT && reload_completed"
17324 [(set (match_dup 2)
17325 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17326 (match_dup 5)
17327 (match_dup 7)))
17328 (set (match_dup 3)
17329 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17330 (match_dup 6)
17331 (match_dup 8)))]
17332 "split_di (operands+2, 1, operands+5, operands+6);
17333 split_di (operands+3, 1, operands+7, operands+8);
17334 split_di (operands, 1, operands+2, operands+3);")
17335
17336 (define_expand "movxfcc"
17337 [(set (match_operand:XF 0 "register_operand" "")
17338 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17339 (match_operand:XF 2 "register_operand" "")
17340 (match_operand:XF 3 "register_operand" "")))]
17341 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17342 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17343
17344 (define_expand "movtfcc"
17345 [(set (match_operand:TF 0 "register_operand" "")
17346 (if_then_else:TF (match_operand 1 "comparison_operator" "")
17347 (match_operand:TF 2 "register_operand" "")
17348 (match_operand:TF 3 "register_operand" "")))]
17349 "TARGET_CMOVE"
17350 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17351
17352 (define_insn "*movxfcc_1"
17353 [(set (match_operand:XF 0 "register_operand" "=f,f")
17354 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17355 [(reg 17) (const_int 0)])
17356 (match_operand:XF 2 "register_operand" "f,0")
17357 (match_operand:XF 3 "register_operand" "0,f")))]
17358 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17359 "@
17360 fcmov%F1\t{%2, %0|%0, %2}
17361 fcmov%f1\t{%3, %0|%0, %3}"
17362 [(set_attr "type" "fcmov")
17363 (set_attr "mode" "XF")])
17364
17365 (define_insn "*movtfcc_1"
17366 [(set (match_operand:TF 0 "register_operand" "=f,f")
17367 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
17368 [(reg 17) (const_int 0)])
17369 (match_operand:TF 2 "register_operand" "f,0")
17370 (match_operand:TF 3 "register_operand" "0,f")))]
17371 "TARGET_CMOVE"
17372 "@
17373 fcmov%F1\t{%2, %0|%0, %2}
17374 fcmov%f1\t{%3, %0|%0, %3}"
17375 [(set_attr "type" "fcmov")
17376 (set_attr "mode" "XF")])
17377
17378 (define_expand "minsf3"
17379 [(parallel [
17380 (set (match_operand:SF 0 "register_operand" "")
17381 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17382 (match_operand:SF 2 "nonimmediate_operand" ""))
17383 (match_dup 1)
17384 (match_dup 2)))
17385 (clobber (reg:CC 17))])]
17386 "TARGET_SSE"
17387 "")
17388
17389 (define_insn "*minsf"
17390 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17391 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17392 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17393 (match_dup 1)
17394 (match_dup 2)))
17395 (clobber (reg:CC 17))]
17396 "TARGET_SSE && TARGET_IEEE_FP"
17397 "#")
17398
17399 (define_insn "*minsf_nonieee"
17400 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17401 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17402 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17403 (match_dup 1)
17404 (match_dup 2)))
17405 (clobber (reg:CC 17))]
17406 "TARGET_SSE && !TARGET_IEEE_FP
17407 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17408 "#")
17409
17410 (define_split
17411 [(set (match_operand:SF 0 "register_operand" "")
17412 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17413 (match_operand:SF 2 "nonimmediate_operand" ""))
17414 (match_operand:SF 3 "register_operand" "")
17415 (match_operand:SF 4 "nonimmediate_operand" "")))
17416 (clobber (reg:CC 17))]
17417 "SSE_REG_P (operands[0]) && reload_completed
17418 && ((operands_match_p (operands[1], operands[3])
17419 && operands_match_p (operands[2], operands[4]))
17420 || (operands_match_p (operands[1], operands[4])
17421 && operands_match_p (operands[2], operands[3])))"
17422 [(set (match_dup 0)
17423 (if_then_else:SF (lt (match_dup 1)
17424 (match_dup 2))
17425 (match_dup 1)
17426 (match_dup 2)))])
17427
17428 ;; Conditional addition patterns
17429 (define_expand "addqicc"
17430 [(match_operand:QI 0 "register_operand" "")
17431 (match_operand 1 "comparison_operator" "")
17432 (match_operand:QI 2 "register_operand" "")
17433 (match_operand:QI 3 "const_int_operand" "")]
17434 ""
17435 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17436
17437 (define_expand "addhicc"
17438 [(match_operand:HI 0 "register_operand" "")
17439 (match_operand 1 "comparison_operator" "")
17440 (match_operand:HI 2 "register_operand" "")
17441 (match_operand:HI 3 "const_int_operand" "")]
17442 ""
17443 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17444
17445 (define_expand "addsicc"
17446 [(match_operand:SI 0 "register_operand" "")
17447 (match_operand 1 "comparison_operator" "")
17448 (match_operand:SI 2 "register_operand" "")
17449 (match_operand:SI 3 "const_int_operand" "")]
17450 ""
17451 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17452
17453 (define_expand "adddicc"
17454 [(match_operand:DI 0 "register_operand" "")
17455 (match_operand 1 "comparison_operator" "")
17456 (match_operand:DI 2 "register_operand" "")
17457 (match_operand:DI 3 "const_int_operand" "")]
17458 "TARGET_64BIT"
17459 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17460
17461 ;; We can't represent the LT test directly. Do this by swapping the operands.
17462
17463 (define_split
17464 [(set (match_operand:SF 0 "fp_register_operand" "")
17465 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17466 (match_operand:SF 2 "register_operand" ""))
17467 (match_operand:SF 3 "register_operand" "")
17468 (match_operand:SF 4 "register_operand" "")))
17469 (clobber (reg:CC 17))]
17470 "reload_completed
17471 && ((operands_match_p (operands[1], operands[3])
17472 && operands_match_p (operands[2], operands[4]))
17473 || (operands_match_p (operands[1], operands[4])
17474 && operands_match_p (operands[2], operands[3])))"
17475 [(set (reg:CCFP 17)
17476 (compare:CCFP (match_dup 2)
17477 (match_dup 1)))
17478 (set (match_dup 0)
17479 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17480 (match_dup 1)
17481 (match_dup 2)))])
17482
17483 (define_insn "*minsf_sse"
17484 [(set (match_operand:SF 0 "register_operand" "=x")
17485 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17486 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17487 (match_dup 1)
17488 (match_dup 2)))]
17489 "TARGET_SSE && reload_completed"
17490 "minss\t{%2, %0|%0, %2}"
17491 [(set_attr "type" "sse")
17492 (set_attr "mode" "SF")])
17493
17494 (define_expand "mindf3"
17495 [(parallel [
17496 (set (match_operand:DF 0 "register_operand" "")
17497 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17498 (match_operand:DF 2 "nonimmediate_operand" ""))
17499 (match_dup 1)
17500 (match_dup 2)))
17501 (clobber (reg:CC 17))])]
17502 "TARGET_SSE2 && TARGET_SSE_MATH"
17503 "#")
17504
17505 (define_insn "*mindf"
17506 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17507 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17508 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17509 (match_dup 1)
17510 (match_dup 2)))
17511 (clobber (reg:CC 17))]
17512 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17513 "#")
17514
17515 (define_insn "*mindf_nonieee"
17516 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17517 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17518 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17519 (match_dup 1)
17520 (match_dup 2)))
17521 (clobber (reg:CC 17))]
17522 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17523 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17524 "#")
17525
17526 (define_split
17527 [(set (match_operand:DF 0 "register_operand" "")
17528 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17529 (match_operand:DF 2 "nonimmediate_operand" ""))
17530 (match_operand:DF 3 "register_operand" "")
17531 (match_operand:DF 4 "nonimmediate_operand" "")))
17532 (clobber (reg:CC 17))]
17533 "SSE_REG_P (operands[0]) && reload_completed
17534 && ((operands_match_p (operands[1], operands[3])
17535 && operands_match_p (operands[2], operands[4]))
17536 || (operands_match_p (operands[1], operands[4])
17537 && operands_match_p (operands[2], operands[3])))"
17538 [(set (match_dup 0)
17539 (if_then_else:DF (lt (match_dup 1)
17540 (match_dup 2))
17541 (match_dup 1)
17542 (match_dup 2)))])
17543
17544 ;; We can't represent the LT test directly. Do this by swapping the operands.
17545 (define_split
17546 [(set (match_operand:DF 0 "fp_register_operand" "")
17547 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17548 (match_operand:DF 2 "register_operand" ""))
17549 (match_operand:DF 3 "register_operand" "")
17550 (match_operand:DF 4 "register_operand" "")))
17551 (clobber (reg:CC 17))]
17552 "reload_completed
17553 && ((operands_match_p (operands[1], operands[3])
17554 && operands_match_p (operands[2], operands[4]))
17555 || (operands_match_p (operands[1], operands[4])
17556 && operands_match_p (operands[2], operands[3])))"
17557 [(set (reg:CCFP 17)
17558 (compare:CCFP (match_dup 2)
17559 (match_dup 2)))
17560 (set (match_dup 0)
17561 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17562 (match_dup 1)
17563 (match_dup 2)))])
17564
17565 (define_insn "*mindf_sse"
17566 [(set (match_operand:DF 0 "register_operand" "=Y")
17567 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17568 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17569 (match_dup 1)
17570 (match_dup 2)))]
17571 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17572 "minsd\t{%2, %0|%0, %2}"
17573 [(set_attr "type" "sse")
17574 (set_attr "mode" "DF")])
17575
17576 (define_expand "maxsf3"
17577 [(parallel [
17578 (set (match_operand:SF 0 "register_operand" "")
17579 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17580 (match_operand:SF 2 "nonimmediate_operand" ""))
17581 (match_dup 1)
17582 (match_dup 2)))
17583 (clobber (reg:CC 17))])]
17584 "TARGET_SSE"
17585 "#")
17586
17587 (define_insn "*maxsf"
17588 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17589 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17590 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17591 (match_dup 1)
17592 (match_dup 2)))
17593 (clobber (reg:CC 17))]
17594 "TARGET_SSE && TARGET_IEEE_FP"
17595 "#")
17596
17597 (define_insn "*maxsf_nonieee"
17598 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17599 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17600 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17601 (match_dup 1)
17602 (match_dup 2)))
17603 (clobber (reg:CC 17))]
17604 "TARGET_SSE && !TARGET_IEEE_FP
17605 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17606 "#")
17607
17608 (define_split
17609 [(set (match_operand:SF 0 "register_operand" "")
17610 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17611 (match_operand:SF 2 "nonimmediate_operand" ""))
17612 (match_operand:SF 3 "register_operand" "")
17613 (match_operand:SF 4 "nonimmediate_operand" "")))
17614 (clobber (reg:CC 17))]
17615 "SSE_REG_P (operands[0]) && reload_completed
17616 && ((operands_match_p (operands[1], operands[3])
17617 && operands_match_p (operands[2], operands[4]))
17618 || (operands_match_p (operands[1], operands[4])
17619 && operands_match_p (operands[2], operands[3])))"
17620 [(set (match_dup 0)
17621 (if_then_else:SF (gt (match_dup 1)
17622 (match_dup 2))
17623 (match_dup 1)
17624 (match_dup 2)))])
17625
17626 (define_split
17627 [(set (match_operand:SF 0 "fp_register_operand" "")
17628 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17629 (match_operand:SF 2 "register_operand" ""))
17630 (match_operand:SF 3 "register_operand" "")
17631 (match_operand:SF 4 "register_operand" "")))
17632 (clobber (reg:CC 17))]
17633 "reload_completed
17634 && ((operands_match_p (operands[1], operands[3])
17635 && operands_match_p (operands[2], operands[4]))
17636 || (operands_match_p (operands[1], operands[4])
17637 && operands_match_p (operands[2], operands[3])))"
17638 [(set (reg:CCFP 17)
17639 (compare:CCFP (match_dup 1)
17640 (match_dup 2)))
17641 (set (match_dup 0)
17642 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17643 (match_dup 1)
17644 (match_dup 2)))])
17645
17646 (define_insn "*maxsf_sse"
17647 [(set (match_operand:SF 0 "register_operand" "=x")
17648 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17649 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17650 (match_dup 1)
17651 (match_dup 2)))]
17652 "TARGET_SSE && reload_completed"
17653 "maxss\t{%2, %0|%0, %2}"
17654 [(set_attr "type" "sse")
17655 (set_attr "mode" "SF")])
17656
17657 (define_expand "maxdf3"
17658 [(parallel [
17659 (set (match_operand:DF 0 "register_operand" "")
17660 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17661 (match_operand:DF 2 "nonimmediate_operand" ""))
17662 (match_dup 1)
17663 (match_dup 2)))
17664 (clobber (reg:CC 17))])]
17665 "TARGET_SSE2 && TARGET_SSE_MATH"
17666 "#")
17667
17668 (define_insn "*maxdf"
17669 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17670 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17671 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17672 (match_dup 1)
17673 (match_dup 2)))
17674 (clobber (reg:CC 17))]
17675 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17676 "#")
17677
17678 (define_insn "*maxdf_nonieee"
17679 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17680 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17681 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17682 (match_dup 1)
17683 (match_dup 2)))
17684 (clobber (reg:CC 17))]
17685 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17686 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17687 "#")
17688
17689 (define_split
17690 [(set (match_operand:DF 0 "register_operand" "")
17691 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17692 (match_operand:DF 2 "nonimmediate_operand" ""))
17693 (match_operand:DF 3 "register_operand" "")
17694 (match_operand:DF 4 "nonimmediate_operand" "")))
17695 (clobber (reg:CC 17))]
17696 "SSE_REG_P (operands[0]) && reload_completed
17697 && ((operands_match_p (operands[1], operands[3])
17698 && operands_match_p (operands[2], operands[4]))
17699 || (operands_match_p (operands[1], operands[4])
17700 && operands_match_p (operands[2], operands[3])))"
17701 [(set (match_dup 0)
17702 (if_then_else:DF (gt (match_dup 1)
17703 (match_dup 2))
17704 (match_dup 1)
17705 (match_dup 2)))])
17706
17707 (define_split
17708 [(set (match_operand:DF 0 "fp_register_operand" "")
17709 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17710 (match_operand:DF 2 "register_operand" ""))
17711 (match_operand:DF 3 "register_operand" "")
17712 (match_operand:DF 4 "register_operand" "")))
17713 (clobber (reg:CC 17))]
17714 "reload_completed
17715 && ((operands_match_p (operands[1], operands[3])
17716 && operands_match_p (operands[2], operands[4]))
17717 || (operands_match_p (operands[1], operands[4])
17718 && operands_match_p (operands[2], operands[3])))"
17719 [(set (reg:CCFP 17)
17720 (compare:CCFP (match_dup 1)
17721 (match_dup 2)))
17722 (set (match_dup 0)
17723 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17724 (match_dup 1)
17725 (match_dup 2)))])
17726
17727 (define_insn "*maxdf_sse"
17728 [(set (match_operand:DF 0 "register_operand" "=Y")
17729 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17730 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17731 (match_dup 1)
17732 (match_dup 2)))]
17733 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17734 "maxsd\t{%2, %0|%0, %2}"
17735 [(set_attr "type" "sse")
17736 (set_attr "mode" "DF")])
17737 \f
17738 ;; Misc patterns (?)
17739
17740 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17741 ;; Otherwise there will be nothing to keep
17742 ;;
17743 ;; [(set (reg ebp) (reg esp))]
17744 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17745 ;; (clobber (eflags)]
17746 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17747 ;;
17748 ;; in proper program order.
17749 (define_expand "pro_epilogue_adjust_stack"
17750 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
17751 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17752 (match_operand:SI 2 "immediate_operand" "i,i")))
17753 (clobber (reg:CC 17))
17754 (clobber (mem:BLK (scratch)))])]
17755 ""
17756 {
17757 if (TARGET_64BIT)
17758 {
17759 emit_insn (gen_pro_epilogue_adjust_stack_rex64
17760 (operands[0], operands[1], operands[2]));
17761 DONE;
17762 }
17763 })
17764
17765 (define_insn "*pro_epilogue_adjust_stack_1"
17766 [(set (match_operand:SI 0 "register_operand" "=r,r")
17767 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17768 (match_operand:SI 2 "immediate_operand" "i,i")))
17769 (clobber (reg:CC 17))
17770 (clobber (mem:BLK (scratch)))]
17771 "!TARGET_64BIT"
17772 {
17773 switch (get_attr_type (insn))
17774 {
17775 case TYPE_IMOV:
17776 return "mov{l}\t{%1, %0|%0, %1}";
17777
17778 case TYPE_ALU:
17779 if (GET_CODE (operands[2]) == CONST_INT
17780 && (INTVAL (operands[2]) == 128
17781 || (INTVAL (operands[2]) < 0
17782 && INTVAL (operands[2]) != -128)))
17783 {
17784 operands[2] = GEN_INT (-INTVAL (operands[2]));
17785 return "sub{l}\t{%2, %0|%0, %2}";
17786 }
17787 return "add{l}\t{%2, %0|%0, %2}";
17788
17789 case TYPE_LEA:
17790 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17791 return "lea{l}\t{%a2, %0|%0, %a2}";
17792
17793 default:
17794 abort ();
17795 }
17796 }
17797 [(set (attr "type")
17798 (cond [(eq_attr "alternative" "0")
17799 (const_string "alu")
17800 (match_operand:SI 2 "const0_operand" "")
17801 (const_string "imov")
17802 ]
17803 (const_string "lea")))
17804 (set_attr "mode" "SI")])
17805
17806 (define_insn "pro_epilogue_adjust_stack_rex64"
17807 [(set (match_operand:DI 0 "register_operand" "=r,r")
17808 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17809 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17810 (clobber (reg:CC 17))
17811 (clobber (mem:BLK (scratch)))]
17812 "TARGET_64BIT"
17813 {
17814 switch (get_attr_type (insn))
17815 {
17816 case TYPE_IMOV:
17817 return "mov{q}\t{%1, %0|%0, %1}";
17818
17819 case TYPE_ALU:
17820 if (GET_CODE (operands[2]) == CONST_INT
17821 && (INTVAL (operands[2]) == 128
17822 || (INTVAL (operands[2]) < 0
17823 && INTVAL (operands[2]) != -128)))
17824 {
17825 operands[2] = GEN_INT (-INTVAL (operands[2]));
17826 return "sub{q}\t{%2, %0|%0, %2}";
17827 }
17828 return "add{q}\t{%2, %0|%0, %2}";
17829
17830 case TYPE_LEA:
17831 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17832 return "lea{q}\t{%a2, %0|%0, %a2}";
17833
17834 default:
17835 abort ();
17836 }
17837 }
17838 [(set (attr "type")
17839 (cond [(eq_attr "alternative" "0")
17840 (const_string "alu")
17841 (match_operand:DI 2 "const0_operand" "")
17842 (const_string "imov")
17843 ]
17844 (const_string "lea")))
17845 (set_attr "mode" "DI")])
17846
17847
17848 ;; Placeholder for the conditional moves. This one is split either to SSE
17849 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17850 ;; fact is that compares supported by the cmp??ss instructions are exactly
17851 ;; swapped of those supported by cmove sequence.
17852 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17853 ;; supported by i387 comparisons and we do need to emit two conditional moves
17854 ;; in tandem.
17855
17856 (define_insn "sse_movsfcc"
17857 [(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")
17858 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17859 [(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")
17860 (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")])
17861 (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")
17862 (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")))
17863 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17864 (clobber (reg:CC 17))]
17865 "TARGET_SSE
17866 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17867 /* Avoid combine from being smart and converting min/max
17868 instruction patterns into conditional moves. */
17869 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17870 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17871 || !rtx_equal_p (operands[4], operands[2])
17872 || !rtx_equal_p (operands[5], operands[3]))
17873 && (!TARGET_IEEE_FP
17874 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17875 "#")
17876
17877 (define_insn "sse_movsfcc_eq"
17878 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17879 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17880 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17881 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17882 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17883 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17884 (clobber (reg:CC 17))]
17885 "TARGET_SSE
17886 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17887 "#")
17888
17889 (define_insn "sse_movdfcc"
17890 [(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")
17891 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17892 [(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")
17893 (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")])
17894 (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")
17895 (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")))
17896 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17897 (clobber (reg:CC 17))]
17898 "TARGET_SSE2
17899 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17900 /* Avoid combine from being smart and converting min/max
17901 instruction patterns into conditional moves. */
17902 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17903 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17904 || !rtx_equal_p (operands[4], operands[2])
17905 || !rtx_equal_p (operands[5], operands[3]))
17906 && (!TARGET_IEEE_FP
17907 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17908 "#")
17909
17910 (define_insn "sse_movdfcc_eq"
17911 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17912 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17913 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17914 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17915 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17916 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17917 (clobber (reg:CC 17))]
17918 "TARGET_SSE
17919 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17920 "#")
17921
17922 ;; For non-sse moves just expand the usual cmove sequence.
17923 (define_split
17924 [(set (match_operand 0 "register_operand" "")
17925 (if_then_else (match_operator 1 "comparison_operator"
17926 [(match_operand 4 "nonimmediate_operand" "")
17927 (match_operand 5 "register_operand" "")])
17928 (match_operand 2 "nonimmediate_operand" "")
17929 (match_operand 3 "nonimmediate_operand" "")))
17930 (clobber (match_operand 6 "" ""))
17931 (clobber (reg:CC 17))]
17932 "!SSE_REG_P (operands[0]) && reload_completed
17933 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17934 [(const_int 0)]
17935 {
17936 ix86_compare_op0 = operands[5];
17937 ix86_compare_op1 = operands[4];
17938 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17939 VOIDmode, operands[5], operands[4]);
17940 ix86_expand_fp_movcc (operands);
17941 DONE;
17942 })
17943
17944 ;; Split SSE based conditional move into sequence:
17945 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17946 ;; and op2, op0 - zero op2 if comparison was false
17947 ;; nand op0, op3 - load op3 to op0 if comparison was false
17948 ;; or op2, op0 - get the nonzero one into the result.
17949 (define_split
17950 [(set (match_operand 0 "register_operand" "")
17951 (if_then_else (match_operator 1 "sse_comparison_operator"
17952 [(match_operand 4 "register_operand" "")
17953 (match_operand 5 "nonimmediate_operand" "")])
17954 (match_operand 2 "register_operand" "")
17955 (match_operand 3 "register_operand" "")))
17956 (clobber (match_operand 6 "" ""))
17957 (clobber (reg:CC 17))]
17958 "SSE_REG_P (operands[0]) && reload_completed"
17959 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17960 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17961 (subreg:TI (match_dup 4) 0)))
17962 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17963 (subreg:TI (match_dup 3) 0)))
17964 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17965 (subreg:TI (match_dup 7) 0)))]
17966 {
17967 if (GET_MODE (operands[2]) == DFmode
17968 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17969 {
17970 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17971 emit_insn (gen_sse2_unpcklpd (op, op, op));
17972 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17973 emit_insn (gen_sse2_unpcklpd (op, op, op));
17974 }
17975
17976 /* If op2 == op3, op3 would be clobbered before it is used. */
17977 if (operands_match_p (operands[2], operands[3]))
17978 {
17979 emit_move_insn (operands[0], operands[2]);
17980 DONE;
17981 }
17982
17983 PUT_MODE (operands[1], GET_MODE (operands[0]));
17984 if (operands_match_p (operands[0], operands[4]))
17985 operands[6] = operands[4], operands[7] = operands[2];
17986 else
17987 operands[6] = operands[2], operands[7] = operands[4];
17988 })
17989
17990 ;; Special case of conditional move we can handle effectively.
17991 ;; Do not brother with the integer/floating point case, since these are
17992 ;; bot considerably slower, unlike in the generic case.
17993 (define_insn "*sse_movsfcc_const0_1"
17994 [(set (match_operand:SF 0 "register_operand" "=&x")
17995 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17996 [(match_operand:SF 4 "register_operand" "0")
17997 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17998 (match_operand:SF 2 "register_operand" "x")
17999 (match_operand:SF 3 "const0_operand" "X")))]
18000 "TARGET_SSE"
18001 "#")
18002
18003 (define_insn "*sse_movsfcc_const0_2"
18004 [(set (match_operand:SF 0 "register_operand" "=&x")
18005 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18006 [(match_operand:SF 4 "register_operand" "0")
18007 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18008 (match_operand:SF 2 "const0_operand" "X")
18009 (match_operand:SF 3 "register_operand" "x")))]
18010 "TARGET_SSE"
18011 "#")
18012
18013 (define_insn "*sse_movsfcc_const0_3"
18014 [(set (match_operand:SF 0 "register_operand" "=&x")
18015 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18016 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18017 (match_operand:SF 5 "register_operand" "0")])
18018 (match_operand:SF 2 "register_operand" "x")
18019 (match_operand:SF 3 "const0_operand" "X")))]
18020 "TARGET_SSE"
18021 "#")
18022
18023 (define_insn "*sse_movsfcc_const0_4"
18024 [(set (match_operand:SF 0 "register_operand" "=&x")
18025 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18026 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18027 (match_operand:SF 5 "register_operand" "0")])
18028 (match_operand:SF 2 "const0_operand" "X")
18029 (match_operand:SF 3 "register_operand" "x")))]
18030 "TARGET_SSE"
18031 "#")
18032
18033 (define_insn "*sse_movdfcc_const0_1"
18034 [(set (match_operand:DF 0 "register_operand" "=&Y")
18035 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18036 [(match_operand:DF 4 "register_operand" "0")
18037 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18038 (match_operand:DF 2 "register_operand" "Y")
18039 (match_operand:DF 3 "const0_operand" "X")))]
18040 "TARGET_SSE2"
18041 "#")
18042
18043 (define_insn "*sse_movdfcc_const0_2"
18044 [(set (match_operand:DF 0 "register_operand" "=&Y")
18045 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18046 [(match_operand:DF 4 "register_operand" "0")
18047 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18048 (match_operand:DF 2 "const0_operand" "X")
18049 (match_operand:DF 3 "register_operand" "Y")))]
18050 "TARGET_SSE2"
18051 "#")
18052
18053 (define_insn "*sse_movdfcc_const0_3"
18054 [(set (match_operand:DF 0 "register_operand" "=&Y")
18055 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18056 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18057 (match_operand:DF 5 "register_operand" "0")])
18058 (match_operand:DF 2 "register_operand" "Y")
18059 (match_operand:DF 3 "const0_operand" "X")))]
18060 "TARGET_SSE2"
18061 "#")
18062
18063 (define_insn "*sse_movdfcc_const0_4"
18064 [(set (match_operand:DF 0 "register_operand" "=&Y")
18065 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18066 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18067 (match_operand:DF 5 "register_operand" "0")])
18068 (match_operand:DF 2 "const0_operand" "X")
18069 (match_operand:DF 3 "register_operand" "Y")))]
18070 "TARGET_SSE2"
18071 "#")
18072
18073 (define_split
18074 [(set (match_operand 0 "register_operand" "")
18075 (if_then_else (match_operator 1 "comparison_operator"
18076 [(match_operand 4 "nonimmediate_operand" "")
18077 (match_operand 5 "nonimmediate_operand" "")])
18078 (match_operand 2 "nonmemory_operand" "")
18079 (match_operand 3 "nonmemory_operand" "")))]
18080 "SSE_REG_P (operands[0]) && reload_completed
18081 && (const0_operand (operands[2], GET_MODE (operands[0]))
18082 || const0_operand (operands[3], GET_MODE (operands[0])))"
18083 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18084 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
18085 (match_dup 7)))]
18086 {
18087 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18088 && GET_MODE (operands[2]) == DFmode)
18089 {
18090 if (REG_P (operands[2]))
18091 {
18092 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18093 emit_insn (gen_sse2_unpcklpd (op, op, op));
18094 }
18095 if (REG_P (operands[3]))
18096 {
18097 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18098 emit_insn (gen_sse2_unpcklpd (op, op, op));
18099 }
18100 }
18101 PUT_MODE (operands[1], GET_MODE (operands[0]));
18102 if (!sse_comparison_operator (operands[1], VOIDmode)
18103 || !rtx_equal_p (operands[0], operands[4]))
18104 {
18105 rtx tmp = operands[5];
18106 operands[5] = operands[4];
18107 operands[4] = tmp;
18108 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18109 }
18110 if (!rtx_equal_p (operands[0], operands[4]))
18111 abort ();
18112 if (const0_operand (operands[2], GET_MODE (operands[0])))
18113 {
18114 operands[7] = operands[3];
18115 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
18116 0));
18117 }
18118 else
18119 {
18120 operands[7] = operands[2];
18121 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
18122 }
18123 operands[7] = simplify_gen_subreg (TImode, operands[7],
18124 GET_MODE (operands[7]), 0);
18125 })
18126
18127 (define_expand "allocate_stack_worker"
18128 [(match_operand:SI 0 "register_operand" "")]
18129 "TARGET_STACK_PROBE"
18130 {
18131 if (TARGET_64BIT)
18132 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18133 else
18134 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18135 DONE;
18136 })
18137
18138 (define_insn "allocate_stack_worker_1"
18139 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18140 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
18141 (clobber (match_dup 0))
18142 (clobber (reg:CC 17))]
18143 "!TARGET_64BIT && TARGET_STACK_PROBE"
18144 "call\t__alloca"
18145 [(set_attr "type" "multi")
18146 (set_attr "length" "5")])
18147
18148 (define_insn "allocate_stack_worker_rex64"
18149 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18150 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
18151 (clobber (match_dup 0))
18152 (clobber (reg:CC 17))]
18153 "TARGET_64BIT && TARGET_STACK_PROBE"
18154 "call\t__alloca"
18155 [(set_attr "type" "multi")
18156 (set_attr "length" "5")])
18157
18158 (define_expand "allocate_stack"
18159 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18160 (minus:SI (reg:SI 7)
18161 (match_operand:SI 1 "general_operand" "")))
18162 (clobber (reg:CC 17))])
18163 (parallel [(set (reg:SI 7)
18164 (minus:SI (reg:SI 7) (match_dup 1)))
18165 (clobber (reg:CC 17))])]
18166 "TARGET_STACK_PROBE"
18167 {
18168 #ifdef CHECK_STACK_LIMIT
18169 if (GET_CODE (operands[1]) == CONST_INT
18170 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18171 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18172 operands[1]));
18173 else
18174 #endif
18175 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18176 operands[1])));
18177
18178 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18179 DONE;
18180 })
18181
18182 (define_expand "builtin_setjmp_receiver"
18183 [(label_ref (match_operand 0 "" ""))]
18184 "!TARGET_64BIT && flag_pic"
18185 {
18186 emit_insn (gen_set_got (pic_offset_table_rtx));
18187 DONE;
18188 })
18189 \f
18190 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18191
18192 (define_split
18193 [(set (match_operand 0 "register_operand" "")
18194 (match_operator 3 "promotable_binary_operator"
18195 [(match_operand 1 "register_operand" "")
18196 (match_operand 2 "aligned_operand" "")]))
18197 (clobber (reg:CC 17))]
18198 "! TARGET_PARTIAL_REG_STALL && reload_completed
18199 && ((GET_MODE (operands[0]) == HImode
18200 && ((!optimize_size && !TARGET_FAST_PREFIX)
18201 || GET_CODE (operands[2]) != CONST_INT
18202 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18203 || (GET_MODE (operands[0]) == QImode
18204 && (TARGET_PROMOTE_QImode || optimize_size)))"
18205 [(parallel [(set (match_dup 0)
18206 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18207 (clobber (reg:CC 17))])]
18208 "operands[0] = gen_lowpart (SImode, operands[0]);
18209 operands[1] = gen_lowpart (SImode, operands[1]);
18210 if (GET_CODE (operands[3]) != ASHIFT)
18211 operands[2] = gen_lowpart (SImode, operands[2]);
18212 PUT_MODE (operands[3], SImode);")
18213
18214 ; Promote the QImode tests, as i386 has encoding of the AND
18215 ; instruction with 32-bit sign-extended immediate and thus the
18216 ; instruction size is unchanged, except in the %eax case for
18217 ; which it is increased by one byte, hence the ! optimize_size.
18218 (define_split
18219 [(set (reg 17)
18220 (compare (and (match_operand 1 "aligned_operand" "")
18221 (match_operand 2 "const_int_operand" ""))
18222 (const_int 0)))
18223 (set (match_operand 0 "register_operand" "")
18224 (and (match_dup 1) (match_dup 2)))]
18225 "! TARGET_PARTIAL_REG_STALL && reload_completed
18226 /* Ensure that the operand will remain sign-extended immediate. */
18227 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18228 && ! optimize_size
18229 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18230 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18231 [(parallel [(set (reg:CCNO 17)
18232 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18233 (const_int 0)))
18234 (set (match_dup 0)
18235 (and:SI (match_dup 1) (match_dup 2)))])]
18236 "operands[2]
18237 = gen_int_mode (INTVAL (operands[2])
18238 & GET_MODE_MASK (GET_MODE (operands[0])),
18239 SImode);
18240 operands[0] = gen_lowpart (SImode, operands[0]);
18241 operands[1] = gen_lowpart (SImode, operands[1]);")
18242
18243 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18244 ; the TEST instruction with 32-bit sign-extended immediate and thus
18245 ; the instruction size would at least double, which is not what we
18246 ; want even with ! optimize_size.
18247 (define_split
18248 [(set (reg 17)
18249 (compare (and (match_operand:HI 0 "aligned_operand" "")
18250 (match_operand:HI 1 "const_int_operand" ""))
18251 (const_int 0)))]
18252 "! TARGET_PARTIAL_REG_STALL && reload_completed
18253 /* Ensure that the operand will remain sign-extended immediate. */
18254 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18255 && ! TARGET_FAST_PREFIX
18256 && ! optimize_size"
18257 [(set (reg:CCNO 17)
18258 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18259 (const_int 0)))]
18260 "operands[1]
18261 = gen_int_mode (INTVAL (operands[1])
18262 & GET_MODE_MASK (GET_MODE (operands[0])),
18263 SImode);
18264 operands[0] = gen_lowpart (SImode, operands[0]);")
18265
18266 (define_split
18267 [(set (match_operand 0 "register_operand" "")
18268 (neg (match_operand 1 "register_operand" "")))
18269 (clobber (reg:CC 17))]
18270 "! TARGET_PARTIAL_REG_STALL && reload_completed
18271 && (GET_MODE (operands[0]) == HImode
18272 || (GET_MODE (operands[0]) == QImode
18273 && (TARGET_PROMOTE_QImode || optimize_size)))"
18274 [(parallel [(set (match_dup 0)
18275 (neg:SI (match_dup 1)))
18276 (clobber (reg:CC 17))])]
18277 "operands[0] = gen_lowpart (SImode, operands[0]);
18278 operands[1] = gen_lowpart (SImode, operands[1]);")
18279
18280 (define_split
18281 [(set (match_operand 0 "register_operand" "")
18282 (not (match_operand 1 "register_operand" "")))]
18283 "! TARGET_PARTIAL_REG_STALL && reload_completed
18284 && (GET_MODE (operands[0]) == HImode
18285 || (GET_MODE (operands[0]) == QImode
18286 && (TARGET_PROMOTE_QImode || optimize_size)))"
18287 [(set (match_dup 0)
18288 (not:SI (match_dup 1)))]
18289 "operands[0] = gen_lowpart (SImode, operands[0]);
18290 operands[1] = gen_lowpart (SImode, operands[1]);")
18291
18292 (define_split
18293 [(set (match_operand 0 "register_operand" "")
18294 (if_then_else (match_operator 1 "comparison_operator"
18295 [(reg 17) (const_int 0)])
18296 (match_operand 2 "register_operand" "")
18297 (match_operand 3 "register_operand" "")))]
18298 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18299 && (GET_MODE (operands[0]) == HImode
18300 || (GET_MODE (operands[0]) == QImode
18301 && (TARGET_PROMOTE_QImode || optimize_size)))"
18302 [(set (match_dup 0)
18303 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18304 "operands[0] = gen_lowpart (SImode, operands[0]);
18305 operands[2] = gen_lowpart (SImode, operands[2]);
18306 operands[3] = gen_lowpart (SImode, operands[3]);")
18307
18308 \f
18309 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18310 ;; transform a complex memory operation into two memory to register operations.
18311
18312 ;; Don't push memory operands
18313 (define_peephole2
18314 [(set (match_operand:SI 0 "push_operand" "")
18315 (match_operand:SI 1 "memory_operand" ""))
18316 (match_scratch:SI 2 "r")]
18317 "! optimize_size && ! TARGET_PUSH_MEMORY"
18318 [(set (match_dup 2) (match_dup 1))
18319 (set (match_dup 0) (match_dup 2))]
18320 "")
18321
18322 (define_peephole2
18323 [(set (match_operand:DI 0 "push_operand" "")
18324 (match_operand:DI 1 "memory_operand" ""))
18325 (match_scratch:DI 2 "r")]
18326 "! optimize_size && ! TARGET_PUSH_MEMORY"
18327 [(set (match_dup 2) (match_dup 1))
18328 (set (match_dup 0) (match_dup 2))]
18329 "")
18330
18331 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18332 ;; SImode pushes.
18333 (define_peephole2
18334 [(set (match_operand:SF 0 "push_operand" "")
18335 (match_operand:SF 1 "memory_operand" ""))
18336 (match_scratch:SF 2 "r")]
18337 "! optimize_size && ! TARGET_PUSH_MEMORY"
18338 [(set (match_dup 2) (match_dup 1))
18339 (set (match_dup 0) (match_dup 2))]
18340 "")
18341
18342 (define_peephole2
18343 [(set (match_operand:HI 0 "push_operand" "")
18344 (match_operand:HI 1 "memory_operand" ""))
18345 (match_scratch:HI 2 "r")]
18346 "! optimize_size && ! TARGET_PUSH_MEMORY"
18347 [(set (match_dup 2) (match_dup 1))
18348 (set (match_dup 0) (match_dup 2))]
18349 "")
18350
18351 (define_peephole2
18352 [(set (match_operand:QI 0 "push_operand" "")
18353 (match_operand:QI 1 "memory_operand" ""))
18354 (match_scratch:QI 2 "q")]
18355 "! optimize_size && ! TARGET_PUSH_MEMORY"
18356 [(set (match_dup 2) (match_dup 1))
18357 (set (match_dup 0) (match_dup 2))]
18358 "")
18359
18360 ;; Don't move an immediate directly to memory when the instruction
18361 ;; gets too big.
18362 (define_peephole2
18363 [(match_scratch:SI 1 "r")
18364 (set (match_operand:SI 0 "memory_operand" "")
18365 (const_int 0))]
18366 "! optimize_size
18367 && ! TARGET_USE_MOV0
18368 && TARGET_SPLIT_LONG_MOVES
18369 && get_attr_length (insn) >= ix86_cost->large_insn
18370 && peep2_regno_dead_p (0, FLAGS_REG)"
18371 [(parallel [(set (match_dup 1) (const_int 0))
18372 (clobber (reg:CC 17))])
18373 (set (match_dup 0) (match_dup 1))]
18374 "")
18375
18376 (define_peephole2
18377 [(match_scratch:HI 1 "r")
18378 (set (match_operand:HI 0 "memory_operand" "")
18379 (const_int 0))]
18380 "! optimize_size
18381 && ! TARGET_USE_MOV0
18382 && TARGET_SPLIT_LONG_MOVES
18383 && get_attr_length (insn) >= ix86_cost->large_insn
18384 && peep2_regno_dead_p (0, FLAGS_REG)"
18385 [(parallel [(set (match_dup 2) (const_int 0))
18386 (clobber (reg:CC 17))])
18387 (set (match_dup 0) (match_dup 1))]
18388 "operands[2] = gen_lowpart (SImode, operands[1]);")
18389
18390 (define_peephole2
18391 [(match_scratch:QI 1 "q")
18392 (set (match_operand:QI 0 "memory_operand" "")
18393 (const_int 0))]
18394 "! optimize_size
18395 && ! TARGET_USE_MOV0
18396 && TARGET_SPLIT_LONG_MOVES
18397 && get_attr_length (insn) >= ix86_cost->large_insn
18398 && peep2_regno_dead_p (0, FLAGS_REG)"
18399 [(parallel [(set (match_dup 2) (const_int 0))
18400 (clobber (reg:CC 17))])
18401 (set (match_dup 0) (match_dup 1))]
18402 "operands[2] = gen_lowpart (SImode, operands[1]);")
18403
18404 (define_peephole2
18405 [(match_scratch:SI 2 "r")
18406 (set (match_operand:SI 0 "memory_operand" "")
18407 (match_operand:SI 1 "immediate_operand" ""))]
18408 "! optimize_size
18409 && get_attr_length (insn) >= ix86_cost->large_insn
18410 && TARGET_SPLIT_LONG_MOVES"
18411 [(set (match_dup 2) (match_dup 1))
18412 (set (match_dup 0) (match_dup 2))]
18413 "")
18414
18415 (define_peephole2
18416 [(match_scratch:HI 2 "r")
18417 (set (match_operand:HI 0 "memory_operand" "")
18418 (match_operand:HI 1 "immediate_operand" ""))]
18419 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18420 && TARGET_SPLIT_LONG_MOVES"
18421 [(set (match_dup 2) (match_dup 1))
18422 (set (match_dup 0) (match_dup 2))]
18423 "")
18424
18425 (define_peephole2
18426 [(match_scratch:QI 2 "q")
18427 (set (match_operand:QI 0 "memory_operand" "")
18428 (match_operand:QI 1 "immediate_operand" ""))]
18429 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18430 && TARGET_SPLIT_LONG_MOVES"
18431 [(set (match_dup 2) (match_dup 1))
18432 (set (match_dup 0) (match_dup 2))]
18433 "")
18434
18435 ;; Don't compare memory with zero, load and use a test instead.
18436 (define_peephole2
18437 [(set (reg 17)
18438 (compare (match_operand:SI 0 "memory_operand" "")
18439 (const_int 0)))
18440 (match_scratch:SI 3 "r")]
18441 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18442 [(set (match_dup 3) (match_dup 0))
18443 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18444 "")
18445
18446 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18447 ;; Don't split NOTs with a displacement operand, because resulting XOR
18448 ;; will not be pairable anyway.
18449 ;;
18450 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18451 ;; represented using a modRM byte. The XOR replacement is long decoded,
18452 ;; so this split helps here as well.
18453 ;;
18454 ;; Note: Can't do this as a regular split because we can't get proper
18455 ;; lifetime information then.
18456
18457 (define_peephole2
18458 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18459 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18460 "!optimize_size
18461 && peep2_regno_dead_p (0, FLAGS_REG)
18462 && ((TARGET_PENTIUM
18463 && (GET_CODE (operands[0]) != MEM
18464 || !memory_displacement_operand (operands[0], SImode)))
18465 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18466 [(parallel [(set (match_dup 0)
18467 (xor:SI (match_dup 1) (const_int -1)))
18468 (clobber (reg:CC 17))])]
18469 "")
18470
18471 (define_peephole2
18472 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18473 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18474 "!optimize_size
18475 && peep2_regno_dead_p (0, FLAGS_REG)
18476 && ((TARGET_PENTIUM
18477 && (GET_CODE (operands[0]) != MEM
18478 || !memory_displacement_operand (operands[0], HImode)))
18479 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18480 [(parallel [(set (match_dup 0)
18481 (xor:HI (match_dup 1) (const_int -1)))
18482 (clobber (reg:CC 17))])]
18483 "")
18484
18485 (define_peephole2
18486 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18487 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18488 "!optimize_size
18489 && peep2_regno_dead_p (0, FLAGS_REG)
18490 && ((TARGET_PENTIUM
18491 && (GET_CODE (operands[0]) != MEM
18492 || !memory_displacement_operand (operands[0], QImode)))
18493 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18494 [(parallel [(set (match_dup 0)
18495 (xor:QI (match_dup 1) (const_int -1)))
18496 (clobber (reg:CC 17))])]
18497 "")
18498
18499 ;; Non pairable "test imm, reg" instructions can be translated to
18500 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18501 ;; byte opcode instead of two, have a short form for byte operands),
18502 ;; so do it for other CPUs as well. Given that the value was dead,
18503 ;; this should not create any new dependencies. Pass on the sub-word
18504 ;; versions if we're concerned about partial register stalls.
18505
18506 (define_peephole2
18507 [(set (reg 17)
18508 (compare (and:SI (match_operand:SI 0 "register_operand" "")
18509 (match_operand:SI 1 "immediate_operand" ""))
18510 (const_int 0)))]
18511 "ix86_match_ccmode (insn, CCNOmode)
18512 && (true_regnum (operands[0]) != 0
18513 || (GET_CODE (operands[1]) == CONST_INT
18514 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18515 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18516 [(parallel
18517 [(set (reg:CCNO 17)
18518 (compare:CCNO (and:SI (match_dup 0)
18519 (match_dup 1))
18520 (const_int 0)))
18521 (set (match_dup 0)
18522 (and:SI (match_dup 0) (match_dup 1)))])]
18523 "")
18524
18525 ;; We don't need to handle HImode case, because it will be promoted to SImode
18526 ;; on ! TARGET_PARTIAL_REG_STALL
18527
18528 (define_peephole2
18529 [(set (reg 17)
18530 (compare (and:QI (match_operand:QI 0 "register_operand" "")
18531 (match_operand:QI 1 "immediate_operand" ""))
18532 (const_int 0)))]
18533 "! TARGET_PARTIAL_REG_STALL
18534 && ix86_match_ccmode (insn, CCNOmode)
18535 && true_regnum (operands[0]) != 0
18536 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18537 [(parallel
18538 [(set (reg:CCNO 17)
18539 (compare:CCNO (and:QI (match_dup 0)
18540 (match_dup 1))
18541 (const_int 0)))
18542 (set (match_dup 0)
18543 (and:QI (match_dup 0) (match_dup 1)))])]
18544 "")
18545
18546 (define_peephole2
18547 [(set (reg 17)
18548 (compare
18549 (and:SI
18550 (zero_extract:SI
18551 (match_operand 0 "ext_register_operand" "")
18552 (const_int 8)
18553 (const_int 8))
18554 (match_operand 1 "const_int_operand" ""))
18555 (const_int 0)))]
18556 "! TARGET_PARTIAL_REG_STALL
18557 && ix86_match_ccmode (insn, CCNOmode)
18558 && true_regnum (operands[0]) != 0
18559 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18560 [(parallel [(set (reg:CCNO 17)
18561 (compare:CCNO
18562 (and:SI
18563 (zero_extract:SI
18564 (match_dup 0)
18565 (const_int 8)
18566 (const_int 8))
18567 (match_dup 1))
18568 (const_int 0)))
18569 (set (zero_extract:SI (match_dup 0)
18570 (const_int 8)
18571 (const_int 8))
18572 (and:SI
18573 (zero_extract:SI
18574 (match_dup 0)
18575 (const_int 8)
18576 (const_int 8))
18577 (match_dup 1)))])]
18578 "")
18579
18580 ;; Don't do logical operations with memory inputs.
18581 (define_peephole2
18582 [(match_scratch:SI 2 "r")
18583 (parallel [(set (match_operand:SI 0 "register_operand" "")
18584 (match_operator:SI 3 "arith_or_logical_operator"
18585 [(match_dup 0)
18586 (match_operand:SI 1 "memory_operand" "")]))
18587 (clobber (reg:CC 17))])]
18588 "! optimize_size && ! TARGET_READ_MODIFY"
18589 [(set (match_dup 2) (match_dup 1))
18590 (parallel [(set (match_dup 0)
18591 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18592 (clobber (reg:CC 17))])]
18593 "")
18594
18595 (define_peephole2
18596 [(match_scratch:SI 2 "r")
18597 (parallel [(set (match_operand:SI 0 "register_operand" "")
18598 (match_operator:SI 3 "arith_or_logical_operator"
18599 [(match_operand:SI 1 "memory_operand" "")
18600 (match_dup 0)]))
18601 (clobber (reg:CC 17))])]
18602 "! optimize_size && ! TARGET_READ_MODIFY"
18603 [(set (match_dup 2) (match_dup 1))
18604 (parallel [(set (match_dup 0)
18605 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18606 (clobber (reg:CC 17))])]
18607 "")
18608
18609 ; Don't do logical operations with memory outputs
18610 ;
18611 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18612 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18613 ; the same decoder scheduling characteristics as the original.
18614
18615 (define_peephole2
18616 [(match_scratch:SI 2 "r")
18617 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18618 (match_operator:SI 3 "arith_or_logical_operator"
18619 [(match_dup 0)
18620 (match_operand:SI 1 "nonmemory_operand" "")]))
18621 (clobber (reg:CC 17))])]
18622 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18623 [(set (match_dup 2) (match_dup 0))
18624 (parallel [(set (match_dup 2)
18625 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18626 (clobber (reg:CC 17))])
18627 (set (match_dup 0) (match_dup 2))]
18628 "")
18629
18630 (define_peephole2
18631 [(match_scratch:SI 2 "r")
18632 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18633 (match_operator:SI 3 "arith_or_logical_operator"
18634 [(match_operand:SI 1 "nonmemory_operand" "")
18635 (match_dup 0)]))
18636 (clobber (reg:CC 17))])]
18637 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18638 [(set (match_dup 2) (match_dup 0))
18639 (parallel [(set (match_dup 2)
18640 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18641 (clobber (reg:CC 17))])
18642 (set (match_dup 0) (match_dup 2))]
18643 "")
18644
18645 ;; Attempt to always use XOR for zeroing registers.
18646 (define_peephole2
18647 [(set (match_operand 0 "register_operand" "")
18648 (const_int 0))]
18649 "(GET_MODE (operands[0]) == QImode
18650 || GET_MODE (operands[0]) == HImode
18651 || GET_MODE (operands[0]) == SImode
18652 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18653 && (! TARGET_USE_MOV0 || optimize_size)
18654 && peep2_regno_dead_p (0, FLAGS_REG)"
18655 [(parallel [(set (match_dup 0) (const_int 0))
18656 (clobber (reg:CC 17))])]
18657 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18658 operands[0]);")
18659
18660 (define_peephole2
18661 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18662 (const_int 0))]
18663 "(GET_MODE (operands[0]) == QImode
18664 || GET_MODE (operands[0]) == HImode)
18665 && (! TARGET_USE_MOV0 || optimize_size)
18666 && peep2_regno_dead_p (0, FLAGS_REG)"
18667 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18668 (clobber (reg:CC 17))])])
18669
18670 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18671 (define_peephole2
18672 [(set (match_operand 0 "register_operand" "")
18673 (const_int -1))]
18674 "(GET_MODE (operands[0]) == HImode
18675 || GET_MODE (operands[0]) == SImode
18676 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18677 && (optimize_size || TARGET_PENTIUM)
18678 && peep2_regno_dead_p (0, FLAGS_REG)"
18679 [(parallel [(set (match_dup 0) (const_int -1))
18680 (clobber (reg:CC 17))])]
18681 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18682 operands[0]);")
18683
18684 ;; Attempt to convert simple leas to adds. These can be created by
18685 ;; move expanders.
18686 (define_peephole2
18687 [(set (match_operand:SI 0 "register_operand" "")
18688 (plus:SI (match_dup 0)
18689 (match_operand:SI 1 "nonmemory_operand" "")))]
18690 "peep2_regno_dead_p (0, FLAGS_REG)"
18691 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18692 (clobber (reg:CC 17))])]
18693 "")
18694
18695 (define_peephole2
18696 [(set (match_operand:SI 0 "register_operand" "")
18697 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18698 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18699 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18700 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18701 (clobber (reg:CC 17))])]
18702 "operands[2] = gen_lowpart (SImode, operands[2]);")
18703
18704 (define_peephole2
18705 [(set (match_operand:DI 0 "register_operand" "")
18706 (plus:DI (match_dup 0)
18707 (match_operand:DI 1 "x86_64_general_operand" "")))]
18708 "peep2_regno_dead_p (0, FLAGS_REG)"
18709 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18710 (clobber (reg:CC 17))])]
18711 "")
18712
18713 (define_peephole2
18714 [(set (match_operand:SI 0 "register_operand" "")
18715 (mult:SI (match_dup 0)
18716 (match_operand:SI 1 "const_int_operand" "")))]
18717 "exact_log2 (INTVAL (operands[1])) >= 0
18718 && peep2_regno_dead_p (0, FLAGS_REG)"
18719 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18720 (clobber (reg:CC 17))])]
18721 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18722
18723 (define_peephole2
18724 [(set (match_operand:DI 0 "register_operand" "")
18725 (mult:DI (match_dup 0)
18726 (match_operand:DI 1 "const_int_operand" "")))]
18727 "exact_log2 (INTVAL (operands[1])) >= 0
18728 && peep2_regno_dead_p (0, FLAGS_REG)"
18729 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18730 (clobber (reg:CC 17))])]
18731 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18732
18733 (define_peephole2
18734 [(set (match_operand:SI 0 "register_operand" "")
18735 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18736 (match_operand:DI 2 "const_int_operand" "")) 0))]
18737 "exact_log2 (INTVAL (operands[2])) >= 0
18738 && REGNO (operands[0]) == REGNO (operands[1])
18739 && peep2_regno_dead_p (0, FLAGS_REG)"
18740 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18741 (clobber (reg:CC 17))])]
18742 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18743
18744 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18745 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18746 ;; many CPUs it is also faster, since special hardware to avoid esp
18747 ;; dependencies is present.
18748
18749 ;; While some of these conversions may be done using splitters, we use peepholes
18750 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18751
18752 ;; Convert prologue esp subtractions to push.
18753 ;; We need register to push. In order to keep verify_flow_info happy we have
18754 ;; two choices
18755 ;; - use scratch and clobber it in order to avoid dependencies
18756 ;; - use already live register
18757 ;; We can't use the second way right now, since there is no reliable way how to
18758 ;; verify that given register is live. First choice will also most likely in
18759 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18760 ;; call clobbered registers are dead. We may want to use base pointer as an
18761 ;; alternative when no register is available later.
18762
18763 (define_peephole2
18764 [(match_scratch:SI 0 "r")
18765 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18766 (clobber (reg:CC 17))
18767 (clobber (mem:BLK (scratch)))])]
18768 "optimize_size || !TARGET_SUB_ESP_4"
18769 [(clobber (match_dup 0))
18770 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18771 (clobber (mem:BLK (scratch)))])])
18772
18773 (define_peephole2
18774 [(match_scratch:SI 0 "r")
18775 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18776 (clobber (reg:CC 17))
18777 (clobber (mem:BLK (scratch)))])]
18778 "optimize_size || !TARGET_SUB_ESP_8"
18779 [(clobber (match_dup 0))
18780 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18781 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18782 (clobber (mem:BLK (scratch)))])])
18783
18784 ;; Convert esp subtractions to push.
18785 (define_peephole2
18786 [(match_scratch:SI 0 "r")
18787 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18788 (clobber (reg:CC 17))])]
18789 "optimize_size || !TARGET_SUB_ESP_4"
18790 [(clobber (match_dup 0))
18791 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18792
18793 (define_peephole2
18794 [(match_scratch:SI 0 "r")
18795 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18796 (clobber (reg:CC 17))])]
18797 "optimize_size || !TARGET_SUB_ESP_8"
18798 [(clobber (match_dup 0))
18799 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18800 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18801
18802 ;; Convert epilogue deallocator to pop.
18803 (define_peephole2
18804 [(match_scratch:SI 0 "r")
18805 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18806 (clobber (reg:CC 17))
18807 (clobber (mem:BLK (scratch)))])]
18808 "optimize_size || !TARGET_ADD_ESP_4"
18809 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18810 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18811 (clobber (mem:BLK (scratch)))])]
18812 "")
18813
18814 ;; Two pops case is tricky, since pop causes dependency on destination register.
18815 ;; We use two registers if available.
18816 (define_peephole2
18817 [(match_scratch:SI 0 "r")
18818 (match_scratch:SI 1 "r")
18819 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18820 (clobber (reg:CC 17))
18821 (clobber (mem:BLK (scratch)))])]
18822 "optimize_size || !TARGET_ADD_ESP_8"
18823 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18824 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18825 (clobber (mem:BLK (scratch)))])
18826 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18827 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18828 "")
18829
18830 (define_peephole2
18831 [(match_scratch:SI 0 "r")
18832 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18833 (clobber (reg:CC 17))
18834 (clobber (mem:BLK (scratch)))])]
18835 "optimize_size"
18836 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18837 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18838 (clobber (mem:BLK (scratch)))])
18839 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18840 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18841 "")
18842
18843 ;; Convert esp additions to pop.
18844 (define_peephole2
18845 [(match_scratch:SI 0 "r")
18846 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18847 (clobber (reg:CC 17))])]
18848 ""
18849 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18850 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18851 "")
18852
18853 ;; Two pops case is tricky, since pop causes dependency on destination register.
18854 ;; We use two registers if available.
18855 (define_peephole2
18856 [(match_scratch:SI 0 "r")
18857 (match_scratch:SI 1 "r")
18858 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18859 (clobber (reg:CC 17))])]
18860 ""
18861 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18862 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18863 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18864 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18865 "")
18866
18867 (define_peephole2
18868 [(match_scratch:SI 0 "r")
18869 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18870 (clobber (reg:CC 17))])]
18871 "optimize_size"
18872 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18873 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18874 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18875 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18876 "")
18877 \f
18878 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18879 ;; required and register dies.
18880 (define_peephole2
18881 [(set (reg 17)
18882 (compare (match_operand:SI 0 "register_operand" "")
18883 (match_operand:SI 1 "incdec_operand" "")))]
18884 "ix86_match_ccmode (insn, CCGCmode)
18885 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18886 [(parallel [(set (reg:CCGC 17)
18887 (compare:CCGC (match_dup 0)
18888 (match_dup 1)))
18889 (clobber (match_dup 0))])]
18890 "")
18891
18892 (define_peephole2
18893 [(set (reg 17)
18894 (compare (match_operand:HI 0 "register_operand" "")
18895 (match_operand:HI 1 "incdec_operand" "")))]
18896 "ix86_match_ccmode (insn, CCGCmode)
18897 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18898 [(parallel [(set (reg:CCGC 17)
18899 (compare:CCGC (match_dup 0)
18900 (match_dup 1)))
18901 (clobber (match_dup 0))])]
18902 "")
18903
18904 (define_peephole2
18905 [(set (reg 17)
18906 (compare (match_operand:QI 0 "register_operand" "")
18907 (match_operand:QI 1 "incdec_operand" "")))]
18908 "ix86_match_ccmode (insn, CCGCmode)
18909 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18910 [(parallel [(set (reg:CCGC 17)
18911 (compare:CCGC (match_dup 0)
18912 (match_dup 1)))
18913 (clobber (match_dup 0))])]
18914 "")
18915
18916 ;; Convert compares with 128 to shorter add -128
18917 (define_peephole2
18918 [(set (reg 17)
18919 (compare (match_operand:SI 0 "register_operand" "")
18920 (const_int 128)))]
18921 "ix86_match_ccmode (insn, CCGCmode)
18922 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18923 [(parallel [(set (reg:CCGC 17)
18924 (compare:CCGC (match_dup 0)
18925 (const_int 128)))
18926 (clobber (match_dup 0))])]
18927 "")
18928
18929 (define_peephole2
18930 [(set (reg 17)
18931 (compare (match_operand:HI 0 "register_operand" "")
18932 (const_int 128)))]
18933 "ix86_match_ccmode (insn, CCGCmode)
18934 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18935 [(parallel [(set (reg:CCGC 17)
18936 (compare:CCGC (match_dup 0)
18937 (const_int 128)))
18938 (clobber (match_dup 0))])]
18939 "")
18940 \f
18941 (define_peephole2
18942 [(match_scratch:DI 0 "r")
18943 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18944 (clobber (reg:CC 17))
18945 (clobber (mem:BLK (scratch)))])]
18946 "optimize_size || !TARGET_SUB_ESP_4"
18947 [(clobber (match_dup 0))
18948 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18949 (clobber (mem:BLK (scratch)))])])
18950
18951 (define_peephole2
18952 [(match_scratch:DI 0 "r")
18953 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18954 (clobber (reg:CC 17))
18955 (clobber (mem:BLK (scratch)))])]
18956 "optimize_size || !TARGET_SUB_ESP_8"
18957 [(clobber (match_dup 0))
18958 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18959 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18960 (clobber (mem:BLK (scratch)))])])
18961
18962 ;; Convert esp subtractions to push.
18963 (define_peephole2
18964 [(match_scratch:DI 0 "r")
18965 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18966 (clobber (reg:CC 17))])]
18967 "optimize_size || !TARGET_SUB_ESP_4"
18968 [(clobber (match_dup 0))
18969 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18970
18971 (define_peephole2
18972 [(match_scratch:DI 0 "r")
18973 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18974 (clobber (reg:CC 17))])]
18975 "optimize_size || !TARGET_SUB_ESP_8"
18976 [(clobber (match_dup 0))
18977 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18978 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18979
18980 ;; Convert epilogue deallocator to pop.
18981 (define_peephole2
18982 [(match_scratch:DI 0 "r")
18983 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18984 (clobber (reg:CC 17))
18985 (clobber (mem:BLK (scratch)))])]
18986 "optimize_size || !TARGET_ADD_ESP_4"
18987 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18988 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18989 (clobber (mem:BLK (scratch)))])]
18990 "")
18991
18992 ;; Two pops case is tricky, since pop causes dependency on destination register.
18993 ;; We use two registers if available.
18994 (define_peephole2
18995 [(match_scratch:DI 0 "r")
18996 (match_scratch:DI 1 "r")
18997 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18998 (clobber (reg:CC 17))
18999 (clobber (mem:BLK (scratch)))])]
19000 "optimize_size || !TARGET_ADD_ESP_8"
19001 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19002 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19003 (clobber (mem:BLK (scratch)))])
19004 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
19005 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19006 "")
19007
19008 (define_peephole2
19009 [(match_scratch:DI 0 "r")
19010 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19011 (clobber (reg:CC 17))
19012 (clobber (mem:BLK (scratch)))])]
19013 "optimize_size"
19014 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19015 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19016 (clobber (mem:BLK (scratch)))])
19017 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19018 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19019 "")
19020
19021 ;; Convert esp additions to pop.
19022 (define_peephole2
19023 [(match_scratch:DI 0 "r")
19024 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19025 (clobber (reg:CC 17))])]
19026 ""
19027 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19028 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19029 "")
19030
19031 ;; Two pops case is tricky, since pop causes dependency on destination register.
19032 ;; We use two registers if available.
19033 (define_peephole2
19034 [(match_scratch:DI 0 "r")
19035 (match_scratch:DI 1 "r")
19036 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19037 (clobber (reg:CC 17))])]
19038 ""
19039 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19040 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
19041 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
19042 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19043 "")
19044
19045 (define_peephole2
19046 [(match_scratch:DI 0 "r")
19047 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19048 (clobber (reg:CC 17))])]
19049 "optimize_size"
19050 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19051 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
19052 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19053 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19054 "")
19055 \f
19056 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19057 ;; imul $32bit_imm, reg, reg is direct decoded.
19058 (define_peephole2
19059 [(match_scratch:DI 3 "r")
19060 (parallel [(set (match_operand:DI 0 "register_operand" "")
19061 (mult:DI (match_operand:DI 1 "memory_operand" "")
19062 (match_operand:DI 2 "immediate_operand" "")))
19063 (clobber (reg:CC 17))])]
19064 "TARGET_K8 && !optimize_size
19065 && (GET_CODE (operands[2]) != CONST_INT
19066 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19067 [(set (match_dup 3) (match_dup 1))
19068 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19069 (clobber (reg:CC 17))])]
19070 "")
19071
19072 (define_peephole2
19073 [(match_scratch:SI 3 "r")
19074 (parallel [(set (match_operand:SI 0 "register_operand" "")
19075 (mult:SI (match_operand:SI 1 "memory_operand" "")
19076 (match_operand:SI 2 "immediate_operand" "")))
19077 (clobber (reg:CC 17))])]
19078 "TARGET_K8 && !optimize_size
19079 && (GET_CODE (operands[2]) != CONST_INT
19080 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19081 [(set (match_dup 3) (match_dup 1))
19082 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19083 (clobber (reg:CC 17))])]
19084 "")
19085
19086 (define_peephole2
19087 [(match_scratch:SI 3 "r")
19088 (parallel [(set (match_operand:DI 0 "register_operand" "")
19089 (zero_extend:DI
19090 (mult:SI (match_operand:SI 1 "memory_operand" "")
19091 (match_operand:SI 2 "immediate_operand" ""))))
19092 (clobber (reg:CC 17))])]
19093 "TARGET_K8 && !optimize_size
19094 && (GET_CODE (operands[2]) != CONST_INT
19095 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19096 [(set (match_dup 3) (match_dup 1))
19097 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19098 (clobber (reg:CC 17))])]
19099 "")
19100
19101 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19102 ;; Convert it into imul reg, reg
19103 ;; It would be better to force assembler to encode instruction using long
19104 ;; immediate, but there is apparently no way to do so.
19105 (define_peephole2
19106 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19107 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19108 (match_operand:DI 2 "const_int_operand" "")))
19109 (clobber (reg:CC 17))])
19110 (match_scratch:DI 3 "r")]
19111 "TARGET_K8 && !optimize_size
19112 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19113 [(set (match_dup 3) (match_dup 2))
19114 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19115 (clobber (reg:CC 17))])]
19116 {
19117 if (!rtx_equal_p (operands[0], operands[1]))
19118 emit_move_insn (operands[0], operands[1]);
19119 })
19120
19121 (define_peephole2
19122 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19123 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19124 (match_operand:SI 2 "const_int_operand" "")))
19125 (clobber (reg:CC 17))])
19126 (match_scratch:SI 3 "r")]
19127 "TARGET_K8 && !optimize_size
19128 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19129 [(set (match_dup 3) (match_dup 2))
19130 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19131 (clobber (reg:CC 17))])]
19132 {
19133 if (!rtx_equal_p (operands[0], operands[1]))
19134 emit_move_insn (operands[0], operands[1]);
19135 })
19136
19137 (define_peephole2
19138 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19139 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19140 (match_operand:HI 2 "immediate_operand" "")))
19141 (clobber (reg:CC 17))])
19142 (match_scratch:HI 3 "r")]
19143 "TARGET_K8 && !optimize_size"
19144 [(set (match_dup 3) (match_dup 2))
19145 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19146 (clobber (reg:CC 17))])]
19147 {
19148 if (!rtx_equal_p (operands[0], operands[1]))
19149 emit_move_insn (operands[0], operands[1]);
19150 })
19151 \f
19152 ;; Call-value patterns last so that the wildcard operand does not
19153 ;; disrupt insn-recog's switch tables.
19154
19155 (define_insn "*call_value_pop_0"
19156 [(set (match_operand 0 "" "")
19157 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19158 (match_operand:SI 2 "" "")))
19159 (set (reg:SI 7) (plus:SI (reg:SI 7)
19160 (match_operand:SI 3 "immediate_operand" "")))]
19161 "!TARGET_64BIT"
19162 {
19163 if (SIBLING_CALL_P (insn))
19164 return "jmp\t%P1";
19165 else
19166 return "call\t%P1";
19167 }
19168 [(set_attr "type" "callv")])
19169
19170 (define_insn "*call_value_pop_1"
19171 [(set (match_operand 0 "" "")
19172 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19173 (match_operand:SI 2 "" "")))
19174 (set (reg:SI 7) (plus:SI (reg:SI 7)
19175 (match_operand:SI 3 "immediate_operand" "i")))]
19176 "!TARGET_64BIT"
19177 {
19178 if (constant_call_address_operand (operands[1], QImode))
19179 {
19180 if (SIBLING_CALL_P (insn))
19181 return "jmp\t%P1";
19182 else
19183 return "call\t%P1";
19184 }
19185 if (SIBLING_CALL_P (insn))
19186 return "jmp\t%A1";
19187 else
19188 return "call\t%A1";
19189 }
19190 [(set_attr "type" "callv")])
19191
19192 (define_insn "*call_value_0"
19193 [(set (match_operand 0 "" "")
19194 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19195 (match_operand:SI 2 "" "")))]
19196 "!TARGET_64BIT"
19197 {
19198 if (SIBLING_CALL_P (insn))
19199 return "jmp\t%P1";
19200 else
19201 return "call\t%P1";
19202 }
19203 [(set_attr "type" "callv")])
19204
19205 (define_insn "*call_value_0_rex64"
19206 [(set (match_operand 0 "" "")
19207 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19208 (match_operand:DI 2 "const_int_operand" "")))]
19209 "TARGET_64BIT"
19210 {
19211 if (SIBLING_CALL_P (insn))
19212 return "jmp\t%P1";
19213 else
19214 return "call\t%P1";
19215 }
19216 [(set_attr "type" "callv")])
19217
19218 (define_insn "*call_value_1"
19219 [(set (match_operand 0 "" "")
19220 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19221 (match_operand:SI 2 "" "")))]
19222 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19223 {
19224 if (constant_call_address_operand (operands[1], QImode))
19225 return "call\t%P1";
19226 return "call\t%*%1";
19227 }
19228 [(set_attr "type" "callv")])
19229
19230 (define_insn "*sibcall_value_1"
19231 [(set (match_operand 0 "" "")
19232 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19233 (match_operand:SI 2 "" "")))]
19234 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19235 {
19236 if (constant_call_address_operand (operands[1], QImode))
19237 return "jmp\t%P1";
19238 return "jmp\t%*%1";
19239 }
19240 [(set_attr "type" "callv")])
19241
19242 (define_insn "*call_value_1_rex64"
19243 [(set (match_operand 0 "" "")
19244 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19245 (match_operand:DI 2 "" "")))]
19246 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19247 {
19248 if (constant_call_address_operand (operands[1], QImode))
19249 return "call\t%P1";
19250 return "call\t%A1";
19251 }
19252 [(set_attr "type" "callv")])
19253
19254 (define_insn "*sibcall_value_1_rex64"
19255 [(set (match_operand 0 "" "")
19256 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19257 (match_operand:DI 2 "" "")))]
19258 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19259 "jmp\t%P1"
19260 [(set_attr "type" "callv")])
19261
19262 (define_insn "*sibcall_value_1_rex64_v"
19263 [(set (match_operand 0 "" "")
19264 (call (mem:QI (reg:DI 40))
19265 (match_operand:DI 1 "" "")))]
19266 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19267 "jmp\t*%%r11"
19268 [(set_attr "type" "callv")])
19269 \f
19270 (define_insn "trap"
19271 [(trap_if (const_int 1) (const_int 5))]
19272 ""
19273 "int\t$5")
19274
19275 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19276 ;;; for the sake of bounds checking. By emitting bounds checks as
19277 ;;; conditional traps rather than as conditional jumps around
19278 ;;; unconditional traps we avoid introducing spurious basic-block
19279 ;;; boundaries and facilitate elimination of redundant checks. In
19280 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19281 ;;; interrupt 5.
19282 ;;;
19283 ;;; FIXME: Static branch prediction rules for ix86 are such that
19284 ;;; forward conditional branches predict as untaken. As implemented
19285 ;;; below, pseudo conditional traps violate that rule. We should use
19286 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19287 ;;; section loaded at the end of the text segment and branch forward
19288 ;;; there on bounds-failure, and then jump back immediately (in case
19289 ;;; the system chooses to ignore bounds violations, or to report
19290 ;;; violations and continue execution).
19291
19292 (define_expand "conditional_trap"
19293 [(trap_if (match_operator 0 "comparison_operator"
19294 [(match_dup 2) (const_int 0)])
19295 (match_operand 1 "const_int_operand" ""))]
19296 ""
19297 {
19298 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19299 ix86_expand_compare (GET_CODE (operands[0]),
19300 NULL, NULL),
19301 operands[1]));
19302 DONE;
19303 })
19304
19305 (define_insn "*conditional_trap_1"
19306 [(trap_if (match_operator 0 "comparison_operator"
19307 [(reg 17) (const_int 0)])
19308 (match_operand 1 "const_int_operand" ""))]
19309 ""
19310 {
19311 operands[2] = gen_label_rtx ();
19312 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19313 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19314 CODE_LABEL_NUMBER (operands[2]));
19315 RET;
19316 })
19317
19318 ;; Pentium III SIMD instructions.
19319
19320 ;; Moves for SSE/MMX regs.
19321
19322 (define_insn "movv4sf_internal"
19323 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19324 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19325 "TARGET_SSE"
19326 "@
19327 xorps\t%0, %0
19328 movaps\t{%1, %0|%0, %1}
19329 movaps\t{%1, %0|%0, %1}"
19330 [(set_attr "type" "ssemov")
19331 (set_attr "mode" "V4SF")])
19332
19333 (define_split
19334 [(set (match_operand:V4SF 0 "register_operand" "")
19335 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19336 "TARGET_SSE"
19337 [(set (match_dup 0)
19338 (vec_merge:V4SF
19339 (vec_duplicate:V4SF (match_dup 1))
19340 (match_dup 2)
19341 (const_int 1)))]
19342 {
19343 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19344 operands[2] = CONST0_RTX (V4SFmode);
19345 })
19346
19347 (define_insn "movv4si_internal"
19348 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19349 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19350 "TARGET_SSE"
19351 {
19352 switch (which_alternative)
19353 {
19354 case 0:
19355 if (get_attr_mode (insn) == MODE_V4SF)
19356 return "xorps\t%0, %0";
19357 else
19358 return "pxor\t%0, %0";
19359 case 1:
19360 case 2:
19361 if (get_attr_mode (insn) == MODE_V4SF)
19362 return "movaps\t{%1, %0|%0, %1}";
19363 else
19364 return "movdqa\t{%1, %0|%0, %1}";
19365 default:
19366 abort ();
19367 }
19368 }
19369 [(set_attr "type" "ssemov")
19370 (set (attr "mode")
19371 (cond [(eq_attr "alternative" "0,1")
19372 (if_then_else
19373 (ne (symbol_ref "optimize_size")
19374 (const_int 0))
19375 (const_string "V4SF")
19376 (const_string "TI"))
19377 (eq_attr "alternative" "2")
19378 (if_then_else
19379 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19380 (const_int 0))
19381 (ne (symbol_ref "optimize_size")
19382 (const_int 0)))
19383 (const_string "V4SF")
19384 (const_string "TI"))]
19385 (const_string "TI")))])
19386
19387 (define_insn "movv2di_internal"
19388 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19389 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19390 "TARGET_SSE2"
19391 {
19392 switch (which_alternative)
19393 {
19394 case 0:
19395 if (get_attr_mode (insn) == MODE_V4SF)
19396 return "xorps\t%0, %0";
19397 else
19398 return "pxor\t%0, %0";
19399 case 1:
19400 case 2:
19401 if (get_attr_mode (insn) == MODE_V4SF)
19402 return "movaps\t{%1, %0|%0, %1}";
19403 else
19404 return "movdqa\t{%1, %0|%0, %1}";
19405 default:
19406 abort ();
19407 }
19408 }
19409 [(set_attr "type" "ssemov")
19410 (set (attr "mode")
19411 (cond [(eq_attr "alternative" "0,1")
19412 (if_then_else
19413 (ne (symbol_ref "optimize_size")
19414 (const_int 0))
19415 (const_string "V4SF")
19416 (const_string "TI"))
19417 (eq_attr "alternative" "2")
19418 (if_then_else
19419 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19420 (const_int 0))
19421 (ne (symbol_ref "optimize_size")
19422 (const_int 0)))
19423 (const_string "V4SF")
19424 (const_string "TI"))]
19425 (const_string "TI")))])
19426
19427 (define_split
19428 [(set (match_operand:V2DF 0 "register_operand" "")
19429 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19430 "TARGET_SSE2"
19431 [(set (match_dup 0)
19432 (vec_merge:V2DF
19433 (vec_duplicate:V2DF (match_dup 1))
19434 (match_dup 2)
19435 (const_int 1)))]
19436 {
19437 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19438 operands[2] = CONST0_RTX (V2DFmode);
19439 })
19440
19441 (define_insn "movv8qi_internal"
19442 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19443 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19444 "TARGET_MMX
19445 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19446 "@
19447 pxor\t%0, %0
19448 movq\t{%1, %0|%0, %1}
19449 movq\t{%1, %0|%0, %1}"
19450 [(set_attr "type" "mmxmov")
19451 (set_attr "mode" "DI")])
19452
19453 (define_insn "movv4hi_internal"
19454 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19455 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19456 "TARGET_MMX
19457 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19458 "@
19459 pxor\t%0, %0
19460 movq\t{%1, %0|%0, %1}
19461 movq\t{%1, %0|%0, %1}"
19462 [(set_attr "type" "mmxmov")
19463 (set_attr "mode" "DI")])
19464
19465 (define_insn "movv2si_internal"
19466 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19467 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19468 "TARGET_MMX
19469 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19470 "@
19471 pxor\t%0, %0
19472 movq\t{%1, %0|%0, %1}
19473 movq\t{%1, %0|%0, %1}"
19474 [(set_attr "type" "mmxcvt")
19475 (set_attr "mode" "DI")])
19476
19477 (define_insn "movv2sf_internal"
19478 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19479 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19480 "TARGET_3DNOW
19481 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19482 "@
19483 pxor\t%0, %0
19484 movq\t{%1, %0|%0, %1}
19485 movq\t{%1, %0|%0, %1}"
19486 [(set_attr "type" "mmxcvt")
19487 (set_attr "mode" "DI")])
19488
19489 (define_expand "movti"
19490 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19491 (match_operand:TI 1 "nonimmediate_operand" ""))]
19492 "TARGET_SSE || TARGET_64BIT"
19493 {
19494 if (TARGET_64BIT)
19495 ix86_expand_move (TImode, operands);
19496 else
19497 ix86_expand_vector_move (TImode, operands);
19498 DONE;
19499 })
19500
19501 (define_insn "movv2df_internal"
19502 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19503 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19504 "TARGET_SSE2
19505 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19506 {
19507 switch (which_alternative)
19508 {
19509 case 0:
19510 if (get_attr_mode (insn) == MODE_V4SF)
19511 return "xorps\t%0, %0";
19512 else
19513 return "xorpd\t%0, %0";
19514 case 1:
19515 case 2:
19516 if (get_attr_mode (insn) == MODE_V4SF)
19517 return "movaps\t{%1, %0|%0, %1}";
19518 else
19519 return "movapd\t{%1, %0|%0, %1}";
19520 default:
19521 abort ();
19522 }
19523 }
19524 [(set_attr "type" "ssemov")
19525 (set (attr "mode")
19526 (cond [(eq_attr "alternative" "0,1")
19527 (if_then_else
19528 (ne (symbol_ref "optimize_size")
19529 (const_int 0))
19530 (const_string "V4SF")
19531 (const_string "V2DF"))
19532 (eq_attr "alternative" "2")
19533 (if_then_else
19534 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19535 (const_int 0))
19536 (ne (symbol_ref "optimize_size")
19537 (const_int 0)))
19538 (const_string "V4SF")
19539 (const_string "V2DF"))]
19540 (const_string "V2DF")))])
19541
19542 (define_insn "movv8hi_internal"
19543 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19544 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19545 "TARGET_SSE2
19546 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19547 {
19548 switch (which_alternative)
19549 {
19550 case 0:
19551 if (get_attr_mode (insn) == MODE_V4SF)
19552 return "xorps\t%0, %0";
19553 else
19554 return "pxor\t%0, %0";
19555 case 1:
19556 case 2:
19557 if (get_attr_mode (insn) == MODE_V4SF)
19558 return "movaps\t{%1, %0|%0, %1}";
19559 else
19560 return "movdqa\t{%1, %0|%0, %1}";
19561 default:
19562 abort ();
19563 }
19564 }
19565 [(set_attr "type" "ssemov")
19566 (set (attr "mode")
19567 (cond [(eq_attr "alternative" "0,1")
19568 (if_then_else
19569 (ne (symbol_ref "optimize_size")
19570 (const_int 0))
19571 (const_string "V4SF")
19572 (const_string "TI"))
19573 (eq_attr "alternative" "2")
19574 (if_then_else
19575 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19576 (const_int 0))
19577 (ne (symbol_ref "optimize_size")
19578 (const_int 0)))
19579 (const_string "V4SF")
19580 (const_string "TI"))]
19581 (const_string "TI")))])
19582
19583 (define_insn "movv16qi_internal"
19584 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19585 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19586 "TARGET_SSE2
19587 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19588 {
19589 switch (which_alternative)
19590 {
19591 case 0:
19592 if (get_attr_mode (insn) == MODE_V4SF)
19593 return "xorps\t%0, %0";
19594 else
19595 return "pxor\t%0, %0";
19596 case 1:
19597 case 2:
19598 if (get_attr_mode (insn) == MODE_V4SF)
19599 return "movaps\t{%1, %0|%0, %1}";
19600 else
19601 return "movdqa\t{%1, %0|%0, %1}";
19602 default:
19603 abort ();
19604 }
19605 }
19606 [(set_attr "type" "ssemov")
19607 (set (attr "mode")
19608 (cond [(eq_attr "alternative" "0,1")
19609 (if_then_else
19610 (ne (symbol_ref "optimize_size")
19611 (const_int 0))
19612 (const_string "V4SF")
19613 (const_string "TI"))
19614 (eq_attr "alternative" "2")
19615 (if_then_else
19616 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19617 (const_int 0))
19618 (ne (symbol_ref "optimize_size")
19619 (const_int 0)))
19620 (const_string "V4SF")
19621 (const_string "TI"))]
19622 (const_string "TI")))])
19623
19624 (define_expand "movv2df"
19625 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19626 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19627 "TARGET_SSE2"
19628 {
19629 ix86_expand_vector_move (V2DFmode, operands);
19630 DONE;
19631 })
19632
19633 (define_expand "movv8hi"
19634 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19635 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19636 "TARGET_SSE2"
19637 {
19638 ix86_expand_vector_move (V8HImode, operands);
19639 DONE;
19640 })
19641
19642 (define_expand "movv16qi"
19643 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19644 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19645 "TARGET_SSE2"
19646 {
19647 ix86_expand_vector_move (V16QImode, operands);
19648 DONE;
19649 })
19650
19651 (define_expand "movv4sf"
19652 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19653 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19654 "TARGET_SSE"
19655 {
19656 ix86_expand_vector_move (V4SFmode, operands);
19657 DONE;
19658 })
19659
19660 (define_expand "movv4si"
19661 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19662 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19663 "TARGET_SSE"
19664 {
19665 ix86_expand_vector_move (V4SImode, operands);
19666 DONE;
19667 })
19668
19669 (define_expand "movv2di"
19670 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19671 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19672 "TARGET_SSE"
19673 {
19674 ix86_expand_vector_move (V2DImode, operands);
19675 DONE;
19676 })
19677
19678 (define_expand "movv2si"
19679 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19680 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19681 "TARGET_MMX"
19682 {
19683 ix86_expand_vector_move (V2SImode, operands);
19684 DONE;
19685 })
19686
19687 (define_expand "movv4hi"
19688 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19689 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19690 "TARGET_MMX"
19691 {
19692 ix86_expand_vector_move (V4HImode, operands);
19693 DONE;
19694 })
19695
19696 (define_expand "movv8qi"
19697 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19698 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19699 "TARGET_MMX"
19700 {
19701 ix86_expand_vector_move (V8QImode, operands);
19702 DONE;
19703 })
19704
19705 (define_expand "movv2sf"
19706 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19707 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19708 "TARGET_3DNOW"
19709 {
19710 ix86_expand_vector_move (V2SFmode, operands);
19711 DONE;
19712 })
19713
19714 (define_insn "*pushti"
19715 [(set (match_operand:TI 0 "push_operand" "=<")
19716 (match_operand:TI 1 "register_operand" "x"))]
19717 "TARGET_SSE"
19718 "#")
19719
19720 (define_insn "*pushv2df"
19721 [(set (match_operand:V2DF 0 "push_operand" "=<")
19722 (match_operand:V2DF 1 "register_operand" "x"))]
19723 "TARGET_SSE"
19724 "#")
19725
19726 (define_insn "*pushv2di"
19727 [(set (match_operand:V2DI 0 "push_operand" "=<")
19728 (match_operand:V2DI 1 "register_operand" "x"))]
19729 "TARGET_SSE2"
19730 "#")
19731
19732 (define_insn "*pushv8hi"
19733 [(set (match_operand:V8HI 0 "push_operand" "=<")
19734 (match_operand:V8HI 1 "register_operand" "x"))]
19735 "TARGET_SSE2"
19736 "#")
19737
19738 (define_insn "*pushv16qi"
19739 [(set (match_operand:V16QI 0 "push_operand" "=<")
19740 (match_operand:V16QI 1 "register_operand" "x"))]
19741 "TARGET_SSE2"
19742 "#")
19743
19744 (define_insn "*pushv4sf"
19745 [(set (match_operand:V4SF 0 "push_operand" "=<")
19746 (match_operand:V4SF 1 "register_operand" "x"))]
19747 "TARGET_SSE"
19748 "#")
19749
19750 (define_insn "*pushv4si"
19751 [(set (match_operand:V4SI 0 "push_operand" "=<")
19752 (match_operand:V4SI 1 "register_operand" "x"))]
19753 "TARGET_SSE2"
19754 "#")
19755
19756 (define_insn "*pushv2si"
19757 [(set (match_operand:V2SI 0 "push_operand" "=<")
19758 (match_operand:V2SI 1 "register_operand" "y"))]
19759 "TARGET_MMX"
19760 "#")
19761
19762 (define_insn "*pushv4hi"
19763 [(set (match_operand:V4HI 0 "push_operand" "=<")
19764 (match_operand:V4HI 1 "register_operand" "y"))]
19765 "TARGET_MMX"
19766 "#")
19767
19768 (define_insn "*pushv8qi"
19769 [(set (match_operand:V8QI 0 "push_operand" "=<")
19770 (match_operand:V8QI 1 "register_operand" "y"))]
19771 "TARGET_MMX"
19772 "#")
19773
19774 (define_insn "*pushv2sf"
19775 [(set (match_operand:V2SF 0 "push_operand" "=<")
19776 (match_operand:V2SF 1 "register_operand" "y"))]
19777 "TARGET_3DNOW"
19778 "#")
19779
19780 (define_split
19781 [(set (match_operand 0 "push_operand" "")
19782 (match_operand 1 "register_operand" ""))]
19783 "!TARGET_64BIT && reload_completed
19784 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19785 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19786 (set (match_dup 2) (match_dup 1))]
19787 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19788 stack_pointer_rtx);
19789 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19790
19791 (define_split
19792 [(set (match_operand 0 "push_operand" "")
19793 (match_operand 1 "register_operand" ""))]
19794 "TARGET_64BIT && reload_completed
19795 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19796 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19797 (set (match_dup 2) (match_dup 1))]
19798 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19799 stack_pointer_rtx);
19800 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19801
19802
19803 (define_insn "movti_internal"
19804 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19805 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19806 "TARGET_SSE && !TARGET_64BIT
19807 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19808 {
19809 switch (which_alternative)
19810 {
19811 case 0:
19812 if (get_attr_mode (insn) == MODE_V4SF)
19813 return "xorps\t%0, %0";
19814 else
19815 return "pxor\t%0, %0";
19816 case 1:
19817 case 2:
19818 if (get_attr_mode (insn) == MODE_V4SF)
19819 return "movaps\t{%1, %0|%0, %1}";
19820 else
19821 return "movdqa\t{%1, %0|%0, %1}";
19822 default:
19823 abort ();
19824 }
19825 }
19826 [(set_attr "type" "ssemov,ssemov,ssemov")
19827 (set (attr "mode")
19828 (cond [(eq_attr "alternative" "0,1")
19829 (if_then_else
19830 (ne (symbol_ref "optimize_size")
19831 (const_int 0))
19832 (const_string "V4SF")
19833 (const_string "TI"))
19834 (eq_attr "alternative" "2")
19835 (if_then_else
19836 (ne (symbol_ref "optimize_size")
19837 (const_int 0))
19838 (const_string "V4SF")
19839 (const_string "TI"))]
19840 (const_string "TI")))])
19841
19842 (define_insn "*movti_rex64"
19843 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19844 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19845 "TARGET_64BIT
19846 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19847 {
19848 switch (which_alternative)
19849 {
19850 case 0:
19851 case 1:
19852 return "#";
19853 case 2:
19854 if (get_attr_mode (insn) == MODE_V4SF)
19855 return "xorps\t%0, %0";
19856 else
19857 return "pxor\t%0, %0";
19858 case 3:
19859 case 4:
19860 if (get_attr_mode (insn) == MODE_V4SF)
19861 return "movaps\t{%1, %0|%0, %1}";
19862 else
19863 return "movdqa\t{%1, %0|%0, %1}";
19864 default:
19865 abort ();
19866 }
19867 }
19868 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19869 (set (attr "mode")
19870 (cond [(eq_attr "alternative" "2,3")
19871 (if_then_else
19872 (ne (symbol_ref "optimize_size")
19873 (const_int 0))
19874 (const_string "V4SF")
19875 (const_string "TI"))
19876 (eq_attr "alternative" "4")
19877 (if_then_else
19878 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19879 (const_int 0))
19880 (ne (symbol_ref "optimize_size")
19881 (const_int 0)))
19882 (const_string "V4SF")
19883 (const_string "TI"))]
19884 (const_string "DI")))])
19885
19886 (define_split
19887 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19888 (match_operand:TI 1 "general_operand" ""))]
19889 "reload_completed && !SSE_REG_P (operands[0])
19890 && !SSE_REG_P (operands[1])"
19891 [(const_int 0)]
19892 "ix86_split_long_move (operands); DONE;")
19893
19894 ;; These two patterns are useful for specifying exactly whether to use
19895 ;; movaps or movups
19896 (define_expand "sse_movaps"
19897 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19898 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19899 UNSPEC_MOVA))]
19900 "TARGET_SSE"
19901 {
19902 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19903 {
19904 rtx tmp = gen_reg_rtx (V4SFmode);
19905 emit_insn (gen_sse_movaps (tmp, operands[1]));
19906 emit_move_insn (operands[0], tmp);
19907 DONE;
19908 }
19909 })
19910
19911 (define_insn "*sse_movaps_1"
19912 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19913 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19914 UNSPEC_MOVA))]
19915 "TARGET_SSE
19916 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19917 "movaps\t{%1, %0|%0, %1}"
19918 [(set_attr "type" "ssemov,ssemov")
19919 (set_attr "mode" "V4SF")])
19920
19921 (define_expand "sse_movups"
19922 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19923 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19924 UNSPEC_MOVU))]
19925 "TARGET_SSE"
19926 {
19927 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19928 {
19929 rtx tmp = gen_reg_rtx (V4SFmode);
19930 emit_insn (gen_sse_movups (tmp, operands[1]));
19931 emit_move_insn (operands[0], tmp);
19932 DONE;
19933 }
19934 })
19935
19936 (define_insn "*sse_movups_1"
19937 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19938 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19939 UNSPEC_MOVU))]
19940 "TARGET_SSE
19941 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19942 "movups\t{%1, %0|%0, %1}"
19943 [(set_attr "type" "ssecvt,ssecvt")
19944 (set_attr "mode" "V4SF")])
19945
19946 ;; SSE Strange Moves.
19947
19948 (define_insn "sse_movmskps"
19949 [(set (match_operand:SI 0 "register_operand" "=r")
19950 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19951 UNSPEC_MOVMSK))]
19952 "TARGET_SSE"
19953 "movmskps\t{%1, %0|%0, %1}"
19954 [(set_attr "type" "ssecvt")
19955 (set_attr "mode" "V4SF")])
19956
19957 (define_insn "mmx_pmovmskb"
19958 [(set (match_operand:SI 0 "register_operand" "=r")
19959 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19960 UNSPEC_MOVMSK))]
19961 "TARGET_SSE || TARGET_3DNOW_A"
19962 "pmovmskb\t{%1, %0|%0, %1}"
19963 [(set_attr "type" "ssecvt")
19964 (set_attr "mode" "V4SF")])
19965
19966
19967 (define_insn "mmx_maskmovq"
19968 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19969 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19970 (match_operand:V8QI 2 "register_operand" "y")]
19971 UNSPEC_MASKMOV))]
19972 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19973 ;; @@@ check ordering of operands in intel/nonintel syntax
19974 "maskmovq\t{%2, %1|%1, %2}"
19975 [(set_attr "type" "mmxcvt")
19976 (set_attr "mode" "DI")])
19977
19978 (define_insn "mmx_maskmovq_rex"
19979 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19980 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19981 (match_operand:V8QI 2 "register_operand" "y")]
19982 UNSPEC_MASKMOV))]
19983 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19984 ;; @@@ check ordering of operands in intel/nonintel syntax
19985 "maskmovq\t{%2, %1|%1, %2}"
19986 [(set_attr "type" "mmxcvt")
19987 (set_attr "mode" "DI")])
19988
19989 (define_insn "sse_movntv4sf"
19990 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19991 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19992 UNSPEC_MOVNT))]
19993 "TARGET_SSE"
19994 "movntps\t{%1, %0|%0, %1}"
19995 [(set_attr "type" "ssemov")
19996 (set_attr "mode" "V4SF")])
19997
19998 (define_insn "sse_movntdi"
19999 [(set (match_operand:DI 0 "memory_operand" "=m")
20000 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20001 UNSPEC_MOVNT))]
20002 "TARGET_SSE || TARGET_3DNOW_A"
20003 "movntq\t{%1, %0|%0, %1}"
20004 [(set_attr "type" "mmxmov")
20005 (set_attr "mode" "DI")])
20006
20007 (define_insn "sse_movhlps"
20008 [(set (match_operand:V4SF 0 "register_operand" "=x")
20009 (vec_merge:V4SF
20010 (match_operand:V4SF 1 "register_operand" "0")
20011 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20012 (parallel [(const_int 2)
20013 (const_int 3)
20014 (const_int 0)
20015 (const_int 1)]))
20016 (const_int 3)))]
20017 "TARGET_SSE"
20018 "movhlps\t{%2, %0|%0, %2}"
20019 [(set_attr "type" "ssecvt")
20020 (set_attr "mode" "V4SF")])
20021
20022 (define_insn "sse_movlhps"
20023 [(set (match_operand:V4SF 0 "register_operand" "=x")
20024 (vec_merge:V4SF
20025 (match_operand:V4SF 1 "register_operand" "0")
20026 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20027 (parallel [(const_int 2)
20028 (const_int 3)
20029 (const_int 0)
20030 (const_int 1)]))
20031 (const_int 12)))]
20032 "TARGET_SSE"
20033 "movlhps\t{%2, %0|%0, %2}"
20034 [(set_attr "type" "ssecvt")
20035 (set_attr "mode" "V4SF")])
20036
20037 (define_insn "sse_movhps"
20038 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20039 (vec_merge:V4SF
20040 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20041 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20042 (const_int 12)))]
20043 "TARGET_SSE
20044 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20045 "movhps\t{%2, %0|%0, %2}"
20046 [(set_attr "type" "ssecvt")
20047 (set_attr "mode" "V4SF")])
20048
20049 (define_insn "sse_movlps"
20050 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20051 (vec_merge:V4SF
20052 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20053 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20054 (const_int 3)))]
20055 "TARGET_SSE
20056 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20057 "movlps\t{%2, %0|%0, %2}"
20058 [(set_attr "type" "ssecvt")
20059 (set_attr "mode" "V4SF")])
20060
20061 (define_expand "sse_loadss"
20062 [(match_operand:V4SF 0 "register_operand" "")
20063 (match_operand:SF 1 "memory_operand" "")]
20064 "TARGET_SSE"
20065 {
20066 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20067 CONST0_RTX (V4SFmode)));
20068 DONE;
20069 })
20070
20071 (define_insn "sse_loadss_1"
20072 [(set (match_operand:V4SF 0 "register_operand" "=x")
20073 (vec_merge:V4SF
20074 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20075 (match_operand:V4SF 2 "const0_operand" "X")
20076 (const_int 1)))]
20077 "TARGET_SSE"
20078 "movss\t{%1, %0|%0, %1}"
20079 [(set_attr "type" "ssemov")
20080 (set_attr "mode" "SF")])
20081
20082 (define_insn "sse_movss"
20083 [(set (match_operand:V4SF 0 "register_operand" "=x")
20084 (vec_merge:V4SF
20085 (match_operand:V4SF 1 "register_operand" "0")
20086 (match_operand:V4SF 2 "register_operand" "x")
20087 (const_int 1)))]
20088 "TARGET_SSE"
20089 "movss\t{%2, %0|%0, %2}"
20090 [(set_attr "type" "ssemov")
20091 (set_attr "mode" "SF")])
20092
20093 (define_insn "sse_storess"
20094 [(set (match_operand:SF 0 "memory_operand" "=m")
20095 (vec_select:SF
20096 (match_operand:V4SF 1 "register_operand" "x")
20097 (parallel [(const_int 0)])))]
20098 "TARGET_SSE"
20099 "movss\t{%1, %0|%0, %1}"
20100 [(set_attr "type" "ssemov")
20101 (set_attr "mode" "SF")])
20102
20103 (define_insn "sse_shufps"
20104 [(set (match_operand:V4SF 0 "register_operand" "=x")
20105 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20106 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20107 (match_operand:SI 3 "immediate_operand" "i")]
20108 UNSPEC_SHUFFLE))]
20109 "TARGET_SSE"
20110 ;; @@@ check operand order for intel/nonintel syntax
20111 "shufps\t{%3, %2, %0|%0, %2, %3}"
20112 [(set_attr "type" "ssecvt")
20113 (set_attr "mode" "V4SF")])
20114
20115
20116 ;; SSE arithmetic
20117
20118 (define_insn "addv4sf3"
20119 [(set (match_operand:V4SF 0 "register_operand" "=x")
20120 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20121 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20122 "TARGET_SSE"
20123 "addps\t{%2, %0|%0, %2}"
20124 [(set_attr "type" "sseadd")
20125 (set_attr "mode" "V4SF")])
20126
20127 (define_insn "vmaddv4sf3"
20128 [(set (match_operand:V4SF 0 "register_operand" "=x")
20129 (vec_merge:V4SF
20130 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20131 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20132 (match_dup 1)
20133 (const_int 1)))]
20134 "TARGET_SSE"
20135 "addss\t{%2, %0|%0, %2}"
20136 [(set_attr "type" "sseadd")
20137 (set_attr "mode" "SF")])
20138
20139 (define_insn "subv4sf3"
20140 [(set (match_operand:V4SF 0 "register_operand" "=x")
20141 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20142 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20143 "TARGET_SSE"
20144 "subps\t{%2, %0|%0, %2}"
20145 [(set_attr "type" "sseadd")
20146 (set_attr "mode" "V4SF")])
20147
20148 (define_insn "vmsubv4sf3"
20149 [(set (match_operand:V4SF 0 "register_operand" "=x")
20150 (vec_merge:V4SF
20151 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20152 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20153 (match_dup 1)
20154 (const_int 1)))]
20155 "TARGET_SSE"
20156 "subss\t{%2, %0|%0, %2}"
20157 [(set_attr "type" "sseadd")
20158 (set_attr "mode" "SF")])
20159
20160 (define_insn "mulv4sf3"
20161 [(set (match_operand:V4SF 0 "register_operand" "=x")
20162 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20163 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20164 "TARGET_SSE"
20165 "mulps\t{%2, %0|%0, %2}"
20166 [(set_attr "type" "ssemul")
20167 (set_attr "mode" "V4SF")])
20168
20169 (define_insn "vmmulv4sf3"
20170 [(set (match_operand:V4SF 0 "register_operand" "=x")
20171 (vec_merge:V4SF
20172 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20173 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20174 (match_dup 1)
20175 (const_int 1)))]
20176 "TARGET_SSE"
20177 "mulss\t{%2, %0|%0, %2}"
20178 [(set_attr "type" "ssemul")
20179 (set_attr "mode" "SF")])
20180
20181 (define_insn "divv4sf3"
20182 [(set (match_operand:V4SF 0 "register_operand" "=x")
20183 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20184 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20185 "TARGET_SSE"
20186 "divps\t{%2, %0|%0, %2}"
20187 [(set_attr "type" "ssediv")
20188 (set_attr "mode" "V4SF")])
20189
20190 (define_insn "vmdivv4sf3"
20191 [(set (match_operand:V4SF 0 "register_operand" "=x")
20192 (vec_merge:V4SF
20193 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20194 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20195 (match_dup 1)
20196 (const_int 1)))]
20197 "TARGET_SSE"
20198 "divss\t{%2, %0|%0, %2}"
20199 [(set_attr "type" "ssediv")
20200 (set_attr "mode" "SF")])
20201
20202
20203 ;; SSE square root/reciprocal
20204
20205 (define_insn "rcpv4sf2"
20206 [(set (match_operand:V4SF 0 "register_operand" "=x")
20207 (unspec:V4SF
20208 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20209 "TARGET_SSE"
20210 "rcpps\t{%1, %0|%0, %1}"
20211 [(set_attr "type" "sse")
20212 (set_attr "mode" "V4SF")])
20213
20214 (define_insn "vmrcpv4sf2"
20215 [(set (match_operand:V4SF 0 "register_operand" "=x")
20216 (vec_merge:V4SF
20217 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20218 UNSPEC_RCP)
20219 (match_operand:V4SF 2 "register_operand" "0")
20220 (const_int 1)))]
20221 "TARGET_SSE"
20222 "rcpss\t{%1, %0|%0, %1}"
20223 [(set_attr "type" "sse")
20224 (set_attr "mode" "SF")])
20225
20226 (define_insn "rsqrtv4sf2"
20227 [(set (match_operand:V4SF 0 "register_operand" "=x")
20228 (unspec:V4SF
20229 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20230 "TARGET_SSE"
20231 "rsqrtps\t{%1, %0|%0, %1}"
20232 [(set_attr "type" "sse")
20233 (set_attr "mode" "V4SF")])
20234
20235 (define_insn "vmrsqrtv4sf2"
20236 [(set (match_operand:V4SF 0 "register_operand" "=x")
20237 (vec_merge:V4SF
20238 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20239 UNSPEC_RSQRT)
20240 (match_operand:V4SF 2 "register_operand" "0")
20241 (const_int 1)))]
20242 "TARGET_SSE"
20243 "rsqrtss\t{%1, %0|%0, %1}"
20244 [(set_attr "type" "sse")
20245 (set_attr "mode" "SF")])
20246
20247 (define_insn "sqrtv4sf2"
20248 [(set (match_operand:V4SF 0 "register_operand" "=x")
20249 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20250 "TARGET_SSE"
20251 "sqrtps\t{%1, %0|%0, %1}"
20252 [(set_attr "type" "sse")
20253 (set_attr "mode" "V4SF")])
20254
20255 (define_insn "vmsqrtv4sf2"
20256 [(set (match_operand:V4SF 0 "register_operand" "=x")
20257 (vec_merge:V4SF
20258 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20259 (match_operand:V4SF 2 "register_operand" "0")
20260 (const_int 1)))]
20261 "TARGET_SSE"
20262 "sqrtss\t{%1, %0|%0, %1}"
20263 [(set_attr "type" "sse")
20264 (set_attr "mode" "SF")])
20265
20266 ;; SSE logical operations.
20267
20268 ;; SSE defines logical operations on floating point values. This brings
20269 ;; interesting challenge to RTL representation where logicals are only valid
20270 ;; on integral types. We deal with this by representing the floating point
20271 ;; logical as logical on arguments casted to TImode as this is what hardware
20272 ;; really does. Unfortunately hardware requires the type information to be
20273 ;; present and thus we must avoid subregs from being simplified and eliminated
20274 ;; in later compilation phases.
20275 ;;
20276 ;; We have following variants from each instruction:
20277 ;; sse_andsf3 - the operation taking V4SF vector operands
20278 ;; and doing TImode cast on them
20279 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20280 ;; TImode, since backend insist on eliminating casts
20281 ;; on memory operands
20282 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20283 ;; We can not accept memory operand here as instruction reads
20284 ;; whole scalar. This is generated only post reload by GCC
20285 ;; scalar float operations that expands to logicals (fabs)
20286 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20287 ;; memory operand. Eventually combine can be able
20288 ;; to synthesize these using splitter.
20289 ;; sse2_anddf3, *sse2_anddf3_memory
20290 ;;
20291 ;;
20292 ;; These are not called andti3 etc. because we really really don't want
20293 ;; the compiler to widen DImode ands to TImode ands and then try to move
20294 ;; into DImode subregs of SSE registers, and them together, and move out
20295 ;; of DImode subregs again!
20296 ;; SSE1 single precision floating point logical operation
20297 (define_expand "sse_andv4sf3"
20298 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20299 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20300 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20301 "TARGET_SSE"
20302 "")
20303
20304 (define_insn "*sse_andv4sf3"
20305 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20306 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20307 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20308 "TARGET_SSE
20309 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20310 "andps\t{%2, %0|%0, %2}"
20311 [(set_attr "type" "sselog")
20312 (set_attr "mode" "V4SF")])
20313
20314 (define_insn "*sse_andsf3"
20315 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20316 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20317 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20318 "TARGET_SSE
20319 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20320 "andps\t{%2, %0|%0, %2}"
20321 [(set_attr "type" "sselog")
20322 (set_attr "mode" "V4SF")])
20323
20324 (define_expand "sse_nandv4sf3"
20325 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20326 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
20327 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20328 "TARGET_SSE"
20329 "")
20330
20331 (define_insn "*sse_nandv4sf3"
20332 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20333 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20334 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20335 "TARGET_SSE"
20336 "andnps\t{%2, %0|%0, %2}"
20337 [(set_attr "type" "sselog")
20338 (set_attr "mode" "V4SF")])
20339
20340 (define_insn "*sse_nandsf3"
20341 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20342 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20343 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20344 "TARGET_SSE"
20345 "andnps\t{%2, %0|%0, %2}"
20346 [(set_attr "type" "sselog")
20347 (set_attr "mode" "V4SF")])
20348
20349 (define_expand "sse_iorv4sf3"
20350 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20351 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20352 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20353 "TARGET_SSE"
20354 "")
20355
20356 (define_insn "*sse_iorv4sf3"
20357 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20358 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20359 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20360 "TARGET_SSE
20361 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20362 "orps\t{%2, %0|%0, %2}"
20363 [(set_attr "type" "sselog")
20364 (set_attr "mode" "V4SF")])
20365
20366 (define_insn "*sse_iorsf3"
20367 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20368 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20369 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20370 "TARGET_SSE
20371 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20372 "orps\t{%2, %0|%0, %2}"
20373 [(set_attr "type" "sselog")
20374 (set_attr "mode" "V4SF")])
20375
20376 (define_expand "sse_xorv4sf3"
20377 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20378 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20379 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20380 "TARGET_SSE
20381 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20382 "")
20383
20384 (define_insn "*sse_xorv4sf3"
20385 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20386 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20387 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20388 "TARGET_SSE
20389 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20390 "xorps\t{%2, %0|%0, %2}"
20391 [(set_attr "type" "sselog")
20392 (set_attr "mode" "V4SF")])
20393
20394 (define_insn "*sse_xorsf3"
20395 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20396 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20397 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20398 "TARGET_SSE
20399 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20400 "xorps\t{%2, %0|%0, %2}"
20401 [(set_attr "type" "sselog")
20402 (set_attr "mode" "V4SF")])
20403
20404 ;; SSE2 double precision floating point logical operation
20405
20406 (define_expand "sse2_andv2df3"
20407 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20408 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20409 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20410 "TARGET_SSE2"
20411 "")
20412
20413 (define_insn "*sse2_andv2df3"
20414 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20415 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20416 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20417 "TARGET_SSE2
20418 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20419 "andpd\t{%2, %0|%0, %2}"
20420 [(set_attr "type" "sselog")
20421 (set_attr "mode" "V2DF")])
20422
20423 (define_insn "*sse2_andv2df3"
20424 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20425 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20426 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20427 "TARGET_SSE2
20428 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20429 "andpd\t{%2, %0|%0, %2}"
20430 [(set_attr "type" "sselog")
20431 (set_attr "mode" "V2DF")])
20432
20433 (define_expand "sse2_nandv2df3"
20434 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20435 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
20436 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20437 "TARGET_SSE2"
20438 "")
20439
20440 (define_insn "*sse2_nandv2df3"
20441 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20442 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20443 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20444 "TARGET_SSE2"
20445 "andnpd\t{%2, %0|%0, %2}"
20446 [(set_attr "type" "sselog")
20447 (set_attr "mode" "V2DF")])
20448
20449 (define_insn "*sse_nandti3_df"
20450 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
20451 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20452 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
20453 "TARGET_SSE2"
20454 "andnpd\t{%2, %0|%0, %2}"
20455 [(set_attr "type" "sselog")
20456 (set_attr "mode" "V2DF")])
20457
20458 (define_expand "sse2_iorv2df3"
20459 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20460 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20461 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20462 "TARGET_SSE2"
20463 "")
20464
20465 (define_insn "*sse2_iorv2df3"
20466 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20467 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20468 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20469 "TARGET_SSE2
20470 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20471 "orpd\t{%2, %0|%0, %2}"
20472 [(set_attr "type" "sselog")
20473 (set_attr "mode" "V2DF")])
20474
20475 (define_insn "*sse2_iordf3"
20476 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20477 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20478 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20479 "TARGET_SSE2
20480 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20481 "orpd\t{%2, %0|%0, %2}"
20482 [(set_attr "type" "sselog")
20483 (set_attr "mode" "V2DF")])
20484
20485 (define_expand "sse2_xorv2df3"
20486 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20487 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
20488 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20489 "TARGET_SSE2"
20490 "")
20491
20492 (define_insn "*sse2_xorv2df3"
20493 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20494 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20495 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20496 "TARGET_SSE2
20497 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20498 "xorpd\t{%2, %0|%0, %2}"
20499 [(set_attr "type" "sselog")
20500 (set_attr "mode" "V2DF")])
20501
20502 (define_insn "*sse2_xordf3"
20503 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20504 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20505 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20506 "TARGET_SSE2
20507 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20508 "xorpd\t{%2, %0|%0, %2}"
20509 [(set_attr "type" "sselog")
20510 (set_attr "mode" "V2DF")])
20511
20512 ;; SSE2 integral logicals. These patterns must always come after floating
20513 ;; point ones since we don't want compiler to use integer opcodes on floating
20514 ;; point SSE values to avoid matching of subregs in the match_operand.
20515 (define_insn "*sse2_andti3"
20516 [(set (match_operand:TI 0 "register_operand" "=x")
20517 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20518 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20519 "TARGET_SSE2
20520 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20521 "pand\t{%2, %0|%0, %2}"
20522 [(set_attr "type" "sselog")
20523 (set_attr "mode" "TI")])
20524
20525 (define_insn "sse2_andv2di3"
20526 [(set (match_operand:V2DI 0 "register_operand" "=x")
20527 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20528 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20529 "TARGET_SSE2
20530 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20531 "pand\t{%2, %0|%0, %2}"
20532 [(set_attr "type" "sselog")
20533 (set_attr "mode" "TI")])
20534
20535 (define_insn "*sse2_nandti3"
20536 [(set (match_operand:TI 0 "register_operand" "=x")
20537 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20538 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20539 "TARGET_SSE2"
20540 "pandn\t{%2, %0|%0, %2}"
20541 [(set_attr "type" "sselog")
20542 (set_attr "mode" "TI")])
20543
20544 (define_insn "sse2_nandv2di3"
20545 [(set (match_operand:V2DI 0 "register_operand" "=x")
20546 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20547 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20548 "TARGET_SSE2
20549 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20550 "pandn\t{%2, %0|%0, %2}"
20551 [(set_attr "type" "sselog")
20552 (set_attr "mode" "TI")])
20553
20554 (define_insn "*sse2_iorti3"
20555 [(set (match_operand:TI 0 "register_operand" "=x")
20556 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20557 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20558 "TARGET_SSE2
20559 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20560 "por\t{%2, %0|%0, %2}"
20561 [(set_attr "type" "sselog")
20562 (set_attr "mode" "TI")])
20563
20564 (define_insn "sse2_iorv2di3"
20565 [(set (match_operand:V2DI 0 "register_operand" "=x")
20566 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20567 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20568 "TARGET_SSE2
20569 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20570 "por\t{%2, %0|%0, %2}"
20571 [(set_attr "type" "sselog")
20572 (set_attr "mode" "TI")])
20573
20574 (define_insn "*sse2_xorti3"
20575 [(set (match_operand:TI 0 "register_operand" "=x")
20576 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20577 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20578 "TARGET_SSE2
20579 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20580 "pxor\t{%2, %0|%0, %2}"
20581 [(set_attr "type" "sselog")
20582 (set_attr "mode" "TI")])
20583
20584 (define_insn "sse2_xorv2di3"
20585 [(set (match_operand:V2DI 0 "register_operand" "=x")
20586 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20587 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20588 "TARGET_SSE2
20589 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20590 "pxor\t{%2, %0|%0, %2}"
20591 [(set_attr "type" "sselog")
20592 (set_attr "mode" "TI")])
20593
20594 ;; Use xor, but don't show input operands so they aren't live before
20595 ;; this insn.
20596 (define_insn "sse_clrv4sf"
20597 [(set (match_operand:V4SF 0 "register_operand" "=x")
20598 (match_operand:V4SF 1 "const0_operand" "X"))]
20599 "TARGET_SSE"
20600 {
20601 if (get_attr_mode (insn) == MODE_TI)
20602 return "pxor\t{%0, %0|%0, %0}";
20603 else
20604 return "xorps\t{%0, %0|%0, %0}";
20605 }
20606 [(set_attr "type" "sselog")
20607 (set_attr "memory" "none")
20608 (set (attr "mode")
20609 (if_then_else
20610 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20611 (const_int 0))
20612 (ne (symbol_ref "TARGET_SSE2")
20613 (const_int 0)))
20614 (eq (symbol_ref "optimize_size")
20615 (const_int 0)))
20616 (const_string "TI")
20617 (const_string "V4SF")))])
20618
20619 ;; Use xor, but don't show input operands so they aren't live before
20620 ;; this insn.
20621 (define_insn "sse_clrv2df"
20622 [(set (match_operand:V2DF 0 "register_operand" "=x")
20623 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20624 "TARGET_SSE2"
20625 "xorpd\t{%0, %0|%0, %0}"
20626 [(set_attr "type" "sselog")
20627 (set_attr "memory" "none")
20628 (set_attr "mode" "V4SF")])
20629
20630 ;; SSE mask-generating compares
20631
20632 (define_insn "maskcmpv4sf3"
20633 [(set (match_operand:V4SI 0 "register_operand" "=x")
20634 (match_operator:V4SI 3 "sse_comparison_operator"
20635 [(match_operand:V4SF 1 "register_operand" "0")
20636 (match_operand:V4SF 2 "register_operand" "x")]))]
20637 "TARGET_SSE"
20638 "cmp%D3ps\t{%2, %0|%0, %2}"
20639 [(set_attr "type" "ssecmp")
20640 (set_attr "mode" "V4SF")])
20641
20642 (define_insn "maskncmpv4sf3"
20643 [(set (match_operand:V4SI 0 "register_operand" "=x")
20644 (not:V4SI
20645 (match_operator:V4SI 3 "sse_comparison_operator"
20646 [(match_operand:V4SF 1 "register_operand" "0")
20647 (match_operand:V4SF 2 "register_operand" "x")])))]
20648 "TARGET_SSE"
20649 {
20650 if (GET_CODE (operands[3]) == UNORDERED)
20651 return "cmpordps\t{%2, %0|%0, %2}";
20652 else
20653 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20654 }
20655 [(set_attr "type" "ssecmp")
20656 (set_attr "mode" "V4SF")])
20657
20658 (define_insn "vmmaskcmpv4sf3"
20659 [(set (match_operand:V4SI 0 "register_operand" "=x")
20660 (vec_merge:V4SI
20661 (match_operator:V4SI 3 "sse_comparison_operator"
20662 [(match_operand:V4SF 1 "register_operand" "0")
20663 (match_operand:V4SF 2 "register_operand" "x")])
20664 (subreg:V4SI (match_dup 1) 0)
20665 (const_int 1)))]
20666 "TARGET_SSE"
20667 "cmp%D3ss\t{%2, %0|%0, %2}"
20668 [(set_attr "type" "ssecmp")
20669 (set_attr "mode" "SF")])
20670
20671 (define_insn "vmmaskncmpv4sf3"
20672 [(set (match_operand:V4SI 0 "register_operand" "=x")
20673 (vec_merge:V4SI
20674 (not:V4SI
20675 (match_operator:V4SI 3 "sse_comparison_operator"
20676 [(match_operand:V4SF 1 "register_operand" "0")
20677 (match_operand:V4SF 2 "register_operand" "x")]))
20678 (subreg:V4SI (match_dup 1) 0)
20679 (const_int 1)))]
20680 "TARGET_SSE"
20681 {
20682 if (GET_CODE (operands[3]) == UNORDERED)
20683 return "cmpordss\t{%2, %0|%0, %2}";
20684 else
20685 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20686 }
20687 [(set_attr "type" "ssecmp")
20688 (set_attr "mode" "SF")])
20689
20690 (define_insn "sse_comi"
20691 [(set (reg:CCFP 17)
20692 (compare:CCFP (vec_select:SF
20693 (match_operand:V4SF 0 "register_operand" "x")
20694 (parallel [(const_int 0)]))
20695 (vec_select:SF
20696 (match_operand:V4SF 1 "register_operand" "x")
20697 (parallel [(const_int 0)]))))]
20698 "TARGET_SSE"
20699 "comiss\t{%1, %0|%0, %1}"
20700 [(set_attr "type" "ssecomi")
20701 (set_attr "mode" "SF")])
20702
20703 (define_insn "sse_ucomi"
20704 [(set (reg:CCFPU 17)
20705 (compare:CCFPU (vec_select:SF
20706 (match_operand:V4SF 0 "register_operand" "x")
20707 (parallel [(const_int 0)]))
20708 (vec_select:SF
20709 (match_operand:V4SF 1 "register_operand" "x")
20710 (parallel [(const_int 0)]))))]
20711 "TARGET_SSE"
20712 "ucomiss\t{%1, %0|%0, %1}"
20713 [(set_attr "type" "ssecomi")
20714 (set_attr "mode" "SF")])
20715
20716
20717 ;; SSE unpack
20718
20719 (define_insn "sse_unpckhps"
20720 [(set (match_operand:V4SF 0 "register_operand" "=x")
20721 (vec_merge:V4SF
20722 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20723 (parallel [(const_int 2)
20724 (const_int 0)
20725 (const_int 3)
20726 (const_int 1)]))
20727 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20728 (parallel [(const_int 0)
20729 (const_int 2)
20730 (const_int 1)
20731 (const_int 3)]))
20732 (const_int 5)))]
20733 "TARGET_SSE"
20734 "unpckhps\t{%2, %0|%0, %2}"
20735 [(set_attr "type" "ssecvt")
20736 (set_attr "mode" "V4SF")])
20737
20738 (define_insn "sse_unpcklps"
20739 [(set (match_operand:V4SF 0 "register_operand" "=x")
20740 (vec_merge:V4SF
20741 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20742 (parallel [(const_int 0)
20743 (const_int 2)
20744 (const_int 1)
20745 (const_int 3)]))
20746 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20747 (parallel [(const_int 2)
20748 (const_int 0)
20749 (const_int 3)
20750 (const_int 1)]))
20751 (const_int 5)))]
20752 "TARGET_SSE"
20753 "unpcklps\t{%2, %0|%0, %2}"
20754 [(set_attr "type" "ssecvt")
20755 (set_attr "mode" "V4SF")])
20756
20757
20758 ;; SSE min/max
20759
20760 (define_insn "smaxv4sf3"
20761 [(set (match_operand:V4SF 0 "register_operand" "=x")
20762 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20763 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20764 "TARGET_SSE"
20765 "maxps\t{%2, %0|%0, %2}"
20766 [(set_attr "type" "sse")
20767 (set_attr "mode" "V4SF")])
20768
20769 (define_insn "vmsmaxv4sf3"
20770 [(set (match_operand:V4SF 0 "register_operand" "=x")
20771 (vec_merge:V4SF
20772 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20773 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20774 (match_dup 1)
20775 (const_int 1)))]
20776 "TARGET_SSE"
20777 "maxss\t{%2, %0|%0, %2}"
20778 [(set_attr "type" "sse")
20779 (set_attr "mode" "SF")])
20780
20781 (define_insn "sminv4sf3"
20782 [(set (match_operand:V4SF 0 "register_operand" "=x")
20783 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20784 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20785 "TARGET_SSE"
20786 "minps\t{%2, %0|%0, %2}"
20787 [(set_attr "type" "sse")
20788 (set_attr "mode" "V4SF")])
20789
20790 (define_insn "vmsminv4sf3"
20791 [(set (match_operand:V4SF 0 "register_operand" "=x")
20792 (vec_merge:V4SF
20793 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20794 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20795 (match_dup 1)
20796 (const_int 1)))]
20797 "TARGET_SSE"
20798 "minss\t{%2, %0|%0, %2}"
20799 [(set_attr "type" "sse")
20800 (set_attr "mode" "SF")])
20801
20802 ;; SSE <-> integer/MMX conversions
20803
20804 (define_insn "cvtpi2ps"
20805 [(set (match_operand:V4SF 0 "register_operand" "=x")
20806 (vec_merge:V4SF
20807 (match_operand:V4SF 1 "register_operand" "0")
20808 (vec_duplicate:V4SF
20809 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20810 (const_int 12)))]
20811 "TARGET_SSE"
20812 "cvtpi2ps\t{%2, %0|%0, %2}"
20813 [(set_attr "type" "ssecvt")
20814 (set_attr "mode" "V4SF")])
20815
20816 (define_insn "cvtps2pi"
20817 [(set (match_operand:V2SI 0 "register_operand" "=y")
20818 (vec_select:V2SI
20819 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20820 (parallel [(const_int 0) (const_int 1)])))]
20821 "TARGET_SSE"
20822 "cvtps2pi\t{%1, %0|%0, %1}"
20823 [(set_attr "type" "ssecvt")
20824 (set_attr "mode" "V4SF")])
20825
20826 (define_insn "cvttps2pi"
20827 [(set (match_operand:V2SI 0 "register_operand" "=y")
20828 (vec_select:V2SI
20829 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20830 UNSPEC_FIX)
20831 (parallel [(const_int 0) (const_int 1)])))]
20832 "TARGET_SSE"
20833 "cvttps2pi\t{%1, %0|%0, %1}"
20834 [(set_attr "type" "ssecvt")
20835 (set_attr "mode" "SF")])
20836
20837 (define_insn "cvtsi2ss"
20838 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20839 (vec_merge:V4SF
20840 (match_operand:V4SF 1 "register_operand" "0,0")
20841 (vec_duplicate:V4SF
20842 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20843 (const_int 14)))]
20844 "TARGET_SSE"
20845 "cvtsi2ss\t{%2, %0|%0, %2}"
20846 [(set_attr "type" "sseicvt")
20847 (set_attr "athlon_decode" "vector,double")
20848 (set_attr "mode" "SF")])
20849
20850 (define_insn "cvtsi2ssq"
20851 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20852 (vec_merge:V4SF
20853 (match_operand:V4SF 1 "register_operand" "0,0")
20854 (vec_duplicate:V4SF
20855 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20856 (const_int 14)))]
20857 "TARGET_SSE && TARGET_64BIT"
20858 "cvtsi2ssq\t{%2, %0|%0, %2}"
20859 [(set_attr "type" "sseicvt")
20860 (set_attr "athlon_decode" "vector,double")
20861 (set_attr "mode" "SF")])
20862
20863 (define_insn "cvtss2si"
20864 [(set (match_operand:SI 0 "register_operand" "=r,r")
20865 (vec_select:SI
20866 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20867 (parallel [(const_int 0)])))]
20868 "TARGET_SSE"
20869 "cvtss2si\t{%1, %0|%0, %1}"
20870 [(set_attr "type" "sseicvt")
20871 (set_attr "athlon_decode" "double,vector")
20872 (set_attr "mode" "SI")])
20873
20874 (define_insn "cvtss2siq"
20875 [(set (match_operand:DI 0 "register_operand" "=r,r")
20876 (vec_select:DI
20877 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20878 (parallel [(const_int 0)])))]
20879 "TARGET_SSE"
20880 "cvtss2siq\t{%1, %0|%0, %1}"
20881 [(set_attr "type" "sseicvt")
20882 (set_attr "athlon_decode" "double,vector")
20883 (set_attr "mode" "DI")])
20884
20885 (define_insn "cvttss2si"
20886 [(set (match_operand:SI 0 "register_operand" "=r,r")
20887 (vec_select:SI
20888 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20889 UNSPEC_FIX)
20890 (parallel [(const_int 0)])))]
20891 "TARGET_SSE"
20892 "cvttss2si\t{%1, %0|%0, %1}"
20893 [(set_attr "type" "sseicvt")
20894 (set_attr "mode" "SF")
20895 (set_attr "athlon_decode" "double,vector")])
20896
20897 (define_insn "cvttss2siq"
20898 [(set (match_operand:DI 0 "register_operand" "=r,r")
20899 (vec_select:DI
20900 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20901 UNSPEC_FIX)
20902 (parallel [(const_int 0)])))]
20903 "TARGET_SSE && TARGET_64BIT"
20904 "cvttss2siq\t{%1, %0|%0, %1}"
20905 [(set_attr "type" "sseicvt")
20906 (set_attr "mode" "SF")
20907 (set_attr "athlon_decode" "double,vector")])
20908
20909
20910 ;; MMX insns
20911
20912 ;; MMX arithmetic
20913
20914 (define_insn "addv8qi3"
20915 [(set (match_operand:V8QI 0 "register_operand" "=y")
20916 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20917 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20918 "TARGET_MMX"
20919 "paddb\t{%2, %0|%0, %2}"
20920 [(set_attr "type" "mmxadd")
20921 (set_attr "mode" "DI")])
20922
20923 (define_insn "addv4hi3"
20924 [(set (match_operand:V4HI 0 "register_operand" "=y")
20925 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20926 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20927 "TARGET_MMX"
20928 "paddw\t{%2, %0|%0, %2}"
20929 [(set_attr "type" "mmxadd")
20930 (set_attr "mode" "DI")])
20931
20932 (define_insn "addv2si3"
20933 [(set (match_operand:V2SI 0 "register_operand" "=y")
20934 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20935 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20936 "TARGET_MMX"
20937 "paddd\t{%2, %0|%0, %2}"
20938 [(set_attr "type" "mmxadd")
20939 (set_attr "mode" "DI")])
20940
20941 (define_insn "mmx_adddi3"
20942 [(set (match_operand:DI 0 "register_operand" "=y")
20943 (unspec:DI
20944 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20945 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20946 UNSPEC_NOP))]
20947 "TARGET_MMX"
20948 "paddq\t{%2, %0|%0, %2}"
20949 [(set_attr "type" "mmxadd")
20950 (set_attr "mode" "DI")])
20951
20952 (define_insn "ssaddv8qi3"
20953 [(set (match_operand:V8QI 0 "register_operand" "=y")
20954 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20955 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20956 "TARGET_MMX"
20957 "paddsb\t{%2, %0|%0, %2}"
20958 [(set_attr "type" "mmxadd")
20959 (set_attr "mode" "DI")])
20960
20961 (define_insn "ssaddv4hi3"
20962 [(set (match_operand:V4HI 0 "register_operand" "=y")
20963 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20964 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20965 "TARGET_MMX"
20966 "paddsw\t{%2, %0|%0, %2}"
20967 [(set_attr "type" "mmxadd")
20968 (set_attr "mode" "DI")])
20969
20970 (define_insn "usaddv8qi3"
20971 [(set (match_operand:V8QI 0 "register_operand" "=y")
20972 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20973 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20974 "TARGET_MMX"
20975 "paddusb\t{%2, %0|%0, %2}"
20976 [(set_attr "type" "mmxadd")
20977 (set_attr "mode" "DI")])
20978
20979 (define_insn "usaddv4hi3"
20980 [(set (match_operand:V4HI 0 "register_operand" "=y")
20981 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20982 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20983 "TARGET_MMX"
20984 "paddusw\t{%2, %0|%0, %2}"
20985 [(set_attr "type" "mmxadd")
20986 (set_attr "mode" "DI")])
20987
20988 (define_insn "subv8qi3"
20989 [(set (match_operand:V8QI 0 "register_operand" "=y")
20990 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20991 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20992 "TARGET_MMX"
20993 "psubb\t{%2, %0|%0, %2}"
20994 [(set_attr "type" "mmxadd")
20995 (set_attr "mode" "DI")])
20996
20997 (define_insn "subv4hi3"
20998 [(set (match_operand:V4HI 0 "register_operand" "=y")
20999 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21000 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21001 "TARGET_MMX"
21002 "psubw\t{%2, %0|%0, %2}"
21003 [(set_attr "type" "mmxadd")
21004 (set_attr "mode" "DI")])
21005
21006 (define_insn "subv2si3"
21007 [(set (match_operand:V2SI 0 "register_operand" "=y")
21008 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21009 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21010 "TARGET_MMX"
21011 "psubd\t{%2, %0|%0, %2}"
21012 [(set_attr "type" "mmxadd")
21013 (set_attr "mode" "DI")])
21014
21015 (define_insn "mmx_subdi3"
21016 [(set (match_operand:DI 0 "register_operand" "=y")
21017 (unspec:DI
21018 [(minus:DI (match_operand:DI 1 "register_operand" "0")
21019 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21020 UNSPEC_NOP))]
21021 "TARGET_MMX"
21022 "psubq\t{%2, %0|%0, %2}"
21023 [(set_attr "type" "mmxadd")
21024 (set_attr "mode" "DI")])
21025
21026 (define_insn "sssubv8qi3"
21027 [(set (match_operand:V8QI 0 "register_operand" "=y")
21028 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21029 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21030 "TARGET_MMX"
21031 "psubsb\t{%2, %0|%0, %2}"
21032 [(set_attr "type" "mmxadd")
21033 (set_attr "mode" "DI")])
21034
21035 (define_insn "sssubv4hi3"
21036 [(set (match_operand:V4HI 0 "register_operand" "=y")
21037 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21038 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21039 "TARGET_MMX"
21040 "psubsw\t{%2, %0|%0, %2}"
21041 [(set_attr "type" "mmxadd")
21042 (set_attr "mode" "DI")])
21043
21044 (define_insn "ussubv8qi3"
21045 [(set (match_operand:V8QI 0 "register_operand" "=y")
21046 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21047 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21048 "TARGET_MMX"
21049 "psubusb\t{%2, %0|%0, %2}"
21050 [(set_attr "type" "mmxadd")
21051 (set_attr "mode" "DI")])
21052
21053 (define_insn "ussubv4hi3"
21054 [(set (match_operand:V4HI 0 "register_operand" "=y")
21055 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21056 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21057 "TARGET_MMX"
21058 "psubusw\t{%2, %0|%0, %2}"
21059 [(set_attr "type" "mmxadd")
21060 (set_attr "mode" "DI")])
21061
21062 (define_insn "mulv4hi3"
21063 [(set (match_operand:V4HI 0 "register_operand" "=y")
21064 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21065 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21066 "TARGET_MMX"
21067 "pmullw\t{%2, %0|%0, %2}"
21068 [(set_attr "type" "mmxmul")
21069 (set_attr "mode" "DI")])
21070
21071 (define_insn "smulv4hi3_highpart"
21072 [(set (match_operand:V4HI 0 "register_operand" "=y")
21073 (truncate:V4HI
21074 (lshiftrt:V4SI
21075 (mult:V4SI (sign_extend:V4SI
21076 (match_operand:V4HI 1 "register_operand" "0"))
21077 (sign_extend:V4SI
21078 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21079 (const_int 16))))]
21080 "TARGET_MMX"
21081 "pmulhw\t{%2, %0|%0, %2}"
21082 [(set_attr "type" "mmxmul")
21083 (set_attr "mode" "DI")])
21084
21085 (define_insn "umulv4hi3_highpart"
21086 [(set (match_operand:V4HI 0 "register_operand" "=y")
21087 (truncate:V4HI
21088 (lshiftrt:V4SI
21089 (mult:V4SI (zero_extend:V4SI
21090 (match_operand:V4HI 1 "register_operand" "0"))
21091 (zero_extend:V4SI
21092 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21093 (const_int 16))))]
21094 "TARGET_SSE || TARGET_3DNOW_A"
21095 "pmulhuw\t{%2, %0|%0, %2}"
21096 [(set_attr "type" "mmxmul")
21097 (set_attr "mode" "DI")])
21098
21099 (define_insn "mmx_pmaddwd"
21100 [(set (match_operand:V2SI 0 "register_operand" "=y")
21101 (plus:V2SI
21102 (mult:V2SI
21103 (sign_extend:V2SI
21104 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21105 (parallel [(const_int 0) (const_int 2)])))
21106 (sign_extend:V2SI
21107 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21108 (parallel [(const_int 0) (const_int 2)]))))
21109 (mult:V2SI
21110 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21111 (parallel [(const_int 1)
21112 (const_int 3)])))
21113 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21114 (parallel [(const_int 1)
21115 (const_int 3)]))))))]
21116 "TARGET_MMX"
21117 "pmaddwd\t{%2, %0|%0, %2}"
21118 [(set_attr "type" "mmxmul")
21119 (set_attr "mode" "DI")])
21120
21121
21122 ;; MMX logical operations
21123 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21124 ;; normal code that also wants to use the FPU from getting broken.
21125 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21126 (define_insn "mmx_iordi3"
21127 [(set (match_operand:DI 0 "register_operand" "=y")
21128 (unspec:DI
21129 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21130 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21131 UNSPEC_NOP))]
21132 "TARGET_MMX"
21133 "por\t{%2, %0|%0, %2}"
21134 [(set_attr "type" "mmxadd")
21135 (set_attr "mode" "DI")])
21136
21137 (define_insn "mmx_xordi3"
21138 [(set (match_operand:DI 0 "register_operand" "=y")
21139 (unspec:DI
21140 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21141 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21142 UNSPEC_NOP))]
21143 "TARGET_MMX"
21144 "pxor\t{%2, %0|%0, %2}"
21145 [(set_attr "type" "mmxadd")
21146 (set_attr "mode" "DI")
21147 (set_attr "memory" "none")])
21148
21149 ;; Same as pxor, but don't show input operands so that we don't think
21150 ;; they are live.
21151 (define_insn "mmx_clrdi"
21152 [(set (match_operand:DI 0 "register_operand" "=y")
21153 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21154 "TARGET_MMX"
21155 "pxor\t{%0, %0|%0, %0}"
21156 [(set_attr "type" "mmxadd")
21157 (set_attr "mode" "DI")
21158 (set_attr "memory" "none")])
21159
21160 (define_insn "mmx_anddi3"
21161 [(set (match_operand:DI 0 "register_operand" "=y")
21162 (unspec:DI
21163 [(and:DI (match_operand:DI 1 "register_operand" "%0")
21164 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21165 UNSPEC_NOP))]
21166 "TARGET_MMX"
21167 "pand\t{%2, %0|%0, %2}"
21168 [(set_attr "type" "mmxadd")
21169 (set_attr "mode" "DI")])
21170
21171 (define_insn "mmx_nanddi3"
21172 [(set (match_operand:DI 0 "register_operand" "=y")
21173 (unspec:DI
21174 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21175 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21176 UNSPEC_NOP))]
21177 "TARGET_MMX"
21178 "pandn\t{%2, %0|%0, %2}"
21179 [(set_attr "type" "mmxadd")
21180 (set_attr "mode" "DI")])
21181
21182
21183 ;; MMX unsigned averages/sum of absolute differences
21184
21185 (define_insn "mmx_uavgv8qi3"
21186 [(set (match_operand:V8QI 0 "register_operand" "=y")
21187 (ashiftrt:V8QI
21188 (plus:V8QI (plus:V8QI
21189 (match_operand:V8QI 1 "register_operand" "0")
21190 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21191 (const_vector:V8QI [(const_int 1)
21192 (const_int 1)
21193 (const_int 1)
21194 (const_int 1)
21195 (const_int 1)
21196 (const_int 1)
21197 (const_int 1)
21198 (const_int 1)]))
21199 (const_int 1)))]
21200 "TARGET_SSE || TARGET_3DNOW_A"
21201 "pavgb\t{%2, %0|%0, %2}"
21202 [(set_attr "type" "mmxshft")
21203 (set_attr "mode" "DI")])
21204
21205 (define_insn "mmx_uavgv4hi3"
21206 [(set (match_operand:V4HI 0 "register_operand" "=y")
21207 (ashiftrt:V4HI
21208 (plus:V4HI (plus:V4HI
21209 (match_operand:V4HI 1 "register_operand" "0")
21210 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21211 (const_vector:V4HI [(const_int 1)
21212 (const_int 1)
21213 (const_int 1)
21214 (const_int 1)]))
21215 (const_int 1)))]
21216 "TARGET_SSE || TARGET_3DNOW_A"
21217 "pavgw\t{%2, %0|%0, %2}"
21218 [(set_attr "type" "mmxshft")
21219 (set_attr "mode" "DI")])
21220
21221 (define_insn "mmx_psadbw"
21222 [(set (match_operand:DI 0 "register_operand" "=y")
21223 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21224 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21225 UNSPEC_PSADBW))]
21226 "TARGET_SSE || TARGET_3DNOW_A"
21227 "psadbw\t{%2, %0|%0, %2}"
21228 [(set_attr "type" "mmxshft")
21229 (set_attr "mode" "DI")])
21230
21231
21232 ;; MMX insert/extract/shuffle
21233
21234 (define_insn "mmx_pinsrw"
21235 [(set (match_operand:V4HI 0 "register_operand" "=y")
21236 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21237 (vec_duplicate:V4HI
21238 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21239 (match_operand:SI 3 "immediate_operand" "i")))]
21240 "TARGET_SSE || TARGET_3DNOW_A"
21241 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21242 [(set_attr "type" "mmxcvt")
21243 (set_attr "mode" "DI")])
21244
21245 (define_insn "mmx_pextrw"
21246 [(set (match_operand:SI 0 "register_operand" "=r")
21247 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21248 (parallel
21249 [(match_operand:SI 2 "immediate_operand" "i")]))))]
21250 "TARGET_SSE || TARGET_3DNOW_A"
21251 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21252 [(set_attr "type" "mmxcvt")
21253 (set_attr "mode" "DI")])
21254
21255 (define_insn "mmx_pshufw"
21256 [(set (match_operand:V4HI 0 "register_operand" "=y")
21257 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
21258 (match_operand:SI 2 "immediate_operand" "i")]
21259 UNSPEC_SHUFFLE))]
21260 "TARGET_SSE || TARGET_3DNOW_A"
21261 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21262 [(set_attr "type" "mmxcvt")
21263 (set_attr "mode" "DI")])
21264
21265
21266 ;; MMX mask-generating comparisons
21267
21268 (define_insn "eqv8qi3"
21269 [(set (match_operand:V8QI 0 "register_operand" "=y")
21270 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21271 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21272 "TARGET_MMX"
21273 "pcmpeqb\t{%2, %0|%0, %2}"
21274 [(set_attr "type" "mmxcmp")
21275 (set_attr "mode" "DI")])
21276
21277 (define_insn "eqv4hi3"
21278 [(set (match_operand:V4HI 0 "register_operand" "=y")
21279 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21280 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21281 "TARGET_MMX"
21282 "pcmpeqw\t{%2, %0|%0, %2}"
21283 [(set_attr "type" "mmxcmp")
21284 (set_attr "mode" "DI")])
21285
21286 (define_insn "eqv2si3"
21287 [(set (match_operand:V2SI 0 "register_operand" "=y")
21288 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21289 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21290 "TARGET_MMX"
21291 "pcmpeqd\t{%2, %0|%0, %2}"
21292 [(set_attr "type" "mmxcmp")
21293 (set_attr "mode" "DI")])
21294
21295 (define_insn "gtv8qi3"
21296 [(set (match_operand:V8QI 0 "register_operand" "=y")
21297 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21298 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21299 "TARGET_MMX"
21300 "pcmpgtb\t{%2, %0|%0, %2}"
21301 [(set_attr "type" "mmxcmp")
21302 (set_attr "mode" "DI")])
21303
21304 (define_insn "gtv4hi3"
21305 [(set (match_operand:V4HI 0 "register_operand" "=y")
21306 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21307 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21308 "TARGET_MMX"
21309 "pcmpgtw\t{%2, %0|%0, %2}"
21310 [(set_attr "type" "mmxcmp")
21311 (set_attr "mode" "DI")])
21312
21313 (define_insn "gtv2si3"
21314 [(set (match_operand:V2SI 0 "register_operand" "=y")
21315 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21316 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21317 "TARGET_MMX"
21318 "pcmpgtd\t{%2, %0|%0, %2}"
21319 [(set_attr "type" "mmxcmp")
21320 (set_attr "mode" "DI")])
21321
21322
21323 ;; MMX max/min insns
21324
21325 (define_insn "umaxv8qi3"
21326 [(set (match_operand:V8QI 0 "register_operand" "=y")
21327 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21328 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21329 "TARGET_SSE || TARGET_3DNOW_A"
21330 "pmaxub\t{%2, %0|%0, %2}"
21331 [(set_attr "type" "mmxadd")
21332 (set_attr "mode" "DI")])
21333
21334 (define_insn "smaxv4hi3"
21335 [(set (match_operand:V4HI 0 "register_operand" "=y")
21336 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21337 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21338 "TARGET_SSE || TARGET_3DNOW_A"
21339 "pmaxsw\t{%2, %0|%0, %2}"
21340 [(set_attr "type" "mmxadd")
21341 (set_attr "mode" "DI")])
21342
21343 (define_insn "uminv8qi3"
21344 [(set (match_operand:V8QI 0 "register_operand" "=y")
21345 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21346 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21347 "TARGET_SSE || TARGET_3DNOW_A"
21348 "pminub\t{%2, %0|%0, %2}"
21349 [(set_attr "type" "mmxadd")
21350 (set_attr "mode" "DI")])
21351
21352 (define_insn "sminv4hi3"
21353 [(set (match_operand:V4HI 0 "register_operand" "=y")
21354 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21355 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21356 "TARGET_SSE || TARGET_3DNOW_A"
21357 "pminsw\t{%2, %0|%0, %2}"
21358 [(set_attr "type" "mmxadd")
21359 (set_attr "mode" "DI")])
21360
21361
21362 ;; MMX shifts
21363
21364 (define_insn "ashrv4hi3"
21365 [(set (match_operand:V4HI 0 "register_operand" "=y")
21366 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21367 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21368 "TARGET_MMX"
21369 "psraw\t{%2, %0|%0, %2}"
21370 [(set_attr "type" "mmxshft")
21371 (set_attr "mode" "DI")])
21372
21373 (define_insn "ashrv2si3"
21374 [(set (match_operand:V2SI 0 "register_operand" "=y")
21375 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21376 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21377 "TARGET_MMX"
21378 "psrad\t{%2, %0|%0, %2}"
21379 [(set_attr "type" "mmxshft")
21380 (set_attr "mode" "DI")])
21381
21382 (define_insn "lshrv4hi3"
21383 [(set (match_operand:V4HI 0 "register_operand" "=y")
21384 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21385 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21386 "TARGET_MMX"
21387 "psrlw\t{%2, %0|%0, %2}"
21388 [(set_attr "type" "mmxshft")
21389 (set_attr "mode" "DI")])
21390
21391 (define_insn "lshrv2si3"
21392 [(set (match_operand:V2SI 0 "register_operand" "=y")
21393 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21394 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21395 "TARGET_MMX"
21396 "psrld\t{%2, %0|%0, %2}"
21397 [(set_attr "type" "mmxshft")
21398 (set_attr "mode" "DI")])
21399
21400 ;; See logical MMX insns.
21401 (define_insn "mmx_lshrdi3"
21402 [(set (match_operand:DI 0 "register_operand" "=y")
21403 (unspec:DI
21404 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21405 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21406 UNSPEC_NOP))]
21407 "TARGET_MMX"
21408 "psrlq\t{%2, %0|%0, %2}"
21409 [(set_attr "type" "mmxshft")
21410 (set_attr "mode" "DI")])
21411
21412 (define_insn "ashlv4hi3"
21413 [(set (match_operand:V4HI 0 "register_operand" "=y")
21414 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21415 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21416 "TARGET_MMX"
21417 "psllw\t{%2, %0|%0, %2}"
21418 [(set_attr "type" "mmxshft")
21419 (set_attr "mode" "DI")])
21420
21421 (define_insn "ashlv2si3"
21422 [(set (match_operand:V2SI 0 "register_operand" "=y")
21423 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21424 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21425 "TARGET_MMX"
21426 "pslld\t{%2, %0|%0, %2}"
21427 [(set_attr "type" "mmxshft")
21428 (set_attr "mode" "DI")])
21429
21430 ;; See logical MMX insns.
21431 (define_insn "mmx_ashldi3"
21432 [(set (match_operand:DI 0 "register_operand" "=y")
21433 (unspec:DI
21434 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21435 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21436 UNSPEC_NOP))]
21437 "TARGET_MMX"
21438 "psllq\t{%2, %0|%0, %2}"
21439 [(set_attr "type" "mmxshft")
21440 (set_attr "mode" "DI")])
21441
21442
21443 ;; MMX pack/unpack insns.
21444
21445 (define_insn "mmx_packsswb"
21446 [(set (match_operand:V8QI 0 "register_operand" "=y")
21447 (vec_concat:V8QI
21448 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21449 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21450 "TARGET_MMX"
21451 "packsswb\t{%2, %0|%0, %2}"
21452 [(set_attr "type" "mmxshft")
21453 (set_attr "mode" "DI")])
21454
21455 (define_insn "mmx_packssdw"
21456 [(set (match_operand:V4HI 0 "register_operand" "=y")
21457 (vec_concat:V4HI
21458 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21459 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21460 "TARGET_MMX"
21461 "packssdw\t{%2, %0|%0, %2}"
21462 [(set_attr "type" "mmxshft")
21463 (set_attr "mode" "DI")])
21464
21465 (define_insn "mmx_packuswb"
21466 [(set (match_operand:V8QI 0 "register_operand" "=y")
21467 (vec_concat:V8QI
21468 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21469 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21470 "TARGET_MMX"
21471 "packuswb\t{%2, %0|%0, %2}"
21472 [(set_attr "type" "mmxshft")
21473 (set_attr "mode" "DI")])
21474
21475 (define_insn "mmx_punpckhbw"
21476 [(set (match_operand:V8QI 0 "register_operand" "=y")
21477 (vec_merge:V8QI
21478 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21479 (parallel [(const_int 4)
21480 (const_int 0)
21481 (const_int 5)
21482 (const_int 1)
21483 (const_int 6)
21484 (const_int 2)
21485 (const_int 7)
21486 (const_int 3)]))
21487 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21488 (parallel [(const_int 0)
21489 (const_int 4)
21490 (const_int 1)
21491 (const_int 5)
21492 (const_int 2)
21493 (const_int 6)
21494 (const_int 3)
21495 (const_int 7)]))
21496 (const_int 85)))]
21497 "TARGET_MMX"
21498 "punpckhbw\t{%2, %0|%0, %2}"
21499 [(set_attr "type" "mmxcvt")
21500 (set_attr "mode" "DI")])
21501
21502 (define_insn "mmx_punpckhwd"
21503 [(set (match_operand:V4HI 0 "register_operand" "=y")
21504 (vec_merge:V4HI
21505 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21506 (parallel [(const_int 0)
21507 (const_int 2)
21508 (const_int 1)
21509 (const_int 3)]))
21510 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21511 (parallel [(const_int 2)
21512 (const_int 0)
21513 (const_int 3)
21514 (const_int 1)]))
21515 (const_int 5)))]
21516 "TARGET_MMX"
21517 "punpckhwd\t{%2, %0|%0, %2}"
21518 [(set_attr "type" "mmxcvt")
21519 (set_attr "mode" "DI")])
21520
21521 (define_insn "mmx_punpckhdq"
21522 [(set (match_operand:V2SI 0 "register_operand" "=y")
21523 (vec_merge:V2SI
21524 (match_operand:V2SI 1 "register_operand" "0")
21525 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21526 (parallel [(const_int 1)
21527 (const_int 0)]))
21528 (const_int 1)))]
21529 "TARGET_MMX"
21530 "punpckhdq\t{%2, %0|%0, %2}"
21531 [(set_attr "type" "mmxcvt")
21532 (set_attr "mode" "DI")])
21533
21534 (define_insn "mmx_punpcklbw"
21535 [(set (match_operand:V8QI 0 "register_operand" "=y")
21536 (vec_merge:V8QI
21537 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21538 (parallel [(const_int 0)
21539 (const_int 4)
21540 (const_int 1)
21541 (const_int 5)
21542 (const_int 2)
21543 (const_int 6)
21544 (const_int 3)
21545 (const_int 7)]))
21546 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21547 (parallel [(const_int 4)
21548 (const_int 0)
21549 (const_int 5)
21550 (const_int 1)
21551 (const_int 6)
21552 (const_int 2)
21553 (const_int 7)
21554 (const_int 3)]))
21555 (const_int 85)))]
21556 "TARGET_MMX"
21557 "punpcklbw\t{%2, %0|%0, %2}"
21558 [(set_attr "type" "mmxcvt")
21559 (set_attr "mode" "DI")])
21560
21561 (define_insn "mmx_punpcklwd"
21562 [(set (match_operand:V4HI 0 "register_operand" "=y")
21563 (vec_merge:V4HI
21564 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21565 (parallel [(const_int 2)
21566 (const_int 0)
21567 (const_int 3)
21568 (const_int 1)]))
21569 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21570 (parallel [(const_int 0)
21571 (const_int 2)
21572 (const_int 1)
21573 (const_int 3)]))
21574 (const_int 5)))]
21575 "TARGET_MMX"
21576 "punpcklwd\t{%2, %0|%0, %2}"
21577 [(set_attr "type" "mmxcvt")
21578 (set_attr "mode" "DI")])
21579
21580 (define_insn "mmx_punpckldq"
21581 [(set (match_operand:V2SI 0 "register_operand" "=y")
21582 (vec_merge:V2SI
21583 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21584 (parallel [(const_int 1)
21585 (const_int 0)]))
21586 (match_operand:V2SI 2 "register_operand" "y")
21587 (const_int 1)))]
21588 "TARGET_MMX"
21589 "punpckldq\t{%2, %0|%0, %2}"
21590 [(set_attr "type" "mmxcvt")
21591 (set_attr "mode" "DI")])
21592
21593
21594 ;; Miscellaneous stuff
21595
21596 (define_insn "emms"
21597 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21598 (clobber (reg:XF 8))
21599 (clobber (reg:XF 9))
21600 (clobber (reg:XF 10))
21601 (clobber (reg:XF 11))
21602 (clobber (reg:XF 12))
21603 (clobber (reg:XF 13))
21604 (clobber (reg:XF 14))
21605 (clobber (reg:XF 15))
21606 (clobber (reg:DI 29))
21607 (clobber (reg:DI 30))
21608 (clobber (reg:DI 31))
21609 (clobber (reg:DI 32))
21610 (clobber (reg:DI 33))
21611 (clobber (reg:DI 34))
21612 (clobber (reg:DI 35))
21613 (clobber (reg:DI 36))]
21614 "TARGET_MMX"
21615 "emms"
21616 [(set_attr "type" "mmx")
21617 (set_attr "memory" "unknown")])
21618
21619 (define_insn "ldmxcsr"
21620 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21621 UNSPECV_LDMXCSR)]
21622 "TARGET_SSE"
21623 "ldmxcsr\t%0"
21624 [(set_attr "type" "sse")
21625 (set_attr "memory" "load")])
21626
21627 (define_insn "stmxcsr"
21628 [(set (match_operand:SI 0 "memory_operand" "=m")
21629 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21630 "TARGET_SSE"
21631 "stmxcsr\t%0"
21632 [(set_attr "type" "sse")
21633 (set_attr "memory" "store")])
21634
21635 (define_expand "sfence"
21636 [(set (match_dup 0)
21637 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21638 "TARGET_SSE || TARGET_3DNOW_A"
21639 {
21640 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21641 MEM_VOLATILE_P (operands[0]) = 1;
21642 })
21643
21644 (define_insn "*sfence_insn"
21645 [(set (match_operand:BLK 0 "" "")
21646 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21647 "TARGET_SSE || TARGET_3DNOW_A"
21648 "sfence"
21649 [(set_attr "type" "sse")
21650 (set_attr "memory" "unknown")])
21651
21652 (define_expand "sse_prologue_save"
21653 [(parallel [(set (match_operand:BLK 0 "" "")
21654 (unspec:BLK [(reg:DI 21)
21655 (reg:DI 22)
21656 (reg:DI 23)
21657 (reg:DI 24)
21658 (reg:DI 25)
21659 (reg:DI 26)
21660 (reg:DI 27)
21661 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21662 (use (match_operand:DI 1 "register_operand" ""))
21663 (use (match_operand:DI 2 "immediate_operand" ""))
21664 (use (label_ref:DI (match_operand 3 "" "")))])]
21665 "TARGET_64BIT"
21666 "")
21667
21668 (define_insn "*sse_prologue_save_insn"
21669 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21670 (match_operand:DI 4 "const_int_operand" "n")))
21671 (unspec:BLK [(reg:DI 21)
21672 (reg:DI 22)
21673 (reg:DI 23)
21674 (reg:DI 24)
21675 (reg:DI 25)
21676 (reg:DI 26)
21677 (reg:DI 27)
21678 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21679 (use (match_operand:DI 1 "register_operand" "r"))
21680 (use (match_operand:DI 2 "const_int_operand" "i"))
21681 (use (label_ref:DI (match_operand 3 "" "X")))]
21682 "TARGET_64BIT
21683 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21684 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21685 "*
21686 {
21687 int i;
21688 operands[0] = gen_rtx_MEM (Pmode,
21689 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21690 output_asm_insn (\"jmp\\t%A1\", operands);
21691 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21692 {
21693 operands[4] = adjust_address (operands[0], DImode, i*16);
21694 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21695 PUT_MODE (operands[4], TImode);
21696 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21697 output_asm_insn (\"rex\", operands);
21698 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21699 }
21700 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21701 CODE_LABEL_NUMBER (operands[3]));
21702 RET;
21703 }
21704 "
21705 [(set_attr "type" "other")
21706 (set_attr "length_immediate" "0")
21707 (set_attr "length_address" "0")
21708 (set_attr "length" "135")
21709 (set_attr "memory" "store")
21710 (set_attr "modrm" "0")
21711 (set_attr "mode" "DI")])
21712
21713 ;; 3Dnow! instructions
21714
21715 (define_insn "addv2sf3"
21716 [(set (match_operand:V2SF 0 "register_operand" "=y")
21717 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21718 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21719 "TARGET_3DNOW"
21720 "pfadd\\t{%2, %0|%0, %2}"
21721 [(set_attr "type" "mmxadd")
21722 (set_attr "mode" "V2SF")])
21723
21724 (define_insn "subv2sf3"
21725 [(set (match_operand:V2SF 0 "register_operand" "=y")
21726 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21727 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21728 "TARGET_3DNOW"
21729 "pfsub\\t{%2, %0|%0, %2}"
21730 [(set_attr "type" "mmxadd")
21731 (set_attr "mode" "V2SF")])
21732
21733 (define_insn "subrv2sf3"
21734 [(set (match_operand:V2SF 0 "register_operand" "=y")
21735 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21736 (match_operand:V2SF 1 "register_operand" "0")))]
21737 "TARGET_3DNOW"
21738 "pfsubr\\t{%2, %0|%0, %2}"
21739 [(set_attr "type" "mmxadd")
21740 (set_attr "mode" "V2SF")])
21741
21742 (define_insn "gtv2sf3"
21743 [(set (match_operand:V2SI 0 "register_operand" "=y")
21744 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21745 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21746 "TARGET_3DNOW"
21747 "pfcmpgt\\t{%2, %0|%0, %2}"
21748 [(set_attr "type" "mmxcmp")
21749 (set_attr "mode" "V2SF")])
21750
21751 (define_insn "gev2sf3"
21752 [(set (match_operand:V2SI 0 "register_operand" "=y")
21753 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21754 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21755 "TARGET_3DNOW"
21756 "pfcmpge\\t{%2, %0|%0, %2}"
21757 [(set_attr "type" "mmxcmp")
21758 (set_attr "mode" "V2SF")])
21759
21760 (define_insn "eqv2sf3"
21761 [(set (match_operand:V2SI 0 "register_operand" "=y")
21762 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21763 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21764 "TARGET_3DNOW"
21765 "pfcmpeq\\t{%2, %0|%0, %2}"
21766 [(set_attr "type" "mmxcmp")
21767 (set_attr "mode" "V2SF")])
21768
21769 (define_insn "pfmaxv2sf3"
21770 [(set (match_operand:V2SF 0 "register_operand" "=y")
21771 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21772 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21773 "TARGET_3DNOW"
21774 "pfmax\\t{%2, %0|%0, %2}"
21775 [(set_attr "type" "mmxadd")
21776 (set_attr "mode" "V2SF")])
21777
21778 (define_insn "pfminv2sf3"
21779 [(set (match_operand:V2SF 0 "register_operand" "=y")
21780 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21781 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21782 "TARGET_3DNOW"
21783 "pfmin\\t{%2, %0|%0, %2}"
21784 [(set_attr "type" "mmxadd")
21785 (set_attr "mode" "V2SF")])
21786
21787 (define_insn "mulv2sf3"
21788 [(set (match_operand:V2SF 0 "register_operand" "=y")
21789 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21790 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21791 "TARGET_3DNOW"
21792 "pfmul\\t{%2, %0|%0, %2}"
21793 [(set_attr "type" "mmxmul")
21794 (set_attr "mode" "V2SF")])
21795
21796 (define_insn "femms"
21797 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21798 (clobber (reg:XF 8))
21799 (clobber (reg:XF 9))
21800 (clobber (reg:XF 10))
21801 (clobber (reg:XF 11))
21802 (clobber (reg:XF 12))
21803 (clobber (reg:XF 13))
21804 (clobber (reg:XF 14))
21805 (clobber (reg:XF 15))
21806 (clobber (reg:DI 29))
21807 (clobber (reg:DI 30))
21808 (clobber (reg:DI 31))
21809 (clobber (reg:DI 32))
21810 (clobber (reg:DI 33))
21811 (clobber (reg:DI 34))
21812 (clobber (reg:DI 35))
21813 (clobber (reg:DI 36))]
21814 "TARGET_3DNOW"
21815 "femms"
21816 [(set_attr "type" "mmx")
21817 (set_attr "memory" "none")])
21818
21819 (define_insn "pf2id"
21820 [(set (match_operand:V2SI 0 "register_operand" "=y")
21821 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21822 "TARGET_3DNOW"
21823 "pf2id\\t{%1, %0|%0, %1}"
21824 [(set_attr "type" "mmxcvt")
21825 (set_attr "mode" "V2SF")])
21826
21827 (define_insn "pf2iw"
21828 [(set (match_operand:V2SI 0 "register_operand" "=y")
21829 (sign_extend:V2SI
21830 (ss_truncate:V2HI
21831 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21832 "TARGET_3DNOW_A"
21833 "pf2iw\\t{%1, %0|%0, %1}"
21834 [(set_attr "type" "mmxcvt")
21835 (set_attr "mode" "V2SF")])
21836
21837 (define_insn "pfacc"
21838 [(set (match_operand:V2SF 0 "register_operand" "=y")
21839 (vec_concat:V2SF
21840 (plus:SF
21841 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21842 (parallel [(const_int 0)]))
21843 (vec_select:SF (match_dup 1)
21844 (parallel [(const_int 1)])))
21845 (plus:SF
21846 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21847 (parallel [(const_int 0)]))
21848 (vec_select:SF (match_dup 2)
21849 (parallel [(const_int 1)])))))]
21850 "TARGET_3DNOW"
21851 "pfacc\\t{%2, %0|%0, %2}"
21852 [(set_attr "type" "mmxadd")
21853 (set_attr "mode" "V2SF")])
21854
21855 (define_insn "pfnacc"
21856 [(set (match_operand:V2SF 0 "register_operand" "=y")
21857 (vec_concat:V2SF
21858 (minus:SF
21859 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21860 (parallel [(const_int 0)]))
21861 (vec_select:SF (match_dup 1)
21862 (parallel [(const_int 1)])))
21863 (minus:SF
21864 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21865 (parallel [(const_int 0)]))
21866 (vec_select:SF (match_dup 2)
21867 (parallel [(const_int 1)])))))]
21868 "TARGET_3DNOW_A"
21869 "pfnacc\\t{%2, %0|%0, %2}"
21870 [(set_attr "type" "mmxadd")
21871 (set_attr "mode" "V2SF")])
21872
21873 (define_insn "pfpnacc"
21874 [(set (match_operand:V2SF 0 "register_operand" "=y")
21875 (vec_concat:V2SF
21876 (minus:SF
21877 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21878 (parallel [(const_int 0)]))
21879 (vec_select:SF (match_dup 1)
21880 (parallel [(const_int 1)])))
21881 (plus:SF
21882 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21883 (parallel [(const_int 0)]))
21884 (vec_select:SF (match_dup 2)
21885 (parallel [(const_int 1)])))))]
21886 "TARGET_3DNOW_A"
21887 "pfpnacc\\t{%2, %0|%0, %2}"
21888 [(set_attr "type" "mmxadd")
21889 (set_attr "mode" "V2SF")])
21890
21891 (define_insn "pi2fw"
21892 [(set (match_operand:V2SF 0 "register_operand" "=y")
21893 (float:V2SF
21894 (vec_concat:V2SI
21895 (sign_extend:SI
21896 (truncate:HI
21897 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21898 (parallel [(const_int 0)]))))
21899 (sign_extend:SI
21900 (truncate:HI
21901 (vec_select:SI (match_dup 1)
21902 (parallel [(const_int 1)])))))))]
21903 "TARGET_3DNOW_A"
21904 "pi2fw\\t{%1, %0|%0, %1}"
21905 [(set_attr "type" "mmxcvt")
21906 (set_attr "mode" "V2SF")])
21907
21908 (define_insn "floatv2si2"
21909 [(set (match_operand:V2SF 0 "register_operand" "=y")
21910 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21911 "TARGET_3DNOW"
21912 "pi2fd\\t{%1, %0|%0, %1}"
21913 [(set_attr "type" "mmxcvt")
21914 (set_attr "mode" "V2SF")])
21915
21916 ;; This insn is identical to pavgb in operation, but the opcode is
21917 ;; different. To avoid accidentally matching pavgb, use an unspec.
21918
21919 (define_insn "pavgusb"
21920 [(set (match_operand:V8QI 0 "register_operand" "=y")
21921 (unspec:V8QI
21922 [(match_operand:V8QI 1 "register_operand" "0")
21923 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21924 UNSPEC_PAVGUSB))]
21925 "TARGET_3DNOW"
21926 "pavgusb\\t{%2, %0|%0, %2}"
21927 [(set_attr "type" "mmxshft")
21928 (set_attr "mode" "TI")])
21929
21930 ;; 3DNow reciprocal and sqrt
21931
21932 (define_insn "pfrcpv2sf2"
21933 [(set (match_operand:V2SF 0 "register_operand" "=y")
21934 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21935 UNSPEC_PFRCP))]
21936 "TARGET_3DNOW"
21937 "pfrcp\\t{%1, %0|%0, %1}"
21938 [(set_attr "type" "mmx")
21939 (set_attr "mode" "TI")])
21940
21941 (define_insn "pfrcpit1v2sf3"
21942 [(set (match_operand:V2SF 0 "register_operand" "=y")
21943 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21944 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21945 UNSPEC_PFRCPIT1))]
21946 "TARGET_3DNOW"
21947 "pfrcpit1\\t{%2, %0|%0, %2}"
21948 [(set_attr "type" "mmx")
21949 (set_attr "mode" "TI")])
21950
21951 (define_insn "pfrcpit2v2sf3"
21952 [(set (match_operand:V2SF 0 "register_operand" "=y")
21953 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21954 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21955 UNSPEC_PFRCPIT2))]
21956 "TARGET_3DNOW"
21957 "pfrcpit2\\t{%2, %0|%0, %2}"
21958 [(set_attr "type" "mmx")
21959 (set_attr "mode" "TI")])
21960
21961 (define_insn "pfrsqrtv2sf2"
21962 [(set (match_operand:V2SF 0 "register_operand" "=y")
21963 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21964 UNSPEC_PFRSQRT))]
21965 "TARGET_3DNOW"
21966 "pfrsqrt\\t{%1, %0|%0, %1}"
21967 [(set_attr "type" "mmx")
21968 (set_attr "mode" "TI")])
21969
21970 (define_insn "pfrsqit1v2sf3"
21971 [(set (match_operand:V2SF 0 "register_operand" "=y")
21972 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21973 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21974 UNSPEC_PFRSQIT1))]
21975 "TARGET_3DNOW"
21976 "pfrsqit1\\t{%2, %0|%0, %2}"
21977 [(set_attr "type" "mmx")
21978 (set_attr "mode" "TI")])
21979
21980 (define_insn "pmulhrwv4hi3"
21981 [(set (match_operand:V4HI 0 "register_operand" "=y")
21982 (truncate:V4HI
21983 (lshiftrt:V4SI
21984 (plus:V4SI
21985 (mult:V4SI
21986 (sign_extend:V4SI
21987 (match_operand:V4HI 1 "register_operand" "0"))
21988 (sign_extend:V4SI
21989 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21990 (const_vector:V4SI [(const_int 32768)
21991 (const_int 32768)
21992 (const_int 32768)
21993 (const_int 32768)]))
21994 (const_int 16))))]
21995 "TARGET_3DNOW"
21996 "pmulhrw\\t{%2, %0|%0, %2}"
21997 [(set_attr "type" "mmxmul")
21998 (set_attr "mode" "TI")])
21999
22000 (define_insn "pswapdv2si2"
22001 [(set (match_operand:V2SI 0 "register_operand" "=y")
22002 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22003 (parallel [(const_int 1) (const_int 0)])))]
22004 "TARGET_3DNOW_A"
22005 "pswapd\\t{%1, %0|%0, %1}"
22006 [(set_attr "type" "mmxcvt")
22007 (set_attr "mode" "TI")])
22008
22009 (define_insn "pswapdv2sf2"
22010 [(set (match_operand:V2SF 0 "register_operand" "=y")
22011 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22012 (parallel [(const_int 1) (const_int 0)])))]
22013 "TARGET_3DNOW_A"
22014 "pswapd\\t{%1, %0|%0, %1}"
22015 [(set_attr "type" "mmxcvt")
22016 (set_attr "mode" "TI")])
22017
22018 (define_expand "prefetch"
22019 [(prefetch (match_operand 0 "address_operand" "")
22020 (match_operand:SI 1 "const_int_operand" "")
22021 (match_operand:SI 2 "const_int_operand" ""))]
22022 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22023 {
22024 int rw = INTVAL (operands[1]);
22025 int locality = INTVAL (operands[2]);
22026
22027 if (rw != 0 && rw != 1)
22028 abort ();
22029 if (locality < 0 || locality > 3)
22030 abort ();
22031 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22032 abort ();
22033
22034 /* Use 3dNOW prefetch in case we are asking for write prefetch not
22035 suported by SSE counterpart or the SSE prefetch is not available
22036 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22037 of locality. */
22038 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22039 operands[2] = GEN_INT (3);
22040 else
22041 operands[1] = const0_rtx;
22042 })
22043
22044 (define_insn "*prefetch_sse"
22045 [(prefetch (match_operand:SI 0 "address_operand" "p")
22046 (const_int 0)
22047 (match_operand:SI 1 "const_int_operand" ""))]
22048 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22049 {
22050 static const char * const patterns[4] = {
22051 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22052 };
22053
22054 int locality = INTVAL (operands[1]);
22055 if (locality < 0 || locality > 3)
22056 abort ();
22057
22058 return patterns[locality];
22059 }
22060 [(set_attr "type" "sse")
22061 (set_attr "memory" "none")])
22062
22063 (define_insn "*prefetch_sse_rex"
22064 [(prefetch (match_operand:DI 0 "address_operand" "p")
22065 (const_int 0)
22066 (match_operand:SI 1 "const_int_operand" ""))]
22067 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22068 {
22069 static const char * const patterns[4] = {
22070 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22071 };
22072
22073 int locality = INTVAL (operands[1]);
22074 if (locality < 0 || locality > 3)
22075 abort ();
22076
22077 return patterns[locality];
22078 }
22079 [(set_attr "type" "sse")
22080 (set_attr "memory" "none")])
22081
22082 (define_insn "*prefetch_3dnow"
22083 [(prefetch (match_operand:SI 0 "address_operand" "p")
22084 (match_operand:SI 1 "const_int_operand" "n")
22085 (const_int 3))]
22086 "TARGET_3DNOW && !TARGET_64BIT"
22087 {
22088 if (INTVAL (operands[1]) == 0)
22089 return "prefetch\t%a0";
22090 else
22091 return "prefetchw\t%a0";
22092 }
22093 [(set_attr "type" "mmx")
22094 (set_attr "memory" "none")])
22095
22096 (define_insn "*prefetch_3dnow_rex"
22097 [(prefetch (match_operand:DI 0 "address_operand" "p")
22098 (match_operand:SI 1 "const_int_operand" "n")
22099 (const_int 3))]
22100 "TARGET_3DNOW && TARGET_64BIT"
22101 {
22102 if (INTVAL (operands[1]) == 0)
22103 return "prefetch\t%a0";
22104 else
22105 return "prefetchw\t%a0";
22106 }
22107 [(set_attr "type" "mmx")
22108 (set_attr "memory" "none")])
22109
22110 ;; SSE2 support
22111
22112 (define_insn "addv2df3"
22113 [(set (match_operand:V2DF 0 "register_operand" "=x")
22114 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22115 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22116 "TARGET_SSE2"
22117 "addpd\t{%2, %0|%0, %2}"
22118 [(set_attr "type" "sseadd")
22119 (set_attr "mode" "V2DF")])
22120
22121 (define_insn "vmaddv2df3"
22122 [(set (match_operand:V2DF 0 "register_operand" "=x")
22123 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22124 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22125 (match_dup 1)
22126 (const_int 1)))]
22127 "TARGET_SSE2"
22128 "addsd\t{%2, %0|%0, %2}"
22129 [(set_attr "type" "sseadd")
22130 (set_attr "mode" "DF")])
22131
22132 (define_insn "subv2df3"
22133 [(set (match_operand:V2DF 0 "register_operand" "=x")
22134 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22135 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22136 "TARGET_SSE2"
22137 "subpd\t{%2, %0|%0, %2}"
22138 [(set_attr "type" "sseadd")
22139 (set_attr "mode" "V2DF")])
22140
22141 (define_insn "vmsubv2df3"
22142 [(set (match_operand:V2DF 0 "register_operand" "=x")
22143 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22144 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22145 (match_dup 1)
22146 (const_int 1)))]
22147 "TARGET_SSE2"
22148 "subsd\t{%2, %0|%0, %2}"
22149 [(set_attr "type" "sseadd")
22150 (set_attr "mode" "DF")])
22151
22152 (define_insn "mulv2df3"
22153 [(set (match_operand:V2DF 0 "register_operand" "=x")
22154 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22155 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22156 "TARGET_SSE2"
22157 "mulpd\t{%2, %0|%0, %2}"
22158 [(set_attr "type" "ssemul")
22159 (set_attr "mode" "V2DF")])
22160
22161 (define_insn "vmmulv2df3"
22162 [(set (match_operand:V2DF 0 "register_operand" "=x")
22163 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22164 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22165 (match_dup 1)
22166 (const_int 1)))]
22167 "TARGET_SSE2"
22168 "mulsd\t{%2, %0|%0, %2}"
22169 [(set_attr "type" "ssemul")
22170 (set_attr "mode" "DF")])
22171
22172 (define_insn "divv2df3"
22173 [(set (match_operand:V2DF 0 "register_operand" "=x")
22174 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22175 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22176 "TARGET_SSE2"
22177 "divpd\t{%2, %0|%0, %2}"
22178 [(set_attr "type" "ssediv")
22179 (set_attr "mode" "V2DF")])
22180
22181 (define_insn "vmdivv2df3"
22182 [(set (match_operand:V2DF 0 "register_operand" "=x")
22183 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22184 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22185 (match_dup 1)
22186 (const_int 1)))]
22187 "TARGET_SSE2"
22188 "divsd\t{%2, %0|%0, %2}"
22189 [(set_attr "type" "ssediv")
22190 (set_attr "mode" "DF")])
22191
22192 ;; SSE min/max
22193
22194 (define_insn "smaxv2df3"
22195 [(set (match_operand:V2DF 0 "register_operand" "=x")
22196 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22197 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22198 "TARGET_SSE2"
22199 "maxpd\t{%2, %0|%0, %2}"
22200 [(set_attr "type" "sseadd")
22201 (set_attr "mode" "V2DF")])
22202
22203 (define_insn "vmsmaxv2df3"
22204 [(set (match_operand:V2DF 0 "register_operand" "=x")
22205 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22206 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22207 (match_dup 1)
22208 (const_int 1)))]
22209 "TARGET_SSE2"
22210 "maxsd\t{%2, %0|%0, %2}"
22211 [(set_attr "type" "sseadd")
22212 (set_attr "mode" "DF")])
22213
22214 (define_insn "sminv2df3"
22215 [(set (match_operand:V2DF 0 "register_operand" "=x")
22216 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22217 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22218 "TARGET_SSE2"
22219 "minpd\t{%2, %0|%0, %2}"
22220 [(set_attr "type" "sseadd")
22221 (set_attr "mode" "V2DF")])
22222
22223 (define_insn "vmsminv2df3"
22224 [(set (match_operand:V2DF 0 "register_operand" "=x")
22225 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22226 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22227 (match_dup 1)
22228 (const_int 1)))]
22229 "TARGET_SSE2"
22230 "minsd\t{%2, %0|%0, %2}"
22231 [(set_attr "type" "sseadd")
22232 (set_attr "mode" "DF")])
22233 ;; SSE2 square root. There doesn't appear to be an extension for the
22234 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22235
22236 (define_insn "sqrtv2df2"
22237 [(set (match_operand:V2DF 0 "register_operand" "=x")
22238 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22239 "TARGET_SSE2"
22240 "sqrtpd\t{%1, %0|%0, %1}"
22241 [(set_attr "type" "sse")
22242 (set_attr "mode" "V2DF")])
22243
22244 (define_insn "vmsqrtv2df2"
22245 [(set (match_operand:V2DF 0 "register_operand" "=x")
22246 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22247 (match_operand:V2DF 2 "register_operand" "0")
22248 (const_int 1)))]
22249 "TARGET_SSE2"
22250 "sqrtsd\t{%1, %0|%0, %1}"
22251 [(set_attr "type" "sse")
22252 (set_attr "mode" "SF")])
22253
22254 ;; SSE mask-generating compares
22255
22256 (define_insn "maskcmpv2df3"
22257 [(set (match_operand:V2DI 0 "register_operand" "=x")
22258 (match_operator:V2DI 3 "sse_comparison_operator"
22259 [(match_operand:V2DF 1 "register_operand" "0")
22260 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22261 "TARGET_SSE2"
22262 "cmp%D3pd\t{%2, %0|%0, %2}"
22263 [(set_attr "type" "ssecmp")
22264 (set_attr "mode" "V2DF")])
22265
22266 (define_insn "maskncmpv2df3"
22267 [(set (match_operand:V2DI 0 "register_operand" "=x")
22268 (not:V2DI
22269 (match_operator:V2DI 3 "sse_comparison_operator"
22270 [(match_operand:V2DF 1 "register_operand" "0")
22271 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22272 "TARGET_SSE2"
22273 {
22274 if (GET_CODE (operands[3]) == UNORDERED)
22275 return "cmpordps\t{%2, %0|%0, %2}";
22276 else
22277 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22278 }
22279 [(set_attr "type" "ssecmp")
22280 (set_attr "mode" "V2DF")])
22281
22282 (define_insn "vmmaskcmpv2df3"
22283 [(set (match_operand:V2DI 0 "register_operand" "=x")
22284 (vec_merge:V2DI
22285 (match_operator:V2DI 3 "sse_comparison_operator"
22286 [(match_operand:V2DF 1 "register_operand" "0")
22287 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22288 (subreg:V2DI (match_dup 1) 0)
22289 (const_int 1)))]
22290 "TARGET_SSE2"
22291 "cmp%D3sd\t{%2, %0|%0, %2}"
22292 [(set_attr "type" "ssecmp")
22293 (set_attr "mode" "DF")])
22294
22295 (define_insn "vmmaskncmpv2df3"
22296 [(set (match_operand:V2DI 0 "register_operand" "=x")
22297 (vec_merge:V2DI
22298 (not:V2DI
22299 (match_operator:V2DI 3 "sse_comparison_operator"
22300 [(match_operand:V2DF 1 "register_operand" "0")
22301 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22302 (subreg:V2DI (match_dup 1) 0)
22303 (const_int 1)))]
22304 "TARGET_SSE2"
22305 {
22306 if (GET_CODE (operands[3]) == UNORDERED)
22307 return "cmpordsd\t{%2, %0|%0, %2}";
22308 else
22309 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22310 }
22311 [(set_attr "type" "ssecmp")
22312 (set_attr "mode" "DF")])
22313
22314 (define_insn "sse2_comi"
22315 [(set (reg:CCFP 17)
22316 (compare:CCFP (vec_select:DF
22317 (match_operand:V2DF 0 "register_operand" "x")
22318 (parallel [(const_int 0)]))
22319 (vec_select:DF
22320 (match_operand:V2DF 1 "register_operand" "x")
22321 (parallel [(const_int 0)]))))]
22322 "TARGET_SSE2"
22323 "comisd\t{%1, %0|%0, %1}"
22324 [(set_attr "type" "ssecomi")
22325 (set_attr "mode" "DF")])
22326
22327 (define_insn "sse2_ucomi"
22328 [(set (reg:CCFPU 17)
22329 (compare:CCFPU (vec_select:DF
22330 (match_operand:V2DF 0 "register_operand" "x")
22331 (parallel [(const_int 0)]))
22332 (vec_select:DF
22333 (match_operand:V2DF 1 "register_operand" "x")
22334 (parallel [(const_int 0)]))))]
22335 "TARGET_SSE2"
22336 "ucomisd\t{%1, %0|%0, %1}"
22337 [(set_attr "type" "ssecomi")
22338 (set_attr "mode" "DF")])
22339
22340 ;; SSE Strange Moves.
22341
22342 (define_insn "sse2_movmskpd"
22343 [(set (match_operand:SI 0 "register_operand" "=r")
22344 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22345 UNSPEC_MOVMSK))]
22346 "TARGET_SSE2"
22347 "movmskpd\t{%1, %0|%0, %1}"
22348 [(set_attr "type" "ssecvt")
22349 (set_attr "mode" "V2DF")])
22350
22351 (define_insn "sse2_pmovmskb"
22352 [(set (match_operand:SI 0 "register_operand" "=r")
22353 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22354 UNSPEC_MOVMSK))]
22355 "TARGET_SSE2"
22356 "pmovmskb\t{%1, %0|%0, %1}"
22357 [(set_attr "type" "ssecvt")
22358 (set_attr "mode" "V2DF")])
22359
22360 (define_insn "sse2_maskmovdqu"
22361 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22362 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22363 (match_operand:V16QI 2 "register_operand" "x")]
22364 UNSPEC_MASKMOV))]
22365 "TARGET_SSE2"
22366 ;; @@@ check ordering of operands in intel/nonintel syntax
22367 "maskmovdqu\t{%2, %1|%1, %2}"
22368 [(set_attr "type" "ssecvt")
22369 (set_attr "mode" "TI")])
22370
22371 (define_insn "sse2_maskmovdqu_rex64"
22372 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22373 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22374 (match_operand:V16QI 2 "register_operand" "x")]
22375 UNSPEC_MASKMOV))]
22376 "TARGET_SSE2"
22377 ;; @@@ check ordering of operands in intel/nonintel syntax
22378 "maskmovdqu\t{%2, %1|%1, %2}"
22379 [(set_attr "type" "ssecvt")
22380 (set_attr "mode" "TI")])
22381
22382 (define_insn "sse2_movntv2df"
22383 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22384 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22385 UNSPEC_MOVNT))]
22386 "TARGET_SSE2"
22387 "movntpd\t{%1, %0|%0, %1}"
22388 [(set_attr "type" "ssecvt")
22389 (set_attr "mode" "V2DF")])
22390
22391 (define_insn "sse2_movntv2di"
22392 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22393 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22394 UNSPEC_MOVNT))]
22395 "TARGET_SSE2"
22396 "movntdq\t{%1, %0|%0, %1}"
22397 [(set_attr "type" "ssecvt")
22398 (set_attr "mode" "TI")])
22399
22400 (define_insn "sse2_movntsi"
22401 [(set (match_operand:SI 0 "memory_operand" "=m")
22402 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22403 UNSPEC_MOVNT))]
22404 "TARGET_SSE2"
22405 "movnti\t{%1, %0|%0, %1}"
22406 [(set_attr "type" "ssecvt")
22407 (set_attr "mode" "V2DF")])
22408
22409 ;; SSE <-> integer/MMX conversions
22410
22411 ;; Conversions between SI and SF
22412
22413 (define_insn "cvtdq2ps"
22414 [(set (match_operand:V4SF 0 "register_operand" "=x")
22415 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22416 "TARGET_SSE2"
22417 "cvtdq2ps\t{%1, %0|%0, %1}"
22418 [(set_attr "type" "ssecvt")
22419 (set_attr "mode" "V2DF")])
22420
22421 (define_insn "cvtps2dq"
22422 [(set (match_operand:V4SI 0 "register_operand" "=x")
22423 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22424 "TARGET_SSE2"
22425 "cvtps2dq\t{%1, %0|%0, %1}"
22426 [(set_attr "type" "ssecvt")
22427 (set_attr "mode" "TI")])
22428
22429 (define_insn "cvttps2dq"
22430 [(set (match_operand:V4SI 0 "register_operand" "=x")
22431 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22432 UNSPEC_FIX))]
22433 "TARGET_SSE2"
22434 "cvttps2dq\t{%1, %0|%0, %1}"
22435 [(set_attr "type" "ssecvt")
22436 (set_attr "mode" "TI")])
22437
22438 ;; Conversions between SI and DF
22439
22440 (define_insn "cvtdq2pd"
22441 [(set (match_operand:V2DF 0 "register_operand" "=x")
22442 (float:V2DF (vec_select:V2SI
22443 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22444 (parallel
22445 [(const_int 0)
22446 (const_int 1)]))))]
22447 "TARGET_SSE2"
22448 "cvtdq2pd\t{%1, %0|%0, %1}"
22449 [(set_attr "type" "ssecvt")
22450 (set_attr "mode" "V2DF")])
22451
22452 (define_insn "cvtpd2dq"
22453 [(set (match_operand:V4SI 0 "register_operand" "=x")
22454 (vec_concat:V4SI
22455 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22456 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22457 "TARGET_SSE2"
22458 "cvtpd2dq\t{%1, %0|%0, %1}"
22459 [(set_attr "type" "ssecvt")
22460 (set_attr "mode" "TI")])
22461
22462 (define_insn "cvttpd2dq"
22463 [(set (match_operand:V4SI 0 "register_operand" "=x")
22464 (vec_concat:V4SI
22465 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22466 UNSPEC_FIX)
22467 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22468 "TARGET_SSE2"
22469 "cvttpd2dq\t{%1, %0|%0, %1}"
22470 [(set_attr "type" "ssecvt")
22471 (set_attr "mode" "TI")])
22472
22473 (define_insn "cvtpd2pi"
22474 [(set (match_operand:V2SI 0 "register_operand" "=y")
22475 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22476 "TARGET_SSE2"
22477 "cvtpd2pi\t{%1, %0|%0, %1}"
22478 [(set_attr "type" "ssecvt")
22479 (set_attr "mode" "TI")])
22480
22481 (define_insn "cvttpd2pi"
22482 [(set (match_operand:V2SI 0 "register_operand" "=y")
22483 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22484 UNSPEC_FIX))]
22485 "TARGET_SSE2"
22486 "cvttpd2pi\t{%1, %0|%0, %1}"
22487 [(set_attr "type" "ssecvt")
22488 (set_attr "mode" "TI")])
22489
22490 (define_insn "cvtpi2pd"
22491 [(set (match_operand:V2DF 0 "register_operand" "=x")
22492 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22493 "TARGET_SSE2"
22494 "cvtpi2pd\t{%1, %0|%0, %1}"
22495 [(set_attr "type" "ssecvt")
22496 (set_attr "mode" "TI")])
22497
22498 ;; Conversions between SI and DF
22499
22500 (define_insn "cvtsd2si"
22501 [(set (match_operand:SI 0 "register_operand" "=r,r")
22502 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22503 (parallel [(const_int 0)]))))]
22504 "TARGET_SSE2"
22505 "cvtsd2si\t{%1, %0|%0, %1}"
22506 [(set_attr "type" "sseicvt")
22507 (set_attr "athlon_decode" "double,vector")
22508 (set_attr "mode" "SI")])
22509
22510 (define_insn "cvtsd2siq"
22511 [(set (match_operand:DI 0 "register_operand" "=r,r")
22512 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22513 (parallel [(const_int 0)]))))]
22514 "TARGET_SSE2 && TARGET_64BIT"
22515 "cvtsd2siq\t{%1, %0|%0, %1}"
22516 [(set_attr "type" "sseicvt")
22517 (set_attr "athlon_decode" "double,vector")
22518 (set_attr "mode" "DI")])
22519
22520 (define_insn "cvttsd2si"
22521 [(set (match_operand:SI 0 "register_operand" "=r,r")
22522 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22523 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22524 "TARGET_SSE2"
22525 "cvttsd2si\t{%1, %0|%0, %1}"
22526 [(set_attr "type" "sseicvt")
22527 (set_attr "mode" "SI")
22528 (set_attr "athlon_decode" "double,vector")])
22529
22530 (define_insn "cvttsd2siq"
22531 [(set (match_operand:DI 0 "register_operand" "=r,r")
22532 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22533 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22534 "TARGET_SSE2 && TARGET_64BIT"
22535 "cvttsd2siq\t{%1, %0|%0, %1}"
22536 [(set_attr "type" "sseicvt")
22537 (set_attr "mode" "DI")
22538 (set_attr "athlon_decode" "double,vector")])
22539
22540 (define_insn "cvtsi2sd"
22541 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22542 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22543 (vec_duplicate:V2DF
22544 (float:DF
22545 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22546 (const_int 2)))]
22547 "TARGET_SSE2"
22548 "cvtsi2sd\t{%2, %0|%0, %2}"
22549 [(set_attr "type" "sseicvt")
22550 (set_attr "mode" "DF")
22551 (set_attr "athlon_decode" "double,direct")])
22552
22553 (define_insn "cvtsi2sdq"
22554 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22555 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22556 (vec_duplicate:V2DF
22557 (float:DF
22558 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22559 (const_int 2)))]
22560 "TARGET_SSE2 && TARGET_64BIT"
22561 "cvtsi2sdq\t{%2, %0|%0, %2}"
22562 [(set_attr "type" "sseicvt")
22563 (set_attr "mode" "DF")
22564 (set_attr "athlon_decode" "double,direct")])
22565
22566 ;; Conversions between SF and DF
22567
22568 (define_insn "cvtsd2ss"
22569 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22570 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22571 (vec_duplicate:V4SF
22572 (float_truncate:V2SF
22573 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22574 (const_int 14)))]
22575 "TARGET_SSE2"
22576 "cvtsd2ss\t{%2, %0|%0, %2}"
22577 [(set_attr "type" "ssecvt")
22578 (set_attr "athlon_decode" "vector,double")
22579 (set_attr "mode" "SF")])
22580
22581 (define_insn "cvtss2sd"
22582 [(set (match_operand:V2DF 0 "register_operand" "=x")
22583 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22584 (float_extend:V2DF
22585 (vec_select:V2SF
22586 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22587 (parallel [(const_int 0)
22588 (const_int 1)])))
22589 (const_int 2)))]
22590 "TARGET_SSE2"
22591 "cvtss2sd\t{%2, %0|%0, %2}"
22592 [(set_attr "type" "ssecvt")
22593 (set_attr "mode" "DF")])
22594
22595 (define_insn "cvtpd2ps"
22596 [(set (match_operand:V4SF 0 "register_operand" "=x")
22597 (subreg:V4SF
22598 (vec_concat:V4SI
22599 (subreg:V2SI (float_truncate:V2SF
22600 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22601 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22602 "TARGET_SSE2"
22603 "cvtpd2ps\t{%1, %0|%0, %1}"
22604 [(set_attr "type" "ssecvt")
22605 (set_attr "mode" "V4SF")])
22606
22607 (define_insn "cvtps2pd"
22608 [(set (match_operand:V2DF 0 "register_operand" "=x")
22609 (float_extend:V2DF
22610 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22611 (parallel [(const_int 0)
22612 (const_int 1)]))))]
22613 "TARGET_SSE2"
22614 "cvtps2pd\t{%1, %0|%0, %1}"
22615 [(set_attr "type" "ssecvt")
22616 (set_attr "mode" "V2DF")])
22617
22618 ;; SSE2 variants of MMX insns
22619
22620 ;; MMX arithmetic
22621
22622 (define_insn "addv16qi3"
22623 [(set (match_operand:V16QI 0 "register_operand" "=x")
22624 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22625 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22626 "TARGET_SSE2"
22627 "paddb\t{%2, %0|%0, %2}"
22628 [(set_attr "type" "sseiadd")
22629 (set_attr "mode" "TI")])
22630
22631 (define_insn "addv8hi3"
22632 [(set (match_operand:V8HI 0 "register_operand" "=x")
22633 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22634 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22635 "TARGET_SSE2"
22636 "paddw\t{%2, %0|%0, %2}"
22637 [(set_attr "type" "sseiadd")
22638 (set_attr "mode" "TI")])
22639
22640 (define_insn "addv4si3"
22641 [(set (match_operand:V4SI 0 "register_operand" "=x")
22642 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22643 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22644 "TARGET_SSE2"
22645 "paddd\t{%2, %0|%0, %2}"
22646 [(set_attr "type" "sseiadd")
22647 (set_attr "mode" "TI")])
22648
22649 (define_insn "addv2di3"
22650 [(set (match_operand:V2DI 0 "register_operand" "=x")
22651 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22652 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22653 "TARGET_SSE2"
22654 "paddq\t{%2, %0|%0, %2}"
22655 [(set_attr "type" "sseiadd")
22656 (set_attr "mode" "TI")])
22657
22658 (define_insn "ssaddv16qi3"
22659 [(set (match_operand:V16QI 0 "register_operand" "=x")
22660 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22661 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22662 "TARGET_SSE2"
22663 "paddsb\t{%2, %0|%0, %2}"
22664 [(set_attr "type" "sseiadd")
22665 (set_attr "mode" "TI")])
22666
22667 (define_insn "ssaddv8hi3"
22668 [(set (match_operand:V8HI 0 "register_operand" "=x")
22669 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22670 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22671 "TARGET_SSE2"
22672 "paddsw\t{%2, %0|%0, %2}"
22673 [(set_attr "type" "sseiadd")
22674 (set_attr "mode" "TI")])
22675
22676 (define_insn "usaddv16qi3"
22677 [(set (match_operand:V16QI 0 "register_operand" "=x")
22678 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22679 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22680 "TARGET_SSE2"
22681 "paddusb\t{%2, %0|%0, %2}"
22682 [(set_attr "type" "sseiadd")
22683 (set_attr "mode" "TI")])
22684
22685 (define_insn "usaddv8hi3"
22686 [(set (match_operand:V8HI 0 "register_operand" "=x")
22687 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22688 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22689 "TARGET_SSE2"
22690 "paddusw\t{%2, %0|%0, %2}"
22691 [(set_attr "type" "sseiadd")
22692 (set_attr "mode" "TI")])
22693
22694 (define_insn "subv16qi3"
22695 [(set (match_operand:V16QI 0 "register_operand" "=x")
22696 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22697 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22698 "TARGET_SSE2"
22699 "psubb\t{%2, %0|%0, %2}"
22700 [(set_attr "type" "sseiadd")
22701 (set_attr "mode" "TI")])
22702
22703 (define_insn "subv8hi3"
22704 [(set (match_operand:V8HI 0 "register_operand" "=x")
22705 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22706 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22707 "TARGET_SSE2"
22708 "psubw\t{%2, %0|%0, %2}"
22709 [(set_attr "type" "sseiadd")
22710 (set_attr "mode" "TI")])
22711
22712 (define_insn "subv4si3"
22713 [(set (match_operand:V4SI 0 "register_operand" "=x")
22714 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22715 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22716 "TARGET_SSE2"
22717 "psubd\t{%2, %0|%0, %2}"
22718 [(set_attr "type" "sseiadd")
22719 (set_attr "mode" "TI")])
22720
22721 (define_insn "subv2di3"
22722 [(set (match_operand:V2DI 0 "register_operand" "=x")
22723 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22724 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22725 "TARGET_SSE2"
22726 "psubq\t{%2, %0|%0, %2}"
22727 [(set_attr "type" "sseiadd")
22728 (set_attr "mode" "TI")])
22729
22730 (define_insn "sssubv16qi3"
22731 [(set (match_operand:V16QI 0 "register_operand" "=x")
22732 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22733 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22734 "TARGET_SSE2"
22735 "psubsb\t{%2, %0|%0, %2}"
22736 [(set_attr "type" "sseiadd")
22737 (set_attr "mode" "TI")])
22738
22739 (define_insn "sssubv8hi3"
22740 [(set (match_operand:V8HI 0 "register_operand" "=x")
22741 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22742 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22743 "TARGET_SSE2"
22744 "psubsw\t{%2, %0|%0, %2}"
22745 [(set_attr "type" "sseiadd")
22746 (set_attr "mode" "TI")])
22747
22748 (define_insn "ussubv16qi3"
22749 [(set (match_operand:V16QI 0 "register_operand" "=x")
22750 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22751 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22752 "TARGET_SSE2"
22753 "psubusb\t{%2, %0|%0, %2}"
22754 [(set_attr "type" "sseiadd")
22755 (set_attr "mode" "TI")])
22756
22757 (define_insn "ussubv8hi3"
22758 [(set (match_operand:V8HI 0 "register_operand" "=x")
22759 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22760 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22761 "TARGET_SSE2"
22762 "psubusw\t{%2, %0|%0, %2}"
22763 [(set_attr "type" "sseiadd")
22764 (set_attr "mode" "TI")])
22765
22766 (define_insn "mulv8hi3"
22767 [(set (match_operand:V8HI 0 "register_operand" "=x")
22768 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22769 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22770 "TARGET_SSE2"
22771 "pmullw\t{%2, %0|%0, %2}"
22772 [(set_attr "type" "sseimul")
22773 (set_attr "mode" "TI")])
22774
22775 (define_insn "smulv8hi3_highpart"
22776 [(set (match_operand:V8HI 0 "register_operand" "=x")
22777 (truncate:V8HI
22778 (lshiftrt:V8SI
22779 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22780 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22781 (const_int 16))))]
22782 "TARGET_SSE2"
22783 "pmulhw\t{%2, %0|%0, %2}"
22784 [(set_attr "type" "sseimul")
22785 (set_attr "mode" "TI")])
22786
22787 (define_insn "umulv8hi3_highpart"
22788 [(set (match_operand:V8HI 0 "register_operand" "=x")
22789 (truncate:V8HI
22790 (lshiftrt:V8SI
22791 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22792 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22793 (const_int 16))))]
22794 "TARGET_SSE2"
22795 "pmulhuw\t{%2, %0|%0, %2}"
22796 [(set_attr "type" "sseimul")
22797 (set_attr "mode" "TI")])
22798
22799 (define_insn "sse2_umulsidi3"
22800 [(set (match_operand:DI 0 "register_operand" "=y")
22801 (mult:DI (zero_extend:DI (vec_select:SI
22802 (match_operand:V2SI 1 "register_operand" "0")
22803 (parallel [(const_int 0)])))
22804 (zero_extend:DI (vec_select:SI
22805 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22806 (parallel [(const_int 0)])))))]
22807 "TARGET_SSE2"
22808 "pmuludq\t{%2, %0|%0, %2}"
22809 [(set_attr "type" "sseimul")
22810 (set_attr "mode" "TI")])
22811
22812 (define_insn "sse2_umulv2siv2di3"
22813 [(set (match_operand:V2DI 0 "register_operand" "=x")
22814 (mult:V2DI (zero_extend:V2DI
22815 (vec_select:V2SI
22816 (match_operand:V4SI 1 "register_operand" "0")
22817 (parallel [(const_int 0) (const_int 2)])))
22818 (zero_extend:V2DI
22819 (vec_select:V2SI
22820 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22821 (parallel [(const_int 0) (const_int 2)])))))]
22822 "TARGET_SSE2"
22823 "pmuludq\t{%2, %0|%0, %2}"
22824 [(set_attr "type" "sseimul")
22825 (set_attr "mode" "TI")])
22826
22827 (define_insn "sse2_pmaddwd"
22828 [(set (match_operand:V4SI 0 "register_operand" "=x")
22829 (plus:V4SI
22830 (mult:V4SI
22831 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22832 (parallel [(const_int 0)
22833 (const_int 2)
22834 (const_int 4)
22835 (const_int 6)])))
22836 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22837 (parallel [(const_int 0)
22838 (const_int 2)
22839 (const_int 4)
22840 (const_int 6)]))))
22841 (mult:V4SI
22842 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22843 (parallel [(const_int 1)
22844 (const_int 3)
22845 (const_int 5)
22846 (const_int 7)])))
22847 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22848 (parallel [(const_int 1)
22849 (const_int 3)
22850 (const_int 5)
22851 (const_int 7)]))))))]
22852 "TARGET_SSE2"
22853 "pmaddwd\t{%2, %0|%0, %2}"
22854 [(set_attr "type" "sseiadd")
22855 (set_attr "mode" "TI")])
22856
22857 ;; Same as pxor, but don't show input operands so that we don't think
22858 ;; they are live.
22859 (define_insn "sse2_clrti"
22860 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22861 "TARGET_SSE2"
22862 {
22863 if (get_attr_mode (insn) == MODE_TI)
22864 return "pxor\t%0, %0";
22865 else
22866 return "xorps\t%0, %0";
22867 }
22868 [(set_attr "type" "ssemov")
22869 (set_attr "memory" "none")
22870 (set (attr "mode")
22871 (if_then_else
22872 (ne (symbol_ref "optimize_size")
22873 (const_int 0))
22874 (const_string "V4SF")
22875 (const_string "TI")))])
22876
22877 ;; MMX unsigned averages/sum of absolute differences
22878
22879 (define_insn "sse2_uavgv16qi3"
22880 [(set (match_operand:V16QI 0 "register_operand" "=x")
22881 (ashiftrt:V16QI
22882 (plus:V16QI (plus:V16QI
22883 (match_operand:V16QI 1 "register_operand" "0")
22884 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22885 (const_vector:V16QI [(const_int 1) (const_int 1)
22886 (const_int 1) (const_int 1)
22887 (const_int 1) (const_int 1)
22888 (const_int 1) (const_int 1)
22889 (const_int 1) (const_int 1)
22890 (const_int 1) (const_int 1)
22891 (const_int 1) (const_int 1)
22892 (const_int 1) (const_int 1)]))
22893 (const_int 1)))]
22894 "TARGET_SSE2"
22895 "pavgb\t{%2, %0|%0, %2}"
22896 [(set_attr "type" "sseiadd")
22897 (set_attr "mode" "TI")])
22898
22899 (define_insn "sse2_uavgv8hi3"
22900 [(set (match_operand:V8HI 0 "register_operand" "=x")
22901 (ashiftrt:V8HI
22902 (plus:V8HI (plus:V8HI
22903 (match_operand:V8HI 1 "register_operand" "0")
22904 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22905 (const_vector:V8HI [(const_int 1) (const_int 1)
22906 (const_int 1) (const_int 1)
22907 (const_int 1) (const_int 1)
22908 (const_int 1) (const_int 1)]))
22909 (const_int 1)))]
22910 "TARGET_SSE2"
22911 "pavgw\t{%2, %0|%0, %2}"
22912 [(set_attr "type" "sseiadd")
22913 (set_attr "mode" "TI")])
22914
22915 ;; @@@ this isn't the right representation.
22916 (define_insn "sse2_psadbw"
22917 [(set (match_operand:V2DI 0 "register_operand" "=x")
22918 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22919 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22920 UNSPEC_PSADBW))]
22921 "TARGET_SSE2"
22922 "psadbw\t{%2, %0|%0, %2}"
22923 [(set_attr "type" "sseiadd")
22924 (set_attr "mode" "TI")])
22925
22926
22927 ;; MMX insert/extract/shuffle
22928
22929 (define_insn "sse2_pinsrw"
22930 [(set (match_operand:V8HI 0 "register_operand" "=x")
22931 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22932 (vec_duplicate:V8HI
22933 (truncate:HI
22934 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22935 (match_operand:SI 3 "immediate_operand" "i")))]
22936 "TARGET_SSE2"
22937 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22938 [(set_attr "type" "ssecvt")
22939 (set_attr "mode" "TI")])
22940
22941 (define_insn "sse2_pextrw"
22942 [(set (match_operand:SI 0 "register_operand" "=r")
22943 (zero_extend:SI
22944 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22945 (parallel
22946 [(match_operand:SI 2 "immediate_operand" "i")]))))]
22947 "TARGET_SSE2"
22948 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22949 [(set_attr "type" "ssecvt")
22950 (set_attr "mode" "TI")])
22951
22952 (define_insn "sse2_pshufd"
22953 [(set (match_operand:V4SI 0 "register_operand" "=x")
22954 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22955 (match_operand:SI 2 "immediate_operand" "i")]
22956 UNSPEC_SHUFFLE))]
22957 "TARGET_SSE2"
22958 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22959 [(set_attr "type" "ssecvt")
22960 (set_attr "mode" "TI")])
22961
22962 (define_insn "sse2_pshuflw"
22963 [(set (match_operand:V8HI 0 "register_operand" "=x")
22964 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22965 (match_operand:SI 2 "immediate_operand" "i")]
22966 UNSPEC_PSHUFLW))]
22967 "TARGET_SSE2"
22968 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22969 [(set_attr "type" "ssecvt")
22970 (set_attr "mode" "TI")])
22971
22972 (define_insn "sse2_pshufhw"
22973 [(set (match_operand:V8HI 0 "register_operand" "=x")
22974 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22975 (match_operand:SI 2 "immediate_operand" "i")]
22976 UNSPEC_PSHUFHW))]
22977 "TARGET_SSE2"
22978 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22979 [(set_attr "type" "ssecvt")
22980 (set_attr "mode" "TI")])
22981
22982 ;; MMX mask-generating comparisons
22983
22984 (define_insn "eqv16qi3"
22985 [(set (match_operand:V16QI 0 "register_operand" "=x")
22986 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22987 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22988 "TARGET_SSE2"
22989 "pcmpeqb\t{%2, %0|%0, %2}"
22990 [(set_attr "type" "ssecmp")
22991 (set_attr "mode" "TI")])
22992
22993 (define_insn "eqv8hi3"
22994 [(set (match_operand:V8HI 0 "register_operand" "=x")
22995 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22996 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22997 "TARGET_SSE2"
22998 "pcmpeqw\t{%2, %0|%0, %2}"
22999 [(set_attr "type" "ssecmp")
23000 (set_attr "mode" "TI")])
23001
23002 (define_insn "eqv4si3"
23003 [(set (match_operand:V4SI 0 "register_operand" "=x")
23004 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23005 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23006 "TARGET_SSE2"
23007 "pcmpeqd\t{%2, %0|%0, %2}"
23008 [(set_attr "type" "ssecmp")
23009 (set_attr "mode" "TI")])
23010
23011 (define_insn "gtv16qi3"
23012 [(set (match_operand:V16QI 0 "register_operand" "=x")
23013 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23014 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23015 "TARGET_SSE2"
23016 "pcmpgtb\t{%2, %0|%0, %2}"
23017 [(set_attr "type" "ssecmp")
23018 (set_attr "mode" "TI")])
23019
23020 (define_insn "gtv8hi3"
23021 [(set (match_operand:V8HI 0 "register_operand" "=x")
23022 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23023 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23024 "TARGET_SSE2"
23025 "pcmpgtw\t{%2, %0|%0, %2}"
23026 [(set_attr "type" "ssecmp")
23027 (set_attr "mode" "TI")])
23028
23029 (define_insn "gtv4si3"
23030 [(set (match_operand:V4SI 0 "register_operand" "=x")
23031 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23032 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23033 "TARGET_SSE2"
23034 "pcmpgtd\t{%2, %0|%0, %2}"
23035 [(set_attr "type" "ssecmp")
23036 (set_attr "mode" "TI")])
23037
23038
23039 ;; MMX max/min insns
23040
23041 (define_insn "umaxv16qi3"
23042 [(set (match_operand:V16QI 0 "register_operand" "=x")
23043 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23044 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23045 "TARGET_SSE2"
23046 "pmaxub\t{%2, %0|%0, %2}"
23047 [(set_attr "type" "sseiadd")
23048 (set_attr "mode" "TI")])
23049
23050 (define_insn "smaxv8hi3"
23051 [(set (match_operand:V8HI 0 "register_operand" "=x")
23052 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23053 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23054 "TARGET_SSE2"
23055 "pmaxsw\t{%2, %0|%0, %2}"
23056 [(set_attr "type" "sseiadd")
23057 (set_attr "mode" "TI")])
23058
23059 (define_insn "uminv16qi3"
23060 [(set (match_operand:V16QI 0 "register_operand" "=x")
23061 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23062 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23063 "TARGET_SSE2"
23064 "pminub\t{%2, %0|%0, %2}"
23065 [(set_attr "type" "sseiadd")
23066 (set_attr "mode" "TI")])
23067
23068 (define_insn "sminv8hi3"
23069 [(set (match_operand:V8HI 0 "register_operand" "=x")
23070 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23071 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23072 "TARGET_SSE2"
23073 "pminsw\t{%2, %0|%0, %2}"
23074 [(set_attr "type" "sseiadd")
23075 (set_attr "mode" "TI")])
23076
23077
23078 ;; MMX shifts
23079
23080 (define_insn "ashrv8hi3"
23081 [(set (match_operand:V8HI 0 "register_operand" "=x")
23082 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23083 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23084 "TARGET_SSE2"
23085 "psraw\t{%2, %0|%0, %2}"
23086 [(set_attr "type" "sseishft")
23087 (set_attr "mode" "TI")])
23088
23089 (define_insn "ashrv4si3"
23090 [(set (match_operand:V4SI 0 "register_operand" "=x")
23091 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23092 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23093 "TARGET_SSE2"
23094 "psrad\t{%2, %0|%0, %2}"
23095 [(set_attr "type" "sseishft")
23096 (set_attr "mode" "TI")])
23097
23098 (define_insn "lshrv8hi3"
23099 [(set (match_operand:V8HI 0 "register_operand" "=x")
23100 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23101 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23102 "TARGET_SSE2"
23103 "psrlw\t{%2, %0|%0, %2}"
23104 [(set_attr "type" "sseishft")
23105 (set_attr "mode" "TI")])
23106
23107 (define_insn "lshrv4si3"
23108 [(set (match_operand:V4SI 0 "register_operand" "=x")
23109 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23110 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23111 "TARGET_SSE2"
23112 "psrld\t{%2, %0|%0, %2}"
23113 [(set_attr "type" "sseishft")
23114 (set_attr "mode" "TI")])
23115
23116 (define_insn "lshrv2di3"
23117 [(set (match_operand:V2DI 0 "register_operand" "=x")
23118 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23119 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23120 "TARGET_SSE2"
23121 "psrlq\t{%2, %0|%0, %2}"
23122 [(set_attr "type" "sseishft")
23123 (set_attr "mode" "TI")])
23124
23125 (define_insn "ashlv8hi3"
23126 [(set (match_operand:V8HI 0 "register_operand" "=x")
23127 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23128 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23129 "TARGET_SSE2"
23130 "psllw\t{%2, %0|%0, %2}"
23131 [(set_attr "type" "sseishft")
23132 (set_attr "mode" "TI")])
23133
23134 (define_insn "ashlv4si3"
23135 [(set (match_operand:V4SI 0 "register_operand" "=x")
23136 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23137 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23138 "TARGET_SSE2"
23139 "pslld\t{%2, %0|%0, %2}"
23140 [(set_attr "type" "sseishft")
23141 (set_attr "mode" "TI")])
23142
23143 (define_insn "ashlv2di3"
23144 [(set (match_operand:V2DI 0 "register_operand" "=x")
23145 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23146 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23147 "TARGET_SSE2"
23148 "psllq\t{%2, %0|%0, %2}"
23149 [(set_attr "type" "sseishft")
23150 (set_attr "mode" "TI")])
23151
23152 (define_insn "ashrv8hi3_ti"
23153 [(set (match_operand:V8HI 0 "register_operand" "=x")
23154 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23155 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23156 "TARGET_SSE2"
23157 "psraw\t{%2, %0|%0, %2}"
23158 [(set_attr "type" "sseishft")
23159 (set_attr "mode" "TI")])
23160
23161 (define_insn "ashrv4si3_ti"
23162 [(set (match_operand:V4SI 0 "register_operand" "=x")
23163 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23164 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23165 "TARGET_SSE2"
23166 "psrad\t{%2, %0|%0, %2}"
23167 [(set_attr "type" "sseishft")
23168 (set_attr "mode" "TI")])
23169
23170 (define_insn "lshrv8hi3_ti"
23171 [(set (match_operand:V8HI 0 "register_operand" "=x")
23172 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23173 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23174 "TARGET_SSE2"
23175 "psrlw\t{%2, %0|%0, %2}"
23176 [(set_attr "type" "sseishft")
23177 (set_attr "mode" "TI")])
23178
23179 (define_insn "lshrv4si3_ti"
23180 [(set (match_operand:V4SI 0 "register_operand" "=x")
23181 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23182 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23183 "TARGET_SSE2"
23184 "psrld\t{%2, %0|%0, %2}"
23185 [(set_attr "type" "sseishft")
23186 (set_attr "mode" "TI")])
23187
23188 (define_insn "lshrv2di3_ti"
23189 [(set (match_operand:V2DI 0 "register_operand" "=x")
23190 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23191 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23192 "TARGET_SSE2"
23193 "psrlq\t{%2, %0|%0, %2}"
23194 [(set_attr "type" "sseishft")
23195 (set_attr "mode" "TI")])
23196
23197 (define_insn "ashlv8hi3_ti"
23198 [(set (match_operand:V8HI 0 "register_operand" "=x")
23199 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23200 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23201 "TARGET_SSE2"
23202 "psllw\t{%2, %0|%0, %2}"
23203 [(set_attr "type" "sseishft")
23204 (set_attr "mode" "TI")])
23205
23206 (define_insn "ashlv4si3_ti"
23207 [(set (match_operand:V4SI 0 "register_operand" "=x")
23208 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23209 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23210 "TARGET_SSE2"
23211 "pslld\t{%2, %0|%0, %2}"
23212 [(set_attr "type" "sseishft")
23213 (set_attr "mode" "TI")])
23214
23215 (define_insn "ashlv2di3_ti"
23216 [(set (match_operand:V2DI 0 "register_operand" "=x")
23217 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23218 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23219 "TARGET_SSE2"
23220 "psllq\t{%2, %0|%0, %2}"
23221 [(set_attr "type" "sseishft")
23222 (set_attr "mode" "TI")])
23223
23224 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23225 ;; we wouldn't need here it since we never generate TImode arithmetic.
23226
23227 ;; There has to be some kind of prize for the weirdest new instruction...
23228 (define_insn "sse2_ashlti3"
23229 [(set (match_operand:TI 0 "register_operand" "=x")
23230 (unspec:TI
23231 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23232 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23233 (const_int 8)))] UNSPEC_NOP))]
23234 "TARGET_SSE2"
23235 "pslldq\t{%2, %0|%0, %2}"
23236 [(set_attr "type" "sseishft")
23237 (set_attr "mode" "TI")])
23238
23239 (define_insn "sse2_lshrti3"
23240 [(set (match_operand:TI 0 "register_operand" "=x")
23241 (unspec:TI
23242 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23243 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23244 (const_int 8)))] UNSPEC_NOP))]
23245 "TARGET_SSE2"
23246 "psrldq\t{%2, %0|%0, %2}"
23247 [(set_attr "type" "sseishft")
23248 (set_attr "mode" "TI")])
23249
23250 ;; SSE unpack
23251
23252 (define_insn "sse2_unpckhpd"
23253 [(set (match_operand:V2DF 0 "register_operand" "=x")
23254 (vec_concat:V2DF
23255 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23256 (parallel [(const_int 1)]))
23257 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23258 (parallel [(const_int 0)]))))]
23259 "TARGET_SSE2"
23260 "unpckhpd\t{%2, %0|%0, %2}"
23261 [(set_attr "type" "ssecvt")
23262 (set_attr "mode" "TI")])
23263
23264 (define_insn "sse2_unpcklpd"
23265 [(set (match_operand:V2DF 0 "register_operand" "=x")
23266 (vec_concat:V2DF
23267 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23268 (parallel [(const_int 0)]))
23269 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23270 (parallel [(const_int 1)]))))]
23271 "TARGET_SSE2"
23272 "unpcklpd\t{%2, %0|%0, %2}"
23273 [(set_attr "type" "ssecvt")
23274 (set_attr "mode" "TI")])
23275
23276 ;; MMX pack/unpack insns.
23277
23278 (define_insn "sse2_packsswb"
23279 [(set (match_operand:V16QI 0 "register_operand" "=x")
23280 (vec_concat:V16QI
23281 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23282 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23283 "TARGET_SSE2"
23284 "packsswb\t{%2, %0|%0, %2}"
23285 [(set_attr "type" "ssecvt")
23286 (set_attr "mode" "TI")])
23287
23288 (define_insn "sse2_packssdw"
23289 [(set (match_operand:V8HI 0 "register_operand" "=x")
23290 (vec_concat:V8HI
23291 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23292 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23293 "TARGET_SSE2"
23294 "packssdw\t{%2, %0|%0, %2}"
23295 [(set_attr "type" "ssecvt")
23296 (set_attr "mode" "TI")])
23297
23298 (define_insn "sse2_packuswb"
23299 [(set (match_operand:V16QI 0 "register_operand" "=x")
23300 (vec_concat:V16QI
23301 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23302 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23303 "TARGET_SSE2"
23304 "packuswb\t{%2, %0|%0, %2}"
23305 [(set_attr "type" "ssecvt")
23306 (set_attr "mode" "TI")])
23307
23308 (define_insn "sse2_punpckhbw"
23309 [(set (match_operand:V16QI 0 "register_operand" "=x")
23310 (vec_merge:V16QI
23311 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23312 (parallel [(const_int 8) (const_int 0)
23313 (const_int 9) (const_int 1)
23314 (const_int 10) (const_int 2)
23315 (const_int 11) (const_int 3)
23316 (const_int 12) (const_int 4)
23317 (const_int 13) (const_int 5)
23318 (const_int 14) (const_int 6)
23319 (const_int 15) (const_int 7)]))
23320 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23321 (parallel [(const_int 0) (const_int 8)
23322 (const_int 1) (const_int 9)
23323 (const_int 2) (const_int 10)
23324 (const_int 3) (const_int 11)
23325 (const_int 4) (const_int 12)
23326 (const_int 5) (const_int 13)
23327 (const_int 6) (const_int 14)
23328 (const_int 7) (const_int 15)]))
23329 (const_int 21845)))]
23330 "TARGET_SSE2"
23331 "punpckhbw\t{%2, %0|%0, %2}"
23332 [(set_attr "type" "ssecvt")
23333 (set_attr "mode" "TI")])
23334
23335 (define_insn "sse2_punpckhwd"
23336 [(set (match_operand:V8HI 0 "register_operand" "=x")
23337 (vec_merge:V8HI
23338 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23339 (parallel [(const_int 4) (const_int 0)
23340 (const_int 5) (const_int 1)
23341 (const_int 6) (const_int 2)
23342 (const_int 7) (const_int 3)]))
23343 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23344 (parallel [(const_int 0) (const_int 4)
23345 (const_int 1) (const_int 5)
23346 (const_int 2) (const_int 6)
23347 (const_int 3) (const_int 7)]))
23348 (const_int 85)))]
23349 "TARGET_SSE2"
23350 "punpckhwd\t{%2, %0|%0, %2}"
23351 [(set_attr "type" "ssecvt")
23352 (set_attr "mode" "TI")])
23353
23354 (define_insn "sse2_punpckhdq"
23355 [(set (match_operand:V4SI 0 "register_operand" "=x")
23356 (vec_merge:V4SI
23357 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23358 (parallel [(const_int 2) (const_int 0)
23359 (const_int 3) (const_int 1)]))
23360 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23361 (parallel [(const_int 0) (const_int 2)
23362 (const_int 1) (const_int 3)]))
23363 (const_int 5)))]
23364 "TARGET_SSE2"
23365 "punpckhdq\t{%2, %0|%0, %2}"
23366 [(set_attr "type" "ssecvt")
23367 (set_attr "mode" "TI")])
23368
23369 (define_insn "sse2_punpcklbw"
23370 [(set (match_operand:V16QI 0 "register_operand" "=x")
23371 (vec_merge:V16QI
23372 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23373 (parallel [(const_int 0) (const_int 8)
23374 (const_int 1) (const_int 9)
23375 (const_int 2) (const_int 10)
23376 (const_int 3) (const_int 11)
23377 (const_int 4) (const_int 12)
23378 (const_int 5) (const_int 13)
23379 (const_int 6) (const_int 14)
23380 (const_int 7) (const_int 15)]))
23381 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23382 (parallel [(const_int 8) (const_int 0)
23383 (const_int 9) (const_int 1)
23384 (const_int 10) (const_int 2)
23385 (const_int 11) (const_int 3)
23386 (const_int 12) (const_int 4)
23387 (const_int 13) (const_int 5)
23388 (const_int 14) (const_int 6)
23389 (const_int 15) (const_int 7)]))
23390 (const_int 21845)))]
23391 "TARGET_SSE2"
23392 "punpcklbw\t{%2, %0|%0, %2}"
23393 [(set_attr "type" "ssecvt")
23394 (set_attr "mode" "TI")])
23395
23396 (define_insn "sse2_punpcklwd"
23397 [(set (match_operand:V8HI 0 "register_operand" "=x")
23398 (vec_merge:V8HI
23399 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23400 (parallel [(const_int 0) (const_int 4)
23401 (const_int 1) (const_int 5)
23402 (const_int 2) (const_int 6)
23403 (const_int 3) (const_int 7)]))
23404 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23405 (parallel [(const_int 4) (const_int 0)
23406 (const_int 5) (const_int 1)
23407 (const_int 6) (const_int 2)
23408 (const_int 7) (const_int 3)]))
23409 (const_int 85)))]
23410 "TARGET_SSE2"
23411 "punpcklwd\t{%2, %0|%0, %2}"
23412 [(set_attr "type" "ssecvt")
23413 (set_attr "mode" "TI")])
23414
23415 (define_insn "sse2_punpckldq"
23416 [(set (match_operand:V4SI 0 "register_operand" "=x")
23417 (vec_merge:V4SI
23418 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23419 (parallel [(const_int 0) (const_int 2)
23420 (const_int 1) (const_int 3)]))
23421 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23422 (parallel [(const_int 2) (const_int 0)
23423 (const_int 3) (const_int 1)]))
23424 (const_int 5)))]
23425 "TARGET_SSE2"
23426 "punpckldq\t{%2, %0|%0, %2}"
23427 [(set_attr "type" "ssecvt")
23428 (set_attr "mode" "TI")])
23429
23430 (define_insn "sse2_punpcklqdq"
23431 [(set (match_operand:V2DI 0 "register_operand" "=x")
23432 (vec_merge:V2DI
23433 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23434 (parallel [(const_int 1)
23435 (const_int 0)]))
23436 (match_operand:V2DI 1 "register_operand" "0")
23437 (const_int 1)))]
23438 "TARGET_SSE2"
23439 "punpcklqdq\t{%2, %0|%0, %2}"
23440 [(set_attr "type" "ssecvt")
23441 (set_attr "mode" "TI")])
23442
23443 (define_insn "sse2_punpckhqdq"
23444 [(set (match_operand:V2DI 0 "register_operand" "=x")
23445 (vec_merge:V2DI
23446 (match_operand:V2DI 1 "register_operand" "0")
23447 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23448 (parallel [(const_int 1)
23449 (const_int 0)]))
23450 (const_int 1)))]
23451 "TARGET_SSE2"
23452 "punpckhqdq\t{%2, %0|%0, %2}"
23453 [(set_attr "type" "ssecvt")
23454 (set_attr "mode" "TI")])
23455
23456 ;; SSE2 moves
23457
23458 (define_insn "sse2_movapd"
23459 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23460 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23461 UNSPEC_MOVA))]
23462 "TARGET_SSE2
23463 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23464 "movapd\t{%1, %0|%0, %1}"
23465 [(set_attr "type" "ssemov")
23466 (set_attr "mode" "V2DF")])
23467
23468 (define_insn "sse2_movupd"
23469 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23470 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23471 UNSPEC_MOVU))]
23472 "TARGET_SSE2
23473 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23474 "movupd\t{%1, %0|%0, %1}"
23475 [(set_attr "type" "ssecvt")
23476 (set_attr "mode" "V2DF")])
23477
23478 (define_insn "sse2_movdqa"
23479 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23480 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23481 UNSPEC_MOVA))]
23482 "TARGET_SSE2
23483 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23484 "movdqa\t{%1, %0|%0, %1}"
23485 [(set_attr "type" "ssemov")
23486 (set_attr "mode" "TI")])
23487
23488 (define_insn "sse2_movdqu"
23489 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23490 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23491 UNSPEC_MOVU))]
23492 "TARGET_SSE2
23493 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23494 "movdqu\t{%1, %0|%0, %1}"
23495 [(set_attr "type" "ssecvt")
23496 (set_attr "mode" "TI")])
23497
23498 (define_insn "sse2_movdq2q"
23499 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23500 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23501 (parallel [(const_int 0)])))]
23502 "TARGET_SSE2 && !TARGET_64BIT"
23503 "@
23504 movq\t{%1, %0|%0, %1}
23505 movdq2q\t{%1, %0|%0, %1}"
23506 [(set_attr "type" "ssecvt")
23507 (set_attr "mode" "TI")])
23508
23509 (define_insn "sse2_movdq2q_rex64"
23510 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23511 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23512 (parallel [(const_int 0)])))]
23513 "TARGET_SSE2 && TARGET_64BIT"
23514 "@
23515 movq\t{%1, %0|%0, %1}
23516 movdq2q\t{%1, %0|%0, %1}
23517 movd\t{%1, %0|%0, %1}"
23518 [(set_attr "type" "ssecvt")
23519 (set_attr "mode" "TI")])
23520
23521 (define_insn "sse2_movq2dq"
23522 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23523 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23524 (const_int 0)))]
23525 "TARGET_SSE2 && !TARGET_64BIT"
23526 "@
23527 movq\t{%1, %0|%0, %1}
23528 movq2dq\t{%1, %0|%0, %1}"
23529 [(set_attr "type" "ssecvt,ssemov")
23530 (set_attr "mode" "TI")])
23531
23532 (define_insn "sse2_movq2dq_rex64"
23533 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23534 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23535 (const_int 0)))]
23536 "TARGET_SSE2 && TARGET_64BIT"
23537 "@
23538 movq\t{%1, %0|%0, %1}
23539 movq2dq\t{%1, %0|%0, %1}
23540 movd\t{%1, %0|%0, %1}"
23541 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23542 (set_attr "mode" "TI")])
23543
23544 (define_insn "sse2_movq"
23545 [(set (match_operand:V2DI 0 "register_operand" "=x")
23546 (vec_concat:V2DI (vec_select:DI
23547 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23548 (parallel [(const_int 0)]))
23549 (const_int 0)))]
23550 "TARGET_SSE2"
23551 "movq\t{%1, %0|%0, %1}"
23552 [(set_attr "type" "ssemov")
23553 (set_attr "mode" "TI")])
23554
23555 (define_insn "sse2_loadd"
23556 [(set (match_operand:V4SI 0 "register_operand" "=x")
23557 (vec_merge:V4SI
23558 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23559 (const_vector:V4SI [(const_int 0)
23560 (const_int 0)
23561 (const_int 0)
23562 (const_int 0)])
23563 (const_int 1)))]
23564 "TARGET_SSE2"
23565 "movd\t{%1, %0|%0, %1}"
23566 [(set_attr "type" "ssemov")
23567 (set_attr "mode" "TI")])
23568
23569 (define_insn "sse2_stored"
23570 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23571 (vec_select:SI
23572 (match_operand:V4SI 1 "register_operand" "x")
23573 (parallel [(const_int 0)])))]
23574 "TARGET_SSE2"
23575 "movd\t{%1, %0|%0, %1}"
23576 [(set_attr "type" "ssemov")
23577 (set_attr "mode" "TI")])
23578
23579 (define_insn "sse2_movhpd"
23580 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23581 (vec_merge:V2DF
23582 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23583 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23584 (const_int 2)))]
23585 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23586 "movhpd\t{%2, %0|%0, %2}"
23587 [(set_attr "type" "ssecvt")
23588 (set_attr "mode" "V2DF")])
23589
23590 (define_insn "sse2_movlpd"
23591 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23592 (vec_merge:V2DF
23593 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23594 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23595 (const_int 1)))]
23596 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23597 "movlpd\t{%2, %0|%0, %2}"
23598 [(set_attr "type" "ssecvt")
23599 (set_attr "mode" "V2DF")])
23600
23601 (define_expand "sse2_loadsd"
23602 [(match_operand:V2DF 0 "register_operand" "")
23603 (match_operand:DF 1 "memory_operand" "")]
23604 "TARGET_SSE2"
23605 {
23606 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23607 CONST0_RTX (V2DFmode)));
23608 DONE;
23609 })
23610
23611 (define_insn "sse2_loadsd_1"
23612 [(set (match_operand:V2DF 0 "register_operand" "=x")
23613 (vec_merge:V2DF
23614 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23615 (match_operand:V2DF 2 "const0_operand" "X")
23616 (const_int 1)))]
23617 "TARGET_SSE2"
23618 "movsd\t{%1, %0|%0, %1}"
23619 [(set_attr "type" "ssecvt")
23620 (set_attr "mode" "DF")])
23621
23622 (define_insn "sse2_movsd"
23623 [(set (match_operand:V2DF 0 "register_operand" "=x")
23624 (vec_merge:V2DF
23625 (match_operand:V2DF 1 "register_operand" "0")
23626 (match_operand:V2DF 2 "register_operand" "x")
23627 (const_int 1)))]
23628 "TARGET_SSE2"
23629 "movsd\t{%2, %0|%0, %2}"
23630 [(set_attr "type" "ssecvt")
23631 (set_attr "mode" "DF")])
23632
23633 (define_insn "sse2_storesd"
23634 [(set (match_operand:DF 0 "memory_operand" "=m")
23635 (vec_select:DF
23636 (match_operand:V2DF 1 "register_operand" "x")
23637 (parallel [(const_int 0)])))]
23638 "TARGET_SSE2"
23639 "movsd\t{%1, %0|%0, %1}"
23640 [(set_attr "type" "ssecvt")
23641 (set_attr "mode" "DF")])
23642
23643 (define_insn "sse2_shufpd"
23644 [(set (match_operand:V2DF 0 "register_operand" "=x")
23645 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23646 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23647 (match_operand:SI 3 "immediate_operand" "i")]
23648 UNSPEC_SHUFFLE))]
23649 "TARGET_SSE2"
23650 ;; @@@ check operand order for intel/nonintel syntax
23651 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23652 [(set_attr "type" "ssecvt")
23653 (set_attr "mode" "V2DF")])
23654
23655 (define_insn "sse2_clflush"
23656 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23657 UNSPECV_CLFLUSH)]
23658 "TARGET_SSE2"
23659 "clflush %0"
23660 [(set_attr "type" "sse")
23661 (set_attr "memory" "unknown")])
23662
23663 (define_expand "sse2_mfence"
23664 [(set (match_dup 0)
23665 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23666 "TARGET_SSE2"
23667 {
23668 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23669 MEM_VOLATILE_P (operands[0]) = 1;
23670 })
23671
23672 (define_insn "*mfence_insn"
23673 [(set (match_operand:BLK 0 "" "")
23674 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23675 "TARGET_SSE2"
23676 "mfence"
23677 [(set_attr "type" "sse")
23678 (set_attr "memory" "unknown")])
23679
23680 (define_expand "sse2_lfence"
23681 [(set (match_dup 0)
23682 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23683 "TARGET_SSE2"
23684 {
23685 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23686 MEM_VOLATILE_P (operands[0]) = 1;
23687 })
23688
23689 (define_insn "*lfence_insn"
23690 [(set (match_operand:BLK 0 "" "")
23691 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23692 "TARGET_SSE2"
23693 "lfence"
23694 [(set_attr "type" "sse")
23695 (set_attr "memory" "unknown")])
23696
23697 ;; PNI
23698
23699 (define_insn "mwait"
23700 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23701 (match_operand:SI 1 "register_operand" "c")]
23702 UNSPECV_MWAIT)]
23703 "TARGET_PNI"
23704 "mwait\t%0, %1"
23705 [(set_attr "length" "3")])
23706
23707 (define_insn "monitor"
23708 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23709 (match_operand:SI 1 "register_operand" "c")
23710 (match_operand:SI 2 "register_operand" "d")]
23711 UNSPECV_MONITOR)]
23712 "TARGET_PNI"
23713 "monitor\t%0, %1, %2"
23714 [(set_attr "length" "3")])
23715
23716 ;; PNI arithmetic
23717
23718 (define_insn "addsubv4sf3"
23719 [(set (match_operand:V4SF 0 "register_operand" "=x")
23720 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23721 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23722 UNSPEC_ADDSUB))]
23723 "TARGET_PNI"
23724 "addsubps\t{%2, %0|%0, %2}"
23725 [(set_attr "type" "sseadd")
23726 (set_attr "mode" "V4SF")])
23727
23728 (define_insn "addsubv2df3"
23729 [(set (match_operand:V2DF 0 "register_operand" "=x")
23730 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23731 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23732 UNSPEC_ADDSUB))]
23733 "TARGET_PNI"
23734 "addsubpd\t{%2, %0|%0, %2}"
23735 [(set_attr "type" "sseadd")
23736 (set_attr "mode" "V2DF")])
23737
23738 (define_insn "haddv4sf3"
23739 [(set (match_operand:V4SF 0 "register_operand" "=x")
23740 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23741 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23742 UNSPEC_HADD))]
23743 "TARGET_PNI"
23744 "haddps\t{%2, %0|%0, %2}"
23745 [(set_attr "type" "sseadd")
23746 (set_attr "mode" "V4SF")])
23747
23748 (define_insn "haddv2df3"
23749 [(set (match_operand:V2DF 0 "register_operand" "=x")
23750 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23751 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23752 UNSPEC_HADD))]
23753 "TARGET_PNI"
23754 "haddpd\t{%2, %0|%0, %2}"
23755 [(set_attr "type" "sseadd")
23756 (set_attr "mode" "V2DF")])
23757
23758 (define_insn "hsubv4sf3"
23759 [(set (match_operand:V4SF 0 "register_operand" "=x")
23760 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23761 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23762 UNSPEC_HSUB))]
23763 "TARGET_PNI"
23764 "hsubps\t{%2, %0|%0, %2}"
23765 [(set_attr "type" "sseadd")
23766 (set_attr "mode" "V4SF")])
23767
23768 (define_insn "hsubv2df3"
23769 [(set (match_operand:V2DF 0 "register_operand" "=x")
23770 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23771 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23772 UNSPEC_HSUB))]
23773 "TARGET_PNI"
23774 "hsubpd\t{%2, %0|%0, %2}"
23775 [(set_attr "type" "sseadd")
23776 (set_attr "mode" "V2DF")])
23777
23778 (define_insn "movshdup"
23779 [(set (match_operand:V4SF 0 "register_operand" "=x")
23780 (unspec:V4SF
23781 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23782 "TARGET_PNI"
23783 "movshdup\t{%1, %0|%0, %1}"
23784 [(set_attr "type" "sse")
23785 (set_attr "mode" "V4SF")])
23786
23787 (define_insn "movsldup"
23788 [(set (match_operand:V4SF 0 "register_operand" "=x")
23789 (unspec:V4SF
23790 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23791 "TARGET_PNI"
23792 "movsldup\t{%1, %0|%0, %1}"
23793 [(set_attr "type" "sse")
23794 (set_attr "mode" "V4SF")])
23795
23796 (define_insn "lddqu"
23797 [(set (match_operand:V16QI 0 "register_operand" "=x")
23798 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23799 UNSPEC_LDQQU))]
23800 "TARGET_PNI"
23801 "lddqu\t{%1, %0|%0, %1}"
23802 [(set_attr "type" "ssecvt")
23803 (set_attr "mode" "TI")])
23804
23805 (define_insn "loadddup"
23806 [(set (match_operand:V2DF 0 "register_operand" "=x")
23807 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23808 "TARGET_PNI"
23809 "movddup\t{%1, %0|%0, %1}"
23810 [(set_attr "type" "ssecvt")
23811 (set_attr "mode" "DF")])
23812
23813 (define_insn "movddup"
23814 [(set (match_operand:V2DF 0 "register_operand" "=x")
23815 (vec_duplicate:V2DF
23816 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23817 (parallel [(const_int 0)]))))]
23818 "TARGET_PNI"
23819 "movddup\t{%1, %0|%0, %1}"
23820 [(set_attr "type" "ssecvt")
23821 (set_attr "mode" "DF")])