builtins.c (expand_builtin_strcmp): Defend against the possibility that gen_cmpstrsi...
[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 GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_PROBE 10)
67 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SET_GOT 12)
69 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70
71 ; TLS support
72 (UNSPEC_TP 15)
73 (UNSPEC_TLS_GD 16)
74 (UNSPEC_TLS_LD_BASE 17)
75
76 ; Other random patterns
77 (UNSPEC_SCAS 20)
78 (UNSPEC_SIN 21)
79 (UNSPEC_COS 22)
80 (UNSPEC_FNSTSW 24)
81 (UNSPEC_SAHF 25)
82 (UNSPEC_FSTCW 26)
83 (UNSPEC_ADD_CARRY 27)
84 (UNSPEC_FLDCW 28)
85
86 ; For SSE/MMX support:
87 (UNSPEC_FIX 30)
88 (UNSPEC_MASKMOV 32)
89 (UNSPEC_MOVMSK 33)
90 (UNSPEC_MOVNT 34)
91 (UNSPEC_MOVA 38)
92 (UNSPEC_MOVU 39)
93 (UNSPEC_SHUFFLE 41)
94 (UNSPEC_RCP 42)
95 (UNSPEC_RSQRT 43)
96 (UNSPEC_SFENCE 44)
97 (UNSPEC_NOP 45) ; prevents combiner cleverness
98 (UNSPEC_PAVGUSB 49)
99 (UNSPEC_PFRCP 50)
100 (UNSPEC_PFRCPIT1 51)
101 (UNSPEC_PFRCPIT2 52)
102 (UNSPEC_PFRSQRT 53)
103 (UNSPEC_PFRSQIT1 54)
104 (UNSPEC_PSHUFLW 55)
105 (UNSPEC_PSHUFHW 56)
106 (UNSPEC_MFENCE 59)
107 (UNSPEC_LFENCE 60)
108 (UNSPEC_PSADBW 61)
109 (UNSPEC_ADDSUB 71)
110 (UNSPEC_HADD 72)
111 (UNSPEC_HSUB 73)
112 (UNSPEC_MOVSHDUP 74)
113 (UNSPEC_MOVSLDUP 75)
114 (UNSPEC_LDQQU 76)
115 (UNSPEC_MOVDDUP 77)
116
117 ; x87 Floating point
118 (UNSPEC_FPATAN 65)
119 (UNSPEC_FYL2X 66)
120 (UNSPEC_FSCALE 67)
121 (UNSPEC_FRNDINT 68)
122 (UNSPEC_F2XM1 69)
123
124 ; REP instruction
125 (UNSPEC_REP 75)
126 ])
127
128 (define_constants
129 [(UNSPECV_BLOCKAGE 0)
130 (UNSPECV_EH_RETURN 13)
131 (UNSPECV_EMMS 31)
132 (UNSPECV_LDMXCSR 37)
133 (UNSPECV_STMXCSR 40)
134 (UNSPECV_FEMMS 46)
135 (UNSPECV_CLFLUSH 57)
136 (UNSPECV_ALIGN 68)
137 (UNSPECV_MONITOR 69)
138 (UNSPECV_MWAIT 70)
139 ])
140
141 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
142 ;; from i386.c.
143
144 ;; In C guard expressions, put expressions which may be compile-time
145 ;; constants first. This allows for better optimization. For
146 ;; example, write "TARGET_64BIT && reload_completed", not
147 ;; "reload_completed && TARGET_64BIT".
148
149 \f
150 ;; Processor type. This attribute must exactly match the processor_type
151 ;; enumeration in i386.h.
152 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
153 (const (symbol_ref "ix86_tune")))
154
155 ;; A basic instruction type. Refinements due to arguments to be
156 ;; provided in other attributes.
157 (define_attr "type"
158 "other,multi,
159 alu,alu1,negnot,imov,imovx,lea,
160 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
161 icmp,test,ibr,setcc,icmov,
162 push,pop,call,callv,leave,
163 str,cld,
164 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
165 sselog,sseiadd,sseishft,sseimul,
166 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
167 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
168 (const_string "other"))
169
170 ;; Main data type used by the insn
171 (define_attr "mode"
172 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
173 (const_string "unknown"))
174
175 ;; The CPU unit operations uses.
176 (define_attr "unit" "integer,i387,sse,mmx,unknown"
177 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
178 (const_string "i387")
179 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
180 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
181 (const_string "sse")
182 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
183 (const_string "mmx")
184 (eq_attr "type" "other")
185 (const_string "unknown")]
186 (const_string "integer")))
187
188 ;; The (bounding maximum) length of an instruction immediate.
189 (define_attr "length_immediate" ""
190 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
191 (const_int 0)
192 (eq_attr "unit" "i387,sse,mmx")
193 (const_int 0)
194 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
195 imul,icmp,push,pop")
196 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
197 (eq_attr "type" "imov,test")
198 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
199 (eq_attr "type" "call")
200 (if_then_else (match_operand 0 "constant_call_address_operand" "")
201 (const_int 4)
202 (const_int 0))
203 (eq_attr "type" "callv")
204 (if_then_else (match_operand 1 "constant_call_address_operand" "")
205 (const_int 4)
206 (const_int 0))
207 ;; We don't know the size before shorten_branches. Expect
208 ;; the instruction to fit for better scheduling.
209 (eq_attr "type" "ibr")
210 (const_int 1)
211 ]
212 (symbol_ref "/* Update immediate_length and other attributes! */
213 abort(),1")))
214
215 ;; The (bounding maximum) length of an instruction address.
216 (define_attr "length_address" ""
217 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
218 (const_int 0)
219 (and (eq_attr "type" "call")
220 (match_operand 0 "constant_call_address_operand" ""))
221 (const_int 0)
222 (and (eq_attr "type" "callv")
223 (match_operand 1 "constant_call_address_operand" ""))
224 (const_int 0)
225 ]
226 (symbol_ref "ix86_attr_length_address_default (insn)")))
227
228 ;; Set when length prefix is used.
229 (define_attr "prefix_data16" ""
230 (if_then_else (ior (eq_attr "mode" "HI")
231 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
232 (const_int 1)
233 (const_int 0)))
234
235 ;; Set when string REP prefix is used.
236 (define_attr "prefix_rep" ""
237 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
238 (const_int 1)
239 (const_int 0)))
240
241 ;; Set when 0f opcode prefix is used.
242 (define_attr "prefix_0f" ""
243 (if_then_else
244 (ior (eq_attr "type" "imovx,setcc,icmov")
245 (eq_attr "unit" "sse,mmx"))
246 (const_int 1)
247 (const_int 0)))
248
249 ;; Set when 0f opcode prefix is used.
250 (define_attr "prefix_rex" ""
251 (cond [(and (eq_attr "mode" "DI")
252 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
253 (const_int 1)
254 (and (eq_attr "mode" "QI")
255 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
256 (const_int 0)))
257 (const_int 1)
258 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
259 (const_int 0))
260 (const_int 1)
261 ]
262 (const_int 0)))
263
264 ;; Set when modrm byte is used.
265 (define_attr "modrm" ""
266 (cond [(eq_attr "type" "str,cld,leave")
267 (const_int 0)
268 (eq_attr "unit" "i387")
269 (const_int 0)
270 (and (eq_attr "type" "incdec")
271 (ior (match_operand:SI 1 "register_operand" "")
272 (match_operand:HI 1 "register_operand" "")))
273 (const_int 0)
274 (and (eq_attr "type" "push")
275 (not (match_operand 1 "memory_operand" "")))
276 (const_int 0)
277 (and (eq_attr "type" "pop")
278 (not (match_operand 0 "memory_operand" "")))
279 (const_int 0)
280 (and (eq_attr "type" "imov")
281 (and (match_operand 0 "register_operand" "")
282 (match_operand 1 "immediate_operand" "")))
283 (const_int 0)
284 (and (eq_attr "type" "call")
285 (match_operand 0 "constant_call_address_operand" ""))
286 (const_int 0)
287 (and (eq_attr "type" "callv")
288 (match_operand 1 "constant_call_address_operand" ""))
289 (const_int 0)
290 ]
291 (const_int 1)))
292
293 ;; The (bounding maximum) length of an instruction in bytes.
294 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
295 ;; to split it and compute proper length as for other insns.
296 (define_attr "length" ""
297 (cond [(eq_attr "type" "other,multi,fistp")
298 (const_int 16)
299 (eq_attr "type" "fcmp")
300 (const_int 4)
301 (eq_attr "unit" "i387")
302 (plus (const_int 2)
303 (plus (attr "prefix_data16")
304 (attr "length_address")))]
305 (plus (plus (attr "modrm")
306 (plus (attr "prefix_0f")
307 (plus (attr "prefix_rex")
308 (const_int 1))))
309 (plus (attr "prefix_rep")
310 (plus (attr "prefix_data16")
311 (plus (attr "length_immediate")
312 (attr "length_address")))))))
313
314 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
315 ;; `store' if there is a simple memory reference therein, or `unknown'
316 ;; if the instruction is complex.
317
318 (define_attr "memory" "none,load,store,both,unknown"
319 (cond [(eq_attr "type" "other,multi,str")
320 (const_string "unknown")
321 (eq_attr "type" "lea,fcmov,fpspc,cld")
322 (const_string "none")
323 (eq_attr "type" "fistp,leave")
324 (const_string "both")
325 (eq_attr "type" "push")
326 (if_then_else (match_operand 1 "memory_operand" "")
327 (const_string "both")
328 (const_string "store"))
329 (eq_attr "type" "pop")
330 (if_then_else (match_operand 0 "memory_operand" "")
331 (const_string "both")
332 (const_string "load"))
333 (eq_attr "type" "setcc")
334 (if_then_else (match_operand 0 "memory_operand" "")
335 (const_string "store")
336 (const_string "none"))
337 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
338 (if_then_else (ior (match_operand 0 "memory_operand" "")
339 (match_operand 1 "memory_operand" ""))
340 (const_string "load")
341 (const_string "none"))
342 (eq_attr "type" "ibr")
343 (if_then_else (match_operand 0 "memory_operand" "")
344 (const_string "load")
345 (const_string "none"))
346 (eq_attr "type" "call")
347 (if_then_else (match_operand 0 "constant_call_address_operand" "")
348 (const_string "none")
349 (const_string "load"))
350 (eq_attr "type" "callv")
351 (if_then_else (match_operand 1 "constant_call_address_operand" "")
352 (const_string "none")
353 (const_string "load"))
354 (and (eq_attr "type" "alu1,negnot,ishift1")
355 (match_operand 1 "memory_operand" ""))
356 (const_string "both")
357 (and (match_operand 0 "memory_operand" "")
358 (match_operand 1 "memory_operand" ""))
359 (const_string "both")
360 (match_operand 0 "memory_operand" "")
361 (const_string "store")
362 (match_operand 1 "memory_operand" "")
363 (const_string "load")
364 (and (eq_attr "type"
365 "!alu1,negnot,ishift1,
366 imov,imovx,icmp,test,
367 fmov,fcmp,fsgn,
368 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
369 mmx,mmxmov,mmxcmp,mmxcvt")
370 (match_operand 2 "memory_operand" ""))
371 (const_string "load")
372 (and (eq_attr "type" "icmov")
373 (match_operand 3 "memory_operand" ""))
374 (const_string "load")
375 ]
376 (const_string "none")))
377
378 ;; Indicates if an instruction has both an immediate and a displacement.
379
380 (define_attr "imm_disp" "false,true,unknown"
381 (cond [(eq_attr "type" "other,multi")
382 (const_string "unknown")
383 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
384 (and (match_operand 0 "memory_displacement_operand" "")
385 (match_operand 1 "immediate_operand" "")))
386 (const_string "true")
387 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
388 (and (match_operand 0 "memory_displacement_operand" "")
389 (match_operand 2 "immediate_operand" "")))
390 (const_string "true")
391 ]
392 (const_string "false")))
393
394 ;; Indicates if an FP operation has an integer source.
395
396 (define_attr "fp_int_src" "false,true"
397 (const_string "false"))
398
399 ;; Describe a user's asm statement.
400 (define_asm_attributes
401 [(set_attr "length" "128")
402 (set_attr "type" "multi")])
403 \f
404 (include "pentium.md")
405 (include "ppro.md")
406 (include "k6.md")
407 (include "athlon.md")
408 \f
409 ;; Compare instructions.
410
411 ;; All compare insns have expanders that save the operands away without
412 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
413 ;; after the cmp) will actually emit the cmpM.
414
415 (define_expand "cmpdi"
416 [(set (reg:CC 17)
417 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
418 (match_operand:DI 1 "x86_64_general_operand" "")))]
419 ""
420 {
421 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
422 operands[0] = force_reg (DImode, operands[0]);
423 ix86_compare_op0 = operands[0];
424 ix86_compare_op1 = operands[1];
425 DONE;
426 })
427
428 (define_expand "cmpsi"
429 [(set (reg:CC 17)
430 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
431 (match_operand:SI 1 "general_operand" "")))]
432 ""
433 {
434 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
435 operands[0] = force_reg (SImode, operands[0]);
436 ix86_compare_op0 = operands[0];
437 ix86_compare_op1 = operands[1];
438 DONE;
439 })
440
441 (define_expand "cmphi"
442 [(set (reg:CC 17)
443 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
444 (match_operand:HI 1 "general_operand" "")))]
445 ""
446 {
447 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
448 operands[0] = force_reg (HImode, operands[0]);
449 ix86_compare_op0 = operands[0];
450 ix86_compare_op1 = operands[1];
451 DONE;
452 })
453
454 (define_expand "cmpqi"
455 [(set (reg:CC 17)
456 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
457 (match_operand:QI 1 "general_operand" "")))]
458 "TARGET_QIMODE_MATH"
459 {
460 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
461 operands[0] = force_reg (QImode, operands[0]);
462 ix86_compare_op0 = operands[0];
463 ix86_compare_op1 = operands[1];
464 DONE;
465 })
466
467 (define_insn "cmpdi_ccno_1_rex64"
468 [(set (reg 17)
469 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
470 (match_operand:DI 1 "const0_operand" "n,n")))]
471 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
472 "@
473 test{q}\t{%0, %0|%0, %0}
474 cmp{q}\t{%1, %0|%0, %1}"
475 [(set_attr "type" "test,icmp")
476 (set_attr "length_immediate" "0,1")
477 (set_attr "mode" "DI")])
478
479 (define_insn "*cmpdi_minus_1_rex64"
480 [(set (reg 17)
481 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
482 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
483 (const_int 0)))]
484 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
485 "cmp{q}\t{%1, %0|%0, %1}"
486 [(set_attr "type" "icmp")
487 (set_attr "mode" "DI")])
488
489 (define_expand "cmpdi_1_rex64"
490 [(set (reg:CC 17)
491 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
492 (match_operand:DI 1 "general_operand" "")))]
493 "TARGET_64BIT"
494 "")
495
496 (define_insn "cmpdi_1_insn_rex64"
497 [(set (reg 17)
498 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
499 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
500 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
501 "cmp{q}\t{%1, %0|%0, %1}"
502 [(set_attr "type" "icmp")
503 (set_attr "mode" "DI")])
504
505
506 (define_insn "*cmpsi_ccno_1"
507 [(set (reg 17)
508 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
509 (match_operand:SI 1 "const0_operand" "n,n")))]
510 "ix86_match_ccmode (insn, CCNOmode)"
511 "@
512 test{l}\t{%0, %0|%0, %0}
513 cmp{l}\t{%1, %0|%0, %1}"
514 [(set_attr "type" "test,icmp")
515 (set_attr "length_immediate" "0,1")
516 (set_attr "mode" "SI")])
517
518 (define_insn "*cmpsi_minus_1"
519 [(set (reg 17)
520 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
521 (match_operand:SI 1 "general_operand" "ri,mr"))
522 (const_int 0)))]
523 "ix86_match_ccmode (insn, CCGOCmode)"
524 "cmp{l}\t{%1, %0|%0, %1}"
525 [(set_attr "type" "icmp")
526 (set_attr "mode" "SI")])
527
528 (define_expand "cmpsi_1"
529 [(set (reg:CC 17)
530 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
531 (match_operand:SI 1 "general_operand" "ri,mr")))]
532 ""
533 "")
534
535 (define_insn "*cmpsi_1_insn"
536 [(set (reg 17)
537 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
538 (match_operand:SI 1 "general_operand" "ri,mr")))]
539 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
540 && ix86_match_ccmode (insn, CCmode)"
541 "cmp{l}\t{%1, %0|%0, %1}"
542 [(set_attr "type" "icmp")
543 (set_attr "mode" "SI")])
544
545 (define_insn "*cmphi_ccno_1"
546 [(set (reg 17)
547 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
548 (match_operand:HI 1 "const0_operand" "n,n")))]
549 "ix86_match_ccmode (insn, CCNOmode)"
550 "@
551 test{w}\t{%0, %0|%0, %0}
552 cmp{w}\t{%1, %0|%0, %1}"
553 [(set_attr "type" "test,icmp")
554 (set_attr "length_immediate" "0,1")
555 (set_attr "mode" "HI")])
556
557 (define_insn "*cmphi_minus_1"
558 [(set (reg 17)
559 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
560 (match_operand:HI 1 "general_operand" "ri,mr"))
561 (const_int 0)))]
562 "ix86_match_ccmode (insn, CCGOCmode)"
563 "cmp{w}\t{%1, %0|%0, %1}"
564 [(set_attr "type" "icmp")
565 (set_attr "mode" "HI")])
566
567 (define_insn "*cmphi_1"
568 [(set (reg 17)
569 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
570 (match_operand:HI 1 "general_operand" "ri,mr")))]
571 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
572 && ix86_match_ccmode (insn, CCmode)"
573 "cmp{w}\t{%1, %0|%0, %1}"
574 [(set_attr "type" "icmp")
575 (set_attr "mode" "HI")])
576
577 (define_insn "*cmpqi_ccno_1"
578 [(set (reg 17)
579 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
580 (match_operand:QI 1 "const0_operand" "n,n")))]
581 "ix86_match_ccmode (insn, CCNOmode)"
582 "@
583 test{b}\t{%0, %0|%0, %0}
584 cmp{b}\t{$0, %0|%0, 0}"
585 [(set_attr "type" "test,icmp")
586 (set_attr "length_immediate" "0,1")
587 (set_attr "mode" "QI")])
588
589 (define_insn "*cmpqi_1"
590 [(set (reg 17)
591 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
592 (match_operand:QI 1 "general_operand" "qi,mq")))]
593 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
594 && ix86_match_ccmode (insn, CCmode)"
595 "cmp{b}\t{%1, %0|%0, %1}"
596 [(set_attr "type" "icmp")
597 (set_attr "mode" "QI")])
598
599 (define_insn "*cmpqi_minus_1"
600 [(set (reg 17)
601 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
602 (match_operand:QI 1 "general_operand" "qi,mq"))
603 (const_int 0)))]
604 "ix86_match_ccmode (insn, CCGOCmode)"
605 "cmp{b}\t{%1, %0|%0, %1}"
606 [(set_attr "type" "icmp")
607 (set_attr "mode" "QI")])
608
609 (define_insn "*cmpqi_ext_1"
610 [(set (reg 17)
611 (compare
612 (match_operand:QI 0 "general_operand" "Qm")
613 (subreg:QI
614 (zero_extract:SI
615 (match_operand 1 "ext_register_operand" "Q")
616 (const_int 8)
617 (const_int 8)) 0)))]
618 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
619 "cmp{b}\t{%h1, %0|%0, %h1}"
620 [(set_attr "type" "icmp")
621 (set_attr "mode" "QI")])
622
623 (define_insn "*cmpqi_ext_1_rex64"
624 [(set (reg 17)
625 (compare
626 (match_operand:QI 0 "register_operand" "Q")
627 (subreg:QI
628 (zero_extract:SI
629 (match_operand 1 "ext_register_operand" "Q")
630 (const_int 8)
631 (const_int 8)) 0)))]
632 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
633 "cmp{b}\t{%h1, %0|%0, %h1}"
634 [(set_attr "type" "icmp")
635 (set_attr "mode" "QI")])
636
637 (define_insn "*cmpqi_ext_2"
638 [(set (reg 17)
639 (compare
640 (subreg:QI
641 (zero_extract:SI
642 (match_operand 0 "ext_register_operand" "Q")
643 (const_int 8)
644 (const_int 8)) 0)
645 (match_operand:QI 1 "const0_operand" "n")))]
646 "ix86_match_ccmode (insn, CCNOmode)"
647 "test{b}\t%h0, %h0"
648 [(set_attr "type" "test")
649 (set_attr "length_immediate" "0")
650 (set_attr "mode" "QI")])
651
652 (define_expand "cmpqi_ext_3"
653 [(set (reg:CC 17)
654 (compare:CC
655 (subreg:QI
656 (zero_extract:SI
657 (match_operand 0 "ext_register_operand" "")
658 (const_int 8)
659 (const_int 8)) 0)
660 (match_operand:QI 1 "general_operand" "")))]
661 ""
662 "")
663
664 (define_insn "cmpqi_ext_3_insn"
665 [(set (reg 17)
666 (compare
667 (subreg:QI
668 (zero_extract:SI
669 (match_operand 0 "ext_register_operand" "Q")
670 (const_int 8)
671 (const_int 8)) 0)
672 (match_operand:QI 1 "general_operand" "Qmn")))]
673 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
674 "cmp{b}\t{%1, %h0|%h0, %1}"
675 [(set_attr "type" "icmp")
676 (set_attr "mode" "QI")])
677
678 (define_insn "cmpqi_ext_3_insn_rex64"
679 [(set (reg 17)
680 (compare
681 (subreg:QI
682 (zero_extract:SI
683 (match_operand 0 "ext_register_operand" "Q")
684 (const_int 8)
685 (const_int 8)) 0)
686 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688 "cmp{b}\t{%1, %h0|%h0, %1}"
689 [(set_attr "type" "icmp")
690 (set_attr "mode" "QI")])
691
692 (define_insn "*cmpqi_ext_4"
693 [(set (reg 17)
694 (compare
695 (subreg:QI
696 (zero_extract:SI
697 (match_operand 0 "ext_register_operand" "Q")
698 (const_int 8)
699 (const_int 8)) 0)
700 (subreg:QI
701 (zero_extract:SI
702 (match_operand 1 "ext_register_operand" "Q")
703 (const_int 8)
704 (const_int 8)) 0)))]
705 "ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%h1, %h0|%h0, %h1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
709
710 ;; These implement float point compares.
711 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
712 ;; which would allow mix and match FP modes on the compares. Which is what
713 ;; the old patterns did, but with many more of them.
714
715 (define_expand "cmpxf"
716 [(set (reg:CC 17)
717 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
718 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
719 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
720 {
721 ix86_compare_op0 = operands[0];
722 ix86_compare_op1 = operands[1];
723 DONE;
724 })
725
726 (define_expand "cmptf"
727 [(set (reg:CC 17)
728 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
729 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
730 "TARGET_80387"
731 {
732 ix86_compare_op0 = operands[0];
733 ix86_compare_op1 = operands[1];
734 DONE;
735 })
736
737 (define_expand "cmpdf"
738 [(set (reg:CC 17)
739 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
740 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
741 "TARGET_80387 || TARGET_SSE2"
742 {
743 ix86_compare_op0 = operands[0];
744 ix86_compare_op1 = operands[1];
745 DONE;
746 })
747
748 (define_expand "cmpsf"
749 [(set (reg:CC 17)
750 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
751 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
752 "TARGET_80387 || TARGET_SSE"
753 {
754 ix86_compare_op0 = operands[0];
755 ix86_compare_op1 = operands[1];
756 DONE;
757 })
758
759 ;; FP compares, step 1:
760 ;; Set the FP condition codes.
761 ;;
762 ;; CCFPmode compare with exceptions
763 ;; CCFPUmode compare with no exceptions
764
765 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
766 ;; and that fp moves clobber the condition codes, and that there is
767 ;; currently no way to describe this fact to reg-stack. So there are
768 ;; no splitters yet for this.
769
770 ;; %%% YIKES! This scheme does not retain a strong connection between
771 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
772 ;; work! Only allow tos/mem with tos in op 0.
773 ;;
774 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
775 ;; things aren't as bad as they sound...
776
777 (define_insn "*cmpfp_0"
778 [(set (match_operand:HI 0 "register_operand" "=a")
779 (unspec:HI
780 [(compare:CCFP (match_operand 1 "register_operand" "f")
781 (match_operand 2 "const0_operand" "X"))]
782 UNSPEC_FNSTSW))]
783 "TARGET_80387
784 && FLOAT_MODE_P (GET_MODE (operands[1]))
785 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
786 {
787 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
788 return "ftst\;fnstsw\t%0\;fstp\t%y0";
789 else
790 return "ftst\;fnstsw\t%0";
791 }
792 [(set_attr "type" "multi")
793 (set (attr "mode")
794 (cond [(match_operand:SF 1 "" "")
795 (const_string "SF")
796 (match_operand:DF 1 "" "")
797 (const_string "DF")
798 ]
799 (const_string "XF")))])
800
801 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
802 ;; used to manage the reg stack popping would not be preserved.
803
804 (define_insn "*cmpfp_2_sf"
805 [(set (reg:CCFP 18)
806 (compare:CCFP
807 (match_operand:SF 0 "register_operand" "f")
808 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
809 "TARGET_80387"
810 "* return output_fp_compare (insn, operands, 0, 0);"
811 [(set_attr "type" "fcmp")
812 (set_attr "mode" "SF")])
813
814 (define_insn "*cmpfp_2_sf_1"
815 [(set (match_operand:HI 0 "register_operand" "=a")
816 (unspec:HI
817 [(compare:CCFP
818 (match_operand:SF 1 "register_operand" "f")
819 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
820 UNSPEC_FNSTSW))]
821 "TARGET_80387"
822 "* return output_fp_compare (insn, operands, 2, 0);"
823 [(set_attr "type" "fcmp")
824 (set_attr "mode" "SF")])
825
826 (define_insn "*cmpfp_2_df"
827 [(set (reg:CCFP 18)
828 (compare:CCFP
829 (match_operand:DF 0 "register_operand" "f")
830 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
831 "TARGET_80387"
832 "* return output_fp_compare (insn, operands, 0, 0);"
833 [(set_attr "type" "fcmp")
834 (set_attr "mode" "DF")])
835
836 (define_insn "*cmpfp_2_df_1"
837 [(set (match_operand:HI 0 "register_operand" "=a")
838 (unspec:HI
839 [(compare:CCFP
840 (match_operand:DF 1 "register_operand" "f")
841 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
842 UNSPEC_FNSTSW))]
843 "TARGET_80387"
844 "* return output_fp_compare (insn, operands, 2, 0);"
845 [(set_attr "type" "multi")
846 (set_attr "mode" "DF")])
847
848 (define_insn "*cmpfp_2_xf"
849 [(set (reg:CCFP 18)
850 (compare:CCFP
851 (match_operand:XF 0 "register_operand" "f")
852 (match_operand:XF 1 "register_operand" "f")))]
853 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
854 "* return output_fp_compare (insn, operands, 0, 0);"
855 [(set_attr "type" "fcmp")
856 (set_attr "mode" "XF")])
857
858 (define_insn "*cmpfp_2_tf"
859 [(set (reg:CCFP 18)
860 (compare:CCFP
861 (match_operand:TF 0 "register_operand" "f")
862 (match_operand:TF 1 "register_operand" "f")))]
863 "TARGET_80387"
864 "* return output_fp_compare (insn, operands, 0, 0);"
865 [(set_attr "type" "fcmp")
866 (set_attr "mode" "XF")])
867
868 (define_insn "*cmpfp_2_xf_1"
869 [(set (match_operand:HI 0 "register_operand" "=a")
870 (unspec:HI
871 [(compare:CCFP
872 (match_operand:XF 1 "register_operand" "f")
873 (match_operand:XF 2 "register_operand" "f"))]
874 UNSPEC_FNSTSW))]
875 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
876 "* return output_fp_compare (insn, operands, 2, 0);"
877 [(set_attr "type" "multi")
878 (set_attr "mode" "XF")])
879
880 (define_insn "*cmpfp_2_tf_1"
881 [(set (match_operand:HI 0 "register_operand" "=a")
882 (unspec:HI
883 [(compare:CCFP
884 (match_operand:TF 1 "register_operand" "f")
885 (match_operand:TF 2 "register_operand" "f"))]
886 UNSPEC_FNSTSW))]
887 "TARGET_80387"
888 "* return output_fp_compare (insn, operands, 2, 0);"
889 [(set_attr "type" "multi")
890 (set_attr "mode" "XF")])
891
892 (define_insn "*cmpfp_2u"
893 [(set (reg:CCFPU 18)
894 (compare:CCFPU
895 (match_operand 0 "register_operand" "f")
896 (match_operand 1 "register_operand" "f")))]
897 "TARGET_80387
898 && FLOAT_MODE_P (GET_MODE (operands[0]))
899 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
900 "* return output_fp_compare (insn, operands, 0, 1);"
901 [(set_attr "type" "fcmp")
902 (set (attr "mode")
903 (cond [(match_operand:SF 1 "" "")
904 (const_string "SF")
905 (match_operand:DF 1 "" "")
906 (const_string "DF")
907 ]
908 (const_string "XF")))])
909
910 (define_insn "*cmpfp_2u_1"
911 [(set (match_operand:HI 0 "register_operand" "=a")
912 (unspec:HI
913 [(compare:CCFPU
914 (match_operand 1 "register_operand" "f")
915 (match_operand 2 "register_operand" "f"))]
916 UNSPEC_FNSTSW))]
917 "TARGET_80387
918 && FLOAT_MODE_P (GET_MODE (operands[1]))
919 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
920 "* return output_fp_compare (insn, operands, 2, 1);"
921 [(set_attr "type" "multi")
922 (set (attr "mode")
923 (cond [(match_operand:SF 1 "" "")
924 (const_string "SF")
925 (match_operand:DF 1 "" "")
926 (const_string "DF")
927 ]
928 (const_string "XF")))])
929
930 ;; Patterns to match the SImode-in-memory ficom instructions.
931 ;;
932 ;; %%% Play games with accepting gp registers, as otherwise we have to
933 ;; force them to memory during rtl generation, which is no good. We
934 ;; can get rid of this once we teach reload to do memory input reloads
935 ;; via pushes.
936
937 (define_insn "*ficom_1"
938 [(set (reg:CCFP 18)
939 (compare:CCFP
940 (match_operand 0 "register_operand" "f,f")
941 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
942 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
943 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
944 "#")
945
946 ;; Split the not-really-implemented gp register case into a
947 ;; push-op-pop sequence.
948 ;;
949 ;; %%% This is most efficient, but am I gonna get in trouble
950 ;; for separating cc0_setter and cc0_user?
951
952 (define_split
953 [(set (reg:CCFP 18)
954 (compare:CCFP
955 (match_operand:SF 0 "register_operand" "")
956 (float (match_operand:SI 1 "register_operand" ""))))]
957 "0 && TARGET_80387 && reload_completed"
958 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
959 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
960 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
961 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
962 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
963 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
964
965 ;; FP compares, step 2
966 ;; Move the fpsw to ax.
967
968 (define_insn "*x86_fnstsw_1"
969 [(set (match_operand:HI 0 "register_operand" "=a")
970 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
971 "TARGET_80387"
972 "fnstsw\t%0"
973 [(set_attr "length" "2")
974 (set_attr "mode" "SI")
975 (set_attr "unit" "i387")
976 (set_attr "ppro_uops" "few")])
977
978 ;; FP compares, step 3
979 ;; Get ax into flags, general case.
980
981 (define_insn "x86_sahf_1"
982 [(set (reg:CC 17)
983 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
984 "!TARGET_64BIT"
985 "sahf"
986 [(set_attr "length" "1")
987 (set_attr "athlon_decode" "vector")
988 (set_attr "mode" "SI")
989 (set_attr "ppro_uops" "one")])
990
991 ;; Pentium Pro can do steps 1 through 3 in one go.
992
993 (define_insn "*cmpfp_i"
994 [(set (reg:CCFP 17)
995 (compare:CCFP (match_operand 0 "register_operand" "f")
996 (match_operand 1 "register_operand" "f")))]
997 "TARGET_80387 && TARGET_CMOVE
998 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999 && FLOAT_MODE_P (GET_MODE (operands[0]))
1000 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1001 "* return output_fp_compare (insn, operands, 1, 0);"
1002 [(set_attr "type" "fcmp")
1003 (set (attr "mode")
1004 (cond [(match_operand:SF 1 "" "")
1005 (const_string "SF")
1006 (match_operand:DF 1 "" "")
1007 (const_string "DF")
1008 ]
1009 (const_string "XF")))
1010 (set_attr "athlon_decode" "vector")])
1011
1012 (define_insn "*cmpfp_i_sse"
1013 [(set (reg:CCFP 17)
1014 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1015 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1016 "TARGET_80387
1017 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1018 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1019 "* return output_fp_compare (insn, operands, 1, 0);"
1020 [(set_attr "type" "fcmp,ssecomi")
1021 (set (attr "mode")
1022 (if_then_else (match_operand:SF 1 "" "")
1023 (const_string "SF")
1024 (const_string "DF")))
1025 (set_attr "athlon_decode" "vector")])
1026
1027 (define_insn "*cmpfp_i_sse_only"
1028 [(set (reg:CCFP 17)
1029 (compare:CCFP (match_operand 0 "register_operand" "x")
1030 (match_operand 1 "nonimmediate_operand" "xm")))]
1031 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1032 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1033 "* return output_fp_compare (insn, operands, 1, 0);"
1034 [(set_attr "type" "ssecomi")
1035 (set (attr "mode")
1036 (if_then_else (match_operand:SF 1 "" "")
1037 (const_string "SF")
1038 (const_string "DF")))
1039 (set_attr "athlon_decode" "vector")])
1040
1041 (define_insn "*cmpfp_iu"
1042 [(set (reg:CCFPU 17)
1043 (compare:CCFPU (match_operand 0 "register_operand" "f")
1044 (match_operand 1 "register_operand" "f")))]
1045 "TARGET_80387 && TARGET_CMOVE
1046 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1047 && FLOAT_MODE_P (GET_MODE (operands[0]))
1048 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1049 "* return output_fp_compare (insn, operands, 1, 1);"
1050 [(set_attr "type" "fcmp")
1051 (set (attr "mode")
1052 (cond [(match_operand:SF 1 "" "")
1053 (const_string "SF")
1054 (match_operand:DF 1 "" "")
1055 (const_string "DF")
1056 ]
1057 (const_string "XF")))
1058 (set_attr "athlon_decode" "vector")])
1059
1060 (define_insn "*cmpfp_iu_sse"
1061 [(set (reg:CCFPU 17)
1062 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1063 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1064 "TARGET_80387
1065 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1066 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1067 "* return output_fp_compare (insn, operands, 1, 1);"
1068 [(set_attr "type" "fcmp,ssecomi")
1069 (set (attr "mode")
1070 (if_then_else (match_operand:SF 1 "" "")
1071 (const_string "SF")
1072 (const_string "DF")))
1073 (set_attr "athlon_decode" "vector")])
1074
1075 (define_insn "*cmpfp_iu_sse_only"
1076 [(set (reg:CCFPU 17)
1077 (compare:CCFPU (match_operand 0 "register_operand" "x")
1078 (match_operand 1 "nonimmediate_operand" "xm")))]
1079 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1080 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1081 "* return output_fp_compare (insn, operands, 1, 1);"
1082 [(set_attr "type" "ssecomi")
1083 (set (attr "mode")
1084 (if_then_else (match_operand:SF 1 "" "")
1085 (const_string "SF")
1086 (const_string "DF")))
1087 (set_attr "athlon_decode" "vector")])
1088 \f
1089 ;; Move instructions.
1090
1091 ;; General case of fullword move.
1092
1093 (define_expand "movsi"
1094 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1095 (match_operand:SI 1 "general_operand" ""))]
1096 ""
1097 "ix86_expand_move (SImode, operands); DONE;")
1098
1099 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1100 ;; general_operand.
1101 ;;
1102 ;; %%% We don't use a post-inc memory reference because x86 is not a
1103 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1104 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1105 ;; targets without our curiosities, and it is just as easy to represent
1106 ;; this differently.
1107
1108 (define_insn "*pushsi2"
1109 [(set (match_operand:SI 0 "push_operand" "=<")
1110 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1111 "!TARGET_64BIT"
1112 "push{l}\t%1"
1113 [(set_attr "type" "push")
1114 (set_attr "mode" "SI")])
1115
1116 ;; For 64BIT abi we always round up to 8 bytes.
1117 (define_insn "*pushsi2_rex64"
1118 [(set (match_operand:SI 0 "push_operand" "=X")
1119 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1120 "TARGET_64BIT"
1121 "push{q}\t%q1"
1122 [(set_attr "type" "push")
1123 (set_attr "mode" "SI")])
1124
1125 (define_insn "*pushsi2_prologue"
1126 [(set (match_operand:SI 0 "push_operand" "=<")
1127 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1128 (clobber (mem:BLK (scratch)))]
1129 "!TARGET_64BIT"
1130 "push{l}\t%1"
1131 [(set_attr "type" "push")
1132 (set_attr "mode" "SI")])
1133
1134 (define_insn "*popsi1_epilogue"
1135 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1136 (mem:SI (reg:SI 7)))
1137 (set (reg:SI 7)
1138 (plus:SI (reg:SI 7) (const_int 4)))
1139 (clobber (mem:BLK (scratch)))]
1140 "!TARGET_64BIT"
1141 "pop{l}\t%0"
1142 [(set_attr "type" "pop")
1143 (set_attr "mode" "SI")])
1144
1145 (define_insn "popsi1"
1146 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1147 (mem:SI (reg:SI 7)))
1148 (set (reg:SI 7)
1149 (plus:SI (reg:SI 7) (const_int 4)))]
1150 "!TARGET_64BIT"
1151 "pop{l}\t%0"
1152 [(set_attr "type" "pop")
1153 (set_attr "mode" "SI")])
1154
1155 (define_insn "*movsi_xor"
1156 [(set (match_operand:SI 0 "register_operand" "=r")
1157 (match_operand:SI 1 "const0_operand" "i"))
1158 (clobber (reg:CC 17))]
1159 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1160 "xor{l}\t{%0, %0|%0, %0}"
1161 [(set_attr "type" "alu1")
1162 (set_attr "mode" "SI")
1163 (set_attr "length_immediate" "0")])
1164
1165 (define_insn "*movsi_or"
1166 [(set (match_operand:SI 0 "register_operand" "=r")
1167 (match_operand:SI 1 "immediate_operand" "i"))
1168 (clobber (reg:CC 17))]
1169 "reload_completed
1170 && operands[1] == constm1_rtx
1171 && (TARGET_PENTIUM || optimize_size)"
1172 {
1173 operands[1] = constm1_rtx;
1174 return "or{l}\t{%1, %0|%0, %1}";
1175 }
1176 [(set_attr "type" "alu1")
1177 (set_attr "mode" "SI")
1178 (set_attr "length_immediate" "1")])
1179
1180 (define_insn "*movsi_1"
1181 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1182 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1183 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1184 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1185 {
1186 switch (get_attr_type (insn))
1187 {
1188 case TYPE_SSEMOV:
1189 if (get_attr_mode (insn) == MODE_TI)
1190 return "movdqa\t{%1, %0|%0, %1}";
1191 return "movd\t{%1, %0|%0, %1}";
1192
1193 case TYPE_MMXMOV:
1194 if (get_attr_mode (insn) == MODE_DI)
1195 return "movq\t{%1, %0|%0, %1}";
1196 return "movd\t{%1, %0|%0, %1}";
1197
1198 case TYPE_LEA:
1199 return "lea{l}\t{%1, %0|%0, %1}";
1200
1201 default:
1202 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1203 abort();
1204 return "mov{l}\t{%1, %0|%0, %1}";
1205 }
1206 }
1207 [(set (attr "type")
1208 (cond [(eq_attr "alternative" "2,3,4")
1209 (const_string "mmxmov")
1210 (eq_attr "alternative" "5,6,7")
1211 (const_string "ssemov")
1212 (and (ne (symbol_ref "flag_pic") (const_int 0))
1213 (match_operand:SI 1 "symbolic_operand" ""))
1214 (const_string "lea")
1215 ]
1216 (const_string "imov")))
1217 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1218
1219 (define_insn "*movsi_1_nointernunit"
1220 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1221 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1222 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1223 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1224 {
1225 switch (get_attr_type (insn))
1226 {
1227 case TYPE_SSEMOV:
1228 if (get_attr_mode (insn) == MODE_TI)
1229 return "movdqa\t{%1, %0|%0, %1}";
1230 return "movd\t{%1, %0|%0, %1}";
1231
1232 case TYPE_MMXMOV:
1233 if (get_attr_mode (insn) == MODE_DI)
1234 return "movq\t{%1, %0|%0, %1}";
1235 return "movd\t{%1, %0|%0, %1}";
1236
1237 case TYPE_LEA:
1238 return "lea{l}\t{%1, %0|%0, %1}";
1239
1240 default:
1241 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1242 abort();
1243 return "mov{l}\t{%1, %0|%0, %1}";
1244 }
1245 }
1246 [(set (attr "type")
1247 (cond [(eq_attr "alternative" "2,3,4")
1248 (const_string "mmxmov")
1249 (eq_attr "alternative" "5,6,7")
1250 (const_string "ssemov")
1251 (and (ne (symbol_ref "flag_pic") (const_int 0))
1252 (match_operand:SI 1 "symbolic_operand" ""))
1253 (const_string "lea")
1254 ]
1255 (const_string "imov")))
1256 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1257
1258 ;; Stores and loads of ax to arbitrary constant address.
1259 ;; We fake an second form of instruction to force reload to load address
1260 ;; into register when rax is not available
1261 (define_insn "*movabssi_1_rex64"
1262 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1263 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1264 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1265 "@
1266 movabs{l}\t{%1, %P0|%P0, %1}
1267 mov{l}\t{%1, %a0|%a0, %1}"
1268 [(set_attr "type" "imov")
1269 (set_attr "modrm" "0,*")
1270 (set_attr "length_address" "8,0")
1271 (set_attr "length_immediate" "0,*")
1272 (set_attr "memory" "store")
1273 (set_attr "mode" "SI")])
1274
1275 (define_insn "*movabssi_2_rex64"
1276 [(set (match_operand:SI 0 "register_operand" "=a,r")
1277 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1278 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1279 "@
1280 movabs{l}\t{%P1, %0|%0, %P1}
1281 mov{l}\t{%a1, %0|%0, %a1}"
1282 [(set_attr "type" "imov")
1283 (set_attr "modrm" "0,*")
1284 (set_attr "length_address" "8,0")
1285 (set_attr "length_immediate" "0")
1286 (set_attr "memory" "load")
1287 (set_attr "mode" "SI")])
1288
1289 (define_insn "*swapsi"
1290 [(set (match_operand:SI 0 "register_operand" "+r")
1291 (match_operand:SI 1 "register_operand" "+r"))
1292 (set (match_dup 1)
1293 (match_dup 0))]
1294 ""
1295 "xchg{l}\t%1, %0"
1296 [(set_attr "type" "imov")
1297 (set_attr "pent_pair" "np")
1298 (set_attr "athlon_decode" "vector")
1299 (set_attr "mode" "SI")
1300 (set_attr "modrm" "0")
1301 (set_attr "ppro_uops" "few")])
1302
1303 (define_expand "movhi"
1304 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1305 (match_operand:HI 1 "general_operand" ""))]
1306 ""
1307 "ix86_expand_move (HImode, operands); DONE;")
1308
1309 (define_insn "*pushhi2"
1310 [(set (match_operand:HI 0 "push_operand" "=<,<")
1311 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1312 "!TARGET_64BIT"
1313 "@
1314 push{w}\t{|WORD PTR }%1
1315 push{w}\t%1"
1316 [(set_attr "type" "push")
1317 (set_attr "mode" "HI")])
1318
1319 ;; For 64BIT abi we always round up to 8 bytes.
1320 (define_insn "*pushhi2_rex64"
1321 [(set (match_operand:HI 0 "push_operand" "=X")
1322 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1323 "TARGET_64BIT"
1324 "push{q}\t%q1"
1325 [(set_attr "type" "push")
1326 (set_attr "mode" "QI")])
1327
1328 (define_insn "*movhi_1"
1329 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1330 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1331 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1332 {
1333 switch (get_attr_type (insn))
1334 {
1335 case TYPE_IMOVX:
1336 /* movzwl is faster than movw on p2 due to partial word stalls,
1337 though not as fast as an aligned movl. */
1338 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1339 default:
1340 if (get_attr_mode (insn) == MODE_SI)
1341 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1342 else
1343 return "mov{w}\t{%1, %0|%0, %1}";
1344 }
1345 }
1346 [(set (attr "type")
1347 (cond [(and (eq_attr "alternative" "0")
1348 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1349 (const_int 0))
1350 (eq (symbol_ref "TARGET_HIMODE_MATH")
1351 (const_int 0))))
1352 (const_string "imov")
1353 (and (eq_attr "alternative" "1,2")
1354 (match_operand:HI 1 "aligned_operand" ""))
1355 (const_string "imov")
1356 (and (ne (symbol_ref "TARGET_MOVX")
1357 (const_int 0))
1358 (eq_attr "alternative" "0,2"))
1359 (const_string "imovx")
1360 ]
1361 (const_string "imov")))
1362 (set (attr "mode")
1363 (cond [(eq_attr "type" "imovx")
1364 (const_string "SI")
1365 (and (eq_attr "alternative" "1,2")
1366 (match_operand:HI 1 "aligned_operand" ""))
1367 (const_string "SI")
1368 (and (eq_attr "alternative" "0")
1369 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1370 (const_int 0))
1371 (eq (symbol_ref "TARGET_HIMODE_MATH")
1372 (const_int 0))))
1373 (const_string "SI")
1374 ]
1375 (const_string "HI")))])
1376
1377 ;; Stores and loads of ax to arbitrary constant address.
1378 ;; We fake an second form of instruction to force reload to load address
1379 ;; into register when rax is not available
1380 (define_insn "*movabshi_1_rex64"
1381 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1382 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1383 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1384 "@
1385 movabs{w}\t{%1, %P0|%P0, %1}
1386 mov{w}\t{%1, %a0|%a0, %1}"
1387 [(set_attr "type" "imov")
1388 (set_attr "modrm" "0,*")
1389 (set_attr "length_address" "8,0")
1390 (set_attr "length_immediate" "0,*")
1391 (set_attr "memory" "store")
1392 (set_attr "mode" "HI")])
1393
1394 (define_insn "*movabshi_2_rex64"
1395 [(set (match_operand:HI 0 "register_operand" "=a,r")
1396 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1397 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1398 "@
1399 movabs{w}\t{%P1, %0|%0, %P1}
1400 mov{w}\t{%a1, %0|%0, %a1}"
1401 [(set_attr "type" "imov")
1402 (set_attr "modrm" "0,*")
1403 (set_attr "length_address" "8,0")
1404 (set_attr "length_immediate" "0")
1405 (set_attr "memory" "load")
1406 (set_attr "mode" "HI")])
1407
1408 (define_insn "*swaphi_1"
1409 [(set (match_operand:HI 0 "register_operand" "+r")
1410 (match_operand:HI 1 "register_operand" "+r"))
1411 (set (match_dup 1)
1412 (match_dup 0))]
1413 "TARGET_PARTIAL_REG_STALL"
1414 "xchg{w}\t%1, %0"
1415 [(set_attr "type" "imov")
1416 (set_attr "pent_pair" "np")
1417 (set_attr "mode" "HI")
1418 (set_attr "modrm" "0")
1419 (set_attr "ppro_uops" "few")])
1420
1421 (define_insn "*swaphi_2"
1422 [(set (match_operand:HI 0 "register_operand" "+r")
1423 (match_operand:HI 1 "register_operand" "+r"))
1424 (set (match_dup 1)
1425 (match_dup 0))]
1426 "! TARGET_PARTIAL_REG_STALL"
1427 "xchg{l}\t%k1, %k0"
1428 [(set_attr "type" "imov")
1429 (set_attr "pent_pair" "np")
1430 (set_attr "mode" "SI")
1431 (set_attr "modrm" "0")
1432 (set_attr "ppro_uops" "few")])
1433
1434 (define_expand "movstricthi"
1435 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1436 (match_operand:HI 1 "general_operand" ""))]
1437 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1438 {
1439 /* Don't generate memory->memory moves, go through a register */
1440 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1441 operands[1] = force_reg (HImode, operands[1]);
1442 })
1443
1444 (define_insn "*movstricthi_1"
1445 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1446 (match_operand:HI 1 "general_operand" "rn,m"))]
1447 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1448 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1449 "mov{w}\t{%1, %0|%0, %1}"
1450 [(set_attr "type" "imov")
1451 (set_attr "mode" "HI")])
1452
1453 (define_insn "*movstricthi_xor"
1454 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1455 (match_operand:HI 1 "const0_operand" "i"))
1456 (clobber (reg:CC 17))]
1457 "reload_completed
1458 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1459 "xor{w}\t{%0, %0|%0, %0}"
1460 [(set_attr "type" "alu1")
1461 (set_attr "mode" "HI")
1462 (set_attr "length_immediate" "0")])
1463
1464 (define_expand "movqi"
1465 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1466 (match_operand:QI 1 "general_operand" ""))]
1467 ""
1468 "ix86_expand_move (QImode, operands); DONE;")
1469
1470 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1471 ;; "push a byte". But actually we use pushw, which has the effect
1472 ;; of rounding the amount pushed up to a halfword.
1473
1474 (define_insn "*pushqi2"
1475 [(set (match_operand:QI 0 "push_operand" "=X,X")
1476 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1477 "!TARGET_64BIT"
1478 "@
1479 push{w}\t{|word ptr }%1
1480 push{w}\t%w1"
1481 [(set_attr "type" "push")
1482 (set_attr "mode" "HI")])
1483
1484 ;; For 64BIT abi we always round up to 8 bytes.
1485 (define_insn "*pushqi2_rex64"
1486 [(set (match_operand:QI 0 "push_operand" "=X")
1487 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1488 "TARGET_64BIT"
1489 "push{q}\t%q1"
1490 [(set_attr "type" "push")
1491 (set_attr "mode" "QI")])
1492
1493 ;; Situation is quite tricky about when to choose full sized (SImode) move
1494 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1495 ;; partial register dependency machines (such as AMD Athlon), where QImode
1496 ;; moves issue extra dependency and for partial register stalls machines
1497 ;; that don't use QImode patterns (and QImode move cause stall on the next
1498 ;; instruction).
1499 ;;
1500 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1501 ;; register stall machines with, where we use QImode instructions, since
1502 ;; partial register stall can be caused there. Then we use movzx.
1503 (define_insn "*movqi_1"
1504 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1505 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1506 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1507 {
1508 switch (get_attr_type (insn))
1509 {
1510 case TYPE_IMOVX:
1511 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1512 abort ();
1513 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1514 default:
1515 if (get_attr_mode (insn) == MODE_SI)
1516 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1517 else
1518 return "mov{b}\t{%1, %0|%0, %1}";
1519 }
1520 }
1521 [(set (attr "type")
1522 (cond [(and (eq_attr "alternative" "3")
1523 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1524 (const_int 0))
1525 (eq (symbol_ref "TARGET_QIMODE_MATH")
1526 (const_int 0))))
1527 (const_string "imov")
1528 (eq_attr "alternative" "3,5")
1529 (const_string "imovx")
1530 (and (ne (symbol_ref "TARGET_MOVX")
1531 (const_int 0))
1532 (eq_attr "alternative" "2"))
1533 (const_string "imovx")
1534 ]
1535 (const_string "imov")))
1536 (set (attr "mode")
1537 (cond [(eq_attr "alternative" "3,4,5")
1538 (const_string "SI")
1539 (eq_attr "alternative" "6")
1540 (const_string "QI")
1541 (eq_attr "type" "imovx")
1542 (const_string "SI")
1543 (and (eq_attr "type" "imov")
1544 (and (eq_attr "alternative" "0,1,2")
1545 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1546 (const_int 0))))
1547 (const_string "SI")
1548 ;; Avoid partial register stalls when not using QImode arithmetic
1549 (and (eq_attr "type" "imov")
1550 (and (eq_attr "alternative" "0,1,2")
1551 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1552 (const_int 0))
1553 (eq (symbol_ref "TARGET_QIMODE_MATH")
1554 (const_int 0)))))
1555 (const_string "SI")
1556 ]
1557 (const_string "QI")))])
1558
1559 (define_expand "reload_outqi"
1560 [(parallel [(match_operand:QI 0 "" "=m")
1561 (match_operand:QI 1 "register_operand" "r")
1562 (match_operand:QI 2 "register_operand" "=&q")])]
1563 ""
1564 {
1565 rtx op0, op1, op2;
1566 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1567
1568 if (reg_overlap_mentioned_p (op2, op0))
1569 abort ();
1570 if (! q_regs_operand (op1, QImode))
1571 {
1572 emit_insn (gen_movqi (op2, op1));
1573 op1 = op2;
1574 }
1575 emit_insn (gen_movqi (op0, op1));
1576 DONE;
1577 })
1578
1579 (define_insn "*swapqi"
1580 [(set (match_operand:QI 0 "register_operand" "+r")
1581 (match_operand:QI 1 "register_operand" "+r"))
1582 (set (match_dup 1)
1583 (match_dup 0))]
1584 ""
1585 "xchg{b}\t%1, %0"
1586 [(set_attr "type" "imov")
1587 (set_attr "pent_pair" "np")
1588 (set_attr "mode" "QI")
1589 (set_attr "modrm" "0")
1590 (set_attr "ppro_uops" "few")])
1591
1592 (define_expand "movstrictqi"
1593 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1594 (match_operand:QI 1 "general_operand" ""))]
1595 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1596 {
1597 /* Don't generate memory->memory moves, go through a register. */
1598 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1599 operands[1] = force_reg (QImode, operands[1]);
1600 })
1601
1602 (define_insn "*movstrictqi_1"
1603 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1604 (match_operand:QI 1 "general_operand" "*qn,m"))]
1605 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1606 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1607 "mov{b}\t{%1, %0|%0, %1}"
1608 [(set_attr "type" "imov")
1609 (set_attr "mode" "QI")])
1610
1611 (define_insn "*movstrictqi_xor"
1612 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1613 (match_operand:QI 1 "const0_operand" "i"))
1614 (clobber (reg:CC 17))]
1615 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1616 "xor{b}\t{%0, %0|%0, %0}"
1617 [(set_attr "type" "alu1")
1618 (set_attr "mode" "QI")
1619 (set_attr "length_immediate" "0")])
1620
1621 (define_insn "*movsi_extv_1"
1622 [(set (match_operand:SI 0 "register_operand" "=R")
1623 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1624 (const_int 8)
1625 (const_int 8)))]
1626 ""
1627 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1628 [(set_attr "type" "imovx")
1629 (set_attr "mode" "SI")])
1630
1631 (define_insn "*movhi_extv_1"
1632 [(set (match_operand:HI 0 "register_operand" "=R")
1633 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1634 (const_int 8)
1635 (const_int 8)))]
1636 ""
1637 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1638 [(set_attr "type" "imovx")
1639 (set_attr "mode" "SI")])
1640
1641 (define_insn "*movqi_extv_1"
1642 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1643 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1644 (const_int 8)
1645 (const_int 8)))]
1646 "!TARGET_64BIT"
1647 {
1648 switch (get_attr_type (insn))
1649 {
1650 case TYPE_IMOVX:
1651 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1652 default:
1653 return "mov{b}\t{%h1, %0|%0, %h1}";
1654 }
1655 }
1656 [(set (attr "type")
1657 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1658 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1659 (ne (symbol_ref "TARGET_MOVX")
1660 (const_int 0))))
1661 (const_string "imovx")
1662 (const_string "imov")))
1663 (set (attr "mode")
1664 (if_then_else (eq_attr "type" "imovx")
1665 (const_string "SI")
1666 (const_string "QI")))])
1667
1668 (define_insn "*movqi_extv_1_rex64"
1669 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1670 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1671 (const_int 8)
1672 (const_int 8)))]
1673 "TARGET_64BIT"
1674 {
1675 switch (get_attr_type (insn))
1676 {
1677 case TYPE_IMOVX:
1678 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1679 default:
1680 return "mov{b}\t{%h1, %0|%0, %h1}";
1681 }
1682 }
1683 [(set (attr "type")
1684 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1685 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1686 (ne (symbol_ref "TARGET_MOVX")
1687 (const_int 0))))
1688 (const_string "imovx")
1689 (const_string "imov")))
1690 (set (attr "mode")
1691 (if_then_else (eq_attr "type" "imovx")
1692 (const_string "SI")
1693 (const_string "QI")))])
1694
1695 ;; Stores and loads of ax to arbitrary constant address.
1696 ;; We fake an second form of instruction to force reload to load address
1697 ;; into register when rax is not available
1698 (define_insn "*movabsqi_1_rex64"
1699 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1700 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1701 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1702 "@
1703 movabs{b}\t{%1, %P0|%P0, %1}
1704 mov{b}\t{%1, %a0|%a0, %1}"
1705 [(set_attr "type" "imov")
1706 (set_attr "modrm" "0,*")
1707 (set_attr "length_address" "8,0")
1708 (set_attr "length_immediate" "0,*")
1709 (set_attr "memory" "store")
1710 (set_attr "mode" "QI")])
1711
1712 (define_insn "*movabsqi_2_rex64"
1713 [(set (match_operand:QI 0 "register_operand" "=a,r")
1714 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1715 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1716 "@
1717 movabs{b}\t{%P1, %0|%0, %P1}
1718 mov{b}\t{%a1, %0|%0, %a1}"
1719 [(set_attr "type" "imov")
1720 (set_attr "modrm" "0,*")
1721 (set_attr "length_address" "8,0")
1722 (set_attr "length_immediate" "0")
1723 (set_attr "memory" "load")
1724 (set_attr "mode" "QI")])
1725
1726 (define_insn "*movsi_extzv_1"
1727 [(set (match_operand:SI 0 "register_operand" "=R")
1728 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1729 (const_int 8)
1730 (const_int 8)))]
1731 ""
1732 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1733 [(set_attr "type" "imovx")
1734 (set_attr "mode" "SI")])
1735
1736 (define_insn "*movqi_extzv_2"
1737 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1738 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1739 (const_int 8)
1740 (const_int 8)) 0))]
1741 "!TARGET_64BIT"
1742 {
1743 switch (get_attr_type (insn))
1744 {
1745 case TYPE_IMOVX:
1746 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1747 default:
1748 return "mov{b}\t{%h1, %0|%0, %h1}";
1749 }
1750 }
1751 [(set (attr "type")
1752 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1753 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1754 (ne (symbol_ref "TARGET_MOVX")
1755 (const_int 0))))
1756 (const_string "imovx")
1757 (const_string "imov")))
1758 (set (attr "mode")
1759 (if_then_else (eq_attr "type" "imovx")
1760 (const_string "SI")
1761 (const_string "QI")))])
1762
1763 (define_insn "*movqi_extzv_2_rex64"
1764 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1765 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1766 (const_int 8)
1767 (const_int 8)) 0))]
1768 "TARGET_64BIT"
1769 {
1770 switch (get_attr_type (insn))
1771 {
1772 case TYPE_IMOVX:
1773 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1774 default:
1775 return "mov{b}\t{%h1, %0|%0, %h1}";
1776 }
1777 }
1778 [(set (attr "type")
1779 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1780 (ne (symbol_ref "TARGET_MOVX")
1781 (const_int 0)))
1782 (const_string "imovx")
1783 (const_string "imov")))
1784 (set (attr "mode")
1785 (if_then_else (eq_attr "type" "imovx")
1786 (const_string "SI")
1787 (const_string "QI")))])
1788
1789 (define_insn "movsi_insv_1"
1790 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1791 (const_int 8)
1792 (const_int 8))
1793 (match_operand:SI 1 "general_operand" "Qmn"))]
1794 "!TARGET_64BIT"
1795 "mov{b}\t{%b1, %h0|%h0, %b1}"
1796 [(set_attr "type" "imov")
1797 (set_attr "mode" "QI")])
1798
1799 (define_insn "*movsi_insv_1_rex64"
1800 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1801 (const_int 8)
1802 (const_int 8))
1803 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1804 "TARGET_64BIT"
1805 "mov{b}\t{%b1, %h0|%h0, %b1}"
1806 [(set_attr "type" "imov")
1807 (set_attr "mode" "QI")])
1808
1809 (define_insn "*movqi_insv_2"
1810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1811 (const_int 8)
1812 (const_int 8))
1813 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1814 (const_int 8))
1815 (const_int 255)))]
1816 ""
1817 "mov{b}\t{%h1, %h0|%h0, %h1}"
1818 [(set_attr "type" "imov")
1819 (set_attr "mode" "QI")])
1820
1821 (define_expand "movdi"
1822 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1823 (match_operand:DI 1 "general_operand" ""))]
1824 ""
1825 "ix86_expand_move (DImode, operands); DONE;")
1826
1827 (define_insn "*pushdi"
1828 [(set (match_operand:DI 0 "push_operand" "=<")
1829 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1830 "!TARGET_64BIT"
1831 "#")
1832
1833 (define_insn "pushdi2_rex64"
1834 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1835 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1836 "TARGET_64BIT"
1837 "@
1838 push{q}\t%1
1839 #"
1840 [(set_attr "type" "push,multi")
1841 (set_attr "mode" "DI")])
1842
1843 ;; Convert impossible pushes of immediate to existing instructions.
1844 ;; First try to get scratch register and go through it. In case this
1845 ;; fails, push sign extended lower part first and then overwrite
1846 ;; upper part by 32bit move.
1847 (define_peephole2
1848 [(match_scratch:DI 2 "r")
1849 (set (match_operand:DI 0 "push_operand" "")
1850 (match_operand:DI 1 "immediate_operand" ""))]
1851 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1852 && !x86_64_immediate_operand (operands[1], DImode)"
1853 [(set (match_dup 2) (match_dup 1))
1854 (set (match_dup 0) (match_dup 2))]
1855 "")
1856
1857 ;; We need to define this as both peepholer and splitter for case
1858 ;; peephole2 pass is not run.
1859 (define_peephole2
1860 [(set (match_operand:DI 0 "push_operand" "")
1861 (match_operand:DI 1 "immediate_operand" ""))]
1862 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1863 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1864 [(set (match_dup 0) (match_dup 1))
1865 (set (match_dup 2) (match_dup 3))]
1866 "split_di (operands + 1, 1, operands + 2, operands + 3);
1867 operands[1] = gen_lowpart (DImode, operands[2]);
1868 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1869 GEN_INT (4)));
1870 ")
1871
1872 (define_split
1873 [(set (match_operand:DI 0 "push_operand" "")
1874 (match_operand:DI 1 "immediate_operand" ""))]
1875 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1876 && !symbolic_operand (operands[1], DImode)
1877 && !x86_64_immediate_operand (operands[1], DImode)"
1878 [(set (match_dup 0) (match_dup 1))
1879 (set (match_dup 2) (match_dup 3))]
1880 "split_di (operands + 1, 1, operands + 2, operands + 3);
1881 operands[1] = gen_lowpart (DImode, operands[2]);
1882 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1883 GEN_INT (4)));
1884 ")
1885
1886 (define_insn "*pushdi2_prologue_rex64"
1887 [(set (match_operand:DI 0 "push_operand" "=<")
1888 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1889 (clobber (mem:BLK (scratch)))]
1890 "TARGET_64BIT"
1891 "push{q}\t%1"
1892 [(set_attr "type" "push")
1893 (set_attr "mode" "DI")])
1894
1895 (define_insn "*popdi1_epilogue_rex64"
1896 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1897 (mem:DI (reg:DI 7)))
1898 (set (reg:DI 7)
1899 (plus:DI (reg:DI 7) (const_int 8)))
1900 (clobber (mem:BLK (scratch)))]
1901 "TARGET_64BIT"
1902 "pop{q}\t%0"
1903 [(set_attr "type" "pop")
1904 (set_attr "mode" "DI")])
1905
1906 (define_insn "popdi1"
1907 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1908 (mem:DI (reg:DI 7)))
1909 (set (reg:DI 7)
1910 (plus:DI (reg:DI 7) (const_int 8)))]
1911 "TARGET_64BIT"
1912 "pop{q}\t%0"
1913 [(set_attr "type" "pop")
1914 (set_attr "mode" "DI")])
1915
1916 (define_insn "*movdi_xor_rex64"
1917 [(set (match_operand:DI 0 "register_operand" "=r")
1918 (match_operand:DI 1 "const0_operand" "i"))
1919 (clobber (reg:CC 17))]
1920 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1921 && reload_completed"
1922 "xor{l}\t{%k0, %k0|%k0, %k0}"
1923 [(set_attr "type" "alu1")
1924 (set_attr "mode" "SI")
1925 (set_attr "length_immediate" "0")])
1926
1927 (define_insn "*movdi_or_rex64"
1928 [(set (match_operand:DI 0 "register_operand" "=r")
1929 (match_operand:DI 1 "const_int_operand" "i"))
1930 (clobber (reg:CC 17))]
1931 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1932 && reload_completed
1933 && operands[1] == constm1_rtx"
1934 {
1935 operands[1] = constm1_rtx;
1936 return "or{q}\t{%1, %0|%0, %1}";
1937 }
1938 [(set_attr "type" "alu1")
1939 (set_attr "mode" "DI")
1940 (set_attr "length_immediate" "1")])
1941
1942 (define_insn "*movdi_2"
1943 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1944 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1945 "!TARGET_64BIT
1946 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1947 "@
1948 #
1949 #
1950 movq\t{%1, %0|%0, %1}
1951 movq\t{%1, %0|%0, %1}
1952 movq\t{%1, %0|%0, %1}
1953 movdqa\t{%1, %0|%0, %1}
1954 movq\t{%1, %0|%0, %1}"
1955 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1956 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1957
1958 (define_split
1959 [(set (match_operand:DI 0 "push_operand" "")
1960 (match_operand:DI 1 "general_operand" ""))]
1961 "!TARGET_64BIT && reload_completed
1962 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1963 [(const_int 0)]
1964 "ix86_split_long_move (operands); DONE;")
1965
1966 ;; %%% This multiword shite has got to go.
1967 (define_split
1968 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1969 (match_operand:DI 1 "general_operand" ""))]
1970 "!TARGET_64BIT && reload_completed
1971 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1972 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1973 [(const_int 0)]
1974 "ix86_split_long_move (operands); DONE;")
1975
1976 (define_insn "*movdi_1_rex64"
1977 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1978 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1979 "TARGET_64BIT
1980 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1981 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1982 {
1983 switch (get_attr_type (insn))
1984 {
1985 case TYPE_SSEMOV:
1986 if (get_attr_mode (insn) == MODE_TI)
1987 return "movdqa\t{%1, %0|%0, %1}";
1988 /* FALLTHRU */
1989 case TYPE_MMXMOV:
1990 /* Moves from and into integer register is done using movd opcode with
1991 REX prefix. */
1992 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1993 return "movd\t{%1, %0|%0, %1}";
1994 return "movq\t{%1, %0|%0, %1}";
1995 case TYPE_MULTI:
1996 return "#";
1997 case TYPE_LEA:
1998 return "lea{q}\t{%a1, %0|%0, %a1}";
1999 default:
2000 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2001 abort ();
2002 if (get_attr_mode (insn) == MODE_SI)
2003 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2004 else if (which_alternative == 2)
2005 return "movabs{q}\t{%1, %0|%0, %1}";
2006 else
2007 return "mov{q}\t{%1, %0|%0, %1}";
2008 }
2009 }
2010 [(set (attr "type")
2011 (cond [(eq_attr "alternative" "5,6,7")
2012 (const_string "mmxmov")
2013 (eq_attr "alternative" "8,9,10")
2014 (const_string "ssemov")
2015 (eq_attr "alternative" "4")
2016 (const_string "multi")
2017 (and (ne (symbol_ref "flag_pic") (const_int 0))
2018 (match_operand:DI 1 "symbolic_operand" ""))
2019 (const_string "lea")
2020 ]
2021 (const_string "imov")))
2022 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2023 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2024 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2025
2026 (define_insn "*movdi_1_rex64_nointerunit"
2027 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2028 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2029 "TARGET_64BIT
2030 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2031 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2032 {
2033 switch (get_attr_type (insn))
2034 {
2035 case TYPE_SSEMOV:
2036 if (get_attr_mode (insn) == MODE_TI)
2037 return "movdqa\t{%1, %0|%0, %1}";
2038 /* FALLTHRU */
2039 case TYPE_MMXMOV:
2040 return "movq\t{%1, %0|%0, %1}";
2041 case TYPE_MULTI:
2042 return "#";
2043 case TYPE_LEA:
2044 return "lea{q}\t{%a1, %0|%0, %a1}";
2045 default:
2046 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2047 abort ();
2048 if (get_attr_mode (insn) == MODE_SI)
2049 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2050 else if (which_alternative == 2)
2051 return "movabs{q}\t{%1, %0|%0, %1}";
2052 else
2053 return "mov{q}\t{%1, %0|%0, %1}";
2054 }
2055 }
2056 [(set (attr "type")
2057 (cond [(eq_attr "alternative" "5,6,7")
2058 (const_string "mmxmov")
2059 (eq_attr "alternative" "8,9,10")
2060 (const_string "ssemov")
2061 (eq_attr "alternative" "4")
2062 (const_string "multi")
2063 (and (ne (symbol_ref "flag_pic") (const_int 0))
2064 (match_operand:DI 1 "symbolic_operand" ""))
2065 (const_string "lea")
2066 ]
2067 (const_string "imov")))
2068 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2069 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2070 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2071
2072 ;; Stores and loads of ax to arbitrary constant address.
2073 ;; We fake an second form of instruction to force reload to load address
2074 ;; into register when rax is not available
2075 (define_insn "*movabsdi_1_rex64"
2076 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2077 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2078 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2079 "@
2080 movabs{q}\t{%1, %P0|%P0, %1}
2081 mov{q}\t{%1, %a0|%a0, %1}"
2082 [(set_attr "type" "imov")
2083 (set_attr "modrm" "0,*")
2084 (set_attr "length_address" "8,0")
2085 (set_attr "length_immediate" "0,*")
2086 (set_attr "memory" "store")
2087 (set_attr "mode" "DI")])
2088
2089 (define_insn "*movabsdi_2_rex64"
2090 [(set (match_operand:DI 0 "register_operand" "=a,r")
2091 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2092 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2093 "@
2094 movabs{q}\t{%P1, %0|%0, %P1}
2095 mov{q}\t{%a1, %0|%0, %a1}"
2096 [(set_attr "type" "imov")
2097 (set_attr "modrm" "0,*")
2098 (set_attr "length_address" "8,0")
2099 (set_attr "length_immediate" "0")
2100 (set_attr "memory" "load")
2101 (set_attr "mode" "DI")])
2102
2103 ;; Convert impossible stores of immediate to existing instructions.
2104 ;; First try to get scratch register and go through it. In case this
2105 ;; fails, move by 32bit parts.
2106 (define_peephole2
2107 [(match_scratch:DI 2 "r")
2108 (set (match_operand:DI 0 "memory_operand" "")
2109 (match_operand:DI 1 "immediate_operand" ""))]
2110 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2111 && !x86_64_immediate_operand (operands[1], DImode)"
2112 [(set (match_dup 2) (match_dup 1))
2113 (set (match_dup 0) (match_dup 2))]
2114 "")
2115
2116 ;; We need to define this as both peepholer and splitter for case
2117 ;; peephole2 pass is not run.
2118 (define_peephole2
2119 [(set (match_operand:DI 0 "memory_operand" "")
2120 (match_operand:DI 1 "immediate_operand" ""))]
2121 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2122 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2123 [(set (match_dup 2) (match_dup 3))
2124 (set (match_dup 4) (match_dup 5))]
2125 "split_di (operands, 2, operands + 2, operands + 4);")
2126
2127 (define_split
2128 [(set (match_operand:DI 0 "memory_operand" "")
2129 (match_operand:DI 1 "immediate_operand" ""))]
2130 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2131 && !symbolic_operand (operands[1], DImode)
2132 && !x86_64_immediate_operand (operands[1], DImode)"
2133 [(set (match_dup 2) (match_dup 3))
2134 (set (match_dup 4) (match_dup 5))]
2135 "split_di (operands, 2, operands + 2, operands + 4);")
2136
2137 (define_insn "*swapdi_rex64"
2138 [(set (match_operand:DI 0 "register_operand" "+r")
2139 (match_operand:DI 1 "register_operand" "+r"))
2140 (set (match_dup 1)
2141 (match_dup 0))]
2142 "TARGET_64BIT"
2143 "xchg{q}\t%1, %0"
2144 [(set_attr "type" "imov")
2145 (set_attr "pent_pair" "np")
2146 (set_attr "athlon_decode" "vector")
2147 (set_attr "mode" "DI")
2148 (set_attr "modrm" "0")
2149 (set_attr "ppro_uops" "few")])
2150
2151
2152 (define_expand "movsf"
2153 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2154 (match_operand:SF 1 "general_operand" ""))]
2155 ""
2156 "ix86_expand_move (SFmode, operands); DONE;")
2157
2158 (define_insn "*pushsf"
2159 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2160 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2161 "!TARGET_64BIT"
2162 {
2163 switch (which_alternative)
2164 {
2165 case 1:
2166 return "push{l}\t%1";
2167
2168 default:
2169 /* This insn should be already splitted before reg-stack. */
2170 abort ();
2171 }
2172 }
2173 [(set_attr "type" "multi,push,multi")
2174 (set_attr "mode" "SF,SI,SF")])
2175
2176 (define_insn "*pushsf_rex64"
2177 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2178 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2179 "TARGET_64BIT"
2180 {
2181 switch (which_alternative)
2182 {
2183 case 1:
2184 return "push{q}\t%q1";
2185
2186 default:
2187 /* This insn should be already splitted before reg-stack. */
2188 abort ();
2189 }
2190 }
2191 [(set_attr "type" "multi,push,multi")
2192 (set_attr "mode" "SF,DI,SF")])
2193
2194 (define_split
2195 [(set (match_operand:SF 0 "push_operand" "")
2196 (match_operand:SF 1 "memory_operand" ""))]
2197 "reload_completed
2198 && GET_CODE (operands[1]) == MEM
2199 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2200 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2201 [(set (match_dup 0)
2202 (match_dup 1))]
2203 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2204
2205
2206 ;; %%% Kill this when call knows how to work this out.
2207 (define_split
2208 [(set (match_operand:SF 0 "push_operand" "")
2209 (match_operand:SF 1 "any_fp_register_operand" ""))]
2210 "!TARGET_64BIT"
2211 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2212 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2213
2214 (define_split
2215 [(set (match_operand:SF 0 "push_operand" "")
2216 (match_operand:SF 1 "any_fp_register_operand" ""))]
2217 "TARGET_64BIT"
2218 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2219 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2220
2221 (define_insn "*movsf_1"
2222 [(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")
2223 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2224 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2225 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2226 && (reload_in_progress || reload_completed
2227 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2228 || GET_CODE (operands[1]) != CONST_DOUBLE
2229 || memory_operand (operands[0], SFmode))"
2230 {
2231 switch (which_alternative)
2232 {
2233 case 0:
2234 if (REG_P (operands[1])
2235 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2236 return "fstp\t%y0";
2237 else if (STACK_TOP_P (operands[0]))
2238 return "fld%z1\t%y1";
2239 else
2240 return "fst\t%y0";
2241
2242 case 1:
2243 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2244 return "fstp%z0\t%y0";
2245 else
2246 return "fst%z0\t%y0";
2247
2248 case 2:
2249 return standard_80387_constant_opcode (operands[1]);
2250
2251 case 3:
2252 case 4:
2253 return "mov{l}\t{%1, %0|%0, %1}";
2254 case 5:
2255 if (get_attr_mode (insn) == MODE_TI)
2256 return "pxor\t%0, %0";
2257 else
2258 return "xorps\t%0, %0";
2259 case 6:
2260 if (get_attr_mode (insn) == MODE_V4SF)
2261 return "movaps\t{%1, %0|%0, %1}";
2262 else
2263 return "movss\t{%1, %0|%0, %1}";
2264 case 7:
2265 case 8:
2266 return "movss\t{%1, %0|%0, %1}";
2267
2268 case 9:
2269 case 10:
2270 return "movd\t{%1, %0|%0, %1}";
2271
2272 case 11:
2273 return "movq\t{%1, %0|%0, %1}";
2274
2275 default:
2276 abort();
2277 }
2278 }
2279 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2280 (set (attr "mode")
2281 (cond [(eq_attr "alternative" "3,4,9,10")
2282 (const_string "SI")
2283 (eq_attr "alternative" "5")
2284 (if_then_else
2285 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2286 (const_int 0))
2287 (ne (symbol_ref "TARGET_SSE2")
2288 (const_int 0)))
2289 (eq (symbol_ref "optimize_size")
2290 (const_int 0)))
2291 (const_string "TI")
2292 (const_string "V4SF"))
2293 /* For architectures resolving dependencies on
2294 whole SSE registers use APS move to break dependency
2295 chains, otherwise use short move to avoid extra work.
2296
2297 Do the same for architectures resolving dependencies on
2298 the parts. While in DF mode it is better to always handle
2299 just register parts, the SF mode is different due to lack
2300 of instructions to load just part of the register. It is
2301 better to maintain the whole registers in single format
2302 to avoid problems on using packed logical operations. */
2303 (eq_attr "alternative" "6")
2304 (if_then_else
2305 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2306 (const_int 0))
2307 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2308 (const_int 0)))
2309 (const_string "V4SF")
2310 (const_string "SF"))
2311 (eq_attr "alternative" "11")
2312 (const_string "DI")]
2313 (const_string "SF")))])
2314
2315 (define_insn "*movsf_1_nointerunit"
2316 [(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")
2317 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2318 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2319 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2320 && (reload_in_progress || reload_completed
2321 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2322 || GET_CODE (operands[1]) != CONST_DOUBLE
2323 || memory_operand (operands[0], SFmode))"
2324 {
2325 switch (which_alternative)
2326 {
2327 case 0:
2328 if (REG_P (operands[1])
2329 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2330 {
2331 if (REGNO (operands[0]) == FIRST_STACK_REG
2332 && TARGET_USE_FFREEP)
2333 return "ffreep\t%y0";
2334 return "fstp\t%y0";
2335 }
2336 else if (STACK_TOP_P (operands[0]))
2337 return "fld%z1\t%y1";
2338 else
2339 return "fst\t%y0";
2340
2341 case 1:
2342 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2343 return "fstp%z0\t%y0";
2344 else
2345 return "fst%z0\t%y0";
2346
2347 case 2:
2348 return standard_80387_constant_opcode (operands[1]);
2349
2350 case 3:
2351 case 4:
2352 return "mov{l}\t{%1, %0|%0, %1}";
2353 case 5:
2354 if (get_attr_mode (insn) == MODE_TI)
2355 return "pxor\t%0, %0";
2356 else
2357 return "xorps\t%0, %0";
2358 case 6:
2359 if (get_attr_mode (insn) == MODE_V4SF)
2360 return "movaps\t{%1, %0|%0, %1}";
2361 else
2362 return "movss\t{%1, %0|%0, %1}";
2363 case 7:
2364 case 8:
2365 return "movss\t{%1, %0|%0, %1}";
2366
2367 case 9:
2368 case 10:
2369 return "movd\t{%1, %0|%0, %1}";
2370
2371 case 11:
2372 return "movq\t{%1, %0|%0, %1}";
2373
2374 default:
2375 abort();
2376 }
2377 }
2378 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2379 (set (attr "mode")
2380 (cond [(eq_attr "alternative" "3,4,9,10")
2381 (const_string "SI")
2382 (eq_attr "alternative" "5")
2383 (if_then_else
2384 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2385 (const_int 0))
2386 (ne (symbol_ref "TARGET_SSE2")
2387 (const_int 0)))
2388 (eq (symbol_ref "optimize_size")
2389 (const_int 0)))
2390 (const_string "TI")
2391 (const_string "V4SF"))
2392 /* For architectures resolving dependencies on
2393 whole SSE registers use APS move to break dependency
2394 chains, otherwise use short move to avoid extra work.
2395
2396 Do the same for architectures resolving dependencies on
2397 the parts. While in DF mode it is better to always handle
2398 just register parts, the SF mode is different due to lack
2399 of instructions to load just part of the register. It is
2400 better to maintain the whole registers in single format
2401 to avoid problems on using packed logical operations. */
2402 (eq_attr "alternative" "6")
2403 (if_then_else
2404 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2405 (const_int 0))
2406 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2407 (const_int 0)))
2408 (const_string "V4SF")
2409 (const_string "SF"))
2410 (eq_attr "alternative" "11")
2411 (const_string "DI")]
2412 (const_string "SF")))])
2413
2414 (define_insn "*swapsf"
2415 [(set (match_operand:SF 0 "register_operand" "+f")
2416 (match_operand:SF 1 "register_operand" "+f"))
2417 (set (match_dup 1)
2418 (match_dup 0))]
2419 "reload_completed || !TARGET_SSE"
2420 {
2421 if (STACK_TOP_P (operands[0]))
2422 return "fxch\t%1";
2423 else
2424 return "fxch\t%0";
2425 }
2426 [(set_attr "type" "fxch")
2427 (set_attr "mode" "SF")])
2428
2429 (define_expand "movdf"
2430 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2431 (match_operand:DF 1 "general_operand" ""))]
2432 ""
2433 "ix86_expand_move (DFmode, operands); DONE;")
2434
2435 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2436 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2437 ;; On the average, pushdf using integers can be still shorter. Allow this
2438 ;; pattern for optimize_size too.
2439
2440 (define_insn "*pushdf_nointeger"
2441 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2442 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2443 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2444 {
2445 /* This insn should be already splitted before reg-stack. */
2446 abort ();
2447 }
2448 [(set_attr "type" "multi")
2449 (set_attr "mode" "DF,SI,SI,DF")])
2450
2451 (define_insn "*pushdf_integer"
2452 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2453 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2454 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2455 {
2456 /* This insn should be already splitted before reg-stack. */
2457 abort ();
2458 }
2459 [(set_attr "type" "multi")
2460 (set_attr "mode" "DF,SI,DF")])
2461
2462 ;; %%% Kill this when call knows how to work this out.
2463 (define_split
2464 [(set (match_operand:DF 0 "push_operand" "")
2465 (match_operand:DF 1 "any_fp_register_operand" ""))]
2466 "!TARGET_64BIT && reload_completed"
2467 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2468 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2469 "")
2470
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:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2476 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2477 "")
2478
2479 (define_split
2480 [(set (match_operand:DF 0 "push_operand" "")
2481 (match_operand:DF 1 "general_operand" ""))]
2482 "reload_completed"
2483 [(const_int 0)]
2484 "ix86_split_long_move (operands); DONE;")
2485
2486 ;; Moving is usually shorter when only FP registers are used. This separate
2487 ;; movdf pattern avoids the use of integer registers for FP operations
2488 ;; when optimizing for size.
2489
2490 (define_insn "*movdf_nointeger"
2491 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2492 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2493 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2494 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2495 && (reload_in_progress || reload_completed
2496 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2497 || GET_CODE (operands[1]) != CONST_DOUBLE
2498 || memory_operand (operands[0], DFmode))"
2499 {
2500 switch (which_alternative)
2501 {
2502 case 0:
2503 if (REG_P (operands[1])
2504 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2505 {
2506 if (REGNO (operands[0]) == FIRST_STACK_REG
2507 && TARGET_USE_FFREEP)
2508 return "ffreep\t%y0";
2509 return "fstp\t%y0";
2510 }
2511 else if (STACK_TOP_P (operands[0]))
2512 return "fld%z1\t%y1";
2513 else
2514 return "fst\t%y0";
2515
2516 case 1:
2517 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2518 return "fstp%z0\t%y0";
2519 else
2520 return "fst%z0\t%y0";
2521
2522 case 2:
2523 return standard_80387_constant_opcode (operands[1]);
2524
2525 case 3:
2526 case 4:
2527 return "#";
2528 case 5:
2529 switch (get_attr_mode (insn))
2530 {
2531 case MODE_V4SF:
2532 return "xorps\t%0, %0";
2533 case MODE_V2DF:
2534 return "xorpd\t%0, %0";
2535 case MODE_TI:
2536 return "pxor\t%0, %0";
2537 default:
2538 abort ();
2539 }
2540 case 6:
2541 switch (get_attr_mode (insn))
2542 {
2543 case MODE_V4SF:
2544 return "movaps\t{%1, %0|%0, %1}";
2545 case MODE_V2DF:
2546 return "movapd\t{%1, %0|%0, %1}";
2547 case MODE_DF:
2548 return "movsd\t{%1, %0|%0, %1}";
2549 default:
2550 abort ();
2551 }
2552 case 7:
2553 if (get_attr_mode (insn) == MODE_V2DF)
2554 return "movlpd\t{%1, %0|%0, %1}";
2555 else
2556 return "movsd\t{%1, %0|%0, %1}";
2557 case 8:
2558 return "movsd\t{%1, %0|%0, %1}";
2559
2560 default:
2561 abort();
2562 }
2563 }
2564 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2565 (set (attr "mode")
2566 (cond [(eq_attr "alternative" "3,4")
2567 (const_string "SI")
2568 /* xorps is one byte shorter. */
2569 (eq_attr "alternative" "5")
2570 (cond [(ne (symbol_ref "optimize_size")
2571 (const_int 0))
2572 (const_string "V4SF")
2573 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2574 (const_int 0))
2575 (const_string "TI")]
2576 (const_string "V2DF"))
2577 /* For architectures resolving dependencies on
2578 whole SSE registers use APD move to break dependency
2579 chains, otherwise use short move to avoid extra work.
2580
2581 movaps encodes one byte shorter. */
2582 (eq_attr "alternative" "6")
2583 (cond
2584 [(ne (symbol_ref "optimize_size")
2585 (const_int 0))
2586 (const_string "V4SF")
2587 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2588 (const_int 0))
2589 (const_string "V2DF")]
2590 (const_string "DF"))
2591 /* For architectures resolving dependencies on register
2592 parts we may avoid extra work to zero out upper part
2593 of register. */
2594 (eq_attr "alternative" "7")
2595 (if_then_else
2596 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2597 (const_int 0))
2598 (const_string "V2DF")
2599 (const_string "DF"))]
2600 (const_string "DF")))])
2601
2602 (define_insn "*movdf_integer"
2603 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2604 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2605 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2606 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2607 && (reload_in_progress || reload_completed
2608 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2609 || GET_CODE (operands[1]) != CONST_DOUBLE
2610 || memory_operand (operands[0], DFmode))"
2611 {
2612 switch (which_alternative)
2613 {
2614 case 0:
2615 if (REG_P (operands[1])
2616 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2617 {
2618 if (REGNO (operands[0]) == FIRST_STACK_REG
2619 && TARGET_USE_FFREEP)
2620 return "ffreep\t%y0";
2621 return "fstp\t%y0";
2622 }
2623 else if (STACK_TOP_P (operands[0]))
2624 return "fld%z1\t%y1";
2625 else
2626 return "fst\t%y0";
2627
2628 case 1:
2629 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2630 return "fstp%z0\t%y0";
2631 else
2632 return "fst%z0\t%y0";
2633
2634 case 2:
2635 return standard_80387_constant_opcode (operands[1]);
2636
2637 case 3:
2638 case 4:
2639 return "#";
2640
2641 case 5:
2642 switch (get_attr_mode (insn))
2643 {
2644 case MODE_V4SF:
2645 return "xorps\t%0, %0";
2646 case MODE_V2DF:
2647 return "xorpd\t%0, %0";
2648 case MODE_TI:
2649 return "pxor\t%0, %0";
2650 default:
2651 abort ();
2652 }
2653 case 6:
2654 switch (get_attr_mode (insn))
2655 {
2656 case MODE_V4SF:
2657 return "movaps\t{%1, %0|%0, %1}";
2658 case MODE_V2DF:
2659 return "movapd\t{%1, %0|%0, %1}";
2660 case MODE_DF:
2661 return "movsd\t{%1, %0|%0, %1}";
2662 default:
2663 abort ();
2664 }
2665 case 7:
2666 if (get_attr_mode (insn) == MODE_V2DF)
2667 return "movlpd\t{%1, %0|%0, %1}";
2668 else
2669 return "movsd\t{%1, %0|%0, %1}";
2670 case 8:
2671 return "movsd\t{%1, %0|%0, %1}";
2672
2673 default:
2674 abort();
2675 }
2676 }
2677 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2678 (set (attr "mode")
2679 (cond [(eq_attr "alternative" "3,4")
2680 (const_string "SI")
2681 /* xorps is one byte shorter. */
2682 (eq_attr "alternative" "5")
2683 (cond [(ne (symbol_ref "optimize_size")
2684 (const_int 0))
2685 (const_string "V4SF")
2686 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2687 (const_int 0))
2688 (const_string "TI")]
2689 (const_string "V2DF"))
2690 /* For architectures resolving dependencies on
2691 whole SSE registers use APD move to break dependency
2692 chains, otherwise use short move to avoid extra work.
2693
2694 movaps encodes one byte shorter. */
2695 (eq_attr "alternative" "6")
2696 (cond
2697 [(ne (symbol_ref "optimize_size")
2698 (const_int 0))
2699 (const_string "V4SF")
2700 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2701 (const_int 0))
2702 (const_string "V2DF")]
2703 (const_string "DF"))
2704 /* For architectures resolving dependencies on register
2705 parts we may avoid extra work to zero out upper part
2706 of register. */
2707 (eq_attr "alternative" "7")
2708 (if_then_else
2709 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2710 (const_int 0))
2711 (const_string "V2DF")
2712 (const_string "DF"))]
2713 (const_string "DF")))])
2714
2715 (define_split
2716 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2717 (match_operand:DF 1 "general_operand" ""))]
2718 "reload_completed
2719 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2720 && ! (ANY_FP_REG_P (operands[0]) ||
2721 (GET_CODE (operands[0]) == SUBREG
2722 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2723 && ! (ANY_FP_REG_P (operands[1]) ||
2724 (GET_CODE (operands[1]) == SUBREG
2725 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2726 [(const_int 0)]
2727 "ix86_split_long_move (operands); DONE;")
2728
2729 (define_insn "*swapdf"
2730 [(set (match_operand:DF 0 "register_operand" "+f")
2731 (match_operand:DF 1 "register_operand" "+f"))
2732 (set (match_dup 1)
2733 (match_dup 0))]
2734 "reload_completed || !TARGET_SSE2"
2735 {
2736 if (STACK_TOP_P (operands[0]))
2737 return "fxch\t%1";
2738 else
2739 return "fxch\t%0";
2740 }
2741 [(set_attr "type" "fxch")
2742 (set_attr "mode" "DF")])
2743
2744 (define_expand "movxf"
2745 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2746 (match_operand:XF 1 "general_operand" ""))]
2747 "!TARGET_128BIT_LONG_DOUBLE"
2748 "ix86_expand_move (XFmode, operands); DONE;")
2749
2750 (define_expand "movtf"
2751 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2752 (match_operand:TF 1 "general_operand" ""))]
2753 ""
2754 "ix86_expand_move (TFmode, operands); DONE;")
2755
2756 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2757 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2758 ;; Pushing using integer instructions is longer except for constants
2759 ;; and direct memory references.
2760 ;; (assuming that any given constant is pushed only once, but this ought to be
2761 ;; handled elsewhere).
2762
2763 (define_insn "*pushxf_nointeger"
2764 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2765 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2766 "!TARGET_128BIT_LONG_DOUBLE && optimize_size"
2767 {
2768 /* This insn should be already splitted before reg-stack. */
2769 abort ();
2770 }
2771 [(set_attr "type" "multi")
2772 (set_attr "mode" "XF,SI,SI")])
2773
2774 (define_insn "*pushtf_nointeger"
2775 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2776 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2777 "optimize_size"
2778 {
2779 /* This insn should be already splitted before reg-stack. */
2780 abort ();
2781 }
2782 [(set_attr "type" "multi")
2783 (set_attr "mode" "XF,SI,SI")])
2784
2785 (define_insn "*pushxf_integer"
2786 [(set (match_operand:XF 0 "push_operand" "=<,<")
2787 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2788 "!TARGET_128BIT_LONG_DOUBLE && !optimize_size"
2789 {
2790 /* This insn should be already splitted before reg-stack. */
2791 abort ();
2792 }
2793 [(set_attr "type" "multi")
2794 (set_attr "mode" "XF,SI")])
2795
2796 (define_insn "*pushtf_integer"
2797 [(set (match_operand:TF 0 "push_operand" "=<,<")
2798 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2799 "!optimize_size"
2800 {
2801 /* This insn should be already splitted before reg-stack. */
2802 abort ();
2803 }
2804 [(set_attr "type" "multi")
2805 (set_attr "mode" "XF,SI")])
2806
2807 (define_split
2808 [(set (match_operand 0 "push_operand" "")
2809 (match_operand 1 "general_operand" ""))]
2810 "reload_completed
2811 && (GET_MODE (operands[0]) == XFmode
2812 || GET_MODE (operands[0]) == TFmode
2813 || GET_MODE (operands[0]) == DFmode)
2814 && !ANY_FP_REG_P (operands[1])"
2815 [(const_int 0)]
2816 "ix86_split_long_move (operands); DONE;")
2817
2818 (define_split
2819 [(set (match_operand:XF 0 "push_operand" "")
2820 (match_operand:XF 1 "any_fp_register_operand" ""))]
2821 "!TARGET_128BIT_LONG_DOUBLE"
2822 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2823 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2824
2825 (define_split
2826 [(set (match_operand:TF 0 "push_operand" "")
2827 (match_operand:TF 1 "any_fp_register_operand" ""))]
2828 "!TARGET_64BIT"
2829 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2830 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2831
2832 (define_split
2833 [(set (match_operand:TF 0 "push_operand" "")
2834 (match_operand:TF 1 "any_fp_register_operand" ""))]
2835 "TARGET_64BIT"
2836 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2837 (set (mem:TF (reg:DI 7)) (match_dup 1))])
2838
2839 ;; Do not use integer registers when optimizing for size
2840 (define_insn "*movxf_nointeger"
2841 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2842 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2843 "!TARGET_128BIT_LONG_DOUBLE
2844 && optimize_size
2845 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2846 && (reload_in_progress || reload_completed
2847 || GET_CODE (operands[1]) != CONST_DOUBLE
2848 || memory_operand (operands[0], XFmode))"
2849 {
2850 switch (which_alternative)
2851 {
2852 case 0:
2853 if (REG_P (operands[1])
2854 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2855 {
2856 if (REGNO (operands[0]) == FIRST_STACK_REG
2857 && TARGET_USE_FFREEP)
2858 return "ffreep\t%y0";
2859 return "fstp\t%y0";
2860 }
2861 else if (STACK_TOP_P (operands[0]))
2862 return "fld%z1\t%y1";
2863 else
2864 return "fst\t%y0";
2865
2866 case 1:
2867 /* There is no non-popping store to memory for XFmode. So if
2868 we need one, follow the store with a load. */
2869 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2870 return "fstp%z0\t%y0\;fld%z0\t%y0";
2871 else
2872 return "fstp%z0\t%y0";
2873
2874 case 2:
2875 return standard_80387_constant_opcode (operands[1]);
2876
2877 case 3: case 4:
2878 return "#";
2879 }
2880 abort();
2881 }
2882 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2883 (set_attr "mode" "XF,XF,XF,SI,SI")])
2884
2885 (define_insn "*movtf_nointeger"
2886 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2887 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2888 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2889 && optimize_size
2890 && (reload_in_progress || reload_completed
2891 || GET_CODE (operands[1]) != CONST_DOUBLE
2892 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2893 || memory_operand (operands[0], TFmode))"
2894 {
2895 switch (which_alternative)
2896 {
2897 case 0:
2898 if (REG_P (operands[1])
2899 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2900 {
2901 if (REGNO (operands[0]) == FIRST_STACK_REG
2902 && TARGET_USE_FFREEP)
2903 return "ffreep\t%y0";
2904 return "fstp\t%y0";
2905 }
2906 else if (STACK_TOP_P (operands[0]))
2907 return "fld%z1\t%y1";
2908 else
2909 return "fst\t%y0";
2910
2911 case 1:
2912 /* There is no non-popping store to memory for XFmode. So if
2913 we need one, follow the store with a load. */
2914 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2915 return "fstp%z0\t%y0\;fld%z0\t%y0";
2916 else
2917 return "fstp%z0\t%y0";
2918
2919 case 2:
2920 return standard_80387_constant_opcode (operands[1]);
2921
2922 case 3: case 4:
2923 return "#";
2924 }
2925 abort();
2926 }
2927 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2928 (set_attr "mode" "XF,XF,XF,SI,SI")])
2929
2930 (define_insn "*movxf_integer"
2931 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2932 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2933 "!TARGET_128BIT_LONG_DOUBLE
2934 && !optimize_size
2935 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2936 && (reload_in_progress || reload_completed
2937 || GET_CODE (operands[1]) != CONST_DOUBLE
2938 || memory_operand (operands[0], XFmode))"
2939 {
2940 switch (which_alternative)
2941 {
2942 case 0:
2943 if (REG_P (operands[1])
2944 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2945 {
2946 if (REGNO (operands[0]) == FIRST_STACK_REG
2947 && TARGET_USE_FFREEP)
2948 return "ffreep\t%y0";
2949 return "fstp\t%y0";
2950 }
2951 else if (STACK_TOP_P (operands[0]))
2952 return "fld%z1\t%y1";
2953 else
2954 return "fst\t%y0";
2955
2956 case 1:
2957 /* There is no non-popping store to memory for XFmode. So if
2958 we need one, follow the store with a load. */
2959 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2960 return "fstp%z0\t%y0\;fld%z0\t%y0";
2961 else
2962 return "fstp%z0\t%y0";
2963
2964 case 2:
2965 return standard_80387_constant_opcode (operands[1]);
2966
2967 case 3: case 4:
2968 return "#";
2969 }
2970 abort();
2971 }
2972 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2973 (set_attr "mode" "XF,XF,XF,SI,SI")])
2974
2975 (define_insn "*movtf_integer"
2976 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2977 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2978 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2979 && !optimize_size
2980 && (reload_in_progress || reload_completed
2981 || GET_CODE (operands[1]) != CONST_DOUBLE
2982 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2983 || memory_operand (operands[0], TFmode))"
2984 {
2985 switch (which_alternative)
2986 {
2987 case 0:
2988 if (REG_P (operands[1])
2989 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2990 {
2991 if (REGNO (operands[0]) == FIRST_STACK_REG
2992 && TARGET_USE_FFREEP)
2993 return "ffreep\t%y0";
2994 return "fstp\t%y0";
2995 }
2996 else if (STACK_TOP_P (operands[0]))
2997 return "fld%z1\t%y1";
2998 else
2999 return "fst\t%y0";
3000
3001 case 1:
3002 /* There is no non-popping store to memory for XFmode. So if
3003 we need one, follow the store with a load. */
3004 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3005 return "fstp%z0\t%y0\;fld%z0\t%y0";
3006 else
3007 return "fstp%z0\t%y0";
3008
3009 case 2:
3010 return standard_80387_constant_opcode (operands[1]);
3011
3012 case 3: case 4:
3013 return "#";
3014 }
3015 abort();
3016 }
3017 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3018 (set_attr "mode" "XF,XF,XF,SI,SI")])
3019
3020 (define_split
3021 [(set (match_operand 0 "nonimmediate_operand" "")
3022 (match_operand 1 "general_operand" ""))]
3023 "reload_completed
3024 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3025 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3026 && ! (ANY_FP_REG_P (operands[0]) ||
3027 (GET_CODE (operands[0]) == SUBREG
3028 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3029 && ! (ANY_FP_REG_P (operands[1]) ||
3030 (GET_CODE (operands[1]) == SUBREG
3031 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3032 [(const_int 0)]
3033 "ix86_split_long_move (operands); DONE;")
3034
3035 (define_split
3036 [(set (match_operand 0 "register_operand" "")
3037 (match_operand 1 "memory_operand" ""))]
3038 "reload_completed
3039 && GET_CODE (operands[1]) == MEM
3040 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3041 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3042 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3043 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3044 && (!(SSE_REG_P (operands[0]) ||
3045 (GET_CODE (operands[0]) == SUBREG
3046 && SSE_REG_P (SUBREG_REG (operands[0]))))
3047 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3048 && (!(FP_REG_P (operands[0]) ||
3049 (GET_CODE (operands[0]) == SUBREG
3050 && FP_REG_P (SUBREG_REG (operands[0]))))
3051 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3052 [(set (match_dup 0)
3053 (match_dup 1))]
3054 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3055
3056 (define_insn "swapxf"
3057 [(set (match_operand:XF 0 "register_operand" "+f")
3058 (match_operand:XF 1 "register_operand" "+f"))
3059 (set (match_dup 1)
3060 (match_dup 0))]
3061 ""
3062 {
3063 if (STACK_TOP_P (operands[0]))
3064 return "fxch\t%1";
3065 else
3066 return "fxch\t%0";
3067 }
3068 [(set_attr "type" "fxch")
3069 (set_attr "mode" "XF")])
3070
3071 (define_insn "swaptf"
3072 [(set (match_operand:TF 0 "register_operand" "+f")
3073 (match_operand:TF 1 "register_operand" "+f"))
3074 (set (match_dup 1)
3075 (match_dup 0))]
3076 ""
3077 {
3078 if (STACK_TOP_P (operands[0]))
3079 return "fxch\t%1";
3080 else
3081 return "fxch\t%0";
3082 }
3083 [(set_attr "type" "fxch")
3084 (set_attr "mode" "XF")])
3085 \f
3086 ;; Zero extension instructions
3087
3088 (define_expand "zero_extendhisi2"
3089 [(set (match_operand:SI 0 "register_operand" "")
3090 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3091 ""
3092 {
3093 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3094 {
3095 operands[1] = force_reg (HImode, operands[1]);
3096 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3097 DONE;
3098 }
3099 })
3100
3101 (define_insn "zero_extendhisi2_and"
3102 [(set (match_operand:SI 0 "register_operand" "=r")
3103 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3104 (clobber (reg:CC 17))]
3105 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3106 "#"
3107 [(set_attr "type" "alu1")
3108 (set_attr "mode" "SI")])
3109
3110 (define_split
3111 [(set (match_operand:SI 0 "register_operand" "")
3112 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3113 (clobber (reg:CC 17))]
3114 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3115 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3116 (clobber (reg:CC 17))])]
3117 "")
3118
3119 (define_insn "*zero_extendhisi2_movzwl"
3120 [(set (match_operand:SI 0 "register_operand" "=r")
3121 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3122 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3123 "movz{wl|x}\t{%1, %0|%0, %1}"
3124 [(set_attr "type" "imovx")
3125 (set_attr "mode" "SI")])
3126
3127 (define_expand "zero_extendqihi2"
3128 [(parallel
3129 [(set (match_operand:HI 0 "register_operand" "")
3130 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3131 (clobber (reg:CC 17))])]
3132 ""
3133 "")
3134
3135 (define_insn "*zero_extendqihi2_and"
3136 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3137 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3138 (clobber (reg:CC 17))]
3139 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3140 "#"
3141 [(set_attr "type" "alu1")
3142 (set_attr "mode" "HI")])
3143
3144 (define_insn "*zero_extendqihi2_movzbw_and"
3145 [(set (match_operand:HI 0 "register_operand" "=r,r")
3146 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3147 (clobber (reg:CC 17))]
3148 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3149 "#"
3150 [(set_attr "type" "imovx,alu1")
3151 (set_attr "mode" "HI")])
3152
3153 (define_insn "*zero_extendqihi2_movzbw"
3154 [(set (match_operand:HI 0 "register_operand" "=r")
3155 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3156 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3157 "movz{bw|x}\t{%1, %0|%0, %1}"
3158 [(set_attr "type" "imovx")
3159 (set_attr "mode" "HI")])
3160
3161 ;; For the movzbw case strip only the clobber
3162 (define_split
3163 [(set (match_operand:HI 0 "register_operand" "")
3164 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3165 (clobber (reg:CC 17))]
3166 "reload_completed
3167 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3168 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3169 [(set (match_operand:HI 0 "register_operand" "")
3170 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3171
3172 ;; When source and destination does not overlap, clear destination
3173 ;; first and then do the movb
3174 (define_split
3175 [(set (match_operand:HI 0 "register_operand" "")
3176 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3177 (clobber (reg:CC 17))]
3178 "reload_completed
3179 && ANY_QI_REG_P (operands[0])
3180 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3181 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3182 [(set (match_dup 0) (const_int 0))
3183 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3184 "operands[2] = gen_lowpart (QImode, operands[0]);")
3185
3186 ;; Rest is handled by single and.
3187 (define_split
3188 [(set (match_operand:HI 0 "register_operand" "")
3189 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3190 (clobber (reg:CC 17))]
3191 "reload_completed
3192 && true_regnum (operands[0]) == true_regnum (operands[1])"
3193 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3194 (clobber (reg:CC 17))])]
3195 "")
3196
3197 (define_expand "zero_extendqisi2"
3198 [(parallel
3199 [(set (match_operand:SI 0 "register_operand" "")
3200 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3201 (clobber (reg:CC 17))])]
3202 ""
3203 "")
3204
3205 (define_insn "*zero_extendqisi2_and"
3206 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3207 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3208 (clobber (reg:CC 17))]
3209 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3210 "#"
3211 [(set_attr "type" "alu1")
3212 (set_attr "mode" "SI")])
3213
3214 (define_insn "*zero_extendqisi2_movzbw_and"
3215 [(set (match_operand:SI 0 "register_operand" "=r,r")
3216 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3217 (clobber (reg:CC 17))]
3218 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3219 "#"
3220 [(set_attr "type" "imovx,alu1")
3221 (set_attr "mode" "SI")])
3222
3223 (define_insn "*zero_extendqisi2_movzbw"
3224 [(set (match_operand:SI 0 "register_operand" "=r")
3225 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3226 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3227 "movz{bl|x}\t{%1, %0|%0, %1}"
3228 [(set_attr "type" "imovx")
3229 (set_attr "mode" "SI")])
3230
3231 ;; For the movzbl case strip only the clobber
3232 (define_split
3233 [(set (match_operand:SI 0 "register_operand" "")
3234 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3235 (clobber (reg:CC 17))]
3236 "reload_completed
3237 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3238 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3239 [(set (match_dup 0)
3240 (zero_extend:SI (match_dup 1)))])
3241
3242 ;; When source and destination does not overlap, clear destination
3243 ;; first and then do the movb
3244 (define_split
3245 [(set (match_operand:SI 0 "register_operand" "")
3246 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3247 (clobber (reg:CC 17))]
3248 "reload_completed
3249 && ANY_QI_REG_P (operands[0])
3250 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3251 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3252 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3253 [(set (match_dup 0) (const_int 0))
3254 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3255 "operands[2] = gen_lowpart (QImode, operands[0]);")
3256
3257 ;; Rest is handled by single and.
3258 (define_split
3259 [(set (match_operand:SI 0 "register_operand" "")
3260 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3261 (clobber (reg:CC 17))]
3262 "reload_completed
3263 && true_regnum (operands[0]) == true_regnum (operands[1])"
3264 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3265 (clobber (reg:CC 17))])]
3266 "")
3267
3268 ;; %%% Kill me once multi-word ops are sane.
3269 (define_expand "zero_extendsidi2"
3270 [(set (match_operand:DI 0 "register_operand" "=r")
3271 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3272 ""
3273 "if (!TARGET_64BIT)
3274 {
3275 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3276 DONE;
3277 }
3278 ")
3279
3280 (define_insn "zero_extendsidi2_32"
3281 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3282 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3283 (clobber (reg:CC 17))]
3284 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3285 "@
3286 #
3287 #
3288 #
3289 movd\t{%1, %0|%0, %1}
3290 movd\t{%1, %0|%0, %1}"
3291 [(set_attr "mode" "SI,SI,SI,DI,TI")
3292 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3293
3294 (define_insn "*zero_extendsidi2_32_1"
3295 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3296 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3297 (clobber (reg:CC 17))]
3298 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3299 "@
3300 #
3301 #
3302 #
3303 movd\t{%1, %0|%0, %1}
3304 movd\t{%1, %0|%0, %1}"
3305 [(set_attr "mode" "SI,SI,SI,DI,TI")
3306 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3307
3308 (define_insn "zero_extendsidi2_rex64"
3309 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3310 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3311 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3312 "@
3313 mov\t{%k1, %k0|%k0, %k1}
3314 #
3315 movd\t{%1, %0|%0, %1}
3316 movd\t{%1, %0|%0, %1}"
3317 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3318 (set_attr "mode" "SI,DI,DI,TI")])
3319
3320 (define_insn "*zero_extendsidi2_rex64_1"
3321 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3322 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3323 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3324 "@
3325 mov\t{%k1, %k0|%k0, %k1}
3326 #
3327 movd\t{%1, %0|%0, %1}
3328 movd\t{%1, %0|%0, %1}"
3329 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3330 (set_attr "mode" "SI,DI,SI,SI")])
3331
3332 (define_split
3333 [(set (match_operand:DI 0 "memory_operand" "")
3334 (zero_extend:DI (match_dup 0)))]
3335 "TARGET_64BIT"
3336 [(set (match_dup 4) (const_int 0))]
3337 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3338
3339 (define_split
3340 [(set (match_operand:DI 0 "register_operand" "")
3341 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3342 (clobber (reg:CC 17))]
3343 "!TARGET_64BIT && reload_completed
3344 && true_regnum (operands[0]) == true_regnum (operands[1])"
3345 [(set (match_dup 4) (const_int 0))]
3346 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3347
3348 (define_split
3349 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3350 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3351 (clobber (reg:CC 17))]
3352 "!TARGET_64BIT && reload_completed
3353 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3354 [(set (match_dup 3) (match_dup 1))
3355 (set (match_dup 4) (const_int 0))]
3356 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3357
3358 (define_insn "zero_extendhidi2"
3359 [(set (match_operand:DI 0 "register_operand" "=r,r")
3360 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3361 "TARGET_64BIT"
3362 "@
3363 movz{wl|x}\t{%1, %k0|%k0, %1}
3364 movz{wq|x}\t{%1, %0|%0, %1}"
3365 [(set_attr "type" "imovx")
3366 (set_attr "mode" "SI,DI")])
3367
3368 (define_insn "zero_extendqidi2"
3369 [(set (match_operand:DI 0 "register_operand" "=r,r")
3370 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3371 "TARGET_64BIT"
3372 "@
3373 movz{bl|x}\t{%1, %k0|%k0, %1}
3374 movz{bq|x}\t{%1, %0|%0, %1}"
3375 [(set_attr "type" "imovx")
3376 (set_attr "mode" "SI,DI")])
3377 \f
3378 ;; Sign extension instructions
3379
3380 (define_expand "extendsidi2"
3381 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3382 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3383 (clobber (reg:CC 17))
3384 (clobber (match_scratch:SI 2 ""))])]
3385 ""
3386 {
3387 if (TARGET_64BIT)
3388 {
3389 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3390 DONE;
3391 }
3392 })
3393
3394 (define_insn "*extendsidi2_1"
3395 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3396 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3397 (clobber (reg:CC 17))
3398 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3399 "!TARGET_64BIT"
3400 "#")
3401
3402 (define_insn "extendsidi2_rex64"
3403 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3404 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3405 "TARGET_64BIT"
3406 "@
3407 {cltq|cdqe}
3408 movs{lq|x}\t{%1,%0|%0, %1}"
3409 [(set_attr "type" "imovx")
3410 (set_attr "mode" "DI")
3411 (set_attr "prefix_0f" "0")
3412 (set_attr "modrm" "0,1")])
3413
3414 (define_insn "extendhidi2"
3415 [(set (match_operand:DI 0 "register_operand" "=r")
3416 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3417 "TARGET_64BIT"
3418 "movs{wq|x}\t{%1,%0|%0, %1}"
3419 [(set_attr "type" "imovx")
3420 (set_attr "mode" "DI")])
3421
3422 (define_insn "extendqidi2"
3423 [(set (match_operand:DI 0 "register_operand" "=r")
3424 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3425 "TARGET_64BIT"
3426 "movs{bq|x}\t{%1,%0|%0, %1}"
3427 [(set_attr "type" "imovx")
3428 (set_attr "mode" "DI")])
3429
3430 ;; Extend to memory case when source register does die.
3431 (define_split
3432 [(set (match_operand:DI 0 "memory_operand" "")
3433 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3434 (clobber (reg:CC 17))
3435 (clobber (match_operand:SI 2 "register_operand" ""))]
3436 "(reload_completed
3437 && dead_or_set_p (insn, operands[1])
3438 && !reg_mentioned_p (operands[1], operands[0]))"
3439 [(set (match_dup 3) (match_dup 1))
3440 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3441 (clobber (reg:CC 17))])
3442 (set (match_dup 4) (match_dup 1))]
3443 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3444
3445 ;; Extend to memory case when source register does not die.
3446 (define_split
3447 [(set (match_operand:DI 0 "memory_operand" "")
3448 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3449 (clobber (reg:CC 17))
3450 (clobber (match_operand:SI 2 "register_operand" ""))]
3451 "reload_completed"
3452 [(const_int 0)]
3453 {
3454 split_di (&operands[0], 1, &operands[3], &operands[4]);
3455
3456 emit_move_insn (operands[3], operands[1]);
3457
3458 /* Generate a cltd if possible and doing so it profitable. */
3459 if (true_regnum (operands[1]) == 0
3460 && true_regnum (operands[2]) == 1
3461 && (optimize_size || TARGET_USE_CLTD))
3462 {
3463 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3464 }
3465 else
3466 {
3467 emit_move_insn (operands[2], operands[1]);
3468 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3469 }
3470 emit_move_insn (operands[4], operands[2]);
3471 DONE;
3472 })
3473
3474 ;; Extend to register case. Optimize case where source and destination
3475 ;; registers match and cases where we can use cltd.
3476 (define_split
3477 [(set (match_operand:DI 0 "register_operand" "")
3478 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3479 (clobber (reg:CC 17))
3480 (clobber (match_scratch:SI 2 ""))]
3481 "reload_completed"
3482 [(const_int 0)]
3483 {
3484 split_di (&operands[0], 1, &operands[3], &operands[4]);
3485
3486 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3487 emit_move_insn (operands[3], operands[1]);
3488
3489 /* Generate a cltd if possible and doing so it profitable. */
3490 if (true_regnum (operands[3]) == 0
3491 && (optimize_size || TARGET_USE_CLTD))
3492 {
3493 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3494 DONE;
3495 }
3496
3497 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3498 emit_move_insn (operands[4], operands[1]);
3499
3500 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3501 DONE;
3502 })
3503
3504 (define_insn "extendhisi2"
3505 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3506 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3507 ""
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,%0|%0, %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 "*extendhisi2_zext"
3531 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3532 (zero_extend:DI
3533 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3534 "TARGET_64BIT"
3535 {
3536 switch (get_attr_prefix_0f (insn))
3537 {
3538 case 0:
3539 return "{cwtl|cwde}";
3540 default:
3541 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3542 }
3543 }
3544 [(set_attr "type" "imovx")
3545 (set_attr "mode" "SI")
3546 (set (attr "prefix_0f")
3547 ;; movsx is short decodable while cwtl is vector decoded.
3548 (if_then_else (and (eq_attr "cpu" "!k6")
3549 (eq_attr "alternative" "0"))
3550 (const_string "0")
3551 (const_string "1")))
3552 (set (attr "modrm")
3553 (if_then_else (eq_attr "prefix_0f" "0")
3554 (const_string "0")
3555 (const_string "1")))])
3556
3557 (define_insn "extendqihi2"
3558 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3559 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3560 ""
3561 {
3562 switch (get_attr_prefix_0f (insn))
3563 {
3564 case 0:
3565 return "{cbtw|cbw}";
3566 default:
3567 return "movs{bw|x}\t{%1,%0|%0, %1}";
3568 }
3569 }
3570 [(set_attr "type" "imovx")
3571 (set_attr "mode" "HI")
3572 (set (attr "prefix_0f")
3573 ;; movsx is short decodable while cwtl is vector decoded.
3574 (if_then_else (and (eq_attr "cpu" "!k6")
3575 (eq_attr "alternative" "0"))
3576 (const_string "0")
3577 (const_string "1")))
3578 (set (attr "modrm")
3579 (if_then_else (eq_attr "prefix_0f" "0")
3580 (const_string "0")
3581 (const_string "1")))])
3582
3583 (define_insn "extendqisi2"
3584 [(set (match_operand:SI 0 "register_operand" "=r")
3585 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3586 ""
3587 "movs{bl|x}\t{%1,%0|%0, %1}"
3588 [(set_attr "type" "imovx")
3589 (set_attr "mode" "SI")])
3590
3591 (define_insn "*extendqisi2_zext"
3592 [(set (match_operand:DI 0 "register_operand" "=r")
3593 (zero_extend:DI
3594 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3595 "TARGET_64BIT"
3596 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3597 [(set_attr "type" "imovx")
3598 (set_attr "mode" "SI")])
3599 \f
3600 ;; Conversions between float and double.
3601
3602 ;; These are all no-ops in the model used for the 80387. So just
3603 ;; emit moves.
3604
3605 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3606 (define_insn "*dummy_extendsfdf2"
3607 [(set (match_operand:DF 0 "push_operand" "=<")
3608 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3609 "0"
3610 "#")
3611
3612 (define_split
3613 [(set (match_operand:DF 0 "push_operand" "")
3614 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3615 "!TARGET_64BIT"
3616 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3617 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3618
3619 (define_split
3620 [(set (match_operand:DF 0 "push_operand" "")
3621 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3622 "TARGET_64BIT"
3623 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3624 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3625
3626 (define_insn "*dummy_extendsfxf2"
3627 [(set (match_operand:XF 0 "push_operand" "=<")
3628 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3629 "0"
3630 "#")
3631
3632 (define_split
3633 [(set (match_operand:XF 0 "push_operand" "")
3634 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3635 "!TARGET_128BIT_LONG_DOUBLE"
3636 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3637 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3638
3639 (define_insn "*dummy_extendsftf2"
3640 [(set (match_operand:TF 0 "push_operand" "=<")
3641 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3642 "0"
3643 "#")
3644
3645 (define_split
3646 [(set (match_operand:TF 0 "push_operand" "")
3647 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3648 "!TARGET_64BIT"
3649 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3650 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3651
3652 (define_split
3653 [(set (match_operand:TF 0 "push_operand" "")
3654 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3655 "TARGET_64BIT"
3656 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3657 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3658
3659 (define_insn "*dummy_extenddfxf2"
3660 [(set (match_operand:XF 0 "push_operand" "=<")
3661 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3662 "0"
3663 "#")
3664
3665 (define_split
3666 [(set (match_operand:XF 0 "push_operand" "")
3667 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3668 "!TARGET_128BIT_LONG_DOUBLE"
3669 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3670 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3671
3672 (define_insn "*dummy_extenddftf2"
3673 [(set (match_operand:TF 0 "push_operand" "=<")
3674 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3675 "0"
3676 "#")
3677
3678 (define_split
3679 [(set (match_operand:TF 0 "push_operand" "")
3680 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3681 "!TARGET_64BIT"
3682 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3683 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3684
3685 (define_split
3686 [(set (match_operand:TF 0 "push_operand" "")
3687 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3688 "TARGET_64BIT"
3689 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3690 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3691
3692 (define_expand "extendsfdf2"
3693 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3694 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3695 "TARGET_80387 || TARGET_SSE2"
3696 {
3697 /* ??? Needed for compress_float_constant since all fp constants
3698 are LEGITIMATE_CONSTANT_P. */
3699 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3700 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3701 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3702 operands[1] = force_reg (SFmode, operands[1]);
3703 })
3704
3705 (define_insn "*extendsfdf2_1"
3706 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3707 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3708 "(TARGET_80387 || TARGET_SSE2)
3709 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3710 {
3711 switch (which_alternative)
3712 {
3713 case 0:
3714 if (REG_P (operands[1])
3715 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3716 return "fstp\t%y0";
3717 else if (STACK_TOP_P (operands[0]))
3718 return "fld%z1\t%y1";
3719 else
3720 return "fst\t%y0";
3721
3722 case 1:
3723 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3724 return "fstp%z0\t%y0";
3725
3726 else
3727 return "fst%z0\t%y0";
3728 case 2:
3729 return "cvtss2sd\t{%1, %0|%0, %1}";
3730
3731 default:
3732 abort ();
3733 }
3734 }
3735 [(set_attr "type" "fmov,fmov,ssecvt")
3736 (set_attr "mode" "SF,XF,DF")])
3737
3738 (define_insn "*extendsfdf2_1_sse_only"
3739 [(set (match_operand:DF 0 "register_operand" "=Y")
3740 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3741 "!TARGET_80387 && TARGET_SSE2
3742 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3743 "cvtss2sd\t{%1, %0|%0, %1}"
3744 [(set_attr "type" "ssecvt")
3745 (set_attr "mode" "DF")])
3746
3747 (define_expand "extendsfxf2"
3748 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3749 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3750 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3751 {
3752 /* ??? Needed for compress_float_constant since all fp constants
3753 are LEGITIMATE_CONSTANT_P. */
3754 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3755 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3756 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3757 operands[1] = force_reg (SFmode, operands[1]);
3758 })
3759
3760 (define_insn "*extendsfxf2_1"
3761 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3762 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3763 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3764 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3765 {
3766 switch (which_alternative)
3767 {
3768 case 0:
3769 if (REG_P (operands[1])
3770 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3771 return "fstp\t%y0";
3772 else if (STACK_TOP_P (operands[0]))
3773 return "fld%z1\t%y1";
3774 else
3775 return "fst\t%y0";
3776
3777 case 1:
3778 /* There is no non-popping store to memory for XFmode. So if
3779 we need one, follow the store with a load. */
3780 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3781 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3782 else
3783 return "fstp%z0\t%y0";
3784
3785 default:
3786 abort ();
3787 }
3788 }
3789 [(set_attr "type" "fmov")
3790 (set_attr "mode" "SF,XF")])
3791
3792 (define_expand "extendsftf2"
3793 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3794 (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3795 "TARGET_80387"
3796 {
3797 /* ??? Needed for compress_float_constant since all fp constants
3798 are LEGITIMATE_CONSTANT_P. */
3799 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3800 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3801 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3802 operands[1] = force_reg (SFmode, operands[1]);
3803 })
3804
3805 (define_insn "*extendsftf2_1"
3806 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3807 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3808 "TARGET_80387
3809 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3810 {
3811 switch (which_alternative)
3812 {
3813 case 0:
3814 if (REG_P (operands[1])
3815 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3816 return "fstp\t%y0";
3817 else if (STACK_TOP_P (operands[0]))
3818 return "fld%z1\t%y1";
3819 else
3820 return "fst\t%y0";
3821
3822 case 1:
3823 /* There is no non-popping store to memory for XFmode. So if
3824 we need one, follow the store with a load. */
3825 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3826 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3827 else
3828 return "fstp%z0\t%y0";
3829
3830 default:
3831 abort ();
3832 }
3833 }
3834 [(set_attr "type" "fmov")
3835 (set_attr "mode" "SF,XF")])
3836
3837 (define_expand "extenddfxf2"
3838 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3839 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3840 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3841 {
3842 /* ??? Needed for compress_float_constant since all fp constants
3843 are LEGITIMATE_CONSTANT_P. */
3844 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3845 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3846 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3847 operands[1] = force_reg (DFmode, operands[1]);
3848 })
3849
3850 (define_insn "*extenddfxf2_1"
3851 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3852 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3853 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3854 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3855 {
3856 switch (which_alternative)
3857 {
3858 case 0:
3859 if (REG_P (operands[1])
3860 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3861 return "fstp\t%y0";
3862 else if (STACK_TOP_P (operands[0]))
3863 return "fld%z1\t%y1";
3864 else
3865 return "fst\t%y0";
3866
3867 case 1:
3868 /* There is no non-popping store to memory for XFmode. So if
3869 we need one, follow the store with a load. */
3870 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3871 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3872 else
3873 return "fstp%z0\t%y0";
3874
3875 default:
3876 abort ();
3877 }
3878 }
3879 [(set_attr "type" "fmov")
3880 (set_attr "mode" "DF,XF")])
3881
3882 (define_expand "extenddftf2"
3883 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3884 (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3885 "TARGET_80387"
3886 {
3887 /* ??? Needed for compress_float_constant since all fp constants
3888 are LEGITIMATE_CONSTANT_P. */
3889 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3890 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3891 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3892 operands[1] = force_reg (DFmode, operands[1]);
3893 })
3894
3895 (define_insn "*extenddftf2_1"
3896 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3897 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3898 "TARGET_80387
3899 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3900 {
3901 switch (which_alternative)
3902 {
3903 case 0:
3904 if (REG_P (operands[1])
3905 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3906 return "fstp\t%y0";
3907 else if (STACK_TOP_P (operands[0]))
3908 return "fld%z1\t%y1";
3909 else
3910 return "fst\t%y0";
3911
3912 case 1:
3913 /* There is no non-popping store to memory for XFmode. So if
3914 we need one, follow the store with a load. */
3915 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3916 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3917 else
3918 return "fstp%z0\t%y0";
3919
3920 default:
3921 abort ();
3922 }
3923 }
3924 [(set_attr "type" "fmov")
3925 (set_attr "mode" "DF,XF")])
3926
3927 ;; %%% This seems bad bad news.
3928 ;; This cannot output into an f-reg because there is no way to be sure
3929 ;; of truncating in that case. Otherwise this is just like a simple move
3930 ;; insn. So we pretend we can output to a reg in order to get better
3931 ;; register preferencing, but we really use a stack slot.
3932
3933 (define_expand "truncdfsf2"
3934 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3935 (float_truncate:SF
3936 (match_operand:DF 1 "register_operand" "")))
3937 (clobber (match_dup 2))])]
3938 "TARGET_80387 || TARGET_SSE2"
3939 "
3940 if (TARGET_80387)
3941 operands[2] = assign_386_stack_local (SFmode, 0);
3942 else
3943 {
3944 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3945 DONE;
3946 }
3947 ")
3948
3949 (define_insn "*truncdfsf2_1"
3950 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3951 (float_truncate:SF
3952 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3953 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3954 "TARGET_80387 && !TARGET_SSE2"
3955 {
3956 switch (which_alternative)
3957 {
3958 case 0:
3959 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3960 return "fstp%z0\t%y0";
3961 else
3962 return "fst%z0\t%y0";
3963 default:
3964 abort ();
3965 }
3966 }
3967 [(set_attr "type" "fmov,multi,multi,multi")
3968 (set_attr "mode" "SF,SF,SF,SF")])
3969
3970 (define_insn "*truncdfsf2_1_sse"
3971 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3972 (float_truncate:SF
3973 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3974 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3975 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3976 {
3977 switch (which_alternative)
3978 {
3979 case 0:
3980 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981 return "fstp%z0\t%y0";
3982 else
3983 return "fst%z0\t%y0";
3984 case 4:
3985 return "#";
3986 default:
3987 abort ();
3988 }
3989 }
3990 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3991 (set_attr "mode" "SF,SF,SF,SF,DF")])
3992
3993 (define_insn "*truncdfsf2_1_sse_nooverlap"
3994 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3995 (float_truncate:SF
3996 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3997 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3998 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3999 {
4000 switch (which_alternative)
4001 {
4002 case 0:
4003 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4004 return "fstp%z0\t%y0";
4005 else
4006 return "fst%z0\t%y0";
4007 case 4:
4008 return "#";
4009 default:
4010 abort ();
4011 }
4012 }
4013 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
4014 (set_attr "mode" "SF,SF,SF,SF,DF")])
4015
4016 (define_insn "*truncdfsf2_2"
4017 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
4018 (float_truncate:SF
4019 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
4020 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
4021 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4022 {
4023 switch (which_alternative)
4024 {
4025 case 0:
4026 case 1:
4027 return "cvtsd2ss\t{%1, %0|%0, %1}";
4028 case 2:
4029 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4030 return "fstp%z0\t%y0";
4031 else
4032 return "fst%z0\t%y0";
4033 default:
4034 abort ();
4035 }
4036 }
4037 [(set_attr "type" "ssecvt,ssecvt,fmov")
4038 (set_attr "athlon_decode" "vector,double,*")
4039 (set_attr "mode" "SF,SF,SF")])
4040
4041 (define_insn "*truncdfsf2_2_nooverlap"
4042 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
4043 (float_truncate:SF
4044 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4045 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
4046 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4047 {
4048 switch (which_alternative)
4049 {
4050 case 0:
4051 return "#";
4052 case 1:
4053 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4054 return "fstp%z0\t%y0";
4055 else
4056 return "fst%z0\t%y0";
4057 default:
4058 abort ();
4059 }
4060 }
4061 [(set_attr "type" "ssecvt,fmov")
4062 (set_attr "mode" "DF,SF")])
4063
4064 (define_insn "*truncdfsf2_3"
4065 [(set (match_operand:SF 0 "memory_operand" "=m")
4066 (float_truncate:SF
4067 (match_operand:DF 1 "register_operand" "f")))]
4068 "TARGET_80387"
4069 {
4070 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4071 return "fstp%z0\t%y0";
4072 else
4073 return "fst%z0\t%y0";
4074 }
4075 [(set_attr "type" "fmov")
4076 (set_attr "mode" "SF")])
4077
4078 (define_insn "truncdfsf2_sse_only"
4079 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
4080 (float_truncate:SF
4081 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
4082 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4083 "cvtsd2ss\t{%1, %0|%0, %1}"
4084 [(set_attr "type" "ssecvt")
4085 (set_attr "athlon_decode" "vector,double")
4086 (set_attr "mode" "SF")])
4087
4088 (define_insn "*truncdfsf2_sse_only_nooverlap"
4089 [(set (match_operand:SF 0 "register_operand" "=&Y")
4090 (float_truncate:SF
4091 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4092 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4093 "#"
4094 [(set_attr "type" "ssecvt")
4095 (set_attr "mode" "DF")])
4096
4097 (define_split
4098 [(set (match_operand:SF 0 "memory_operand" "")
4099 (float_truncate:SF
4100 (match_operand:DF 1 "register_operand" "")))
4101 (clobber (match_operand:SF 2 "memory_operand" ""))]
4102 "TARGET_80387"
4103 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4104 "")
4105
4106 ; Avoid possible reformatting penalty on the destination by first
4107 ; zeroing it out
4108 (define_split
4109 [(set (match_operand:SF 0 "register_operand" "")
4110 (float_truncate:SF
4111 (match_operand:DF 1 "nonimmediate_operand" "")))
4112 (clobber (match_operand 2 "" ""))]
4113 "TARGET_80387 && reload_completed
4114 && SSE_REG_P (operands[0])
4115 && !STACK_REG_P (operands[1])"
4116 [(const_int 0)]
4117 {
4118 rtx src, dest;
4119 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
4120 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4121 else
4122 {
4123 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4124 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4125 /* simplify_gen_subreg refuses to widen memory references. */
4126 if (GET_CODE (src) == SUBREG)
4127 alter_subreg (&src);
4128 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4129 abort ();
4130 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4131 emit_insn (gen_cvtsd2ss (dest, dest, src));
4132 }
4133 DONE;
4134 })
4135
4136 (define_split
4137 [(set (match_operand:SF 0 "register_operand" "")
4138 (float_truncate:SF
4139 (match_operand:DF 1 "nonimmediate_operand" "")))]
4140 "TARGET_80387 && reload_completed
4141 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4142 [(const_int 0)]
4143 {
4144 rtx src, dest;
4145 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4146 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4147 /* simplify_gen_subreg refuses to widen memory references. */
4148 if (GET_CODE (src) == SUBREG)
4149 alter_subreg (&src);
4150 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4151 abort ();
4152 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4153 emit_insn (gen_cvtsd2ss (dest, dest, src));
4154 DONE;
4155 })
4156
4157 (define_split
4158 [(set (match_operand:SF 0 "register_operand" "")
4159 (float_truncate:SF
4160 (match_operand:DF 1 "fp_register_operand" "")))
4161 (clobber (match_operand:SF 2 "memory_operand" ""))]
4162 "TARGET_80387 && reload_completed"
4163 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4164 (set (match_dup 0) (match_dup 2))]
4165 "")
4166
4167 (define_expand "truncxfsf2"
4168 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4169 (float_truncate:SF
4170 (match_operand:XF 1 "register_operand" "")))
4171 (clobber (match_dup 2))])]
4172 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4173 "operands[2] = assign_386_stack_local (SFmode, 0);")
4174
4175 (define_insn "*truncxfsf2_1"
4176 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4177 (float_truncate:SF
4178 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4179 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4180 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4181 {
4182 switch (which_alternative)
4183 {
4184 case 0:
4185 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4186 return "fstp%z0\t%y0";
4187 else
4188 return "fst%z0\t%y0";
4189 default:
4190 abort();
4191 }
4192 }
4193 [(set_attr "type" "fmov,multi,multi,multi")
4194 (set_attr "mode" "SF")])
4195
4196 (define_insn "*truncxfsf2_2"
4197 [(set (match_operand:SF 0 "memory_operand" "=m")
4198 (float_truncate:SF
4199 (match_operand:XF 1 "register_operand" "f")))]
4200 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4201 {
4202 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4203 return "fstp%z0\t%y0";
4204 else
4205 return "fst%z0\t%y0";
4206 }
4207 [(set_attr "type" "fmov")
4208 (set_attr "mode" "SF")])
4209
4210 (define_split
4211 [(set (match_operand:SF 0 "memory_operand" "")
4212 (float_truncate:SF
4213 (match_operand:XF 1 "register_operand" "")))
4214 (clobber (match_operand:SF 2 "memory_operand" ""))]
4215 "TARGET_80387"
4216 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4217 "")
4218
4219 (define_split
4220 [(set (match_operand:SF 0 "register_operand" "")
4221 (float_truncate:SF
4222 (match_operand:XF 1 "register_operand" "")))
4223 (clobber (match_operand:SF 2 "memory_operand" ""))]
4224 "TARGET_80387 && reload_completed"
4225 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4226 (set (match_dup 0) (match_dup 2))]
4227 "")
4228
4229 (define_expand "trunctfsf2"
4230 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4231 (float_truncate:SF
4232 (match_operand:TF 1 "register_operand" "")))
4233 (clobber (match_dup 2))])]
4234 "TARGET_80387"
4235 "operands[2] = assign_386_stack_local (SFmode, 0);")
4236
4237 (define_insn "*trunctfsf2_1"
4238 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4239 (float_truncate:SF
4240 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4241 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4242 "TARGET_80387"
4243 {
4244 switch (which_alternative)
4245 {
4246 case 0:
4247 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4248 return "fstp%z0\t%y0";
4249 else
4250 return "fst%z0\t%y0";
4251 default:
4252 abort();
4253 }
4254 }
4255 [(set_attr "type" "fmov,multi,multi,multi")
4256 (set_attr "mode" "SF")])
4257
4258 (define_insn "*trunctfsf2_2"
4259 [(set (match_operand:SF 0 "memory_operand" "=m")
4260 (float_truncate:SF
4261 (match_operand:TF 1 "register_operand" "f")))]
4262 "TARGET_80387"
4263 {
4264 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4265 return "fstp%z0\t%y0";
4266 else
4267 return "fst%z0\t%y0";
4268 }
4269 [(set_attr "type" "fmov")
4270 (set_attr "mode" "SF")])
4271
4272 (define_split
4273 [(set (match_operand:SF 0 "memory_operand" "")
4274 (float_truncate:SF
4275 (match_operand:TF 1 "register_operand" "")))
4276 (clobber (match_operand:SF 2 "memory_operand" ""))]
4277 "TARGET_80387"
4278 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4279 "")
4280
4281 (define_split
4282 [(set (match_operand:SF 0 "register_operand" "")
4283 (float_truncate:SF
4284 (match_operand:TF 1 "register_operand" "")))
4285 (clobber (match_operand:SF 2 "memory_operand" ""))]
4286 "TARGET_80387 && reload_completed"
4287 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4288 (set (match_dup 0) (match_dup 2))]
4289 "")
4290
4291
4292 (define_expand "truncxfdf2"
4293 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4294 (float_truncate:DF
4295 (match_operand:XF 1 "register_operand" "")))
4296 (clobber (match_dup 2))])]
4297 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4298 "operands[2] = assign_386_stack_local (DFmode, 0);")
4299
4300 (define_insn "*truncxfdf2_1"
4301 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4302 (float_truncate:DF
4303 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4304 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4305 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4306 {
4307 switch (which_alternative)
4308 {
4309 case 0:
4310 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4311 return "fstp%z0\t%y0";
4312 else
4313 return "fst%z0\t%y0";
4314 default:
4315 abort();
4316 }
4317 abort ();
4318 }
4319 [(set_attr "type" "fmov,multi,multi,multi")
4320 (set_attr "mode" "DF")])
4321
4322 (define_insn "*truncxfdf2_2"
4323 [(set (match_operand:DF 0 "memory_operand" "=m")
4324 (float_truncate:DF
4325 (match_operand:XF 1 "register_operand" "f")))]
4326 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4327 {
4328 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4329 return "fstp%z0\t%y0";
4330 else
4331 return "fst%z0\t%y0";
4332 }
4333 [(set_attr "type" "fmov")
4334 (set_attr "mode" "DF")])
4335
4336 (define_split
4337 [(set (match_operand:DF 0 "memory_operand" "")
4338 (float_truncate:DF
4339 (match_operand:XF 1 "register_operand" "")))
4340 (clobber (match_operand:DF 2 "memory_operand" ""))]
4341 "TARGET_80387"
4342 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4343 "")
4344
4345 (define_split
4346 [(set (match_operand:DF 0 "register_operand" "")
4347 (float_truncate:DF
4348 (match_operand:XF 1 "register_operand" "")))
4349 (clobber (match_operand:DF 2 "memory_operand" ""))]
4350 "TARGET_80387 && reload_completed"
4351 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4352 (set (match_dup 0) (match_dup 2))]
4353 "")
4354
4355 (define_expand "trunctfdf2"
4356 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4357 (float_truncate:DF
4358 (match_operand:TF 1 "register_operand" "")))
4359 (clobber (match_dup 2))])]
4360 "TARGET_80387"
4361 "operands[2] = assign_386_stack_local (DFmode, 0);")
4362
4363 (define_insn "*trunctfdf2_1"
4364 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4365 (float_truncate:DF
4366 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4367 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4368 "TARGET_80387"
4369 {
4370 switch (which_alternative)
4371 {
4372 case 0:
4373 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4374 return "fstp%z0\t%y0";
4375 else
4376 return "fst%z0\t%y0";
4377 default:
4378 abort();
4379 }
4380 abort ();
4381 }
4382 [(set_attr "type" "fmov,multi,multi,multi")
4383 (set_attr "mode" "DF")])
4384
4385 (define_insn "*trunctfdf2_2"
4386 [(set (match_operand:DF 0 "memory_operand" "=m")
4387 (float_truncate:DF
4388 (match_operand:TF 1 "register_operand" "f")))]
4389 "TARGET_80387"
4390 {
4391 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4392 return "fstp%z0\t%y0";
4393 else
4394 return "fst%z0\t%y0";
4395 }
4396 [(set_attr "type" "fmov")
4397 (set_attr "mode" "DF")])
4398
4399 (define_split
4400 [(set (match_operand:DF 0 "memory_operand" "")
4401 (float_truncate:DF
4402 (match_operand:TF 1 "register_operand" "")))
4403 (clobber (match_operand:DF 2 "memory_operand" ""))]
4404 "TARGET_80387"
4405 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4406 "")
4407
4408 (define_split
4409 [(set (match_operand:DF 0 "register_operand" "")
4410 (float_truncate:DF
4411 (match_operand:TF 1 "register_operand" "")))
4412 (clobber (match_operand:DF 2 "memory_operand" ""))]
4413 "TARGET_80387 && reload_completed"
4414 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4415 (set (match_dup 0) (match_dup 2))]
4416 "")
4417
4418 \f
4419 ;; %%% Break up all these bad boys.
4420
4421 ;; Signed conversion to DImode.
4422
4423 (define_expand "fix_truncxfdi2"
4424 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4425 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4426 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4427 "")
4428
4429 (define_expand "fix_trunctfdi2"
4430 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4431 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4432 "TARGET_80387"
4433 "")
4434
4435 (define_expand "fix_truncdfdi2"
4436 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4437 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4438 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4439 {
4440 if (TARGET_64BIT && TARGET_SSE2)
4441 {
4442 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4443 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4444 if (out != operands[0])
4445 emit_move_insn (operands[0], out);
4446 DONE;
4447 }
4448 })
4449
4450 (define_expand "fix_truncsfdi2"
4451 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4452 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4453 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4454 {
4455 if (TARGET_SSE && TARGET_64BIT)
4456 {
4457 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4458 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4459 if (out != operands[0])
4460 emit_move_insn (operands[0], out);
4461 DONE;
4462 }
4463 })
4464
4465 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4466 ;; of the machinery.
4467 (define_insn_and_split "*fix_truncdi_1"
4468 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4469 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4470 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4471 && !reload_completed && !reload_in_progress
4472 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4473 "#"
4474 "&& 1"
4475 [(const_int 0)]
4476 {
4477 ix86_optimize_mode_switching = 1;
4478 operands[2] = assign_386_stack_local (HImode, 1);
4479 operands[3] = assign_386_stack_local (HImode, 2);
4480 if (memory_operand (operands[0], VOIDmode))
4481 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4482 operands[2], operands[3]));
4483 else
4484 {
4485 operands[4] = assign_386_stack_local (DImode, 0);
4486 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4487 operands[2], operands[3],
4488 operands[4]));
4489 }
4490 DONE;
4491 }
4492 [(set_attr "type" "fistp")
4493 (set_attr "mode" "DI")])
4494
4495 (define_insn "fix_truncdi_nomemory"
4496 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4497 (fix:DI (match_operand 1 "register_operand" "f,f")))
4498 (use (match_operand:HI 2 "memory_operand" "m,m"))
4499 (use (match_operand:HI 3 "memory_operand" "m,m"))
4500 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4501 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4502 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4503 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4504 "#"
4505 [(set_attr "type" "fistp")
4506 (set_attr "mode" "DI")])
4507
4508 (define_insn "fix_truncdi_memory"
4509 [(set (match_operand:DI 0 "memory_operand" "=m")
4510 (fix:DI (match_operand 1 "register_operand" "f")))
4511 (use (match_operand:HI 2 "memory_operand" "m"))
4512 (use (match_operand:HI 3 "memory_operand" "m"))
4513 (clobber (match_scratch:DF 4 "=&1f"))]
4514 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4515 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4516 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4517 [(set_attr "type" "fistp")
4518 (set_attr "mode" "DI")])
4519
4520 (define_split
4521 [(set (match_operand:DI 0 "register_operand" "")
4522 (fix:DI (match_operand 1 "register_operand" "")))
4523 (use (match_operand:HI 2 "memory_operand" ""))
4524 (use (match_operand:HI 3 "memory_operand" ""))
4525 (clobber (match_operand:DI 4 "memory_operand" ""))
4526 (clobber (match_scratch 5 ""))]
4527 "reload_completed"
4528 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4529 (use (match_dup 2))
4530 (use (match_dup 3))
4531 (clobber (match_dup 5))])
4532 (set (match_dup 0) (match_dup 4))]
4533 "")
4534
4535 (define_split
4536 [(set (match_operand:DI 0 "memory_operand" "")
4537 (fix:DI (match_operand 1 "register_operand" "")))
4538 (use (match_operand:HI 2 "memory_operand" ""))
4539 (use (match_operand:HI 3 "memory_operand" ""))
4540 (clobber (match_operand:DI 4 "memory_operand" ""))
4541 (clobber (match_scratch 5 ""))]
4542 "reload_completed"
4543 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4544 (use (match_dup 2))
4545 (use (match_dup 3))
4546 (clobber (match_dup 5))])]
4547 "")
4548
4549 ;; When SSE available, it is always faster to use it!
4550 (define_insn "fix_truncsfdi_sse"
4551 [(set (match_operand:DI 0 "register_operand" "=r,r")
4552 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4553 "TARGET_64BIT && TARGET_SSE"
4554 "cvttss2si{q}\t{%1, %0|%0, %1}"
4555 [(set_attr "type" "sseicvt")
4556 (set_attr "mode" "SF")
4557 (set_attr "athlon_decode" "double,vector")])
4558
4559 ;; Avoid vector decoded form of the instruction.
4560 (define_peephole2
4561 [(match_scratch:SF 2 "x")
4562 (set (match_operand:DI 0 "register_operand" "")
4563 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4564 "TARGET_K8 && !optimize_size"
4565 [(set (match_dup 2) (match_dup 1))
4566 (set (match_dup 0) (fix:DI (match_dup 2)))]
4567 "")
4568
4569 (define_insn "fix_truncdfdi_sse"
4570 [(set (match_operand:DI 0 "register_operand" "=r,r")
4571 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4572 "TARGET_64BIT && TARGET_SSE2"
4573 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4574 [(set_attr "type" "sseicvt,sseicvt")
4575 (set_attr "mode" "DF")
4576 (set_attr "athlon_decode" "double,vector")])
4577
4578 ;; Avoid vector decoded form of the instruction.
4579 (define_peephole2
4580 [(match_scratch:DF 2 "Y")
4581 (set (match_operand:DI 0 "register_operand" "")
4582 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4583 "TARGET_K8 && !optimize_size"
4584 [(set (match_dup 2) (match_dup 1))
4585 (set (match_dup 0) (fix:DI (match_dup 2)))]
4586 "")
4587
4588 ;; Signed conversion to SImode.
4589
4590 (define_expand "fix_truncxfsi2"
4591 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4592 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4593 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4594 "")
4595
4596 (define_expand "fix_trunctfsi2"
4597 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4598 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4599 "TARGET_80387"
4600 "")
4601
4602 (define_expand "fix_truncdfsi2"
4603 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4604 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4605 "TARGET_80387 || TARGET_SSE2"
4606 {
4607 if (TARGET_SSE2)
4608 {
4609 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4610 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4611 if (out != operands[0])
4612 emit_move_insn (operands[0], out);
4613 DONE;
4614 }
4615 })
4616
4617 (define_expand "fix_truncsfsi2"
4618 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4619 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4620 "TARGET_80387 || TARGET_SSE"
4621 {
4622 if (TARGET_SSE)
4623 {
4624 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4625 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4626 if (out != operands[0])
4627 emit_move_insn (operands[0], out);
4628 DONE;
4629 }
4630 })
4631
4632 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4633 ;; of the machinery.
4634 (define_insn_and_split "*fix_truncsi_1"
4635 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4636 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4637 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4638 && !reload_completed && !reload_in_progress
4639 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4640 "#"
4641 "&& 1"
4642 [(const_int 0)]
4643 {
4644 ix86_optimize_mode_switching = 1;
4645 operands[2] = assign_386_stack_local (HImode, 1);
4646 operands[3] = assign_386_stack_local (HImode, 2);
4647 if (memory_operand (operands[0], VOIDmode))
4648 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4649 operands[2], operands[3]));
4650 else
4651 {
4652 operands[4] = assign_386_stack_local (SImode, 0);
4653 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4654 operands[2], operands[3],
4655 operands[4]));
4656 }
4657 DONE;
4658 }
4659 [(set_attr "type" "fistp")
4660 (set_attr "mode" "SI")])
4661
4662 (define_insn "fix_truncsi_nomemory"
4663 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4664 (fix:SI (match_operand 1 "register_operand" "f,f")))
4665 (use (match_operand:HI 2 "memory_operand" "m,m"))
4666 (use (match_operand:HI 3 "memory_operand" "m,m"))
4667 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4668 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4669 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4670 "#"
4671 [(set_attr "type" "fistp")
4672 (set_attr "mode" "SI")])
4673
4674 (define_insn "fix_truncsi_memory"
4675 [(set (match_operand:SI 0 "memory_operand" "=m")
4676 (fix:SI (match_operand 1 "register_operand" "f")))
4677 (use (match_operand:HI 2 "memory_operand" "m"))
4678 (use (match_operand:HI 3 "memory_operand" "m"))]
4679 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4680 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4681 "* return output_fix_trunc (insn, operands);"
4682 [(set_attr "type" "fistp")
4683 (set_attr "mode" "SI")])
4684
4685 ;; When SSE available, it is always faster to use it!
4686 (define_insn "fix_truncsfsi_sse"
4687 [(set (match_operand:SI 0 "register_operand" "=r,r")
4688 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4689 "TARGET_SSE"
4690 "cvttss2si\t{%1, %0|%0, %1}"
4691 [(set_attr "type" "sseicvt")
4692 (set_attr "mode" "DF")
4693 (set_attr "athlon_decode" "double,vector")])
4694
4695 ;; Avoid vector decoded form of the instruction.
4696 (define_peephole2
4697 [(match_scratch:SF 2 "x")
4698 (set (match_operand:SI 0 "register_operand" "")
4699 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4700 "TARGET_K8 && !optimize_size"
4701 [(set (match_dup 2) (match_dup 1))
4702 (set (match_dup 0) (fix:SI (match_dup 2)))]
4703 "")
4704
4705 (define_insn "fix_truncdfsi_sse"
4706 [(set (match_operand:SI 0 "register_operand" "=r,r")
4707 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4708 "TARGET_SSE2"
4709 "cvttsd2si\t{%1, %0|%0, %1}"
4710 [(set_attr "type" "sseicvt")
4711 (set_attr "mode" "DF")
4712 (set_attr "athlon_decode" "double,vector")])
4713
4714 ;; Avoid vector decoded form of the instruction.
4715 (define_peephole2
4716 [(match_scratch:DF 2 "Y")
4717 (set (match_operand:SI 0 "register_operand" "")
4718 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4719 "TARGET_K8 && !optimize_size"
4720 [(set (match_dup 2) (match_dup 1))
4721 (set (match_dup 0) (fix:SI (match_dup 2)))]
4722 "")
4723
4724 (define_split
4725 [(set (match_operand:SI 0 "register_operand" "")
4726 (fix:SI (match_operand 1 "register_operand" "")))
4727 (use (match_operand:HI 2 "memory_operand" ""))
4728 (use (match_operand:HI 3 "memory_operand" ""))
4729 (clobber (match_operand:SI 4 "memory_operand" ""))]
4730 "reload_completed"
4731 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4732 (use (match_dup 2))
4733 (use (match_dup 3))])
4734 (set (match_dup 0) (match_dup 4))]
4735 "")
4736
4737 (define_split
4738 [(set (match_operand:SI 0 "memory_operand" "")
4739 (fix:SI (match_operand 1 "register_operand" "")))
4740 (use (match_operand:HI 2 "memory_operand" ""))
4741 (use (match_operand:HI 3 "memory_operand" ""))
4742 (clobber (match_operand:SI 4 "memory_operand" ""))]
4743 "reload_completed"
4744 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4745 (use (match_dup 2))
4746 (use (match_dup 3))])]
4747 "")
4748
4749 ;; Signed conversion to HImode.
4750
4751 (define_expand "fix_truncxfhi2"
4752 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4753 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4754 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4755 "")
4756
4757 (define_expand "fix_trunctfhi2"
4758 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4759 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4760 "TARGET_80387"
4761 "")
4762
4763 (define_expand "fix_truncdfhi2"
4764 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4765 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4766 "TARGET_80387 && !TARGET_SSE2"
4767 "")
4768
4769 (define_expand "fix_truncsfhi2"
4770 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4771 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4772 "TARGET_80387 && !TARGET_SSE"
4773 "")
4774
4775 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4776 ;; of the machinery.
4777 (define_insn_and_split "*fix_trunchi_1"
4778 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4779 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4780 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4781 && !reload_completed && !reload_in_progress
4782 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4783 "#"
4784 ""
4785 [(const_int 0)]
4786 {
4787 ix86_optimize_mode_switching = 1;
4788 operands[2] = assign_386_stack_local (HImode, 1);
4789 operands[3] = assign_386_stack_local (HImode, 2);
4790 if (memory_operand (operands[0], VOIDmode))
4791 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4792 operands[2], operands[3]));
4793 else
4794 {
4795 operands[4] = assign_386_stack_local (HImode, 0);
4796 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4797 operands[2], operands[3],
4798 operands[4]));
4799 }
4800 DONE;
4801 }
4802 [(set_attr "type" "fistp")
4803 (set_attr "mode" "HI")])
4804
4805 (define_insn "fix_trunchi_nomemory"
4806 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4807 (fix:HI (match_operand 1 "register_operand" "f,f")))
4808 (use (match_operand:HI 2 "memory_operand" "m,m"))
4809 (use (match_operand:HI 3 "memory_operand" "m,m"))
4810 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4811 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4812 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4813 "#"
4814 [(set_attr "type" "fistp")
4815 (set_attr "mode" "HI")])
4816
4817 (define_insn "fix_trunchi_memory"
4818 [(set (match_operand:HI 0 "memory_operand" "=m")
4819 (fix:HI (match_operand 1 "register_operand" "f")))
4820 (use (match_operand:HI 2 "memory_operand" "m"))
4821 (use (match_operand:HI 3 "memory_operand" "m"))]
4822 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4823 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4824 "* return output_fix_trunc (insn, operands);"
4825 [(set_attr "type" "fistp")
4826 (set_attr "mode" "HI")])
4827
4828 (define_split
4829 [(set (match_operand:HI 0 "memory_operand" "")
4830 (fix:HI (match_operand 1 "register_operand" "")))
4831 (use (match_operand:HI 2 "memory_operand" ""))
4832 (use (match_operand:HI 3 "memory_operand" ""))
4833 (clobber (match_operand:HI 4 "memory_operand" ""))]
4834 "reload_completed"
4835 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4836 (use (match_dup 2))
4837 (use (match_dup 3))])]
4838 "")
4839
4840 (define_split
4841 [(set (match_operand:HI 0 "register_operand" "")
4842 (fix:HI (match_operand 1 "register_operand" "")))
4843 (use (match_operand:HI 2 "memory_operand" ""))
4844 (use (match_operand:HI 3 "memory_operand" ""))
4845 (clobber (match_operand:HI 4 "memory_operand" ""))]
4846 "reload_completed"
4847 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4848 (use (match_dup 2))
4849 (use (match_dup 3))
4850 (clobber (match_dup 4))])
4851 (set (match_dup 0) (match_dup 4))]
4852 "")
4853
4854 ;; %% Not used yet.
4855 (define_insn "x86_fnstcw_1"
4856 [(set (match_operand:HI 0 "memory_operand" "=m")
4857 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4858 "TARGET_80387"
4859 "fnstcw\t%0"
4860 [(set_attr "length" "2")
4861 (set_attr "mode" "HI")
4862 (set_attr "unit" "i387")
4863 (set_attr "ppro_uops" "few")])
4864
4865 (define_insn "x86_fldcw_1"
4866 [(set (reg:HI 18)
4867 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4868 "TARGET_80387"
4869 "fldcw\t%0"
4870 [(set_attr "length" "2")
4871 (set_attr "mode" "HI")
4872 (set_attr "unit" "i387")
4873 (set_attr "athlon_decode" "vector")
4874 (set_attr "ppro_uops" "few")])
4875 \f
4876 ;; Conversion between fixed point and floating point.
4877
4878 ;; Even though we only accept memory inputs, the backend _really_
4879 ;; wants to be able to do this between registers.
4880
4881 (define_expand "floathisf2"
4882 [(set (match_operand:SF 0 "register_operand" "")
4883 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4884 "TARGET_SSE || TARGET_80387"
4885 {
4886 if (TARGET_SSE && TARGET_SSE_MATH)
4887 {
4888 emit_insn (gen_floatsisf2 (operands[0],
4889 convert_to_mode (SImode, operands[1], 0)));
4890 DONE;
4891 }
4892 })
4893
4894 (define_insn "*floathisf2_1"
4895 [(set (match_operand:SF 0 "register_operand" "=f,f")
4896 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4897 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4898 "@
4899 fild%z1\t%1
4900 #"
4901 [(set_attr "type" "fmov,multi")
4902 (set_attr "mode" "SF")
4903 (set_attr "fp_int_src" "true")])
4904
4905 (define_expand "floatsisf2"
4906 [(set (match_operand:SF 0 "register_operand" "")
4907 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4908 "TARGET_SSE || TARGET_80387"
4909 "")
4910
4911 (define_insn "*floatsisf2_i387"
4912 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4913 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4914 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4915 "@
4916 fild%z1\t%1
4917 #
4918 cvtsi2ss\t{%1, %0|%0, %1}
4919 cvtsi2ss\t{%1, %0|%0, %1}"
4920 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4921 (set_attr "mode" "SF")
4922 (set_attr "athlon_decode" "*,*,vector,double")
4923 (set_attr "fp_int_src" "true")])
4924
4925 (define_insn "*floatsisf2_sse"
4926 [(set (match_operand:SF 0 "register_operand" "=x,x")
4927 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4928 "TARGET_SSE"
4929 "cvtsi2ss\t{%1, %0|%0, %1}"
4930 [(set_attr "type" "sseicvt")
4931 (set_attr "mode" "SF")
4932 (set_attr "athlon_decode" "vector,double")
4933 (set_attr "fp_int_src" "true")])
4934
4935 ; Avoid possible reformatting penalty on the destination by first
4936 ; zeroing it out
4937 (define_split
4938 [(set (match_operand:SF 0 "register_operand" "")
4939 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4940 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4941 && SSE_REG_P (operands[0])"
4942 [(const_int 0)]
4943 {
4944 rtx dest;
4945 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4946 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4947 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4948 DONE;
4949 })
4950
4951 (define_expand "floatdisf2"
4952 [(set (match_operand:SF 0 "register_operand" "")
4953 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4954 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4955 "")
4956
4957 (define_insn "*floatdisf2_i387_only"
4958 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4959 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4960 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4961 "@
4962 fild%z1\t%1
4963 #"
4964 [(set_attr "type" "fmov,multi")
4965 (set_attr "mode" "SF")
4966 (set_attr "fp_int_src" "true")])
4967
4968 (define_insn "*floatdisf2_i387"
4969 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4970 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4971 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4972 "@
4973 fild%z1\t%1
4974 #
4975 cvtsi2ss{q}\t{%1, %0|%0, %1}
4976 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4977 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4978 (set_attr "mode" "SF")
4979 (set_attr "athlon_decode" "*,*,vector,double")
4980 (set_attr "fp_int_src" "true")])
4981
4982 (define_insn "*floatdisf2_sse"
4983 [(set (match_operand:SF 0 "register_operand" "=x,x")
4984 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4985 "TARGET_64BIT && TARGET_SSE"
4986 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4987 [(set_attr "type" "sseicvt")
4988 (set_attr "mode" "SF")
4989 (set_attr "athlon_decode" "vector,double")
4990 (set_attr "fp_int_src" "true")])
4991
4992 ; Avoid possible reformatting penalty on the destination by first
4993 ; zeroing it out
4994 (define_split
4995 [(set (match_operand:SF 0 "register_operand" "")
4996 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4997 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4998 && SSE_REG_P (operands[0])"
4999 [(const_int 0)]
5000 {
5001 rtx dest;
5002 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
5003 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
5004 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
5005 DONE;
5006 })
5007
5008 (define_expand "floathidf2"
5009 [(set (match_operand:DF 0 "register_operand" "")
5010 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
5011 "TARGET_SSE2 || TARGET_80387"
5012 {
5013 if (TARGET_SSE && TARGET_SSE_MATH)
5014 {
5015 emit_insn (gen_floatsidf2 (operands[0],
5016 convert_to_mode (SImode, operands[1], 0)));
5017 DONE;
5018 }
5019 })
5020
5021 (define_insn "*floathidf2_1"
5022 [(set (match_operand:DF 0 "register_operand" "=f,f")
5023 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5024 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
5025 "@
5026 fild%z1\t%1
5027 #"
5028 [(set_attr "type" "fmov,multi")
5029 (set_attr "mode" "DF")
5030 (set_attr "fp_int_src" "true")])
5031
5032 (define_expand "floatsidf2"
5033 [(set (match_operand:DF 0 "register_operand" "")
5034 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
5035 "TARGET_80387 || TARGET_SSE2"
5036 "")
5037
5038 (define_insn "*floatsidf2_i387"
5039 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5040 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
5041 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5042 "@
5043 fild%z1\t%1
5044 #
5045 cvtsi2sd\t{%1, %0|%0, %1}
5046 cvtsi2sd\t{%1, %0|%0, %1}"
5047 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5048 (set_attr "mode" "DF")
5049 (set_attr "athlon_decode" "*,*,double,direct")
5050 (set_attr "fp_int_src" "true")])
5051
5052 (define_insn "*floatsidf2_sse"
5053 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5054 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
5055 "TARGET_SSE2"
5056 "cvtsi2sd\t{%1, %0|%0, %1}"
5057 [(set_attr "type" "sseicvt")
5058 (set_attr "mode" "DF")
5059 (set_attr "athlon_decode" "double,direct")
5060 (set_attr "fp_int_src" "true")])
5061
5062 (define_expand "floatdidf2"
5063 [(set (match_operand:DF 0 "register_operand" "")
5064 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5065 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5066 "")
5067
5068 (define_insn "*floatdidf2_i387_only"
5069 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5070 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5071 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5072 "@
5073 fild%z1\t%1
5074 #"
5075 [(set_attr "type" "fmov,multi")
5076 (set_attr "mode" "DF")
5077 (set_attr "fp_int_src" "true")])
5078
5079 (define_insn "*floatdidf2_i387"
5080 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5081 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
5082 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5083 "@
5084 fild%z1\t%1
5085 #
5086 cvtsi2sd{q}\t{%1, %0|%0, %1}
5087 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5088 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5089 (set_attr "mode" "DF")
5090 (set_attr "athlon_decode" "*,*,double,direct")
5091 (set_attr "fp_int_src" "true")])
5092
5093 (define_insn "*floatdidf2_sse"
5094 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5095 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
5096 "TARGET_SSE2"
5097 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5098 [(set_attr "type" "sseicvt")
5099 (set_attr "mode" "DF")
5100 (set_attr "athlon_decode" "double,direct")
5101 (set_attr "fp_int_src" "true")])
5102
5103 (define_insn "floathixf2"
5104 [(set (match_operand:XF 0 "register_operand" "=f,f")
5105 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5106 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5107 "@
5108 fild%z1\t%1
5109 #"
5110 [(set_attr "type" "fmov,multi")
5111 (set_attr "mode" "XF")
5112 (set_attr "fp_int_src" "true")])
5113
5114 (define_insn "floathitf2"
5115 [(set (match_operand:TF 0 "register_operand" "=f,f")
5116 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5117 "TARGET_80387"
5118 "@
5119 fild%z1\t%1
5120 #"
5121 [(set_attr "type" "fmov,multi")
5122 (set_attr "mode" "XF")
5123 (set_attr "fp_int_src" "true")])
5124
5125 (define_insn "floatsixf2"
5126 [(set (match_operand:XF 0 "register_operand" "=f,f")
5127 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5128 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5129 "@
5130 fild%z1\t%1
5131 #"
5132 [(set_attr "type" "fmov,multi")
5133 (set_attr "mode" "XF")
5134 (set_attr "fp_int_src" "true")])
5135
5136 (define_insn "floatsitf2"
5137 [(set (match_operand:TF 0 "register_operand" "=f,f")
5138 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5139 "TARGET_80387"
5140 "@
5141 fild%z1\t%1
5142 #"
5143 [(set_attr "type" "fmov,multi")
5144 (set_attr "mode" "XF")
5145 (set_attr "fp_int_src" "true")])
5146
5147 (define_insn "floatdixf2"
5148 [(set (match_operand:XF 0 "register_operand" "=f,f")
5149 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5150 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5151 "@
5152 fild%z1\t%1
5153 #"
5154 [(set_attr "type" "fmov,multi")
5155 (set_attr "mode" "XF")
5156 (set_attr "fp_int_src" "true")])
5157
5158 (define_insn "floatditf2"
5159 [(set (match_operand:TF 0 "register_operand" "=f,f")
5160 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5161 "TARGET_80387"
5162 "@
5163 fild%z1\t%1
5164 #"
5165 [(set_attr "type" "fmov,multi")
5166 (set_attr "mode" "XF")
5167 (set_attr "fp_int_src" "true")])
5168
5169 ;; %%% Kill these when reload knows how to do it.
5170 (define_split
5171 [(set (match_operand 0 "fp_register_operand" "")
5172 (float (match_operand 1 "register_operand" "")))]
5173 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5174 [(const_int 0)]
5175 {
5176 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5177 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5178 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5179 ix86_free_from_memory (GET_MODE (operands[1]));
5180 DONE;
5181 })
5182
5183 (define_expand "floatunssisf2"
5184 [(use (match_operand:SF 0 "register_operand" ""))
5185 (use (match_operand:SI 1 "register_operand" ""))]
5186 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
5187 "x86_emit_floatuns (operands); DONE;")
5188
5189 (define_expand "floatunsdisf2"
5190 [(use (match_operand:SF 0 "register_operand" ""))
5191 (use (match_operand:DI 1 "register_operand" ""))]
5192 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
5193 "x86_emit_floatuns (operands); DONE;")
5194
5195 (define_expand "floatunsdidf2"
5196 [(use (match_operand:DF 0 "register_operand" ""))
5197 (use (match_operand:DI 1 "register_operand" ""))]
5198 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
5199 "x86_emit_floatuns (operands); DONE;")
5200 \f
5201 ;; Add instructions
5202
5203 ;; %%% splits for addsidi3
5204 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5205 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5206 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5207
5208 (define_expand "adddi3"
5209 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5210 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5211 (match_operand:DI 2 "x86_64_general_operand" "")))
5212 (clobber (reg:CC 17))]
5213 ""
5214 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5215
5216 (define_insn "*adddi3_1"
5217 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5218 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5219 (match_operand:DI 2 "general_operand" "roiF,riF")))
5220 (clobber (reg:CC 17))]
5221 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5222 "#")
5223
5224 (define_split
5225 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5226 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5227 (match_operand:DI 2 "general_operand" "")))
5228 (clobber (reg:CC 17))]
5229 "!TARGET_64BIT && reload_completed"
5230 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
5231 UNSPEC_ADD_CARRY))
5232 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5233 (parallel [(set (match_dup 3)
5234 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5235 (match_dup 4))
5236 (match_dup 5)))
5237 (clobber (reg:CC 17))])]
5238 "split_di (operands+0, 1, operands+0, operands+3);
5239 split_di (operands+1, 1, operands+1, operands+4);
5240 split_di (operands+2, 1, operands+2, operands+5);")
5241
5242 (define_insn "adddi3_carry_rex64"
5243 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5244 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5245 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5246 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5247 (clobber (reg:CC 17))]
5248 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5249 "adc{q}\t{%2, %0|%0, %2}"
5250 [(set_attr "type" "alu")
5251 (set_attr "pent_pair" "pu")
5252 (set_attr "mode" "DI")
5253 (set_attr "ppro_uops" "few")])
5254
5255 (define_insn "*adddi3_cc_rex64"
5256 [(set (reg:CC 17)
5257 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5258 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5259 UNSPEC_ADD_CARRY))
5260 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5261 (plus:DI (match_dup 1) (match_dup 2)))]
5262 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5263 "add{q}\t{%2, %0|%0, %2}"
5264 [(set_attr "type" "alu")
5265 (set_attr "mode" "DI")])
5266
5267 (define_insn "addqi3_carry"
5268 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
5269 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5270 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5271 (match_operand:QI 2 "general_operand" "ri,rm")))
5272 (clobber (reg:CC 17))]
5273 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5274 "adc{b}\t{%2, %0|%0, %2}"
5275 [(set_attr "type" "alu")
5276 (set_attr "pent_pair" "pu")
5277 (set_attr "mode" "QI")
5278 (set_attr "ppro_uops" "few")])
5279
5280 (define_insn "addhi3_carry"
5281 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5282 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5283 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5284 (match_operand:HI 2 "general_operand" "ri,rm")))
5285 (clobber (reg:CC 17))]
5286 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5287 "adc{w}\t{%2, %0|%0, %2}"
5288 [(set_attr "type" "alu")
5289 (set_attr "pent_pair" "pu")
5290 (set_attr "mode" "HI")
5291 (set_attr "ppro_uops" "few")])
5292
5293 (define_insn "addsi3_carry"
5294 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5295 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5296 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5297 (match_operand:SI 2 "general_operand" "ri,rm")))
5298 (clobber (reg:CC 17))]
5299 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5300 "adc{l}\t{%2, %0|%0, %2}"
5301 [(set_attr "type" "alu")
5302 (set_attr "pent_pair" "pu")
5303 (set_attr "mode" "SI")
5304 (set_attr "ppro_uops" "few")])
5305
5306 (define_insn "*addsi3_carry_zext"
5307 [(set (match_operand:DI 0 "register_operand" "=r")
5308 (zero_extend:DI
5309 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5310 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5311 (match_operand:SI 2 "general_operand" "rim"))))
5312 (clobber (reg:CC 17))]
5313 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5314 "adc{l}\t{%2, %k0|%k0, %2}"
5315 [(set_attr "type" "alu")
5316 (set_attr "pent_pair" "pu")
5317 (set_attr "mode" "SI")
5318 (set_attr "ppro_uops" "few")])
5319
5320 (define_insn "*addsi3_cc"
5321 [(set (reg:CC 17)
5322 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5323 (match_operand:SI 2 "general_operand" "ri,rm")]
5324 UNSPEC_ADD_CARRY))
5325 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5326 (plus:SI (match_dup 1) (match_dup 2)))]
5327 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5328 "add{l}\t{%2, %0|%0, %2}"
5329 [(set_attr "type" "alu")
5330 (set_attr "mode" "SI")])
5331
5332 (define_insn "addqi3_cc"
5333 [(set (reg:CC 17)
5334 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5335 (match_operand:QI 2 "general_operand" "qi,qm")]
5336 UNSPEC_ADD_CARRY))
5337 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5338 (plus:QI (match_dup 1) (match_dup 2)))]
5339 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5340 "add{b}\t{%2, %0|%0, %2}"
5341 [(set_attr "type" "alu")
5342 (set_attr "mode" "QI")])
5343
5344 (define_expand "addsi3"
5345 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5346 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5347 (match_operand:SI 2 "general_operand" "")))
5348 (clobber (reg:CC 17))])]
5349 ""
5350 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5351
5352 (define_insn "*lea_1"
5353 [(set (match_operand:SI 0 "register_operand" "=r")
5354 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5355 "!TARGET_64BIT"
5356 "lea{l}\t{%a1, %0|%0, %a1}"
5357 [(set_attr "type" "lea")
5358 (set_attr "mode" "SI")])
5359
5360 (define_insn "*lea_1_rex64"
5361 [(set (match_operand:SI 0 "register_operand" "=r")
5362 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5363 "TARGET_64BIT"
5364 "lea{l}\t{%a1, %0|%0, %a1}"
5365 [(set_attr "type" "lea")
5366 (set_attr "mode" "SI")])
5367
5368 (define_insn "*lea_1_zext"
5369 [(set (match_operand:DI 0 "register_operand" "=r")
5370 (zero_extend:DI
5371 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5372 "TARGET_64BIT"
5373 "lea{l}\t{%a1, %k0|%k0, %a1}"
5374 [(set_attr "type" "lea")
5375 (set_attr "mode" "SI")])
5376
5377 (define_insn "*lea_2_rex64"
5378 [(set (match_operand:DI 0 "register_operand" "=r")
5379 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5380 "TARGET_64BIT"
5381 "lea{q}\t{%a1, %0|%0, %a1}"
5382 [(set_attr "type" "lea")
5383 (set_attr "mode" "DI")])
5384
5385 ;; The lea patterns for non-Pmodes needs to be matched by several
5386 ;; insns converted to real lea by splitters.
5387
5388 (define_insn_and_split "*lea_general_1"
5389 [(set (match_operand 0 "register_operand" "=r")
5390 (plus (plus (match_operand 1 "index_register_operand" "r")
5391 (match_operand 2 "register_operand" "r"))
5392 (match_operand 3 "immediate_operand" "i")))]
5393 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5394 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5395 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5396 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5397 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5398 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5399 || GET_MODE (operands[3]) == VOIDmode)"
5400 "#"
5401 "&& reload_completed"
5402 [(const_int 0)]
5403 {
5404 rtx pat;
5405 operands[0] = gen_lowpart (SImode, operands[0]);
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 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5410 operands[3]);
5411 if (Pmode != SImode)
5412 pat = gen_rtx_SUBREG (SImode, pat, 0);
5413 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5414 DONE;
5415 }
5416 [(set_attr "type" "lea")
5417 (set_attr "mode" "SI")])
5418
5419 (define_insn_and_split "*lea_general_1_zext"
5420 [(set (match_operand:DI 0 "register_operand" "=r")
5421 (zero_extend:DI
5422 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5423 (match_operand:SI 2 "register_operand" "r"))
5424 (match_operand:SI 3 "immediate_operand" "i"))))]
5425 "TARGET_64BIT"
5426 "#"
5427 "&& reload_completed"
5428 [(set (match_dup 0)
5429 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5430 (match_dup 2))
5431 (match_dup 3)) 0)))]
5432 {
5433 operands[1] = gen_lowpart (Pmode, operands[1]);
5434 operands[2] = gen_lowpart (Pmode, operands[2]);
5435 operands[3] = gen_lowpart (Pmode, operands[3]);
5436 }
5437 [(set_attr "type" "lea")
5438 (set_attr "mode" "SI")])
5439
5440 (define_insn_and_split "*lea_general_2"
5441 [(set (match_operand 0 "register_operand" "=r")
5442 (plus (mult (match_operand 1 "index_register_operand" "r")
5443 (match_operand 2 "const248_operand" "i"))
5444 (match_operand 3 "nonmemory_operand" "ri")))]
5445 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5446 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5447 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5448 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5449 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5450 || GET_MODE (operands[3]) == VOIDmode)"
5451 "#"
5452 "&& reload_completed"
5453 [(const_int 0)]
5454 {
5455 rtx pat;
5456 operands[0] = gen_lowpart (SImode, operands[0]);
5457 operands[1] = gen_lowpart (Pmode, operands[1]);
5458 operands[3] = gen_lowpart (Pmode, operands[3]);
5459 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5460 operands[3]);
5461 if (Pmode != SImode)
5462 pat = gen_rtx_SUBREG (SImode, pat, 0);
5463 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5464 DONE;
5465 }
5466 [(set_attr "type" "lea")
5467 (set_attr "mode" "SI")])
5468
5469 (define_insn_and_split "*lea_general_2_zext"
5470 [(set (match_operand:DI 0 "register_operand" "=r")
5471 (zero_extend:DI
5472 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5473 (match_operand:SI 2 "const248_operand" "n"))
5474 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5475 "TARGET_64BIT"
5476 "#"
5477 "&& reload_completed"
5478 [(set (match_dup 0)
5479 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5480 (match_dup 2))
5481 (match_dup 3)) 0)))]
5482 {
5483 operands[1] = gen_lowpart (Pmode, operands[1]);
5484 operands[3] = gen_lowpart (Pmode, operands[3]);
5485 }
5486 [(set_attr "type" "lea")
5487 (set_attr "mode" "SI")])
5488
5489 (define_insn_and_split "*lea_general_3"
5490 [(set (match_operand 0 "register_operand" "=r")
5491 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5492 (match_operand 2 "const248_operand" "i"))
5493 (match_operand 3 "register_operand" "r"))
5494 (match_operand 4 "immediate_operand" "i")))]
5495 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5496 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5497 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5498 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5499 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5500 "#"
5501 "&& reload_completed"
5502 [(const_int 0)]
5503 {
5504 rtx pat;
5505 operands[0] = gen_lowpart (SImode, operands[0]);
5506 operands[1] = gen_lowpart (Pmode, operands[1]);
5507 operands[3] = gen_lowpart (Pmode, operands[3]);
5508 operands[4] = gen_lowpart (Pmode, operands[4]);
5509 pat = gen_rtx_PLUS (Pmode,
5510 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5511 operands[2]),
5512 operands[3]),
5513 operands[4]);
5514 if (Pmode != SImode)
5515 pat = gen_rtx_SUBREG (SImode, pat, 0);
5516 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5517 DONE;
5518 }
5519 [(set_attr "type" "lea")
5520 (set_attr "mode" "SI")])
5521
5522 (define_insn_and_split "*lea_general_3_zext"
5523 [(set (match_operand:DI 0 "register_operand" "=r")
5524 (zero_extend:DI
5525 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5526 (match_operand:SI 2 "const248_operand" "n"))
5527 (match_operand:SI 3 "register_operand" "r"))
5528 (match_operand:SI 4 "immediate_operand" "i"))))]
5529 "TARGET_64BIT"
5530 "#"
5531 "&& reload_completed"
5532 [(set (match_dup 0)
5533 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5534 (match_dup 2))
5535 (match_dup 3))
5536 (match_dup 4)) 0)))]
5537 {
5538 operands[1] = gen_lowpart (Pmode, operands[1]);
5539 operands[3] = gen_lowpart (Pmode, operands[3]);
5540 operands[4] = gen_lowpart (Pmode, operands[4]);
5541 }
5542 [(set_attr "type" "lea")
5543 (set_attr "mode" "SI")])
5544
5545 (define_insn "*adddi_1_rex64"
5546 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5547 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5548 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5549 (clobber (reg:CC 17))]
5550 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5551 {
5552 switch (get_attr_type (insn))
5553 {
5554 case TYPE_LEA:
5555 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5556 return "lea{q}\t{%a2, %0|%0, %a2}";
5557
5558 case TYPE_INCDEC:
5559 if (! rtx_equal_p (operands[0], operands[1]))
5560 abort ();
5561 if (operands[2] == const1_rtx)
5562 return "inc{q}\t%0";
5563 else if (operands[2] == constm1_rtx)
5564 return "dec{q}\t%0";
5565 else
5566 abort ();
5567
5568 default:
5569 if (! rtx_equal_p (operands[0], operands[1]))
5570 abort ();
5571
5572 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5573 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5574 if (GET_CODE (operands[2]) == CONST_INT
5575 /* Avoid overflows. */
5576 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5577 && (INTVAL (operands[2]) == 128
5578 || (INTVAL (operands[2]) < 0
5579 && INTVAL (operands[2]) != -128)))
5580 {
5581 operands[2] = GEN_INT (-INTVAL (operands[2]));
5582 return "sub{q}\t{%2, %0|%0, %2}";
5583 }
5584 return "add{q}\t{%2, %0|%0, %2}";
5585 }
5586 }
5587 [(set (attr "type")
5588 (cond [(eq_attr "alternative" "2")
5589 (const_string "lea")
5590 ; Current assemblers are broken and do not allow @GOTOFF in
5591 ; ought but a memory context.
5592 (match_operand:DI 2 "pic_symbolic_operand" "")
5593 (const_string "lea")
5594 (match_operand:DI 2 "incdec_operand" "")
5595 (const_string "incdec")
5596 ]
5597 (const_string "alu")))
5598 (set_attr "mode" "DI")])
5599
5600 ;; Convert lea to the lea pattern to avoid flags dependency.
5601 (define_split
5602 [(set (match_operand:DI 0 "register_operand" "")
5603 (plus:DI (match_operand:DI 1 "register_operand" "")
5604 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5605 (clobber (reg:CC 17))]
5606 "TARGET_64BIT && reload_completed
5607 && true_regnum (operands[0]) != true_regnum (operands[1])"
5608 [(set (match_dup 0)
5609 (plus:DI (match_dup 1)
5610 (match_dup 2)))]
5611 "")
5612
5613 (define_insn "*adddi_2_rex64"
5614 [(set (reg 17)
5615 (compare
5616 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5617 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5618 (const_int 0)))
5619 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5620 (plus:DI (match_dup 1) (match_dup 2)))]
5621 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5622 && ix86_binary_operator_ok (PLUS, DImode, operands)
5623 /* Current assemblers are broken and do not allow @GOTOFF in
5624 ought but a memory context. */
5625 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5626 {
5627 switch (get_attr_type (insn))
5628 {
5629 case TYPE_INCDEC:
5630 if (! rtx_equal_p (operands[0], operands[1]))
5631 abort ();
5632 if (operands[2] == const1_rtx)
5633 return "inc{q}\t%0";
5634 else if (operands[2] == constm1_rtx)
5635 return "dec{q}\t%0";
5636 else
5637 abort ();
5638
5639 default:
5640 if (! rtx_equal_p (operands[0], operands[1]))
5641 abort ();
5642 /* ???? We ought to handle there the 32bit case too
5643 - do we need new constraint? */
5644 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5645 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5646 if (GET_CODE (operands[2]) == CONST_INT
5647 /* Avoid overflows. */
5648 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5649 && (INTVAL (operands[2]) == 128
5650 || (INTVAL (operands[2]) < 0
5651 && INTVAL (operands[2]) != -128)))
5652 {
5653 operands[2] = GEN_INT (-INTVAL (operands[2]));
5654 return "sub{q}\t{%2, %0|%0, %2}";
5655 }
5656 return "add{q}\t{%2, %0|%0, %2}";
5657 }
5658 }
5659 [(set (attr "type")
5660 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5661 (const_string "incdec")
5662 (const_string "alu")))
5663 (set_attr "mode" "DI")])
5664
5665 (define_insn "*adddi_3_rex64"
5666 [(set (reg 17)
5667 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5668 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5669 (clobber (match_scratch:DI 0 "=r"))]
5670 "TARGET_64BIT
5671 && ix86_match_ccmode (insn, CCZmode)
5672 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5673 /* Current assemblers are broken and do not allow @GOTOFF in
5674 ought but a memory context. */
5675 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5676 {
5677 switch (get_attr_type (insn))
5678 {
5679 case TYPE_INCDEC:
5680 if (! rtx_equal_p (operands[0], operands[1]))
5681 abort ();
5682 if (operands[2] == const1_rtx)
5683 return "inc{q}\t%0";
5684 else if (operands[2] == constm1_rtx)
5685 return "dec{q}\t%0";
5686 else
5687 abort ();
5688
5689 default:
5690 if (! rtx_equal_p (operands[0], operands[1]))
5691 abort ();
5692 /* ???? We ought to handle there the 32bit case too
5693 - do we need new constraint? */
5694 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5695 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5696 if (GET_CODE (operands[2]) == CONST_INT
5697 /* Avoid overflows. */
5698 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5699 && (INTVAL (operands[2]) == 128
5700 || (INTVAL (operands[2]) < 0
5701 && INTVAL (operands[2]) != -128)))
5702 {
5703 operands[2] = GEN_INT (-INTVAL (operands[2]));
5704 return "sub{q}\t{%2, %0|%0, %2}";
5705 }
5706 return "add{q}\t{%2, %0|%0, %2}";
5707 }
5708 }
5709 [(set (attr "type")
5710 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5711 (const_string "incdec")
5712 (const_string "alu")))
5713 (set_attr "mode" "DI")])
5714
5715 ; For comparisons against 1, -1 and 128, we may generate better code
5716 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5717 ; is matched then. We can't accept general immediate, because for
5718 ; case of overflows, the result is messed up.
5719 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5720 ; when negated.
5721 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5722 ; only for comparisons not depending on it.
5723 (define_insn "*adddi_4_rex64"
5724 [(set (reg 17)
5725 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5726 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5727 (clobber (match_scratch:DI 0 "=rm"))]
5728 "TARGET_64BIT
5729 && ix86_match_ccmode (insn, CCGCmode)"
5730 {
5731 switch (get_attr_type (insn))
5732 {
5733 case TYPE_INCDEC:
5734 if (operands[2] == constm1_rtx)
5735 return "inc{q}\t%0";
5736 else if (operands[2] == const1_rtx)
5737 return "dec{q}\t%0";
5738 else
5739 abort();
5740
5741 default:
5742 if (! rtx_equal_p (operands[0], operands[1]))
5743 abort ();
5744 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5745 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5746 if ((INTVAL (operands[2]) == -128
5747 || (INTVAL (operands[2]) > 0
5748 && INTVAL (operands[2]) != 128))
5749 /* Avoid overflows. */
5750 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5751 return "sub{q}\t{%2, %0|%0, %2}";
5752 operands[2] = GEN_INT (-INTVAL (operands[2]));
5753 return "add{q}\t{%2, %0|%0, %2}";
5754 }
5755 }
5756 [(set (attr "type")
5757 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5758 (const_string "incdec")
5759 (const_string "alu")))
5760 (set_attr "mode" "DI")])
5761
5762 (define_insn "*adddi_5_rex64"
5763 [(set (reg 17)
5764 (compare
5765 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5766 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5767 (const_int 0)))
5768 (clobber (match_scratch:DI 0 "=r"))]
5769 "TARGET_64BIT
5770 && ix86_match_ccmode (insn, CCGOCmode)
5771 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5772 /* Current assemblers are broken and do not allow @GOTOFF in
5773 ought but a memory context. */
5774 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5775 {
5776 switch (get_attr_type (insn))
5777 {
5778 case TYPE_INCDEC:
5779 if (! rtx_equal_p (operands[0], operands[1]))
5780 abort ();
5781 if (operands[2] == const1_rtx)
5782 return "inc{q}\t%0";
5783 else if (operands[2] == constm1_rtx)
5784 return "dec{q}\t%0";
5785 else
5786 abort();
5787
5788 default:
5789 if (! rtx_equal_p (operands[0], operands[1]))
5790 abort ();
5791 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5792 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5793 if (GET_CODE (operands[2]) == CONST_INT
5794 /* Avoid overflows. */
5795 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5796 && (INTVAL (operands[2]) == 128
5797 || (INTVAL (operands[2]) < 0
5798 && INTVAL (operands[2]) != -128)))
5799 {
5800 operands[2] = GEN_INT (-INTVAL (operands[2]));
5801 return "sub{q}\t{%2, %0|%0, %2}";
5802 }
5803 return "add{q}\t{%2, %0|%0, %2}";
5804 }
5805 }
5806 [(set (attr "type")
5807 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5808 (const_string "incdec")
5809 (const_string "alu")))
5810 (set_attr "mode" "DI")])
5811
5812
5813 (define_insn "*addsi_1"
5814 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5815 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5816 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5817 (clobber (reg:CC 17))]
5818 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5819 {
5820 switch (get_attr_type (insn))
5821 {
5822 case TYPE_LEA:
5823 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5824 return "lea{l}\t{%a2, %0|%0, %a2}";
5825
5826 case TYPE_INCDEC:
5827 if (! rtx_equal_p (operands[0], operands[1]))
5828 abort ();
5829 if (operands[2] == const1_rtx)
5830 return "inc{l}\t%0";
5831 else if (operands[2] == constm1_rtx)
5832 return "dec{l}\t%0";
5833 else
5834 abort();
5835
5836 default:
5837 if (! rtx_equal_p (operands[0], operands[1]))
5838 abort ();
5839
5840 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5842 if (GET_CODE (operands[2]) == CONST_INT
5843 && (INTVAL (operands[2]) == 128
5844 || (INTVAL (operands[2]) < 0
5845 && INTVAL (operands[2]) != -128)))
5846 {
5847 operands[2] = GEN_INT (-INTVAL (operands[2]));
5848 return "sub{l}\t{%2, %0|%0, %2}";
5849 }
5850 return "add{l}\t{%2, %0|%0, %2}";
5851 }
5852 }
5853 [(set (attr "type")
5854 (cond [(eq_attr "alternative" "2")
5855 (const_string "lea")
5856 ; Current assemblers are broken and do not allow @GOTOFF in
5857 ; ought but a memory context.
5858 (match_operand:SI 2 "pic_symbolic_operand" "")
5859 (const_string "lea")
5860 (match_operand:SI 2 "incdec_operand" "")
5861 (const_string "incdec")
5862 ]
5863 (const_string "alu")))
5864 (set_attr "mode" "SI")])
5865
5866 ;; Convert lea to the lea pattern to avoid flags dependency.
5867 (define_split
5868 [(set (match_operand 0 "register_operand" "")
5869 (plus (match_operand 1 "register_operand" "")
5870 (match_operand 2 "nonmemory_operand" "")))
5871 (clobber (reg:CC 17))]
5872 "reload_completed
5873 && true_regnum (operands[0]) != true_regnum (operands[1])"
5874 [(const_int 0)]
5875 {
5876 rtx pat;
5877 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5878 may confuse gen_lowpart. */
5879 if (GET_MODE (operands[0]) != Pmode)
5880 {
5881 operands[1] = gen_lowpart (Pmode, operands[1]);
5882 operands[2] = gen_lowpart (Pmode, operands[2]);
5883 }
5884 operands[0] = gen_lowpart (SImode, operands[0]);
5885 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5886 if (Pmode != SImode)
5887 pat = gen_rtx_SUBREG (SImode, pat, 0);
5888 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5889 DONE;
5890 })
5891
5892 ;; It may seem that nonimmediate operand is proper one for operand 1.
5893 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5894 ;; we take care in ix86_binary_operator_ok to not allow two memory
5895 ;; operands so proper swapping will be done in reload. This allow
5896 ;; patterns constructed from addsi_1 to match.
5897 (define_insn "addsi_1_zext"
5898 [(set (match_operand:DI 0 "register_operand" "=r,r")
5899 (zero_extend:DI
5900 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5901 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5902 (clobber (reg:CC 17))]
5903 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5904 {
5905 switch (get_attr_type (insn))
5906 {
5907 case TYPE_LEA:
5908 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5909 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5910
5911 case TYPE_INCDEC:
5912 if (operands[2] == const1_rtx)
5913 return "inc{l}\t%k0";
5914 else if (operands[2] == constm1_rtx)
5915 return "dec{l}\t%k0";
5916 else
5917 abort();
5918
5919 default:
5920 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5921 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5922 if (GET_CODE (operands[2]) == CONST_INT
5923 && (INTVAL (operands[2]) == 128
5924 || (INTVAL (operands[2]) < 0
5925 && INTVAL (operands[2]) != -128)))
5926 {
5927 operands[2] = GEN_INT (-INTVAL (operands[2]));
5928 return "sub{l}\t{%2, %k0|%k0, %2}";
5929 }
5930 return "add{l}\t{%2, %k0|%k0, %2}";
5931 }
5932 }
5933 [(set (attr "type")
5934 (cond [(eq_attr "alternative" "1")
5935 (const_string "lea")
5936 ; Current assemblers are broken and do not allow @GOTOFF in
5937 ; ought but a memory context.
5938 (match_operand:SI 2 "pic_symbolic_operand" "")
5939 (const_string "lea")
5940 (match_operand:SI 2 "incdec_operand" "")
5941 (const_string "incdec")
5942 ]
5943 (const_string "alu")))
5944 (set_attr "mode" "SI")])
5945
5946 ;; Convert lea to the lea pattern to avoid flags dependency.
5947 (define_split
5948 [(set (match_operand:DI 0 "register_operand" "")
5949 (zero_extend:DI
5950 (plus:SI (match_operand:SI 1 "register_operand" "")
5951 (match_operand:SI 2 "nonmemory_operand" ""))))
5952 (clobber (reg:CC 17))]
5953 "TARGET_64BIT && reload_completed
5954 && true_regnum (operands[0]) != true_regnum (operands[1])"
5955 [(set (match_dup 0)
5956 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5957 {
5958 operands[1] = gen_lowpart (Pmode, operands[1]);
5959 operands[2] = gen_lowpart (Pmode, operands[2]);
5960 })
5961
5962 (define_insn "*addsi_2"
5963 [(set (reg 17)
5964 (compare
5965 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5966 (match_operand:SI 2 "general_operand" "rmni,rni"))
5967 (const_int 0)))
5968 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5969 (plus:SI (match_dup 1) (match_dup 2)))]
5970 "ix86_match_ccmode (insn, CCGOCmode)
5971 && ix86_binary_operator_ok (PLUS, SImode, operands)
5972 /* Current assemblers are broken and do not allow @GOTOFF in
5973 ought but a memory context. */
5974 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5975 {
5976 switch (get_attr_type (insn))
5977 {
5978 case TYPE_INCDEC:
5979 if (! rtx_equal_p (operands[0], operands[1]))
5980 abort ();
5981 if (operands[2] == const1_rtx)
5982 return "inc{l}\t%0";
5983 else if (operands[2] == constm1_rtx)
5984 return "dec{l}\t%0";
5985 else
5986 abort();
5987
5988 default:
5989 if (! rtx_equal_p (operands[0], operands[1]))
5990 abort ();
5991 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5992 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5993 if (GET_CODE (operands[2]) == CONST_INT
5994 && (INTVAL (operands[2]) == 128
5995 || (INTVAL (operands[2]) < 0
5996 && INTVAL (operands[2]) != -128)))
5997 {
5998 operands[2] = GEN_INT (-INTVAL (operands[2]));
5999 return "sub{l}\t{%2, %0|%0, %2}";
6000 }
6001 return "add{l}\t{%2, %0|%0, %2}";
6002 }
6003 }
6004 [(set (attr "type")
6005 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6006 (const_string "incdec")
6007 (const_string "alu")))
6008 (set_attr "mode" "SI")])
6009
6010 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6011 (define_insn "*addsi_2_zext"
6012 [(set (reg 17)
6013 (compare
6014 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6015 (match_operand:SI 2 "general_operand" "rmni"))
6016 (const_int 0)))
6017 (set (match_operand:DI 0 "register_operand" "=r")
6018 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6019 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6020 && ix86_binary_operator_ok (PLUS, SImode, operands)
6021 /* Current assemblers are broken and do not allow @GOTOFF in
6022 ought but a memory context. */
6023 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6024 {
6025 switch (get_attr_type (insn))
6026 {
6027 case TYPE_INCDEC:
6028 if (operands[2] == const1_rtx)
6029 return "inc{l}\t%k0";
6030 else if (operands[2] == constm1_rtx)
6031 return "dec{l}\t%k0";
6032 else
6033 abort();
6034
6035 default:
6036 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6037 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6038 if (GET_CODE (operands[2]) == CONST_INT
6039 && (INTVAL (operands[2]) == 128
6040 || (INTVAL (operands[2]) < 0
6041 && INTVAL (operands[2]) != -128)))
6042 {
6043 operands[2] = GEN_INT (-INTVAL (operands[2]));
6044 return "sub{l}\t{%2, %k0|%k0, %2}";
6045 }
6046 return "add{l}\t{%2, %k0|%k0, %2}";
6047 }
6048 }
6049 [(set (attr "type")
6050 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6051 (const_string "incdec")
6052 (const_string "alu")))
6053 (set_attr "mode" "SI")])
6054
6055 (define_insn "*addsi_3"
6056 [(set (reg 17)
6057 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6058 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6059 (clobber (match_scratch:SI 0 "=r"))]
6060 "ix86_match_ccmode (insn, CCZmode)
6061 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6062 /* Current assemblers are broken and do not allow @GOTOFF in
6063 ought but a memory context. */
6064 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6065 {
6066 switch (get_attr_type (insn))
6067 {
6068 case TYPE_INCDEC:
6069 if (! rtx_equal_p (operands[0], operands[1]))
6070 abort ();
6071 if (operands[2] == const1_rtx)
6072 return "inc{l}\t%0";
6073 else if (operands[2] == constm1_rtx)
6074 return "dec{l}\t%0";
6075 else
6076 abort();
6077
6078 default:
6079 if (! rtx_equal_p (operands[0], operands[1]))
6080 abort ();
6081 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6082 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6083 if (GET_CODE (operands[2]) == CONST_INT
6084 && (INTVAL (operands[2]) == 128
6085 || (INTVAL (operands[2]) < 0
6086 && INTVAL (operands[2]) != -128)))
6087 {
6088 operands[2] = GEN_INT (-INTVAL (operands[2]));
6089 return "sub{l}\t{%2, %0|%0, %2}";
6090 }
6091 return "add{l}\t{%2, %0|%0, %2}";
6092 }
6093 }
6094 [(set (attr "type")
6095 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6096 (const_string "incdec")
6097 (const_string "alu")))
6098 (set_attr "mode" "SI")])
6099
6100 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6101 (define_insn "*addsi_3_zext"
6102 [(set (reg 17)
6103 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6104 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6105 (set (match_operand:DI 0 "register_operand" "=r")
6106 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6107 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6108 && ix86_binary_operator_ok (PLUS, SImode, operands)
6109 /* Current assemblers are broken and do not allow @GOTOFF in
6110 ought but a memory context. */
6111 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6112 {
6113 switch (get_attr_type (insn))
6114 {
6115 case TYPE_INCDEC:
6116 if (operands[2] == const1_rtx)
6117 return "inc{l}\t%k0";
6118 else if (operands[2] == constm1_rtx)
6119 return "dec{l}\t%k0";
6120 else
6121 abort();
6122
6123 default:
6124 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6125 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6126 if (GET_CODE (operands[2]) == CONST_INT
6127 && (INTVAL (operands[2]) == 128
6128 || (INTVAL (operands[2]) < 0
6129 && INTVAL (operands[2]) != -128)))
6130 {
6131 operands[2] = GEN_INT (-INTVAL (operands[2]));
6132 return "sub{l}\t{%2, %k0|%k0, %2}";
6133 }
6134 return "add{l}\t{%2, %k0|%k0, %2}";
6135 }
6136 }
6137 [(set (attr "type")
6138 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6139 (const_string "incdec")
6140 (const_string "alu")))
6141 (set_attr "mode" "SI")])
6142
6143 ; For comparisons against 1, -1 and 128, we may generate better code
6144 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6145 ; is matched then. We can't accept general immediate, because for
6146 ; case of overflows, the result is messed up.
6147 ; This pattern also don't hold of 0x80000000, since the value overflows
6148 ; when negated.
6149 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6150 ; only for comparisons not depending on it.
6151 (define_insn "*addsi_4"
6152 [(set (reg 17)
6153 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6154 (match_operand:SI 2 "const_int_operand" "n")))
6155 (clobber (match_scratch:SI 0 "=rm"))]
6156 "ix86_match_ccmode (insn, CCGCmode)
6157 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6158 {
6159 switch (get_attr_type (insn))
6160 {
6161 case TYPE_INCDEC:
6162 if (operands[2] == constm1_rtx)
6163 return "inc{l}\t%0";
6164 else if (operands[2] == const1_rtx)
6165 return "dec{l}\t%0";
6166 else
6167 abort();
6168
6169 default:
6170 if (! rtx_equal_p (operands[0], operands[1]))
6171 abort ();
6172 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6173 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6174 if ((INTVAL (operands[2]) == -128
6175 || (INTVAL (operands[2]) > 0
6176 && INTVAL (operands[2]) != 128)))
6177 return "sub{l}\t{%2, %0|%0, %2}";
6178 operands[2] = GEN_INT (-INTVAL (operands[2]));
6179 return "add{l}\t{%2, %0|%0, %2}";
6180 }
6181 }
6182 [(set (attr "type")
6183 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6184 (const_string "incdec")
6185 (const_string "alu")))
6186 (set_attr "mode" "SI")])
6187
6188 (define_insn "*addsi_5"
6189 [(set (reg 17)
6190 (compare
6191 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6192 (match_operand:SI 2 "general_operand" "rmni"))
6193 (const_int 0)))
6194 (clobber (match_scratch:SI 0 "=r"))]
6195 "ix86_match_ccmode (insn, CCGOCmode)
6196 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6197 /* Current assemblers are broken and do not allow @GOTOFF in
6198 ought but a memory context. */
6199 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6200 {
6201 switch (get_attr_type (insn))
6202 {
6203 case TYPE_INCDEC:
6204 if (! rtx_equal_p (operands[0], operands[1]))
6205 abort ();
6206 if (operands[2] == const1_rtx)
6207 return "inc{l}\t%0";
6208 else if (operands[2] == constm1_rtx)
6209 return "dec{l}\t%0";
6210 else
6211 abort();
6212
6213 default:
6214 if (! rtx_equal_p (operands[0], operands[1]))
6215 abort ();
6216 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6217 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6218 if (GET_CODE (operands[2]) == CONST_INT
6219 && (INTVAL (operands[2]) == 128
6220 || (INTVAL (operands[2]) < 0
6221 && INTVAL (operands[2]) != -128)))
6222 {
6223 operands[2] = GEN_INT (-INTVAL (operands[2]));
6224 return "sub{l}\t{%2, %0|%0, %2}";
6225 }
6226 return "add{l}\t{%2, %0|%0, %2}";
6227 }
6228 }
6229 [(set (attr "type")
6230 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6231 (const_string "incdec")
6232 (const_string "alu")))
6233 (set_attr "mode" "SI")])
6234
6235 (define_expand "addhi3"
6236 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6237 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6238 (match_operand:HI 2 "general_operand" "")))
6239 (clobber (reg:CC 17))])]
6240 "TARGET_HIMODE_MATH"
6241 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6242
6243 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6244 ;; type optimizations enabled by define-splits. This is not important
6245 ;; for PII, and in fact harmful because of partial register stalls.
6246
6247 (define_insn "*addhi_1_lea"
6248 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6249 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6250 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6251 (clobber (reg:CC 17))]
6252 "!TARGET_PARTIAL_REG_STALL
6253 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6254 {
6255 switch (get_attr_type (insn))
6256 {
6257 case TYPE_LEA:
6258 return "#";
6259 case TYPE_INCDEC:
6260 if (operands[2] == const1_rtx)
6261 return "inc{w}\t%0";
6262 else if (operands[2] == constm1_rtx)
6263 return "dec{w}\t%0";
6264 abort();
6265
6266 default:
6267 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6268 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6269 if (GET_CODE (operands[2]) == CONST_INT
6270 && (INTVAL (operands[2]) == 128
6271 || (INTVAL (operands[2]) < 0
6272 && INTVAL (operands[2]) != -128)))
6273 {
6274 operands[2] = GEN_INT (-INTVAL (operands[2]));
6275 return "sub{w}\t{%2, %0|%0, %2}";
6276 }
6277 return "add{w}\t{%2, %0|%0, %2}";
6278 }
6279 }
6280 [(set (attr "type")
6281 (if_then_else (eq_attr "alternative" "2")
6282 (const_string "lea")
6283 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6284 (const_string "incdec")
6285 (const_string "alu"))))
6286 (set_attr "mode" "HI,HI,SI")])
6287
6288 (define_insn "*addhi_1"
6289 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6290 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6291 (match_operand:HI 2 "general_operand" "ri,rm")))
6292 (clobber (reg:CC 17))]
6293 "TARGET_PARTIAL_REG_STALL
6294 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6295 {
6296 switch (get_attr_type (insn))
6297 {
6298 case TYPE_INCDEC:
6299 if (operands[2] == const1_rtx)
6300 return "inc{w}\t%0";
6301 else if (operands[2] == constm1_rtx)
6302 return "dec{w}\t%0";
6303 abort();
6304
6305 default:
6306 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6307 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6308 if (GET_CODE (operands[2]) == CONST_INT
6309 && (INTVAL (operands[2]) == 128
6310 || (INTVAL (operands[2]) < 0
6311 && INTVAL (operands[2]) != -128)))
6312 {
6313 operands[2] = GEN_INT (-INTVAL (operands[2]));
6314 return "sub{w}\t{%2, %0|%0, %2}";
6315 }
6316 return "add{w}\t{%2, %0|%0, %2}";
6317 }
6318 }
6319 [(set (attr "type")
6320 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6321 (const_string "incdec")
6322 (const_string "alu")))
6323 (set_attr "mode" "HI")])
6324
6325 (define_insn "*addhi_2"
6326 [(set (reg 17)
6327 (compare
6328 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6329 (match_operand:HI 2 "general_operand" "rmni,rni"))
6330 (const_int 0)))
6331 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6332 (plus:HI (match_dup 1) (match_dup 2)))]
6333 "ix86_match_ccmode (insn, CCGOCmode)
6334 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6335 {
6336 switch (get_attr_type (insn))
6337 {
6338 case TYPE_INCDEC:
6339 if (operands[2] == const1_rtx)
6340 return "inc{w}\t%0";
6341 else if (operands[2] == constm1_rtx)
6342 return "dec{w}\t%0";
6343 abort();
6344
6345 default:
6346 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6347 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6348 if (GET_CODE (operands[2]) == CONST_INT
6349 && (INTVAL (operands[2]) == 128
6350 || (INTVAL (operands[2]) < 0
6351 && INTVAL (operands[2]) != -128)))
6352 {
6353 operands[2] = GEN_INT (-INTVAL (operands[2]));
6354 return "sub{w}\t{%2, %0|%0, %2}";
6355 }
6356 return "add{w}\t{%2, %0|%0, %2}";
6357 }
6358 }
6359 [(set (attr "type")
6360 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6361 (const_string "incdec")
6362 (const_string "alu")))
6363 (set_attr "mode" "HI")])
6364
6365 (define_insn "*addhi_3"
6366 [(set (reg 17)
6367 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6368 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6369 (clobber (match_scratch:HI 0 "=r"))]
6370 "ix86_match_ccmode (insn, CCZmode)
6371 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6372 {
6373 switch (get_attr_type (insn))
6374 {
6375 case TYPE_INCDEC:
6376 if (operands[2] == const1_rtx)
6377 return "inc{w}\t%0";
6378 else if (operands[2] == constm1_rtx)
6379 return "dec{w}\t%0";
6380 abort();
6381
6382 default:
6383 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6384 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6385 if (GET_CODE (operands[2]) == CONST_INT
6386 && (INTVAL (operands[2]) == 128
6387 || (INTVAL (operands[2]) < 0
6388 && INTVAL (operands[2]) != -128)))
6389 {
6390 operands[2] = GEN_INT (-INTVAL (operands[2]));
6391 return "sub{w}\t{%2, %0|%0, %2}";
6392 }
6393 return "add{w}\t{%2, %0|%0, %2}";
6394 }
6395 }
6396 [(set (attr "type")
6397 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6398 (const_string "incdec")
6399 (const_string "alu")))
6400 (set_attr "mode" "HI")])
6401
6402 ; See comments above addsi_3_imm for details.
6403 (define_insn "*addhi_4"
6404 [(set (reg 17)
6405 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6406 (match_operand:HI 2 "const_int_operand" "n")))
6407 (clobber (match_scratch:HI 0 "=rm"))]
6408 "ix86_match_ccmode (insn, CCGCmode)
6409 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6410 {
6411 switch (get_attr_type (insn))
6412 {
6413 case TYPE_INCDEC:
6414 if (operands[2] == constm1_rtx)
6415 return "inc{w}\t%0";
6416 else if (operands[2] == const1_rtx)
6417 return "dec{w}\t%0";
6418 else
6419 abort();
6420
6421 default:
6422 if (! rtx_equal_p (operands[0], operands[1]))
6423 abort ();
6424 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6425 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6426 if ((INTVAL (operands[2]) == -128
6427 || (INTVAL (operands[2]) > 0
6428 && INTVAL (operands[2]) != 128)))
6429 return "sub{w}\t{%2, %0|%0, %2}";
6430 operands[2] = GEN_INT (-INTVAL (operands[2]));
6431 return "add{w}\t{%2, %0|%0, %2}";
6432 }
6433 }
6434 [(set (attr "type")
6435 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6436 (const_string "incdec")
6437 (const_string "alu")))
6438 (set_attr "mode" "SI")])
6439
6440
6441 (define_insn "*addhi_5"
6442 [(set (reg 17)
6443 (compare
6444 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6445 (match_operand:HI 2 "general_operand" "rmni"))
6446 (const_int 0)))
6447 (clobber (match_scratch:HI 0 "=r"))]
6448 "ix86_match_ccmode (insn, CCGOCmode)
6449 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6450 {
6451 switch (get_attr_type (insn))
6452 {
6453 case TYPE_INCDEC:
6454 if (operands[2] == const1_rtx)
6455 return "inc{w}\t%0";
6456 else if (operands[2] == constm1_rtx)
6457 return "dec{w}\t%0";
6458 abort();
6459
6460 default:
6461 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6462 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6463 if (GET_CODE (operands[2]) == CONST_INT
6464 && (INTVAL (operands[2]) == 128
6465 || (INTVAL (operands[2]) < 0
6466 && INTVAL (operands[2]) != -128)))
6467 {
6468 operands[2] = GEN_INT (-INTVAL (operands[2]));
6469 return "sub{w}\t{%2, %0|%0, %2}";
6470 }
6471 return "add{w}\t{%2, %0|%0, %2}";
6472 }
6473 }
6474 [(set (attr "type")
6475 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6476 (const_string "incdec")
6477 (const_string "alu")))
6478 (set_attr "mode" "HI")])
6479
6480 (define_expand "addqi3"
6481 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6482 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6483 (match_operand:QI 2 "general_operand" "")))
6484 (clobber (reg:CC 17))])]
6485 "TARGET_QIMODE_MATH"
6486 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6487
6488 ;; %%% Potential partial reg stall on alternative 2. What to do?
6489 (define_insn "*addqi_1_lea"
6490 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6491 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6492 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6493 (clobber (reg:CC 17))]
6494 "!TARGET_PARTIAL_REG_STALL
6495 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6496 {
6497 int widen = (which_alternative == 2);
6498 switch (get_attr_type (insn))
6499 {
6500 case TYPE_LEA:
6501 return "#";
6502 case TYPE_INCDEC:
6503 if (operands[2] == const1_rtx)
6504 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6505 else if (operands[2] == constm1_rtx)
6506 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6507 abort();
6508
6509 default:
6510 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6511 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6512 if (GET_CODE (operands[2]) == CONST_INT
6513 && (INTVAL (operands[2]) == 128
6514 || (INTVAL (operands[2]) < 0
6515 && INTVAL (operands[2]) != -128)))
6516 {
6517 operands[2] = GEN_INT (-INTVAL (operands[2]));
6518 if (widen)
6519 return "sub{l}\t{%2, %k0|%k0, %2}";
6520 else
6521 return "sub{b}\t{%2, %0|%0, %2}";
6522 }
6523 if (widen)
6524 return "add{l}\t{%k2, %k0|%k0, %k2}";
6525 else
6526 return "add{b}\t{%2, %0|%0, %2}";
6527 }
6528 }
6529 [(set (attr "type")
6530 (if_then_else (eq_attr "alternative" "3")
6531 (const_string "lea")
6532 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6533 (const_string "incdec")
6534 (const_string "alu"))))
6535 (set_attr "mode" "QI,QI,SI,SI")])
6536
6537 (define_insn "*addqi_1"
6538 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6539 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6540 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6541 (clobber (reg:CC 17))]
6542 "TARGET_PARTIAL_REG_STALL
6543 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6544 {
6545 int widen = (which_alternative == 2);
6546 switch (get_attr_type (insn))
6547 {
6548 case TYPE_INCDEC:
6549 if (operands[2] == const1_rtx)
6550 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6551 else if (operands[2] == constm1_rtx)
6552 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6553 abort();
6554
6555 default:
6556 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6557 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6558 if (GET_CODE (operands[2]) == CONST_INT
6559 && (INTVAL (operands[2]) == 128
6560 || (INTVAL (operands[2]) < 0
6561 && INTVAL (operands[2]) != -128)))
6562 {
6563 operands[2] = GEN_INT (-INTVAL (operands[2]));
6564 if (widen)
6565 return "sub{l}\t{%2, %k0|%k0, %2}";
6566 else
6567 return "sub{b}\t{%2, %0|%0, %2}";
6568 }
6569 if (widen)
6570 return "add{l}\t{%k2, %k0|%k0, %k2}";
6571 else
6572 return "add{b}\t{%2, %0|%0, %2}";
6573 }
6574 }
6575 [(set (attr "type")
6576 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6577 (const_string "incdec")
6578 (const_string "alu")))
6579 (set_attr "mode" "QI,QI,SI")])
6580
6581 (define_insn "*addqi_1_slp"
6582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6583 (plus:QI (match_dup 0)
6584 (match_operand:QI 1 "general_operand" "qn,qnm")))
6585 (clobber (reg:CC 17))]
6586 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6587 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6588 {
6589 switch (get_attr_type (insn))
6590 {
6591 case TYPE_INCDEC:
6592 if (operands[1] == const1_rtx)
6593 return "inc{b}\t%0";
6594 else if (operands[1] == constm1_rtx)
6595 return "dec{b}\t%0";
6596 abort();
6597
6598 default:
6599 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6600 if (GET_CODE (operands[1]) == CONST_INT
6601 && INTVAL (operands[1]) < 0)
6602 {
6603 operands[2] = GEN_INT (-INTVAL (operands[2]));
6604 return "sub{b}\t{%1, %0|%0, %1}";
6605 }
6606 return "add{b}\t{%1, %0|%0, %1}";
6607 }
6608 }
6609 [(set (attr "type")
6610 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6611 (const_string "incdec")
6612 (const_string "alu1")))
6613 (set_attr "mode" "QI")])
6614
6615 (define_insn "*addqi_2"
6616 [(set (reg 17)
6617 (compare
6618 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6619 (match_operand:QI 2 "general_operand" "qmni,qni"))
6620 (const_int 0)))
6621 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6622 (plus:QI (match_dup 1) (match_dup 2)))]
6623 "ix86_match_ccmode (insn, CCGOCmode)
6624 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6625 {
6626 switch (get_attr_type (insn))
6627 {
6628 case TYPE_INCDEC:
6629 if (operands[2] == const1_rtx)
6630 return "inc{b}\t%0";
6631 else if (operands[2] == constm1_rtx
6632 || (GET_CODE (operands[2]) == CONST_INT
6633 && INTVAL (operands[2]) == 255))
6634 return "dec{b}\t%0";
6635 abort();
6636
6637 default:
6638 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6639 if (GET_CODE (operands[2]) == CONST_INT
6640 && INTVAL (operands[2]) < 0)
6641 {
6642 operands[2] = GEN_INT (-INTVAL (operands[2]));
6643 return "sub{b}\t{%2, %0|%0, %2}";
6644 }
6645 return "add{b}\t{%2, %0|%0, %2}";
6646 }
6647 }
6648 [(set (attr "type")
6649 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6650 (const_string "incdec")
6651 (const_string "alu")))
6652 (set_attr "mode" "QI")])
6653
6654 (define_insn "*addqi_3"
6655 [(set (reg 17)
6656 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6657 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6658 (clobber (match_scratch:QI 0 "=q"))]
6659 "ix86_match_ccmode (insn, CCZmode)
6660 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6661 {
6662 switch (get_attr_type (insn))
6663 {
6664 case TYPE_INCDEC:
6665 if (operands[2] == const1_rtx)
6666 return "inc{b}\t%0";
6667 else if (operands[2] == constm1_rtx
6668 || (GET_CODE (operands[2]) == CONST_INT
6669 && INTVAL (operands[2]) == 255))
6670 return "dec{b}\t%0";
6671 abort();
6672
6673 default:
6674 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6675 if (GET_CODE (operands[2]) == CONST_INT
6676 && INTVAL (operands[2]) < 0)
6677 {
6678 operands[2] = GEN_INT (-INTVAL (operands[2]));
6679 return "sub{b}\t{%2, %0|%0, %2}";
6680 }
6681 return "add{b}\t{%2, %0|%0, %2}";
6682 }
6683 }
6684 [(set (attr "type")
6685 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6686 (const_string "incdec")
6687 (const_string "alu")))
6688 (set_attr "mode" "QI")])
6689
6690 ; See comments above addsi_3_imm for details.
6691 (define_insn "*addqi_4"
6692 [(set (reg 17)
6693 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6694 (match_operand:QI 2 "const_int_operand" "n")))
6695 (clobber (match_scratch:QI 0 "=qm"))]
6696 "ix86_match_ccmode (insn, CCGCmode)
6697 && (INTVAL (operands[2]) & 0xff) != 0x80"
6698 {
6699 switch (get_attr_type (insn))
6700 {
6701 case TYPE_INCDEC:
6702 if (operands[2] == constm1_rtx
6703 || (GET_CODE (operands[2]) == CONST_INT
6704 && INTVAL (operands[2]) == 255))
6705 return "inc{b}\t%0";
6706 else if (operands[2] == const1_rtx)
6707 return "dec{b}\t%0";
6708 else
6709 abort();
6710
6711 default:
6712 if (! rtx_equal_p (operands[0], operands[1]))
6713 abort ();
6714 if (INTVAL (operands[2]) < 0)
6715 {
6716 operands[2] = GEN_INT (-INTVAL (operands[2]));
6717 return "add{b}\t{%2, %0|%0, %2}";
6718 }
6719 return "sub{b}\t{%2, %0|%0, %2}";
6720 }
6721 }
6722 [(set (attr "type")
6723 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6724 (const_string "incdec")
6725 (const_string "alu")))
6726 (set_attr "mode" "QI")])
6727
6728
6729 (define_insn "*addqi_5"
6730 [(set (reg 17)
6731 (compare
6732 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6733 (match_operand:QI 2 "general_operand" "qmni"))
6734 (const_int 0)))
6735 (clobber (match_scratch:QI 0 "=q"))]
6736 "ix86_match_ccmode (insn, CCGOCmode)
6737 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6738 {
6739 switch (get_attr_type (insn))
6740 {
6741 case TYPE_INCDEC:
6742 if (operands[2] == const1_rtx)
6743 return "inc{b}\t%0";
6744 else if (operands[2] == constm1_rtx
6745 || (GET_CODE (operands[2]) == CONST_INT
6746 && INTVAL (operands[2]) == 255))
6747 return "dec{b}\t%0";
6748 abort();
6749
6750 default:
6751 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6752 if (GET_CODE (operands[2]) == CONST_INT
6753 && INTVAL (operands[2]) < 0)
6754 {
6755 operands[2] = GEN_INT (-INTVAL (operands[2]));
6756 return "sub{b}\t{%2, %0|%0, %2}";
6757 }
6758 return "add{b}\t{%2, %0|%0, %2}";
6759 }
6760 }
6761 [(set (attr "type")
6762 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6763 (const_string "incdec")
6764 (const_string "alu")))
6765 (set_attr "mode" "QI")])
6766
6767
6768 (define_insn "addqi_ext_1"
6769 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6770 (const_int 8)
6771 (const_int 8))
6772 (plus:SI
6773 (zero_extract:SI
6774 (match_operand 1 "ext_register_operand" "0")
6775 (const_int 8)
6776 (const_int 8))
6777 (match_operand:QI 2 "general_operand" "Qmn")))
6778 (clobber (reg:CC 17))]
6779 "!TARGET_64BIT"
6780 {
6781 switch (get_attr_type (insn))
6782 {
6783 case TYPE_INCDEC:
6784 if (operands[2] == const1_rtx)
6785 return "inc{b}\t%h0";
6786 else if (operands[2] == constm1_rtx
6787 || (GET_CODE (operands[2]) == CONST_INT
6788 && INTVAL (operands[2]) == 255))
6789 return "dec{b}\t%h0";
6790 abort();
6791
6792 default:
6793 return "add{b}\t{%2, %h0|%h0, %2}";
6794 }
6795 }
6796 [(set (attr "type")
6797 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6798 (const_string "incdec")
6799 (const_string "alu")))
6800 (set_attr "mode" "QI")])
6801
6802 (define_insn "*addqi_ext_1_rex64"
6803 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6804 (const_int 8)
6805 (const_int 8))
6806 (plus:SI
6807 (zero_extract:SI
6808 (match_operand 1 "ext_register_operand" "0")
6809 (const_int 8)
6810 (const_int 8))
6811 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6812 (clobber (reg:CC 17))]
6813 "TARGET_64BIT"
6814 {
6815 switch (get_attr_type (insn))
6816 {
6817 case TYPE_INCDEC:
6818 if (operands[2] == const1_rtx)
6819 return "inc{b}\t%h0";
6820 else if (operands[2] == constm1_rtx
6821 || (GET_CODE (operands[2]) == CONST_INT
6822 && INTVAL (operands[2]) == 255))
6823 return "dec{b}\t%h0";
6824 abort();
6825
6826 default:
6827 return "add{b}\t{%2, %h0|%h0, %2}";
6828 }
6829 }
6830 [(set (attr "type")
6831 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6832 (const_string "incdec")
6833 (const_string "alu")))
6834 (set_attr "mode" "QI")])
6835
6836 (define_insn "*addqi_ext_2"
6837 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6838 (const_int 8)
6839 (const_int 8))
6840 (plus:SI
6841 (zero_extract:SI
6842 (match_operand 1 "ext_register_operand" "%0")
6843 (const_int 8)
6844 (const_int 8))
6845 (zero_extract:SI
6846 (match_operand 2 "ext_register_operand" "Q")
6847 (const_int 8)
6848 (const_int 8))))
6849 (clobber (reg:CC 17))]
6850 ""
6851 "add{b}\t{%h2, %h0|%h0, %h2}"
6852 [(set_attr "type" "alu")
6853 (set_attr "mode" "QI")])
6854
6855 ;; The patterns that match these are at the end of this file.
6856
6857 (define_expand "addxf3"
6858 [(set (match_operand:XF 0 "register_operand" "")
6859 (plus:XF (match_operand:XF 1 "register_operand" "")
6860 (match_operand:XF 2 "register_operand" "")))]
6861 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
6862 "")
6863
6864 (define_expand "addtf3"
6865 [(set (match_operand:TF 0 "register_operand" "")
6866 (plus:TF (match_operand:TF 1 "register_operand" "")
6867 (match_operand:TF 2 "register_operand" "")))]
6868 "TARGET_80387"
6869 "")
6870
6871 (define_expand "adddf3"
6872 [(set (match_operand:DF 0 "register_operand" "")
6873 (plus:DF (match_operand:DF 1 "register_operand" "")
6874 (match_operand:DF 2 "nonimmediate_operand" "")))]
6875 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6876 "")
6877
6878 (define_expand "addsf3"
6879 [(set (match_operand:SF 0 "register_operand" "")
6880 (plus:SF (match_operand:SF 1 "register_operand" "")
6881 (match_operand:SF 2 "nonimmediate_operand" "")))]
6882 "TARGET_80387 || TARGET_SSE_MATH"
6883 "")
6884 \f
6885 ;; Subtract instructions
6886
6887 ;; %%% splits for subsidi3
6888
6889 (define_expand "subdi3"
6890 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6891 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6892 (match_operand:DI 2 "x86_64_general_operand" "")))
6893 (clobber (reg:CC 17))])]
6894 ""
6895 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6896
6897 (define_insn "*subdi3_1"
6898 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6899 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6900 (match_operand:DI 2 "general_operand" "roiF,riF")))
6901 (clobber (reg:CC 17))]
6902 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6903 "#")
6904
6905 (define_split
6906 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6907 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6908 (match_operand:DI 2 "general_operand" "")))
6909 (clobber (reg:CC 17))]
6910 "!TARGET_64BIT && reload_completed"
6911 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6912 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6913 (parallel [(set (match_dup 3)
6914 (minus:SI (match_dup 4)
6915 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6916 (match_dup 5))))
6917 (clobber (reg:CC 17))])]
6918 "split_di (operands+0, 1, operands+0, operands+3);
6919 split_di (operands+1, 1, operands+1, operands+4);
6920 split_di (operands+2, 1, operands+2, operands+5);")
6921
6922 (define_insn "subdi3_carry_rex64"
6923 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6924 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6925 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6926 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6927 (clobber (reg:CC 17))]
6928 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6929 "sbb{q}\t{%2, %0|%0, %2}"
6930 [(set_attr "type" "alu")
6931 (set_attr "pent_pair" "pu")
6932 (set_attr "ppro_uops" "few")
6933 (set_attr "mode" "DI")])
6934
6935 (define_insn "*subdi_1_rex64"
6936 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6937 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6938 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6939 (clobber (reg:CC 17))]
6940 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6941 "sub{q}\t{%2, %0|%0, %2}"
6942 [(set_attr "type" "alu")
6943 (set_attr "mode" "DI")])
6944
6945 (define_insn "*subdi_2_rex64"
6946 [(set (reg 17)
6947 (compare
6948 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6949 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6950 (const_int 0)))
6951 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6952 (minus:DI (match_dup 1) (match_dup 2)))]
6953 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6954 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6955 "sub{q}\t{%2, %0|%0, %2}"
6956 [(set_attr "type" "alu")
6957 (set_attr "mode" "DI")])
6958
6959 (define_insn "*subdi_3_rex63"
6960 [(set (reg 17)
6961 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6962 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6963 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6964 (minus:DI (match_dup 1) (match_dup 2)))]
6965 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6966 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6967 "sub{q}\t{%2, %0|%0, %2}"
6968 [(set_attr "type" "alu")
6969 (set_attr "mode" "DI")])
6970
6971 (define_insn "subqi3_carry"
6972 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
6973 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6974 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6975 (match_operand:QI 2 "general_operand" "ri,rm"))))
6976 (clobber (reg:CC 17))]
6977 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6978 "sbb{b}\t{%2, %0|%0, %2}"
6979 [(set_attr "type" "alu")
6980 (set_attr "pent_pair" "pu")
6981 (set_attr "ppro_uops" "few")
6982 (set_attr "mode" "QI")])
6983
6984 (define_insn "subhi3_carry"
6985 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6986 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6987 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6988 (match_operand:HI 2 "general_operand" "ri,rm"))))
6989 (clobber (reg:CC 17))]
6990 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6991 "sbb{w}\t{%2, %0|%0, %2}"
6992 [(set_attr "type" "alu")
6993 (set_attr "pent_pair" "pu")
6994 (set_attr "ppro_uops" "few")
6995 (set_attr "mode" "HI")])
6996
6997 (define_insn "subsi3_carry"
6998 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6999 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7000 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7001 (match_operand:SI 2 "general_operand" "ri,rm"))))
7002 (clobber (reg:CC 17))]
7003 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7004 "sbb{l}\t{%2, %0|%0, %2}"
7005 [(set_attr "type" "alu")
7006 (set_attr "pent_pair" "pu")
7007 (set_attr "ppro_uops" "few")
7008 (set_attr "mode" "SI")])
7009
7010 (define_insn "subsi3_carry_zext"
7011 [(set (match_operand:DI 0 "register_operand" "=rm,r")
7012 (zero_extend:DI
7013 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
7014 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7015 (match_operand:SI 2 "general_operand" "ri,rm")))))
7016 (clobber (reg:CC 17))]
7017 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7018 "sbb{l}\t{%2, %k0|%k0, %2}"
7019 [(set_attr "type" "alu")
7020 (set_attr "pent_pair" "pu")
7021 (set_attr "ppro_uops" "few")
7022 (set_attr "mode" "SI")])
7023
7024 (define_expand "subsi3"
7025 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7026 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7027 (match_operand:SI 2 "general_operand" "")))
7028 (clobber (reg:CC 17))])]
7029 ""
7030 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7031
7032 (define_insn "*subsi_1"
7033 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7034 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7035 (match_operand:SI 2 "general_operand" "ri,rm")))
7036 (clobber (reg:CC 17))]
7037 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7038 "sub{l}\t{%2, %0|%0, %2}"
7039 [(set_attr "type" "alu")
7040 (set_attr "mode" "SI")])
7041
7042 (define_insn "*subsi_1_zext"
7043 [(set (match_operand:DI 0 "register_operand" "=r")
7044 (zero_extend:DI
7045 (minus:SI (match_operand:SI 1 "register_operand" "0")
7046 (match_operand:SI 2 "general_operand" "rim"))))
7047 (clobber (reg:CC 17))]
7048 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7049 "sub{l}\t{%2, %k0|%k0, %2}"
7050 [(set_attr "type" "alu")
7051 (set_attr "mode" "SI")])
7052
7053 (define_insn "*subsi_2"
7054 [(set (reg 17)
7055 (compare
7056 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7057 (match_operand:SI 2 "general_operand" "ri,rm"))
7058 (const_int 0)))
7059 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7060 (minus:SI (match_dup 1) (match_dup 2)))]
7061 "ix86_match_ccmode (insn, CCGOCmode)
7062 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7063 "sub{l}\t{%2, %0|%0, %2}"
7064 [(set_attr "type" "alu")
7065 (set_attr "mode" "SI")])
7066
7067 (define_insn "*subsi_2_zext"
7068 [(set (reg 17)
7069 (compare
7070 (minus:SI (match_operand:SI 1 "register_operand" "0")
7071 (match_operand:SI 2 "general_operand" "rim"))
7072 (const_int 0)))
7073 (set (match_operand:DI 0 "register_operand" "=r")
7074 (zero_extend:DI
7075 (minus:SI (match_dup 1)
7076 (match_dup 2))))]
7077 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7078 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7079 "sub{l}\t{%2, %k0|%k0, %2}"
7080 [(set_attr "type" "alu")
7081 (set_attr "mode" "SI")])
7082
7083 (define_insn "*subsi_3"
7084 [(set (reg 17)
7085 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7086 (match_operand:SI 2 "general_operand" "ri,rm")))
7087 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7088 (minus:SI (match_dup 1) (match_dup 2)))]
7089 "ix86_match_ccmode (insn, CCmode)
7090 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7091 "sub{l}\t{%2, %0|%0, %2}"
7092 [(set_attr "type" "alu")
7093 (set_attr "mode" "SI")])
7094
7095 (define_insn "*subsi_3_zext"
7096 [(set (reg 17)
7097 (compare (match_operand:SI 1 "register_operand" "0")
7098 (match_operand:SI 2 "general_operand" "rim")))
7099 (set (match_operand:DI 0 "register_operand" "=r")
7100 (zero_extend:DI
7101 (minus:SI (match_dup 1)
7102 (match_dup 2))))]
7103 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7104 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7105 "sub{q}\t{%2, %0|%0, %2}"
7106 [(set_attr "type" "alu")
7107 (set_attr "mode" "DI")])
7108
7109 (define_expand "subhi3"
7110 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7111 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7112 (match_operand:HI 2 "general_operand" "")))
7113 (clobber (reg:CC 17))])]
7114 "TARGET_HIMODE_MATH"
7115 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7116
7117 (define_insn "*subhi_1"
7118 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7119 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7120 (match_operand:HI 2 "general_operand" "ri,rm")))
7121 (clobber (reg:CC 17))]
7122 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7123 "sub{w}\t{%2, %0|%0, %2}"
7124 [(set_attr "type" "alu")
7125 (set_attr "mode" "HI")])
7126
7127 (define_insn "*subhi_2"
7128 [(set (reg 17)
7129 (compare
7130 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7131 (match_operand:HI 2 "general_operand" "ri,rm"))
7132 (const_int 0)))
7133 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7134 (minus:HI (match_dup 1) (match_dup 2)))]
7135 "ix86_match_ccmode (insn, CCGOCmode)
7136 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7137 "sub{w}\t{%2, %0|%0, %2}"
7138 [(set_attr "type" "alu")
7139 (set_attr "mode" "HI")])
7140
7141 (define_insn "*subhi_3"
7142 [(set (reg 17)
7143 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7144 (match_operand:HI 2 "general_operand" "ri,rm")))
7145 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7146 (minus:HI (match_dup 1) (match_dup 2)))]
7147 "ix86_match_ccmode (insn, CCmode)
7148 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7149 "sub{w}\t{%2, %0|%0, %2}"
7150 [(set_attr "type" "alu")
7151 (set_attr "mode" "HI")])
7152
7153 (define_expand "subqi3"
7154 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7155 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7156 (match_operand:QI 2 "general_operand" "")))
7157 (clobber (reg:CC 17))])]
7158 "TARGET_QIMODE_MATH"
7159 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7160
7161 (define_insn "*subqi_1"
7162 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7163 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7164 (match_operand:QI 2 "general_operand" "qn,qmn")))
7165 (clobber (reg:CC 17))]
7166 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7167 "sub{b}\t{%2, %0|%0, %2}"
7168 [(set_attr "type" "alu")
7169 (set_attr "mode" "QI")])
7170
7171 (define_insn "*subqi_1_slp"
7172 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7173 (minus:QI (match_dup 0)
7174 (match_operand:QI 1 "general_operand" "qn,qmn")))
7175 (clobber (reg:CC 17))]
7176 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7177 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7178 "sub{b}\t{%1, %0|%0, %1}"
7179 [(set_attr "type" "alu1")
7180 (set_attr "mode" "QI")])
7181
7182 (define_insn "*subqi_2"
7183 [(set (reg 17)
7184 (compare
7185 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7186 (match_operand:QI 2 "general_operand" "qi,qm"))
7187 (const_int 0)))
7188 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7189 (minus:HI (match_dup 1) (match_dup 2)))]
7190 "ix86_match_ccmode (insn, CCGOCmode)
7191 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7192 "sub{b}\t{%2, %0|%0, %2}"
7193 [(set_attr "type" "alu")
7194 (set_attr "mode" "QI")])
7195
7196 (define_insn "*subqi_3"
7197 [(set (reg 17)
7198 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7199 (match_operand:QI 2 "general_operand" "qi,qm")))
7200 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7201 (minus:HI (match_dup 1) (match_dup 2)))]
7202 "ix86_match_ccmode (insn, CCmode)
7203 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7204 "sub{b}\t{%2, %0|%0, %2}"
7205 [(set_attr "type" "alu")
7206 (set_attr "mode" "QI")])
7207
7208 ;; The patterns that match these are at the end of this file.
7209
7210 (define_expand "subxf3"
7211 [(set (match_operand:XF 0 "register_operand" "")
7212 (minus:XF (match_operand:XF 1 "register_operand" "")
7213 (match_operand:XF 2 "register_operand" "")))]
7214 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7215 "")
7216
7217 (define_expand "subtf3"
7218 [(set (match_operand:TF 0 "register_operand" "")
7219 (minus:TF (match_operand:TF 1 "register_operand" "")
7220 (match_operand:TF 2 "register_operand" "")))]
7221 "TARGET_80387"
7222 "")
7223
7224 (define_expand "subdf3"
7225 [(set (match_operand:DF 0 "register_operand" "")
7226 (minus:DF (match_operand:DF 1 "register_operand" "")
7227 (match_operand:DF 2 "nonimmediate_operand" "")))]
7228 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7229 "")
7230
7231 (define_expand "subsf3"
7232 [(set (match_operand:SF 0 "register_operand" "")
7233 (minus:SF (match_operand:SF 1 "register_operand" "")
7234 (match_operand:SF 2 "nonimmediate_operand" "")))]
7235 "TARGET_80387 || TARGET_SSE_MATH"
7236 "")
7237 \f
7238 ;; Multiply instructions
7239
7240 (define_expand "muldi3"
7241 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7242 (mult:DI (match_operand:DI 1 "register_operand" "")
7243 (match_operand:DI 2 "x86_64_general_operand" "")))
7244 (clobber (reg:CC 17))])]
7245 "TARGET_64BIT"
7246 "")
7247
7248 (define_insn "*muldi3_1_rex64"
7249 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7250 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7251 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7252 (clobber (reg:CC 17))]
7253 "TARGET_64BIT
7254 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7255 "@
7256 imul{q}\t{%2, %1, %0|%0, %1, %2}
7257 imul{q}\t{%2, %1, %0|%0, %1, %2}
7258 imul{q}\t{%2, %0|%0, %2}"
7259 [(set_attr "type" "imul")
7260 (set_attr "prefix_0f" "0,0,1")
7261 (set (attr "athlon_decode")
7262 (cond [(eq_attr "cpu" "athlon")
7263 (const_string "vector")
7264 (eq_attr "alternative" "1")
7265 (const_string "vector")
7266 (and (eq_attr "alternative" "2")
7267 (match_operand 1 "memory_operand" ""))
7268 (const_string "vector")]
7269 (const_string "direct")))
7270 (set_attr "mode" "DI")])
7271
7272 (define_expand "mulsi3"
7273 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7274 (mult:SI (match_operand:SI 1 "register_operand" "")
7275 (match_operand:SI 2 "general_operand" "")))
7276 (clobber (reg:CC 17))])]
7277 ""
7278 "")
7279
7280 (define_insn "*mulsi3_1"
7281 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7282 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7283 (match_operand:SI 2 "general_operand" "K,i,mr")))
7284 (clobber (reg:CC 17))]
7285 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7286 "@
7287 imul{l}\t{%2, %1, %0|%0, %1, %2}
7288 imul{l}\t{%2, %1, %0|%0, %1, %2}
7289 imul{l}\t{%2, %0|%0, %2}"
7290 [(set_attr "type" "imul")
7291 (set_attr "prefix_0f" "0,0,1")
7292 (set (attr "athlon_decode")
7293 (cond [(eq_attr "cpu" "athlon")
7294 (const_string "vector")
7295 (eq_attr "alternative" "1")
7296 (const_string "vector")
7297 (and (eq_attr "alternative" "2")
7298 (match_operand 1 "memory_operand" ""))
7299 (const_string "vector")]
7300 (const_string "direct")))
7301 (set_attr "mode" "SI")])
7302
7303 (define_insn "*mulsi3_1_zext"
7304 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7305 (zero_extend:DI
7306 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7307 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7308 (clobber (reg:CC 17))]
7309 "TARGET_64BIT
7310 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7311 "@
7312 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7313 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7314 imul{l}\t{%2, %k0|%k0, %2}"
7315 [(set_attr "type" "imul")
7316 (set_attr "prefix_0f" "0,0,1")
7317 (set (attr "athlon_decode")
7318 (cond [(eq_attr "cpu" "athlon")
7319 (const_string "vector")
7320 (eq_attr "alternative" "1")
7321 (const_string "vector")
7322 (and (eq_attr "alternative" "2")
7323 (match_operand 1 "memory_operand" ""))
7324 (const_string "vector")]
7325 (const_string "direct")))
7326 (set_attr "mode" "SI")])
7327
7328 (define_expand "mulhi3"
7329 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7330 (mult:HI (match_operand:HI 1 "register_operand" "")
7331 (match_operand:HI 2 "general_operand" "")))
7332 (clobber (reg:CC 17))])]
7333 "TARGET_HIMODE_MATH"
7334 "")
7335
7336 (define_insn "*mulhi3_1"
7337 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7338 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7339 (match_operand:HI 2 "general_operand" "K,i,mr")))
7340 (clobber (reg:CC 17))]
7341 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7342 "@
7343 imul{w}\t{%2, %1, %0|%0, %1, %2}
7344 imul{w}\t{%2, %1, %0|%0, %1, %2}
7345 imul{w}\t{%2, %0|%0, %2}"
7346 [(set_attr "type" "imul")
7347 (set_attr "prefix_0f" "0,0,1")
7348 (set (attr "athlon_decode")
7349 (cond [(eq_attr "cpu" "athlon")
7350 (const_string "vector")
7351 (eq_attr "alternative" "1,2")
7352 (const_string "vector")]
7353 (const_string "direct")))
7354 (set_attr "mode" "HI")])
7355
7356 (define_expand "mulqi3"
7357 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7358 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7359 (match_operand:QI 2 "register_operand" "")))
7360 (clobber (reg:CC 17))])]
7361 "TARGET_QIMODE_MATH"
7362 "")
7363
7364 (define_insn "*mulqi3_1"
7365 [(set (match_operand:QI 0 "register_operand" "=a")
7366 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7367 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7368 (clobber (reg:CC 17))]
7369 "TARGET_QIMODE_MATH
7370 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7371 "mul{b}\t%2"
7372 [(set_attr "type" "imul")
7373 (set_attr "length_immediate" "0")
7374 (set (attr "athlon_decode")
7375 (if_then_else (eq_attr "cpu" "athlon")
7376 (const_string "vector")
7377 (const_string "direct")))
7378 (set_attr "mode" "QI")])
7379
7380 (define_expand "umulqihi3"
7381 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7382 (mult:HI (zero_extend:HI
7383 (match_operand:QI 1 "nonimmediate_operand" ""))
7384 (zero_extend:HI
7385 (match_operand:QI 2 "register_operand" ""))))
7386 (clobber (reg:CC 17))])]
7387 "TARGET_QIMODE_MATH"
7388 "")
7389
7390 (define_insn "*umulqihi3_1"
7391 [(set (match_operand:HI 0 "register_operand" "=a")
7392 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7393 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7394 (clobber (reg:CC 17))]
7395 "TARGET_QIMODE_MATH
7396 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7397 "mul{b}\t%2"
7398 [(set_attr "type" "imul")
7399 (set_attr "length_immediate" "0")
7400 (set (attr "athlon_decode")
7401 (if_then_else (eq_attr "cpu" "athlon")
7402 (const_string "vector")
7403 (const_string "direct")))
7404 (set_attr "mode" "QI")])
7405
7406 (define_expand "mulqihi3"
7407 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7408 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7409 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7410 (clobber (reg:CC 17))])]
7411 "TARGET_QIMODE_MATH"
7412 "")
7413
7414 (define_insn "*mulqihi3_insn"
7415 [(set (match_operand:HI 0 "register_operand" "=a")
7416 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7417 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7418 (clobber (reg:CC 17))]
7419 "TARGET_QIMODE_MATH
7420 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7421 "imul{b}\t%2"
7422 [(set_attr "type" "imul")
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 "direct")))
7428 (set_attr "mode" "QI")])
7429
7430 (define_expand "umulditi3"
7431 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7432 (mult:TI (zero_extend:TI
7433 (match_operand:DI 1 "nonimmediate_operand" ""))
7434 (zero_extend:TI
7435 (match_operand:DI 2 "register_operand" ""))))
7436 (clobber (reg:CC 17))])]
7437 "TARGET_64BIT"
7438 "")
7439
7440 (define_insn "*umulditi3_insn"
7441 [(set (match_operand:TI 0 "register_operand" "=A")
7442 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7443 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7444 (clobber (reg:CC 17))]
7445 "TARGET_64BIT
7446 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7447 "mul{q}\t%2"
7448 [(set_attr "type" "imul")
7449 (set_attr "ppro_uops" "few")
7450 (set_attr "length_immediate" "0")
7451 (set (attr "athlon_decode")
7452 (if_then_else (eq_attr "cpu" "athlon")
7453 (const_string "vector")
7454 (const_string "double")))
7455 (set_attr "mode" "DI")])
7456
7457 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7458 (define_expand "umulsidi3"
7459 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7460 (mult:DI (zero_extend:DI
7461 (match_operand:SI 1 "nonimmediate_operand" ""))
7462 (zero_extend:DI
7463 (match_operand:SI 2 "register_operand" ""))))
7464 (clobber (reg:CC 17))])]
7465 "!TARGET_64BIT"
7466 "")
7467
7468 (define_insn "*umulsidi3_insn"
7469 [(set (match_operand:DI 0 "register_operand" "=A")
7470 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7471 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7472 (clobber (reg:CC 17))]
7473 "!TARGET_64BIT
7474 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7475 "mul{l}\t%2"
7476 [(set_attr "type" "imul")
7477 (set_attr "ppro_uops" "few")
7478 (set_attr "length_immediate" "0")
7479 (set (attr "athlon_decode")
7480 (if_then_else (eq_attr "cpu" "athlon")
7481 (const_string "vector")
7482 (const_string "double")))
7483 (set_attr "mode" "SI")])
7484
7485 (define_expand "mulditi3"
7486 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7487 (mult:TI (sign_extend:TI
7488 (match_operand:DI 1 "nonimmediate_operand" ""))
7489 (sign_extend:TI
7490 (match_operand:DI 2 "register_operand" ""))))
7491 (clobber (reg:CC 17))])]
7492 "TARGET_64BIT"
7493 "")
7494
7495 (define_insn "*mulditi3_insn"
7496 [(set (match_operand:TI 0 "register_operand" "=A")
7497 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7498 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7499 (clobber (reg:CC 17))]
7500 "TARGET_64BIT
7501 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7502 "imul{q}\t%2"
7503 [(set_attr "type" "imul")
7504 (set_attr "length_immediate" "0")
7505 (set (attr "athlon_decode")
7506 (if_then_else (eq_attr "cpu" "athlon")
7507 (const_string "vector")
7508 (const_string "double")))
7509 (set_attr "mode" "DI")])
7510
7511 (define_expand "mulsidi3"
7512 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7513 (mult:DI (sign_extend:DI
7514 (match_operand:SI 1 "nonimmediate_operand" ""))
7515 (sign_extend:DI
7516 (match_operand:SI 2 "register_operand" ""))))
7517 (clobber (reg:CC 17))])]
7518 "!TARGET_64BIT"
7519 "")
7520
7521 (define_insn "*mulsidi3_insn"
7522 [(set (match_operand:DI 0 "register_operand" "=A")
7523 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7524 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7525 (clobber (reg:CC 17))]
7526 "!TARGET_64BIT
7527 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7528 "imul{l}\t%2"
7529 [(set_attr "type" "imul")
7530 (set_attr "length_immediate" "0")
7531 (set (attr "athlon_decode")
7532 (if_then_else (eq_attr "cpu" "athlon")
7533 (const_string "vector")
7534 (const_string "double")))
7535 (set_attr "mode" "SI")])
7536
7537 (define_expand "umuldi3_highpart"
7538 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7539 (truncate:DI
7540 (lshiftrt:TI
7541 (mult:TI (zero_extend:TI
7542 (match_operand:DI 1 "nonimmediate_operand" ""))
7543 (zero_extend:TI
7544 (match_operand:DI 2 "register_operand" "")))
7545 (const_int 64))))
7546 (clobber (match_scratch:DI 3 ""))
7547 (clobber (reg:CC 17))])]
7548 "TARGET_64BIT"
7549 "")
7550
7551 (define_insn "*umuldi3_highpart_rex64"
7552 [(set (match_operand:DI 0 "register_operand" "=d")
7553 (truncate:DI
7554 (lshiftrt:TI
7555 (mult:TI (zero_extend:TI
7556 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7557 (zero_extend:TI
7558 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7559 (const_int 64))))
7560 (clobber (match_scratch:DI 3 "=1"))
7561 (clobber (reg:CC 17))]
7562 "TARGET_64BIT
7563 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7564 "mul{q}\t%2"
7565 [(set_attr "type" "imul")
7566 (set_attr "ppro_uops" "few")
7567 (set_attr "length_immediate" "0")
7568 (set (attr "athlon_decode")
7569 (if_then_else (eq_attr "cpu" "athlon")
7570 (const_string "vector")
7571 (const_string "double")))
7572 (set_attr "mode" "DI")])
7573
7574 (define_expand "umulsi3_highpart"
7575 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7576 (truncate:SI
7577 (lshiftrt:DI
7578 (mult:DI (zero_extend:DI
7579 (match_operand:SI 1 "nonimmediate_operand" ""))
7580 (zero_extend:DI
7581 (match_operand:SI 2 "register_operand" "")))
7582 (const_int 32))))
7583 (clobber (match_scratch:SI 3 ""))
7584 (clobber (reg:CC 17))])]
7585 ""
7586 "")
7587
7588 (define_insn "*umulsi3_highpart_insn"
7589 [(set (match_operand:SI 0 "register_operand" "=d")
7590 (truncate:SI
7591 (lshiftrt:DI
7592 (mult:DI (zero_extend:DI
7593 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7594 (zero_extend:DI
7595 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7596 (const_int 32))))
7597 (clobber (match_scratch:SI 3 "=1"))
7598 (clobber (reg:CC 17))]
7599 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7600 "mul{l}\t%2"
7601 [(set_attr "type" "imul")
7602 (set_attr "ppro_uops" "few")
7603 (set_attr "length_immediate" "0")
7604 (set (attr "athlon_decode")
7605 (if_then_else (eq_attr "cpu" "athlon")
7606 (const_string "vector")
7607 (const_string "double")))
7608 (set_attr "mode" "SI")])
7609
7610 (define_insn "*umulsi3_highpart_zext"
7611 [(set (match_operand:DI 0 "register_operand" "=d")
7612 (zero_extend:DI (truncate:SI
7613 (lshiftrt:DI
7614 (mult:DI (zero_extend:DI
7615 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7616 (zero_extend:DI
7617 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7618 (const_int 32)))))
7619 (clobber (match_scratch:SI 3 "=1"))
7620 (clobber (reg:CC 17))]
7621 "TARGET_64BIT
7622 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7623 "mul{l}\t%2"
7624 [(set_attr "type" "imul")
7625 (set_attr "ppro_uops" "few")
7626 (set_attr "length_immediate" "0")
7627 (set (attr "athlon_decode")
7628 (if_then_else (eq_attr "cpu" "athlon")
7629 (const_string "vector")
7630 (const_string "double")))
7631 (set_attr "mode" "SI")])
7632
7633 (define_expand "smuldi3_highpart"
7634 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7635 (truncate:DI
7636 (lshiftrt:TI
7637 (mult:TI (sign_extend:TI
7638 (match_operand:DI 1 "nonimmediate_operand" ""))
7639 (sign_extend:TI
7640 (match_operand:DI 2 "register_operand" "")))
7641 (const_int 64))))
7642 (clobber (match_scratch:DI 3 ""))
7643 (clobber (reg:CC 17))])]
7644 "TARGET_64BIT"
7645 "")
7646
7647 (define_insn "*smuldi3_highpart_rex64"
7648 [(set (match_operand:DI 0 "register_operand" "=d")
7649 (truncate:DI
7650 (lshiftrt:TI
7651 (mult:TI (sign_extend:TI
7652 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7653 (sign_extend:TI
7654 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7655 (const_int 64))))
7656 (clobber (match_scratch:DI 3 "=1"))
7657 (clobber (reg:CC 17))]
7658 "TARGET_64BIT
7659 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7660 "imul{q}\t%2"
7661 [(set_attr "type" "imul")
7662 (set_attr "ppro_uops" "few")
7663 (set (attr "athlon_decode")
7664 (if_then_else (eq_attr "cpu" "athlon")
7665 (const_string "vector")
7666 (const_string "double")))
7667 (set_attr "mode" "DI")])
7668
7669 (define_expand "smulsi3_highpart"
7670 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7671 (truncate:SI
7672 (lshiftrt:DI
7673 (mult:DI (sign_extend:DI
7674 (match_operand:SI 1 "nonimmediate_operand" ""))
7675 (sign_extend:DI
7676 (match_operand:SI 2 "register_operand" "")))
7677 (const_int 32))))
7678 (clobber (match_scratch:SI 3 ""))
7679 (clobber (reg:CC 17))])]
7680 ""
7681 "")
7682
7683 (define_insn "*smulsi3_highpart_insn"
7684 [(set (match_operand:SI 0 "register_operand" "=d")
7685 (truncate:SI
7686 (lshiftrt:DI
7687 (mult:DI (sign_extend:DI
7688 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7689 (sign_extend:DI
7690 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7691 (const_int 32))))
7692 (clobber (match_scratch:SI 3 "=1"))
7693 (clobber (reg:CC 17))]
7694 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7695 "imul{l}\t%2"
7696 [(set_attr "type" "imul")
7697 (set_attr "ppro_uops" "few")
7698 (set (attr "athlon_decode")
7699 (if_then_else (eq_attr "cpu" "athlon")
7700 (const_string "vector")
7701 (const_string "double")))
7702 (set_attr "mode" "SI")])
7703
7704 (define_insn "*smulsi3_highpart_zext"
7705 [(set (match_operand:DI 0 "register_operand" "=d")
7706 (zero_extend:DI (truncate:SI
7707 (lshiftrt:DI
7708 (mult:DI (sign_extend:DI
7709 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7710 (sign_extend:DI
7711 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7712 (const_int 32)))))
7713 (clobber (match_scratch:SI 3 "=1"))
7714 (clobber (reg:CC 17))]
7715 "TARGET_64BIT
7716 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7717 "imul{l}\t%2"
7718 [(set_attr "type" "imul")
7719 (set_attr "ppro_uops" "few")
7720 (set (attr "athlon_decode")
7721 (if_then_else (eq_attr "cpu" "athlon")
7722 (const_string "vector")
7723 (const_string "double")))
7724 (set_attr "mode" "SI")])
7725
7726 ;; The patterns that match these are at the end of this file.
7727
7728 (define_expand "mulxf3"
7729 [(set (match_operand:XF 0 "register_operand" "")
7730 (mult:XF (match_operand:XF 1 "register_operand" "")
7731 (match_operand:XF 2 "register_operand" "")))]
7732 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7733 "")
7734
7735 (define_expand "multf3"
7736 [(set (match_operand:TF 0 "register_operand" "")
7737 (mult:TF (match_operand:TF 1 "register_operand" "")
7738 (match_operand:TF 2 "register_operand" "")))]
7739 "TARGET_80387"
7740 "")
7741
7742 (define_expand "muldf3"
7743 [(set (match_operand:DF 0 "register_operand" "")
7744 (mult:DF (match_operand:DF 1 "register_operand" "")
7745 (match_operand:DF 2 "nonimmediate_operand" "")))]
7746 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7747 "")
7748
7749 (define_expand "mulsf3"
7750 [(set (match_operand:SF 0 "register_operand" "")
7751 (mult:SF (match_operand:SF 1 "register_operand" "")
7752 (match_operand:SF 2 "nonimmediate_operand" "")))]
7753 "TARGET_80387 || TARGET_SSE_MATH"
7754 "")
7755 \f
7756 ;; Divide instructions
7757
7758 (define_insn "divqi3"
7759 [(set (match_operand:QI 0 "register_operand" "=a")
7760 (div:QI (match_operand:HI 1 "register_operand" "0")
7761 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7762 (clobber (reg:CC 17))]
7763 "TARGET_QIMODE_MATH"
7764 "idiv{b}\t%2"
7765 [(set_attr "type" "idiv")
7766 (set_attr "mode" "QI")
7767 (set_attr "ppro_uops" "few")])
7768
7769 (define_insn "udivqi3"
7770 [(set (match_operand:QI 0 "register_operand" "=a")
7771 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7772 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7773 (clobber (reg:CC 17))]
7774 "TARGET_QIMODE_MATH"
7775 "div{b}\t%2"
7776 [(set_attr "type" "idiv")
7777 (set_attr "mode" "QI")
7778 (set_attr "ppro_uops" "few")])
7779
7780 ;; The patterns that match these are at the end of this file.
7781
7782 (define_expand "divxf3"
7783 [(set (match_operand:XF 0 "register_operand" "")
7784 (div:XF (match_operand:XF 1 "register_operand" "")
7785 (match_operand:XF 2 "register_operand" "")))]
7786 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7787 "")
7788
7789 (define_expand "divtf3"
7790 [(set (match_operand:TF 0 "register_operand" "")
7791 (div:TF (match_operand:TF 1 "register_operand" "")
7792 (match_operand:TF 2 "register_operand" "")))]
7793 "TARGET_80387"
7794 "")
7795
7796 (define_expand "divdf3"
7797 [(set (match_operand:DF 0 "register_operand" "")
7798 (div:DF (match_operand:DF 1 "register_operand" "")
7799 (match_operand:DF 2 "nonimmediate_operand" "")))]
7800 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7801 "")
7802
7803 (define_expand "divsf3"
7804 [(set (match_operand:SF 0 "register_operand" "")
7805 (div:SF (match_operand:SF 1 "register_operand" "")
7806 (match_operand:SF 2 "nonimmediate_operand" "")))]
7807 "TARGET_80387 || TARGET_SSE_MATH"
7808 "")
7809 \f
7810 ;; Remainder instructions.
7811
7812 (define_expand "divmoddi4"
7813 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7814 (div:DI (match_operand:DI 1 "register_operand" "")
7815 (match_operand:DI 2 "nonimmediate_operand" "")))
7816 (set (match_operand:DI 3 "register_operand" "")
7817 (mod:DI (match_dup 1) (match_dup 2)))
7818 (clobber (reg:CC 17))])]
7819 "TARGET_64BIT"
7820 "")
7821
7822 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7823 ;; Penalize eax case slightly because it results in worse scheduling
7824 ;; of code.
7825 (define_insn "*divmoddi4_nocltd_rex64"
7826 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7827 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7828 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7829 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7830 (mod:DI (match_dup 2) (match_dup 3)))
7831 (clobber (reg:CC 17))]
7832 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7833 "#"
7834 [(set_attr "type" "multi")])
7835
7836 (define_insn "*divmoddi4_cltd_rex64"
7837 [(set (match_operand:DI 0 "register_operand" "=a")
7838 (div:DI (match_operand:DI 2 "register_operand" "a")
7839 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7840 (set (match_operand:DI 1 "register_operand" "=&d")
7841 (mod:DI (match_dup 2) (match_dup 3)))
7842 (clobber (reg:CC 17))]
7843 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7844 "#"
7845 [(set_attr "type" "multi")])
7846
7847 (define_insn "*divmoddi_noext_rex64"
7848 [(set (match_operand:DI 0 "register_operand" "=a")
7849 (div:DI (match_operand:DI 1 "register_operand" "0")
7850 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7851 (set (match_operand:DI 3 "register_operand" "=d")
7852 (mod:DI (match_dup 1) (match_dup 2)))
7853 (use (match_operand:DI 4 "register_operand" "3"))
7854 (clobber (reg:CC 17))]
7855 "TARGET_64BIT"
7856 "idiv{q}\t%2"
7857 [(set_attr "type" "idiv")
7858 (set_attr "mode" "DI")
7859 (set_attr "ppro_uops" "few")])
7860
7861 (define_split
7862 [(set (match_operand:DI 0 "register_operand" "")
7863 (div:DI (match_operand:DI 1 "register_operand" "")
7864 (match_operand:DI 2 "nonimmediate_operand" "")))
7865 (set (match_operand:DI 3 "register_operand" "")
7866 (mod:DI (match_dup 1) (match_dup 2)))
7867 (clobber (reg:CC 17))]
7868 "TARGET_64BIT && reload_completed"
7869 [(parallel [(set (match_dup 3)
7870 (ashiftrt:DI (match_dup 4) (const_int 63)))
7871 (clobber (reg:CC 17))])
7872 (parallel [(set (match_dup 0)
7873 (div:DI (reg:DI 0) (match_dup 2)))
7874 (set (match_dup 3)
7875 (mod:DI (reg:DI 0) (match_dup 2)))
7876 (use (match_dup 3))
7877 (clobber (reg:CC 17))])]
7878 {
7879 /* Avoid use of cltd in favor of a mov+shift. */
7880 if (!TARGET_USE_CLTD && !optimize_size)
7881 {
7882 if (true_regnum (operands[1]))
7883 emit_move_insn (operands[0], operands[1]);
7884 else
7885 emit_move_insn (operands[3], operands[1]);
7886 operands[4] = operands[3];
7887 }
7888 else
7889 {
7890 if (true_regnum (operands[1]))
7891 abort();
7892 operands[4] = operands[1];
7893 }
7894 })
7895
7896
7897 (define_expand "divmodsi4"
7898 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7899 (div:SI (match_operand:SI 1 "register_operand" "")
7900 (match_operand:SI 2 "nonimmediate_operand" "")))
7901 (set (match_operand:SI 3 "register_operand" "")
7902 (mod:SI (match_dup 1) (match_dup 2)))
7903 (clobber (reg:CC 17))])]
7904 ""
7905 "")
7906
7907 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7908 ;; Penalize eax case slightly because it results in worse scheduling
7909 ;; of code.
7910 (define_insn "*divmodsi4_nocltd"
7911 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7912 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7913 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7914 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7915 (mod:SI (match_dup 2) (match_dup 3)))
7916 (clobber (reg:CC 17))]
7917 "!optimize_size && !TARGET_USE_CLTD"
7918 "#"
7919 [(set_attr "type" "multi")])
7920
7921 (define_insn "*divmodsi4_cltd"
7922 [(set (match_operand:SI 0 "register_operand" "=a")
7923 (div:SI (match_operand:SI 2 "register_operand" "a")
7924 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7925 (set (match_operand:SI 1 "register_operand" "=&d")
7926 (mod:SI (match_dup 2) (match_dup 3)))
7927 (clobber (reg:CC 17))]
7928 "optimize_size || TARGET_USE_CLTD"
7929 "#"
7930 [(set_attr "type" "multi")])
7931
7932 (define_insn "*divmodsi_noext"
7933 [(set (match_operand:SI 0 "register_operand" "=a")
7934 (div:SI (match_operand:SI 1 "register_operand" "0")
7935 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7936 (set (match_operand:SI 3 "register_operand" "=d")
7937 (mod:SI (match_dup 1) (match_dup 2)))
7938 (use (match_operand:SI 4 "register_operand" "3"))
7939 (clobber (reg:CC 17))]
7940 ""
7941 "idiv{l}\t%2"
7942 [(set_attr "type" "idiv")
7943 (set_attr "mode" "SI")
7944 (set_attr "ppro_uops" "few")])
7945
7946 (define_split
7947 [(set (match_operand:SI 0 "register_operand" "")
7948 (div:SI (match_operand:SI 1 "register_operand" "")
7949 (match_operand:SI 2 "nonimmediate_operand" "")))
7950 (set (match_operand:SI 3 "register_operand" "")
7951 (mod:SI (match_dup 1) (match_dup 2)))
7952 (clobber (reg:CC 17))]
7953 "reload_completed"
7954 [(parallel [(set (match_dup 3)
7955 (ashiftrt:SI (match_dup 4) (const_int 31)))
7956 (clobber (reg:CC 17))])
7957 (parallel [(set (match_dup 0)
7958 (div:SI (reg:SI 0) (match_dup 2)))
7959 (set (match_dup 3)
7960 (mod:SI (reg:SI 0) (match_dup 2)))
7961 (use (match_dup 3))
7962 (clobber (reg:CC 17))])]
7963 {
7964 /* Avoid use of cltd in favor of a mov+shift. */
7965 if (!TARGET_USE_CLTD && !optimize_size)
7966 {
7967 if (true_regnum (operands[1]))
7968 emit_move_insn (operands[0], operands[1]);
7969 else
7970 emit_move_insn (operands[3], operands[1]);
7971 operands[4] = operands[3];
7972 }
7973 else
7974 {
7975 if (true_regnum (operands[1]))
7976 abort();
7977 operands[4] = operands[1];
7978 }
7979 })
7980 ;; %%% Split me.
7981 (define_insn "divmodhi4"
7982 [(set (match_operand:HI 0 "register_operand" "=a")
7983 (div:HI (match_operand:HI 1 "register_operand" "0")
7984 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7985 (set (match_operand:HI 3 "register_operand" "=&d")
7986 (mod:HI (match_dup 1) (match_dup 2)))
7987 (clobber (reg:CC 17))]
7988 "TARGET_HIMODE_MATH"
7989 "cwtd\;idiv{w}\t%2"
7990 [(set_attr "type" "multi")
7991 (set_attr "length_immediate" "0")
7992 (set_attr "mode" "SI")])
7993
7994 (define_insn "udivmoddi4"
7995 [(set (match_operand:DI 0 "register_operand" "=a")
7996 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7997 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7998 (set (match_operand:DI 3 "register_operand" "=&d")
7999 (umod:DI (match_dup 1) (match_dup 2)))
8000 (clobber (reg:CC 17))]
8001 "TARGET_64BIT"
8002 "xor{q}\t%3, %3\;div{q}\t%2"
8003 [(set_attr "type" "multi")
8004 (set_attr "length_immediate" "0")
8005 (set_attr "mode" "DI")])
8006
8007 (define_insn "*udivmoddi4_noext"
8008 [(set (match_operand:DI 0 "register_operand" "=a")
8009 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8010 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8011 (set (match_operand:DI 3 "register_operand" "=d")
8012 (umod:DI (match_dup 1) (match_dup 2)))
8013 (use (match_dup 3))
8014 (clobber (reg:CC 17))]
8015 "TARGET_64BIT"
8016 "div{q}\t%2"
8017 [(set_attr "type" "idiv")
8018 (set_attr "ppro_uops" "few")
8019 (set_attr "mode" "DI")])
8020
8021 (define_split
8022 [(set (match_operand:DI 0 "register_operand" "")
8023 (udiv:DI (match_operand:DI 1 "register_operand" "")
8024 (match_operand:DI 2 "nonimmediate_operand" "")))
8025 (set (match_operand:DI 3 "register_operand" "")
8026 (umod:DI (match_dup 1) (match_dup 2)))
8027 (clobber (reg:CC 17))]
8028 "TARGET_64BIT && reload_completed"
8029 [(set (match_dup 3) (const_int 0))
8030 (parallel [(set (match_dup 0)
8031 (udiv:DI (match_dup 1) (match_dup 2)))
8032 (set (match_dup 3)
8033 (umod:DI (match_dup 1) (match_dup 2)))
8034 (use (match_dup 3))
8035 (clobber (reg:CC 17))])]
8036 "")
8037
8038 (define_insn "udivmodsi4"
8039 [(set (match_operand:SI 0 "register_operand" "=a")
8040 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8041 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8042 (set (match_operand:SI 3 "register_operand" "=&d")
8043 (umod:SI (match_dup 1) (match_dup 2)))
8044 (clobber (reg:CC 17))]
8045 ""
8046 "xor{l}\t%3, %3\;div{l}\t%2"
8047 [(set_attr "type" "multi")
8048 (set_attr "length_immediate" "0")
8049 (set_attr "mode" "SI")])
8050
8051 (define_insn "*udivmodsi4_noext"
8052 [(set (match_operand:SI 0 "register_operand" "=a")
8053 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8054 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8055 (set (match_operand:SI 3 "register_operand" "=d")
8056 (umod:SI (match_dup 1) (match_dup 2)))
8057 (use (match_dup 3))
8058 (clobber (reg:CC 17))]
8059 ""
8060 "div{l}\t%2"
8061 [(set_attr "type" "idiv")
8062 (set_attr "ppro_uops" "few")
8063 (set_attr "mode" "SI")])
8064
8065 (define_split
8066 [(set (match_operand:SI 0 "register_operand" "")
8067 (udiv:SI (match_operand:SI 1 "register_operand" "")
8068 (match_operand:SI 2 "nonimmediate_operand" "")))
8069 (set (match_operand:SI 3 "register_operand" "")
8070 (umod:SI (match_dup 1) (match_dup 2)))
8071 (clobber (reg:CC 17))]
8072 "reload_completed"
8073 [(set (match_dup 3) (const_int 0))
8074 (parallel [(set (match_dup 0)
8075 (udiv:SI (match_dup 1) (match_dup 2)))
8076 (set (match_dup 3)
8077 (umod:SI (match_dup 1) (match_dup 2)))
8078 (use (match_dup 3))
8079 (clobber (reg:CC 17))])]
8080 "")
8081
8082 (define_expand "udivmodhi4"
8083 [(set (match_dup 4) (const_int 0))
8084 (parallel [(set (match_operand:HI 0 "register_operand" "")
8085 (udiv:HI (match_operand:HI 1 "register_operand" "")
8086 (match_operand:HI 2 "nonimmediate_operand" "")))
8087 (set (match_operand:HI 3 "register_operand" "")
8088 (umod:HI (match_dup 1) (match_dup 2)))
8089 (use (match_dup 4))
8090 (clobber (reg:CC 17))])]
8091 "TARGET_HIMODE_MATH"
8092 "operands[4] = gen_reg_rtx (HImode);")
8093
8094 (define_insn "*udivmodhi_noext"
8095 [(set (match_operand:HI 0 "register_operand" "=a")
8096 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8097 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8098 (set (match_operand:HI 3 "register_operand" "=d")
8099 (umod:HI (match_dup 1) (match_dup 2)))
8100 (use (match_operand:HI 4 "register_operand" "3"))
8101 (clobber (reg:CC 17))]
8102 ""
8103 "div{w}\t%2"
8104 [(set_attr "type" "idiv")
8105 (set_attr "mode" "HI")
8106 (set_attr "ppro_uops" "few")])
8107
8108 ;; We can not use div/idiv for double division, because it causes
8109 ;; "division by zero" on the overflow and that's not what we expect
8110 ;; from truncate. Because true (non truncating) double division is
8111 ;; never generated, we can't create this insn anyway.
8112 ;
8113 ;(define_insn ""
8114 ; [(set (match_operand:SI 0 "register_operand" "=a")
8115 ; (truncate:SI
8116 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8117 ; (zero_extend:DI
8118 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8119 ; (set (match_operand:SI 3 "register_operand" "=d")
8120 ; (truncate:SI
8121 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8122 ; (clobber (reg:CC 17))]
8123 ; ""
8124 ; "div{l}\t{%2, %0|%0, %2}"
8125 ; [(set_attr "type" "idiv")
8126 ; (set_attr "ppro_uops" "few")])
8127 \f
8128 ;;- Logical AND instructions
8129
8130 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8131 ;; Note that this excludes ah.
8132
8133 (define_insn "*testdi_1_rex64"
8134 [(set (reg 17)
8135 (compare
8136 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8137 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8138 (const_int 0)))]
8139 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8140 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8141 "@
8142 test{l}\t{%k1, %k0|%k0, %k1}
8143 test{l}\t{%k1, %k0|%k0, %k1}
8144 test{q}\t{%1, %0|%0, %1}
8145 test{q}\t{%1, %0|%0, %1}
8146 test{q}\t{%1, %0|%0, %1}"
8147 [(set_attr "type" "test")
8148 (set_attr "modrm" "0,1,0,1,1")
8149 (set_attr "mode" "SI,SI,DI,DI,DI")
8150 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8151
8152 (define_insn "testsi_1"
8153 [(set (reg 17)
8154 (compare
8155 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8156 (match_operand:SI 1 "general_operand" "in,in,rin"))
8157 (const_int 0)))]
8158 "ix86_match_ccmode (insn, CCNOmode)
8159 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8160 "test{l}\t{%1, %0|%0, %1}"
8161 [(set_attr "type" "test")
8162 (set_attr "modrm" "0,1,1")
8163 (set_attr "mode" "SI")
8164 (set_attr "pent_pair" "uv,np,uv")])
8165
8166 (define_expand "testsi_ccno_1"
8167 [(set (reg:CCNO 17)
8168 (compare:CCNO
8169 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8170 (match_operand:SI 1 "nonmemory_operand" ""))
8171 (const_int 0)))]
8172 ""
8173 "")
8174
8175 (define_insn "*testhi_1"
8176 [(set (reg 17)
8177 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8178 (match_operand:HI 1 "general_operand" "n,n,rn"))
8179 (const_int 0)))]
8180 "ix86_match_ccmode (insn, CCNOmode)
8181 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8182 "test{w}\t{%1, %0|%0, %1}"
8183 [(set_attr "type" "test")
8184 (set_attr "modrm" "0,1,1")
8185 (set_attr "mode" "HI")
8186 (set_attr "pent_pair" "uv,np,uv")])
8187
8188 (define_expand "testqi_ccz_1"
8189 [(set (reg:CCZ 17)
8190 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8191 (match_operand:QI 1 "nonmemory_operand" ""))
8192 (const_int 0)))]
8193 ""
8194 "")
8195
8196 (define_insn "*testqi_1"
8197 [(set (reg 17)
8198 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8199 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8200 (const_int 0)))]
8201 "ix86_match_ccmode (insn, CCNOmode)
8202 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8203 {
8204 if (which_alternative == 3)
8205 {
8206 if (GET_CODE (operands[1]) == CONST_INT
8207 && (INTVAL (operands[1]) & 0xffffff00))
8208 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8209 return "test{l}\t{%1, %k0|%k0, %1}";
8210 }
8211 return "test{b}\t{%1, %0|%0, %1}";
8212 }
8213 [(set_attr "type" "test")
8214 (set_attr "modrm" "0,1,1,1")
8215 (set_attr "mode" "QI,QI,QI,SI")
8216 (set_attr "pent_pair" "uv,np,uv,np")])
8217
8218 (define_expand "testqi_ext_ccno_0"
8219 [(set (reg:CCNO 17)
8220 (compare:CCNO
8221 (and:SI
8222 (zero_extract:SI
8223 (match_operand 0 "ext_register_operand" "")
8224 (const_int 8)
8225 (const_int 8))
8226 (match_operand 1 "const_int_operand" ""))
8227 (const_int 0)))]
8228 ""
8229 "")
8230
8231 (define_insn "*testqi_ext_0"
8232 [(set (reg 17)
8233 (compare
8234 (and:SI
8235 (zero_extract:SI
8236 (match_operand 0 "ext_register_operand" "Q")
8237 (const_int 8)
8238 (const_int 8))
8239 (match_operand 1 "const_int_operand" "n"))
8240 (const_int 0)))]
8241 "ix86_match_ccmode (insn, CCNOmode)"
8242 "test{b}\t{%1, %h0|%h0, %1}"
8243 [(set_attr "type" "test")
8244 (set_attr "mode" "QI")
8245 (set_attr "length_immediate" "1")
8246 (set_attr "pent_pair" "np")])
8247
8248 (define_insn "*testqi_ext_1"
8249 [(set (reg 17)
8250 (compare
8251 (and:SI
8252 (zero_extract:SI
8253 (match_operand 0 "ext_register_operand" "Q")
8254 (const_int 8)
8255 (const_int 8))
8256 (zero_extend:SI
8257 (match_operand:QI 1 "general_operand" "Qm")))
8258 (const_int 0)))]
8259 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8260 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8261 "test{b}\t{%1, %h0|%h0, %1}"
8262 [(set_attr "type" "test")
8263 (set_attr "mode" "QI")])
8264
8265 (define_insn "*testqi_ext_1_rex64"
8266 [(set (reg 17)
8267 (compare
8268 (and:SI
8269 (zero_extract:SI
8270 (match_operand 0 "ext_register_operand" "Q")
8271 (const_int 8)
8272 (const_int 8))
8273 (zero_extend:SI
8274 (match_operand:QI 1 "register_operand" "Q")))
8275 (const_int 0)))]
8276 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8277 "test{b}\t{%1, %h0|%h0, %1}"
8278 [(set_attr "type" "test")
8279 (set_attr "mode" "QI")])
8280
8281 (define_insn "*testqi_ext_2"
8282 [(set (reg 17)
8283 (compare
8284 (and:SI
8285 (zero_extract:SI
8286 (match_operand 0 "ext_register_operand" "Q")
8287 (const_int 8)
8288 (const_int 8))
8289 (zero_extract:SI
8290 (match_operand 1 "ext_register_operand" "Q")
8291 (const_int 8)
8292 (const_int 8)))
8293 (const_int 0)))]
8294 "ix86_match_ccmode (insn, CCNOmode)"
8295 "test{b}\t{%h1, %h0|%h0, %h1}"
8296 [(set_attr "type" "test")
8297 (set_attr "mode" "QI")])
8298
8299 ;; Combine likes to form bit extractions for some tests. Humor it.
8300 (define_insn "*testqi_ext_3"
8301 [(set (reg 17)
8302 (compare (zero_extract:SI
8303 (match_operand 0 "nonimmediate_operand" "rm")
8304 (match_operand:SI 1 "const_int_operand" "")
8305 (match_operand:SI 2 "const_int_operand" ""))
8306 (const_int 0)))]
8307 "ix86_match_ccmode (insn, CCNOmode)
8308 && (GET_MODE (operands[0]) == SImode
8309 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8310 || GET_MODE (operands[0]) == HImode
8311 || GET_MODE (operands[0]) == QImode)"
8312 "#")
8313
8314 (define_insn "*testqi_ext_3_rex64"
8315 [(set (reg 17)
8316 (compare (zero_extract:DI
8317 (match_operand 0 "nonimmediate_operand" "rm")
8318 (match_operand:DI 1 "const_int_operand" "")
8319 (match_operand:DI 2 "const_int_operand" ""))
8320 (const_int 0)))]
8321 "TARGET_64BIT
8322 && ix86_match_ccmode (insn, CCNOmode)
8323 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8324 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8325 /* Ensure that resulting mask is zero or sign extended operand. */
8326 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8327 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8328 && INTVAL (operands[1]) > 32))
8329 && (GET_MODE (operands[0]) == SImode
8330 || GET_MODE (operands[0]) == DImode
8331 || GET_MODE (operands[0]) == HImode
8332 || GET_MODE (operands[0]) == QImode)"
8333 "#")
8334
8335 (define_split
8336 [(set (reg 17)
8337 (compare (zero_extract
8338 (match_operand 0 "nonimmediate_operand" "")
8339 (match_operand 1 "const_int_operand" "")
8340 (match_operand 2 "const_int_operand" ""))
8341 (const_int 0)))]
8342 "ix86_match_ccmode (insn, CCNOmode)"
8343 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8344 {
8345 HOST_WIDE_INT len = INTVAL (operands[1]);
8346 HOST_WIDE_INT pos = INTVAL (operands[2]);
8347 HOST_WIDE_INT mask;
8348 enum machine_mode mode, submode;
8349
8350 mode = GET_MODE (operands[0]);
8351 if (GET_CODE (operands[0]) == MEM)
8352 {
8353 /* ??? Combine likes to put non-volatile mem extractions in QImode
8354 no matter the size of the test. So find a mode that works. */
8355 if (! MEM_VOLATILE_P (operands[0]))
8356 {
8357 mode = smallest_mode_for_size (pos + len, MODE_INT);
8358 operands[0] = adjust_address (operands[0], mode, 0);
8359 }
8360 }
8361 else if (GET_CODE (operands[0]) == SUBREG
8362 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8363 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8364 && pos + len <= GET_MODE_BITSIZE (submode))
8365 {
8366 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8367 mode = submode;
8368 operands[0] = SUBREG_REG (operands[0]);
8369 }
8370 else if (mode == HImode && pos + len <= 8)
8371 {
8372 /* Small HImode tests can be converted to QImode. */
8373 mode = QImode;
8374 operands[0] = gen_lowpart (QImode, operands[0]);
8375 }
8376
8377 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8378 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8379
8380 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8381 })
8382
8383 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8384 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8385 ;; this is relatively important trick.
8386 ;; Do the conversion only post-reload to avoid limiting of the register class
8387 ;; to QI regs.
8388 (define_split
8389 [(set (reg 17)
8390 (compare
8391 (and (match_operand 0 "register_operand" "")
8392 (match_operand 1 "const_int_operand" ""))
8393 (const_int 0)))]
8394 "reload_completed
8395 && QI_REG_P (operands[0])
8396 && ((ix86_match_ccmode (insn, CCZmode)
8397 && !(INTVAL (operands[1]) & ~(255 << 8)))
8398 || (ix86_match_ccmode (insn, CCNOmode)
8399 && !(INTVAL (operands[1]) & ~(127 << 8))))
8400 && GET_MODE (operands[0]) != QImode"
8401 [(set (reg:CCNO 17)
8402 (compare:CCNO
8403 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8404 (match_dup 1))
8405 (const_int 0)))]
8406 "operands[0] = gen_lowpart (SImode, operands[0]);
8407 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8408
8409 (define_split
8410 [(set (reg 17)
8411 (compare
8412 (and (match_operand 0 "nonimmediate_operand" "")
8413 (match_operand 1 "const_int_operand" ""))
8414 (const_int 0)))]
8415 "reload_completed
8416 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8417 && ((ix86_match_ccmode (insn, CCZmode)
8418 && !(INTVAL (operands[1]) & ~255))
8419 || (ix86_match_ccmode (insn, CCNOmode)
8420 && !(INTVAL (operands[1]) & ~127)))
8421 && GET_MODE (operands[0]) != QImode"
8422 [(set (reg:CCNO 17)
8423 (compare:CCNO
8424 (and:QI (match_dup 0)
8425 (match_dup 1))
8426 (const_int 0)))]
8427 "operands[0] = gen_lowpart (QImode, operands[0]);
8428 operands[1] = gen_lowpart (QImode, operands[1]);")
8429
8430
8431 ;; %%% This used to optimize known byte-wide and operations to memory,
8432 ;; and sometimes to QImode registers. If this is considered useful,
8433 ;; it should be done with splitters.
8434
8435 (define_expand "anddi3"
8436 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8437 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8438 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8439 (clobber (reg:CC 17))]
8440 "TARGET_64BIT"
8441 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8442
8443 (define_insn "*anddi_1_rex64"
8444 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8445 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8446 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8447 (clobber (reg:CC 17))]
8448 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8449 {
8450 switch (get_attr_type (insn))
8451 {
8452 case TYPE_IMOVX:
8453 {
8454 enum machine_mode mode;
8455
8456 if (GET_CODE (operands[2]) != CONST_INT)
8457 abort ();
8458 if (INTVAL (operands[2]) == 0xff)
8459 mode = QImode;
8460 else if (INTVAL (operands[2]) == 0xffff)
8461 mode = HImode;
8462 else
8463 abort ();
8464
8465 operands[1] = gen_lowpart (mode, operands[1]);
8466 if (mode == QImode)
8467 return "movz{bq|x}\t{%1,%0|%0, %1}";
8468 else
8469 return "movz{wq|x}\t{%1,%0|%0, %1}";
8470 }
8471
8472 default:
8473 if (! rtx_equal_p (operands[0], operands[1]))
8474 abort ();
8475 if (get_attr_mode (insn) == MODE_SI)
8476 return "and{l}\t{%k2, %k0|%k0, %k2}";
8477 else
8478 return "and{q}\t{%2, %0|%0, %2}";
8479 }
8480 }
8481 [(set_attr "type" "alu,alu,alu,imovx")
8482 (set_attr "length_immediate" "*,*,*,0")
8483 (set_attr "mode" "SI,DI,DI,DI")])
8484
8485 (define_insn "*anddi_2"
8486 [(set (reg 17)
8487 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8488 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8489 (const_int 0)))
8490 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8491 (and:DI (match_dup 1) (match_dup 2)))]
8492 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8493 && ix86_binary_operator_ok (AND, DImode, operands)"
8494 "@
8495 and{l}\t{%k2, %k0|%k0, %k2}
8496 and{q}\t{%2, %0|%0, %2}
8497 and{q}\t{%2, %0|%0, %2}"
8498 [(set_attr "type" "alu")
8499 (set_attr "mode" "SI,DI,DI")])
8500
8501 (define_expand "andsi3"
8502 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8503 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8504 (match_operand:SI 2 "general_operand" "")))
8505 (clobber (reg:CC 17))]
8506 ""
8507 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8508
8509 (define_insn "*andsi_1"
8510 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8511 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8512 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8513 (clobber (reg:CC 17))]
8514 "ix86_binary_operator_ok (AND, SImode, operands)"
8515 {
8516 switch (get_attr_type (insn))
8517 {
8518 case TYPE_IMOVX:
8519 {
8520 enum machine_mode mode;
8521
8522 if (GET_CODE (operands[2]) != CONST_INT)
8523 abort ();
8524 if (INTVAL (operands[2]) == 0xff)
8525 mode = QImode;
8526 else if (INTVAL (operands[2]) == 0xffff)
8527 mode = HImode;
8528 else
8529 abort ();
8530
8531 operands[1] = gen_lowpart (mode, operands[1]);
8532 if (mode == QImode)
8533 return "movz{bl|x}\t{%1,%0|%0, %1}";
8534 else
8535 return "movz{wl|x}\t{%1,%0|%0, %1}";
8536 }
8537
8538 default:
8539 if (! rtx_equal_p (operands[0], operands[1]))
8540 abort ();
8541 return "and{l}\t{%2, %0|%0, %2}";
8542 }
8543 }
8544 [(set_attr "type" "alu,alu,imovx")
8545 (set_attr "length_immediate" "*,*,0")
8546 (set_attr "mode" "SI")])
8547
8548 (define_split
8549 [(set (match_operand 0 "register_operand" "")
8550 (and (match_dup 0)
8551 (const_int -65536)))
8552 (clobber (reg:CC 17))]
8553 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8554 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8555 "operands[1] = gen_lowpart (HImode, operands[0]);")
8556
8557 (define_split
8558 [(set (match_operand 0 "ext_register_operand" "")
8559 (and (match_dup 0)
8560 (const_int -256)))
8561 (clobber (reg:CC 17))]
8562 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8563 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8564 "operands[1] = gen_lowpart (QImode, operands[0]);")
8565
8566 (define_split
8567 [(set (match_operand 0 "ext_register_operand" "")
8568 (and (match_dup 0)
8569 (const_int -65281)))
8570 (clobber (reg:CC 17))]
8571 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8572 [(parallel [(set (zero_extract:SI (match_dup 0)
8573 (const_int 8)
8574 (const_int 8))
8575 (xor:SI
8576 (zero_extract:SI (match_dup 0)
8577 (const_int 8)
8578 (const_int 8))
8579 (zero_extract:SI (match_dup 0)
8580 (const_int 8)
8581 (const_int 8))))
8582 (clobber (reg:CC 17))])]
8583 "operands[0] = gen_lowpart (SImode, operands[0]);")
8584
8585 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8586 (define_insn "*andsi_1_zext"
8587 [(set (match_operand:DI 0 "register_operand" "=r")
8588 (zero_extend:DI
8589 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8590 (match_operand:SI 2 "general_operand" "rim"))))
8591 (clobber (reg:CC 17))]
8592 "TARGET_64BIT && 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_insn "*andsi_2"
8598 [(set (reg 17)
8599 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8600 (match_operand:SI 2 "general_operand" "rim,ri"))
8601 (const_int 0)))
8602 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8603 (and:SI (match_dup 1) (match_dup 2)))]
8604 "ix86_match_ccmode (insn, CCNOmode)
8605 && ix86_binary_operator_ok (AND, SImode, operands)"
8606 "and{l}\t{%2, %0|%0, %2}"
8607 [(set_attr "type" "alu")
8608 (set_attr "mode" "SI")])
8609
8610 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8611 (define_insn "*andsi_2_zext"
8612 [(set (reg 17)
8613 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8614 (match_operand:SI 2 "general_operand" "rim"))
8615 (const_int 0)))
8616 (set (match_operand:DI 0 "register_operand" "=r")
8617 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8618 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8619 && ix86_binary_operator_ok (AND, SImode, operands)"
8620 "and{l}\t{%2, %k0|%k0, %2}"
8621 [(set_attr "type" "alu")
8622 (set_attr "mode" "SI")])
8623
8624 (define_expand "andhi3"
8625 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8626 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8627 (match_operand:HI 2 "general_operand" "")))
8628 (clobber (reg:CC 17))]
8629 "TARGET_HIMODE_MATH"
8630 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8631
8632 (define_insn "*andhi_1"
8633 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8634 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8635 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8636 (clobber (reg:CC 17))]
8637 "ix86_binary_operator_ok (AND, HImode, operands)"
8638 {
8639 switch (get_attr_type (insn))
8640 {
8641 case TYPE_IMOVX:
8642 if (GET_CODE (operands[2]) != CONST_INT)
8643 abort ();
8644 if (INTVAL (operands[2]) == 0xff)
8645 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8646 abort ();
8647
8648 default:
8649 if (! rtx_equal_p (operands[0], operands[1]))
8650 abort ();
8651
8652 return "and{w}\t{%2, %0|%0, %2}";
8653 }
8654 }
8655 [(set_attr "type" "alu,alu,imovx")
8656 (set_attr "length_immediate" "*,*,0")
8657 (set_attr "mode" "HI,HI,SI")])
8658
8659 (define_insn "*andhi_2"
8660 [(set (reg 17)
8661 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8662 (match_operand:HI 2 "general_operand" "rim,ri"))
8663 (const_int 0)))
8664 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8665 (and:HI (match_dup 1) (match_dup 2)))]
8666 "ix86_match_ccmode (insn, CCNOmode)
8667 && ix86_binary_operator_ok (AND, HImode, operands)"
8668 "and{w}\t{%2, %0|%0, %2}"
8669 [(set_attr "type" "alu")
8670 (set_attr "mode" "HI")])
8671
8672 (define_expand "andqi3"
8673 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8674 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8675 (match_operand:QI 2 "general_operand" "")))
8676 (clobber (reg:CC 17))]
8677 "TARGET_QIMODE_MATH"
8678 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8679
8680 ;; %%% Potential partial reg stall on alternative 2. What to do?
8681 (define_insn "*andqi_1"
8682 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8683 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8684 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8685 (clobber (reg:CC 17))]
8686 "ix86_binary_operator_ok (AND, QImode, operands)"
8687 "@
8688 and{b}\t{%2, %0|%0, %2}
8689 and{b}\t{%2, %0|%0, %2}
8690 and{l}\t{%k2, %k0|%k0, %k2}"
8691 [(set_attr "type" "alu")
8692 (set_attr "mode" "QI,QI,SI")])
8693
8694 (define_insn "*andqi_1_slp"
8695 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8696 (and:QI (match_dup 0)
8697 (match_operand:QI 1 "general_operand" "qi,qmi")))
8698 (clobber (reg:CC 17))]
8699 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8700 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8701 "and{b}\t{%1, %0|%0, %1}"
8702 [(set_attr "type" "alu1")
8703 (set_attr "mode" "QI")])
8704
8705 (define_insn "*andqi_2"
8706 [(set (reg 17)
8707 (compare (and:QI
8708 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8709 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8710 (const_int 0)))
8711 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8712 (and:QI (match_dup 1) (match_dup 2)))]
8713 "ix86_match_ccmode (insn, CCNOmode)
8714 && ix86_binary_operator_ok (AND, QImode, operands)"
8715 {
8716 if (which_alternative == 2)
8717 {
8718 if (GET_CODE (operands[2]) == CONST_INT
8719 && (INTVAL (operands[2]) & 0xffffff00))
8720 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8721 return "and{l}\t{%2, %k0|%k0, %2}";
8722 }
8723 return "and{b}\t{%2, %0|%0, %2}";
8724 }
8725 [(set_attr "type" "alu")
8726 (set_attr "mode" "QI,QI,SI")])
8727
8728 (define_insn "*andqi_2_slp"
8729 [(set (reg 17)
8730 (compare (and:QI
8731 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8732 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8733 (const_int 0)))
8734 (set (strict_low_part (match_dup 0))
8735 (and:QI (match_dup 0) (match_dup 1)))]
8736 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8737 && ix86_match_ccmode (insn, CCNOmode)
8738 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8739 "and{b}\t{%1, %0|%0, %1}"
8740 [(set_attr "type" "alu1")
8741 (set_attr "mode" "QI")])
8742
8743 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8744 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8745 ;; for a QImode operand, which of course failed.
8746
8747 (define_insn "andqi_ext_0"
8748 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8749 (const_int 8)
8750 (const_int 8))
8751 (and:SI
8752 (zero_extract:SI
8753 (match_operand 1 "ext_register_operand" "0")
8754 (const_int 8)
8755 (const_int 8))
8756 (match_operand 2 "const_int_operand" "n")))
8757 (clobber (reg:CC 17))]
8758 ""
8759 "and{b}\t{%2, %h0|%h0, %2}"
8760 [(set_attr "type" "alu")
8761 (set_attr "length_immediate" "1")
8762 (set_attr "mode" "QI")])
8763
8764 ;; Generated by peephole translating test to and. This shows up
8765 ;; often in fp comparisons.
8766
8767 (define_insn "*andqi_ext_0_cc"
8768 [(set (reg 17)
8769 (compare
8770 (and:SI
8771 (zero_extract:SI
8772 (match_operand 1 "ext_register_operand" "0")
8773 (const_int 8)
8774 (const_int 8))
8775 (match_operand 2 "const_int_operand" "n"))
8776 (const_int 0)))
8777 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8778 (const_int 8)
8779 (const_int 8))
8780 (and:SI
8781 (zero_extract:SI
8782 (match_dup 1)
8783 (const_int 8)
8784 (const_int 8))
8785 (match_dup 2)))]
8786 "ix86_match_ccmode (insn, CCNOmode)"
8787 "and{b}\t{%2, %h0|%h0, %2}"
8788 [(set_attr "type" "alu")
8789 (set_attr "length_immediate" "1")
8790 (set_attr "mode" "QI")])
8791
8792 (define_insn "*andqi_ext_1"
8793 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8794 (const_int 8)
8795 (const_int 8))
8796 (and:SI
8797 (zero_extract:SI
8798 (match_operand 1 "ext_register_operand" "0")
8799 (const_int 8)
8800 (const_int 8))
8801 (zero_extend:SI
8802 (match_operand:QI 2 "general_operand" "Qm"))))
8803 (clobber (reg:CC 17))]
8804 "!TARGET_64BIT"
8805 "and{b}\t{%2, %h0|%h0, %2}"
8806 [(set_attr "type" "alu")
8807 (set_attr "length_immediate" "0")
8808 (set_attr "mode" "QI")])
8809
8810 (define_insn "*andqi_ext_1_rex64"
8811 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8812 (const_int 8)
8813 (const_int 8))
8814 (and:SI
8815 (zero_extract:SI
8816 (match_operand 1 "ext_register_operand" "0")
8817 (const_int 8)
8818 (const_int 8))
8819 (zero_extend:SI
8820 (match_operand 2 "ext_register_operand" "Q"))))
8821 (clobber (reg:CC 17))]
8822 "TARGET_64BIT"
8823 "and{b}\t{%2, %h0|%h0, %2}"
8824 [(set_attr "type" "alu")
8825 (set_attr "length_immediate" "0")
8826 (set_attr "mode" "QI")])
8827
8828 (define_insn "*andqi_ext_2"
8829 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8830 (const_int 8)
8831 (const_int 8))
8832 (and:SI
8833 (zero_extract:SI
8834 (match_operand 1 "ext_register_operand" "%0")
8835 (const_int 8)
8836 (const_int 8))
8837 (zero_extract:SI
8838 (match_operand 2 "ext_register_operand" "Q")
8839 (const_int 8)
8840 (const_int 8))))
8841 (clobber (reg:CC 17))]
8842 ""
8843 "and{b}\t{%h2, %h0|%h0, %h2}"
8844 [(set_attr "type" "alu")
8845 (set_attr "length_immediate" "0")
8846 (set_attr "mode" "QI")])
8847
8848 ;; Convert wide AND instructions with immediate operand to shorter QImode
8849 ;; equivalents when possible.
8850 ;; Don't do the splitting with memory operands, since it introduces risk
8851 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8852 ;; for size, but that can (should?) be handled by generic code instead.
8853 (define_split
8854 [(set (match_operand 0 "register_operand" "")
8855 (and (match_operand 1 "register_operand" "")
8856 (match_operand 2 "const_int_operand" "")))
8857 (clobber (reg:CC 17))]
8858 "reload_completed
8859 && QI_REG_P (operands[0])
8860 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8861 && !(~INTVAL (operands[2]) & ~(255 << 8))
8862 && GET_MODE (operands[0]) != QImode"
8863 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8864 (and:SI (zero_extract:SI (match_dup 1)
8865 (const_int 8) (const_int 8))
8866 (match_dup 2)))
8867 (clobber (reg:CC 17))])]
8868 "operands[0] = gen_lowpart (SImode, operands[0]);
8869 operands[1] = gen_lowpart (SImode, operands[1]);
8870 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8871
8872 ;; Since AND can be encoded with sign extended immediate, this is only
8873 ;; profitable when 7th bit is not set.
8874 (define_split
8875 [(set (match_operand 0 "register_operand" "")
8876 (and (match_operand 1 "general_operand" "")
8877 (match_operand 2 "const_int_operand" "")))
8878 (clobber (reg:CC 17))]
8879 "reload_completed
8880 && ANY_QI_REG_P (operands[0])
8881 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8882 && !(~INTVAL (operands[2]) & ~255)
8883 && !(INTVAL (operands[2]) & 128)
8884 && GET_MODE (operands[0]) != QImode"
8885 [(parallel [(set (strict_low_part (match_dup 0))
8886 (and:QI (match_dup 1)
8887 (match_dup 2)))
8888 (clobber (reg:CC 17))])]
8889 "operands[0] = gen_lowpart (QImode, operands[0]);
8890 operands[1] = gen_lowpart (QImode, operands[1]);
8891 operands[2] = gen_lowpart (QImode, operands[2]);")
8892 \f
8893 ;; Logical inclusive OR instructions
8894
8895 ;; %%% This used to optimize known byte-wide and operations to memory.
8896 ;; If this is considered useful, it should be done with splitters.
8897
8898 (define_expand "iordi3"
8899 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8900 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8901 (match_operand:DI 2 "x86_64_general_operand" "")))
8902 (clobber (reg:CC 17))]
8903 "TARGET_64BIT"
8904 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8905
8906 (define_insn "*iordi_1_rex64"
8907 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8908 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8909 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8910 (clobber (reg:CC 17))]
8911 "TARGET_64BIT
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 (define_insn "*iordi_2_rex64"
8918 [(set (reg 17)
8919 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8920 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8921 (const_int 0)))
8922 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8923 (ior:DI (match_dup 1) (match_dup 2)))]
8924 "TARGET_64BIT
8925 && ix86_match_ccmode (insn, CCNOmode)
8926 && ix86_binary_operator_ok (IOR, DImode, operands)"
8927 "or{q}\t{%2, %0|%0, %2}"
8928 [(set_attr "type" "alu")
8929 (set_attr "mode" "DI")])
8930
8931 (define_insn "*iordi_3_rex64"
8932 [(set (reg 17)
8933 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8934 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8935 (const_int 0)))
8936 (clobber (match_scratch:DI 0 "=r"))]
8937 "TARGET_64BIT
8938 && ix86_match_ccmode (insn, CCNOmode)
8939 && ix86_binary_operator_ok (IOR, DImode, operands)"
8940 "or{q}\t{%2, %0|%0, %2}"
8941 [(set_attr "type" "alu")
8942 (set_attr "mode" "DI")])
8943
8944
8945 (define_expand "iorsi3"
8946 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8947 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8948 (match_operand:SI 2 "general_operand" "")))
8949 (clobber (reg:CC 17))]
8950 ""
8951 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8952
8953 (define_insn "*iorsi_1"
8954 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8955 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8956 (match_operand:SI 2 "general_operand" "ri,rmi")))
8957 (clobber (reg:CC 17))]
8958 "ix86_binary_operator_ok (IOR, SImode, operands)"
8959 "or{l}\t{%2, %0|%0, %2}"
8960 [(set_attr "type" "alu")
8961 (set_attr "mode" "SI")])
8962
8963 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8964 (define_insn "*iorsi_1_zext"
8965 [(set (match_operand:DI 0 "register_operand" "=rm")
8966 (zero_extend:DI
8967 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8968 (match_operand:SI 2 "general_operand" "rim"))))
8969 (clobber (reg:CC 17))]
8970 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8971 "or{l}\t{%2, %k0|%k0, %2}"
8972 [(set_attr "type" "alu")
8973 (set_attr "mode" "SI")])
8974
8975 (define_insn "*iorsi_1_zext_imm"
8976 [(set (match_operand:DI 0 "register_operand" "=rm")
8977 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8978 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8979 (clobber (reg:CC 17))]
8980 "TARGET_64BIT"
8981 "or{l}\t{%2, %k0|%k0, %2}"
8982 [(set_attr "type" "alu")
8983 (set_attr "mode" "SI")])
8984
8985 (define_insn "*iorsi_2"
8986 [(set (reg 17)
8987 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8988 (match_operand:SI 2 "general_operand" "rim,ri"))
8989 (const_int 0)))
8990 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8991 (ior:SI (match_dup 1) (match_dup 2)))]
8992 "ix86_match_ccmode (insn, CCNOmode)
8993 && ix86_binary_operator_ok (IOR, SImode, operands)"
8994 "or{l}\t{%2, %0|%0, %2}"
8995 [(set_attr "type" "alu")
8996 (set_attr "mode" "SI")])
8997
8998 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8999 ;; ??? Special case for immediate operand is missing - it is tricky.
9000 (define_insn "*iorsi_2_zext"
9001 [(set (reg 17)
9002 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9003 (match_operand:SI 2 "general_operand" "rim"))
9004 (const_int 0)))
9005 (set (match_operand:DI 0 "register_operand" "=r")
9006 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9007 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9008 && ix86_binary_operator_ok (IOR, SImode, operands)"
9009 "or{l}\t{%2, %k0|%k0, %2}"
9010 [(set_attr "type" "alu")
9011 (set_attr "mode" "SI")])
9012
9013 (define_insn "*iorsi_2_zext_imm"
9014 [(set (reg 17)
9015 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9016 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9017 (const_int 0)))
9018 (set (match_operand:DI 0 "register_operand" "=r")
9019 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9020 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9021 && ix86_binary_operator_ok (IOR, SImode, operands)"
9022 "or{l}\t{%2, %k0|%k0, %2}"
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "SI")])
9025
9026 (define_insn "*iorsi_3"
9027 [(set (reg 17)
9028 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9029 (match_operand:SI 2 "general_operand" "rim"))
9030 (const_int 0)))
9031 (clobber (match_scratch:SI 0 "=r"))]
9032 "ix86_match_ccmode (insn, CCNOmode)
9033 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9034 "or{l}\t{%2, %0|%0, %2}"
9035 [(set_attr "type" "alu")
9036 (set_attr "mode" "SI")])
9037
9038 (define_expand "iorhi3"
9039 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9040 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9041 (match_operand:HI 2 "general_operand" "")))
9042 (clobber (reg:CC 17))]
9043 "TARGET_HIMODE_MATH"
9044 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9045
9046 (define_insn "*iorhi_1"
9047 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9048 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9049 (match_operand:HI 2 "general_operand" "rmi,ri")))
9050 (clobber (reg:CC 17))]
9051 "ix86_binary_operator_ok (IOR, HImode, operands)"
9052 "or{w}\t{%2, %0|%0, %2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "mode" "HI")])
9055
9056 (define_insn "*iorhi_2"
9057 [(set (reg 17)
9058 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9059 (match_operand:HI 2 "general_operand" "rim,ri"))
9060 (const_int 0)))
9061 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9062 (ior:HI (match_dup 1) (match_dup 2)))]
9063 "ix86_match_ccmode (insn, CCNOmode)
9064 && ix86_binary_operator_ok (IOR, HImode, operands)"
9065 "or{w}\t{%2, %0|%0, %2}"
9066 [(set_attr "type" "alu")
9067 (set_attr "mode" "HI")])
9068
9069 (define_insn "*iorhi_3"
9070 [(set (reg 17)
9071 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9072 (match_operand:HI 2 "general_operand" "rim"))
9073 (const_int 0)))
9074 (clobber (match_scratch:HI 0 "=r"))]
9075 "ix86_match_ccmode (insn, CCNOmode)
9076 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9077 "or{w}\t{%2, %0|%0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "mode" "HI")])
9080
9081 (define_expand "iorqi3"
9082 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9083 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9084 (match_operand:QI 2 "general_operand" "")))
9085 (clobber (reg:CC 17))]
9086 "TARGET_QIMODE_MATH"
9087 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9088
9089 ;; %%% Potential partial reg stall on alternative 2. What to do?
9090 (define_insn "*iorqi_1"
9091 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9092 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9093 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9094 (clobber (reg:CC 17))]
9095 "ix86_binary_operator_ok (IOR, QImode, operands)"
9096 "@
9097 or{b}\t{%2, %0|%0, %2}
9098 or{b}\t{%2, %0|%0, %2}
9099 or{l}\t{%k2, %k0|%k0, %k2}"
9100 [(set_attr "type" "alu")
9101 (set_attr "mode" "QI,QI,SI")])
9102
9103 (define_insn "*iorqi_1_slp"
9104 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9105 (ior:QI (match_dup 0)
9106 (match_operand:QI 1 "general_operand" "qmi,qi")))
9107 (clobber (reg:CC 17))]
9108 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
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_2"
9115 [(set (reg 17)
9116 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9117 (match_operand:QI 2 "general_operand" "qim,qi"))
9118 (const_int 0)))
9119 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9120 (ior:QI (match_dup 1) (match_dup 2)))]
9121 "ix86_match_ccmode (insn, CCNOmode)
9122 && ix86_binary_operator_ok (IOR, QImode, operands)"
9123 "or{b}\t{%2, %0|%0, %2}"
9124 [(set_attr "type" "alu")
9125 (set_attr "mode" "QI")])
9126
9127 (define_insn "*iorqi_2_slp"
9128 [(set (reg 17)
9129 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9130 (match_operand:QI 1 "general_operand" "qim,qi"))
9131 (const_int 0)))
9132 (set (strict_low_part (match_dup 0))
9133 (ior:QI (match_dup 0) (match_dup 1)))]
9134 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9135 && ix86_match_ccmode (insn, CCNOmode)
9136 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9137 "or{b}\t{%1, %0|%0, %1}"
9138 [(set_attr "type" "alu1")
9139 (set_attr "mode" "QI")])
9140
9141 (define_insn "*iorqi_3"
9142 [(set (reg 17)
9143 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9144 (match_operand:QI 2 "general_operand" "qim"))
9145 (const_int 0)))
9146 (clobber (match_scratch:QI 0 "=q"))]
9147 "ix86_match_ccmode (insn, CCNOmode)
9148 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9149 "or{b}\t{%2, %0|%0, %2}"
9150 [(set_attr "type" "alu")
9151 (set_attr "mode" "QI")])
9152
9153 (define_insn "iorqi_ext_0"
9154 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9155 (const_int 8)
9156 (const_int 8))
9157 (ior:SI
9158 (zero_extract:SI
9159 (match_operand 1 "ext_register_operand" "0")
9160 (const_int 8)
9161 (const_int 8))
9162 (match_operand 2 "const_int_operand" "n")))
9163 (clobber (reg:CC 17))]
9164 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9165 "or{b}\t{%2, %h0|%h0, %2}"
9166 [(set_attr "type" "alu")
9167 (set_attr "length_immediate" "1")
9168 (set_attr "mode" "QI")])
9169
9170 (define_insn "*iorqi_ext_1"
9171 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9172 (const_int 8)
9173 (const_int 8))
9174 (ior:SI
9175 (zero_extract:SI
9176 (match_operand 1 "ext_register_operand" "0")
9177 (const_int 8)
9178 (const_int 8))
9179 (zero_extend:SI
9180 (match_operand:QI 2 "general_operand" "Qm"))))
9181 (clobber (reg:CC 17))]
9182 "!TARGET_64BIT
9183 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9184 "or{b}\t{%2, %h0|%h0, %2}"
9185 [(set_attr "type" "alu")
9186 (set_attr "length_immediate" "0")
9187 (set_attr "mode" "QI")])
9188
9189 (define_insn "*iorqi_ext_1_rex64"
9190 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9191 (const_int 8)
9192 (const_int 8))
9193 (ior:SI
9194 (zero_extract:SI
9195 (match_operand 1 "ext_register_operand" "0")
9196 (const_int 8)
9197 (const_int 8))
9198 (zero_extend:SI
9199 (match_operand 2 "ext_register_operand" "Q"))))
9200 (clobber (reg:CC 17))]
9201 "TARGET_64BIT
9202 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9203 "or{b}\t{%2, %h0|%h0, %2}"
9204 [(set_attr "type" "alu")
9205 (set_attr "length_immediate" "0")
9206 (set_attr "mode" "QI")])
9207
9208 (define_insn "*iorqi_ext_2"
9209 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9210 (const_int 8)
9211 (const_int 8))
9212 (ior:SI
9213 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9214 (const_int 8)
9215 (const_int 8))
9216 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9217 (const_int 8)
9218 (const_int 8))))
9219 (clobber (reg:CC 17))]
9220 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9221 "ior{b}\t{%h2, %h0|%h0, %h2}"
9222 [(set_attr "type" "alu")
9223 (set_attr "length_immediate" "0")
9224 (set_attr "mode" "QI")])
9225
9226 (define_split
9227 [(set (match_operand 0 "register_operand" "")
9228 (ior (match_operand 1 "register_operand" "")
9229 (match_operand 2 "const_int_operand" "")))
9230 (clobber (reg:CC 17))]
9231 "reload_completed
9232 && QI_REG_P (operands[0])
9233 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9234 && !(INTVAL (operands[2]) & ~(255 << 8))
9235 && GET_MODE (operands[0]) != QImode"
9236 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9237 (ior:SI (zero_extract:SI (match_dup 1)
9238 (const_int 8) (const_int 8))
9239 (match_dup 2)))
9240 (clobber (reg:CC 17))])]
9241 "operands[0] = gen_lowpart (SImode, operands[0]);
9242 operands[1] = gen_lowpart (SImode, operands[1]);
9243 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9244
9245 ;; Since OR can be encoded with sign extended immediate, this is only
9246 ;; profitable when 7th bit is set.
9247 (define_split
9248 [(set (match_operand 0 "register_operand" "")
9249 (ior (match_operand 1 "general_operand" "")
9250 (match_operand 2 "const_int_operand" "")))
9251 (clobber (reg:CC 17))]
9252 "reload_completed
9253 && ANY_QI_REG_P (operands[0])
9254 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9255 && !(INTVAL (operands[2]) & ~255)
9256 && (INTVAL (operands[2]) & 128)
9257 && GET_MODE (operands[0]) != QImode"
9258 [(parallel [(set (strict_low_part (match_dup 0))
9259 (ior:QI (match_dup 1)
9260 (match_dup 2)))
9261 (clobber (reg:CC 17))])]
9262 "operands[0] = gen_lowpart (QImode, operands[0]);
9263 operands[1] = gen_lowpart (QImode, operands[1]);
9264 operands[2] = gen_lowpart (QImode, operands[2]);")
9265 \f
9266 ;; Logical XOR instructions
9267
9268 ;; %%% This used to optimize known byte-wide and operations to memory.
9269 ;; If this is considered useful, it should be done with splitters.
9270
9271 (define_expand "xordi3"
9272 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9273 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9274 (match_operand:DI 2 "x86_64_general_operand" "")))
9275 (clobber (reg:CC 17))]
9276 "TARGET_64BIT"
9277 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9278
9279 (define_insn "*xordi_1_rex64"
9280 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9281 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9282 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9283 (clobber (reg:CC 17))]
9284 "TARGET_64BIT
9285 && ix86_binary_operator_ok (XOR, DImode, operands)"
9286 "@
9287 xor{q}\t{%2, %0|%0, %2}
9288 xor{q}\t{%2, %0|%0, %2}"
9289 [(set_attr "type" "alu")
9290 (set_attr "mode" "DI,DI")])
9291
9292 (define_insn "*xordi_2_rex64"
9293 [(set (reg 17)
9294 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9295 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9296 (const_int 0)))
9297 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9298 (xor:DI (match_dup 1) (match_dup 2)))]
9299 "TARGET_64BIT
9300 && ix86_match_ccmode (insn, CCNOmode)
9301 && ix86_binary_operator_ok (XOR, DImode, operands)"
9302 "@
9303 xor{q}\t{%2, %0|%0, %2}
9304 xor{q}\t{%2, %0|%0, %2}"
9305 [(set_attr "type" "alu")
9306 (set_attr "mode" "DI,DI")])
9307
9308 (define_insn "*xordi_3_rex64"
9309 [(set (reg 17)
9310 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9311 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9312 (const_int 0)))
9313 (clobber (match_scratch:DI 0 "=r"))]
9314 "TARGET_64BIT
9315 && ix86_match_ccmode (insn, CCNOmode)
9316 && ix86_binary_operator_ok (XOR, DImode, operands)"
9317 "xor{q}\t{%2, %0|%0, %2}"
9318 [(set_attr "type" "alu")
9319 (set_attr "mode" "DI")])
9320
9321 (define_expand "xorsi3"
9322 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9323 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9324 (match_operand:SI 2 "general_operand" "")))
9325 (clobber (reg:CC 17))]
9326 ""
9327 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9328
9329 (define_insn "*xorsi_1"
9330 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9331 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9332 (match_operand:SI 2 "general_operand" "ri,rm")))
9333 (clobber (reg:CC 17))]
9334 "ix86_binary_operator_ok (XOR, SImode, operands)"
9335 "xor{l}\t{%2, %0|%0, %2}"
9336 [(set_attr "type" "alu")
9337 (set_attr "mode" "SI")])
9338
9339 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9340 ;; Add speccase for immediates
9341 (define_insn "*xorsi_1_zext"
9342 [(set (match_operand:DI 0 "register_operand" "=r")
9343 (zero_extend:DI
9344 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9345 (match_operand:SI 2 "general_operand" "rim"))))
9346 (clobber (reg:CC 17))]
9347 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9348 "xor{l}\t{%2, %k0|%k0, %2}"
9349 [(set_attr "type" "alu")
9350 (set_attr "mode" "SI")])
9351
9352 (define_insn "*xorsi_1_zext_imm"
9353 [(set (match_operand:DI 0 "register_operand" "=r")
9354 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9355 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9356 (clobber (reg:CC 17))]
9357 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9358 "xor{l}\t{%2, %k0|%k0, %2}"
9359 [(set_attr "type" "alu")
9360 (set_attr "mode" "SI")])
9361
9362 (define_insn "*xorsi_2"
9363 [(set (reg 17)
9364 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9365 (match_operand:SI 2 "general_operand" "rim,ri"))
9366 (const_int 0)))
9367 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9368 (xor:SI (match_dup 1) (match_dup 2)))]
9369 "ix86_match_ccmode (insn, CCNOmode)
9370 && ix86_binary_operator_ok (XOR, SImode, operands)"
9371 "xor{l}\t{%2, %0|%0, %2}"
9372 [(set_attr "type" "alu")
9373 (set_attr "mode" "SI")])
9374
9375 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9376 ;; ??? Special case for immediate operand is missing - it is tricky.
9377 (define_insn "*xorsi_2_zext"
9378 [(set (reg 17)
9379 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9380 (match_operand:SI 2 "general_operand" "rim"))
9381 (const_int 0)))
9382 (set (match_operand:DI 0 "register_operand" "=r")
9383 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9384 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9385 && ix86_binary_operator_ok (XOR, SImode, operands)"
9386 "xor{l}\t{%2, %k0|%k0, %2}"
9387 [(set_attr "type" "alu")
9388 (set_attr "mode" "SI")])
9389
9390 (define_insn "*xorsi_2_zext_imm"
9391 [(set (reg 17)
9392 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9393 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9394 (const_int 0)))
9395 (set (match_operand:DI 0 "register_operand" "=r")
9396 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9397 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9398 && ix86_binary_operator_ok (XOR, SImode, operands)"
9399 "xor{l}\t{%2, %k0|%k0, %2}"
9400 [(set_attr "type" "alu")
9401 (set_attr "mode" "SI")])
9402
9403 (define_insn "*xorsi_3"
9404 [(set (reg 17)
9405 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9406 (match_operand:SI 2 "general_operand" "rim"))
9407 (const_int 0)))
9408 (clobber (match_scratch:SI 0 "=r"))]
9409 "ix86_match_ccmode (insn, CCNOmode)
9410 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9411 "xor{l}\t{%2, %0|%0, %2}"
9412 [(set_attr "type" "alu")
9413 (set_attr "mode" "SI")])
9414
9415 (define_expand "xorhi3"
9416 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9417 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9418 (match_operand:HI 2 "general_operand" "")))
9419 (clobber (reg:CC 17))]
9420 "TARGET_HIMODE_MATH"
9421 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9422
9423 (define_insn "*xorhi_1"
9424 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9425 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9426 (match_operand:HI 2 "general_operand" "rmi,ri")))
9427 (clobber (reg:CC 17))]
9428 "ix86_binary_operator_ok (XOR, HImode, operands)"
9429 "xor{w}\t{%2, %0|%0, %2}"
9430 [(set_attr "type" "alu")
9431 (set_attr "mode" "HI")])
9432
9433 (define_insn "*xorhi_2"
9434 [(set (reg 17)
9435 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9436 (match_operand:HI 2 "general_operand" "rim,ri"))
9437 (const_int 0)))
9438 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9439 (xor:HI (match_dup 1) (match_dup 2)))]
9440 "ix86_match_ccmode (insn, CCNOmode)
9441 && ix86_binary_operator_ok (XOR, HImode, operands)"
9442 "xor{w}\t{%2, %0|%0, %2}"
9443 [(set_attr "type" "alu")
9444 (set_attr "mode" "HI")])
9445
9446 (define_insn "*xorhi_3"
9447 [(set (reg 17)
9448 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9449 (match_operand:HI 2 "general_operand" "rim"))
9450 (const_int 0)))
9451 (clobber (match_scratch:HI 0 "=r"))]
9452 "ix86_match_ccmode (insn, CCNOmode)
9453 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9454 "xor{w}\t{%2, %0|%0, %2}"
9455 [(set_attr "type" "alu")
9456 (set_attr "mode" "HI")])
9457
9458 (define_expand "xorqi3"
9459 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9460 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9461 (match_operand:QI 2 "general_operand" "")))
9462 (clobber (reg:CC 17))]
9463 "TARGET_QIMODE_MATH"
9464 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9465
9466 ;; %%% Potential partial reg stall on alternative 2. What to do?
9467 (define_insn "*xorqi_1"
9468 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9469 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9470 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9471 (clobber (reg:CC 17))]
9472 "ix86_binary_operator_ok (XOR, QImode, operands)"
9473 "@
9474 xor{b}\t{%2, %0|%0, %2}
9475 xor{b}\t{%2, %0|%0, %2}
9476 xor{l}\t{%k2, %k0|%k0, %k2}"
9477 [(set_attr "type" "alu")
9478 (set_attr "mode" "QI,QI,SI")])
9479
9480 (define_insn "*xorqi_1_slp"
9481 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9482 (xor:QI (match_dup 0)
9483 (match_operand:QI 1 "general_operand" "qi,qmi")))
9484 (clobber (reg:CC 17))]
9485 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9486 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9487 "xor{b}\t{%1, %0|%0, %1}"
9488 [(set_attr "type" "alu1")
9489 (set_attr "mode" "QI")])
9490
9491 (define_insn "xorqi_ext_0"
9492 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9493 (const_int 8)
9494 (const_int 8))
9495 (xor:SI
9496 (zero_extract:SI
9497 (match_operand 1 "ext_register_operand" "0")
9498 (const_int 8)
9499 (const_int 8))
9500 (match_operand 2 "const_int_operand" "n")))
9501 (clobber (reg:CC 17))]
9502 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9503 "xor{b}\t{%2, %h0|%h0, %2}"
9504 [(set_attr "type" "alu")
9505 (set_attr "length_immediate" "1")
9506 (set_attr "mode" "QI")])
9507
9508 (define_insn "*xorqi_ext_1"
9509 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9510 (const_int 8)
9511 (const_int 8))
9512 (xor:SI
9513 (zero_extract:SI
9514 (match_operand 1 "ext_register_operand" "0")
9515 (const_int 8)
9516 (const_int 8))
9517 (zero_extend:SI
9518 (match_operand:QI 2 "general_operand" "Qm"))))
9519 (clobber (reg:CC 17))]
9520 "!TARGET_64BIT
9521 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9522 "xor{b}\t{%2, %h0|%h0, %2}"
9523 [(set_attr "type" "alu")
9524 (set_attr "length_immediate" "0")
9525 (set_attr "mode" "QI")])
9526
9527 (define_insn "*xorqi_ext_1_rex64"
9528 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9529 (const_int 8)
9530 (const_int 8))
9531 (xor:SI
9532 (zero_extract:SI
9533 (match_operand 1 "ext_register_operand" "0")
9534 (const_int 8)
9535 (const_int 8))
9536 (zero_extend:SI
9537 (match_operand 2 "ext_register_operand" "Q"))))
9538 (clobber (reg:CC 17))]
9539 "TARGET_64BIT
9540 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9541 "xor{b}\t{%2, %h0|%h0, %2}"
9542 [(set_attr "type" "alu")
9543 (set_attr "length_immediate" "0")
9544 (set_attr "mode" "QI")])
9545
9546 (define_insn "*xorqi_ext_2"
9547 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9548 (const_int 8)
9549 (const_int 8))
9550 (xor:SI
9551 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9552 (const_int 8)
9553 (const_int 8))
9554 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9555 (const_int 8)
9556 (const_int 8))))
9557 (clobber (reg:CC 17))]
9558 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9559 "xor{b}\t{%h2, %h0|%h0, %h2}"
9560 [(set_attr "type" "alu")
9561 (set_attr "length_immediate" "0")
9562 (set_attr "mode" "QI")])
9563
9564 (define_insn "*xorqi_cc_1"
9565 [(set (reg 17)
9566 (compare
9567 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9568 (match_operand:QI 2 "general_operand" "qim,qi"))
9569 (const_int 0)))
9570 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9571 (xor:QI (match_dup 1) (match_dup 2)))]
9572 "ix86_match_ccmode (insn, CCNOmode)
9573 && ix86_binary_operator_ok (XOR, QImode, operands)"
9574 "xor{b}\t{%2, %0|%0, %2}"
9575 [(set_attr "type" "alu")
9576 (set_attr "mode" "QI")])
9577
9578 (define_insn "*xorqi_2_slp"
9579 [(set (reg 17)
9580 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9581 (match_operand:QI 1 "general_operand" "qim,qi"))
9582 (const_int 0)))
9583 (set (strict_low_part (match_dup 0))
9584 (xor:QI (match_dup 0) (match_dup 1)))]
9585 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9586 && ix86_match_ccmode (insn, CCNOmode)
9587 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9588 "xor{b}\t{%1, %0|%0, %1}"
9589 [(set_attr "type" "alu1")
9590 (set_attr "mode" "QI")])
9591
9592 (define_insn "*xorqi_cc_2"
9593 [(set (reg 17)
9594 (compare
9595 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9596 (match_operand:QI 2 "general_operand" "qim"))
9597 (const_int 0)))
9598 (clobber (match_scratch:QI 0 "=q"))]
9599 "ix86_match_ccmode (insn, CCNOmode)
9600 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9601 "xor{b}\t{%2, %0|%0, %2}"
9602 [(set_attr "type" "alu")
9603 (set_attr "mode" "QI")])
9604
9605 (define_insn "*xorqi_cc_ext_1"
9606 [(set (reg 17)
9607 (compare
9608 (xor:SI
9609 (zero_extract:SI
9610 (match_operand 1 "ext_register_operand" "0")
9611 (const_int 8)
9612 (const_int 8))
9613 (match_operand:QI 2 "general_operand" "qmn"))
9614 (const_int 0)))
9615 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9616 (const_int 8)
9617 (const_int 8))
9618 (xor:SI
9619 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9620 (match_dup 2)))]
9621 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9622 "xor{b}\t{%2, %h0|%h0, %2}"
9623 [(set_attr "type" "alu")
9624 (set_attr "mode" "QI")])
9625
9626 (define_insn "*xorqi_cc_ext_1_rex64"
9627 [(set (reg 17)
9628 (compare
9629 (xor:SI
9630 (zero_extract:SI
9631 (match_operand 1 "ext_register_operand" "0")
9632 (const_int 8)
9633 (const_int 8))
9634 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9635 (const_int 0)))
9636 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9637 (const_int 8)
9638 (const_int 8))
9639 (xor:SI
9640 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9641 (match_dup 2)))]
9642 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9643 "xor{b}\t{%2, %h0|%h0, %2}"
9644 [(set_attr "type" "alu")
9645 (set_attr "mode" "QI")])
9646
9647 (define_expand "xorqi_cc_ext_1"
9648 [(parallel [
9649 (set (reg:CCNO 17)
9650 (compare:CCNO
9651 (xor:SI
9652 (zero_extract:SI
9653 (match_operand 1 "ext_register_operand" "")
9654 (const_int 8)
9655 (const_int 8))
9656 (match_operand:QI 2 "general_operand" ""))
9657 (const_int 0)))
9658 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9659 (const_int 8)
9660 (const_int 8))
9661 (xor:SI
9662 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9663 (match_dup 2)))])]
9664 ""
9665 "")
9666
9667 (define_split
9668 [(set (match_operand 0 "register_operand" "")
9669 (xor (match_operand 1 "register_operand" "")
9670 (match_operand 2 "const_int_operand" "")))
9671 (clobber (reg:CC 17))]
9672 "reload_completed
9673 && QI_REG_P (operands[0])
9674 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9675 && !(INTVAL (operands[2]) & ~(255 << 8))
9676 && GET_MODE (operands[0]) != QImode"
9677 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9678 (xor:SI (zero_extract:SI (match_dup 1)
9679 (const_int 8) (const_int 8))
9680 (match_dup 2)))
9681 (clobber (reg:CC 17))])]
9682 "operands[0] = gen_lowpart (SImode, operands[0]);
9683 operands[1] = gen_lowpart (SImode, operands[1]);
9684 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9685
9686 ;; Since XOR can be encoded with sign extended immediate, this is only
9687 ;; profitable when 7th bit is set.
9688 (define_split
9689 [(set (match_operand 0 "register_operand" "")
9690 (xor (match_operand 1 "general_operand" "")
9691 (match_operand 2 "const_int_operand" "")))
9692 (clobber (reg:CC 17))]
9693 "reload_completed
9694 && ANY_QI_REG_P (operands[0])
9695 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9696 && !(INTVAL (operands[2]) & ~255)
9697 && (INTVAL (operands[2]) & 128)
9698 && GET_MODE (operands[0]) != QImode"
9699 [(parallel [(set (strict_low_part (match_dup 0))
9700 (xor:QI (match_dup 1)
9701 (match_dup 2)))
9702 (clobber (reg:CC 17))])]
9703 "operands[0] = gen_lowpart (QImode, operands[0]);
9704 operands[1] = gen_lowpart (QImode, operands[1]);
9705 operands[2] = gen_lowpart (QImode, operands[2]);")
9706 \f
9707 ;; Negation instructions
9708
9709 (define_expand "negdi2"
9710 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9711 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9712 (clobber (reg:CC 17))])]
9713 ""
9714 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9715
9716 (define_insn "*negdi2_1"
9717 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9718 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9719 (clobber (reg:CC 17))]
9720 "!TARGET_64BIT
9721 && ix86_unary_operator_ok (NEG, DImode, operands)"
9722 "#")
9723
9724 (define_split
9725 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9726 (neg:DI (match_operand:DI 1 "general_operand" "")))
9727 (clobber (reg:CC 17))]
9728 "!TARGET_64BIT && reload_completed"
9729 [(parallel
9730 [(set (reg:CCZ 17)
9731 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9732 (set (match_dup 0) (neg:SI (match_dup 2)))])
9733 (parallel
9734 [(set (match_dup 1)
9735 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9736 (match_dup 3))
9737 (const_int 0)))
9738 (clobber (reg:CC 17))])
9739 (parallel
9740 [(set (match_dup 1)
9741 (neg:SI (match_dup 1)))
9742 (clobber (reg:CC 17))])]
9743 "split_di (operands+1, 1, operands+2, operands+3);
9744 split_di (operands+0, 1, operands+0, operands+1);")
9745
9746 (define_insn "*negdi2_1_rex64"
9747 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9748 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9749 (clobber (reg:CC 17))]
9750 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9751 "neg{q}\t%0"
9752 [(set_attr "type" "negnot")
9753 (set_attr "mode" "DI")])
9754
9755 ;; The problem with neg is that it does not perform (compare x 0),
9756 ;; it really performs (compare 0 x), which leaves us with the zero
9757 ;; flag being the only useful item.
9758
9759 (define_insn "*negdi2_cmpz_rex64"
9760 [(set (reg:CCZ 17)
9761 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9762 (const_int 0)))
9763 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9764 (neg:DI (match_dup 1)))]
9765 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9766 "neg{q}\t%0"
9767 [(set_attr "type" "negnot")
9768 (set_attr "mode" "DI")])
9769
9770
9771 (define_expand "negsi2"
9772 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9773 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9774 (clobber (reg:CC 17))])]
9775 ""
9776 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9777
9778 (define_insn "*negsi2_1"
9779 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9780 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9781 (clobber (reg:CC 17))]
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 ;; Combine is quite creative about this pattern.
9788 (define_insn "*negsi2_1_zext"
9789 [(set (match_operand:DI 0 "register_operand" "=r")
9790 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9791 (const_int 32)))
9792 (const_int 32)))
9793 (clobber (reg:CC 17))]
9794 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9795 "neg{l}\t%k0"
9796 [(set_attr "type" "negnot")
9797 (set_attr "mode" "SI")])
9798
9799 ;; The problem with neg is that it does not perform (compare x 0),
9800 ;; it really performs (compare 0 x), which leaves us with the zero
9801 ;; flag being the only useful item.
9802
9803 (define_insn "*negsi2_cmpz"
9804 [(set (reg:CCZ 17)
9805 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9806 (const_int 0)))
9807 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9808 (neg:SI (match_dup 1)))]
9809 "ix86_unary_operator_ok (NEG, SImode, operands)"
9810 "neg{l}\t%0"
9811 [(set_attr "type" "negnot")
9812 (set_attr "mode" "SI")])
9813
9814 (define_insn "*negsi2_cmpz_zext"
9815 [(set (reg:CCZ 17)
9816 (compare:CCZ (lshiftrt:DI
9817 (neg:DI (ashift:DI
9818 (match_operand:DI 1 "register_operand" "0")
9819 (const_int 32)))
9820 (const_int 32))
9821 (const_int 0)))
9822 (set (match_operand:DI 0 "register_operand" "=r")
9823 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9824 (const_int 32)))
9825 (const_int 32)))]
9826 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9827 "neg{l}\t%k0"
9828 [(set_attr "type" "negnot")
9829 (set_attr "mode" "SI")])
9830
9831 (define_expand "neghi2"
9832 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9833 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9834 (clobber (reg:CC 17))])]
9835 "TARGET_HIMODE_MATH"
9836 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9837
9838 (define_insn "*neghi2_1"
9839 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9840 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9841 (clobber (reg:CC 17))]
9842 "ix86_unary_operator_ok (NEG, HImode, operands)"
9843 "neg{w}\t%0"
9844 [(set_attr "type" "negnot")
9845 (set_attr "mode" "HI")])
9846
9847 (define_insn "*neghi2_cmpz"
9848 [(set (reg:CCZ 17)
9849 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9850 (const_int 0)))
9851 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9852 (neg:HI (match_dup 1)))]
9853 "ix86_unary_operator_ok (NEG, HImode, operands)"
9854 "neg{w}\t%0"
9855 [(set_attr "type" "negnot")
9856 (set_attr "mode" "HI")])
9857
9858 (define_expand "negqi2"
9859 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9860 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9861 (clobber (reg:CC 17))])]
9862 "TARGET_QIMODE_MATH"
9863 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9864
9865 (define_insn "*negqi2_1"
9866 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9867 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9868 (clobber (reg:CC 17))]
9869 "ix86_unary_operator_ok (NEG, QImode, operands)"
9870 "neg{b}\t%0"
9871 [(set_attr "type" "negnot")
9872 (set_attr "mode" "QI")])
9873
9874 (define_insn "*negqi2_cmpz"
9875 [(set (reg:CCZ 17)
9876 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9877 (const_int 0)))
9878 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9879 (neg:QI (match_dup 1)))]
9880 "ix86_unary_operator_ok (NEG, QImode, operands)"
9881 "neg{b}\t%0"
9882 [(set_attr "type" "negnot")
9883 (set_attr "mode" "QI")])
9884
9885 ;; Changing of sign for FP values is doable using integer unit too.
9886
9887 (define_expand "negsf2"
9888 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9889 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9890 (clobber (reg:CC 17))])]
9891 "TARGET_80387"
9892 "if (TARGET_SSE)
9893 {
9894 /* In case operand is in memory, we will not use SSE. */
9895 if (memory_operand (operands[0], VOIDmode)
9896 && rtx_equal_p (operands[0], operands[1]))
9897 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9898 else
9899 {
9900 /* Using SSE is tricky, since we need bitwise negation of -0
9901 in register. */
9902 rtx reg = gen_reg_rtx (SFmode);
9903 rtx dest = operands[0];
9904 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9905
9906 operands[1] = force_reg (SFmode, operands[1]);
9907 operands[0] = force_reg (SFmode, operands[0]);
9908 reg = force_reg (V4SFmode,
9909 gen_rtx_CONST_VECTOR (V4SFmode,
9910 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9911 CONST0_RTX (SFmode),
9912 CONST0_RTX (SFmode))));
9913 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9914 if (dest != operands[0])
9915 emit_move_insn (dest, operands[0]);
9916 }
9917 DONE;
9918 }
9919 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9920
9921 (define_insn "negsf2_memory"
9922 [(set (match_operand:SF 0 "memory_operand" "=m")
9923 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9924 (clobber (reg:CC 17))]
9925 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9926 "#")
9927
9928 (define_insn "negsf2_ifs"
9929 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9930 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9931 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9932 (clobber (reg:CC 17))]
9933 "TARGET_SSE
9934 && (reload_in_progress || reload_completed
9935 || (register_operand (operands[0], VOIDmode)
9936 && register_operand (operands[1], VOIDmode)))"
9937 "#")
9938
9939 (define_split
9940 [(set (match_operand:SF 0 "memory_operand" "")
9941 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9942 (use (match_operand:SF 2 "" ""))
9943 (clobber (reg:CC 17))]
9944 ""
9945 [(parallel [(set (match_dup 0)
9946 (neg:SF (match_dup 1)))
9947 (clobber (reg:CC 17))])])
9948
9949 (define_split
9950 [(set (match_operand:SF 0 "register_operand" "")
9951 (neg:SF (match_operand:SF 1 "register_operand" "")))
9952 (use (match_operand:V4SF 2 "" ""))
9953 (clobber (reg:CC 17))]
9954 "reload_completed && !SSE_REG_P (operands[0])"
9955 [(parallel [(set (match_dup 0)
9956 (neg:SF (match_dup 1)))
9957 (clobber (reg:CC 17))])])
9958
9959 (define_split
9960 [(set (match_operand:SF 0 "register_operand" "")
9961 (neg:SF (match_operand:SF 1 "register_operand" "")))
9962 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9963 (clobber (reg:CC 17))]
9964 "reload_completed && SSE_REG_P (operands[0])"
9965 [(set (subreg:TI (match_dup 0) 0)
9966 (xor:TI (match_dup 1)
9967 (match_dup 2)))]
9968 {
9969 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9970 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9971 if (operands_match_p (operands[0], operands[2]))
9972 {
9973 rtx tmp;
9974 tmp = operands[1];
9975 operands[1] = operands[2];
9976 operands[2] = tmp;
9977 }
9978 })
9979
9980
9981 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9982 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9983 ;; to itself.
9984 (define_insn "*negsf2_if"
9985 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9986 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9987 (clobber (reg:CC 17))]
9988 "TARGET_80387 && !TARGET_SSE
9989 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9990 "#")
9991
9992 (define_split
9993 [(set (match_operand:SF 0 "fp_register_operand" "")
9994 (neg:SF (match_operand:SF 1 "register_operand" "")))
9995 (clobber (reg:CC 17))]
9996 "TARGET_80387 && reload_completed"
9997 [(set (match_dup 0)
9998 (neg:SF (match_dup 1)))]
9999 "")
10000
10001 (define_split
10002 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10003 (neg:SF (match_operand:SF 1 "register_operand" "")))
10004 (clobber (reg:CC 17))]
10005 "TARGET_80387 && reload_completed"
10006 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10007 (clobber (reg:CC 17))])]
10008 "operands[1] = gen_int_mode (0x80000000, SImode);
10009 operands[0] = gen_lowpart (SImode, operands[0]);")
10010
10011 (define_split
10012 [(set (match_operand 0 "memory_operand" "")
10013 (neg (match_operand 1 "memory_operand" "")))
10014 (clobber (reg:CC 17))]
10015 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10016 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
10017 (clobber (reg:CC 17))])]
10018 {
10019 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10020
10021 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10022 if (size >= 12)
10023 size = 10;
10024 operands[0] = adjust_address (operands[0], QImode, size - 1);
10025 operands[1] = gen_int_mode (0x80, QImode);
10026 })
10027
10028 (define_expand "negdf2"
10029 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10030 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10031 (clobber (reg:CC 17))])]
10032 "TARGET_80387"
10033 "if (TARGET_SSE2)
10034 {
10035 /* In case operand is in memory, we will not use SSE. */
10036 if (memory_operand (operands[0], VOIDmode)
10037 && rtx_equal_p (operands[0], operands[1]))
10038 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
10039 else
10040 {
10041 /* Using SSE is tricky, since we need bitwise negation of -0
10042 in register. */
10043 rtx reg;
10044 #if HOST_BITS_PER_WIDE_INT >= 64
10045 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
10046 #else
10047 rtx imm = immed_double_const (0, 0x80000000, DImode);
10048 #endif
10049 rtx dest = operands[0];
10050
10051 operands[1] = force_reg (DFmode, operands[1]);
10052 operands[0] = force_reg (DFmode, operands[0]);
10053 imm = gen_lowpart (DFmode, imm);
10054 reg = force_reg (V2DFmode,
10055 gen_rtx_CONST_VECTOR (V2DFmode,
10056 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10057 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
10058 if (dest != operands[0])
10059 emit_move_insn (dest, operands[0]);
10060 }
10061 DONE;
10062 }
10063 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
10064
10065 (define_insn "negdf2_memory"
10066 [(set (match_operand:DF 0 "memory_operand" "=m")
10067 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
10068 (clobber (reg:CC 17))]
10069 "ix86_unary_operator_ok (NEG, DFmode, operands)"
10070 "#")
10071
10072 (define_insn "negdf2_ifs"
10073 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
10074 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10075 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10076 (clobber (reg:CC 17))]
10077 "!TARGET_64BIT && TARGET_SSE2
10078 && (reload_in_progress || reload_completed
10079 || (register_operand (operands[0], VOIDmode)
10080 && register_operand (operands[1], VOIDmode)))"
10081 "#")
10082
10083 (define_insn "*negdf2_ifs_rex64"
10084 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
10085 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10086 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10087 (clobber (reg:CC 17))]
10088 "TARGET_64BIT && TARGET_SSE2
10089 && (reload_in_progress || reload_completed
10090 || (register_operand (operands[0], VOIDmode)
10091 && register_operand (operands[1], VOIDmode)))"
10092 "#")
10093
10094 (define_split
10095 [(set (match_operand:DF 0 "memory_operand" "")
10096 (neg:DF (match_operand:DF 1 "memory_operand" "")))
10097 (use (match_operand:V2DF 2 "" ""))
10098 (clobber (reg:CC 17))]
10099 ""
10100 [(parallel [(set (match_dup 0)
10101 (neg:DF (match_dup 1)))
10102 (clobber (reg:CC 17))])])
10103
10104 (define_split
10105 [(set (match_operand:DF 0 "register_operand" "")
10106 (neg:DF (match_operand:DF 1 "register_operand" "")))
10107 (use (match_operand:V2DF 2 "" ""))
10108 (clobber (reg:CC 17))]
10109 "reload_completed && !SSE_REG_P (operands[0])
10110 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
10111 [(parallel [(set (match_dup 0)
10112 (neg:DF (match_dup 1)))
10113 (clobber (reg:CC 17))])])
10114
10115 (define_split
10116 [(set (match_operand:DF 0 "register_operand" "")
10117 (neg:DF (match_operand:DF 1 "register_operand" "")))
10118 (use (match_operand:V2DF 2 "" ""))
10119 (clobber (reg:CC 17))]
10120 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
10121 [(parallel [(set (match_dup 0)
10122 (xor:DI (match_dup 1) (match_dup 2)))
10123 (clobber (reg:CC 17))])]
10124 "operands[0] = gen_lowpart (DImode, operands[0]);
10125 operands[1] = gen_lowpart (DImode, operands[1]);
10126 operands[2] = gen_lowpart (DImode, operands[2]);")
10127
10128 (define_split
10129 [(set (match_operand:DF 0 "register_operand" "")
10130 (neg:DF (match_operand:DF 1 "register_operand" "")))
10131 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10132 (clobber (reg:CC 17))]
10133 "reload_completed && SSE_REG_P (operands[0])"
10134 [(set (subreg:TI (match_dup 0) 0)
10135 (xor:TI (match_dup 1)
10136 (match_dup 2)))]
10137 {
10138 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10139 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10140 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10141 /* Avoid possible reformatting on the operands. */
10142 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10143 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10144 if (operands_match_p (operands[0], operands[2]))
10145 {
10146 rtx tmp;
10147 tmp = operands[1];
10148 operands[1] = operands[2];
10149 operands[2] = tmp;
10150 }
10151 })
10152
10153 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10154 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10155 ;; to itself.
10156 (define_insn "*negdf2_if"
10157 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10158 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10159 (clobber (reg:CC 17))]
10160 "!TARGET_64BIT && TARGET_80387
10161 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10162 "#")
10163
10164 ;; FIXME: We should to allow integer registers here. Problem is that
10165 ;; we need another scratch register to get constant from.
10166 ;; Forcing constant to mem if no register available in peep2 should be
10167 ;; safe even for PIC mode, because of RIP relative addressing.
10168 (define_insn "*negdf2_if_rex64"
10169 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10170 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10171 (clobber (reg:CC 17))]
10172 "TARGET_64BIT && TARGET_80387
10173 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10174 "#")
10175
10176 (define_split
10177 [(set (match_operand:DF 0 "fp_register_operand" "")
10178 (neg:DF (match_operand:DF 1 "register_operand" "")))
10179 (clobber (reg:CC 17))]
10180 "TARGET_80387 && reload_completed"
10181 [(set (match_dup 0)
10182 (neg:DF (match_dup 1)))]
10183 "")
10184
10185 (define_split
10186 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10187 (neg:DF (match_operand:DF 1 "register_operand" "")))
10188 (clobber (reg:CC 17))]
10189 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10190 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
10191 (clobber (reg:CC 17))])]
10192 "operands[4] = gen_int_mode (0x80000000, SImode);
10193 split_di (operands+0, 1, operands+2, operands+3);")
10194
10195 (define_expand "negxf2"
10196 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10197 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10198 (clobber (reg:CC 17))])]
10199 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10200 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
10201
10202 (define_expand "negtf2"
10203 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10204 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10205 (clobber (reg:CC 17))])]
10206 "TARGET_80387"
10207 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
10208
10209 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10210 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10211 ;; to itself.
10212 (define_insn "*negxf2_if"
10213 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10214 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10215 (clobber (reg:CC 17))]
10216 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10217 && ix86_unary_operator_ok (NEG, XFmode, operands)"
10218 "#")
10219
10220 (define_split
10221 [(set (match_operand:XF 0 "fp_register_operand" "")
10222 (neg:XF (match_operand:XF 1 "register_operand" "")))
10223 (clobber (reg:CC 17))]
10224 "TARGET_80387 && reload_completed"
10225 [(set (match_dup 0)
10226 (neg:XF (match_dup 1)))]
10227 "")
10228
10229 (define_split
10230 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10231 (neg:XF (match_operand:XF 1 "register_operand" "")))
10232 (clobber (reg:CC 17))]
10233 "TARGET_80387 && reload_completed"
10234 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10235 (clobber (reg:CC 17))])]
10236 "operands[1] = GEN_INT (0x8000);
10237 operands[0] = gen_rtx_REG (SImode,
10238 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10239
10240 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10241 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10242 ;; to itself.
10243 (define_insn "*negtf2_if"
10244 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10245 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10246 (clobber (reg:CC 17))]
10247 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
10248 "#")
10249
10250 (define_split
10251 [(set (match_operand:TF 0 "fp_register_operand" "")
10252 (neg:TF (match_operand:TF 1 "register_operand" "")))
10253 (clobber (reg:CC 17))]
10254 "TARGET_80387 && reload_completed"
10255 [(set (match_dup 0)
10256 (neg:TF (match_dup 1)))]
10257 "")
10258
10259 (define_split
10260 [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
10261 (neg:TF (match_operand:TF 1 "register_operand" "")))
10262 (clobber (reg:CC 17))]
10263 "TARGET_80387 && reload_completed"
10264 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10265 (clobber (reg:CC 17))])]
10266 "operands[1] = GEN_INT (0x8000);
10267 operands[0] = gen_rtx_REG (SImode,
10268 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10269
10270 ;; Conditionalize these after reload. If they matches before reload, we
10271 ;; lose the clobber and ability to use integer instructions.
10272
10273 (define_insn "*negsf2_1"
10274 [(set (match_operand:SF 0 "register_operand" "=f")
10275 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10276 "TARGET_80387 && reload_completed"
10277 "fchs"
10278 [(set_attr "type" "fsgn")
10279 (set_attr "mode" "SF")
10280 (set_attr "ppro_uops" "few")])
10281
10282 (define_insn "*negdf2_1"
10283 [(set (match_operand:DF 0 "register_operand" "=f")
10284 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10285 "TARGET_80387 && reload_completed"
10286 "fchs"
10287 [(set_attr "type" "fsgn")
10288 (set_attr "mode" "DF")
10289 (set_attr "ppro_uops" "few")])
10290
10291 (define_insn "*negextendsfdf2"
10292 [(set (match_operand:DF 0 "register_operand" "=f")
10293 (neg:DF (float_extend:DF
10294 (match_operand:SF 1 "register_operand" "0"))))]
10295 "TARGET_80387"
10296 "fchs"
10297 [(set_attr "type" "fsgn")
10298 (set_attr "mode" "DF")
10299 (set_attr "ppro_uops" "few")])
10300
10301 (define_insn "*negxf2_1"
10302 [(set (match_operand:XF 0 "register_operand" "=f")
10303 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10304 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10305 "fchs"
10306 [(set_attr "type" "fsgn")
10307 (set_attr "mode" "XF")
10308 (set_attr "ppro_uops" "few")])
10309
10310 (define_insn "*negextenddfxf2"
10311 [(set (match_operand:XF 0 "register_operand" "=f")
10312 (neg:XF (float_extend:XF
10313 (match_operand:DF 1 "register_operand" "0"))))]
10314 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10315 "fchs"
10316 [(set_attr "type" "fsgn")
10317 (set_attr "mode" "XF")
10318 (set_attr "ppro_uops" "few")])
10319
10320 (define_insn "*negextendsfxf2"
10321 [(set (match_operand:XF 0 "register_operand" "=f")
10322 (neg:XF (float_extend:XF
10323 (match_operand:SF 1 "register_operand" "0"))))]
10324 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10325 "fchs"
10326 [(set_attr "type" "fsgn")
10327 (set_attr "mode" "XF")
10328 (set_attr "ppro_uops" "few")])
10329
10330 (define_insn "*negtf2_1"
10331 [(set (match_operand:TF 0 "register_operand" "=f")
10332 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
10333 "TARGET_80387 && reload_completed"
10334 "fchs"
10335 [(set_attr "type" "fsgn")
10336 (set_attr "mode" "XF")
10337 (set_attr "ppro_uops" "few")])
10338
10339 (define_insn "*negextenddftf2"
10340 [(set (match_operand:TF 0 "register_operand" "=f")
10341 (neg:TF (float_extend:TF
10342 (match_operand:DF 1 "register_operand" "0"))))]
10343 "TARGET_80387"
10344 "fchs"
10345 [(set_attr "type" "fsgn")
10346 (set_attr "mode" "XF")
10347 (set_attr "ppro_uops" "few")])
10348
10349 (define_insn "*negextendsftf2"
10350 [(set (match_operand:TF 0 "register_operand" "=f")
10351 (neg:TF (float_extend:TF
10352 (match_operand:SF 1 "register_operand" "0"))))]
10353 "TARGET_80387"
10354 "fchs"
10355 [(set_attr "type" "fsgn")
10356 (set_attr "mode" "XF")
10357 (set_attr "ppro_uops" "few")])
10358 \f
10359 ;; Absolute value instructions
10360
10361 (define_expand "abssf2"
10362 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10363 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10364 (clobber (reg:CC 17))])]
10365 "TARGET_80387"
10366 "if (TARGET_SSE)
10367 {
10368 /* In case operand is in memory, we will not use SSE. */
10369 if (memory_operand (operands[0], VOIDmode)
10370 && rtx_equal_p (operands[0], operands[1]))
10371 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10372 else
10373 {
10374 /* Using SSE is tricky, since we need bitwise negation of -0
10375 in register. */
10376 rtx reg = gen_reg_rtx (V4SFmode);
10377 rtx dest = operands[0];
10378 rtx imm;
10379
10380 operands[1] = force_reg (SFmode, operands[1]);
10381 operands[0] = force_reg (SFmode, operands[0]);
10382 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10383 reg = force_reg (V4SFmode,
10384 gen_rtx_CONST_VECTOR (V4SFmode,
10385 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10386 CONST0_RTX (SFmode),
10387 CONST0_RTX (SFmode))));
10388 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10389 if (dest != operands[0])
10390 emit_move_insn (dest, operands[0]);
10391 }
10392 DONE;
10393 }
10394 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10395
10396 (define_insn "abssf2_memory"
10397 [(set (match_operand:SF 0 "memory_operand" "=m")
10398 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10399 (clobber (reg:CC 17))]
10400 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10401 "#")
10402
10403 (define_insn "abssf2_ifs"
10404 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10405 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10406 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10407 (clobber (reg:CC 17))]
10408 "TARGET_SSE
10409 && (reload_in_progress || reload_completed
10410 || (register_operand (operands[0], VOIDmode)
10411 && register_operand (operands[1], VOIDmode)))"
10412 "#")
10413
10414 (define_split
10415 [(set (match_operand:SF 0 "memory_operand" "")
10416 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10417 (use (match_operand:V4SF 2 "" ""))
10418 (clobber (reg:CC 17))]
10419 ""
10420 [(parallel [(set (match_dup 0)
10421 (abs:SF (match_dup 1)))
10422 (clobber (reg:CC 17))])])
10423
10424 (define_split
10425 [(set (match_operand:SF 0 "register_operand" "")
10426 (abs:SF (match_operand:SF 1 "register_operand" "")))
10427 (use (match_operand:V4SF 2 "" ""))
10428 (clobber (reg:CC 17))]
10429 "reload_completed && !SSE_REG_P (operands[0])"
10430 [(parallel [(set (match_dup 0)
10431 (abs:SF (match_dup 1)))
10432 (clobber (reg:CC 17))])])
10433
10434 (define_split
10435 [(set (match_operand:SF 0 "register_operand" "")
10436 (abs:SF (match_operand:SF 1 "register_operand" "")))
10437 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10438 (clobber (reg:CC 17))]
10439 "reload_completed && SSE_REG_P (operands[0])"
10440 [(set (subreg:TI (match_dup 0) 0)
10441 (and:TI (match_dup 1)
10442 (match_dup 2)))]
10443 {
10444 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10445 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10446 if (operands_match_p (operands[0], operands[2]))
10447 {
10448 rtx tmp;
10449 tmp = operands[1];
10450 operands[1] = operands[2];
10451 operands[2] = tmp;
10452 }
10453 })
10454
10455 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10456 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10457 ;; to itself.
10458 (define_insn "*abssf2_if"
10459 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10460 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10461 (clobber (reg:CC 17))]
10462 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10463 "#")
10464
10465 (define_split
10466 [(set (match_operand:SF 0 "fp_register_operand" "")
10467 (abs:SF (match_operand:SF 1 "register_operand" "")))
10468 (clobber (reg:CC 17))]
10469 "TARGET_80387 && reload_completed"
10470 [(set (match_dup 0)
10471 (abs:SF (match_dup 1)))]
10472 "")
10473
10474 (define_split
10475 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10476 (abs:SF (match_operand:SF 1 "register_operand" "")))
10477 (clobber (reg:CC 17))]
10478 "TARGET_80387 && reload_completed"
10479 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10480 (clobber (reg:CC 17))])]
10481 "operands[1] = gen_int_mode (~0x80000000, SImode);
10482 operands[0] = gen_lowpart (SImode, operands[0]);")
10483
10484 (define_split
10485 [(set (match_operand 0 "memory_operand" "")
10486 (abs (match_operand 1 "memory_operand" "")))
10487 (clobber (reg:CC 17))]
10488 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10489 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10490 (clobber (reg:CC 17))])]
10491 {
10492 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10493
10494 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10495 if (size >= 12)
10496 size = 10;
10497 operands[0] = adjust_address (operands[0], QImode, size - 1);
10498 operands[1] = gen_int_mode (~0x80, QImode);
10499 })
10500
10501 (define_expand "absdf2"
10502 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10503 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10504 (clobber (reg:CC 17))])]
10505 "TARGET_80387"
10506 "if (TARGET_SSE2)
10507 {
10508 /* In case operand is in memory, we will not use SSE. */
10509 if (memory_operand (operands[0], VOIDmode)
10510 && rtx_equal_p (operands[0], operands[1]))
10511 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10512 else
10513 {
10514 /* Using SSE is tricky, since we need bitwise negation of -0
10515 in register. */
10516 rtx reg = gen_reg_rtx (V2DFmode);
10517 #if HOST_BITS_PER_WIDE_INT >= 64
10518 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10519 #else
10520 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10521 #endif
10522 rtx dest = operands[0];
10523
10524 operands[1] = force_reg (DFmode, operands[1]);
10525 operands[0] = force_reg (DFmode, operands[0]);
10526
10527 /* Produce LONG_DOUBLE with the proper immediate argument. */
10528 imm = gen_lowpart (DFmode, imm);
10529 reg = force_reg (V2DFmode,
10530 gen_rtx_CONST_VECTOR (V2DFmode,
10531 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10532 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10533 if (dest != operands[0])
10534 emit_move_insn (dest, operands[0]);
10535 }
10536 DONE;
10537 }
10538 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10539
10540 (define_insn "absdf2_memory"
10541 [(set (match_operand:DF 0 "memory_operand" "=m")
10542 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10543 (clobber (reg:CC 17))]
10544 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10545 "#")
10546
10547 (define_insn "absdf2_ifs"
10548 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10549 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10550 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10551 (clobber (reg:CC 17))]
10552 "!TARGET_64BIT && TARGET_SSE2
10553 && (reload_in_progress || reload_completed
10554 || (register_operand (operands[0], VOIDmode)
10555 && register_operand (operands[1], VOIDmode)))"
10556 "#")
10557
10558 (define_insn "*absdf2_ifs_rex64"
10559 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10560 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10561 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10562 (clobber (reg:CC 17))]
10563 "TARGET_64BIT && TARGET_SSE2
10564 && (reload_in_progress || reload_completed
10565 || (register_operand (operands[0], VOIDmode)
10566 && register_operand (operands[1], VOIDmode)))"
10567 "#")
10568
10569 (define_split
10570 [(set (match_operand:DF 0 "memory_operand" "")
10571 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10572 (use (match_operand:V2DF 2 "" ""))
10573 (clobber (reg:CC 17))]
10574 ""
10575 [(parallel [(set (match_dup 0)
10576 (abs:DF (match_dup 1)))
10577 (clobber (reg:CC 17))])])
10578
10579 (define_split
10580 [(set (match_operand:DF 0 "register_operand" "")
10581 (abs:DF (match_operand:DF 1 "register_operand" "")))
10582 (use (match_operand:V2DF 2 "" ""))
10583 (clobber (reg:CC 17))]
10584 "reload_completed && !SSE_REG_P (operands[0])"
10585 [(parallel [(set (match_dup 0)
10586 (abs:DF (match_dup 1)))
10587 (clobber (reg:CC 17))])])
10588
10589 (define_split
10590 [(set (match_operand:DF 0 "register_operand" "")
10591 (abs:DF (match_operand:DF 1 "register_operand" "")))
10592 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10593 (clobber (reg:CC 17))]
10594 "reload_completed && SSE_REG_P (operands[0])"
10595 [(set (subreg:TI (match_dup 0) 0)
10596 (and:TI (match_dup 1)
10597 (match_dup 2)))]
10598 {
10599 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10600 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10601 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10602 /* Avoid possible reformatting on the operands. */
10603 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10604 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10605 if (operands_match_p (operands[0], operands[2]))
10606 {
10607 rtx tmp;
10608 tmp = operands[1];
10609 operands[1] = operands[2];
10610 operands[2] = tmp;
10611 }
10612 })
10613
10614
10615 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10616 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10617 ;; to itself.
10618 (define_insn "*absdf2_if"
10619 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10620 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10621 (clobber (reg:CC 17))]
10622 "!TARGET_64BIT && TARGET_80387
10623 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10624 "#")
10625
10626 ;; FIXME: We should to allow integer registers here. Problem is that
10627 ;; we need another scratch register to get constant from.
10628 ;; Forcing constant to mem if no register available in peep2 should be
10629 ;; safe even for PIC mode, because of RIP relative addressing.
10630 (define_insn "*absdf2_if_rex64"
10631 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10632 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10633 (clobber (reg:CC 17))]
10634 "TARGET_64BIT && TARGET_80387
10635 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10636 "#")
10637
10638 (define_split
10639 [(set (match_operand:DF 0 "fp_register_operand" "")
10640 (abs:DF (match_operand:DF 1 "register_operand" "")))
10641 (clobber (reg:CC 17))]
10642 "TARGET_80387 && reload_completed"
10643 [(set (match_dup 0)
10644 (abs:DF (match_dup 1)))]
10645 "")
10646
10647 (define_split
10648 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10649 (abs:DF (match_operand:DF 1 "register_operand" "")))
10650 (clobber (reg:CC 17))]
10651 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10652 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10653 (clobber (reg:CC 17))])]
10654 "operands[4] = gen_int_mode (~0x80000000, SImode);
10655 split_di (operands+0, 1, operands+2, operands+3);")
10656
10657 (define_expand "absxf2"
10658 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10659 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10660 (clobber (reg:CC 17))])]
10661 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10662 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10663
10664 (define_expand "abstf2"
10665 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10666 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10667 (clobber (reg:CC 17))])]
10668 "TARGET_80387"
10669 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10670
10671 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10672 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10673 ;; to itself.
10674 (define_insn "*absxf2_if"
10675 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10676 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10677 (clobber (reg:CC 17))]
10678 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10679 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10680 "#")
10681
10682 (define_split
10683 [(set (match_operand:XF 0 "fp_register_operand" "")
10684 (abs:XF (match_operand:XF 1 "register_operand" "")))
10685 (clobber (reg:CC 17))]
10686 "TARGET_80387 && reload_completed"
10687 [(set (match_dup 0)
10688 (abs:XF (match_dup 1)))]
10689 "")
10690
10691 (define_split
10692 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10693 (abs:XF (match_operand:XF 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 "*abstf2_if"
10703 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10704 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10705 (clobber (reg:CC 17))]
10706 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10707 "#")
10708
10709 (define_split
10710 [(set (match_operand:TF 0 "fp_register_operand" "")
10711 (abs:TF (match_operand:TF 1 "register_operand" "")))
10712 (clobber (reg:CC 17))]
10713 "TARGET_80387 && reload_completed"
10714 [(set (match_dup 0)
10715 (abs:TF (match_dup 1)))]
10716 "")
10717
10718 (define_split
10719 [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
10720 (abs:TF (match_operand:TF 1 "register_operand" "")))
10721 (clobber (reg:CC 17))]
10722 "TARGET_80387 && reload_completed"
10723 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10724 (clobber (reg:CC 17))])]
10725 "operands[1] = GEN_INT (~0x8000);
10726 operands[0] = gen_rtx_REG (SImode,
10727 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10728
10729 (define_insn "*abssf2_1"
10730 [(set (match_operand:SF 0 "register_operand" "=f")
10731 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10732 "TARGET_80387 && reload_completed"
10733 "fabs"
10734 [(set_attr "type" "fsgn")
10735 (set_attr "mode" "SF")])
10736
10737 (define_insn "*absdf2_1"
10738 [(set (match_operand:DF 0 "register_operand" "=f")
10739 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10740 "TARGET_80387 && reload_completed"
10741 "fabs"
10742 [(set_attr "type" "fsgn")
10743 (set_attr "mode" "DF")])
10744
10745 (define_insn "*absextendsfdf2"
10746 [(set (match_operand:DF 0 "register_operand" "=f")
10747 (abs:DF (float_extend:DF
10748 (match_operand:SF 1 "register_operand" "0"))))]
10749 "TARGET_80387"
10750 "fabs"
10751 [(set_attr "type" "fsgn")
10752 (set_attr "mode" "DF")])
10753
10754 (define_insn "*absxf2_1"
10755 [(set (match_operand:XF 0 "register_operand" "=f")
10756 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10757 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10758 "fabs"
10759 [(set_attr "type" "fsgn")
10760 (set_attr "mode" "DF")])
10761
10762 (define_insn "*absextenddfxf2"
10763 [(set (match_operand:XF 0 "register_operand" "=f")
10764 (abs:XF (float_extend:XF
10765 (match_operand:DF 1 "register_operand" "0"))))]
10766 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10767 "fabs"
10768 [(set_attr "type" "fsgn")
10769 (set_attr "mode" "XF")])
10770
10771 (define_insn "*absextendsfxf2"
10772 [(set (match_operand:XF 0 "register_operand" "=f")
10773 (abs:XF (float_extend:XF
10774 (match_operand:SF 1 "register_operand" "0"))))]
10775 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10776 "fabs"
10777 [(set_attr "type" "fsgn")
10778 (set_attr "mode" "XF")])
10779
10780 (define_insn "*abstf2_1"
10781 [(set (match_operand:TF 0 "register_operand" "=f")
10782 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10783 "TARGET_80387 && reload_completed"
10784 "fabs"
10785 [(set_attr "type" "fsgn")
10786 (set_attr "mode" "DF")])
10787
10788 (define_insn "*absextenddftf2"
10789 [(set (match_operand:TF 0 "register_operand" "=f")
10790 (abs:TF (float_extend:TF
10791 (match_operand:DF 1 "register_operand" "0"))))]
10792 "TARGET_80387"
10793 "fabs"
10794 [(set_attr "type" "fsgn")
10795 (set_attr "mode" "XF")])
10796
10797 (define_insn "*absextendsftf2"
10798 [(set (match_operand:TF 0 "register_operand" "=f")
10799 (abs:TF (float_extend:TF
10800 (match_operand:SF 1 "register_operand" "0"))))]
10801 "TARGET_80387"
10802 "fabs"
10803 [(set_attr "type" "fsgn")
10804 (set_attr "mode" "XF")])
10805 \f
10806 ;; One complement instructions
10807
10808 (define_expand "one_cmpldi2"
10809 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10810 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10811 "TARGET_64BIT"
10812 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10813
10814 (define_insn "*one_cmpldi2_1_rex64"
10815 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10816 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10817 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10818 "not{q}\t%0"
10819 [(set_attr "type" "negnot")
10820 (set_attr "mode" "DI")])
10821
10822 (define_insn "*one_cmpldi2_2_rex64"
10823 [(set (reg 17)
10824 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10825 (const_int 0)))
10826 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10827 (not:DI (match_dup 1)))]
10828 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10829 && ix86_unary_operator_ok (NOT, DImode, operands)"
10830 "#"
10831 [(set_attr "type" "alu1")
10832 (set_attr "mode" "DI")])
10833
10834 (define_split
10835 [(set (reg 17)
10836 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10837 (const_int 0)))
10838 (set (match_operand:DI 0 "nonimmediate_operand" "")
10839 (not:DI (match_dup 1)))]
10840 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10841 [(parallel [(set (reg:CCNO 17)
10842 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10843 (const_int 0)))
10844 (set (match_dup 0)
10845 (xor:DI (match_dup 1) (const_int -1)))])]
10846 "")
10847
10848 (define_expand "one_cmplsi2"
10849 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10850 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10851 ""
10852 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10853
10854 (define_insn "*one_cmplsi2_1"
10855 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10856 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10857 "ix86_unary_operator_ok (NOT, SImode, operands)"
10858 "not{l}\t%0"
10859 [(set_attr "type" "negnot")
10860 (set_attr "mode" "SI")])
10861
10862 ;; ??? Currently never generated - xor is used instead.
10863 (define_insn "*one_cmplsi2_1_zext"
10864 [(set (match_operand:DI 0 "register_operand" "=r")
10865 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10866 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10867 "not{l}\t%k0"
10868 [(set_attr "type" "negnot")
10869 (set_attr "mode" "SI")])
10870
10871 (define_insn "*one_cmplsi2_2"
10872 [(set (reg 17)
10873 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10874 (const_int 0)))
10875 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10876 (not:SI (match_dup 1)))]
10877 "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 "nonimmediate_operand" ""))
10886 (const_int 0)))
10887 (set (match_operand:SI 0 "nonimmediate_operand" "")
10888 (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 (xor:SI (match_dup 1) (const_int -1)))])]
10895 "")
10896
10897 ;; ??? Currently never generated - xor is used instead.
10898 (define_insn "*one_cmplsi2_2_zext"
10899 [(set (reg 17)
10900 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10901 (const_int 0)))
10902 (set (match_operand:DI 0 "register_operand" "=r")
10903 (zero_extend:DI (not:SI (match_dup 1))))]
10904 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10905 && ix86_unary_operator_ok (NOT, SImode, operands)"
10906 "#"
10907 [(set_attr "type" "alu1")
10908 (set_attr "mode" "SI")])
10909
10910 (define_split
10911 [(set (reg 17)
10912 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10913 (const_int 0)))
10914 (set (match_operand:DI 0 "register_operand" "")
10915 (zero_extend:DI (not:SI (match_dup 1))))]
10916 "ix86_match_ccmode (insn, CCNOmode)"
10917 [(parallel [(set (reg:CCNO 17)
10918 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10919 (const_int 0)))
10920 (set (match_dup 0)
10921 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10922 "")
10923
10924 (define_expand "one_cmplhi2"
10925 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10926 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10927 "TARGET_HIMODE_MATH"
10928 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10929
10930 (define_insn "*one_cmplhi2_1"
10931 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10932 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10933 "ix86_unary_operator_ok (NOT, HImode, operands)"
10934 "not{w}\t%0"
10935 [(set_attr "type" "negnot")
10936 (set_attr "mode" "HI")])
10937
10938 (define_insn "*one_cmplhi2_2"
10939 [(set (reg 17)
10940 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10941 (const_int 0)))
10942 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10943 (not:HI (match_dup 1)))]
10944 "ix86_match_ccmode (insn, CCNOmode)
10945 && ix86_unary_operator_ok (NEG, HImode, operands)"
10946 "#"
10947 [(set_attr "type" "alu1")
10948 (set_attr "mode" "HI")])
10949
10950 (define_split
10951 [(set (reg 17)
10952 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10953 (const_int 0)))
10954 (set (match_operand:HI 0 "nonimmediate_operand" "")
10955 (not:HI (match_dup 1)))]
10956 "ix86_match_ccmode (insn, CCNOmode)"
10957 [(parallel [(set (reg:CCNO 17)
10958 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10959 (const_int 0)))
10960 (set (match_dup 0)
10961 (xor:HI (match_dup 1) (const_int -1)))])]
10962 "")
10963
10964 ;; %%% Potential partial reg stall on alternative 1. What to do?
10965 (define_expand "one_cmplqi2"
10966 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10967 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10968 "TARGET_QIMODE_MATH"
10969 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10970
10971 (define_insn "*one_cmplqi2_1"
10972 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10973 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10974 "ix86_unary_operator_ok (NOT, QImode, operands)"
10975 "@
10976 not{b}\t%0
10977 not{l}\t%k0"
10978 [(set_attr "type" "negnot")
10979 (set_attr "mode" "QI,SI")])
10980
10981 (define_insn "*one_cmplqi2_2"
10982 [(set (reg 17)
10983 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10984 (const_int 0)))
10985 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10986 (not:QI (match_dup 1)))]
10987 "ix86_match_ccmode (insn, CCNOmode)
10988 && ix86_unary_operator_ok (NOT, QImode, operands)"
10989 "#"
10990 [(set_attr "type" "alu1")
10991 (set_attr "mode" "QI")])
10992
10993 (define_split
10994 [(set (reg 17)
10995 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10996 (const_int 0)))
10997 (set (match_operand:QI 0 "nonimmediate_operand" "")
10998 (not:QI (match_dup 1)))]
10999 "ix86_match_ccmode (insn, CCNOmode)"
11000 [(parallel [(set (reg:CCNO 17)
11001 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
11002 (const_int 0)))
11003 (set (match_dup 0)
11004 (xor:QI (match_dup 1) (const_int -1)))])]
11005 "")
11006 \f
11007 ;; Arithmetic shift instructions
11008
11009 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11010 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11011 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11012 ;; from the assembler input.
11013 ;;
11014 ;; This instruction shifts the target reg/mem as usual, but instead of
11015 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11016 ;; is a left shift double, bits are taken from the high order bits of
11017 ;; reg, else if the insn is a shift right double, bits are taken from the
11018 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11019 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11020 ;;
11021 ;; Since sh[lr]d does not change the `reg' operand, that is done
11022 ;; separately, making all shifts emit pairs of shift double and normal
11023 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11024 ;; support a 63 bit shift, each shift where the count is in a reg expands
11025 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11026 ;;
11027 ;; If the shift count is a constant, we need never emit more than one
11028 ;; shift pair, instead using moves and sign extension for counts greater
11029 ;; than 31.
11030
11031 (define_expand "ashldi3"
11032 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11033 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
11034 (match_operand:QI 2 "nonmemory_operand" "")))
11035 (clobber (reg:CC 17))])]
11036 ""
11037 {
11038 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11039 {
11040 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
11041 DONE;
11042 }
11043 ix86_expand_binary_operator (ASHIFT, DImode, operands);
11044 DONE;
11045 })
11046
11047 (define_insn "*ashldi3_1_rex64"
11048 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11049 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
11050 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11051 (clobber (reg:CC 17))]
11052 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11053 {
11054 switch (get_attr_type (insn))
11055 {
11056 case TYPE_ALU:
11057 if (operands[2] != const1_rtx)
11058 abort ();
11059 if (!rtx_equal_p (operands[0], operands[1]))
11060 abort ();
11061 return "add{q}\t{%0, %0|%0, %0}";
11062
11063 case TYPE_LEA:
11064 if (GET_CODE (operands[2]) != CONST_INT
11065 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
11066 abort ();
11067 operands[1] = gen_rtx_MULT (DImode, operands[1],
11068 GEN_INT (1 << INTVAL (operands[2])));
11069 return "lea{q}\t{%a1, %0|%0, %a1}";
11070
11071 default:
11072 if (REG_P (operands[2]))
11073 return "sal{q}\t{%b2, %0|%0, %b2}";
11074 else if (GET_CODE (operands[2]) == CONST_INT
11075 && INTVAL (operands[2]) == 1
11076 && (TARGET_SHIFT1 || optimize_size))
11077 return "sal{q}\t%0";
11078 else
11079 return "sal{q}\t{%2, %0|%0, %2}";
11080 }
11081 }
11082 [(set (attr "type")
11083 (cond [(eq_attr "alternative" "1")
11084 (const_string "lea")
11085 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11086 (const_int 0))
11087 (match_operand 0 "register_operand" ""))
11088 (match_operand 2 "const1_operand" ""))
11089 (const_string "alu")
11090 ]
11091 (const_string "ishift")))
11092 (set_attr "mode" "DI")])
11093
11094 ;; Convert lea to the lea pattern to avoid flags dependency.
11095 (define_split
11096 [(set (match_operand:DI 0 "register_operand" "")
11097 (ashift:DI (match_operand:DI 1 "register_operand" "")
11098 (match_operand:QI 2 "immediate_operand" "")))
11099 (clobber (reg:CC 17))]
11100 "TARGET_64BIT && reload_completed
11101 && true_regnum (operands[0]) != true_regnum (operands[1])"
11102 [(set (match_dup 0)
11103 (mult:DI (match_dup 1)
11104 (match_dup 2)))]
11105 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11106
11107 ;; This pattern can't accept a variable shift count, since shifts by
11108 ;; zero don't affect the flags. We assume that shifts by constant
11109 ;; zero are optimized away.
11110 (define_insn "*ashldi3_cmp_rex64"
11111 [(set (reg 17)
11112 (compare
11113 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11114 (match_operand:QI 2 "immediate_operand" "e"))
11115 (const_int 0)))
11116 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11117 (ashift:DI (match_dup 1) (match_dup 2)))]
11118 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11119 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11120 {
11121 switch (get_attr_type (insn))
11122 {
11123 case TYPE_ALU:
11124 if (operands[2] != const1_rtx)
11125 abort ();
11126 return "add{q}\t{%0, %0|%0, %0}";
11127
11128 default:
11129 if (REG_P (operands[2]))
11130 return "sal{q}\t{%b2, %0|%0, %b2}";
11131 else if (GET_CODE (operands[2]) == CONST_INT
11132 && INTVAL (operands[2]) == 1
11133 && (TARGET_SHIFT1 || optimize_size))
11134 return "sal{q}\t%0";
11135 else
11136 return "sal{q}\t{%2, %0|%0, %2}";
11137 }
11138 }
11139 [(set (attr "type")
11140 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11141 (const_int 0))
11142 (match_operand 0 "register_operand" ""))
11143 (match_operand 2 "const1_operand" ""))
11144 (const_string "alu")
11145 ]
11146 (const_string "ishift")))
11147 (set_attr "mode" "DI")])
11148
11149 (define_insn "ashldi3_1"
11150 [(set (match_operand:DI 0 "register_operand" "=r")
11151 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11152 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11153 (clobber (match_scratch:SI 3 "=&r"))
11154 (clobber (reg:CC 17))]
11155 "!TARGET_64BIT && TARGET_CMOVE"
11156 "#"
11157 [(set_attr "type" "multi")])
11158
11159 (define_insn "*ashldi3_2"
11160 [(set (match_operand:DI 0 "register_operand" "=r")
11161 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11162 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11163 (clobber (reg:CC 17))]
11164 "!TARGET_64BIT"
11165 "#"
11166 [(set_attr "type" "multi")])
11167
11168 (define_split
11169 [(set (match_operand:DI 0 "register_operand" "")
11170 (ashift:DI (match_operand:DI 1 "register_operand" "")
11171 (match_operand:QI 2 "nonmemory_operand" "")))
11172 (clobber (match_scratch:SI 3 ""))
11173 (clobber (reg:CC 17))]
11174 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11175 [(const_int 0)]
11176 "ix86_split_ashldi (operands, operands[3]); DONE;")
11177
11178 (define_split
11179 [(set (match_operand:DI 0 "register_operand" "")
11180 (ashift:DI (match_operand:DI 1 "register_operand" "")
11181 (match_operand:QI 2 "nonmemory_operand" "")))
11182 (clobber (reg:CC 17))]
11183 "!TARGET_64BIT && reload_completed"
11184 [(const_int 0)]
11185 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
11186
11187 (define_insn "x86_shld_1"
11188 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11189 (ior:SI (ashift:SI (match_dup 0)
11190 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11191 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11192 (minus:QI (const_int 32) (match_dup 2)))))
11193 (clobber (reg:CC 17))]
11194 ""
11195 "@
11196 shld{l}\t{%2, %1, %0|%0, %1, %2}
11197 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11198 [(set_attr "type" "ishift")
11199 (set_attr "prefix_0f" "1")
11200 (set_attr "mode" "SI")
11201 (set_attr "pent_pair" "np")
11202 (set_attr "athlon_decode" "vector")
11203 (set_attr "ppro_uops" "few")])
11204
11205 (define_expand "x86_shift_adj_1"
11206 [(set (reg:CCZ 17)
11207 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11208 (const_int 32))
11209 (const_int 0)))
11210 (set (match_operand:SI 0 "register_operand" "")
11211 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11212 (match_operand:SI 1 "register_operand" "")
11213 (match_dup 0)))
11214 (set (match_dup 1)
11215 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11216 (match_operand:SI 3 "register_operand" "r")
11217 (match_dup 1)))]
11218 "TARGET_CMOVE"
11219 "")
11220
11221 (define_expand "x86_shift_adj_2"
11222 [(use (match_operand:SI 0 "register_operand" ""))
11223 (use (match_operand:SI 1 "register_operand" ""))
11224 (use (match_operand:QI 2 "register_operand" ""))]
11225 ""
11226 {
11227 rtx label = gen_label_rtx ();
11228 rtx tmp;
11229
11230 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11231
11232 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11233 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11234 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11235 gen_rtx_LABEL_REF (VOIDmode, label),
11236 pc_rtx);
11237 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11238 JUMP_LABEL (tmp) = label;
11239
11240 emit_move_insn (operands[0], operands[1]);
11241 emit_move_insn (operands[1], const0_rtx);
11242
11243 emit_label (label);
11244 LABEL_NUSES (label) = 1;
11245
11246 DONE;
11247 })
11248
11249 (define_expand "ashlsi3"
11250 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11251 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11252 (match_operand:QI 2 "nonmemory_operand" "")))
11253 (clobber (reg:CC 17))]
11254 ""
11255 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11256
11257 (define_insn "*ashlsi3_1"
11258 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11259 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
11260 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11261 (clobber (reg:CC 17))]
11262 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11263 {
11264 switch (get_attr_type (insn))
11265 {
11266 case TYPE_ALU:
11267 if (operands[2] != const1_rtx)
11268 abort ();
11269 if (!rtx_equal_p (operands[0], operands[1]))
11270 abort ();
11271 return "add{l}\t{%0, %0|%0, %0}";
11272
11273 case TYPE_LEA:
11274 return "#";
11275
11276 default:
11277 if (REG_P (operands[2]))
11278 return "sal{l}\t{%b2, %0|%0, %b2}";
11279 else if (GET_CODE (operands[2]) == CONST_INT
11280 && INTVAL (operands[2]) == 1
11281 && (TARGET_SHIFT1 || optimize_size))
11282 return "sal{l}\t%0";
11283 else
11284 return "sal{l}\t{%2, %0|%0, %2}";
11285 }
11286 }
11287 [(set (attr "type")
11288 (cond [(eq_attr "alternative" "1")
11289 (const_string "lea")
11290 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11291 (const_int 0))
11292 (match_operand 0 "register_operand" ""))
11293 (match_operand 2 "const1_operand" ""))
11294 (const_string "alu")
11295 ]
11296 (const_string "ishift")))
11297 (set_attr "mode" "SI")])
11298
11299 ;; Convert lea to the lea pattern to avoid flags dependency.
11300 (define_split
11301 [(set (match_operand 0 "register_operand" "")
11302 (ashift (match_operand 1 "index_register_operand" "")
11303 (match_operand:QI 2 "const_int_operand" "")))
11304 (clobber (reg:CC 17))]
11305 "reload_completed
11306 && true_regnum (operands[0]) != true_regnum (operands[1])"
11307 [(const_int 0)]
11308 {
11309 rtx pat;
11310 operands[0] = gen_lowpart (SImode, operands[0]);
11311 operands[1] = gen_lowpart (Pmode, operands[1]);
11312 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11313 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11314 if (Pmode != SImode)
11315 pat = gen_rtx_SUBREG (SImode, pat, 0);
11316 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11317 DONE;
11318 })
11319
11320 ;; Rare case of shifting RSP is handled by generating move and shift
11321 (define_split
11322 [(set (match_operand 0 "register_operand" "")
11323 (ashift (match_operand 1 "register_operand" "")
11324 (match_operand:QI 2 "const_int_operand" "")))
11325 (clobber (reg:CC 17))]
11326 "reload_completed
11327 && true_regnum (operands[0]) != true_regnum (operands[1])"
11328 [(const_int 0)]
11329 {
11330 rtx pat, clob;
11331 emit_move_insn (operands[1], operands[0]);
11332 pat = gen_rtx_SET (VOIDmode, operands[0],
11333 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11334 operands[0], operands[2]));
11335 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11336 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11337 DONE;
11338 })
11339
11340 (define_insn "*ashlsi3_1_zext"
11341 [(set (match_operand:DI 0 "register_operand" "=r,r")
11342 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
11343 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11344 (clobber (reg:CC 17))]
11345 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11346 {
11347 switch (get_attr_type (insn))
11348 {
11349 case TYPE_ALU:
11350 if (operands[2] != const1_rtx)
11351 abort ();
11352 return "add{l}\t{%k0, %k0|%k0, %k0}";
11353
11354 case TYPE_LEA:
11355 return "#";
11356
11357 default:
11358 if (REG_P (operands[2]))
11359 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11360 else if (GET_CODE (operands[2]) == CONST_INT
11361 && INTVAL (operands[2]) == 1
11362 && (TARGET_SHIFT1 || optimize_size))
11363 return "sal{l}\t%k0";
11364 else
11365 return "sal{l}\t{%2, %k0|%k0, %2}";
11366 }
11367 }
11368 [(set (attr "type")
11369 (cond [(eq_attr "alternative" "1")
11370 (const_string "lea")
11371 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11372 (const_int 0))
11373 (match_operand 2 "const1_operand" ""))
11374 (const_string "alu")
11375 ]
11376 (const_string "ishift")))
11377 (set_attr "mode" "SI")])
11378
11379 ;; Convert lea to the lea pattern to avoid flags dependency.
11380 (define_split
11381 [(set (match_operand:DI 0 "register_operand" "")
11382 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11383 (match_operand:QI 2 "const_int_operand" ""))))
11384 (clobber (reg:CC 17))]
11385 "TARGET_64BIT && reload_completed
11386 && true_regnum (operands[0]) != true_regnum (operands[1])"
11387 [(set (match_dup 0) (zero_extend:DI
11388 (subreg:SI (mult:SI (match_dup 1)
11389 (match_dup 2)) 0)))]
11390 {
11391 operands[1] = gen_lowpart (Pmode, operands[1]);
11392 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11393 })
11394
11395 ;; This pattern can't accept a variable shift count, since shifts by
11396 ;; zero don't affect the flags. We assume that shifts by constant
11397 ;; zero are optimized away.
11398 (define_insn "*ashlsi3_cmp"
11399 [(set (reg 17)
11400 (compare
11401 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11402 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11403 (const_int 0)))
11404 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11405 (ashift:SI (match_dup 1) (match_dup 2)))]
11406 "ix86_match_ccmode (insn, CCGOCmode)
11407 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11408 {
11409 switch (get_attr_type (insn))
11410 {
11411 case TYPE_ALU:
11412 if (operands[2] != const1_rtx)
11413 abort ();
11414 return "add{l}\t{%0, %0|%0, %0}";
11415
11416 default:
11417 if (REG_P (operands[2]))
11418 return "sal{l}\t{%b2, %0|%0, %b2}";
11419 else if (GET_CODE (operands[2]) == CONST_INT
11420 && INTVAL (operands[2]) == 1
11421 && (TARGET_SHIFT1 || optimize_size))
11422 return "sal{l}\t%0";
11423 else
11424 return "sal{l}\t{%2, %0|%0, %2}";
11425 }
11426 }
11427 [(set (attr "type")
11428 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11429 (const_int 0))
11430 (match_operand 0 "register_operand" ""))
11431 (match_operand 2 "const1_operand" ""))
11432 (const_string "alu")
11433 ]
11434 (const_string "ishift")))
11435 (set_attr "mode" "SI")])
11436
11437 (define_insn "*ashlsi3_cmp_zext"
11438 [(set (reg 17)
11439 (compare
11440 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11441 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11442 (const_int 0)))
11443 (set (match_operand:DI 0 "register_operand" "=r")
11444 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11445 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11446 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11447 {
11448 switch (get_attr_type (insn))
11449 {
11450 case TYPE_ALU:
11451 if (operands[2] != const1_rtx)
11452 abort ();
11453 return "add{l}\t{%k0, %k0|%k0, %k0}";
11454
11455 default:
11456 if (REG_P (operands[2]))
11457 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11458 else if (GET_CODE (operands[2]) == CONST_INT
11459 && INTVAL (operands[2]) == 1
11460 && (TARGET_SHIFT1 || optimize_size))
11461 return "sal{l}\t%k0";
11462 else
11463 return "sal{l}\t{%2, %k0|%k0, %2}";
11464 }
11465 }
11466 [(set (attr "type")
11467 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11468 (const_int 0))
11469 (match_operand 2 "const1_operand" ""))
11470 (const_string "alu")
11471 ]
11472 (const_string "ishift")))
11473 (set_attr "mode" "SI")])
11474
11475 (define_expand "ashlhi3"
11476 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11477 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11478 (match_operand:QI 2 "nonmemory_operand" "")))
11479 (clobber (reg:CC 17))]
11480 "TARGET_HIMODE_MATH"
11481 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11482
11483 (define_insn "*ashlhi3_1_lea"
11484 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11485 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11486 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11487 (clobber (reg:CC 17))]
11488 "!TARGET_PARTIAL_REG_STALL
11489 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11490 {
11491 switch (get_attr_type (insn))
11492 {
11493 case TYPE_LEA:
11494 return "#";
11495 case TYPE_ALU:
11496 if (operands[2] != const1_rtx)
11497 abort ();
11498 return "add{w}\t{%0, %0|%0, %0}";
11499
11500 default:
11501 if (REG_P (operands[2]))
11502 return "sal{w}\t{%b2, %0|%0, %b2}";
11503 else if (GET_CODE (operands[2]) == CONST_INT
11504 && INTVAL (operands[2]) == 1
11505 && (TARGET_SHIFT1 || optimize_size))
11506 return "sal{w}\t%0";
11507 else
11508 return "sal{w}\t{%2, %0|%0, %2}";
11509 }
11510 }
11511 [(set (attr "type")
11512 (cond [(eq_attr "alternative" "1")
11513 (const_string "lea")
11514 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11515 (const_int 0))
11516 (match_operand 0 "register_operand" ""))
11517 (match_operand 2 "const1_operand" ""))
11518 (const_string "alu")
11519 ]
11520 (const_string "ishift")))
11521 (set_attr "mode" "HI,SI")])
11522
11523 (define_insn "*ashlhi3_1"
11524 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11525 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11526 (match_operand:QI 2 "nonmemory_operand" "cI")))
11527 (clobber (reg:CC 17))]
11528 "TARGET_PARTIAL_REG_STALL
11529 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11530 {
11531 switch (get_attr_type (insn))
11532 {
11533 case TYPE_ALU:
11534 if (operands[2] != const1_rtx)
11535 abort ();
11536 return "add{w}\t{%0, %0|%0, %0}";
11537
11538 default:
11539 if (REG_P (operands[2]))
11540 return "sal{w}\t{%b2, %0|%0, %b2}";
11541 else if (GET_CODE (operands[2]) == CONST_INT
11542 && INTVAL (operands[2]) == 1
11543 && (TARGET_SHIFT1 || optimize_size))
11544 return "sal{w}\t%0";
11545 else
11546 return "sal{w}\t{%2, %0|%0, %2}";
11547 }
11548 }
11549 [(set (attr "type")
11550 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11551 (const_int 0))
11552 (match_operand 0 "register_operand" ""))
11553 (match_operand 2 "const1_operand" ""))
11554 (const_string "alu")
11555 ]
11556 (const_string "ishift")))
11557 (set_attr "mode" "HI")])
11558
11559 ;; This pattern can't accept a variable shift count, since shifts by
11560 ;; zero don't affect the flags. We assume that shifts by constant
11561 ;; zero are optimized away.
11562 (define_insn "*ashlhi3_cmp"
11563 [(set (reg 17)
11564 (compare
11565 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11566 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11567 (const_int 0)))
11568 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11569 (ashift:HI (match_dup 1) (match_dup 2)))]
11570 "ix86_match_ccmode (insn, CCGOCmode)
11571 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11572 {
11573 switch (get_attr_type (insn))
11574 {
11575 case TYPE_ALU:
11576 if (operands[2] != const1_rtx)
11577 abort ();
11578 return "add{w}\t{%0, %0|%0, %0}";
11579
11580 default:
11581 if (REG_P (operands[2]))
11582 return "sal{w}\t{%b2, %0|%0, %b2}";
11583 else if (GET_CODE (operands[2]) == CONST_INT
11584 && INTVAL (operands[2]) == 1
11585 && (TARGET_SHIFT1 || optimize_size))
11586 return "sal{w}\t%0";
11587 else
11588 return "sal{w}\t{%2, %0|%0, %2}";
11589 }
11590 }
11591 [(set (attr "type")
11592 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11593 (const_int 0))
11594 (match_operand 0 "register_operand" ""))
11595 (match_operand 2 "const1_operand" ""))
11596 (const_string "alu")
11597 ]
11598 (const_string "ishift")))
11599 (set_attr "mode" "HI")])
11600
11601 (define_expand "ashlqi3"
11602 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11603 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11604 (match_operand:QI 2 "nonmemory_operand" "")))
11605 (clobber (reg:CC 17))]
11606 "TARGET_QIMODE_MATH"
11607 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11608
11609 ;; %%% Potential partial reg stall on alternative 2. What to do?
11610
11611 (define_insn "*ashlqi3_1_lea"
11612 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11613 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11614 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11615 (clobber (reg:CC 17))]
11616 "!TARGET_PARTIAL_REG_STALL
11617 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11618 {
11619 switch (get_attr_type (insn))
11620 {
11621 case TYPE_LEA:
11622 return "#";
11623 case TYPE_ALU:
11624 if (operands[2] != const1_rtx)
11625 abort ();
11626 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11627 return "add{l}\t{%k0, %k0|%k0, %k0}";
11628 else
11629 return "add{b}\t{%0, %0|%0, %0}";
11630
11631 default:
11632 if (REG_P (operands[2]))
11633 {
11634 if (get_attr_mode (insn) == MODE_SI)
11635 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11636 else
11637 return "sal{b}\t{%b2, %0|%0, %b2}";
11638 }
11639 else if (GET_CODE (operands[2]) == CONST_INT
11640 && INTVAL (operands[2]) == 1
11641 && (TARGET_SHIFT1 || optimize_size))
11642 {
11643 if (get_attr_mode (insn) == MODE_SI)
11644 return "sal{l}\t%0";
11645 else
11646 return "sal{b}\t%0";
11647 }
11648 else
11649 {
11650 if (get_attr_mode (insn) == MODE_SI)
11651 return "sal{l}\t{%2, %k0|%k0, %2}";
11652 else
11653 return "sal{b}\t{%2, %0|%0, %2}";
11654 }
11655 }
11656 }
11657 [(set (attr "type")
11658 (cond [(eq_attr "alternative" "2")
11659 (const_string "lea")
11660 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11661 (const_int 0))
11662 (match_operand 0 "register_operand" ""))
11663 (match_operand 2 "const1_operand" ""))
11664 (const_string "alu")
11665 ]
11666 (const_string "ishift")))
11667 (set_attr "mode" "QI,SI,SI")])
11668
11669 (define_insn "*ashlqi3_1"
11670 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11671 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11672 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11673 (clobber (reg:CC 17))]
11674 "TARGET_PARTIAL_REG_STALL
11675 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11676 {
11677 switch (get_attr_type (insn))
11678 {
11679 case TYPE_ALU:
11680 if (operands[2] != const1_rtx)
11681 abort ();
11682 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11683 return "add{l}\t{%k0, %k0|%k0, %k0}";
11684 else
11685 return "add{b}\t{%0, %0|%0, %0}";
11686
11687 default:
11688 if (REG_P (operands[2]))
11689 {
11690 if (get_attr_mode (insn) == MODE_SI)
11691 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11692 else
11693 return "sal{b}\t{%b2, %0|%0, %b2}";
11694 }
11695 else if (GET_CODE (operands[2]) == CONST_INT
11696 && INTVAL (operands[2]) == 1
11697 && (TARGET_SHIFT1 || optimize_size))
11698 {
11699 if (get_attr_mode (insn) == MODE_SI)
11700 return "sal{l}\t%0";
11701 else
11702 return "sal{b}\t%0";
11703 }
11704 else
11705 {
11706 if (get_attr_mode (insn) == MODE_SI)
11707 return "sal{l}\t{%2, %k0|%k0, %2}";
11708 else
11709 return "sal{b}\t{%2, %0|%0, %2}";
11710 }
11711 }
11712 }
11713 [(set (attr "type")
11714 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11715 (const_int 0))
11716 (match_operand 0 "register_operand" ""))
11717 (match_operand 2 "const1_operand" ""))
11718 (const_string "alu")
11719 ]
11720 (const_string "ishift")))
11721 (set_attr "mode" "QI,SI")])
11722
11723 ;; This pattern can't accept a variable shift count, since shifts by
11724 ;; zero don't affect the flags. We assume that shifts by constant
11725 ;; zero are optimized away.
11726 (define_insn "*ashlqi3_cmp"
11727 [(set (reg 17)
11728 (compare
11729 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11730 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11731 (const_int 0)))
11732 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11733 (ashift:QI (match_dup 1) (match_dup 2)))]
11734 "ix86_match_ccmode (insn, CCGOCmode)
11735 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11736 {
11737 switch (get_attr_type (insn))
11738 {
11739 case TYPE_ALU:
11740 if (operands[2] != const1_rtx)
11741 abort ();
11742 return "add{b}\t{%0, %0|%0, %0}";
11743
11744 default:
11745 if (REG_P (operands[2]))
11746 return "sal{b}\t{%b2, %0|%0, %b2}";
11747 else if (GET_CODE (operands[2]) == CONST_INT
11748 && INTVAL (operands[2]) == 1
11749 && (TARGET_SHIFT1 || optimize_size))
11750 return "sal{b}\t%0";
11751 else
11752 return "sal{b}\t{%2, %0|%0, %2}";
11753 }
11754 }
11755 [(set (attr "type")
11756 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11757 (const_int 0))
11758 (match_operand 0 "register_operand" ""))
11759 (match_operand 2 "const1_operand" ""))
11760 (const_string "alu")
11761 ]
11762 (const_string "ishift")))
11763 (set_attr "mode" "QI")])
11764
11765 ;; See comment above `ashldi3' about how this works.
11766
11767 (define_expand "ashrdi3"
11768 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11769 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11770 (match_operand:QI 2 "nonmemory_operand" "")))
11771 (clobber (reg:CC 17))])]
11772 ""
11773 {
11774 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11775 {
11776 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11777 DONE;
11778 }
11779 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11780 DONE;
11781 })
11782
11783 (define_insn "ashrdi3_63_rex64"
11784 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11785 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11786 (match_operand:DI 2 "const_int_operand" "i,i")))
11787 (clobber (reg:CC 17))]
11788 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11789 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11790 "@
11791 {cqto|cqo}
11792 sar{q}\t{%2, %0|%0, %2}"
11793 [(set_attr "type" "imovx,ishift")
11794 (set_attr "prefix_0f" "0,*")
11795 (set_attr "length_immediate" "0,*")
11796 (set_attr "modrm" "0,1")
11797 (set_attr "mode" "DI")])
11798
11799 (define_insn "*ashrdi3_1_one_bit_rex64"
11800 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11801 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11802 (match_operand:QI 2 "const_int_1_operand" "")))
11803 (clobber (reg:CC 17))]
11804 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11805 && (TARGET_SHIFT1 || optimize_size)"
11806 "sar{q}\t%0"
11807 [(set_attr "type" "ishift")
11808 (set (attr "length")
11809 (if_then_else (match_operand:DI 0 "register_operand" "")
11810 (const_string "2")
11811 (const_string "*")))])
11812
11813 (define_insn "*ashrdi3_1_rex64"
11814 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11815 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11816 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11817 (clobber (reg:CC 17))]
11818 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11819 "@
11820 sar{q}\t{%2, %0|%0, %2}
11821 sar{q}\t{%b2, %0|%0, %b2}"
11822 [(set_attr "type" "ishift")
11823 (set_attr "mode" "DI")])
11824
11825 ;; This pattern can't accept a variable shift count, since shifts by
11826 ;; zero don't affect the flags. We assume that shifts by constant
11827 ;; zero are optimized away.
11828 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11829 [(set (reg 17)
11830 (compare
11831 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11832 (match_operand:QI 2 "const_int_1_operand" ""))
11833 (const_int 0)))
11834 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11835 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11836 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11837 && (TARGET_SHIFT1 || optimize_size)
11838 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11839 "sar{q}\t%0"
11840 [(set_attr "type" "ishift")
11841 (set (attr "length")
11842 (if_then_else (match_operand:DI 0 "register_operand" "")
11843 (const_string "2")
11844 (const_string "*")))])
11845
11846 ;; This pattern can't accept a variable shift count, since shifts by
11847 ;; zero don't affect the flags. We assume that shifts by constant
11848 ;; zero are optimized away.
11849 (define_insn "*ashrdi3_cmp_rex64"
11850 [(set (reg 17)
11851 (compare
11852 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11853 (match_operand:QI 2 "const_int_operand" "n"))
11854 (const_int 0)))
11855 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11856 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11857 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11858 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11859 "sar{q}\t{%2, %0|%0, %2}"
11860 [(set_attr "type" "ishift")
11861 (set_attr "mode" "DI")])
11862
11863
11864 (define_insn "ashrdi3_1"
11865 [(set (match_operand:DI 0 "register_operand" "=r")
11866 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11867 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11868 (clobber (match_scratch:SI 3 "=&r"))
11869 (clobber (reg:CC 17))]
11870 "!TARGET_64BIT && TARGET_CMOVE"
11871 "#"
11872 [(set_attr "type" "multi")])
11873
11874 (define_insn "*ashrdi3_2"
11875 [(set (match_operand:DI 0 "register_operand" "=r")
11876 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11877 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11878 (clobber (reg:CC 17))]
11879 "!TARGET_64BIT"
11880 "#"
11881 [(set_attr "type" "multi")])
11882
11883 (define_split
11884 [(set (match_operand:DI 0 "register_operand" "")
11885 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11886 (match_operand:QI 2 "nonmemory_operand" "")))
11887 (clobber (match_scratch:SI 3 ""))
11888 (clobber (reg:CC 17))]
11889 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11890 [(const_int 0)]
11891 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11892
11893 (define_split
11894 [(set (match_operand:DI 0 "register_operand" "")
11895 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11896 (match_operand:QI 2 "nonmemory_operand" "")))
11897 (clobber (reg:CC 17))]
11898 "!TARGET_64BIT && reload_completed"
11899 [(const_int 0)]
11900 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11901
11902 (define_insn "x86_shrd_1"
11903 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11904 (ior:SI (ashiftrt:SI (match_dup 0)
11905 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11906 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11907 (minus:QI (const_int 32) (match_dup 2)))))
11908 (clobber (reg:CC 17))]
11909 ""
11910 "@
11911 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11912 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11913 [(set_attr "type" "ishift")
11914 (set_attr "prefix_0f" "1")
11915 (set_attr "pent_pair" "np")
11916 (set_attr "ppro_uops" "few")
11917 (set_attr "mode" "SI")])
11918
11919 (define_expand "x86_shift_adj_3"
11920 [(use (match_operand:SI 0 "register_operand" ""))
11921 (use (match_operand:SI 1 "register_operand" ""))
11922 (use (match_operand:QI 2 "register_operand" ""))]
11923 ""
11924 {
11925 rtx label = gen_label_rtx ();
11926 rtx tmp;
11927
11928 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11929
11930 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11931 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11932 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11933 gen_rtx_LABEL_REF (VOIDmode, label),
11934 pc_rtx);
11935 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11936 JUMP_LABEL (tmp) = label;
11937
11938 emit_move_insn (operands[0], operands[1]);
11939 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11940
11941 emit_label (label);
11942 LABEL_NUSES (label) = 1;
11943
11944 DONE;
11945 })
11946
11947 (define_insn "ashrsi3_31"
11948 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11949 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11950 (match_operand:SI 2 "const_int_operand" "i,i")))
11951 (clobber (reg:CC 17))]
11952 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11953 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11954 "@
11955 {cltd|cdq}
11956 sar{l}\t{%2, %0|%0, %2}"
11957 [(set_attr "type" "imovx,ishift")
11958 (set_attr "prefix_0f" "0,*")
11959 (set_attr "length_immediate" "0,*")
11960 (set_attr "modrm" "0,1")
11961 (set_attr "mode" "SI")])
11962
11963 (define_insn "*ashrsi3_31_zext"
11964 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11965 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11966 (match_operand:SI 2 "const_int_operand" "i,i"))))
11967 (clobber (reg:CC 17))]
11968 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11969 && INTVAL (operands[2]) == 31
11970 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11971 "@
11972 {cltd|cdq}
11973 sar{l}\t{%2, %k0|%k0, %2}"
11974 [(set_attr "type" "imovx,ishift")
11975 (set_attr "prefix_0f" "0,*")
11976 (set_attr "length_immediate" "0,*")
11977 (set_attr "modrm" "0,1")
11978 (set_attr "mode" "SI")])
11979
11980 (define_expand "ashrsi3"
11981 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11982 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11983 (match_operand:QI 2 "nonmemory_operand" "")))
11984 (clobber (reg:CC 17))]
11985 ""
11986 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11987
11988 (define_insn "*ashrsi3_1_one_bit"
11989 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11990 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11991 (match_operand:QI 2 "const_int_1_operand" "")))
11992 (clobber (reg:CC 17))]
11993 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11994 && (TARGET_SHIFT1 || optimize_size)"
11995 "sar{l}\t%0"
11996 [(set_attr "type" "ishift")
11997 (set (attr "length")
11998 (if_then_else (match_operand:SI 0 "register_operand" "")
11999 (const_string "2")
12000 (const_string "*")))])
12001
12002 (define_insn "*ashrsi3_1_one_bit_zext"
12003 [(set (match_operand:DI 0 "register_operand" "=r")
12004 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12005 (match_operand:QI 2 "const_int_1_operand" ""))))
12006 (clobber (reg:CC 17))]
12007 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12008 && (TARGET_SHIFT1 || optimize_size)"
12009 "sar{l}\t%k0"
12010 [(set_attr "type" "ishift")
12011 (set_attr "length" "2")])
12012
12013 (define_insn "*ashrsi3_1"
12014 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12015 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12016 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12017 (clobber (reg:CC 17))]
12018 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12019 "@
12020 sar{l}\t{%2, %0|%0, %2}
12021 sar{l}\t{%b2, %0|%0, %b2}"
12022 [(set_attr "type" "ishift")
12023 (set_attr "mode" "SI")])
12024
12025 (define_insn "*ashrsi3_1_zext"
12026 [(set (match_operand:DI 0 "register_operand" "=r,r")
12027 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12028 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12029 (clobber (reg:CC 17))]
12030 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12031 "@
12032 sar{l}\t{%2, %k0|%k0, %2}
12033 sar{l}\t{%b2, %k0|%k0, %b2}"
12034 [(set_attr "type" "ishift")
12035 (set_attr "mode" "SI")])
12036
12037 ;; This pattern can't accept a variable shift count, since shifts by
12038 ;; zero don't affect the flags. We assume that shifts by constant
12039 ;; zero are optimized away.
12040 (define_insn "*ashrsi3_one_bit_cmp"
12041 [(set (reg 17)
12042 (compare
12043 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12044 (match_operand:QI 2 "const_int_1_operand" ""))
12045 (const_int 0)))
12046 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12047 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12048 "ix86_match_ccmode (insn, CCGOCmode)
12049 && (TARGET_SHIFT1 || optimize_size)
12050 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12051 "sar{l}\t%0"
12052 [(set_attr "type" "ishift")
12053 (set (attr "length")
12054 (if_then_else (match_operand:SI 0 "register_operand" "")
12055 (const_string "2")
12056 (const_string "*")))])
12057
12058 (define_insn "*ashrsi3_one_bit_cmp_zext"
12059 [(set (reg 17)
12060 (compare
12061 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12062 (match_operand:QI 2 "const_int_1_operand" ""))
12063 (const_int 0)))
12064 (set (match_operand:DI 0 "register_operand" "=r")
12065 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12066 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
12067 && (TARGET_SHIFT1 || optimize_size)
12068 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12069 "sar{l}\t%k0"
12070 [(set_attr "type" "ishift")
12071 (set_attr "length" "2")])
12072
12073 ;; This pattern can't accept a variable shift count, since shifts by
12074 ;; zero don't affect the flags. We assume that shifts by constant
12075 ;; zero are optimized away.
12076 (define_insn "*ashrsi3_cmp"
12077 [(set (reg 17)
12078 (compare
12079 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12080 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12081 (const_int 0)))
12082 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12083 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12084 "ix86_match_ccmode (insn, CCGOCmode)
12085 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12086 "sar{l}\t{%2, %0|%0, %2}"
12087 [(set_attr "type" "ishift")
12088 (set_attr "mode" "SI")])
12089
12090 (define_insn "*ashrsi3_cmp_zext"
12091 [(set (reg 17)
12092 (compare
12093 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12094 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12095 (const_int 0)))
12096 (set (match_operand:DI 0 "register_operand" "=r")
12097 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12098 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12099 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12100 "sar{l}\t{%2, %k0|%k0, %2}"
12101 [(set_attr "type" "ishift")
12102 (set_attr "mode" "SI")])
12103
12104 (define_expand "ashrhi3"
12105 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12106 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12107 (match_operand:QI 2 "nonmemory_operand" "")))
12108 (clobber (reg:CC 17))]
12109 "TARGET_HIMODE_MATH"
12110 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12111
12112 (define_insn "*ashrhi3_1_one_bit"
12113 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12114 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12115 (match_operand:QI 2 "const_int_1_operand" "")))
12116 (clobber (reg:CC 17))]
12117 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12118 && (TARGET_SHIFT1 || optimize_size)"
12119 "sar{w}\t%0"
12120 [(set_attr "type" "ishift")
12121 (set (attr "length")
12122 (if_then_else (match_operand 0 "register_operand" "")
12123 (const_string "2")
12124 (const_string "*")))])
12125
12126 (define_insn "*ashrhi3_1"
12127 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12128 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12129 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12130 (clobber (reg:CC 17))]
12131 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12132 "@
12133 sar{w}\t{%2, %0|%0, %2}
12134 sar{w}\t{%b2, %0|%0, %b2}"
12135 [(set_attr "type" "ishift")
12136 (set_attr "mode" "HI")])
12137
12138 ;; This pattern can't accept a variable shift count, since shifts by
12139 ;; zero don't affect the flags. We assume that shifts by constant
12140 ;; zero are optimized away.
12141 (define_insn "*ashrhi3_one_bit_cmp"
12142 [(set (reg 17)
12143 (compare
12144 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12145 (match_operand:QI 2 "const_int_1_operand" ""))
12146 (const_int 0)))
12147 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12148 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12149 "ix86_match_ccmode (insn, CCGOCmode)
12150 && (TARGET_SHIFT1 || optimize_size)
12151 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12152 "sar{w}\t%0"
12153 [(set_attr "type" "ishift")
12154 (set (attr "length")
12155 (if_then_else (match_operand 0 "register_operand" "")
12156 (const_string "2")
12157 (const_string "*")))])
12158
12159 ;; This pattern can't accept a variable shift count, since shifts by
12160 ;; zero don't affect the flags. We assume that shifts by constant
12161 ;; zero are optimized away.
12162 (define_insn "*ashrhi3_cmp"
12163 [(set (reg 17)
12164 (compare
12165 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12166 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12167 (const_int 0)))
12168 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12169 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12170 "ix86_match_ccmode (insn, CCGOCmode)
12171 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12172 "sar{w}\t{%2, %0|%0, %2}"
12173 [(set_attr "type" "ishift")
12174 (set_attr "mode" "HI")])
12175
12176 (define_expand "ashrqi3"
12177 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12178 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12179 (match_operand:QI 2 "nonmemory_operand" "")))
12180 (clobber (reg:CC 17))]
12181 "TARGET_QIMODE_MATH"
12182 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12183
12184 (define_insn "*ashrqi3_1_one_bit"
12185 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12186 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12187 (match_operand:QI 2 "const_int_1_operand" "")))
12188 (clobber (reg:CC 17))]
12189 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12190 && (TARGET_SHIFT1 || optimize_size)"
12191 "sar{b}\t%0"
12192 [(set_attr "type" "ishift")
12193 (set (attr "length")
12194 (if_then_else (match_operand 0 "register_operand" "")
12195 (const_string "2")
12196 (const_string "*")))])
12197
12198 (define_insn "*ashrqi3_1_one_bit_slp"
12199 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12200 (ashiftrt:QI (match_dup 0)
12201 (match_operand:QI 1 "const_int_1_operand" "")))
12202 (clobber (reg:CC 17))]
12203 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12204 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12205 && (TARGET_SHIFT1 || optimize_size)"
12206 "sar{b}\t%0"
12207 [(set_attr "type" "ishift1")
12208 (set (attr "length")
12209 (if_then_else (match_operand 0 "register_operand" "")
12210 (const_string "2")
12211 (const_string "*")))])
12212
12213 (define_insn "*ashrqi3_1"
12214 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12215 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12216 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12217 (clobber (reg:CC 17))]
12218 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12219 "@
12220 sar{b}\t{%2, %0|%0, %2}
12221 sar{b}\t{%b2, %0|%0, %b2}"
12222 [(set_attr "type" "ishift")
12223 (set_attr "mode" "QI")])
12224
12225 (define_insn "*ashrqi3_1_slp"
12226 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12227 (ashiftrt:QI (match_dup 0)
12228 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12229 (clobber (reg:CC 17))]
12230 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12231 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12232 "@
12233 sar{b}\t{%1, %0|%0, %1}
12234 sar{b}\t{%b1, %0|%0, %b1}"
12235 [(set_attr "type" "ishift1")
12236 (set_attr "mode" "QI")])
12237
12238 ;; This pattern can't accept a variable shift count, since shifts by
12239 ;; zero don't affect the flags. We assume that shifts by constant
12240 ;; zero are optimized away.
12241 (define_insn "*ashrqi3_one_bit_cmp"
12242 [(set (reg 17)
12243 (compare
12244 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12245 (match_operand:QI 2 "const_int_1_operand" "I"))
12246 (const_int 0)))
12247 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12248 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12249 "ix86_match_ccmode (insn, CCGOCmode)
12250 && (TARGET_SHIFT1 || optimize_size)
12251 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12252 "sar{b}\t%0"
12253 [(set_attr "type" "ishift")
12254 (set (attr "length")
12255 (if_then_else (match_operand 0 "register_operand" "")
12256 (const_string "2")
12257 (const_string "*")))])
12258
12259 ;; This pattern can't accept a variable shift count, since shifts by
12260 ;; zero don't affect the flags. We assume that shifts by constant
12261 ;; zero are optimized away.
12262 (define_insn "*ashrqi3_cmp"
12263 [(set (reg 17)
12264 (compare
12265 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12266 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12267 (const_int 0)))
12268 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12269 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12270 "ix86_match_ccmode (insn, CCGOCmode)
12271 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12272 "sar{b}\t{%2, %0|%0, %2}"
12273 [(set_attr "type" "ishift")
12274 (set_attr "mode" "QI")])
12275 \f
12276 ;; Logical shift instructions
12277
12278 ;; See comment above `ashldi3' about how this works.
12279
12280 (define_expand "lshrdi3"
12281 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
12282 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12283 (match_operand:QI 2 "nonmemory_operand" "")))
12284 (clobber (reg:CC 17))])]
12285 ""
12286 {
12287 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
12288 {
12289 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
12290 DONE;
12291 }
12292 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
12293 DONE;
12294 })
12295
12296 (define_insn "*lshrdi3_1_one_bit_rex64"
12297 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12298 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12299 (match_operand:QI 2 "const_int_1_operand" "")))
12300 (clobber (reg:CC 17))]
12301 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12302 && (TARGET_SHIFT1 || optimize_size)"
12303 "shr{q}\t%0"
12304 [(set_attr "type" "ishift")
12305 (set (attr "length")
12306 (if_then_else (match_operand:DI 0 "register_operand" "")
12307 (const_string "2")
12308 (const_string "*")))])
12309
12310 (define_insn "*lshrdi3_1_rex64"
12311 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12312 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12313 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12314 (clobber (reg:CC 17))]
12315 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12316 "@
12317 shr{q}\t{%2, %0|%0, %2}
12318 shr{q}\t{%b2, %0|%0, %b2}"
12319 [(set_attr "type" "ishift")
12320 (set_attr "mode" "DI")])
12321
12322 ;; This pattern can't accept a variable shift count, since shifts by
12323 ;; zero don't affect the flags. We assume that shifts by constant
12324 ;; zero are optimized away.
12325 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12326 [(set (reg 17)
12327 (compare
12328 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12329 (match_operand:QI 2 "const_int_1_operand" ""))
12330 (const_int 0)))
12331 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12332 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12333 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12334 && (TARGET_SHIFT1 || optimize_size)
12335 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12336 "shr{q}\t%0"
12337 [(set_attr "type" "ishift")
12338 (set (attr "length")
12339 (if_then_else (match_operand:DI 0 "register_operand" "")
12340 (const_string "2")
12341 (const_string "*")))])
12342
12343 ;; This pattern can't accept a variable shift count, since shifts by
12344 ;; zero don't affect the flags. We assume that shifts by constant
12345 ;; zero are optimized away.
12346 (define_insn "*lshrdi3_cmp_rex64"
12347 [(set (reg 17)
12348 (compare
12349 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12350 (match_operand:QI 2 "const_int_operand" "e"))
12351 (const_int 0)))
12352 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12353 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12354 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12355 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12356 "shr{q}\t{%2, %0|%0, %2}"
12357 [(set_attr "type" "ishift")
12358 (set_attr "mode" "DI")])
12359
12360 (define_insn "lshrdi3_1"
12361 [(set (match_operand:DI 0 "register_operand" "=r")
12362 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12363 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12364 (clobber (match_scratch:SI 3 "=&r"))
12365 (clobber (reg:CC 17))]
12366 "!TARGET_64BIT && TARGET_CMOVE"
12367 "#"
12368 [(set_attr "type" "multi")])
12369
12370 (define_insn "*lshrdi3_2"
12371 [(set (match_operand:DI 0 "register_operand" "=r")
12372 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12373 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12374 (clobber (reg:CC 17))]
12375 "!TARGET_64BIT"
12376 "#"
12377 [(set_attr "type" "multi")])
12378
12379 (define_split
12380 [(set (match_operand:DI 0 "register_operand" "")
12381 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12382 (match_operand:QI 2 "nonmemory_operand" "")))
12383 (clobber (match_scratch:SI 3 ""))
12384 (clobber (reg:CC 17))]
12385 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
12386 [(const_int 0)]
12387 "ix86_split_lshrdi (operands, operands[3]); DONE;")
12388
12389 (define_split
12390 [(set (match_operand:DI 0 "register_operand" "")
12391 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12392 (match_operand:QI 2 "nonmemory_operand" "")))
12393 (clobber (reg:CC 17))]
12394 "!TARGET_64BIT && reload_completed"
12395 [(const_int 0)]
12396 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
12397
12398 (define_expand "lshrsi3"
12399 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12400 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12401 (match_operand:QI 2 "nonmemory_operand" "")))
12402 (clobber (reg:CC 17))]
12403 ""
12404 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12405
12406 (define_insn "*lshrsi3_1_one_bit"
12407 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12408 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12409 (match_operand:QI 2 "const_int_1_operand" "")))
12410 (clobber (reg:CC 17))]
12411 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12412 && (TARGET_SHIFT1 || optimize_size)"
12413 "shr{l}\t%0"
12414 [(set_attr "type" "ishift")
12415 (set (attr "length")
12416 (if_then_else (match_operand:SI 0 "register_operand" "")
12417 (const_string "2")
12418 (const_string "*")))])
12419
12420 (define_insn "*lshrsi3_1_one_bit_zext"
12421 [(set (match_operand:DI 0 "register_operand" "=r")
12422 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12423 (match_operand:QI 2 "const_int_1_operand" "")))
12424 (clobber (reg:CC 17))]
12425 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12426 && (TARGET_SHIFT1 || optimize_size)"
12427 "shr{l}\t%k0"
12428 [(set_attr "type" "ishift")
12429 (set_attr "length" "2")])
12430
12431 (define_insn "*lshrsi3_1"
12432 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12433 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12434 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12435 (clobber (reg:CC 17))]
12436 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12437 "@
12438 shr{l}\t{%2, %0|%0, %2}
12439 shr{l}\t{%b2, %0|%0, %b2}"
12440 [(set_attr "type" "ishift")
12441 (set_attr "mode" "SI")])
12442
12443 (define_insn "*lshrsi3_1_zext"
12444 [(set (match_operand:DI 0 "register_operand" "=r,r")
12445 (zero_extend:DI
12446 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12447 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12448 (clobber (reg:CC 17))]
12449 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12450 "@
12451 shr{l}\t{%2, %k0|%k0, %2}
12452 shr{l}\t{%b2, %k0|%k0, %b2}"
12453 [(set_attr "type" "ishift")
12454 (set_attr "mode" "SI")])
12455
12456 ;; This pattern can't accept a variable shift count, since shifts by
12457 ;; zero don't affect the flags. We assume that shifts by constant
12458 ;; zero are optimized away.
12459 (define_insn "*lshrsi3_one_bit_cmp"
12460 [(set (reg 17)
12461 (compare
12462 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12463 (match_operand:QI 2 "const_int_1_operand" ""))
12464 (const_int 0)))
12465 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12466 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12467 "ix86_match_ccmode (insn, CCGOCmode)
12468 && (TARGET_SHIFT1 || optimize_size)
12469 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12470 "shr{l}\t%0"
12471 [(set_attr "type" "ishift")
12472 (set (attr "length")
12473 (if_then_else (match_operand:SI 0 "register_operand" "")
12474 (const_string "2")
12475 (const_string "*")))])
12476
12477 (define_insn "*lshrsi3_cmp_one_bit_zext"
12478 [(set (reg 17)
12479 (compare
12480 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12481 (match_operand:QI 2 "const_int_1_operand" ""))
12482 (const_int 0)))
12483 (set (match_operand:DI 0 "register_operand" "=r")
12484 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12485 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12486 && (TARGET_SHIFT1 || optimize_size)
12487 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12488 "shr{l}\t%k0"
12489 [(set_attr "type" "ishift")
12490 (set_attr "length" "2")])
12491
12492 ;; This pattern can't accept a variable shift count, since shifts by
12493 ;; zero don't affect the flags. We assume that shifts by constant
12494 ;; zero are optimized away.
12495 (define_insn "*lshrsi3_cmp"
12496 [(set (reg 17)
12497 (compare
12498 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12499 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12500 (const_int 0)))
12501 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12502 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12503 "ix86_match_ccmode (insn, CCGOCmode)
12504 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12505 "shr{l}\t{%2, %0|%0, %2}"
12506 [(set_attr "type" "ishift")
12507 (set_attr "mode" "SI")])
12508
12509 (define_insn "*lshrsi3_cmp_zext"
12510 [(set (reg 17)
12511 (compare
12512 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12513 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12514 (const_int 0)))
12515 (set (match_operand:DI 0 "register_operand" "=r")
12516 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12517 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12518 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12519 "shr{l}\t{%2, %k0|%k0, %2}"
12520 [(set_attr "type" "ishift")
12521 (set_attr "mode" "SI")])
12522
12523 (define_expand "lshrhi3"
12524 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12525 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12526 (match_operand:QI 2 "nonmemory_operand" "")))
12527 (clobber (reg:CC 17))]
12528 "TARGET_HIMODE_MATH"
12529 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12530
12531 (define_insn "*lshrhi3_1_one_bit"
12532 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12533 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12534 (match_operand:QI 2 "const_int_1_operand" "")))
12535 (clobber (reg:CC 17))]
12536 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12537 && (TARGET_SHIFT1 || optimize_size)"
12538 "shr{w}\t%0"
12539 [(set_attr "type" "ishift")
12540 (set (attr "length")
12541 (if_then_else (match_operand 0 "register_operand" "")
12542 (const_string "2")
12543 (const_string "*")))])
12544
12545 (define_insn "*lshrhi3_1"
12546 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12547 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12548 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12549 (clobber (reg:CC 17))]
12550 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12551 "@
12552 shr{w}\t{%2, %0|%0, %2}
12553 shr{w}\t{%b2, %0|%0, %b2}"
12554 [(set_attr "type" "ishift")
12555 (set_attr "mode" "HI")])
12556
12557 ;; This pattern can't accept a variable shift count, since shifts by
12558 ;; zero don't affect the flags. We assume that shifts by constant
12559 ;; zero are optimized away.
12560 (define_insn "*lshrhi3_one_bit_cmp"
12561 [(set (reg 17)
12562 (compare
12563 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12564 (match_operand:QI 2 "const_int_1_operand" ""))
12565 (const_int 0)))
12566 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12567 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12568 "ix86_match_ccmode (insn, CCGOCmode)
12569 && (TARGET_SHIFT1 || optimize_size)
12570 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12571 "shr{w}\t%0"
12572 [(set_attr "type" "ishift")
12573 (set (attr "length")
12574 (if_then_else (match_operand:SI 0 "register_operand" "")
12575 (const_string "2")
12576 (const_string "*")))])
12577
12578 ;; This pattern can't accept a variable shift count, since shifts by
12579 ;; zero don't affect the flags. We assume that shifts by constant
12580 ;; zero are optimized away.
12581 (define_insn "*lshrhi3_cmp"
12582 [(set (reg 17)
12583 (compare
12584 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12585 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12586 (const_int 0)))
12587 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12588 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12589 "ix86_match_ccmode (insn, CCGOCmode)
12590 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12591 "shr{w}\t{%2, %0|%0, %2}"
12592 [(set_attr "type" "ishift")
12593 (set_attr "mode" "HI")])
12594
12595 (define_expand "lshrqi3"
12596 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12597 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12598 (match_operand:QI 2 "nonmemory_operand" "")))
12599 (clobber (reg:CC 17))]
12600 "TARGET_QIMODE_MATH"
12601 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12602
12603 (define_insn "*lshrqi3_1_one_bit"
12604 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12605 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12606 (match_operand:QI 2 "const_int_1_operand" "")))
12607 (clobber (reg:CC 17))]
12608 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12609 && (TARGET_SHIFT1 || optimize_size)"
12610 "shr{b}\t%0"
12611 [(set_attr "type" "ishift")
12612 (set (attr "length")
12613 (if_then_else (match_operand 0 "register_operand" "")
12614 (const_string "2")
12615 (const_string "*")))])
12616
12617 (define_insn "*lshrqi3_1_one_bit_slp"
12618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12619 (lshiftrt:QI (match_dup 0)
12620 (match_operand:QI 1 "const_int_1_operand" "")))
12621 (clobber (reg:CC 17))]
12622 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12623 && (TARGET_SHIFT1 || optimize_size)"
12624 "shr{b}\t%0"
12625 [(set_attr "type" "ishift1")
12626 (set (attr "length")
12627 (if_then_else (match_operand 0 "register_operand" "")
12628 (const_string "2")
12629 (const_string "*")))])
12630
12631 (define_insn "*lshrqi3_1"
12632 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12633 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12634 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12635 (clobber (reg:CC 17))]
12636 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12637 "@
12638 shr{b}\t{%2, %0|%0, %2}
12639 shr{b}\t{%b2, %0|%0, %b2}"
12640 [(set_attr "type" "ishift")
12641 (set_attr "mode" "QI")])
12642
12643 (define_insn "*lshrqi3_1_slp"
12644 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12645 (lshiftrt:QI (match_dup 0)
12646 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12647 (clobber (reg:CC 17))]
12648 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12649 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12650 "@
12651 shr{b}\t{%1, %0|%0, %1}
12652 shr{b}\t{%b1, %0|%0, %b1}"
12653 [(set_attr "type" "ishift1")
12654 (set_attr "mode" "QI")])
12655
12656 ;; This pattern can't accept a variable shift count, since shifts by
12657 ;; zero don't affect the flags. We assume that shifts by constant
12658 ;; zero are optimized away.
12659 (define_insn "*lshrqi2_one_bit_cmp"
12660 [(set (reg 17)
12661 (compare
12662 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12663 (match_operand:QI 2 "const_int_1_operand" ""))
12664 (const_int 0)))
12665 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12666 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12667 "ix86_match_ccmode (insn, CCGOCmode)
12668 && (TARGET_SHIFT1 || optimize_size)
12669 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12670 "shr{b}\t%0"
12671 [(set_attr "type" "ishift")
12672 (set (attr "length")
12673 (if_then_else (match_operand:SI 0 "register_operand" "")
12674 (const_string "2")
12675 (const_string "*")))])
12676
12677 ;; This pattern can't accept a variable shift count, since shifts by
12678 ;; zero don't affect the flags. We assume that shifts by constant
12679 ;; zero are optimized away.
12680 (define_insn "*lshrqi2_cmp"
12681 [(set (reg 17)
12682 (compare
12683 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12684 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12685 (const_int 0)))
12686 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12687 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12688 "ix86_match_ccmode (insn, CCGOCmode)
12689 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12690 "shr{b}\t{%2, %0|%0, %2}"
12691 [(set_attr "type" "ishift")
12692 (set_attr "mode" "QI")])
12693 \f
12694 ;; Rotate instructions
12695
12696 (define_expand "rotldi3"
12697 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12698 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12699 (match_operand:QI 2 "nonmemory_operand" "")))
12700 (clobber (reg:CC 17))]
12701 "TARGET_64BIT"
12702 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12703
12704 (define_insn "*rotlsi3_1_one_bit_rex64"
12705 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12706 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12707 (match_operand:QI 2 "const_int_1_operand" "")))
12708 (clobber (reg:CC 17))]
12709 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12710 && (TARGET_SHIFT1 || optimize_size)"
12711 "rol{q}\t%0"
12712 [(set_attr "type" "rotate")
12713 (set (attr "length")
12714 (if_then_else (match_operand:DI 0 "register_operand" "")
12715 (const_string "2")
12716 (const_string "*")))])
12717
12718 (define_insn "*rotldi3_1_rex64"
12719 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12720 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12721 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12722 (clobber (reg:CC 17))]
12723 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12724 "@
12725 rol{q}\t{%2, %0|%0, %2}
12726 rol{q}\t{%b2, %0|%0, %b2}"
12727 [(set_attr "type" "rotate")
12728 (set_attr "mode" "DI")])
12729
12730 (define_expand "rotlsi3"
12731 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12732 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12733 (match_operand:QI 2 "nonmemory_operand" "")))
12734 (clobber (reg:CC 17))]
12735 ""
12736 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12737
12738 (define_insn "*rotlsi3_1_one_bit"
12739 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12740 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12741 (match_operand:QI 2 "const_int_1_operand" "")))
12742 (clobber (reg:CC 17))]
12743 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12744 && (TARGET_SHIFT1 || optimize_size)"
12745 "rol{l}\t%0"
12746 [(set_attr "type" "rotate")
12747 (set (attr "length")
12748 (if_then_else (match_operand:SI 0 "register_operand" "")
12749 (const_string "2")
12750 (const_string "*")))])
12751
12752 (define_insn "*rotlsi3_1_one_bit_zext"
12753 [(set (match_operand:DI 0 "register_operand" "=r")
12754 (zero_extend:DI
12755 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12756 (match_operand:QI 2 "const_int_1_operand" ""))))
12757 (clobber (reg:CC 17))]
12758 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12759 && (TARGET_SHIFT1 || optimize_size)"
12760 "rol{l}\t%k0"
12761 [(set_attr "type" "rotate")
12762 (set_attr "length" "2")])
12763
12764 (define_insn "*rotlsi3_1"
12765 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12766 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12767 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12768 (clobber (reg:CC 17))]
12769 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12770 "@
12771 rol{l}\t{%2, %0|%0, %2}
12772 rol{l}\t{%b2, %0|%0, %b2}"
12773 [(set_attr "type" "rotate")
12774 (set_attr "mode" "SI")])
12775
12776 (define_insn "*rotlsi3_1_zext"
12777 [(set (match_operand:DI 0 "register_operand" "=r,r")
12778 (zero_extend:DI
12779 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12780 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12781 (clobber (reg:CC 17))]
12782 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12783 "@
12784 rol{l}\t{%2, %k0|%k0, %2}
12785 rol{l}\t{%b2, %k0|%k0, %b2}"
12786 [(set_attr "type" "rotate")
12787 (set_attr "mode" "SI")])
12788
12789 (define_expand "rotlhi3"
12790 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12791 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12792 (match_operand:QI 2 "nonmemory_operand" "")))
12793 (clobber (reg:CC 17))]
12794 "TARGET_HIMODE_MATH"
12795 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12796
12797 (define_insn "*rotlhi3_1_one_bit"
12798 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12799 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12800 (match_operand:QI 2 "const_int_1_operand" "")))
12801 (clobber (reg:CC 17))]
12802 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12803 && (TARGET_SHIFT1 || optimize_size)"
12804 "rol{w}\t%0"
12805 [(set_attr "type" "rotate")
12806 (set (attr "length")
12807 (if_then_else (match_operand 0 "register_operand" "")
12808 (const_string "2")
12809 (const_string "*")))])
12810
12811 (define_insn "*rotlhi3_1"
12812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12813 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12814 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12815 (clobber (reg:CC 17))]
12816 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12817 "@
12818 rol{w}\t{%2, %0|%0, %2}
12819 rol{w}\t{%b2, %0|%0, %b2}"
12820 [(set_attr "type" "rotate")
12821 (set_attr "mode" "HI")])
12822
12823 (define_expand "rotlqi3"
12824 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12825 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12826 (match_operand:QI 2 "nonmemory_operand" "")))
12827 (clobber (reg:CC 17))]
12828 "TARGET_QIMODE_MATH"
12829 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12830
12831 (define_insn "*rotlqi3_1_one_bit_slp"
12832 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12833 (rotate:QI (match_dup 0)
12834 (match_operand:QI 1 "const_int_1_operand" "")))
12835 (clobber (reg:CC 17))]
12836 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12837 && (TARGET_SHIFT1 || optimize_size)"
12838 "rol{b}\t%0"
12839 [(set_attr "type" "rotate1")
12840 (set (attr "length")
12841 (if_then_else (match_operand 0 "register_operand" "")
12842 (const_string "2")
12843 (const_string "*")))])
12844
12845 (define_insn "*rotlqi3_1_one_bit"
12846 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12847 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12848 (match_operand:QI 2 "const_int_1_operand" "")))
12849 (clobber (reg:CC 17))]
12850 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12851 && (TARGET_SHIFT1 || optimize_size)"
12852 "rol{b}\t%0"
12853 [(set_attr "type" "rotate")
12854 (set (attr "length")
12855 (if_then_else (match_operand 0 "register_operand" "")
12856 (const_string "2")
12857 (const_string "*")))])
12858
12859 (define_insn "*rotlqi3_1_slp"
12860 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12861 (rotate:QI (match_dup 0)
12862 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12863 (clobber (reg:CC 17))]
12864 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12865 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12866 "@
12867 rol{b}\t{%1, %0|%0, %1}
12868 rol{b}\t{%b1, %0|%0, %b1}"
12869 [(set_attr "type" "rotate1")
12870 (set_attr "mode" "QI")])
12871
12872 (define_insn "*rotlqi3_1"
12873 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12874 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12875 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12876 (clobber (reg:CC 17))]
12877 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12878 "@
12879 rol{b}\t{%2, %0|%0, %2}
12880 rol{b}\t{%b2, %0|%0, %b2}"
12881 [(set_attr "type" "rotate")
12882 (set_attr "mode" "QI")])
12883
12884 (define_expand "rotrdi3"
12885 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12886 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12887 (match_operand:QI 2 "nonmemory_operand" "")))
12888 (clobber (reg:CC 17))]
12889 "TARGET_64BIT"
12890 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12891
12892 (define_insn "*rotrdi3_1_one_bit_rex64"
12893 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12894 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12895 (match_operand:QI 2 "const_int_1_operand" "")))
12896 (clobber (reg:CC 17))]
12897 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12898 && (TARGET_SHIFT1 || optimize_size)"
12899 "ror{q}\t%0"
12900 [(set_attr "type" "rotate")
12901 (set (attr "length")
12902 (if_then_else (match_operand:DI 0 "register_operand" "")
12903 (const_string "2")
12904 (const_string "*")))])
12905
12906 (define_insn "*rotrdi3_1_rex64"
12907 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12908 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12909 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12910 (clobber (reg:CC 17))]
12911 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12912 "@
12913 ror{q}\t{%2, %0|%0, %2}
12914 ror{q}\t{%b2, %0|%0, %b2}"
12915 [(set_attr "type" "rotate")
12916 (set_attr "mode" "DI")])
12917
12918 (define_expand "rotrsi3"
12919 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12920 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12921 (match_operand:QI 2 "nonmemory_operand" "")))
12922 (clobber (reg:CC 17))]
12923 ""
12924 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12925
12926 (define_insn "*rotrsi3_1_one_bit"
12927 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12928 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12929 (match_operand:QI 2 "const_int_1_operand" "")))
12930 (clobber (reg:CC 17))]
12931 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12932 && (TARGET_SHIFT1 || optimize_size)"
12933 "ror{l}\t%0"
12934 [(set_attr "type" "rotate")
12935 (set (attr "length")
12936 (if_then_else (match_operand:SI 0 "register_operand" "")
12937 (const_string "2")
12938 (const_string "*")))])
12939
12940 (define_insn "*rotrsi3_1_one_bit_zext"
12941 [(set (match_operand:DI 0 "register_operand" "=r")
12942 (zero_extend:DI
12943 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12944 (match_operand:QI 2 "const_int_1_operand" ""))))
12945 (clobber (reg:CC 17))]
12946 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12947 && (TARGET_SHIFT1 || optimize_size)"
12948 "ror{l}\t%k0"
12949 [(set_attr "type" "rotate")
12950 (set (attr "length")
12951 (if_then_else (match_operand:SI 0 "register_operand" "")
12952 (const_string "2")
12953 (const_string "*")))])
12954
12955 (define_insn "*rotrsi3_1"
12956 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12957 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12958 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12959 (clobber (reg:CC 17))]
12960 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12961 "@
12962 ror{l}\t{%2, %0|%0, %2}
12963 ror{l}\t{%b2, %0|%0, %b2}"
12964 [(set_attr "type" "rotate")
12965 (set_attr "mode" "SI")])
12966
12967 (define_insn "*rotrsi3_1_zext"
12968 [(set (match_operand:DI 0 "register_operand" "=r,r")
12969 (zero_extend:DI
12970 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12971 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12972 (clobber (reg:CC 17))]
12973 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12974 "@
12975 ror{l}\t{%2, %k0|%k0, %2}
12976 ror{l}\t{%b2, %k0|%k0, %b2}"
12977 [(set_attr "type" "rotate")
12978 (set_attr "mode" "SI")])
12979
12980 (define_expand "rotrhi3"
12981 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12982 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12983 (match_operand:QI 2 "nonmemory_operand" "")))
12984 (clobber (reg:CC 17))]
12985 "TARGET_HIMODE_MATH"
12986 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12987
12988 (define_insn "*rotrhi3_one_bit"
12989 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12990 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12991 (match_operand:QI 2 "const_int_1_operand" "")))
12992 (clobber (reg:CC 17))]
12993 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12994 && (TARGET_SHIFT1 || optimize_size)"
12995 "ror{w}\t%0"
12996 [(set_attr "type" "rotate")
12997 (set (attr "length")
12998 (if_then_else (match_operand 0 "register_operand" "")
12999 (const_string "2")
13000 (const_string "*")))])
13001
13002 (define_insn "*rotrhi3"
13003 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13004 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13005 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13006 (clobber (reg:CC 17))]
13007 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13008 "@
13009 ror{w}\t{%2, %0|%0, %2}
13010 ror{w}\t{%b2, %0|%0, %b2}"
13011 [(set_attr "type" "rotate")
13012 (set_attr "mode" "HI")])
13013
13014 (define_expand "rotrqi3"
13015 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13016 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13017 (match_operand:QI 2 "nonmemory_operand" "")))
13018 (clobber (reg:CC 17))]
13019 "TARGET_QIMODE_MATH"
13020 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13021
13022 (define_insn "*rotrqi3_1_one_bit"
13023 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13024 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13025 (match_operand:QI 2 "const_int_1_operand" "")))
13026 (clobber (reg:CC 17))]
13027 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13028 && (TARGET_SHIFT1 || optimize_size)"
13029 "ror{b}\t%0"
13030 [(set_attr "type" "rotate")
13031 (set (attr "length")
13032 (if_then_else (match_operand 0 "register_operand" "")
13033 (const_string "2")
13034 (const_string "*")))])
13035
13036 (define_insn "*rotrqi3_1_one_bit_slp"
13037 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13038 (rotatert:QI (match_dup 0)
13039 (match_operand:QI 1 "const_int_1_operand" "")))
13040 (clobber (reg:CC 17))]
13041 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13042 && (TARGET_SHIFT1 || optimize_size)"
13043 "ror{b}\t%0"
13044 [(set_attr "type" "rotate1")
13045 (set (attr "length")
13046 (if_then_else (match_operand 0 "register_operand" "")
13047 (const_string "2")
13048 (const_string "*")))])
13049
13050 (define_insn "*rotrqi3_1"
13051 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13052 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13053 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13054 (clobber (reg:CC 17))]
13055 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13056 "@
13057 ror{b}\t{%2, %0|%0, %2}
13058 ror{b}\t{%b2, %0|%0, %b2}"
13059 [(set_attr "type" "rotate")
13060 (set_attr "mode" "QI")])
13061
13062 (define_insn "*rotrqi3_1_slp"
13063 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13064 (rotatert:QI (match_dup 0)
13065 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13066 (clobber (reg:CC 17))]
13067 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13068 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13069 "@
13070 ror{b}\t{%1, %0|%0, %1}
13071 ror{b}\t{%b1, %0|%0, %b1}"
13072 [(set_attr "type" "rotate1")
13073 (set_attr "mode" "QI")])
13074 \f
13075 ;; Bit set / bit test instructions
13076
13077 (define_expand "extv"
13078 [(set (match_operand:SI 0 "register_operand" "")
13079 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13080 (match_operand:SI 2 "immediate_operand" "")
13081 (match_operand:SI 3 "immediate_operand" "")))]
13082 ""
13083 {
13084 /* Handle extractions from %ah et al. */
13085 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13086 FAIL;
13087
13088 /* From mips.md: extract_bit_field doesn't verify that our source
13089 matches the predicate, so check it again here. */
13090 if (! register_operand (operands[1], VOIDmode))
13091 FAIL;
13092 })
13093
13094 (define_expand "extzv"
13095 [(set (match_operand:SI 0 "register_operand" "")
13096 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13097 (match_operand:SI 2 "immediate_operand" "")
13098 (match_operand:SI 3 "immediate_operand" "")))]
13099 ""
13100 {
13101 /* Handle extractions from %ah et al. */
13102 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13103 FAIL;
13104
13105 /* From mips.md: extract_bit_field doesn't verify that our source
13106 matches the predicate, so check it again here. */
13107 if (! register_operand (operands[1], VOIDmode))
13108 FAIL;
13109 })
13110
13111 (define_expand "insv"
13112 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
13113 (match_operand:SI 1 "immediate_operand" "")
13114 (match_operand:SI 2 "immediate_operand" ""))
13115 (match_operand:SI 3 "register_operand" ""))]
13116 ""
13117 {
13118 /* Handle extractions from %ah et al. */
13119 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13120 FAIL;
13121
13122 /* From mips.md: insert_bit_field doesn't verify that our source
13123 matches the predicate, so check it again here. */
13124 if (! register_operand (operands[0], VOIDmode))
13125 FAIL;
13126 })
13127
13128 ;; %%% bts, btr, btc, bt.
13129 \f
13130 ;; Store-flag instructions.
13131
13132 ;; For all sCOND expanders, also expand the compare or test insn that
13133 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13134
13135 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13136 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13137 ;; way, which can later delete the movzx if only QImode is needed.
13138
13139 (define_expand "seq"
13140 [(set (match_operand:QI 0 "register_operand" "")
13141 (eq:QI (reg:CC 17) (const_int 0)))]
13142 ""
13143 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13144
13145 (define_expand "sne"
13146 [(set (match_operand:QI 0 "register_operand" "")
13147 (ne:QI (reg:CC 17) (const_int 0)))]
13148 ""
13149 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13150
13151 (define_expand "sgt"
13152 [(set (match_operand:QI 0 "register_operand" "")
13153 (gt:QI (reg:CC 17) (const_int 0)))]
13154 ""
13155 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13156
13157 (define_expand "sgtu"
13158 [(set (match_operand:QI 0 "register_operand" "")
13159 (gtu:QI (reg:CC 17) (const_int 0)))]
13160 ""
13161 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13162
13163 (define_expand "slt"
13164 [(set (match_operand:QI 0 "register_operand" "")
13165 (lt:QI (reg:CC 17) (const_int 0)))]
13166 ""
13167 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13168
13169 (define_expand "sltu"
13170 [(set (match_operand:QI 0 "register_operand" "")
13171 (ltu:QI (reg:CC 17) (const_int 0)))]
13172 ""
13173 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13174
13175 (define_expand "sge"
13176 [(set (match_operand:QI 0 "register_operand" "")
13177 (ge:QI (reg:CC 17) (const_int 0)))]
13178 ""
13179 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13180
13181 (define_expand "sgeu"
13182 [(set (match_operand:QI 0 "register_operand" "")
13183 (geu:QI (reg:CC 17) (const_int 0)))]
13184 ""
13185 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13186
13187 (define_expand "sle"
13188 [(set (match_operand:QI 0 "register_operand" "")
13189 (le:QI (reg:CC 17) (const_int 0)))]
13190 ""
13191 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13192
13193 (define_expand "sleu"
13194 [(set (match_operand:QI 0 "register_operand" "")
13195 (leu:QI (reg:CC 17) (const_int 0)))]
13196 ""
13197 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13198
13199 (define_expand "sunordered"
13200 [(set (match_operand:QI 0 "register_operand" "")
13201 (unordered:QI (reg:CC 17) (const_int 0)))]
13202 "TARGET_80387 || TARGET_SSE"
13203 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13204
13205 (define_expand "sordered"
13206 [(set (match_operand:QI 0 "register_operand" "")
13207 (ordered:QI (reg:CC 17) (const_int 0)))]
13208 "TARGET_80387"
13209 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13210
13211 (define_expand "suneq"
13212 [(set (match_operand:QI 0 "register_operand" "")
13213 (uneq:QI (reg:CC 17) (const_int 0)))]
13214 "TARGET_80387 || TARGET_SSE"
13215 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13216
13217 (define_expand "sunge"
13218 [(set (match_operand:QI 0 "register_operand" "")
13219 (unge:QI (reg:CC 17) (const_int 0)))]
13220 "TARGET_80387 || TARGET_SSE"
13221 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13222
13223 (define_expand "sungt"
13224 [(set (match_operand:QI 0 "register_operand" "")
13225 (ungt:QI (reg:CC 17) (const_int 0)))]
13226 "TARGET_80387 || TARGET_SSE"
13227 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13228
13229 (define_expand "sunle"
13230 [(set (match_operand:QI 0 "register_operand" "")
13231 (unle:QI (reg:CC 17) (const_int 0)))]
13232 "TARGET_80387 || TARGET_SSE"
13233 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13234
13235 (define_expand "sunlt"
13236 [(set (match_operand:QI 0 "register_operand" "")
13237 (unlt:QI (reg:CC 17) (const_int 0)))]
13238 "TARGET_80387 || TARGET_SSE"
13239 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13240
13241 (define_expand "sltgt"
13242 [(set (match_operand:QI 0 "register_operand" "")
13243 (ltgt:QI (reg:CC 17) (const_int 0)))]
13244 "TARGET_80387 || TARGET_SSE"
13245 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13246
13247 (define_insn "*setcc_1"
13248 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13249 (match_operator:QI 1 "ix86_comparison_operator"
13250 [(reg 17) (const_int 0)]))]
13251 ""
13252 "set%C1\t%0"
13253 [(set_attr "type" "setcc")
13254 (set_attr "mode" "QI")])
13255
13256 (define_insn "setcc_2"
13257 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13258 (match_operator:QI 1 "ix86_comparison_operator"
13259 [(reg 17) (const_int 0)]))]
13260 ""
13261 "set%C1\t%0"
13262 [(set_attr "type" "setcc")
13263 (set_attr "mode" "QI")])
13264
13265 ;; In general it is not safe to assume too much about CCmode registers,
13266 ;; so simplify-rtx stops when it sees a second one. Under certain
13267 ;; conditions this is safe on x86, so help combine not create
13268 ;;
13269 ;; seta %al
13270 ;; testb %al, %al
13271 ;; sete %al
13272
13273 (define_split
13274 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13275 (ne:QI (match_operator 1 "ix86_comparison_operator"
13276 [(reg 17) (const_int 0)])
13277 (const_int 0)))]
13278 ""
13279 [(set (match_dup 0) (match_dup 1))]
13280 {
13281 PUT_MODE (operands[1], QImode);
13282 })
13283
13284 (define_split
13285 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13286 (ne:QI (match_operator 1 "ix86_comparison_operator"
13287 [(reg 17) (const_int 0)])
13288 (const_int 0)))]
13289 ""
13290 [(set (match_dup 0) (match_dup 1))]
13291 {
13292 PUT_MODE (operands[1], QImode);
13293 })
13294
13295 (define_split
13296 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13297 (eq:QI (match_operator 1 "ix86_comparison_operator"
13298 [(reg 17) (const_int 0)])
13299 (const_int 0)))]
13300 ""
13301 [(set (match_dup 0) (match_dup 1))]
13302 {
13303 rtx new_op1 = copy_rtx (operands[1]);
13304 operands[1] = new_op1;
13305 PUT_MODE (new_op1, QImode);
13306 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13307 GET_MODE (XEXP (new_op1, 0))));
13308
13309 /* Make sure that (a) the CCmode we have for the flags is strong
13310 enough for the reversed compare or (b) we have a valid FP compare. */
13311 if (! ix86_comparison_operator (new_op1, VOIDmode))
13312 FAIL;
13313 })
13314
13315 (define_split
13316 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13317 (eq:QI (match_operator 1 "ix86_comparison_operator"
13318 [(reg 17) (const_int 0)])
13319 (const_int 0)))]
13320 ""
13321 [(set (match_dup 0) (match_dup 1))]
13322 {
13323 rtx new_op1 = copy_rtx (operands[1]);
13324 operands[1] = new_op1;
13325 PUT_MODE (new_op1, QImode);
13326 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13327 GET_MODE (XEXP (new_op1, 0))));
13328
13329 /* Make sure that (a) the CCmode we have for the flags is strong
13330 enough for the reversed compare or (b) we have a valid FP compare. */
13331 if (! ix86_comparison_operator (new_op1, VOIDmode))
13332 FAIL;
13333 })
13334
13335 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13336 ;; subsequent logical operations are used to imitate conditional moves.
13337 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13338 ;; it directly. Further holding this value in pseudo register might bring
13339 ;; problem in implicit normalization in spill code.
13340 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
13341 ;; instructions after reload by splitting the conditional move patterns.
13342
13343 (define_insn "*sse_setccsf"
13344 [(set (match_operand:SF 0 "register_operand" "=x")
13345 (match_operator:SF 1 "sse_comparison_operator"
13346 [(match_operand:SF 2 "register_operand" "0")
13347 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13348 "TARGET_SSE && reload_completed"
13349 "cmp%D1ss\t{%3, %0|%0, %3}"
13350 [(set_attr "type" "ssecmp")
13351 (set_attr "mode" "SF")])
13352
13353 (define_insn "*sse_setccdf"
13354 [(set (match_operand:DF 0 "register_operand" "=Y")
13355 (match_operator:DF 1 "sse_comparison_operator"
13356 [(match_operand:DF 2 "register_operand" "0")
13357 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13358 "TARGET_SSE2 && reload_completed"
13359 "cmp%D1sd\t{%3, %0|%0, %3}"
13360 [(set_attr "type" "ssecmp")
13361 (set_attr "mode" "DF")])
13362 \f
13363 ;; Basic conditional jump instructions.
13364 ;; We ignore the overflow flag for signed branch instructions.
13365
13366 ;; For all bCOND expanders, also expand the compare or test insn that
13367 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
13368
13369 (define_expand "beq"
13370 [(set (pc)
13371 (if_then_else (match_dup 1)
13372 (label_ref (match_operand 0 "" ""))
13373 (pc)))]
13374 ""
13375 "ix86_expand_branch (EQ, operands[0]); DONE;")
13376
13377 (define_expand "bne"
13378 [(set (pc)
13379 (if_then_else (match_dup 1)
13380 (label_ref (match_operand 0 "" ""))
13381 (pc)))]
13382 ""
13383 "ix86_expand_branch (NE, operands[0]); DONE;")
13384
13385 (define_expand "bgt"
13386 [(set (pc)
13387 (if_then_else (match_dup 1)
13388 (label_ref (match_operand 0 "" ""))
13389 (pc)))]
13390 ""
13391 "ix86_expand_branch (GT, operands[0]); DONE;")
13392
13393 (define_expand "bgtu"
13394 [(set (pc)
13395 (if_then_else (match_dup 1)
13396 (label_ref (match_operand 0 "" ""))
13397 (pc)))]
13398 ""
13399 "ix86_expand_branch (GTU, operands[0]); DONE;")
13400
13401 (define_expand "blt"
13402 [(set (pc)
13403 (if_then_else (match_dup 1)
13404 (label_ref (match_operand 0 "" ""))
13405 (pc)))]
13406 ""
13407 "ix86_expand_branch (LT, operands[0]); DONE;")
13408
13409 (define_expand "bltu"
13410 [(set (pc)
13411 (if_then_else (match_dup 1)
13412 (label_ref (match_operand 0 "" ""))
13413 (pc)))]
13414 ""
13415 "ix86_expand_branch (LTU, operands[0]); DONE;")
13416
13417 (define_expand "bge"
13418 [(set (pc)
13419 (if_then_else (match_dup 1)
13420 (label_ref (match_operand 0 "" ""))
13421 (pc)))]
13422 ""
13423 "ix86_expand_branch (GE, operands[0]); DONE;")
13424
13425 (define_expand "bgeu"
13426 [(set (pc)
13427 (if_then_else (match_dup 1)
13428 (label_ref (match_operand 0 "" ""))
13429 (pc)))]
13430 ""
13431 "ix86_expand_branch (GEU, operands[0]); DONE;")
13432
13433 (define_expand "ble"
13434 [(set (pc)
13435 (if_then_else (match_dup 1)
13436 (label_ref (match_operand 0 "" ""))
13437 (pc)))]
13438 ""
13439 "ix86_expand_branch (LE, operands[0]); DONE;")
13440
13441 (define_expand "bleu"
13442 [(set (pc)
13443 (if_then_else (match_dup 1)
13444 (label_ref (match_operand 0 "" ""))
13445 (pc)))]
13446 ""
13447 "ix86_expand_branch (LEU, operands[0]); DONE;")
13448
13449 (define_expand "bunordered"
13450 [(set (pc)
13451 (if_then_else (match_dup 1)
13452 (label_ref (match_operand 0 "" ""))
13453 (pc)))]
13454 "TARGET_80387 || TARGET_SSE"
13455 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13456
13457 (define_expand "bordered"
13458 [(set (pc)
13459 (if_then_else (match_dup 1)
13460 (label_ref (match_operand 0 "" ""))
13461 (pc)))]
13462 "TARGET_80387 || TARGET_SSE"
13463 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13464
13465 (define_expand "buneq"
13466 [(set (pc)
13467 (if_then_else (match_dup 1)
13468 (label_ref (match_operand 0 "" ""))
13469 (pc)))]
13470 "TARGET_80387 || TARGET_SSE"
13471 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13472
13473 (define_expand "bunge"
13474 [(set (pc)
13475 (if_then_else (match_dup 1)
13476 (label_ref (match_operand 0 "" ""))
13477 (pc)))]
13478 "TARGET_80387 || TARGET_SSE"
13479 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13480
13481 (define_expand "bungt"
13482 [(set (pc)
13483 (if_then_else (match_dup 1)
13484 (label_ref (match_operand 0 "" ""))
13485 (pc)))]
13486 "TARGET_80387 || TARGET_SSE"
13487 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13488
13489 (define_expand "bunle"
13490 [(set (pc)
13491 (if_then_else (match_dup 1)
13492 (label_ref (match_operand 0 "" ""))
13493 (pc)))]
13494 "TARGET_80387 || TARGET_SSE"
13495 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13496
13497 (define_expand "bunlt"
13498 [(set (pc)
13499 (if_then_else (match_dup 1)
13500 (label_ref (match_operand 0 "" ""))
13501 (pc)))]
13502 "TARGET_80387 || TARGET_SSE"
13503 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13504
13505 (define_expand "bltgt"
13506 [(set (pc)
13507 (if_then_else (match_dup 1)
13508 (label_ref (match_operand 0 "" ""))
13509 (pc)))]
13510 "TARGET_80387 || TARGET_SSE"
13511 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13512
13513 (define_insn "*jcc_1"
13514 [(set (pc)
13515 (if_then_else (match_operator 1 "ix86_comparison_operator"
13516 [(reg 17) (const_int 0)])
13517 (label_ref (match_operand 0 "" ""))
13518 (pc)))]
13519 ""
13520 "%+j%C1\t%l0"
13521 [(set_attr "type" "ibr")
13522 (set_attr "modrm" "0")
13523 (set (attr "length")
13524 (if_then_else (and (ge (minus (match_dup 0) (pc))
13525 (const_int -126))
13526 (lt (minus (match_dup 0) (pc))
13527 (const_int 128)))
13528 (const_int 2)
13529 (const_int 6)))])
13530
13531 (define_insn "*jcc_2"
13532 [(set (pc)
13533 (if_then_else (match_operator 1 "ix86_comparison_operator"
13534 [(reg 17) (const_int 0)])
13535 (pc)
13536 (label_ref (match_operand 0 "" ""))))]
13537 ""
13538 "%+j%c1\t%l0"
13539 [(set_attr "type" "ibr")
13540 (set_attr "modrm" "0")
13541 (set (attr "length")
13542 (if_then_else (and (ge (minus (match_dup 0) (pc))
13543 (const_int -126))
13544 (lt (minus (match_dup 0) (pc))
13545 (const_int 128)))
13546 (const_int 2)
13547 (const_int 6)))])
13548
13549 ;; In general it is not safe to assume too much about CCmode registers,
13550 ;; so simplify-rtx stops when it sees a second one. Under certain
13551 ;; conditions this is safe on x86, so help combine not create
13552 ;;
13553 ;; seta %al
13554 ;; testb %al, %al
13555 ;; je Lfoo
13556
13557 (define_split
13558 [(set (pc)
13559 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13560 [(reg 17) (const_int 0)])
13561 (const_int 0))
13562 (label_ref (match_operand 1 "" ""))
13563 (pc)))]
13564 ""
13565 [(set (pc)
13566 (if_then_else (match_dup 0)
13567 (label_ref (match_dup 1))
13568 (pc)))]
13569 {
13570 PUT_MODE (operands[0], VOIDmode);
13571 })
13572
13573 (define_split
13574 [(set (pc)
13575 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13576 [(reg 17) (const_int 0)])
13577 (const_int 0))
13578 (label_ref (match_operand 1 "" ""))
13579 (pc)))]
13580 ""
13581 [(set (pc)
13582 (if_then_else (match_dup 0)
13583 (label_ref (match_dup 1))
13584 (pc)))]
13585 {
13586 rtx new_op0 = copy_rtx (operands[0]);
13587 operands[0] = new_op0;
13588 PUT_MODE (new_op0, VOIDmode);
13589 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13590 GET_MODE (XEXP (new_op0, 0))));
13591
13592 /* Make sure that (a) the CCmode we have for the flags is strong
13593 enough for the reversed compare or (b) we have a valid FP compare. */
13594 if (! ix86_comparison_operator (new_op0, VOIDmode))
13595 FAIL;
13596 })
13597
13598 ;; Define combination compare-and-branch fp compare instructions to use
13599 ;; during early optimization. Splitting the operation apart early makes
13600 ;; for bad code when we want to reverse the operation.
13601
13602 (define_insn "*fp_jcc_1"
13603 [(set (pc)
13604 (if_then_else (match_operator 0 "comparison_operator"
13605 [(match_operand 1 "register_operand" "f")
13606 (match_operand 2 "register_operand" "f")])
13607 (label_ref (match_operand 3 "" ""))
13608 (pc)))
13609 (clobber (reg:CCFP 18))
13610 (clobber (reg:CCFP 17))]
13611 "TARGET_CMOVE && TARGET_80387
13612 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13613 && FLOAT_MODE_P (GET_MODE (operands[1]))
13614 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13615 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13616 "#")
13617
13618 (define_insn "*fp_jcc_1_sse"
13619 [(set (pc)
13620 (if_then_else (match_operator 0 "comparison_operator"
13621 [(match_operand 1 "register_operand" "f#x,x#f")
13622 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13623 (label_ref (match_operand 3 "" ""))
13624 (pc)))
13625 (clobber (reg:CCFP 18))
13626 (clobber (reg:CCFP 17))]
13627 "TARGET_80387
13628 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13629 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13630 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13631 "#")
13632
13633 (define_insn "*fp_jcc_1_sse_only"
13634 [(set (pc)
13635 (if_then_else (match_operator 0 "comparison_operator"
13636 [(match_operand 1 "register_operand" "x")
13637 (match_operand 2 "nonimmediate_operand" "xm")])
13638 (label_ref (match_operand 3 "" ""))
13639 (pc)))
13640 (clobber (reg:CCFP 18))
13641 (clobber (reg:CCFP 17))]
13642 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13643 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13644 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13645 "#")
13646
13647 (define_insn "*fp_jcc_2"
13648 [(set (pc)
13649 (if_then_else (match_operator 0 "comparison_operator"
13650 [(match_operand 1 "register_operand" "f")
13651 (match_operand 2 "register_operand" "f")])
13652 (pc)
13653 (label_ref (match_operand 3 "" ""))))
13654 (clobber (reg:CCFP 18))
13655 (clobber (reg:CCFP 17))]
13656 "TARGET_CMOVE && TARGET_80387
13657 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13658 && FLOAT_MODE_P (GET_MODE (operands[1]))
13659 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13660 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13661 "#")
13662
13663 (define_insn "*fp_jcc_2_sse"
13664 [(set (pc)
13665 (if_then_else (match_operator 0 "comparison_operator"
13666 [(match_operand 1 "register_operand" "f#x,x#f")
13667 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13668 (pc)
13669 (label_ref (match_operand 3 "" ""))))
13670 (clobber (reg:CCFP 18))
13671 (clobber (reg:CCFP 17))]
13672 "TARGET_80387
13673 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13674 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13675 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13676 "#")
13677
13678 (define_insn "*fp_jcc_2_sse_only"
13679 [(set (pc)
13680 (if_then_else (match_operator 0 "comparison_operator"
13681 [(match_operand 1 "register_operand" "x")
13682 (match_operand 2 "nonimmediate_operand" "xm")])
13683 (pc)
13684 (label_ref (match_operand 3 "" ""))))
13685 (clobber (reg:CCFP 18))
13686 (clobber (reg:CCFP 17))]
13687 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13688 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13689 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13690 "#")
13691
13692 (define_insn "*fp_jcc_3"
13693 [(set (pc)
13694 (if_then_else (match_operator 0 "comparison_operator"
13695 [(match_operand 1 "register_operand" "f")
13696 (match_operand 2 "nonimmediate_operand" "fm")])
13697 (label_ref (match_operand 3 "" ""))
13698 (pc)))
13699 (clobber (reg:CCFP 18))
13700 (clobber (reg:CCFP 17))
13701 (clobber (match_scratch:HI 4 "=a"))]
13702 "TARGET_80387
13703 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13704 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13705 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13706 && SELECT_CC_MODE (GET_CODE (operands[0]),
13707 operands[1], operands[2]) == CCFPmode
13708 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13709 "#")
13710
13711 (define_insn "*fp_jcc_4"
13712 [(set (pc)
13713 (if_then_else (match_operator 0 "comparison_operator"
13714 [(match_operand 1 "register_operand" "f")
13715 (match_operand 2 "nonimmediate_operand" "fm")])
13716 (pc)
13717 (label_ref (match_operand 3 "" ""))))
13718 (clobber (reg:CCFP 18))
13719 (clobber (reg:CCFP 17))
13720 (clobber (match_scratch:HI 4 "=a"))]
13721 "TARGET_80387
13722 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13723 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13724 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13725 && SELECT_CC_MODE (GET_CODE (operands[0]),
13726 operands[1], operands[2]) == CCFPmode
13727 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13728 "#")
13729
13730 (define_insn "*fp_jcc_5"
13731 [(set (pc)
13732 (if_then_else (match_operator 0 "comparison_operator"
13733 [(match_operand 1 "register_operand" "f")
13734 (match_operand 2 "register_operand" "f")])
13735 (label_ref (match_operand 3 "" ""))
13736 (pc)))
13737 (clobber (reg:CCFP 18))
13738 (clobber (reg:CCFP 17))
13739 (clobber (match_scratch:HI 4 "=a"))]
13740 "TARGET_80387
13741 && FLOAT_MODE_P (GET_MODE (operands[1]))
13742 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13743 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13744 "#")
13745
13746 (define_insn "*fp_jcc_6"
13747 [(set (pc)
13748 (if_then_else (match_operator 0 "comparison_operator"
13749 [(match_operand 1 "register_operand" "f")
13750 (match_operand 2 "register_operand" "f")])
13751 (pc)
13752 (label_ref (match_operand 3 "" ""))))
13753 (clobber (reg:CCFP 18))
13754 (clobber (reg:CCFP 17))
13755 (clobber (match_scratch:HI 4 "=a"))]
13756 "TARGET_80387
13757 && FLOAT_MODE_P (GET_MODE (operands[1]))
13758 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13759 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13760 "#")
13761
13762 (define_split
13763 [(set (pc)
13764 (if_then_else (match_operator 0 "comparison_operator"
13765 [(match_operand 1 "register_operand" "")
13766 (match_operand 2 "nonimmediate_operand" "")])
13767 (match_operand 3 "" "")
13768 (match_operand 4 "" "")))
13769 (clobber (reg:CCFP 18))
13770 (clobber (reg:CCFP 17))]
13771 "reload_completed"
13772 [(const_int 0)]
13773 {
13774 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13775 operands[3], operands[4], NULL_RTX);
13776 DONE;
13777 })
13778
13779 (define_split
13780 [(set (pc)
13781 (if_then_else (match_operator 0 "comparison_operator"
13782 [(match_operand 1 "register_operand" "")
13783 (match_operand 2 "nonimmediate_operand" "")])
13784 (match_operand 3 "" "")
13785 (match_operand 4 "" "")))
13786 (clobber (reg:CCFP 18))
13787 (clobber (reg:CCFP 17))
13788 (clobber (match_scratch:HI 5 "=a"))]
13789 "reload_completed"
13790 [(set (pc)
13791 (if_then_else (match_dup 6)
13792 (match_dup 3)
13793 (match_dup 4)))]
13794 {
13795 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13796 operands[3], operands[4], operands[5]);
13797 DONE;
13798 })
13799 \f
13800 ;; Unconditional and other jump instructions
13801
13802 (define_insn "jump"
13803 [(set (pc)
13804 (label_ref (match_operand 0 "" "")))]
13805 ""
13806 "jmp\t%l0"
13807 [(set_attr "type" "ibr")
13808 (set (attr "length")
13809 (if_then_else (and (ge (minus (match_dup 0) (pc))
13810 (const_int -126))
13811 (lt (minus (match_dup 0) (pc))
13812 (const_int 128)))
13813 (const_int 2)
13814 (const_int 5)))
13815 (set_attr "modrm" "0")])
13816
13817 (define_expand "indirect_jump"
13818 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13819 ""
13820 "")
13821
13822 (define_insn "*indirect_jump"
13823 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13824 "!TARGET_64BIT"
13825 "jmp\t%A0"
13826 [(set_attr "type" "ibr")
13827 (set_attr "length_immediate" "0")])
13828
13829 (define_insn "*indirect_jump_rtx64"
13830 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13831 "TARGET_64BIT"
13832 "jmp\t%A0"
13833 [(set_attr "type" "ibr")
13834 (set_attr "length_immediate" "0")])
13835
13836 (define_expand "tablejump"
13837 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13838 (use (label_ref (match_operand 1 "" "")))])]
13839 ""
13840 {
13841 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13842 relative. Convert the relative address to an absolute address. */
13843 if (flag_pic)
13844 {
13845 rtx op0, op1;
13846 enum rtx_code code;
13847
13848 if (TARGET_64BIT)
13849 {
13850 code = PLUS;
13851 op0 = operands[0];
13852 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13853 }
13854 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13855 {
13856 code = PLUS;
13857 op0 = operands[0];
13858 op1 = pic_offset_table_rtx;
13859 }
13860 else
13861 {
13862 code = MINUS;
13863 op0 = pic_offset_table_rtx;
13864 op1 = operands[0];
13865 }
13866
13867 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13868 OPTAB_DIRECT);
13869 }
13870 })
13871
13872 (define_insn "*tablejump_1"
13873 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13874 (use (label_ref (match_operand 1 "" "")))]
13875 "!TARGET_64BIT"
13876 "jmp\t%A0"
13877 [(set_attr "type" "ibr")
13878 (set_attr "length_immediate" "0")])
13879
13880 (define_insn "*tablejump_1_rtx64"
13881 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13882 (use (label_ref (match_operand 1 "" "")))]
13883 "TARGET_64BIT"
13884 "jmp\t%A0"
13885 [(set_attr "type" "ibr")
13886 (set_attr "length_immediate" "0")])
13887 \f
13888 ;; Loop instruction
13889 ;;
13890 ;; This is all complicated by the fact that since this is a jump insn
13891 ;; we must handle our own reloads.
13892
13893 (define_expand "doloop_end"
13894 [(use (match_operand 0 "" "")) ; loop pseudo
13895 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13896 (use (match_operand 2 "" "")) ; max iterations
13897 (use (match_operand 3 "" "")) ; loop level
13898 (use (match_operand 4 "" ""))] ; label
13899 "!TARGET_64BIT && TARGET_USE_LOOP"
13900 "
13901 {
13902 /* Only use cloop on innermost loops. */
13903 if (INTVAL (operands[3]) > 1)
13904 FAIL;
13905 if (GET_MODE (operands[0]) != SImode)
13906 FAIL;
13907 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13908 operands[0]));
13909 DONE;
13910 }")
13911
13912 (define_insn "doloop_end_internal"
13913 [(set (pc)
13914 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13915 (const_int 1))
13916 (label_ref (match_operand 0 "" ""))
13917 (pc)))
13918 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13919 (plus:SI (match_dup 1)
13920 (const_int -1)))
13921 (clobber (match_scratch:SI 3 "=X,X,r"))
13922 (clobber (reg:CC 17))]
13923 "!TARGET_64BIT && TARGET_USE_LOOP"
13924 {
13925 if (which_alternative != 0)
13926 return "#";
13927 if (get_attr_length (insn) == 2)
13928 return "%+loop\t%l0";
13929 else
13930 return "dec{l}\t%1\;%+jne\t%l0";
13931 }
13932 [(set_attr "ppro_uops" "many")
13933 (set (attr "length")
13934 (if_then_else (and (eq_attr "alternative" "0")
13935 (and (ge (minus (match_dup 0) (pc))
13936 (const_int -126))
13937 (lt (minus (match_dup 0) (pc))
13938 (const_int 128))))
13939 (const_int 2)
13940 (const_int 16)))
13941 ;; We don't know the type before shorten branches. Optimistically expect
13942 ;; the loop instruction to match.
13943 (set (attr "type") (const_string "ibr"))])
13944
13945 (define_split
13946 [(set (pc)
13947 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13948 (const_int 1))
13949 (match_operand 0 "" "")
13950 (pc)))
13951 (set (match_dup 1)
13952 (plus:SI (match_dup 1)
13953 (const_int -1)))
13954 (clobber (match_scratch:SI 2 ""))
13955 (clobber (reg:CC 17))]
13956 "!TARGET_64BIT && TARGET_USE_LOOP
13957 && reload_completed
13958 && REGNO (operands[1]) != 2"
13959 [(parallel [(set (reg:CCZ 17)
13960 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13961 (const_int 0)))
13962 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13963 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13964 (match_dup 0)
13965 (pc)))]
13966 "")
13967
13968 (define_split
13969 [(set (pc)
13970 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13971 (const_int 1))
13972 (match_operand 0 "" "")
13973 (pc)))
13974 (set (match_operand:SI 2 "nonimmediate_operand" "")
13975 (plus:SI (match_dup 1)
13976 (const_int -1)))
13977 (clobber (match_scratch:SI 3 ""))
13978 (clobber (reg:CC 17))]
13979 "!TARGET_64BIT && TARGET_USE_LOOP
13980 && reload_completed
13981 && (! REG_P (operands[2])
13982 || ! rtx_equal_p (operands[1], operands[2]))"
13983 [(set (match_dup 3) (match_dup 1))
13984 (parallel [(set (reg:CCZ 17)
13985 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13986 (const_int 0)))
13987 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13988 (set (match_dup 2) (match_dup 3))
13989 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13990 (match_dup 0)
13991 (pc)))]
13992 "")
13993
13994 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13995
13996 (define_peephole2
13997 [(set (reg 17) (match_operand 0 "" ""))
13998 (set (match_operand:QI 1 "register_operand" "")
13999 (match_operator:QI 2 "ix86_comparison_operator"
14000 [(reg 17) (const_int 0)]))
14001 (set (match_operand 3 "q_regs_operand" "")
14002 (zero_extend (match_dup 1)))]
14003 "(peep2_reg_dead_p (3, operands[1])
14004 || operands_match_p (operands[1], operands[3]))
14005 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14006 [(set (match_dup 4) (match_dup 0))
14007 (set (strict_low_part (match_dup 5))
14008 (match_dup 2))]
14009 {
14010 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
14011 operands[5] = gen_lowpart (QImode, operands[3]);
14012 ix86_expand_clear (operands[3]);
14013 })
14014
14015 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14016
14017 (define_peephole2
14018 [(set (reg 17) (match_operand 0 "" ""))
14019 (set (match_operand:QI 1 "register_operand" "")
14020 (match_operator:QI 2 "ix86_comparison_operator"
14021 [(reg 17) (const_int 0)]))
14022 (parallel [(set (match_operand 3 "q_regs_operand" "")
14023 (zero_extend (match_dup 1)))
14024 (clobber (reg:CC 17))])]
14025 "(peep2_reg_dead_p (3, operands[1])
14026 || operands_match_p (operands[1], operands[3]))
14027 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14028 [(set (match_dup 4) (match_dup 0))
14029 (set (strict_low_part (match_dup 5))
14030 (match_dup 2))]
14031 {
14032 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
14033 operands[5] = gen_lowpart (QImode, operands[3]);
14034 ix86_expand_clear (operands[3]);
14035 })
14036 \f
14037 ;; Call instructions.
14038
14039 ;; The predicates normally associated with named expanders are not properly
14040 ;; checked for calls. This is a bug in the generic code, but it isn't that
14041 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14042
14043 ;; Call subroutine returning no value.
14044
14045 (define_expand "call_pop"
14046 [(parallel [(call (match_operand:QI 0 "" "")
14047 (match_operand:SI 1 "" ""))
14048 (set (reg:SI 7)
14049 (plus:SI (reg:SI 7)
14050 (match_operand:SI 3 "" "")))])]
14051 "!TARGET_64BIT"
14052 {
14053 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14054 DONE;
14055 })
14056
14057 (define_insn "*call_pop_0"
14058 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14059 (match_operand:SI 1 "" ""))
14060 (set (reg:SI 7) (plus:SI (reg:SI 7)
14061 (match_operand:SI 2 "immediate_operand" "")))]
14062 "!TARGET_64BIT"
14063 {
14064 if (SIBLING_CALL_P (insn))
14065 return "jmp\t%P0";
14066 else
14067 return "call\t%P0";
14068 }
14069 [(set_attr "type" "call")])
14070
14071 (define_insn "*call_pop_1"
14072 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14073 (match_operand:SI 1 "" ""))
14074 (set (reg:SI 7) (plus:SI (reg:SI 7)
14075 (match_operand:SI 2 "immediate_operand" "i")))]
14076 "!TARGET_64BIT"
14077 {
14078 if (constant_call_address_operand (operands[0], Pmode))
14079 {
14080 if (SIBLING_CALL_P (insn))
14081 return "jmp\t%P0";
14082 else
14083 return "call\t%P0";
14084 }
14085 if (SIBLING_CALL_P (insn))
14086 return "jmp\t%A0";
14087 else
14088 return "call\t%A0";
14089 }
14090 [(set_attr "type" "call")])
14091
14092 (define_expand "call"
14093 [(call (match_operand:QI 0 "" "")
14094 (match_operand 1 "" ""))
14095 (use (match_operand 2 "" ""))]
14096 ""
14097 {
14098 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14099 DONE;
14100 })
14101
14102 (define_expand "sibcall"
14103 [(call (match_operand:QI 0 "" "")
14104 (match_operand 1 "" ""))
14105 (use (match_operand 2 "" ""))]
14106 ""
14107 {
14108 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14109 DONE;
14110 })
14111
14112 (define_insn "*call_0"
14113 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14114 (match_operand 1 "" ""))]
14115 ""
14116 {
14117 if (SIBLING_CALL_P (insn))
14118 return "jmp\t%P0";
14119 else
14120 return "call\t%P0";
14121 }
14122 [(set_attr "type" "call")])
14123
14124 (define_insn "*call_1"
14125 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14126 (match_operand 1 "" ""))]
14127 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14128 {
14129 if (constant_call_address_operand (operands[0], QImode))
14130 return "call\t%P0";
14131 return "call\t%A0";
14132 }
14133 [(set_attr "type" "call")])
14134
14135 (define_insn "*sibcall_1"
14136 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14137 (match_operand 1 "" ""))]
14138 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14139 {
14140 if (constant_call_address_operand (operands[0], QImode))
14141 return "jmp\t%P0";
14142 return "jmp\t%A0";
14143 }
14144 [(set_attr "type" "call")])
14145
14146 (define_insn "*call_1_rex64"
14147 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14148 (match_operand 1 "" ""))]
14149 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14150 {
14151 if (constant_call_address_operand (operands[0], QImode))
14152 return "call\t%P0";
14153 return "call\t%A0";
14154 }
14155 [(set_attr "type" "call")])
14156
14157 (define_insn "*sibcall_1_rex64"
14158 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14159 (match_operand 1 "" ""))]
14160 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14161 "jmp\t%P0"
14162 [(set_attr "type" "call")])
14163
14164 (define_insn "*sibcall_1_rex64_v"
14165 [(call (mem:QI (reg:DI 40))
14166 (match_operand 0 "" ""))]
14167 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14168 "jmp\t*%%r11"
14169 [(set_attr "type" "call")])
14170
14171
14172 ;; Call subroutine, returning value in operand 0
14173
14174 (define_expand "call_value_pop"
14175 [(parallel [(set (match_operand 0 "" "")
14176 (call (match_operand:QI 1 "" "")
14177 (match_operand:SI 2 "" "")))
14178 (set (reg:SI 7)
14179 (plus:SI (reg:SI 7)
14180 (match_operand:SI 4 "" "")))])]
14181 "!TARGET_64BIT"
14182 {
14183 ix86_expand_call (operands[0], operands[1], operands[2],
14184 operands[3], operands[4], 0);
14185 DONE;
14186 })
14187
14188 (define_expand "call_value"
14189 [(set (match_operand 0 "" "")
14190 (call (match_operand:QI 1 "" "")
14191 (match_operand:SI 2 "" "")))
14192 (use (match_operand:SI 3 "" ""))]
14193 ;; Operand 2 not used on the i386.
14194 ""
14195 {
14196 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14197 DONE;
14198 })
14199
14200 (define_expand "sibcall_value"
14201 [(set (match_operand 0 "" "")
14202 (call (match_operand:QI 1 "" "")
14203 (match_operand:SI 2 "" "")))
14204 (use (match_operand:SI 3 "" ""))]
14205 ;; Operand 2 not used on the i386.
14206 ""
14207 {
14208 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14209 DONE;
14210 })
14211
14212 ;; Call subroutine returning any type.
14213
14214 (define_expand "untyped_call"
14215 [(parallel [(call (match_operand 0 "" "")
14216 (const_int 0))
14217 (match_operand 1 "" "")
14218 (match_operand 2 "" "")])]
14219 ""
14220 {
14221 int i;
14222
14223 /* In order to give reg-stack an easier job in validating two
14224 coprocessor registers as containing a possible return value,
14225 simply pretend the untyped call returns a complex long double
14226 value. */
14227
14228 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14229 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14230 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14231 NULL, 0);
14232
14233 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14234 {
14235 rtx set = XVECEXP (operands[2], 0, i);
14236 emit_move_insn (SET_DEST (set), SET_SRC (set));
14237 }
14238
14239 /* The optimizer does not know that the call sets the function value
14240 registers we stored in the result block. We avoid problems by
14241 claiming that all hard registers are used and clobbered at this
14242 point. */
14243 emit_insn (gen_blockage (const0_rtx));
14244
14245 DONE;
14246 })
14247 \f
14248 ;; Prologue and epilogue instructions
14249
14250 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14251 ;; all of memory. This blocks insns from being moved across this point.
14252
14253 (define_insn "blockage"
14254 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14255 ""
14256 ""
14257 [(set_attr "length" "0")])
14258
14259 ;; Insn emitted into the body of a function to return from a function.
14260 ;; This is only done if the function's epilogue is known to be simple.
14261 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14262
14263 (define_expand "return"
14264 [(return)]
14265 "ix86_can_use_return_insn_p ()"
14266 {
14267 if (current_function_pops_args)
14268 {
14269 rtx popc = GEN_INT (current_function_pops_args);
14270 emit_jump_insn (gen_return_pop_internal (popc));
14271 DONE;
14272 }
14273 })
14274
14275 (define_insn "return_internal"
14276 [(return)]
14277 "reload_completed"
14278 "ret"
14279 [(set_attr "length" "1")
14280 (set_attr "length_immediate" "0")
14281 (set_attr "modrm" "0")])
14282
14283 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14284 ;; instruction Athlon and K8 have.
14285
14286 (define_insn "return_internal_long"
14287 [(return)
14288 (unspec [(const_int 0)] UNSPEC_REP)]
14289 "reload_completed"
14290 "rep {;} ret"
14291 [(set_attr "length" "1")
14292 (set_attr "length_immediate" "0")
14293 (set_attr "prefix_rep" "1")
14294 (set_attr "modrm" "0")])
14295
14296 (define_insn "return_pop_internal"
14297 [(return)
14298 (use (match_operand:SI 0 "const_int_operand" ""))]
14299 "reload_completed"
14300 "ret\t%0"
14301 [(set_attr "length" "3")
14302 (set_attr "length_immediate" "2")
14303 (set_attr "modrm" "0")])
14304
14305 (define_insn "return_indirect_internal"
14306 [(return)
14307 (use (match_operand:SI 0 "register_operand" "r"))]
14308 "reload_completed"
14309 "jmp\t%A0"
14310 [(set_attr "type" "ibr")
14311 (set_attr "length_immediate" "0")])
14312
14313 (define_insn "nop"
14314 [(const_int 0)]
14315 ""
14316 "nop"
14317 [(set_attr "length" "1")
14318 (set_attr "length_immediate" "0")
14319 (set_attr "modrm" "0")
14320 (set_attr "ppro_uops" "one")])
14321
14322 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14323 ;; branch prediction penalty for the third jump in a 16-byte
14324 ;; block on K8.
14325
14326 (define_insn "align"
14327 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14328 ""
14329 {
14330 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14331 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14332 #else
14333 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14334 The align insn is used to avoid 3 jump instructions in the row to improve
14335 branch prediction and the benefits hardly outweight the cost of extra 8
14336 nops on the average inserted by full alignment pseudo operation. */
14337 #endif
14338 return "";
14339 }
14340 [(set_attr "length" "16")])
14341
14342 (define_expand "prologue"
14343 [(const_int 1)]
14344 ""
14345 "ix86_expand_prologue (); DONE;")
14346
14347 (define_insn "set_got"
14348 [(set (match_operand:SI 0 "register_operand" "=r")
14349 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14350 (clobber (reg:CC 17))]
14351 "!TARGET_64BIT"
14352 { return output_set_got (operands[0]); }
14353 [(set_attr "type" "multi")
14354 (set_attr "length" "12")])
14355
14356 (define_expand "epilogue"
14357 [(const_int 1)]
14358 ""
14359 "ix86_expand_epilogue (1); DONE;")
14360
14361 (define_expand "sibcall_epilogue"
14362 [(const_int 1)]
14363 ""
14364 "ix86_expand_epilogue (0); DONE;")
14365
14366 (define_expand "eh_return"
14367 [(use (match_operand 0 "register_operand" ""))]
14368 ""
14369 {
14370 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14371
14372 /* Tricky bit: we write the address of the handler to which we will
14373 be returning into someone else's stack frame, one word below the
14374 stack address we wish to restore. */
14375 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14376 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14377 tmp = gen_rtx_MEM (Pmode, tmp);
14378 emit_move_insn (tmp, ra);
14379
14380 if (Pmode == SImode)
14381 emit_insn (gen_eh_return_si (sa));
14382 else
14383 emit_insn (gen_eh_return_di (sa));
14384 emit_barrier ();
14385 DONE;
14386 })
14387
14388 (define_insn_and_split "eh_return_si"
14389 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
14390 UNSPECV_EH_RETURN)]
14391 "!TARGET_64BIT"
14392 "#"
14393 "reload_completed"
14394 [(const_int 1)]
14395 "ix86_expand_epilogue (2); DONE;")
14396
14397 (define_insn_and_split "eh_return_di"
14398 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14399 UNSPECV_EH_RETURN)]
14400 "TARGET_64BIT"
14401 "#"
14402 "reload_completed"
14403 [(const_int 1)]
14404 "ix86_expand_epilogue (2); DONE;")
14405
14406 (define_insn "leave"
14407 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14408 (set (reg:SI 6) (mem:SI (reg:SI 6)))
14409 (clobber (mem:BLK (scratch)))]
14410 "!TARGET_64BIT"
14411 "leave"
14412 [(set_attr "type" "leave")])
14413
14414 (define_insn "leave_rex64"
14415 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14416 (set (reg:DI 6) (mem:DI (reg:DI 6)))
14417 (clobber (mem:BLK (scratch)))]
14418 "TARGET_64BIT"
14419 "leave"
14420 [(set_attr "type" "leave")])
14421 \f
14422 (define_expand "ffssi2"
14423 [(parallel
14424 [(set (match_operand:SI 0 "register_operand" "")
14425 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14426 (clobber (match_scratch:SI 2 ""))
14427 (clobber (reg:CC 17))])]
14428 ""
14429 "")
14430
14431 (define_insn_and_split "*ffs_cmove"
14432 [(set (match_operand:SI 0 "register_operand" "=r")
14433 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14434 (clobber (match_scratch:SI 2 "=&r"))
14435 (clobber (reg:CC 17))]
14436 "TARGET_CMOVE"
14437 "#"
14438 "&& reload_completed"
14439 [(set (match_dup 2) (const_int -1))
14440 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14441 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14442 (set (match_dup 0) (if_then_else:SI
14443 (eq (reg:CCZ 17) (const_int 0))
14444 (match_dup 2)
14445 (match_dup 0)))
14446 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14447 (clobber (reg:CC 17))])]
14448 "")
14449
14450 (define_insn_and_split "*ffs_no_cmove"
14451 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14452 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14453 (clobber (match_scratch:SI 2 "=&q"))
14454 (clobber (reg:CC 17))]
14455 ""
14456 "#"
14457 "reload_completed"
14458 [(parallel [(set (match_dup 2) (const_int 0))
14459 (clobber (reg:CC 17))])
14460 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14461 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14462 (set (strict_low_part (match_dup 3))
14463 (eq:QI (reg:CCZ 17) (const_int 0)))
14464 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14465 (clobber (reg:CC 17))])
14466 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14467 (clobber (reg:CC 17))])
14468 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14469 (clobber (reg:CC 17))])]
14470 {
14471 operands[3] = gen_lowpart (QImode, operands[2]);
14472 })
14473
14474 (define_insn "*ffssi_1"
14475 [(set (reg:CCZ 17)
14476 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14477 (const_int 0)))
14478 (set (match_operand:SI 0 "register_operand" "=r")
14479 (ctz:SI (match_dup 1)))]
14480 ""
14481 "bsf{l}\t{%1, %0|%0, %1}"
14482 [(set_attr "prefix_0f" "1")
14483 (set_attr "ppro_uops" "few")])
14484
14485 (define_insn "ctzsi2"
14486 [(set (match_operand:SI 0 "register_operand" "=r")
14487 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14488 (clobber (reg:CC 17))]
14489 ""
14490 "bsf{l}\t{%1, %0|%0, %1}"
14491 [(set_attr "prefix_0f" "1")
14492 (set_attr "ppro_uops" "few")])
14493
14494 (define_expand "clzsi2"
14495 [(parallel
14496 [(set (match_operand:SI 0 "register_operand" "")
14497 (minus:SI (const_int 31)
14498 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14499 (clobber (reg:CC 17))])
14500 (parallel
14501 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14502 (clobber (reg:CC 17))])]
14503 ""
14504 "")
14505
14506 (define_insn "*bsr"
14507 [(set (match_operand:SI 0 "register_operand" "=r")
14508 (minus:SI (const_int 31)
14509 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14510 (clobber (reg:CC 17))]
14511 ""
14512 "bsr{l}\t{%1, %0|%0, %1}"
14513 [(set_attr "prefix_0f" "1")
14514 (set_attr "ppro_uops" "few")])
14515 \f
14516 ;; Thread-local storage patterns for ELF.
14517 ;;
14518 ;; Note that these code sequences must appear exactly as shown
14519 ;; in order to allow linker relaxation.
14520
14521 (define_insn "*tls_global_dynamic_32_gnu"
14522 [(set (match_operand:SI 0 "register_operand" "=a")
14523 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14524 (match_operand:SI 2 "tls_symbolic_operand" "")
14525 (match_operand:SI 3 "call_insn_operand" "")]
14526 UNSPEC_TLS_GD))
14527 (clobber (match_scratch:SI 4 "=d"))
14528 (clobber (match_scratch:SI 5 "=c"))
14529 (clobber (reg:CC 17))]
14530 "!TARGET_64BIT && TARGET_GNU_TLS"
14531 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14532 [(set_attr "type" "multi")
14533 (set_attr "length" "12")])
14534
14535 (define_insn "*tls_global_dynamic_32_sun"
14536 [(set (match_operand:SI 0 "register_operand" "=a")
14537 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14538 (match_operand:SI 2 "tls_symbolic_operand" "")
14539 (match_operand:SI 3 "call_insn_operand" "")]
14540 UNSPEC_TLS_GD))
14541 (clobber (match_scratch:SI 4 "=d"))
14542 (clobber (match_scratch:SI 5 "=c"))
14543 (clobber (reg:CC 17))]
14544 "!TARGET_64BIT && TARGET_SUN_TLS"
14545 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14546 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14547 [(set_attr "type" "multi")
14548 (set_attr "length" "14")])
14549
14550 (define_expand "tls_global_dynamic_32"
14551 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14552 (unspec:SI
14553 [(match_dup 2)
14554 (match_operand:SI 1 "tls_symbolic_operand" "")
14555 (match_dup 3)]
14556 UNSPEC_TLS_GD))
14557 (clobber (match_scratch:SI 4 ""))
14558 (clobber (match_scratch:SI 5 ""))
14559 (clobber (reg:CC 17))])]
14560 ""
14561 {
14562 if (flag_pic)
14563 operands[2] = pic_offset_table_rtx;
14564 else
14565 {
14566 operands[2] = gen_reg_rtx (Pmode);
14567 emit_insn (gen_set_got (operands[2]));
14568 }
14569 operands[3] = ix86_tls_get_addr ();
14570 })
14571
14572 (define_insn "*tls_global_dynamic_64"
14573 [(set (match_operand:DI 0 "register_operand" "=a")
14574 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14575 (match_operand:DI 3 "" "")))
14576 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14577 UNSPEC_TLS_GD)]
14578 "TARGET_64BIT"
14579 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14580 [(set_attr "type" "multi")
14581 (set_attr "length" "16")])
14582
14583 (define_expand "tls_global_dynamic_64"
14584 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14585 (call (mem:QI (match_dup 2)) (const_int 0)))
14586 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14587 UNSPEC_TLS_GD)])]
14588 ""
14589 {
14590 operands[2] = ix86_tls_get_addr ();
14591 })
14592
14593 (define_insn "*tls_local_dynamic_base_32_gnu"
14594 [(set (match_operand:SI 0 "register_operand" "=a")
14595 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14596 (match_operand:SI 2 "call_insn_operand" "")]
14597 UNSPEC_TLS_LD_BASE))
14598 (clobber (match_scratch:SI 3 "=d"))
14599 (clobber (match_scratch:SI 4 "=c"))
14600 (clobber (reg:CC 17))]
14601 "!TARGET_64BIT && TARGET_GNU_TLS"
14602 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14603 [(set_attr "type" "multi")
14604 (set_attr "length" "11")])
14605
14606 (define_insn "*tls_local_dynamic_base_32_sun"
14607 [(set (match_operand:SI 0 "register_operand" "=a")
14608 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14609 (match_operand:SI 2 "call_insn_operand" "")]
14610 UNSPEC_TLS_LD_BASE))
14611 (clobber (match_scratch:SI 3 "=d"))
14612 (clobber (match_scratch:SI 4 "=c"))
14613 (clobber (reg:CC 17))]
14614 "!TARGET_64BIT && TARGET_SUN_TLS"
14615 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14616 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14617 [(set_attr "type" "multi")
14618 (set_attr "length" "13")])
14619
14620 (define_expand "tls_local_dynamic_base_32"
14621 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14622 (unspec:SI [(match_dup 1) (match_dup 2)]
14623 UNSPEC_TLS_LD_BASE))
14624 (clobber (match_scratch:SI 3 ""))
14625 (clobber (match_scratch:SI 4 ""))
14626 (clobber (reg:CC 17))])]
14627 ""
14628 {
14629 if (flag_pic)
14630 operands[1] = pic_offset_table_rtx;
14631 else
14632 {
14633 operands[1] = gen_reg_rtx (Pmode);
14634 emit_insn (gen_set_got (operands[1]));
14635 }
14636 operands[2] = ix86_tls_get_addr ();
14637 })
14638
14639 (define_insn "*tls_local_dynamic_base_64"
14640 [(set (match_operand:DI 0 "register_operand" "=a")
14641 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14642 (match_operand:DI 2 "" "")))
14643 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14644 "TARGET_64BIT"
14645 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14646 [(set_attr "type" "multi")
14647 (set_attr "length" "12")])
14648
14649 (define_expand "tls_local_dynamic_base_64"
14650 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14651 (call (mem:QI (match_dup 1)) (const_int 0)))
14652 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14653 ""
14654 {
14655 operands[1] = ix86_tls_get_addr ();
14656 })
14657
14658 ;; Local dynamic of a single variable is a lose. Show combine how
14659 ;; to convert that back to global dynamic.
14660
14661 (define_insn_and_split "*tls_local_dynamic_32_once"
14662 [(set (match_operand:SI 0 "register_operand" "=a")
14663 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14664 (match_operand:SI 2 "call_insn_operand" "")]
14665 UNSPEC_TLS_LD_BASE)
14666 (const:SI (unspec:SI
14667 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14668 UNSPEC_DTPOFF))))
14669 (clobber (match_scratch:SI 4 "=d"))
14670 (clobber (match_scratch:SI 5 "=c"))
14671 (clobber (reg:CC 17))]
14672 ""
14673 "#"
14674 ""
14675 [(parallel [(set (match_dup 0)
14676 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14677 UNSPEC_TLS_GD))
14678 (clobber (match_dup 4))
14679 (clobber (match_dup 5))
14680 (clobber (reg:CC 17))])]
14681 "")
14682
14683 ;; Load and add the thread base pointer from %gs:0.
14684
14685 (define_insn "*load_tp_si"
14686 [(set (match_operand:SI 0 "register_operand" "=r")
14687 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14688 "!TARGET_64BIT"
14689 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14690 [(set_attr "type" "imov")
14691 (set_attr "modrm" "0")
14692 (set_attr "length" "7")
14693 (set_attr "memory" "load")
14694 (set_attr "imm_disp" "false")])
14695
14696 (define_insn "*add_tp_si"
14697 [(set (match_operand:SI 0 "register_operand" "=r")
14698 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14699 (match_operand:SI 1 "register_operand" "0")))
14700 (clobber (reg:CC 17))]
14701 "!TARGET_64BIT"
14702 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14703 [(set_attr "type" "alu")
14704 (set_attr "modrm" "0")
14705 (set_attr "length" "7")
14706 (set_attr "memory" "load")
14707 (set_attr "imm_disp" "false")])
14708
14709 (define_insn "*load_tp_di"
14710 [(set (match_operand:DI 0 "register_operand" "=r")
14711 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14712 "TARGET_64BIT"
14713 "mov{l}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14714 [(set_attr "type" "imov")
14715 (set_attr "modrm" "0")
14716 (set_attr "length" "7")
14717 (set_attr "memory" "load")
14718 (set_attr "imm_disp" "false")])
14719
14720 (define_insn "*add_tp_di"
14721 [(set (match_operand:DI 0 "register_operand" "=r")
14722 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14723 (match_operand:DI 1 "register_operand" "0")))
14724 (clobber (reg:CC 17))]
14725 "TARGET_64BIT"
14726 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14727 [(set_attr "type" "alu")
14728 (set_attr "modrm" "0")
14729 (set_attr "length" "7")
14730 (set_attr "memory" "load")
14731 (set_attr "imm_disp" "false")])
14732 \f
14733 ;; These patterns match the binary 387 instructions for addM3, subM3,
14734 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14735 ;; SFmode. The first is the normal insn, the second the same insn but
14736 ;; with one operand a conversion, and the third the same insn but with
14737 ;; the other operand a conversion. The conversion may be SFmode or
14738 ;; SImode if the target mode DFmode, but only SImode if the target mode
14739 ;; is SFmode.
14740
14741 ;; Gcc is slightly more smart about handling normal two address instructions
14742 ;; so use special patterns for add and mull.
14743 (define_insn "*fop_sf_comm_nosse"
14744 [(set (match_operand:SF 0 "register_operand" "=f")
14745 (match_operator:SF 3 "binary_fp_operator"
14746 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14747 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14748 "TARGET_80387 && !TARGET_SSE_MATH
14749 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14750 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14751 "* return output_387_binary_op (insn, operands);"
14752 [(set (attr "type")
14753 (if_then_else (match_operand:SF 3 "mult_operator" "")
14754 (const_string "fmul")
14755 (const_string "fop")))
14756 (set_attr "mode" "SF")])
14757
14758 (define_insn "*fop_sf_comm"
14759 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14760 (match_operator:SF 3 "binary_fp_operator"
14761 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14762 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14763 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14764 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14765 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14766 "* return output_387_binary_op (insn, operands);"
14767 [(set (attr "type")
14768 (if_then_else (eq_attr "alternative" "1")
14769 (if_then_else (match_operand:SF 3 "mult_operator" "")
14770 (const_string "ssemul")
14771 (const_string "sseadd"))
14772 (if_then_else (match_operand:SF 3 "mult_operator" "")
14773 (const_string "fmul")
14774 (const_string "fop"))))
14775 (set_attr "mode" "SF")])
14776
14777 (define_insn "*fop_sf_comm_sse"
14778 [(set (match_operand:SF 0 "register_operand" "=x")
14779 (match_operator:SF 3 "binary_fp_operator"
14780 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14781 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14782 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14783 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14784 "* return output_387_binary_op (insn, operands);"
14785 [(set (attr "type")
14786 (if_then_else (match_operand:SF 3 "mult_operator" "")
14787 (const_string "ssemul")
14788 (const_string "sseadd")))
14789 (set_attr "mode" "SF")])
14790
14791 (define_insn "*fop_df_comm_nosse"
14792 [(set (match_operand:DF 0 "register_operand" "=f")
14793 (match_operator:DF 3 "binary_fp_operator"
14794 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14795 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14796 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14797 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14798 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14799 "* return output_387_binary_op (insn, operands);"
14800 [(set (attr "type")
14801 (if_then_else (match_operand:SF 3 "mult_operator" "")
14802 (const_string "fmul")
14803 (const_string "fop")))
14804 (set_attr "mode" "DF")])
14805
14806 (define_insn "*fop_df_comm"
14807 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14808 (match_operator:DF 3 "binary_fp_operator"
14809 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14810 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14811 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14812 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14813 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14814 "* return output_387_binary_op (insn, operands);"
14815 [(set (attr "type")
14816 (if_then_else (eq_attr "alternative" "1")
14817 (if_then_else (match_operand:SF 3 "mult_operator" "")
14818 (const_string "ssemul")
14819 (const_string "sseadd"))
14820 (if_then_else (match_operand:SF 3 "mult_operator" "")
14821 (const_string "fmul")
14822 (const_string "fop"))))
14823 (set_attr "mode" "DF")])
14824
14825 (define_insn "*fop_df_comm_sse"
14826 [(set (match_operand:DF 0 "register_operand" "=Y")
14827 (match_operator:DF 3 "binary_fp_operator"
14828 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14829 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14830 "TARGET_SSE2 && TARGET_SSE_MATH
14831 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14832 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14833 "* return output_387_binary_op (insn, operands);"
14834 [(set (attr "type")
14835 (if_then_else (match_operand:SF 3 "mult_operator" "")
14836 (const_string "ssemul")
14837 (const_string "sseadd")))
14838 (set_attr "mode" "DF")])
14839
14840 (define_insn "*fop_xf_comm"
14841 [(set (match_operand:XF 0 "register_operand" "=f")
14842 (match_operator:XF 3 "binary_fp_operator"
14843 [(match_operand:XF 1 "register_operand" "%0")
14844 (match_operand:XF 2 "register_operand" "f")]))]
14845 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
14846 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14847 "* return output_387_binary_op (insn, operands);"
14848 [(set (attr "type")
14849 (if_then_else (match_operand:XF 3 "mult_operator" "")
14850 (const_string "fmul")
14851 (const_string "fop")))
14852 (set_attr "mode" "XF")])
14853
14854 (define_insn "*fop_tf_comm"
14855 [(set (match_operand:TF 0 "register_operand" "=f")
14856 (match_operator:TF 3 "binary_fp_operator"
14857 [(match_operand:TF 1 "register_operand" "%0")
14858 (match_operand:TF 2 "register_operand" "f")]))]
14859 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14860 "* return output_387_binary_op (insn, operands);"
14861 [(set (attr "type")
14862 (if_then_else (match_operand:TF 3 "mult_operator" "")
14863 (const_string "fmul")
14864 (const_string "fop")))
14865 (set_attr "mode" "XF")])
14866
14867 (define_insn "*fop_sf_1_nosse"
14868 [(set (match_operand:SF 0 "register_operand" "=f,f")
14869 (match_operator:SF 3 "binary_fp_operator"
14870 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14871 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14872 "TARGET_80387 && !TARGET_SSE_MATH
14873 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14874 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14875 "* return output_387_binary_op (insn, operands);"
14876 [(set (attr "type")
14877 (cond [(match_operand:SF 3 "mult_operator" "")
14878 (const_string "fmul")
14879 (match_operand:SF 3 "div_operator" "")
14880 (const_string "fdiv")
14881 ]
14882 (const_string "fop")))
14883 (set_attr "mode" "SF")])
14884
14885 (define_insn "*fop_sf_1"
14886 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14887 (match_operator:SF 3 "binary_fp_operator"
14888 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14889 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14890 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14891 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14892 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14893 "* return output_387_binary_op (insn, operands);"
14894 [(set (attr "type")
14895 (cond [(and (eq_attr "alternative" "2")
14896 (match_operand:SF 3 "mult_operator" ""))
14897 (const_string "ssemul")
14898 (and (eq_attr "alternative" "2")
14899 (match_operand:SF 3 "div_operator" ""))
14900 (const_string "ssediv")
14901 (eq_attr "alternative" "2")
14902 (const_string "sseadd")
14903 (match_operand:SF 3 "mult_operator" "")
14904 (const_string "fmul")
14905 (match_operand:SF 3 "div_operator" "")
14906 (const_string "fdiv")
14907 ]
14908 (const_string "fop")))
14909 (set_attr "mode" "SF")])
14910
14911 (define_insn "*fop_sf_1_sse"
14912 [(set (match_operand:SF 0 "register_operand" "=x")
14913 (match_operator:SF 3 "binary_fp_operator"
14914 [(match_operand:SF 1 "register_operand" "0")
14915 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14916 "TARGET_SSE_MATH
14917 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14918 "* return output_387_binary_op (insn, operands);"
14919 [(set (attr "type")
14920 (cond [(match_operand:SF 3 "mult_operator" "")
14921 (const_string "ssemul")
14922 (match_operand:SF 3 "div_operator" "")
14923 (const_string "ssediv")
14924 ]
14925 (const_string "sseadd")))
14926 (set_attr "mode" "SF")])
14927
14928 ;; ??? Add SSE splitters for these!
14929 (define_insn "*fop_sf_2"
14930 [(set (match_operand:SF 0 "register_operand" "=f,f")
14931 (match_operator:SF 3 "binary_fp_operator"
14932 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14933 (match_operand:SF 2 "register_operand" "0,0")]))]
14934 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14935 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14936 [(set (attr "type")
14937 (cond [(match_operand:SF 3 "mult_operator" "")
14938 (const_string "fmul")
14939 (match_operand:SF 3 "div_operator" "")
14940 (const_string "fdiv")
14941 ]
14942 (const_string "fop")))
14943 (set_attr "fp_int_src" "true")
14944 (set_attr "ppro_uops" "many")
14945 (set_attr "mode" "SI")])
14946
14947 (define_insn "*fop_sf_3"
14948 [(set (match_operand:SF 0 "register_operand" "=f,f")
14949 (match_operator:SF 3 "binary_fp_operator"
14950 [(match_operand:SF 1 "register_operand" "0,0")
14951 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14952 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14953 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14954 [(set (attr "type")
14955 (cond [(match_operand:SF 3 "mult_operator" "")
14956 (const_string "fmul")
14957 (match_operand:SF 3 "div_operator" "")
14958 (const_string "fdiv")
14959 ]
14960 (const_string "fop")))
14961 (set_attr "fp_int_src" "true")
14962 (set_attr "ppro_uops" "many")
14963 (set_attr "mode" "SI")])
14964
14965 (define_insn "*fop_df_1_nosse"
14966 [(set (match_operand:DF 0 "register_operand" "=f,f")
14967 (match_operator:DF 3 "binary_fp_operator"
14968 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14969 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14970 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14971 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14972 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14973 "* return output_387_binary_op (insn, operands);"
14974 [(set (attr "type")
14975 (cond [(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
14984 (define_insn "*fop_df_1"
14985 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14986 (match_operator:DF 3 "binary_fp_operator"
14987 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14988 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14989 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14990 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14992 "* return output_387_binary_op (insn, operands);"
14993 [(set (attr "type")
14994 (cond [(and (eq_attr "alternative" "2")
14995 (match_operand:SF 3 "mult_operator" ""))
14996 (const_string "ssemul")
14997 (and (eq_attr "alternative" "2")
14998 (match_operand:SF 3 "div_operator" ""))
14999 (const_string "ssediv")
15000 (eq_attr "alternative" "2")
15001 (const_string "sseadd")
15002 (match_operand:DF 3 "mult_operator" "")
15003 (const_string "fmul")
15004 (match_operand:DF 3 "div_operator" "")
15005 (const_string "fdiv")
15006 ]
15007 (const_string "fop")))
15008 (set_attr "mode" "DF")])
15009
15010 (define_insn "*fop_df_1_sse"
15011 [(set (match_operand:DF 0 "register_operand" "=Y")
15012 (match_operator:DF 3 "binary_fp_operator"
15013 [(match_operand:DF 1 "register_operand" "0")
15014 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15015 "TARGET_SSE2 && TARGET_SSE_MATH
15016 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15017 "* return output_387_binary_op (insn, operands);"
15018 [(set_attr "mode" "DF")
15019 (set (attr "type")
15020 (cond [(match_operand:SF 3 "mult_operator" "")
15021 (const_string "ssemul")
15022 (match_operand:SF 3 "div_operator" "")
15023 (const_string "ssediv")
15024 ]
15025 (const_string "sseadd")))])
15026
15027 ;; ??? Add SSE splitters for these!
15028 (define_insn "*fop_df_2"
15029 [(set (match_operand:DF 0 "register_operand" "=f,f")
15030 (match_operator:DF 3 "binary_fp_operator"
15031 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15032 (match_operand:DF 2 "register_operand" "0,0")]))]
15033 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15034 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15035 [(set (attr "type")
15036 (cond [(match_operand:DF 3 "mult_operator" "")
15037 (const_string "fmul")
15038 (match_operand:DF 3 "div_operator" "")
15039 (const_string "fdiv")
15040 ]
15041 (const_string "fop")))
15042 (set_attr "fp_int_src" "true")
15043 (set_attr "ppro_uops" "many")
15044 (set_attr "mode" "SI")])
15045
15046 (define_insn "*fop_df_3"
15047 [(set (match_operand:DF 0 "register_operand" "=f,f")
15048 (match_operator:DF 3 "binary_fp_operator"
15049 [(match_operand:DF 1 "register_operand" "0,0")
15050 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15051 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15052 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15053 [(set (attr "type")
15054 (cond [(match_operand:DF 3 "mult_operator" "")
15055 (const_string "fmul")
15056 (match_operand:DF 3 "div_operator" "")
15057 (const_string "fdiv")
15058 ]
15059 (const_string "fop")))
15060 (set_attr "fp_int_src" "true")
15061 (set_attr "ppro_uops" "many")
15062 (set_attr "mode" "SI")])
15063
15064 (define_insn "*fop_df_4"
15065 [(set (match_operand:DF 0 "register_operand" "=f,f")
15066 (match_operator:DF 3 "binary_fp_operator"
15067 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15068 (match_operand:DF 2 "register_operand" "0,f")]))]
15069 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
15070 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15071 "* return output_387_binary_op (insn, operands);"
15072 [(set (attr "type")
15073 (cond [(match_operand:DF 3 "mult_operator" "")
15074 (const_string "fmul")
15075 (match_operand:DF 3 "div_operator" "")
15076 (const_string "fdiv")
15077 ]
15078 (const_string "fop")))
15079 (set_attr "mode" "SF")])
15080
15081 (define_insn "*fop_df_5"
15082 [(set (match_operand:DF 0 "register_operand" "=f,f")
15083 (match_operator:DF 3 "binary_fp_operator"
15084 [(match_operand:DF 1 "register_operand" "0,f")
15085 (float_extend:DF
15086 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15087 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15088 "* return output_387_binary_op (insn, operands);"
15089 [(set (attr "type")
15090 (cond [(match_operand:DF 3 "mult_operator" "")
15091 (const_string "fmul")
15092 (match_operand:DF 3 "div_operator" "")
15093 (const_string "fdiv")
15094 ]
15095 (const_string "fop")))
15096 (set_attr "mode" "SF")])
15097
15098 (define_insn "*fop_df_6"
15099 [(set (match_operand:DF 0 "register_operand" "=f,f")
15100 (match_operator:DF 3 "binary_fp_operator"
15101 [(float_extend:DF
15102 (match_operand:SF 1 "register_operand" "0,f"))
15103 (float_extend:DF
15104 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15105 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15106 "* return output_387_binary_op (insn, operands);"
15107 [(set (attr "type")
15108 (cond [(match_operand:DF 3 "mult_operator" "")
15109 (const_string "fmul")
15110 (match_operand:DF 3 "div_operator" "")
15111 (const_string "fdiv")
15112 ]
15113 (const_string "fop")))
15114 (set_attr "mode" "SF")])
15115
15116 (define_insn "*fop_xf_1"
15117 [(set (match_operand:XF 0 "register_operand" "=f,f")
15118 (match_operator:XF 3 "binary_fp_operator"
15119 [(match_operand:XF 1 "register_operand" "0,f")
15120 (match_operand:XF 2 "register_operand" "f,0")]))]
15121 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
15122 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15123 "* return output_387_binary_op (insn, operands);"
15124 [(set (attr "type")
15125 (cond [(match_operand:XF 3 "mult_operator" "")
15126 (const_string "fmul")
15127 (match_operand:XF 3 "div_operator" "")
15128 (const_string "fdiv")
15129 ]
15130 (const_string "fop")))
15131 (set_attr "mode" "XF")])
15132
15133 (define_insn "*fop_tf_1"
15134 [(set (match_operand:TF 0 "register_operand" "=f,f")
15135 (match_operator:TF 3 "binary_fp_operator"
15136 [(match_operand:TF 1 "register_operand" "0,f")
15137 (match_operand:TF 2 "register_operand" "f,0")]))]
15138 "TARGET_80387
15139 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15140 "* return output_387_binary_op (insn, operands);"
15141 [(set (attr "type")
15142 (cond [(match_operand:TF 3 "mult_operator" "")
15143 (const_string "fmul")
15144 (match_operand:TF 3 "div_operator" "")
15145 (const_string "fdiv")
15146 ]
15147 (const_string "fop")))
15148 (set_attr "mode" "XF")])
15149
15150 (define_insn "*fop_xf_2"
15151 [(set (match_operand:XF 0 "register_operand" "=f,f")
15152 (match_operator:XF 3 "binary_fp_operator"
15153 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15154 (match_operand:XF 2 "register_operand" "0,0")]))]
15155 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15156 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15157 [(set (attr "type")
15158 (cond [(match_operand:XF 3 "mult_operator" "")
15159 (const_string "fmul")
15160 (match_operand:XF 3 "div_operator" "")
15161 (const_string "fdiv")
15162 ]
15163 (const_string "fop")))
15164 (set_attr "fp_int_src" "true")
15165 (set_attr "mode" "SI")
15166 (set_attr "ppro_uops" "many")])
15167
15168 (define_insn "*fop_tf_2"
15169 [(set (match_operand:TF 0 "register_operand" "=f,f")
15170 (match_operator:TF 3 "binary_fp_operator"
15171 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15172 (match_operand:TF 2 "register_operand" "0,0")]))]
15173 "TARGET_80387 && TARGET_USE_FIOP"
15174 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15175 [(set (attr "type")
15176 (cond [(match_operand:TF 3 "mult_operator" "")
15177 (const_string "fmul")
15178 (match_operand:TF 3 "div_operator" "")
15179 (const_string "fdiv")
15180 ]
15181 (const_string "fop")))
15182 (set_attr "fp_int_src" "true")
15183 (set_attr "mode" "SI")
15184 (set_attr "ppro_uops" "many")])
15185
15186 (define_insn "*fop_xf_3"
15187 [(set (match_operand:XF 0 "register_operand" "=f,f")
15188 (match_operator:XF 3 "binary_fp_operator"
15189 [(match_operand:XF 1 "register_operand" "0,0")
15190 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15191 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15192 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15193 [(set (attr "type")
15194 (cond [(match_operand:XF 3 "mult_operator" "")
15195 (const_string "fmul")
15196 (match_operand:XF 3 "div_operator" "")
15197 (const_string "fdiv")
15198 ]
15199 (const_string "fop")))
15200 (set_attr "fp_int_src" "true")
15201 (set_attr "mode" "SI")
15202 (set_attr "ppro_uops" "many")])
15203
15204 (define_insn "*fop_tf_3"
15205 [(set (match_operand:TF 0 "register_operand" "=f,f")
15206 (match_operator:TF 3 "binary_fp_operator"
15207 [(match_operand:TF 1 "register_operand" "0,0")
15208 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15209 "TARGET_80387 && TARGET_USE_FIOP"
15210 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15211 [(set (attr "type")
15212 (cond [(match_operand:TF 3 "mult_operator" "")
15213 (const_string "fmul")
15214 (match_operand:TF 3 "div_operator" "")
15215 (const_string "fdiv")
15216 ]
15217 (const_string "fop")))
15218 (set_attr "fp_int_src" "true")
15219 (set_attr "mode" "SI")
15220 (set_attr "ppro_uops" "many")])
15221
15222 (define_insn "*fop_xf_4"
15223 [(set (match_operand:XF 0 "register_operand" "=f,f")
15224 (match_operator:XF 3 "binary_fp_operator"
15225 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15226 (match_operand:XF 2 "register_operand" "0,f")]))]
15227 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15228 "* return output_387_binary_op (insn, operands);"
15229 [(set (attr "type")
15230 (cond [(match_operand:XF 3 "mult_operator" "")
15231 (const_string "fmul")
15232 (match_operand:XF 3 "div_operator" "")
15233 (const_string "fdiv")
15234 ]
15235 (const_string "fop")))
15236 (set_attr "mode" "SF")])
15237
15238 (define_insn "*fop_tf_4"
15239 [(set (match_operand:TF 0 "register_operand" "=f,f")
15240 (match_operator:TF 3 "binary_fp_operator"
15241 [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
15242 (match_operand:TF 2 "register_operand" "0,f")]))]
15243 "TARGET_80387"
15244 "* return output_387_binary_op (insn, operands);"
15245 [(set (attr "type")
15246 (cond [(match_operand:TF 3 "mult_operator" "")
15247 (const_string "fmul")
15248 (match_operand:TF 3 "div_operator" "")
15249 (const_string "fdiv")
15250 ]
15251 (const_string "fop")))
15252 (set_attr "mode" "SF")])
15253
15254 (define_insn "*fop_xf_5"
15255 [(set (match_operand:XF 0 "register_operand" "=f,f")
15256 (match_operator:XF 3 "binary_fp_operator"
15257 [(match_operand:XF 1 "register_operand" "0,f")
15258 (float_extend:XF
15259 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15260 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15261 "* return output_387_binary_op (insn, operands);"
15262 [(set (attr "type")
15263 (cond [(match_operand:XF 3 "mult_operator" "")
15264 (const_string "fmul")
15265 (match_operand:XF 3 "div_operator" "")
15266 (const_string "fdiv")
15267 ]
15268 (const_string "fop")))
15269 (set_attr "mode" "SF")])
15270
15271 (define_insn "*fop_tf_5"
15272 [(set (match_operand:TF 0 "register_operand" "=f,f")
15273 (match_operator:TF 3 "binary_fp_operator"
15274 [(match_operand:TF 1 "register_operand" "0,f")
15275 (float_extend:TF
15276 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15277 "TARGET_80387"
15278 "* return output_387_binary_op (insn, operands);"
15279 [(set (attr "type")
15280 (cond [(match_operand:TF 3 "mult_operator" "")
15281 (const_string "fmul")
15282 (match_operand:TF 3 "div_operator" "")
15283 (const_string "fdiv")
15284 ]
15285 (const_string "fop")))
15286 (set_attr "mode" "SF")])
15287
15288 (define_insn "*fop_xf_6"
15289 [(set (match_operand:XF 0 "register_operand" "=f,f")
15290 (match_operator:XF 3 "binary_fp_operator"
15291 [(float_extend:XF
15292 (match_operand 1 "register_operand" "0,f"))
15293 (float_extend:XF
15294 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15295 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15296 "* return output_387_binary_op (insn, operands);"
15297 [(set (attr "type")
15298 (cond [(match_operand:XF 3 "mult_operator" "")
15299 (const_string "fmul")
15300 (match_operand:XF 3 "div_operator" "")
15301 (const_string "fdiv")
15302 ]
15303 (const_string "fop")))
15304 (set_attr "mode" "SF")])
15305
15306 (define_insn "*fop_tf_6"
15307 [(set (match_operand:TF 0 "register_operand" "=f,f")
15308 (match_operator:TF 3 "binary_fp_operator"
15309 [(float_extend:TF
15310 (match_operand 1 "register_operand" "0,f"))
15311 (float_extend:TF
15312 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15313 "TARGET_80387"
15314 "* return output_387_binary_op (insn, operands);"
15315 [(set (attr "type")
15316 (cond [(match_operand:TF 3 "mult_operator" "")
15317 (const_string "fmul")
15318 (match_operand:TF 3 "div_operator" "")
15319 (const_string "fdiv")
15320 ]
15321 (const_string "fop")))
15322 (set_attr "mode" "SF")])
15323
15324 (define_split
15325 [(set (match_operand 0 "register_operand" "")
15326 (match_operator 3 "binary_fp_operator"
15327 [(float (match_operand:SI 1 "register_operand" ""))
15328 (match_operand 2 "register_operand" "")]))]
15329 "TARGET_80387 && reload_completed
15330 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15331 [(const_int 0)]
15332 {
15333 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15334 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15335 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15336 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15337 GET_MODE (operands[3]),
15338 operands[4],
15339 operands[2])));
15340 ix86_free_from_memory (GET_MODE (operands[1]));
15341 DONE;
15342 })
15343
15344 (define_split
15345 [(set (match_operand 0 "register_operand" "")
15346 (match_operator 3 "binary_fp_operator"
15347 [(match_operand 1 "register_operand" "")
15348 (float (match_operand:SI 2 "register_operand" ""))]))]
15349 "TARGET_80387 && reload_completed
15350 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15351 [(const_int 0)]
15352 {
15353 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15354 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15355 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15356 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15357 GET_MODE (operands[3]),
15358 operands[1],
15359 operands[4])));
15360 ix86_free_from_memory (GET_MODE (operands[2]));
15361 DONE;
15362 })
15363 \f
15364 ;; FPU special functions.
15365
15366 (define_expand "sqrtsf2"
15367 [(set (match_operand:SF 0 "register_operand" "")
15368 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15369 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
15370 {
15371 if (!TARGET_SSE_MATH)
15372 operands[1] = force_reg (SFmode, operands[1]);
15373 })
15374
15375 (define_insn "sqrtsf2_1"
15376 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15377 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15378 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15379 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15380 "@
15381 fsqrt
15382 sqrtss\t{%1, %0|%0, %1}"
15383 [(set_attr "type" "fpspc,sse")
15384 (set_attr "mode" "SF,SF")
15385 (set_attr "athlon_decode" "direct,*")])
15386
15387 (define_insn "sqrtsf2_1_sse_only"
15388 [(set (match_operand:SF 0 "register_operand" "=x")
15389 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15390 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15391 "sqrtss\t{%1, %0|%0, %1}"
15392 [(set_attr "type" "sse")
15393 (set_attr "mode" "SF")
15394 (set_attr "athlon_decode" "*")])
15395
15396 (define_insn "sqrtsf2_i387"
15397 [(set (match_operand:SF 0 "register_operand" "=f")
15398 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15399 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15400 && !TARGET_SSE_MATH"
15401 "fsqrt"
15402 [(set_attr "type" "fpspc")
15403 (set_attr "mode" "SF")
15404 (set_attr "athlon_decode" "direct")])
15405
15406 (define_expand "sqrtdf2"
15407 [(set (match_operand:DF 0 "register_operand" "")
15408 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15409 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
15410 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15411 {
15412 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
15413 operands[1] = force_reg (DFmode, operands[1]);
15414 })
15415
15416 (define_insn "sqrtdf2_1"
15417 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15418 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15419 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15420 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15421 "@
15422 fsqrt
15423 sqrtsd\t{%1, %0|%0, %1}"
15424 [(set_attr "type" "fpspc,sse")
15425 (set_attr "mode" "DF,DF")
15426 (set_attr "athlon_decode" "direct,*")])
15427
15428 (define_insn "sqrtdf2_1_sse_only"
15429 [(set (match_operand:DF 0 "register_operand" "=Y")
15430 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15431 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15432 "sqrtsd\t{%1, %0|%0, %1}"
15433 [(set_attr "type" "sse")
15434 (set_attr "mode" "DF")
15435 (set_attr "athlon_decode" "*")])
15436
15437 (define_insn "sqrtdf2_i387"
15438 [(set (match_operand:DF 0 "register_operand" "=f")
15439 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15440 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15441 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
15442 "fsqrt"
15443 [(set_attr "type" "fpspc")
15444 (set_attr "mode" "DF")
15445 (set_attr "athlon_decode" "direct")])
15446
15447 (define_insn "*sqrtextendsfdf2"
15448 [(set (match_operand:DF 0 "register_operand" "=f")
15449 (sqrt:DF (float_extend:DF
15450 (match_operand:SF 1 "register_operand" "0"))))]
15451 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15452 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15453 "fsqrt"
15454 [(set_attr "type" "fpspc")
15455 (set_attr "mode" "DF")
15456 (set_attr "athlon_decode" "direct")])
15457
15458 (define_insn "sqrtxf2"
15459 [(set (match_operand:XF 0 "register_operand" "=f")
15460 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15461 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15462 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15463 "fsqrt"
15464 [(set_attr "type" "fpspc")
15465 (set_attr "mode" "XF")
15466 (set_attr "athlon_decode" "direct")])
15467
15468 (define_insn "sqrttf2"
15469 [(set (match_operand:TF 0 "register_operand" "=f")
15470 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
15471 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15472 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15473 "fsqrt"
15474 [(set_attr "type" "fpspc")
15475 (set_attr "mode" "XF")
15476 (set_attr "athlon_decode" "direct")])
15477
15478 (define_insn "*sqrtextenddfxf2"
15479 [(set (match_operand:XF 0 "register_operand" "=f")
15480 (sqrt:XF (float_extend:XF
15481 (match_operand:DF 1 "register_operand" "0"))))]
15482 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15483 "fsqrt"
15484 [(set_attr "type" "fpspc")
15485 (set_attr "mode" "XF")
15486 (set_attr "athlon_decode" "direct")])
15487
15488 (define_insn "*sqrtextenddftf2"
15489 [(set (match_operand:TF 0 "register_operand" "=f")
15490 (sqrt:TF (float_extend:TF
15491 (match_operand:DF 1 "register_operand" "0"))))]
15492 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15493 "fsqrt"
15494 [(set_attr "type" "fpspc")
15495 (set_attr "mode" "XF")
15496 (set_attr "athlon_decode" "direct")])
15497
15498 (define_insn "*sqrtextendsfxf2"
15499 [(set (match_operand:XF 0 "register_operand" "=f")
15500 (sqrt:XF (float_extend:XF
15501 (match_operand:SF 1 "register_operand" "0"))))]
15502 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15503 "fsqrt"
15504 [(set_attr "type" "fpspc")
15505 (set_attr "mode" "XF")
15506 (set_attr "athlon_decode" "direct")])
15507
15508 (define_insn "*sqrtextendsftf2"
15509 [(set (match_operand:TF 0 "register_operand" "=f")
15510 (sqrt:TF (float_extend:TF
15511 (match_operand:SF 1 "register_operand" "0"))))]
15512 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15513 "fsqrt"
15514 [(set_attr "type" "fpspc")
15515 (set_attr "mode" "XF")
15516 (set_attr "athlon_decode" "direct")])
15517
15518 (define_insn "sindf2"
15519 [(set (match_operand:DF 0 "register_operand" "=f")
15520 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15521 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15522 && flag_unsafe_math_optimizations"
15523 "fsin"
15524 [(set_attr "type" "fpspc")
15525 (set_attr "mode" "DF")])
15526
15527 (define_insn "sinsf2"
15528 [(set (match_operand:SF 0 "register_operand" "=f")
15529 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15530 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15531 && flag_unsafe_math_optimizations"
15532 "fsin"
15533 [(set_attr "type" "fpspc")
15534 (set_attr "mode" "SF")])
15535
15536 (define_insn "*sinextendsfdf2"
15537 [(set (match_operand:DF 0 "register_operand" "=f")
15538 (unspec:DF [(float_extend:DF
15539 (match_operand:SF 1 "register_operand" "0"))]
15540 UNSPEC_SIN))]
15541 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15542 && flag_unsafe_math_optimizations"
15543 "fsin"
15544 [(set_attr "type" "fpspc")
15545 (set_attr "mode" "DF")])
15546
15547 (define_insn "sinxf2"
15548 [(set (match_operand:XF 0 "register_operand" "=f")
15549 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15550 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15551 && flag_unsafe_math_optimizations"
15552 "fsin"
15553 [(set_attr "type" "fpspc")
15554 (set_attr "mode" "XF")])
15555
15556 (define_insn "sintf2"
15557 [(set (match_operand:TF 0 "register_operand" "=f")
15558 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15559 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15560 && flag_unsafe_math_optimizations"
15561 "fsin"
15562 [(set_attr "type" "fpspc")
15563 (set_attr "mode" "XF")])
15564
15565 (define_insn "cosdf2"
15566 [(set (match_operand:DF 0 "register_operand" "=f")
15567 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15568 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15569 && flag_unsafe_math_optimizations"
15570 "fcos"
15571 [(set_attr "type" "fpspc")
15572 (set_attr "mode" "DF")])
15573
15574 (define_insn "cossf2"
15575 [(set (match_operand:SF 0 "register_operand" "=f")
15576 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15577 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15578 && flag_unsafe_math_optimizations"
15579 "fcos"
15580 [(set_attr "type" "fpspc")
15581 (set_attr "mode" "SF")])
15582
15583 (define_insn "*cosextendsfdf2"
15584 [(set (match_operand:DF 0 "register_operand" "=f")
15585 (unspec:DF [(float_extend:DF
15586 (match_operand:SF 1 "register_operand" "0"))]
15587 UNSPEC_COS))]
15588 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15589 && flag_unsafe_math_optimizations"
15590 "fcos"
15591 [(set_attr "type" "fpspc")
15592 (set_attr "mode" "DF")])
15593
15594 (define_insn "cosxf2"
15595 [(set (match_operand:XF 0 "register_operand" "=f")
15596 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15597 "!TARGET_128BIT_LONG_DOUBLE && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15598 && flag_unsafe_math_optimizations"
15599 "fcos"
15600 [(set_attr "type" "fpspc")
15601 (set_attr "mode" "XF")])
15602
15603 (define_insn "costf2"
15604 [(set (match_operand:TF 0 "register_operand" "=f")
15605 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15606 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15607 && flag_unsafe_math_optimizations"
15608 "fcos"
15609 [(set_attr "type" "fpspc")
15610 (set_attr "mode" "XF")])
15611
15612 (define_insn "atan2df3_1"
15613 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15614 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15615 (match_operand:DF 1 "register_operand" "u")]
15616 UNSPEC_FPATAN))
15617 (clobber (match_dup 1))])]
15618 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15619 && flag_unsafe_math_optimizations"
15620 "fpatan"
15621 [(set_attr "type" "fpspc")
15622 (set_attr "mode" "DF")])
15623
15624 (define_expand "atan2df3"
15625 [(use (match_operand:DF 0 "register_operand" "=f"))
15626 (use (match_operand:DF 2 "register_operand" "0"))
15627 (use (match_operand:DF 1 "register_operand" "u"))]
15628 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15629 && flag_unsafe_math_optimizations"
15630 {
15631 rtx copy = gen_reg_rtx (DFmode);
15632 emit_move_insn (copy, operands[1]);
15633 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15634 DONE;
15635 })
15636
15637 (define_insn "atan2sf3_1"
15638 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15639 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15640 (match_operand:SF 1 "register_operand" "u")]
15641 UNSPEC_FPATAN))
15642 (clobber (match_dup 1))])]
15643 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15644 && flag_unsafe_math_optimizations"
15645 "fpatan"
15646 [(set_attr "type" "fpspc")
15647 (set_attr "mode" "SF")])
15648
15649 (define_expand "atan2sf3"
15650 [(use (match_operand:SF 0 "register_operand" "=f"))
15651 (use (match_operand:SF 2 "register_operand" "0"))
15652 (use (match_operand:SF 1 "register_operand" "u"))]
15653 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15654 && flag_unsafe_math_optimizations"
15655 {
15656 rtx copy = gen_reg_rtx (SFmode);
15657 emit_move_insn (copy, operands[1]);
15658 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15659 DONE;
15660 })
15661
15662 (define_insn "atan2xf3_1"
15663 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15664 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15665 (match_operand:XF 1 "register_operand" "u")]
15666 UNSPEC_FPATAN))
15667 (clobber (match_dup 1))])]
15668 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15669 && flag_unsafe_math_optimizations && ! TARGET_128BIT_LONG_DOUBLE"
15670 "fpatan"
15671 [(set_attr "type" "fpspc")
15672 (set_attr "mode" "XF")])
15673
15674 (define_expand "atan2xf3"
15675 [(use (match_operand:XF 0 "register_operand" "=f"))
15676 (use (match_operand:XF 2 "register_operand" "0"))
15677 (use (match_operand:XF 1 "register_operand" "u"))]
15678 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15679 && flag_unsafe_math_optimizations && ! TARGET_128BIT_LONG_DOUBLE"
15680 {
15681 rtx copy = gen_reg_rtx (XFmode);
15682 emit_move_insn (copy, operands[1]);
15683 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15684 DONE;
15685 })
15686
15687 (define_insn "atan2tf3_1"
15688 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15689 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15690 (match_operand:TF 1 "register_operand" "u")]
15691 UNSPEC_FPATAN))
15692 (clobber (match_dup 1))])]
15693 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15694 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15695 "fpatan"
15696 [(set_attr "type" "fpspc")
15697 (set_attr "mode" "XF")])
15698
15699 (define_expand "atan2tf3"
15700 [(use (match_operand:TF 0 "register_operand" "=f"))
15701 (use (match_operand:TF 2 "register_operand" "0"))
15702 (use (match_operand:TF 1 "register_operand" "u"))]
15703 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15704 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15705 {
15706 rtx copy = gen_reg_rtx (TFmode);
15707 emit_move_insn (copy, operands[1]);
15708 emit_insn (gen_atan2tf3_1 (operands[0], copy, operands[2]));
15709 DONE;
15710 })
15711
15712 (define_insn "*fyl2x_sfxf3"
15713 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15714 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15715 (match_operand 1 "register_operand" "u")]
15716 UNSPEC_FYL2X))
15717 (clobber (match_dup 1))])]
15718 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15719 && flag_unsafe_math_optimizations
15720 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15721 "fyl2x"
15722 [(set_attr "type" "fpspc")
15723 (set_attr "mode" "SF")])
15724
15725 (define_insn "*fyl2x_dfxf3"
15726 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15727 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15728 (match_operand 1 "register_operand" "u")]
15729 UNSPEC_FYL2X))
15730 (clobber (match_dup 1))])]
15731 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15732 && flag_unsafe_math_optimizations
15733 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15734 "fyl2x"
15735 [(set_attr "type" "fpspc")
15736 (set_attr "mode" "DF")])
15737
15738 (define_insn "*fyl2x_xf3"
15739 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15740 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15741 (match_operand:XF 1 "register_operand" "u")]
15742 UNSPEC_FYL2X))
15743 (clobber (match_dup 1))])]
15744 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15745 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15746 "fyl2x"
15747 [(set_attr "type" "fpspc")
15748 (set_attr "mode" "XF")])
15749
15750 (define_insn "*fyl2x_tfxf3"
15751 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15752 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15753 (match_operand:TF 1 "register_operand" "u")]
15754 UNSPEC_FYL2X))
15755 (clobber (match_dup 1))])]
15756 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15757 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15758 "fyl2x"
15759 [(set_attr "type" "fpspc")
15760 (set_attr "mode" "XF")])
15761
15762 (define_expand "logsf2"
15763 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15764 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15765 (match_dup 2)] UNSPEC_FYL2X))
15766 (clobber (match_dup 2))])]
15767 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15768 && flag_unsafe_math_optimizations"
15769 {
15770 rtx temp;
15771
15772 operands[2] = gen_reg_rtx (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode);
15773 temp = standard_80387_constant_rtx (4); /* fldln2 */
15774 emit_move_insn (operands[2], temp);
15775 })
15776
15777 (define_expand "logdf2"
15778 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15779 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15780 (match_dup 2)] UNSPEC_FYL2X))
15781 (clobber (match_dup 2))])]
15782 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15783 && flag_unsafe_math_optimizations"
15784 {
15785 rtx temp;
15786
15787 operands[2] = gen_reg_rtx (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode);
15788 temp = standard_80387_constant_rtx (4); /* fldln2 */
15789 emit_move_insn (operands[2], temp);
15790 })
15791
15792 (define_expand "logxf2"
15793 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15794 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15795 (match_dup 2)] UNSPEC_FYL2X))
15796 (clobber (match_dup 2))])]
15797 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15798 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15799 {
15800 rtx temp;
15801
15802 operands[2] = gen_reg_rtx (XFmode);
15803 temp = standard_80387_constant_rtx (4); /* fldln2 */
15804 emit_move_insn (operands[2], temp);
15805 })
15806
15807 (define_expand "logtf2"
15808 [(parallel [(set (match_operand:TF 0 "register_operand" "")
15809 (unspec:TF [(match_operand:TF 1 "register_operand" "")
15810 (match_dup 2)] UNSPEC_FYL2X))
15811 (clobber (match_dup 2))])]
15812 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15813 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15814 {
15815 rtx temp;
15816
15817 operands[2] = gen_reg_rtx (TFmode);
15818 temp = standard_80387_constant_rtx (4); /* fldln2 */
15819 emit_move_insn (operands[2], temp);
15820 })
15821
15822 (define_insn "*fscale_sfxf3"
15823 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15824 (unspec:SF [(match_operand 2 "register_operand" "0")
15825 (match_operand 1 "register_operand" "u")]
15826 UNSPEC_FSCALE))
15827 (clobber (match_dup 1))])]
15828 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15829 && flag_unsafe_math_optimizations
15830 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)
15831 && GET_MODE (operands[2]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15832 "fscale\;fstp\t%y1"
15833 [(set_attr "type" "fpspc")
15834 (set_attr "mode" "SF")])
15835
15836 (define_insn "*fscale_dfxf3"
15837 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15838 (unspec:DF [(match_operand 2 "register_operand" "0")
15839 (match_operand 1 "register_operand" "u")]
15840 UNSPEC_FSCALE))
15841 (clobber (match_dup 1))])]
15842 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15843 && flag_unsafe_math_optimizations
15844 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)
15845 && GET_MODE (operands[2]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15846 "fscale\;fstp\t%y1"
15847 [(set_attr "type" "fpspc")
15848 (set_attr "mode" "DF")])
15849
15850 (define_insn "*fscale_xf3"
15851 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15852 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15853 (match_operand:XF 1 "register_operand" "u")]
15854 UNSPEC_FSCALE))
15855 (clobber (match_dup 1))])]
15856 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15857 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15858 "fscale\;fstp\t%y1"
15859 [(set_attr "type" "fpspc")
15860 (set_attr "mode" "XF")])
15861
15862 (define_insn "*fscale_tf3"
15863 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15864 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15865 (match_operand:TF 1 "register_operand" "u")]
15866 UNSPEC_FSCALE))
15867 (clobber (match_dup 1))])]
15868 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15869 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15870 "fscale\;fstp\t%y1"
15871 [(set_attr "type" "fpspc")
15872 (set_attr "mode" "XF")])
15873
15874 (define_insn "*frndintxf2"
15875 [(set (match_operand:XF 0 "register_operand" "=f")
15876 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15877 UNSPEC_FRNDINT))]
15878 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15879 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15880 "frndint"
15881 [(set_attr "type" "fpspc")
15882 (set_attr "mode" "XF")])
15883
15884 (define_insn "*frndinttf2"
15885 [(set (match_operand:TF 0 "register_operand" "=f")
15886 (unspec:TF [(match_operand:TF 1 "register_operand" "0")]
15887 UNSPEC_FRNDINT))]
15888 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15889 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15890 "frndint"
15891 [(set_attr "type" "fpspc")
15892 (set_attr "mode" "XF")])
15893
15894 (define_insn "*f2xm1xf2"
15895 [(set (match_operand:XF 0 "register_operand" "=f")
15896 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15897 UNSPEC_F2XM1))]
15898 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15899 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15900 "f2xm1"
15901 [(set_attr "type" "fpspc")
15902 (set_attr "mode" "XF")])
15903
15904 (define_insn "*f2xm1tf2"
15905 [(set (match_operand:TF 0 "register_operand" "=f")
15906 (unspec:TF [(match_operand:TF 1 "register_operand" "0")]
15907 UNSPEC_F2XM1))]
15908 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15909 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15910 "f2xm1"
15911 [(set_attr "type" "fpspc")
15912 (set_attr "mode" "XF")])
15913
15914 (define_expand "expsf2"
15915 [(set (match_dup 2)
15916 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15917 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15918 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15919 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15920 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15921 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15922 (parallel [(set (match_operand:SF 0 "register_operand" "")
15923 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15924 (clobber (match_dup 5))])]
15925 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15926 && flag_unsafe_math_optimizations"
15927 {
15928 rtx temp;
15929 int i;
15930
15931 if (TARGET_128BIT_LONG_DOUBLE)
15932 {
15933 emit_insn (gen_expsf2_tf (operands[0], operands[1]));
15934 DONE;
15935 }
15936
15937 for (i=2; i<10; i++)
15938 operands[i] = gen_reg_rtx (XFmode);
15939 temp = standard_80387_constant_rtx (5); /* fldl2e */
15940 emit_move_insn (operands[3], temp);
15941 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15942 })
15943
15944 (define_expand "expsf2_tf"
15945 [(set (match_dup 2)
15946 (float_extend:TF (match_operand:SF 1 "register_operand" "")))
15947 (set (match_dup 4) (mult:TF (match_dup 2) (match_dup 3)))
15948 (set (match_dup 5) (unspec:TF [(match_dup 4)] UNSPEC_FRNDINT))
15949 (set (match_dup 6) (minus:TF (match_dup 4) (match_dup 5)))
15950 (set (match_dup 7) (unspec:TF [(match_dup 6)] UNSPEC_F2XM1))
15951 (set (match_dup 9) (plus:TF (match_dup 7) (match_dup 8)))
15952 (parallel [(set (match_operand:SF 0 "register_operand" "")
15953 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15954 (clobber (match_dup 5))])]
15955 ""
15956 {
15957 rtx temp;
15958 int i;
15959
15960 for (i=2; i<10; i++)
15961 operands[i] = gen_reg_rtx (TFmode);
15962 temp = standard_80387_constant_rtx (5); /* fldl2e */
15963 emit_move_insn (operands[3], temp);
15964 emit_move_insn (operands[8], CONST1_RTX (TFmode)); /* fld1 */
15965 })
15966
15967 (define_expand "expdf2"
15968 [(set (match_dup 2)
15969 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15970 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15971 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15972 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15973 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15974 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15975 (parallel [(set (match_operand:DF 0 "register_operand" "")
15976 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15977 (clobber (match_dup 5))])]
15978 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15979 && flag_unsafe_math_optimizations"
15980 {
15981 rtx temp;
15982 int i;
15983
15984 if (TARGET_128BIT_LONG_DOUBLE)
15985 {
15986 emit_insn (gen_expdf2_tf (operands[0], operands[1]));
15987 DONE;
15988 }
15989
15990 for (i=2; i<10; i++)
15991 operands[i] = gen_reg_rtx (XFmode);
15992 temp = standard_80387_constant_rtx (5); /* fldl2e */
15993 emit_move_insn (operands[3], temp);
15994 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15995 })
15996
15997
15998 (define_expand "expdf2_tf"
15999 [(set (match_dup 2)
16000 (float_extend:TF (match_operand:DF 1 "register_operand" "")))
16001 (set (match_dup 4) (mult:TF (match_dup 2) (match_dup 3)))
16002 (set (match_dup 5) (unspec:TF [(match_dup 4)] UNSPEC_FRNDINT))
16003 (set (match_dup 6) (minus:TF (match_dup 4) (match_dup 5)))
16004 (set (match_dup 7) (unspec:TF [(match_dup 6)] UNSPEC_F2XM1))
16005 (set (match_dup 9) (plus:TF (match_dup 7) (match_dup 8)))
16006 (parallel [(set (match_operand:DF 0 "register_operand" "")
16007 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
16008 (clobber (match_dup 5))])]
16009 ""
16010 {
16011 rtx temp;
16012 int i;
16013
16014 for (i=2; i<10; i++)
16015 operands[i] = gen_reg_rtx (TFmode);
16016 temp = standard_80387_constant_rtx (5); /* fldl2e */
16017 emit_move_insn (operands[3], temp);
16018 emit_move_insn (operands[8], CONST1_RTX (TFmode)); /* fld1 */
16019 })
16020
16021 (define_expand "expxf2"
16022 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16023 (match_dup 2)))
16024 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16025 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16026 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16027 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16028 (parallel [(set (match_operand:XF 0 "register_operand" "")
16029 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
16030 (clobber (match_dup 4))])]
16031 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16032 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
16033 {
16034 rtx temp;
16035 int i;
16036
16037 for (i=2; i<9; i++)
16038 operands[i] = gen_reg_rtx (XFmode);
16039 temp = standard_80387_constant_rtx (5); /* fldl2e */
16040 emit_move_insn (operands[2], temp);
16041 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16042 })
16043
16044 (define_expand "atansf2"
16045 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16046 (unspec:SF [(match_dup 2)
16047 (match_operand:SF 1 "register_operand" "")]
16048 UNSPEC_FPATAN))
16049 (clobber (match_dup 1))])]
16050 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16051 && flag_unsafe_math_optimizations"
16052 {
16053 operands[2] = gen_reg_rtx (SFmode);
16054 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16055 })
16056
16057 (define_expand "exptf2"
16058 [(set (match_dup 3) (mult:TF (match_operand:TF 1 "register_operand" "")
16059 (match_dup 2)))
16060 (set (match_dup 4) (unspec:TF [(match_dup 3)] UNSPEC_FRNDINT))
16061 (set (match_dup 5) (minus:TF (match_dup 3) (match_dup 4)))
16062 (set (match_dup 6) (unspec:TF [(match_dup 5)] UNSPEC_F2XM1))
16063 (set (match_dup 8) (plus:TF (match_dup 6) (match_dup 7)))
16064 (parallel [(set (match_operand:TF 0 "register_operand" "")
16065 (unspec:TF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
16066 (clobber (match_dup 4))])]
16067 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16068 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
16069 {
16070 rtx temp;
16071 int i;
16072
16073 for (i=2; i<9; i++)
16074 operands[i] = gen_reg_rtx (TFmode);
16075 temp = standard_80387_constant_rtx (5); /* fldl2e */
16076 emit_move_insn (operands[2], temp);
16077 emit_move_insn (operands[7], CONST1_RTX (TFmode)); /* fld1 */
16078 })
16079
16080 (define_expand "atandf2"
16081 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16082 (unspec:DF [(match_dup 2)
16083 (match_operand:DF 1 "register_operand" "")]
16084 UNSPEC_FPATAN))
16085 (clobber (match_dup 1))])]
16086 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16087 && flag_unsafe_math_optimizations"
16088 {
16089 operands[2] = gen_reg_rtx (DFmode);
16090 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16091 })
16092
16093 (define_expand "atanxf2"
16094 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16095 (unspec:XF [(match_dup 2)
16096 (match_operand:XF 1 "register_operand" "")]
16097 UNSPEC_FPATAN))
16098 (clobber (match_dup 1))])]
16099 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16100 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
16101 {
16102 operands[2] = gen_reg_rtx (XFmode);
16103 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16104 })
16105
16106 (define_expand "atantf2"
16107 [(parallel [(set (match_operand:TF 0 "register_operand" "")
16108 (unspec:TF [(match_dup 2)
16109 (match_operand:TF 1 "register_operand" "")]
16110 UNSPEC_FPATAN))
16111 (clobber (match_dup 1))])]
16112 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16113 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
16114 {
16115 operands[2] = gen_reg_rtx (TFmode);
16116 emit_move_insn (operands[2], CONST1_RTX (TFmode)); /* fld1 */
16117 })
16118 \f
16119 ;; Block operation instructions
16120
16121 (define_insn "cld"
16122 [(set (reg:SI 19) (const_int 0))]
16123 ""
16124 "cld"
16125 [(set_attr "type" "cld")])
16126
16127 (define_expand "movstrsi"
16128 [(use (match_operand:BLK 0 "memory_operand" ""))
16129 (use (match_operand:BLK 1 "memory_operand" ""))
16130 (use (match_operand:SI 2 "nonmemory_operand" ""))
16131 (use (match_operand:SI 3 "const_int_operand" ""))]
16132 "! optimize_size"
16133 {
16134 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16135 DONE;
16136 else
16137 FAIL;
16138 })
16139
16140 (define_expand "movstrdi"
16141 [(use (match_operand:BLK 0 "memory_operand" ""))
16142 (use (match_operand:BLK 1 "memory_operand" ""))
16143 (use (match_operand:DI 2 "nonmemory_operand" ""))
16144 (use (match_operand:DI 3 "const_int_operand" ""))]
16145 "TARGET_64BIT"
16146 {
16147 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16148 DONE;
16149 else
16150 FAIL;
16151 })
16152
16153 ;; Most CPUs don't like single string operations
16154 ;; Handle this case here to simplify previous expander.
16155
16156 (define_expand "strmovdi_rex64"
16157 [(set (match_dup 2)
16158 (mem:DI (match_operand:DI 1 "register_operand" "")))
16159 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
16160 (match_dup 2))
16161 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16162 (clobber (reg:CC 17))])
16163 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
16164 (clobber (reg:CC 17))])]
16165 "TARGET_64BIT"
16166 {
16167 if (TARGET_SINGLE_STRINGOP || optimize_size)
16168 {
16169 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
16170 operands[1]));
16171 DONE;
16172 }
16173 else
16174 operands[2] = gen_reg_rtx (DImode);
16175 })
16176
16177
16178 (define_expand "strmovsi"
16179 [(set (match_dup 2)
16180 (mem:SI (match_operand:SI 1 "register_operand" "")))
16181 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
16182 (match_dup 2))
16183 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16184 (clobber (reg:CC 17))])
16185 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
16186 (clobber (reg:CC 17))])]
16187 ""
16188 {
16189 if (TARGET_64BIT)
16190 {
16191 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
16192 DONE;
16193 }
16194 if (TARGET_SINGLE_STRINGOP || optimize_size)
16195 {
16196 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
16197 operands[1]));
16198 DONE;
16199 }
16200 else
16201 operands[2] = gen_reg_rtx (SImode);
16202 })
16203
16204 (define_expand "strmovsi_rex64"
16205 [(set (match_dup 2)
16206 (mem:SI (match_operand:DI 1 "register_operand" "")))
16207 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
16208 (match_dup 2))
16209 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16210 (clobber (reg:CC 17))])
16211 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
16212 (clobber (reg:CC 17))])]
16213 "TARGET_64BIT"
16214 {
16215 if (TARGET_SINGLE_STRINGOP || optimize_size)
16216 {
16217 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
16218 operands[1]));
16219 DONE;
16220 }
16221 else
16222 operands[2] = gen_reg_rtx (SImode);
16223 })
16224
16225 (define_expand "strmovhi"
16226 [(set (match_dup 2)
16227 (mem:HI (match_operand:SI 1 "register_operand" "")))
16228 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
16229 (match_dup 2))
16230 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16231 (clobber (reg:CC 17))])
16232 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
16233 (clobber (reg:CC 17))])]
16234 ""
16235 {
16236 if (TARGET_64BIT)
16237 {
16238 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
16239 DONE;
16240 }
16241 if (TARGET_SINGLE_STRINGOP || optimize_size)
16242 {
16243 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
16244 operands[1]));
16245 DONE;
16246 }
16247 else
16248 operands[2] = gen_reg_rtx (HImode);
16249 })
16250
16251 (define_expand "strmovhi_rex64"
16252 [(set (match_dup 2)
16253 (mem:HI (match_operand:DI 1 "register_operand" "")))
16254 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
16255 (match_dup 2))
16256 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16257 (clobber (reg:CC 17))])
16258 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
16259 (clobber (reg:CC 17))])]
16260 "TARGET_64BIT"
16261 {
16262 if (TARGET_SINGLE_STRINGOP || optimize_size)
16263 {
16264 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
16265 operands[1]));
16266 DONE;
16267 }
16268 else
16269 operands[2] = gen_reg_rtx (HImode);
16270 })
16271
16272 (define_expand "strmovqi"
16273 [(set (match_dup 2)
16274 (mem:QI (match_operand:SI 1 "register_operand" "")))
16275 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
16276 (match_dup 2))
16277 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16278 (clobber (reg:CC 17))])
16279 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
16280 (clobber (reg:CC 17))])]
16281 ""
16282 {
16283 if (TARGET_64BIT)
16284 {
16285 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
16286 DONE;
16287 }
16288 if (TARGET_SINGLE_STRINGOP || optimize_size)
16289 {
16290 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
16291 operands[1]));
16292 DONE;
16293 }
16294 else
16295 operands[2] = gen_reg_rtx (QImode);
16296 })
16297
16298 (define_expand "strmovqi_rex64"
16299 [(set (match_dup 2)
16300 (mem:QI (match_operand:DI 1 "register_operand" "")))
16301 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
16302 (match_dup 2))
16303 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16304 (clobber (reg:CC 17))])
16305 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
16306 (clobber (reg:CC 17))])]
16307 "TARGET_64BIT"
16308 {
16309 if (TARGET_SINGLE_STRINGOP || optimize_size)
16310 {
16311 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
16312 operands[1]));
16313 DONE;
16314 }
16315 else
16316 operands[2] = gen_reg_rtx (QImode);
16317 })
16318
16319 (define_insn "strmovdi_rex_1"
16320 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16321 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16322 (set (match_operand:DI 0 "register_operand" "=D")
16323 (plus:DI (match_dup 2)
16324 (const_int 8)))
16325 (set (match_operand:DI 1 "register_operand" "=S")
16326 (plus:DI (match_dup 3)
16327 (const_int 8)))
16328 (use (reg:SI 19))]
16329 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16330 "movsq"
16331 [(set_attr "type" "str")
16332 (set_attr "mode" "DI")
16333 (set_attr "memory" "both")])
16334
16335 (define_insn "strmovsi_1"
16336 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16337 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16338 (set (match_operand:SI 0 "register_operand" "=D")
16339 (plus:SI (match_dup 2)
16340 (const_int 4)))
16341 (set (match_operand:SI 1 "register_operand" "=S")
16342 (plus:SI (match_dup 3)
16343 (const_int 4)))
16344 (use (reg:SI 19))]
16345 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16346 "{movsl|movsd}"
16347 [(set_attr "type" "str")
16348 (set_attr "mode" "SI")
16349 (set_attr "memory" "both")])
16350
16351 (define_insn "strmovsi_rex_1"
16352 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16353 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16354 (set (match_operand:DI 0 "register_operand" "=D")
16355 (plus:DI (match_dup 2)
16356 (const_int 4)))
16357 (set (match_operand:DI 1 "register_operand" "=S")
16358 (plus:DI (match_dup 3)
16359 (const_int 4)))
16360 (use (reg:SI 19))]
16361 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16362 "{movsl|movsd}"
16363 [(set_attr "type" "str")
16364 (set_attr "mode" "SI")
16365 (set_attr "memory" "both")])
16366
16367 (define_insn "strmovhi_1"
16368 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16369 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16370 (set (match_operand:SI 0 "register_operand" "=D")
16371 (plus:SI (match_dup 2)
16372 (const_int 2)))
16373 (set (match_operand:SI 1 "register_operand" "=S")
16374 (plus:SI (match_dup 3)
16375 (const_int 2)))
16376 (use (reg:SI 19))]
16377 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16378 "movsw"
16379 [(set_attr "type" "str")
16380 (set_attr "memory" "both")
16381 (set_attr "mode" "HI")])
16382
16383 (define_insn "strmovhi_rex_1"
16384 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16385 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16386 (set (match_operand:DI 0 "register_operand" "=D")
16387 (plus:DI (match_dup 2)
16388 (const_int 2)))
16389 (set (match_operand:DI 1 "register_operand" "=S")
16390 (plus:DI (match_dup 3)
16391 (const_int 2)))
16392 (use (reg:SI 19))]
16393 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16394 "movsw"
16395 [(set_attr "type" "str")
16396 (set_attr "memory" "both")
16397 (set_attr "mode" "HI")])
16398
16399 (define_insn "strmovqi_1"
16400 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16401 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16402 (set (match_operand:SI 0 "register_operand" "=D")
16403 (plus:SI (match_dup 2)
16404 (const_int 1)))
16405 (set (match_operand:SI 1 "register_operand" "=S")
16406 (plus:SI (match_dup 3)
16407 (const_int 1)))
16408 (use (reg:SI 19))]
16409 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16410 "movsb"
16411 [(set_attr "type" "str")
16412 (set_attr "memory" "both")
16413 (set_attr "mode" "QI")])
16414
16415 (define_insn "strmovqi_rex_1"
16416 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16417 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16418 (set (match_operand:DI 0 "register_operand" "=D")
16419 (plus:DI (match_dup 2)
16420 (const_int 1)))
16421 (set (match_operand:DI 1 "register_operand" "=S")
16422 (plus:DI (match_dup 3)
16423 (const_int 1)))
16424 (use (reg:SI 19))]
16425 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16426 "movsb"
16427 [(set_attr "type" "str")
16428 (set_attr "memory" "both")
16429 (set_attr "mode" "QI")])
16430
16431 (define_insn "rep_movdi_rex64"
16432 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16433 (set (match_operand:DI 0 "register_operand" "=D")
16434 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16435 (const_int 3))
16436 (match_operand:DI 3 "register_operand" "0")))
16437 (set (match_operand:DI 1 "register_operand" "=S")
16438 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16439 (match_operand:DI 4 "register_operand" "1")))
16440 (set (mem:BLK (match_dup 3))
16441 (mem:BLK (match_dup 4)))
16442 (use (match_dup 5))
16443 (use (reg:SI 19))]
16444 "TARGET_64BIT"
16445 "{rep\;movsq|rep movsq}"
16446 [(set_attr "type" "str")
16447 (set_attr "prefix_rep" "1")
16448 (set_attr "memory" "both")
16449 (set_attr "mode" "DI")])
16450
16451 (define_insn "rep_movsi"
16452 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16453 (set (match_operand:SI 0 "register_operand" "=D")
16454 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16455 (const_int 2))
16456 (match_operand:SI 3 "register_operand" "0")))
16457 (set (match_operand:SI 1 "register_operand" "=S")
16458 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16459 (match_operand:SI 4 "register_operand" "1")))
16460 (set (mem:BLK (match_dup 3))
16461 (mem:BLK (match_dup 4)))
16462 (use (match_dup 5))
16463 (use (reg:SI 19))]
16464 "!TARGET_64BIT"
16465 "{rep\;movsl|rep movsd}"
16466 [(set_attr "type" "str")
16467 (set_attr "prefix_rep" "1")
16468 (set_attr "memory" "both")
16469 (set_attr "mode" "SI")])
16470
16471 (define_insn "rep_movsi_rex64"
16472 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16473 (set (match_operand:DI 0 "register_operand" "=D")
16474 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16475 (const_int 2))
16476 (match_operand:DI 3 "register_operand" "0")))
16477 (set (match_operand:DI 1 "register_operand" "=S")
16478 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16479 (match_operand:DI 4 "register_operand" "1")))
16480 (set (mem:BLK (match_dup 3))
16481 (mem:BLK (match_dup 4)))
16482 (use (match_dup 5))
16483 (use (reg:SI 19))]
16484 "TARGET_64BIT"
16485 "{rep\;movsl|rep movsd}"
16486 [(set_attr "type" "str")
16487 (set_attr "prefix_rep" "1")
16488 (set_attr "memory" "both")
16489 (set_attr "mode" "SI")])
16490
16491 (define_insn "rep_movqi"
16492 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16493 (set (match_operand:SI 0 "register_operand" "=D")
16494 (plus:SI (match_operand:SI 3 "register_operand" "0")
16495 (match_operand:SI 5 "register_operand" "2")))
16496 (set (match_operand:SI 1 "register_operand" "=S")
16497 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16498 (set (mem:BLK (match_dup 3))
16499 (mem:BLK (match_dup 4)))
16500 (use (match_dup 5))
16501 (use (reg:SI 19))]
16502 "!TARGET_64BIT"
16503 "{rep\;movsb|rep movsb}"
16504 [(set_attr "type" "str")
16505 (set_attr "prefix_rep" "1")
16506 (set_attr "memory" "both")
16507 (set_attr "mode" "SI")])
16508
16509 (define_insn "rep_movqi_rex64"
16510 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16511 (set (match_operand:DI 0 "register_operand" "=D")
16512 (plus:DI (match_operand:DI 3 "register_operand" "0")
16513 (match_operand:DI 5 "register_operand" "2")))
16514 (set (match_operand:DI 1 "register_operand" "=S")
16515 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16516 (set (mem:BLK (match_dup 3))
16517 (mem:BLK (match_dup 4)))
16518 (use (match_dup 5))
16519 (use (reg:SI 19))]
16520 "TARGET_64BIT"
16521 "{rep\;movsb|rep movsb}"
16522 [(set_attr "type" "str")
16523 (set_attr "prefix_rep" "1")
16524 (set_attr "memory" "both")
16525 (set_attr "mode" "SI")])
16526
16527 (define_expand "clrstrsi"
16528 [(use (match_operand:BLK 0 "memory_operand" ""))
16529 (use (match_operand:SI 1 "nonmemory_operand" ""))
16530 (use (match_operand 2 "const_int_operand" ""))]
16531 ""
16532 {
16533 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16534 DONE;
16535 else
16536 FAIL;
16537 })
16538
16539 (define_expand "clrstrdi"
16540 [(use (match_operand:BLK 0 "memory_operand" ""))
16541 (use (match_operand:DI 1 "nonmemory_operand" ""))
16542 (use (match_operand 2 "const_int_operand" ""))]
16543 "TARGET_64BIT"
16544 {
16545 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16546 DONE;
16547 else
16548 FAIL;
16549 })
16550
16551 ;; Most CPUs don't like single string operations
16552 ;; Handle this case here to simplify previous expander.
16553
16554 (define_expand "strsetdi_rex64"
16555 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
16556 (match_operand:DI 1 "register_operand" ""))
16557 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16558 (clobber (reg:CC 17))])]
16559 "TARGET_64BIT"
16560 {
16561 if (TARGET_SINGLE_STRINGOP || optimize_size)
16562 {
16563 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
16564 DONE;
16565 }
16566 })
16567
16568 (define_expand "strsetsi"
16569 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
16570 (match_operand:SI 1 "register_operand" ""))
16571 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16572 (clobber (reg:CC 17))])]
16573 ""
16574 {
16575 if (TARGET_64BIT)
16576 {
16577 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
16578 DONE;
16579 }
16580 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16581 {
16582 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
16583 DONE;
16584 }
16585 })
16586
16587 (define_expand "strsetsi_rex64"
16588 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
16589 (match_operand:SI 1 "register_operand" ""))
16590 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16591 (clobber (reg:CC 17))])]
16592 "TARGET_64BIT"
16593 {
16594 if (TARGET_SINGLE_STRINGOP || optimize_size)
16595 {
16596 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
16597 DONE;
16598 }
16599 })
16600
16601 (define_expand "strsethi"
16602 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
16603 (match_operand:HI 1 "register_operand" ""))
16604 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16605 (clobber (reg:CC 17))])]
16606 ""
16607 {
16608 if (TARGET_64BIT)
16609 {
16610 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
16611 DONE;
16612 }
16613 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16614 {
16615 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
16616 DONE;
16617 }
16618 })
16619
16620 (define_expand "strsethi_rex64"
16621 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
16622 (match_operand:HI 1 "register_operand" ""))
16623 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16624 (clobber (reg:CC 17))])]
16625 "TARGET_64BIT"
16626 {
16627 if (TARGET_SINGLE_STRINGOP || optimize_size)
16628 {
16629 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
16630 DONE;
16631 }
16632 })
16633
16634 (define_expand "strsetqi"
16635 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
16636 (match_operand:QI 1 "register_operand" ""))
16637 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16638 (clobber (reg:CC 17))])]
16639 ""
16640 {
16641 if (TARGET_64BIT)
16642 {
16643 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
16644 DONE;
16645 }
16646 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16647 {
16648 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
16649 DONE;
16650 }
16651 })
16652
16653 (define_expand "strsetqi_rex64"
16654 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
16655 (match_operand:QI 1 "register_operand" ""))
16656 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16657 (clobber (reg:CC 17))])]
16658 "TARGET_64BIT"
16659 {
16660 if (TARGET_SINGLE_STRINGOP || optimize_size)
16661 {
16662 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
16663 DONE;
16664 }
16665 })
16666
16667 (define_insn "strsetdi_rex_1"
16668 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16669 (match_operand:SI 2 "register_operand" "a"))
16670 (set (match_operand:DI 0 "register_operand" "=D")
16671 (plus:DI (match_dup 1)
16672 (const_int 8)))
16673 (use (reg:SI 19))]
16674 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16675 "stosq"
16676 [(set_attr "type" "str")
16677 (set_attr "memory" "store")
16678 (set_attr "mode" "DI")])
16679
16680 (define_insn "strsetsi_1"
16681 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16682 (match_operand:SI 2 "register_operand" "a"))
16683 (set (match_operand:SI 0 "register_operand" "=D")
16684 (plus:SI (match_dup 1)
16685 (const_int 4)))
16686 (use (reg:SI 19))]
16687 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16688 "{stosl|stosd}"
16689 [(set_attr "type" "str")
16690 (set_attr "memory" "store")
16691 (set_attr "mode" "SI")])
16692
16693 (define_insn "strsetsi_rex_1"
16694 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16695 (match_operand:SI 2 "register_operand" "a"))
16696 (set (match_operand:DI 0 "register_operand" "=D")
16697 (plus:DI (match_dup 1)
16698 (const_int 4)))
16699 (use (reg:SI 19))]
16700 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16701 "{stosl|stosd}"
16702 [(set_attr "type" "str")
16703 (set_attr "memory" "store")
16704 (set_attr "mode" "SI")])
16705
16706 (define_insn "strsethi_1"
16707 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16708 (match_operand:HI 2 "register_operand" "a"))
16709 (set (match_operand:SI 0 "register_operand" "=D")
16710 (plus:SI (match_dup 1)
16711 (const_int 2)))
16712 (use (reg:SI 19))]
16713 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16714 "stosw"
16715 [(set_attr "type" "str")
16716 (set_attr "memory" "store")
16717 (set_attr "mode" "HI")])
16718
16719 (define_insn "strsethi_rex_1"
16720 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16721 (match_operand:HI 2 "register_operand" "a"))
16722 (set (match_operand:DI 0 "register_operand" "=D")
16723 (plus:DI (match_dup 1)
16724 (const_int 2)))
16725 (use (reg:SI 19))]
16726 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16727 "stosw"
16728 [(set_attr "type" "str")
16729 (set_attr "memory" "store")
16730 (set_attr "mode" "HI")])
16731
16732 (define_insn "strsetqi_1"
16733 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16734 (match_operand:QI 2 "register_operand" "a"))
16735 (set (match_operand:SI 0 "register_operand" "=D")
16736 (plus:SI (match_dup 1)
16737 (const_int 1)))
16738 (use (reg:SI 19))]
16739 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16740 "stosb"
16741 [(set_attr "type" "str")
16742 (set_attr "memory" "store")
16743 (set_attr "mode" "QI")])
16744
16745 (define_insn "strsetqi_rex_1"
16746 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16747 (match_operand:QI 2 "register_operand" "a"))
16748 (set (match_operand:DI 0 "register_operand" "=D")
16749 (plus:DI (match_dup 1)
16750 (const_int 1)))
16751 (use (reg:SI 19))]
16752 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16753 "stosb"
16754 [(set_attr "type" "str")
16755 (set_attr "memory" "store")
16756 (set_attr "mode" "QI")])
16757
16758 (define_insn "rep_stosdi_rex64"
16759 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16760 (set (match_operand:DI 0 "register_operand" "=D")
16761 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16762 (const_int 3))
16763 (match_operand:DI 3 "register_operand" "0")))
16764 (set (mem:BLK (match_dup 3))
16765 (const_int 0))
16766 (use (match_operand:DI 2 "register_operand" "a"))
16767 (use (match_dup 4))
16768 (use (reg:SI 19))]
16769 "TARGET_64BIT"
16770 "{rep\;stosq|rep stosq}"
16771 [(set_attr "type" "str")
16772 (set_attr "prefix_rep" "1")
16773 (set_attr "memory" "store")
16774 (set_attr "mode" "DI")])
16775
16776 (define_insn "rep_stossi"
16777 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16778 (set (match_operand:SI 0 "register_operand" "=D")
16779 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16780 (const_int 2))
16781 (match_operand:SI 3 "register_operand" "0")))
16782 (set (mem:BLK (match_dup 3))
16783 (const_int 0))
16784 (use (match_operand:SI 2 "register_operand" "a"))
16785 (use (match_dup 4))
16786 (use (reg:SI 19))]
16787 "!TARGET_64BIT"
16788 "{rep\;stosl|rep stosd}"
16789 [(set_attr "type" "str")
16790 (set_attr "prefix_rep" "1")
16791 (set_attr "memory" "store")
16792 (set_attr "mode" "SI")])
16793
16794 (define_insn "rep_stossi_rex64"
16795 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16796 (set (match_operand:DI 0 "register_operand" "=D")
16797 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16798 (const_int 2))
16799 (match_operand:DI 3 "register_operand" "0")))
16800 (set (mem:BLK (match_dup 3))
16801 (const_int 0))
16802 (use (match_operand:SI 2 "register_operand" "a"))
16803 (use (match_dup 4))
16804 (use (reg:SI 19))]
16805 "TARGET_64BIT"
16806 "{rep\;stosl|rep stosd}"
16807 [(set_attr "type" "str")
16808 (set_attr "prefix_rep" "1")
16809 (set_attr "memory" "store")
16810 (set_attr "mode" "SI")])
16811
16812 (define_insn "rep_stosqi"
16813 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16814 (set (match_operand:SI 0 "register_operand" "=D")
16815 (plus:SI (match_operand:SI 3 "register_operand" "0")
16816 (match_operand:SI 4 "register_operand" "1")))
16817 (set (mem:BLK (match_dup 3))
16818 (const_int 0))
16819 (use (match_operand:QI 2 "register_operand" "a"))
16820 (use (match_dup 4))
16821 (use (reg:SI 19))]
16822 "!TARGET_64BIT"
16823 "{rep\;stosb|rep stosb}"
16824 [(set_attr "type" "str")
16825 (set_attr "prefix_rep" "1")
16826 (set_attr "memory" "store")
16827 (set_attr "mode" "QI")])
16828
16829 (define_insn "rep_stosqi_rex64"
16830 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16831 (set (match_operand:DI 0 "register_operand" "=D")
16832 (plus:DI (match_operand:DI 3 "register_operand" "0")
16833 (match_operand:DI 4 "register_operand" "1")))
16834 (set (mem:BLK (match_dup 3))
16835 (const_int 0))
16836 (use (match_operand:QI 2 "register_operand" "a"))
16837 (use (match_dup 4))
16838 (use (reg:DI 19))]
16839 "TARGET_64BIT"
16840 "{rep\;stosb|rep stosb}"
16841 [(set_attr "type" "str")
16842 (set_attr "prefix_rep" "1")
16843 (set_attr "memory" "store")
16844 (set_attr "mode" "QI")])
16845
16846 (define_expand "cmpstrsi"
16847 [(set (match_operand:SI 0 "register_operand" "")
16848 (compare:SI (match_operand:BLK 1 "general_operand" "")
16849 (match_operand:BLK 2 "general_operand" "")))
16850 (use (match_operand 3 "general_operand" ""))
16851 (use (match_operand 4 "immediate_operand" ""))]
16852 "! optimize_size"
16853 {
16854 rtx addr1, addr2, out, outlow, count, countreg, align;
16855
16856 /* Can't use this if the user has appropriated esi or edi. */
16857 if (global_regs[4] || global_regs[5])
16858 FAIL;
16859
16860 out = operands[0];
16861 if (GET_CODE (out) != REG)
16862 out = gen_reg_rtx (SImode);
16863
16864 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16865 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16866
16867 count = operands[3];
16868 countreg = ix86_zero_extend_to_Pmode (count);
16869
16870 /* %%% Iff we are testing strict equality, we can use known alignment
16871 to good advantage. This may be possible with combine, particularly
16872 once cc0 is dead. */
16873 align = operands[4];
16874
16875 emit_insn (gen_cld ());
16876 if (GET_CODE (count) == CONST_INT)
16877 {
16878 if (INTVAL (count) == 0)
16879 {
16880 emit_move_insn (operands[0], const0_rtx);
16881 DONE;
16882 }
16883 if (TARGET_64BIT)
16884 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16885 addr1, addr2, countreg));
16886 else
16887 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16888 addr1, addr2, countreg));
16889 }
16890 else
16891 {
16892 if (TARGET_64BIT)
16893 {
16894 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16895 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16896 addr1, addr2, countreg));
16897 }
16898 else
16899 {
16900 emit_insn (gen_cmpsi_1 (countreg, countreg));
16901 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16902 addr1, addr2, countreg));
16903 }
16904 }
16905
16906 outlow = gen_lowpart (QImode, out);
16907 emit_insn (gen_cmpintqi (outlow));
16908 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16909
16910 if (operands[0] != out)
16911 emit_move_insn (operands[0], out);
16912
16913 DONE;
16914 })
16915
16916 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16917
16918 (define_expand "cmpintqi"
16919 [(set (match_dup 1)
16920 (gtu:QI (reg:CC 17) (const_int 0)))
16921 (set (match_dup 2)
16922 (ltu:QI (reg:CC 17) (const_int 0)))
16923 (parallel [(set (match_operand:QI 0 "register_operand" "")
16924 (minus:QI (match_dup 1)
16925 (match_dup 2)))
16926 (clobber (reg:CC 17))])]
16927 ""
16928 "operands[1] = gen_reg_rtx (QImode);
16929 operands[2] = gen_reg_rtx (QImode);")
16930
16931 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16932 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16933
16934 (define_insn "cmpstrqi_nz_1"
16935 [(set (reg:CC 17)
16936 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16937 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16938 (use (match_operand:SI 6 "register_operand" "2"))
16939 (use (match_operand:SI 3 "immediate_operand" "i"))
16940 (use (reg:SI 19))
16941 (clobber (match_operand:SI 0 "register_operand" "=S"))
16942 (clobber (match_operand:SI 1 "register_operand" "=D"))
16943 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16944 "!TARGET_64BIT"
16945 "repz{\;| }cmpsb"
16946 [(set_attr "type" "str")
16947 (set_attr "mode" "QI")
16948 (set_attr "prefix_rep" "1")])
16949
16950 (define_insn "cmpstrqi_nz_rex_1"
16951 [(set (reg:CC 17)
16952 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16953 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16954 (use (match_operand:DI 6 "register_operand" "2"))
16955 (use (match_operand:SI 3 "immediate_operand" "i"))
16956 (use (reg:SI 19))
16957 (clobber (match_operand:DI 0 "register_operand" "=S"))
16958 (clobber (match_operand:DI 1 "register_operand" "=D"))
16959 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16960 "TARGET_64BIT"
16961 "repz{\;| }cmpsb"
16962 [(set_attr "type" "str")
16963 (set_attr "mode" "QI")
16964 (set_attr "prefix_rep" "1")])
16965
16966 ;; The same, but the count is not known to not be zero.
16967
16968 (define_insn "cmpstrqi_1"
16969 [(set (reg:CC 17)
16970 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16971 (const_int 0))
16972 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16973 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16974 (const_int 0)))
16975 (use (match_operand:SI 3 "immediate_operand" "i"))
16976 (use (reg:CC 17))
16977 (use (reg:SI 19))
16978 (clobber (match_operand:SI 0 "register_operand" "=S"))
16979 (clobber (match_operand:SI 1 "register_operand" "=D"))
16980 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16981 "!TARGET_64BIT"
16982 "repz{\;| }cmpsb"
16983 [(set_attr "type" "str")
16984 (set_attr "mode" "QI")
16985 (set_attr "prefix_rep" "1")])
16986
16987 (define_insn "cmpstrqi_rex_1"
16988 [(set (reg:CC 17)
16989 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16990 (const_int 0))
16991 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16992 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16993 (const_int 0)))
16994 (use (match_operand:SI 3 "immediate_operand" "i"))
16995 (use (reg:CC 17))
16996 (use (reg:SI 19))
16997 (clobber (match_operand:DI 0 "register_operand" "=S"))
16998 (clobber (match_operand:DI 1 "register_operand" "=D"))
16999 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17000 "TARGET_64BIT"
17001 "repz{\;| }cmpsb"
17002 [(set_attr "type" "str")
17003 (set_attr "mode" "QI")
17004 (set_attr "prefix_rep" "1")])
17005
17006 (define_expand "strlensi"
17007 [(set (match_operand:SI 0 "register_operand" "")
17008 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17009 (match_operand:QI 2 "immediate_operand" "")
17010 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17011 ""
17012 {
17013 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17014 DONE;
17015 else
17016 FAIL;
17017 })
17018
17019 (define_expand "strlendi"
17020 [(set (match_operand:DI 0 "register_operand" "")
17021 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17022 (match_operand:QI 2 "immediate_operand" "")
17023 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17024 ""
17025 {
17026 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17027 DONE;
17028 else
17029 FAIL;
17030 })
17031
17032 (define_insn "strlenqi_1"
17033 [(set (match_operand:SI 0 "register_operand" "=&c")
17034 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17035 (match_operand:QI 2 "register_operand" "a")
17036 (match_operand:SI 3 "immediate_operand" "i")
17037 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17038 (use (reg:SI 19))
17039 (clobber (match_operand:SI 1 "register_operand" "=D"))
17040 (clobber (reg:CC 17))]
17041 "!TARGET_64BIT"
17042 "repnz{\;| }scasb"
17043 [(set_attr "type" "str")
17044 (set_attr "mode" "QI")
17045 (set_attr "prefix_rep" "1")])
17046
17047 (define_insn "strlenqi_rex_1"
17048 [(set (match_operand:DI 0 "register_operand" "=&c")
17049 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17050 (match_operand:QI 2 "register_operand" "a")
17051 (match_operand:DI 3 "immediate_operand" "i")
17052 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17053 (use (reg:SI 19))
17054 (clobber (match_operand:DI 1 "register_operand" "=D"))
17055 (clobber (reg:CC 17))]
17056 "TARGET_64BIT"
17057 "repnz{\;| }scasb"
17058 [(set_attr "type" "str")
17059 (set_attr "mode" "QI")
17060 (set_attr "prefix_rep" "1")])
17061
17062 ;; Peephole optimizations to clean up after cmpstr*. This should be
17063 ;; handled in combine, but it is not currently up to the task.
17064 ;; When used for their truth value, the cmpstr* expanders generate
17065 ;; code like this:
17066 ;;
17067 ;; repz cmpsb
17068 ;; seta %al
17069 ;; setb %dl
17070 ;; cmpb %al, %dl
17071 ;; jcc label
17072 ;;
17073 ;; The intermediate three instructions are unnecessary.
17074
17075 ;; This one handles cmpstr*_nz_1...
17076 (define_peephole2
17077 [(parallel[
17078 (set (reg:CC 17)
17079 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17080 (mem:BLK (match_operand 5 "register_operand" ""))))
17081 (use (match_operand 6 "register_operand" ""))
17082 (use (match_operand:SI 3 "immediate_operand" ""))
17083 (use (reg:SI 19))
17084 (clobber (match_operand 0 "register_operand" ""))
17085 (clobber (match_operand 1 "register_operand" ""))
17086 (clobber (match_operand 2 "register_operand" ""))])
17087 (set (match_operand:QI 7 "register_operand" "")
17088 (gtu:QI (reg:CC 17) (const_int 0)))
17089 (set (match_operand:QI 8 "register_operand" "")
17090 (ltu:QI (reg:CC 17) (const_int 0)))
17091 (set (reg 17)
17092 (compare (match_dup 7) (match_dup 8)))
17093 ]
17094 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17095 [(parallel[
17096 (set (reg:CC 17)
17097 (compare:CC (mem:BLK (match_dup 4))
17098 (mem:BLK (match_dup 5))))
17099 (use (match_dup 6))
17100 (use (match_dup 3))
17101 (use (reg:SI 19))
17102 (clobber (match_dup 0))
17103 (clobber (match_dup 1))
17104 (clobber (match_dup 2))])]
17105 "")
17106
17107 ;; ...and this one handles cmpstr*_1.
17108 (define_peephole2
17109 [(parallel[
17110 (set (reg:CC 17)
17111 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17112 (const_int 0))
17113 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17114 (mem:BLK (match_operand 5 "register_operand" "")))
17115 (const_int 0)))
17116 (use (match_operand:SI 3 "immediate_operand" ""))
17117 (use (reg:CC 17))
17118 (use (reg:SI 19))
17119 (clobber (match_operand 0 "register_operand" ""))
17120 (clobber (match_operand 1 "register_operand" ""))
17121 (clobber (match_operand 2 "register_operand" ""))])
17122 (set (match_operand:QI 7 "register_operand" "")
17123 (gtu:QI (reg:CC 17) (const_int 0)))
17124 (set (match_operand:QI 8 "register_operand" "")
17125 (ltu:QI (reg:CC 17) (const_int 0)))
17126 (set (reg 17)
17127 (compare (match_dup 7) (match_dup 8)))
17128 ]
17129 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17130 [(parallel[
17131 (set (reg:CC 17)
17132 (if_then_else:CC (ne (match_dup 6)
17133 (const_int 0))
17134 (compare:CC (mem:BLK (match_dup 4))
17135 (mem:BLK (match_dup 5)))
17136 (const_int 0)))
17137 (use (match_dup 3))
17138 (use (reg:CC 17))
17139 (use (reg:SI 19))
17140 (clobber (match_dup 0))
17141 (clobber (match_dup 1))
17142 (clobber (match_dup 2))])]
17143 "")
17144
17145
17146 \f
17147 ;; Conditional move instructions.
17148
17149 (define_expand "movdicc"
17150 [(set (match_operand:DI 0 "register_operand" "")
17151 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17152 (match_operand:DI 2 "general_operand" "")
17153 (match_operand:DI 3 "general_operand" "")))]
17154 "TARGET_64BIT"
17155 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17156
17157 (define_insn "x86_movdicc_0_m1_rex64"
17158 [(set (match_operand:DI 0 "register_operand" "=r")
17159 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17160 (const_int -1)
17161 (const_int 0)))
17162 (clobber (reg:CC 17))]
17163 "TARGET_64BIT"
17164 "sbb{q}\t%0, %0"
17165 ; Since we don't have the proper number of operands for an alu insn,
17166 ; fill in all the blanks.
17167 [(set_attr "type" "alu")
17168 (set_attr "pent_pair" "pu")
17169 (set_attr "memory" "none")
17170 (set_attr "imm_disp" "false")
17171 (set_attr "mode" "DI")
17172 (set_attr "length_immediate" "0")])
17173
17174 (define_insn "movdicc_c_rex64"
17175 [(set (match_operand:DI 0 "register_operand" "=r,r")
17176 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17177 [(reg 17) (const_int 0)])
17178 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17179 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17180 "TARGET_64BIT && TARGET_CMOVE
17181 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17182 "@
17183 cmov%O2%C1\t{%2, %0|%0, %2}
17184 cmov%O2%c1\t{%3, %0|%0, %3}"
17185 [(set_attr "type" "icmov")
17186 (set_attr "mode" "DI")])
17187
17188 (define_expand "movsicc"
17189 [(set (match_operand:SI 0 "register_operand" "")
17190 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17191 (match_operand:SI 2 "general_operand" "")
17192 (match_operand:SI 3 "general_operand" "")))]
17193 ""
17194 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17195
17196 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17197 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17198 ;; So just document what we're doing explicitly.
17199
17200 (define_insn "x86_movsicc_0_m1"
17201 [(set (match_operand:SI 0 "register_operand" "=r")
17202 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17203 (const_int -1)
17204 (const_int 0)))
17205 (clobber (reg:CC 17))]
17206 ""
17207 "sbb{l}\t%0, %0"
17208 ; Since we don't have the proper number of operands for an alu insn,
17209 ; fill in all the blanks.
17210 [(set_attr "type" "alu")
17211 (set_attr "pent_pair" "pu")
17212 (set_attr "memory" "none")
17213 (set_attr "imm_disp" "false")
17214 (set_attr "mode" "SI")
17215 (set_attr "length_immediate" "0")])
17216
17217 (define_insn "*movsicc_noc"
17218 [(set (match_operand:SI 0 "register_operand" "=r,r")
17219 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17220 [(reg 17) (const_int 0)])
17221 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17222 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17223 "TARGET_CMOVE
17224 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17225 "@
17226 cmov%O2%C1\t{%2, %0|%0, %2}
17227 cmov%O2%c1\t{%3, %0|%0, %3}"
17228 [(set_attr "type" "icmov")
17229 (set_attr "mode" "SI")])
17230
17231 (define_expand "movhicc"
17232 [(set (match_operand:HI 0 "register_operand" "")
17233 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17234 (match_operand:HI 2 "general_operand" "")
17235 (match_operand:HI 3 "general_operand" "")))]
17236 "TARGET_HIMODE_MATH"
17237 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17238
17239 (define_insn "*movhicc_noc"
17240 [(set (match_operand:HI 0 "register_operand" "=r,r")
17241 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17242 [(reg 17) (const_int 0)])
17243 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17244 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17245 "TARGET_CMOVE
17246 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17247 "@
17248 cmov%O2%C1\t{%2, %0|%0, %2}
17249 cmov%O2%c1\t{%3, %0|%0, %3}"
17250 [(set_attr "type" "icmov")
17251 (set_attr "mode" "HI")])
17252
17253 (define_expand "movqicc"
17254 [(set (match_operand:QI 0 "register_operand" "")
17255 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17256 (match_operand:QI 2 "general_operand" "")
17257 (match_operand:QI 3 "general_operand" "")))]
17258 "TARGET_QIMODE_MATH"
17259 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17260
17261 (define_insn_and_split "*movqicc_noc"
17262 [(set (match_operand:QI 0 "register_operand" "=r,r")
17263 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17264 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17265 (match_operand:QI 2 "register_operand" "r,0")
17266 (match_operand:QI 3 "register_operand" "0,r")))]
17267 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17268 "#"
17269 "&& reload_completed"
17270 [(set (match_dup 0)
17271 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17272 (match_dup 2)
17273 (match_dup 3)))]
17274 "operands[0] = gen_lowpart (SImode, operands[0]);
17275 operands[2] = gen_lowpart (SImode, operands[2]);
17276 operands[3] = gen_lowpart (SImode, operands[3]);"
17277 [(set_attr "type" "icmov")
17278 (set_attr "mode" "SI")])
17279
17280 (define_expand "movsfcc"
17281 [(set (match_operand:SF 0 "register_operand" "")
17282 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17283 (match_operand:SF 2 "register_operand" "")
17284 (match_operand:SF 3 "register_operand" "")))]
17285 "TARGET_CMOVE"
17286 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17287
17288 (define_insn "*movsfcc_1"
17289 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17290 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17291 [(reg 17) (const_int 0)])
17292 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17293 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17294 "TARGET_CMOVE
17295 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17296 "@
17297 fcmov%F1\t{%2, %0|%0, %2}
17298 fcmov%f1\t{%3, %0|%0, %3}
17299 cmov%O2%C1\t{%2, %0|%0, %2}
17300 cmov%O2%c1\t{%3, %0|%0, %3}"
17301 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17302 (set_attr "mode" "SF,SF,SI,SI")])
17303
17304 (define_expand "movdfcc"
17305 [(set (match_operand:DF 0 "register_operand" "")
17306 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17307 (match_operand:DF 2 "register_operand" "")
17308 (match_operand:DF 3 "register_operand" "")))]
17309 "TARGET_CMOVE"
17310 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17311
17312 (define_insn "*movdfcc_1"
17313 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17314 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17315 [(reg 17) (const_int 0)])
17316 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17317 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17318 "!TARGET_64BIT && TARGET_CMOVE
17319 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17320 "@
17321 fcmov%F1\t{%2, %0|%0, %2}
17322 fcmov%f1\t{%3, %0|%0, %3}
17323 #
17324 #"
17325 [(set_attr "type" "fcmov,fcmov,multi,multi")
17326 (set_attr "mode" "DF")])
17327
17328 (define_insn "*movdfcc_1_rex64"
17329 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17330 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17331 [(reg 17) (const_int 0)])
17332 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17333 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17334 "TARGET_64BIT && TARGET_CMOVE
17335 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17336 "@
17337 fcmov%F1\t{%2, %0|%0, %2}
17338 fcmov%f1\t{%3, %0|%0, %3}
17339 cmov%O2%C1\t{%2, %0|%0, %2}
17340 cmov%O2%c1\t{%3, %0|%0, %3}"
17341 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17342 (set_attr "mode" "DF")])
17343
17344 (define_split
17345 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17346 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17347 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17348 (match_operand:DF 2 "nonimmediate_operand" "")
17349 (match_operand:DF 3 "nonimmediate_operand" "")))]
17350 "!TARGET_64BIT && reload_completed"
17351 [(set (match_dup 2)
17352 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17353 (match_dup 5)
17354 (match_dup 7)))
17355 (set (match_dup 3)
17356 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17357 (match_dup 6)
17358 (match_dup 8)))]
17359 "split_di (operands+2, 1, operands+5, operands+6);
17360 split_di (operands+3, 1, operands+7, operands+8);
17361 split_di (operands, 1, operands+2, operands+3);")
17362
17363 (define_expand "movxfcc"
17364 [(set (match_operand:XF 0 "register_operand" "")
17365 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17366 (match_operand:XF 2 "register_operand" "")
17367 (match_operand:XF 3 "register_operand" "")))]
17368 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17369 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17370
17371 (define_expand "movtfcc"
17372 [(set (match_operand:TF 0 "register_operand" "")
17373 (if_then_else:TF (match_operand 1 "comparison_operator" "")
17374 (match_operand:TF 2 "register_operand" "")
17375 (match_operand:TF 3 "register_operand" "")))]
17376 "TARGET_CMOVE"
17377 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17378
17379 (define_insn "*movxfcc_1"
17380 [(set (match_operand:XF 0 "register_operand" "=f,f")
17381 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17382 [(reg 17) (const_int 0)])
17383 (match_operand:XF 2 "register_operand" "f,0")
17384 (match_operand:XF 3 "register_operand" "0,f")))]
17385 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17386 "@
17387 fcmov%F1\t{%2, %0|%0, %2}
17388 fcmov%f1\t{%3, %0|%0, %3}"
17389 [(set_attr "type" "fcmov")
17390 (set_attr "mode" "XF")])
17391
17392 (define_insn "*movtfcc_1"
17393 [(set (match_operand:TF 0 "register_operand" "=f,f")
17394 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
17395 [(reg 17) (const_int 0)])
17396 (match_operand:TF 2 "register_operand" "f,0")
17397 (match_operand:TF 3 "register_operand" "0,f")))]
17398 "TARGET_CMOVE"
17399 "@
17400 fcmov%F1\t{%2, %0|%0, %2}
17401 fcmov%f1\t{%3, %0|%0, %3}"
17402 [(set_attr "type" "fcmov")
17403 (set_attr "mode" "XF")])
17404
17405 (define_expand "minsf3"
17406 [(parallel [
17407 (set (match_operand:SF 0 "register_operand" "")
17408 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17409 (match_operand:SF 2 "nonimmediate_operand" ""))
17410 (match_dup 1)
17411 (match_dup 2)))
17412 (clobber (reg:CC 17))])]
17413 "TARGET_SSE"
17414 "")
17415
17416 (define_insn "*minsf"
17417 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17418 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17419 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17420 (match_dup 1)
17421 (match_dup 2)))
17422 (clobber (reg:CC 17))]
17423 "TARGET_SSE && TARGET_IEEE_FP"
17424 "#")
17425
17426 (define_insn "*minsf_nonieee"
17427 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17428 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17429 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17430 (match_dup 1)
17431 (match_dup 2)))
17432 (clobber (reg:CC 17))]
17433 "TARGET_SSE && !TARGET_IEEE_FP
17434 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17435 "#")
17436
17437 (define_split
17438 [(set (match_operand:SF 0 "register_operand" "")
17439 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17440 (match_operand:SF 2 "nonimmediate_operand" ""))
17441 (match_operand:SF 3 "register_operand" "")
17442 (match_operand:SF 4 "nonimmediate_operand" "")))
17443 (clobber (reg:CC 17))]
17444 "SSE_REG_P (operands[0]) && reload_completed
17445 && ((operands_match_p (operands[1], operands[3])
17446 && operands_match_p (operands[2], operands[4]))
17447 || (operands_match_p (operands[1], operands[4])
17448 && operands_match_p (operands[2], operands[3])))"
17449 [(set (match_dup 0)
17450 (if_then_else:SF (lt (match_dup 1)
17451 (match_dup 2))
17452 (match_dup 1)
17453 (match_dup 2)))])
17454
17455 ;; Conditional addition patterns
17456 (define_expand "addqicc"
17457 [(match_operand:QI 0 "register_operand" "")
17458 (match_operand 1 "comparison_operator" "")
17459 (match_operand:QI 2 "register_operand" "")
17460 (match_operand:QI 3 "const_int_operand" "")]
17461 ""
17462 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17463
17464 (define_expand "addhicc"
17465 [(match_operand:HI 0 "register_operand" "")
17466 (match_operand 1 "comparison_operator" "")
17467 (match_operand:HI 2 "register_operand" "")
17468 (match_operand:HI 3 "const_int_operand" "")]
17469 ""
17470 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17471
17472 (define_expand "addsicc"
17473 [(match_operand:SI 0 "register_operand" "")
17474 (match_operand 1 "comparison_operator" "")
17475 (match_operand:SI 2 "register_operand" "")
17476 (match_operand:SI 3 "const_int_operand" "")]
17477 ""
17478 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17479
17480 (define_expand "adddicc"
17481 [(match_operand:DI 0 "register_operand" "")
17482 (match_operand 1 "comparison_operator" "")
17483 (match_operand:DI 2 "register_operand" "")
17484 (match_operand:DI 3 "const_int_operand" "")]
17485 "TARGET_64BIT"
17486 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17487
17488 ;; We can't represent the LT test directly. Do this by swapping the operands.
17489
17490 (define_split
17491 [(set (match_operand:SF 0 "fp_register_operand" "")
17492 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17493 (match_operand:SF 2 "register_operand" ""))
17494 (match_operand:SF 3 "register_operand" "")
17495 (match_operand:SF 4 "register_operand" "")))
17496 (clobber (reg:CC 17))]
17497 "reload_completed
17498 && ((operands_match_p (operands[1], operands[3])
17499 && operands_match_p (operands[2], operands[4]))
17500 || (operands_match_p (operands[1], operands[4])
17501 && operands_match_p (operands[2], operands[3])))"
17502 [(set (reg:CCFP 17)
17503 (compare:CCFP (match_dup 2)
17504 (match_dup 1)))
17505 (set (match_dup 0)
17506 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17507 (match_dup 1)
17508 (match_dup 2)))])
17509
17510 (define_insn "*minsf_sse"
17511 [(set (match_operand:SF 0 "register_operand" "=x")
17512 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17513 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17514 (match_dup 1)
17515 (match_dup 2)))]
17516 "TARGET_SSE && reload_completed"
17517 "minss\t{%2, %0|%0, %2}"
17518 [(set_attr "type" "sse")
17519 (set_attr "mode" "SF")])
17520
17521 (define_expand "mindf3"
17522 [(parallel [
17523 (set (match_operand:DF 0 "register_operand" "")
17524 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17525 (match_operand:DF 2 "nonimmediate_operand" ""))
17526 (match_dup 1)
17527 (match_dup 2)))
17528 (clobber (reg:CC 17))])]
17529 "TARGET_SSE2 && TARGET_SSE_MATH"
17530 "#")
17531
17532 (define_insn "*mindf"
17533 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17534 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17535 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17536 (match_dup 1)
17537 (match_dup 2)))
17538 (clobber (reg:CC 17))]
17539 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17540 "#")
17541
17542 (define_insn "*mindf_nonieee"
17543 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17544 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17545 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17546 (match_dup 1)
17547 (match_dup 2)))
17548 (clobber (reg:CC 17))]
17549 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17550 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17551 "#")
17552
17553 (define_split
17554 [(set (match_operand:DF 0 "register_operand" "")
17555 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17556 (match_operand:DF 2 "nonimmediate_operand" ""))
17557 (match_operand:DF 3 "register_operand" "")
17558 (match_operand:DF 4 "nonimmediate_operand" "")))
17559 (clobber (reg:CC 17))]
17560 "SSE_REG_P (operands[0]) && reload_completed
17561 && ((operands_match_p (operands[1], operands[3])
17562 && operands_match_p (operands[2], operands[4]))
17563 || (operands_match_p (operands[1], operands[4])
17564 && operands_match_p (operands[2], operands[3])))"
17565 [(set (match_dup 0)
17566 (if_then_else:DF (lt (match_dup 1)
17567 (match_dup 2))
17568 (match_dup 1)
17569 (match_dup 2)))])
17570
17571 ;; We can't represent the LT test directly. Do this by swapping the operands.
17572 (define_split
17573 [(set (match_operand:DF 0 "fp_register_operand" "")
17574 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17575 (match_operand:DF 2 "register_operand" ""))
17576 (match_operand:DF 3 "register_operand" "")
17577 (match_operand:DF 4 "register_operand" "")))
17578 (clobber (reg:CC 17))]
17579 "reload_completed
17580 && ((operands_match_p (operands[1], operands[3])
17581 && operands_match_p (operands[2], operands[4]))
17582 || (operands_match_p (operands[1], operands[4])
17583 && operands_match_p (operands[2], operands[3])))"
17584 [(set (reg:CCFP 17)
17585 (compare:CCFP (match_dup 2)
17586 (match_dup 2)))
17587 (set (match_dup 0)
17588 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17589 (match_dup 1)
17590 (match_dup 2)))])
17591
17592 (define_insn "*mindf_sse"
17593 [(set (match_operand:DF 0 "register_operand" "=Y")
17594 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17595 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17596 (match_dup 1)
17597 (match_dup 2)))]
17598 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17599 "minsd\t{%2, %0|%0, %2}"
17600 [(set_attr "type" "sse")
17601 (set_attr "mode" "DF")])
17602
17603 (define_expand "maxsf3"
17604 [(parallel [
17605 (set (match_operand:SF 0 "register_operand" "")
17606 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17607 (match_operand:SF 2 "nonimmediate_operand" ""))
17608 (match_dup 1)
17609 (match_dup 2)))
17610 (clobber (reg:CC 17))])]
17611 "TARGET_SSE"
17612 "#")
17613
17614 (define_insn "*maxsf"
17615 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17616 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17617 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17618 (match_dup 1)
17619 (match_dup 2)))
17620 (clobber (reg:CC 17))]
17621 "TARGET_SSE && TARGET_IEEE_FP"
17622 "#")
17623
17624 (define_insn "*maxsf_nonieee"
17625 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17626 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17627 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17628 (match_dup 1)
17629 (match_dup 2)))
17630 (clobber (reg:CC 17))]
17631 "TARGET_SSE && !TARGET_IEEE_FP
17632 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17633 "#")
17634
17635 (define_split
17636 [(set (match_operand:SF 0 "register_operand" "")
17637 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17638 (match_operand:SF 2 "nonimmediate_operand" ""))
17639 (match_operand:SF 3 "register_operand" "")
17640 (match_operand:SF 4 "nonimmediate_operand" "")))
17641 (clobber (reg:CC 17))]
17642 "SSE_REG_P (operands[0]) && reload_completed
17643 && ((operands_match_p (operands[1], operands[3])
17644 && operands_match_p (operands[2], operands[4]))
17645 || (operands_match_p (operands[1], operands[4])
17646 && operands_match_p (operands[2], operands[3])))"
17647 [(set (match_dup 0)
17648 (if_then_else:SF (gt (match_dup 1)
17649 (match_dup 2))
17650 (match_dup 1)
17651 (match_dup 2)))])
17652
17653 (define_split
17654 [(set (match_operand:SF 0 "fp_register_operand" "")
17655 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17656 (match_operand:SF 2 "register_operand" ""))
17657 (match_operand:SF 3 "register_operand" "")
17658 (match_operand:SF 4 "register_operand" "")))
17659 (clobber (reg:CC 17))]
17660 "reload_completed
17661 && ((operands_match_p (operands[1], operands[3])
17662 && operands_match_p (operands[2], operands[4]))
17663 || (operands_match_p (operands[1], operands[4])
17664 && operands_match_p (operands[2], operands[3])))"
17665 [(set (reg:CCFP 17)
17666 (compare:CCFP (match_dup 1)
17667 (match_dup 2)))
17668 (set (match_dup 0)
17669 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17670 (match_dup 1)
17671 (match_dup 2)))])
17672
17673 (define_insn "*maxsf_sse"
17674 [(set (match_operand:SF 0 "register_operand" "=x")
17675 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17676 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17677 (match_dup 1)
17678 (match_dup 2)))]
17679 "TARGET_SSE && reload_completed"
17680 "maxss\t{%2, %0|%0, %2}"
17681 [(set_attr "type" "sse")
17682 (set_attr "mode" "SF")])
17683
17684 (define_expand "maxdf3"
17685 [(parallel [
17686 (set (match_operand:DF 0 "register_operand" "")
17687 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17688 (match_operand:DF 2 "nonimmediate_operand" ""))
17689 (match_dup 1)
17690 (match_dup 2)))
17691 (clobber (reg:CC 17))])]
17692 "TARGET_SSE2 && TARGET_SSE_MATH"
17693 "#")
17694
17695 (define_insn "*maxdf"
17696 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17697 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17698 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17699 (match_dup 1)
17700 (match_dup 2)))
17701 (clobber (reg:CC 17))]
17702 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17703 "#")
17704
17705 (define_insn "*maxdf_nonieee"
17706 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17707 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17708 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17709 (match_dup 1)
17710 (match_dup 2)))
17711 (clobber (reg:CC 17))]
17712 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17713 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17714 "#")
17715
17716 (define_split
17717 [(set (match_operand:DF 0 "register_operand" "")
17718 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17719 (match_operand:DF 2 "nonimmediate_operand" ""))
17720 (match_operand:DF 3 "register_operand" "")
17721 (match_operand:DF 4 "nonimmediate_operand" "")))
17722 (clobber (reg:CC 17))]
17723 "SSE_REG_P (operands[0]) && reload_completed
17724 && ((operands_match_p (operands[1], operands[3])
17725 && operands_match_p (operands[2], operands[4]))
17726 || (operands_match_p (operands[1], operands[4])
17727 && operands_match_p (operands[2], operands[3])))"
17728 [(set (match_dup 0)
17729 (if_then_else:DF (gt (match_dup 1)
17730 (match_dup 2))
17731 (match_dup 1)
17732 (match_dup 2)))])
17733
17734 (define_split
17735 [(set (match_operand:DF 0 "fp_register_operand" "")
17736 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17737 (match_operand:DF 2 "register_operand" ""))
17738 (match_operand:DF 3 "register_operand" "")
17739 (match_operand:DF 4 "register_operand" "")))
17740 (clobber (reg:CC 17))]
17741 "reload_completed
17742 && ((operands_match_p (operands[1], operands[3])
17743 && operands_match_p (operands[2], operands[4]))
17744 || (operands_match_p (operands[1], operands[4])
17745 && operands_match_p (operands[2], operands[3])))"
17746 [(set (reg:CCFP 17)
17747 (compare:CCFP (match_dup 1)
17748 (match_dup 2)))
17749 (set (match_dup 0)
17750 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17751 (match_dup 1)
17752 (match_dup 2)))])
17753
17754 (define_insn "*maxdf_sse"
17755 [(set (match_operand:DF 0 "register_operand" "=Y")
17756 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17757 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17758 (match_dup 1)
17759 (match_dup 2)))]
17760 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17761 "maxsd\t{%2, %0|%0, %2}"
17762 [(set_attr "type" "sse")
17763 (set_attr "mode" "DF")])
17764 \f
17765 ;; Misc patterns (?)
17766
17767 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17768 ;; Otherwise there will be nothing to keep
17769 ;;
17770 ;; [(set (reg ebp) (reg esp))]
17771 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17772 ;; (clobber (eflags)]
17773 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17774 ;;
17775 ;; in proper program order.
17776 (define_expand "pro_epilogue_adjust_stack"
17777 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
17778 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17779 (match_operand:SI 2 "immediate_operand" "i,i")))
17780 (clobber (reg:CC 17))
17781 (clobber (mem:BLK (scratch)))])]
17782 ""
17783 {
17784 if (TARGET_64BIT)
17785 {
17786 emit_insn (gen_pro_epilogue_adjust_stack_rex64
17787 (operands[0], operands[1], operands[2]));
17788 DONE;
17789 }
17790 })
17791
17792 (define_insn "*pro_epilogue_adjust_stack_1"
17793 [(set (match_operand:SI 0 "register_operand" "=r,r")
17794 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17795 (match_operand:SI 2 "immediate_operand" "i,i")))
17796 (clobber (reg:CC 17))
17797 (clobber (mem:BLK (scratch)))]
17798 "!TARGET_64BIT"
17799 {
17800 switch (get_attr_type (insn))
17801 {
17802 case TYPE_IMOV:
17803 return "mov{l}\t{%1, %0|%0, %1}";
17804
17805 case TYPE_ALU:
17806 if (GET_CODE (operands[2]) == CONST_INT
17807 && (INTVAL (operands[2]) == 128
17808 || (INTVAL (operands[2]) < 0
17809 && INTVAL (operands[2]) != -128)))
17810 {
17811 operands[2] = GEN_INT (-INTVAL (operands[2]));
17812 return "sub{l}\t{%2, %0|%0, %2}";
17813 }
17814 return "add{l}\t{%2, %0|%0, %2}";
17815
17816 case TYPE_LEA:
17817 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17818 return "lea{l}\t{%a2, %0|%0, %a2}";
17819
17820 default:
17821 abort ();
17822 }
17823 }
17824 [(set (attr "type")
17825 (cond [(eq_attr "alternative" "0")
17826 (const_string "alu")
17827 (match_operand:SI 2 "const0_operand" "")
17828 (const_string "imov")
17829 ]
17830 (const_string "lea")))
17831 (set_attr "mode" "SI")])
17832
17833 (define_insn "pro_epilogue_adjust_stack_rex64"
17834 [(set (match_operand:DI 0 "register_operand" "=r,r")
17835 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17836 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17837 (clobber (reg:CC 17))
17838 (clobber (mem:BLK (scratch)))]
17839 "TARGET_64BIT"
17840 {
17841 switch (get_attr_type (insn))
17842 {
17843 case TYPE_IMOV:
17844 return "mov{q}\t{%1, %0|%0, %1}";
17845
17846 case TYPE_ALU:
17847 if (GET_CODE (operands[2]) == CONST_INT
17848 && (INTVAL (operands[2]) == 128
17849 || (INTVAL (operands[2]) < 0
17850 && INTVAL (operands[2]) != -128)))
17851 {
17852 operands[2] = GEN_INT (-INTVAL (operands[2]));
17853 return "sub{q}\t{%2, %0|%0, %2}";
17854 }
17855 return "add{q}\t{%2, %0|%0, %2}";
17856
17857 case TYPE_LEA:
17858 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17859 return "lea{q}\t{%a2, %0|%0, %a2}";
17860
17861 default:
17862 abort ();
17863 }
17864 }
17865 [(set (attr "type")
17866 (cond [(eq_attr "alternative" "0")
17867 (const_string "alu")
17868 (match_operand:DI 2 "const0_operand" "")
17869 (const_string "imov")
17870 ]
17871 (const_string "lea")))
17872 (set_attr "mode" "DI")])
17873
17874
17875 ;; Placeholder for the conditional moves. This one is split either to SSE
17876 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17877 ;; fact is that compares supported by the cmp??ss instructions are exactly
17878 ;; swapped of those supported by cmove sequence.
17879 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17880 ;; supported by i387 comparisons and we do need to emit two conditional moves
17881 ;; in tandem.
17882
17883 (define_insn "sse_movsfcc"
17884 [(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")
17885 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17886 [(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")
17887 (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")])
17888 (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")
17889 (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")))
17890 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17891 (clobber (reg:CC 17))]
17892 "TARGET_SSE
17893 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17894 /* Avoid combine from being smart and converting min/max
17895 instruction patterns into conditional moves. */
17896 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17897 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17898 || !rtx_equal_p (operands[4], operands[2])
17899 || !rtx_equal_p (operands[5], operands[3]))
17900 && (!TARGET_IEEE_FP
17901 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17902 "#")
17903
17904 (define_insn "sse_movsfcc_eq"
17905 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17906 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17907 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17908 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17909 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17910 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17911 (clobber (reg:CC 17))]
17912 "TARGET_SSE
17913 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17914 "#")
17915
17916 (define_insn "sse_movdfcc"
17917 [(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")
17918 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17919 [(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")
17920 (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")])
17921 (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")
17922 (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")))
17923 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17924 (clobber (reg:CC 17))]
17925 "TARGET_SSE2
17926 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17927 /* Avoid combine from being smart and converting min/max
17928 instruction patterns into conditional moves. */
17929 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17930 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17931 || !rtx_equal_p (operands[4], operands[2])
17932 || !rtx_equal_p (operands[5], operands[3]))
17933 && (!TARGET_IEEE_FP
17934 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17935 "#")
17936
17937 (define_insn "sse_movdfcc_eq"
17938 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17939 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17940 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17941 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17942 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17943 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17944 (clobber (reg:CC 17))]
17945 "TARGET_SSE
17946 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17947 "#")
17948
17949 ;; For non-sse moves just expand the usual cmove sequence.
17950 (define_split
17951 [(set (match_operand 0 "register_operand" "")
17952 (if_then_else (match_operator 1 "comparison_operator"
17953 [(match_operand 4 "nonimmediate_operand" "")
17954 (match_operand 5 "register_operand" "")])
17955 (match_operand 2 "nonimmediate_operand" "")
17956 (match_operand 3 "nonimmediate_operand" "")))
17957 (clobber (match_operand 6 "" ""))
17958 (clobber (reg:CC 17))]
17959 "!SSE_REG_P (operands[0]) && reload_completed
17960 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17961 [(const_int 0)]
17962 {
17963 ix86_compare_op0 = operands[5];
17964 ix86_compare_op1 = operands[4];
17965 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17966 VOIDmode, operands[5], operands[4]);
17967 ix86_expand_fp_movcc (operands);
17968 DONE;
17969 })
17970
17971 ;; Split SSE based conditional move into sequence:
17972 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17973 ;; and op2, op0 - zero op2 if comparison was false
17974 ;; nand op0, op3 - load op3 to op0 if comparison was false
17975 ;; or op2, op0 - get the nonzero one into the result.
17976 (define_split
17977 [(set (match_operand 0 "register_operand" "")
17978 (if_then_else (match_operator 1 "sse_comparison_operator"
17979 [(match_operand 4 "register_operand" "")
17980 (match_operand 5 "nonimmediate_operand" "")])
17981 (match_operand 2 "register_operand" "")
17982 (match_operand 3 "register_operand" "")))
17983 (clobber (match_operand 6 "" ""))
17984 (clobber (reg:CC 17))]
17985 "SSE_REG_P (operands[0]) && reload_completed"
17986 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17987 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17988 (subreg:TI (match_dup 4) 0)))
17989 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17990 (subreg:TI (match_dup 3) 0)))
17991 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17992 (subreg:TI (match_dup 7) 0)))]
17993 {
17994 if (GET_MODE (operands[2]) == DFmode
17995 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17996 {
17997 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17998 emit_insn (gen_sse2_unpcklpd (op, op, op));
17999 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18000 emit_insn (gen_sse2_unpcklpd (op, op, op));
18001 }
18002
18003 /* If op2 == op3, op3 would be clobbered before it is used. */
18004 if (operands_match_p (operands[2], operands[3]))
18005 {
18006 emit_move_insn (operands[0], operands[2]);
18007 DONE;
18008 }
18009
18010 PUT_MODE (operands[1], GET_MODE (operands[0]));
18011 if (operands_match_p (operands[0], operands[4]))
18012 operands[6] = operands[4], operands[7] = operands[2];
18013 else
18014 operands[6] = operands[2], operands[7] = operands[4];
18015 })
18016
18017 ;; Special case of conditional move we can handle effectively.
18018 ;; Do not brother with the integer/floating point case, since these are
18019 ;; bot considerably slower, unlike in the generic case.
18020 (define_insn "*sse_movsfcc_const0_1"
18021 [(set (match_operand:SF 0 "register_operand" "=&x")
18022 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18023 [(match_operand:SF 4 "register_operand" "0")
18024 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18025 (match_operand:SF 2 "register_operand" "x")
18026 (match_operand:SF 3 "const0_operand" "X")))]
18027 "TARGET_SSE"
18028 "#")
18029
18030 (define_insn "*sse_movsfcc_const0_2"
18031 [(set (match_operand:SF 0 "register_operand" "=&x")
18032 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18033 [(match_operand:SF 4 "register_operand" "0")
18034 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18035 (match_operand:SF 2 "const0_operand" "X")
18036 (match_operand:SF 3 "register_operand" "x")))]
18037 "TARGET_SSE"
18038 "#")
18039
18040 (define_insn "*sse_movsfcc_const0_3"
18041 [(set (match_operand:SF 0 "register_operand" "=&x")
18042 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18043 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18044 (match_operand:SF 5 "register_operand" "0")])
18045 (match_operand:SF 2 "register_operand" "x")
18046 (match_operand:SF 3 "const0_operand" "X")))]
18047 "TARGET_SSE"
18048 "#")
18049
18050 (define_insn "*sse_movsfcc_const0_4"
18051 [(set (match_operand:SF 0 "register_operand" "=&x")
18052 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18053 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18054 (match_operand:SF 5 "register_operand" "0")])
18055 (match_operand:SF 2 "const0_operand" "X")
18056 (match_operand:SF 3 "register_operand" "x")))]
18057 "TARGET_SSE"
18058 "#")
18059
18060 (define_insn "*sse_movdfcc_const0_1"
18061 [(set (match_operand:DF 0 "register_operand" "=&Y")
18062 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18063 [(match_operand:DF 4 "register_operand" "0")
18064 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18065 (match_operand:DF 2 "register_operand" "Y")
18066 (match_operand:DF 3 "const0_operand" "X")))]
18067 "TARGET_SSE2"
18068 "#")
18069
18070 (define_insn "*sse_movdfcc_const0_2"
18071 [(set (match_operand:DF 0 "register_operand" "=&Y")
18072 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18073 [(match_operand:DF 4 "register_operand" "0")
18074 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18075 (match_operand:DF 2 "const0_operand" "X")
18076 (match_operand:DF 3 "register_operand" "Y")))]
18077 "TARGET_SSE2"
18078 "#")
18079
18080 (define_insn "*sse_movdfcc_const0_3"
18081 [(set (match_operand:DF 0 "register_operand" "=&Y")
18082 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18083 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18084 (match_operand:DF 5 "register_operand" "0")])
18085 (match_operand:DF 2 "register_operand" "Y")
18086 (match_operand:DF 3 "const0_operand" "X")))]
18087 "TARGET_SSE2"
18088 "#")
18089
18090 (define_insn "*sse_movdfcc_const0_4"
18091 [(set (match_operand:DF 0 "register_operand" "=&Y")
18092 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18093 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18094 (match_operand:DF 5 "register_operand" "0")])
18095 (match_operand:DF 2 "const0_operand" "X")
18096 (match_operand:DF 3 "register_operand" "Y")))]
18097 "TARGET_SSE2"
18098 "#")
18099
18100 (define_split
18101 [(set (match_operand 0 "register_operand" "")
18102 (if_then_else (match_operator 1 "comparison_operator"
18103 [(match_operand 4 "nonimmediate_operand" "")
18104 (match_operand 5 "nonimmediate_operand" "")])
18105 (match_operand 2 "nonmemory_operand" "")
18106 (match_operand 3 "nonmemory_operand" "")))]
18107 "SSE_REG_P (operands[0]) && reload_completed
18108 && (const0_operand (operands[2], GET_MODE (operands[0]))
18109 || const0_operand (operands[3], GET_MODE (operands[0])))"
18110 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18111 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
18112 (match_dup 7)))]
18113 {
18114 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18115 && GET_MODE (operands[2]) == DFmode)
18116 {
18117 if (REG_P (operands[2]))
18118 {
18119 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18120 emit_insn (gen_sse2_unpcklpd (op, op, op));
18121 }
18122 if (REG_P (operands[3]))
18123 {
18124 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18125 emit_insn (gen_sse2_unpcklpd (op, op, op));
18126 }
18127 }
18128 PUT_MODE (operands[1], GET_MODE (operands[0]));
18129 if (!sse_comparison_operator (operands[1], VOIDmode)
18130 || !rtx_equal_p (operands[0], operands[4]))
18131 {
18132 rtx tmp = operands[5];
18133 operands[5] = operands[4];
18134 operands[4] = tmp;
18135 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18136 }
18137 if (!rtx_equal_p (operands[0], operands[4]))
18138 abort ();
18139 if (const0_operand (operands[2], GET_MODE (operands[0])))
18140 {
18141 operands[7] = operands[3];
18142 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
18143 0));
18144 }
18145 else
18146 {
18147 operands[7] = operands[2];
18148 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
18149 }
18150 operands[7] = simplify_gen_subreg (TImode, operands[7],
18151 GET_MODE (operands[7]), 0);
18152 })
18153
18154 (define_expand "allocate_stack_worker"
18155 [(match_operand:SI 0 "register_operand" "")]
18156 "TARGET_STACK_PROBE"
18157 {
18158 if (TARGET_64BIT)
18159 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18160 else
18161 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18162 DONE;
18163 })
18164
18165 (define_insn "allocate_stack_worker_1"
18166 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18167 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
18168 (clobber (match_dup 0))
18169 (clobber (reg:CC 17))]
18170 "!TARGET_64BIT && TARGET_STACK_PROBE"
18171 "call\t__alloca"
18172 [(set_attr "type" "multi")
18173 (set_attr "length" "5")])
18174
18175 (define_insn "allocate_stack_worker_rex64"
18176 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18177 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
18178 (clobber (match_dup 0))
18179 (clobber (reg:CC 17))]
18180 "TARGET_64BIT && TARGET_STACK_PROBE"
18181 "call\t__alloca"
18182 [(set_attr "type" "multi")
18183 (set_attr "length" "5")])
18184
18185 (define_expand "allocate_stack"
18186 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18187 (minus:SI (reg:SI 7)
18188 (match_operand:SI 1 "general_operand" "")))
18189 (clobber (reg:CC 17))])
18190 (parallel [(set (reg:SI 7)
18191 (minus:SI (reg:SI 7) (match_dup 1)))
18192 (clobber (reg:CC 17))])]
18193 "TARGET_STACK_PROBE"
18194 {
18195 #ifdef CHECK_STACK_LIMIT
18196 if (GET_CODE (operands[1]) == CONST_INT
18197 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18198 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18199 operands[1]));
18200 else
18201 #endif
18202 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18203 operands[1])));
18204
18205 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18206 DONE;
18207 })
18208
18209 (define_expand "builtin_setjmp_receiver"
18210 [(label_ref (match_operand 0 "" ""))]
18211 "!TARGET_64BIT && flag_pic"
18212 {
18213 emit_insn (gen_set_got (pic_offset_table_rtx));
18214 DONE;
18215 })
18216 \f
18217 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18218
18219 (define_split
18220 [(set (match_operand 0 "register_operand" "")
18221 (match_operator 3 "promotable_binary_operator"
18222 [(match_operand 1 "register_operand" "")
18223 (match_operand 2 "aligned_operand" "")]))
18224 (clobber (reg:CC 17))]
18225 "! TARGET_PARTIAL_REG_STALL && reload_completed
18226 && ((GET_MODE (operands[0]) == HImode
18227 && ((!optimize_size && !TARGET_FAST_PREFIX)
18228 || GET_CODE (operands[2]) != CONST_INT
18229 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18230 || (GET_MODE (operands[0]) == QImode
18231 && (TARGET_PROMOTE_QImode || optimize_size)))"
18232 [(parallel [(set (match_dup 0)
18233 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18234 (clobber (reg:CC 17))])]
18235 "operands[0] = gen_lowpart (SImode, operands[0]);
18236 operands[1] = gen_lowpart (SImode, operands[1]);
18237 if (GET_CODE (operands[3]) != ASHIFT)
18238 operands[2] = gen_lowpart (SImode, operands[2]);
18239 PUT_MODE (operands[3], SImode);")
18240
18241 ; Promote the QImode tests, as i386 has encoding of the AND
18242 ; instruction with 32-bit sign-extended immediate and thus the
18243 ; instruction size is unchanged, except in the %eax case for
18244 ; which it is increased by one byte, hence the ! optimize_size.
18245 (define_split
18246 [(set (reg 17)
18247 (compare (and (match_operand 1 "aligned_operand" "")
18248 (match_operand 2 "const_int_operand" ""))
18249 (const_int 0)))
18250 (set (match_operand 0 "register_operand" "")
18251 (and (match_dup 1) (match_dup 2)))]
18252 "! TARGET_PARTIAL_REG_STALL && reload_completed
18253 /* Ensure that the operand will remain sign-extended immediate. */
18254 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18255 && ! optimize_size
18256 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18257 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18258 [(parallel [(set (reg:CCNO 17)
18259 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18260 (const_int 0)))
18261 (set (match_dup 0)
18262 (and:SI (match_dup 1) (match_dup 2)))])]
18263 "operands[2]
18264 = gen_int_mode (INTVAL (operands[2])
18265 & GET_MODE_MASK (GET_MODE (operands[0])),
18266 SImode);
18267 operands[0] = gen_lowpart (SImode, operands[0]);
18268 operands[1] = gen_lowpart (SImode, operands[1]);")
18269
18270 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18271 ; the TEST instruction with 32-bit sign-extended immediate and thus
18272 ; the instruction size would at least double, which is not what we
18273 ; want even with ! optimize_size.
18274 (define_split
18275 [(set (reg 17)
18276 (compare (and (match_operand:HI 0 "aligned_operand" "")
18277 (match_operand:HI 1 "const_int_operand" ""))
18278 (const_int 0)))]
18279 "! TARGET_PARTIAL_REG_STALL && reload_completed
18280 /* Ensure that the operand will remain sign-extended immediate. */
18281 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18282 && ! TARGET_FAST_PREFIX
18283 && ! optimize_size"
18284 [(set (reg:CCNO 17)
18285 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18286 (const_int 0)))]
18287 "operands[1]
18288 = gen_int_mode (INTVAL (operands[1])
18289 & GET_MODE_MASK (GET_MODE (operands[0])),
18290 SImode);
18291 operands[0] = gen_lowpart (SImode, operands[0]);")
18292
18293 (define_split
18294 [(set (match_operand 0 "register_operand" "")
18295 (neg (match_operand 1 "register_operand" "")))
18296 (clobber (reg:CC 17))]
18297 "! TARGET_PARTIAL_REG_STALL && reload_completed
18298 && (GET_MODE (operands[0]) == HImode
18299 || (GET_MODE (operands[0]) == QImode
18300 && (TARGET_PROMOTE_QImode || optimize_size)))"
18301 [(parallel [(set (match_dup 0)
18302 (neg:SI (match_dup 1)))
18303 (clobber (reg:CC 17))])]
18304 "operands[0] = gen_lowpart (SImode, operands[0]);
18305 operands[1] = gen_lowpart (SImode, operands[1]);")
18306
18307 (define_split
18308 [(set (match_operand 0 "register_operand" "")
18309 (not (match_operand 1 "register_operand" "")))]
18310 "! TARGET_PARTIAL_REG_STALL && reload_completed
18311 && (GET_MODE (operands[0]) == HImode
18312 || (GET_MODE (operands[0]) == QImode
18313 && (TARGET_PROMOTE_QImode || optimize_size)))"
18314 [(set (match_dup 0)
18315 (not:SI (match_dup 1)))]
18316 "operands[0] = gen_lowpart (SImode, operands[0]);
18317 operands[1] = gen_lowpart (SImode, operands[1]);")
18318
18319 (define_split
18320 [(set (match_operand 0 "register_operand" "")
18321 (if_then_else (match_operator 1 "comparison_operator"
18322 [(reg 17) (const_int 0)])
18323 (match_operand 2 "register_operand" "")
18324 (match_operand 3 "register_operand" "")))]
18325 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18326 && (GET_MODE (operands[0]) == HImode
18327 || (GET_MODE (operands[0]) == QImode
18328 && (TARGET_PROMOTE_QImode || optimize_size)))"
18329 [(set (match_dup 0)
18330 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18331 "operands[0] = gen_lowpart (SImode, operands[0]);
18332 operands[2] = gen_lowpart (SImode, operands[2]);
18333 operands[3] = gen_lowpart (SImode, operands[3]);")
18334
18335 \f
18336 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18337 ;; transform a complex memory operation into two memory to register operations.
18338
18339 ;; Don't push memory operands
18340 (define_peephole2
18341 [(set (match_operand:SI 0 "push_operand" "")
18342 (match_operand:SI 1 "memory_operand" ""))
18343 (match_scratch:SI 2 "r")]
18344 "! optimize_size && ! TARGET_PUSH_MEMORY"
18345 [(set (match_dup 2) (match_dup 1))
18346 (set (match_dup 0) (match_dup 2))]
18347 "")
18348
18349 (define_peephole2
18350 [(set (match_operand:DI 0 "push_operand" "")
18351 (match_operand:DI 1 "memory_operand" ""))
18352 (match_scratch:DI 2 "r")]
18353 "! optimize_size && ! TARGET_PUSH_MEMORY"
18354 [(set (match_dup 2) (match_dup 1))
18355 (set (match_dup 0) (match_dup 2))]
18356 "")
18357
18358 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18359 ;; SImode pushes.
18360 (define_peephole2
18361 [(set (match_operand:SF 0 "push_operand" "")
18362 (match_operand:SF 1 "memory_operand" ""))
18363 (match_scratch:SF 2 "r")]
18364 "! optimize_size && ! TARGET_PUSH_MEMORY"
18365 [(set (match_dup 2) (match_dup 1))
18366 (set (match_dup 0) (match_dup 2))]
18367 "")
18368
18369 (define_peephole2
18370 [(set (match_operand:HI 0 "push_operand" "")
18371 (match_operand:HI 1 "memory_operand" ""))
18372 (match_scratch:HI 2 "r")]
18373 "! optimize_size && ! TARGET_PUSH_MEMORY"
18374 [(set (match_dup 2) (match_dup 1))
18375 (set (match_dup 0) (match_dup 2))]
18376 "")
18377
18378 (define_peephole2
18379 [(set (match_operand:QI 0 "push_operand" "")
18380 (match_operand:QI 1 "memory_operand" ""))
18381 (match_scratch:QI 2 "q")]
18382 "! optimize_size && ! TARGET_PUSH_MEMORY"
18383 [(set (match_dup 2) (match_dup 1))
18384 (set (match_dup 0) (match_dup 2))]
18385 "")
18386
18387 ;; Don't move an immediate directly to memory when the instruction
18388 ;; gets too big.
18389 (define_peephole2
18390 [(match_scratch:SI 1 "r")
18391 (set (match_operand:SI 0 "memory_operand" "")
18392 (const_int 0))]
18393 "! optimize_size
18394 && ! TARGET_USE_MOV0
18395 && TARGET_SPLIT_LONG_MOVES
18396 && get_attr_length (insn) >= ix86_cost->large_insn
18397 && peep2_regno_dead_p (0, FLAGS_REG)"
18398 [(parallel [(set (match_dup 1) (const_int 0))
18399 (clobber (reg:CC 17))])
18400 (set (match_dup 0) (match_dup 1))]
18401 "")
18402
18403 (define_peephole2
18404 [(match_scratch:HI 1 "r")
18405 (set (match_operand:HI 0 "memory_operand" "")
18406 (const_int 0))]
18407 "! optimize_size
18408 && ! TARGET_USE_MOV0
18409 && TARGET_SPLIT_LONG_MOVES
18410 && get_attr_length (insn) >= ix86_cost->large_insn
18411 && peep2_regno_dead_p (0, FLAGS_REG)"
18412 [(parallel [(set (match_dup 2) (const_int 0))
18413 (clobber (reg:CC 17))])
18414 (set (match_dup 0) (match_dup 1))]
18415 "operands[2] = gen_lowpart (SImode, operands[1]);")
18416
18417 (define_peephole2
18418 [(match_scratch:QI 1 "q")
18419 (set (match_operand:QI 0 "memory_operand" "")
18420 (const_int 0))]
18421 "! optimize_size
18422 && ! TARGET_USE_MOV0
18423 && TARGET_SPLIT_LONG_MOVES
18424 && get_attr_length (insn) >= ix86_cost->large_insn
18425 && peep2_regno_dead_p (0, FLAGS_REG)"
18426 [(parallel [(set (match_dup 2) (const_int 0))
18427 (clobber (reg:CC 17))])
18428 (set (match_dup 0) (match_dup 1))]
18429 "operands[2] = gen_lowpart (SImode, operands[1]);")
18430
18431 (define_peephole2
18432 [(match_scratch:SI 2 "r")
18433 (set (match_operand:SI 0 "memory_operand" "")
18434 (match_operand:SI 1 "immediate_operand" ""))]
18435 "! optimize_size
18436 && get_attr_length (insn) >= ix86_cost->large_insn
18437 && TARGET_SPLIT_LONG_MOVES"
18438 [(set (match_dup 2) (match_dup 1))
18439 (set (match_dup 0) (match_dup 2))]
18440 "")
18441
18442 (define_peephole2
18443 [(match_scratch:HI 2 "r")
18444 (set (match_operand:HI 0 "memory_operand" "")
18445 (match_operand:HI 1 "immediate_operand" ""))]
18446 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18447 && TARGET_SPLIT_LONG_MOVES"
18448 [(set (match_dup 2) (match_dup 1))
18449 (set (match_dup 0) (match_dup 2))]
18450 "")
18451
18452 (define_peephole2
18453 [(match_scratch:QI 2 "q")
18454 (set (match_operand:QI 0 "memory_operand" "")
18455 (match_operand:QI 1 "immediate_operand" ""))]
18456 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18457 && TARGET_SPLIT_LONG_MOVES"
18458 [(set (match_dup 2) (match_dup 1))
18459 (set (match_dup 0) (match_dup 2))]
18460 "")
18461
18462 ;; Don't compare memory with zero, load and use a test instead.
18463 (define_peephole2
18464 [(set (reg 17)
18465 (compare (match_operand:SI 0 "memory_operand" "")
18466 (const_int 0)))
18467 (match_scratch:SI 3 "r")]
18468 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18469 [(set (match_dup 3) (match_dup 0))
18470 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18471 "")
18472
18473 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18474 ;; Don't split NOTs with a displacement operand, because resulting XOR
18475 ;; will not be pairable anyway.
18476 ;;
18477 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18478 ;; represented using a modRM byte. The XOR replacement is long decoded,
18479 ;; so this split helps here as well.
18480 ;;
18481 ;; Note: Can't do this as a regular split because we can't get proper
18482 ;; lifetime information then.
18483
18484 (define_peephole2
18485 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18486 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18487 "!optimize_size
18488 && peep2_regno_dead_p (0, FLAGS_REG)
18489 && ((TARGET_PENTIUM
18490 && (GET_CODE (operands[0]) != MEM
18491 || !memory_displacement_operand (operands[0], SImode)))
18492 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18493 [(parallel [(set (match_dup 0)
18494 (xor:SI (match_dup 1) (const_int -1)))
18495 (clobber (reg:CC 17))])]
18496 "")
18497
18498 (define_peephole2
18499 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18500 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18501 "!optimize_size
18502 && peep2_regno_dead_p (0, FLAGS_REG)
18503 && ((TARGET_PENTIUM
18504 && (GET_CODE (operands[0]) != MEM
18505 || !memory_displacement_operand (operands[0], HImode)))
18506 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18507 [(parallel [(set (match_dup 0)
18508 (xor:HI (match_dup 1) (const_int -1)))
18509 (clobber (reg:CC 17))])]
18510 "")
18511
18512 (define_peephole2
18513 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18514 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18515 "!optimize_size
18516 && peep2_regno_dead_p (0, FLAGS_REG)
18517 && ((TARGET_PENTIUM
18518 && (GET_CODE (operands[0]) != MEM
18519 || !memory_displacement_operand (operands[0], QImode)))
18520 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18521 [(parallel [(set (match_dup 0)
18522 (xor:QI (match_dup 1) (const_int -1)))
18523 (clobber (reg:CC 17))])]
18524 "")
18525
18526 ;; Non pairable "test imm, reg" instructions can be translated to
18527 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18528 ;; byte opcode instead of two, have a short form for byte operands),
18529 ;; so do it for other CPUs as well. Given that the value was dead,
18530 ;; this should not create any new dependencies. Pass on the sub-word
18531 ;; versions if we're concerned about partial register stalls.
18532
18533 (define_peephole2
18534 [(set (reg 17)
18535 (compare (and:SI (match_operand:SI 0 "register_operand" "")
18536 (match_operand:SI 1 "immediate_operand" ""))
18537 (const_int 0)))]
18538 "ix86_match_ccmode (insn, CCNOmode)
18539 && (true_regnum (operands[0]) != 0
18540 || (GET_CODE (operands[1]) == CONST_INT
18541 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18542 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18543 [(parallel
18544 [(set (reg:CCNO 17)
18545 (compare:CCNO (and:SI (match_dup 0)
18546 (match_dup 1))
18547 (const_int 0)))
18548 (set (match_dup 0)
18549 (and:SI (match_dup 0) (match_dup 1)))])]
18550 "")
18551
18552 ;; We don't need to handle HImode case, because it will be promoted to SImode
18553 ;; on ! TARGET_PARTIAL_REG_STALL
18554
18555 (define_peephole2
18556 [(set (reg 17)
18557 (compare (and:QI (match_operand:QI 0 "register_operand" "")
18558 (match_operand:QI 1 "immediate_operand" ""))
18559 (const_int 0)))]
18560 "! TARGET_PARTIAL_REG_STALL
18561 && ix86_match_ccmode (insn, CCNOmode)
18562 && true_regnum (operands[0]) != 0
18563 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18564 [(parallel
18565 [(set (reg:CCNO 17)
18566 (compare:CCNO (and:QI (match_dup 0)
18567 (match_dup 1))
18568 (const_int 0)))
18569 (set (match_dup 0)
18570 (and:QI (match_dup 0) (match_dup 1)))])]
18571 "")
18572
18573 (define_peephole2
18574 [(set (reg 17)
18575 (compare
18576 (and:SI
18577 (zero_extract:SI
18578 (match_operand 0 "ext_register_operand" "")
18579 (const_int 8)
18580 (const_int 8))
18581 (match_operand 1 "const_int_operand" ""))
18582 (const_int 0)))]
18583 "! TARGET_PARTIAL_REG_STALL
18584 && ix86_match_ccmode (insn, CCNOmode)
18585 && true_regnum (operands[0]) != 0
18586 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18587 [(parallel [(set (reg:CCNO 17)
18588 (compare:CCNO
18589 (and:SI
18590 (zero_extract:SI
18591 (match_dup 0)
18592 (const_int 8)
18593 (const_int 8))
18594 (match_dup 1))
18595 (const_int 0)))
18596 (set (zero_extract:SI (match_dup 0)
18597 (const_int 8)
18598 (const_int 8))
18599 (and:SI
18600 (zero_extract:SI
18601 (match_dup 0)
18602 (const_int 8)
18603 (const_int 8))
18604 (match_dup 1)))])]
18605 "")
18606
18607 ;; Don't do logical operations with memory inputs.
18608 (define_peephole2
18609 [(match_scratch:SI 2 "r")
18610 (parallel [(set (match_operand:SI 0 "register_operand" "")
18611 (match_operator:SI 3 "arith_or_logical_operator"
18612 [(match_dup 0)
18613 (match_operand:SI 1 "memory_operand" "")]))
18614 (clobber (reg:CC 17))])]
18615 "! optimize_size && ! TARGET_READ_MODIFY"
18616 [(set (match_dup 2) (match_dup 1))
18617 (parallel [(set (match_dup 0)
18618 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18619 (clobber (reg:CC 17))])]
18620 "")
18621
18622 (define_peephole2
18623 [(match_scratch:SI 2 "r")
18624 (parallel [(set (match_operand:SI 0 "register_operand" "")
18625 (match_operator:SI 3 "arith_or_logical_operator"
18626 [(match_operand:SI 1 "memory_operand" "")
18627 (match_dup 0)]))
18628 (clobber (reg:CC 17))])]
18629 "! optimize_size && ! TARGET_READ_MODIFY"
18630 [(set (match_dup 2) (match_dup 1))
18631 (parallel [(set (match_dup 0)
18632 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18633 (clobber (reg:CC 17))])]
18634 "")
18635
18636 ; Don't do logical operations with memory outputs
18637 ;
18638 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18639 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18640 ; the same decoder scheduling characteristics as the original.
18641
18642 (define_peephole2
18643 [(match_scratch:SI 2 "r")
18644 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18645 (match_operator:SI 3 "arith_or_logical_operator"
18646 [(match_dup 0)
18647 (match_operand:SI 1 "nonmemory_operand" "")]))
18648 (clobber (reg:CC 17))])]
18649 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18650 [(set (match_dup 2) (match_dup 0))
18651 (parallel [(set (match_dup 2)
18652 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18653 (clobber (reg:CC 17))])
18654 (set (match_dup 0) (match_dup 2))]
18655 "")
18656
18657 (define_peephole2
18658 [(match_scratch:SI 2 "r")
18659 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18660 (match_operator:SI 3 "arith_or_logical_operator"
18661 [(match_operand:SI 1 "nonmemory_operand" "")
18662 (match_dup 0)]))
18663 (clobber (reg:CC 17))])]
18664 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18665 [(set (match_dup 2) (match_dup 0))
18666 (parallel [(set (match_dup 2)
18667 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18668 (clobber (reg:CC 17))])
18669 (set (match_dup 0) (match_dup 2))]
18670 "")
18671
18672 ;; Attempt to always use XOR for zeroing registers.
18673 (define_peephole2
18674 [(set (match_operand 0 "register_operand" "")
18675 (const_int 0))]
18676 "(GET_MODE (operands[0]) == QImode
18677 || GET_MODE (operands[0]) == HImode
18678 || GET_MODE (operands[0]) == SImode
18679 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18680 && (! TARGET_USE_MOV0 || optimize_size)
18681 && peep2_regno_dead_p (0, FLAGS_REG)"
18682 [(parallel [(set (match_dup 0) (const_int 0))
18683 (clobber (reg:CC 17))])]
18684 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18685 operands[0]);")
18686
18687 (define_peephole2
18688 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18689 (const_int 0))]
18690 "(GET_MODE (operands[0]) == QImode
18691 || GET_MODE (operands[0]) == HImode)
18692 && (! TARGET_USE_MOV0 || optimize_size)
18693 && peep2_regno_dead_p (0, FLAGS_REG)"
18694 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18695 (clobber (reg:CC 17))])])
18696
18697 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18698 (define_peephole2
18699 [(set (match_operand 0 "register_operand" "")
18700 (const_int -1))]
18701 "(GET_MODE (operands[0]) == HImode
18702 || GET_MODE (operands[0]) == SImode
18703 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18704 && (optimize_size || TARGET_PENTIUM)
18705 && peep2_regno_dead_p (0, FLAGS_REG)"
18706 [(parallel [(set (match_dup 0) (const_int -1))
18707 (clobber (reg:CC 17))])]
18708 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18709 operands[0]);")
18710
18711 ;; Attempt to convert simple leas to adds. These can be created by
18712 ;; move expanders.
18713 (define_peephole2
18714 [(set (match_operand:SI 0 "register_operand" "")
18715 (plus:SI (match_dup 0)
18716 (match_operand:SI 1 "nonmemory_operand" "")))]
18717 "peep2_regno_dead_p (0, FLAGS_REG)"
18718 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18719 (clobber (reg:CC 17))])]
18720 "")
18721
18722 (define_peephole2
18723 [(set (match_operand:SI 0 "register_operand" "")
18724 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18725 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18726 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18727 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18728 (clobber (reg:CC 17))])]
18729 "operands[2] = gen_lowpart (SImode, operands[2]);")
18730
18731 (define_peephole2
18732 [(set (match_operand:DI 0 "register_operand" "")
18733 (plus:DI (match_dup 0)
18734 (match_operand:DI 1 "x86_64_general_operand" "")))]
18735 "peep2_regno_dead_p (0, FLAGS_REG)"
18736 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18737 (clobber (reg:CC 17))])]
18738 "")
18739
18740 (define_peephole2
18741 [(set (match_operand:SI 0 "register_operand" "")
18742 (mult:SI (match_dup 0)
18743 (match_operand:SI 1 "const_int_operand" "")))]
18744 "exact_log2 (INTVAL (operands[1])) >= 0
18745 && peep2_regno_dead_p (0, FLAGS_REG)"
18746 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18747 (clobber (reg:CC 17))])]
18748 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18749
18750 (define_peephole2
18751 [(set (match_operand:DI 0 "register_operand" "")
18752 (mult:DI (match_dup 0)
18753 (match_operand:DI 1 "const_int_operand" "")))]
18754 "exact_log2 (INTVAL (operands[1])) >= 0
18755 && peep2_regno_dead_p (0, FLAGS_REG)"
18756 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18757 (clobber (reg:CC 17))])]
18758 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18759
18760 (define_peephole2
18761 [(set (match_operand:SI 0 "register_operand" "")
18762 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18763 (match_operand:DI 2 "const_int_operand" "")) 0))]
18764 "exact_log2 (INTVAL (operands[2])) >= 0
18765 && REGNO (operands[0]) == REGNO (operands[1])
18766 && peep2_regno_dead_p (0, FLAGS_REG)"
18767 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18768 (clobber (reg:CC 17))])]
18769 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18770
18771 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18772 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18773 ;; many CPUs it is also faster, since special hardware to avoid esp
18774 ;; dependencies is present.
18775
18776 ;; While some of these conversions may be done using splitters, we use peepholes
18777 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18778
18779 ;; Convert prologue esp subtractions to push.
18780 ;; We need register to push. In order to keep verify_flow_info happy we have
18781 ;; two choices
18782 ;; - use scratch and clobber it in order to avoid dependencies
18783 ;; - use already live register
18784 ;; We can't use the second way right now, since there is no reliable way how to
18785 ;; verify that given register is live. First choice will also most likely in
18786 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18787 ;; call clobbered registers are dead. We may want to use base pointer as an
18788 ;; alternative when no register is available later.
18789
18790 (define_peephole2
18791 [(match_scratch:SI 0 "r")
18792 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18793 (clobber (reg:CC 17))
18794 (clobber (mem:BLK (scratch)))])]
18795 "optimize_size || !TARGET_SUB_ESP_4"
18796 [(clobber (match_dup 0))
18797 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18798 (clobber (mem:BLK (scratch)))])])
18799
18800 (define_peephole2
18801 [(match_scratch:SI 0 "r")
18802 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18803 (clobber (reg:CC 17))
18804 (clobber (mem:BLK (scratch)))])]
18805 "optimize_size || !TARGET_SUB_ESP_8"
18806 [(clobber (match_dup 0))
18807 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18808 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18809 (clobber (mem:BLK (scratch)))])])
18810
18811 ;; Convert esp subtractions to push.
18812 (define_peephole2
18813 [(match_scratch:SI 0 "r")
18814 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18815 (clobber (reg:CC 17))])]
18816 "optimize_size || !TARGET_SUB_ESP_4"
18817 [(clobber (match_dup 0))
18818 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18819
18820 (define_peephole2
18821 [(match_scratch:SI 0 "r")
18822 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18823 (clobber (reg:CC 17))])]
18824 "optimize_size || !TARGET_SUB_ESP_8"
18825 [(clobber (match_dup 0))
18826 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18827 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18828
18829 ;; Convert epilogue deallocator to pop.
18830 (define_peephole2
18831 [(match_scratch:SI 0 "r")
18832 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18833 (clobber (reg:CC 17))
18834 (clobber (mem:BLK (scratch)))])]
18835 "optimize_size || !TARGET_ADD_ESP_4"
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 "")
18840
18841 ;; Two pops case is tricky, since pop causes dependency on destination register.
18842 ;; We use two registers if available.
18843 (define_peephole2
18844 [(match_scratch:SI 0 "r")
18845 (match_scratch:SI 1 "r")
18846 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18847 (clobber (reg:CC 17))
18848 (clobber (mem:BLK (scratch)))])]
18849 "optimize_size || !TARGET_ADD_ESP_8"
18850 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18851 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18852 (clobber (mem:BLK (scratch)))])
18853 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18854 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18855 "")
18856
18857 (define_peephole2
18858 [(match_scratch:SI 0 "r")
18859 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18860 (clobber (reg:CC 17))
18861 (clobber (mem:BLK (scratch)))])]
18862 "optimize_size"
18863 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18864 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18865 (clobber (mem:BLK (scratch)))])
18866 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18867 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18868 "")
18869
18870 ;; Convert esp additions to pop.
18871 (define_peephole2
18872 [(match_scratch:SI 0 "r")
18873 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18874 (clobber (reg:CC 17))])]
18875 ""
18876 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18877 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18878 "")
18879
18880 ;; Two pops case is tricky, since pop causes dependency on destination register.
18881 ;; We use two registers if available.
18882 (define_peephole2
18883 [(match_scratch:SI 0 "r")
18884 (match_scratch:SI 1 "r")
18885 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18886 (clobber (reg:CC 17))])]
18887 ""
18888 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18889 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18890 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18891 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18892 "")
18893
18894 (define_peephole2
18895 [(match_scratch:SI 0 "r")
18896 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18897 (clobber (reg:CC 17))])]
18898 "optimize_size"
18899 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18900 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18901 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18902 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18903 "")
18904 \f
18905 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18906 ;; required and register dies.
18907 (define_peephole2
18908 [(set (reg 17)
18909 (compare (match_operand:SI 0 "register_operand" "")
18910 (match_operand:SI 1 "incdec_operand" "")))]
18911 "ix86_match_ccmode (insn, CCGCmode)
18912 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18913 [(parallel [(set (reg:CCGC 17)
18914 (compare:CCGC (match_dup 0)
18915 (match_dup 1)))
18916 (clobber (match_dup 0))])]
18917 "")
18918
18919 (define_peephole2
18920 [(set (reg 17)
18921 (compare (match_operand:HI 0 "register_operand" "")
18922 (match_operand:HI 1 "incdec_operand" "")))]
18923 "ix86_match_ccmode (insn, CCGCmode)
18924 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18925 [(parallel [(set (reg:CCGC 17)
18926 (compare:CCGC (match_dup 0)
18927 (match_dup 1)))
18928 (clobber (match_dup 0))])]
18929 "")
18930
18931 (define_peephole2
18932 [(set (reg 17)
18933 (compare (match_operand:QI 0 "register_operand" "")
18934 (match_operand:QI 1 "incdec_operand" "")))]
18935 "ix86_match_ccmode (insn, CCGCmode)
18936 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18937 [(parallel [(set (reg:CCGC 17)
18938 (compare:CCGC (match_dup 0)
18939 (match_dup 1)))
18940 (clobber (match_dup 0))])]
18941 "")
18942
18943 ;; Convert compares with 128 to shorter add -128
18944 (define_peephole2
18945 [(set (reg 17)
18946 (compare (match_operand:SI 0 "register_operand" "")
18947 (const_int 128)))]
18948 "ix86_match_ccmode (insn, CCGCmode)
18949 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18950 [(parallel [(set (reg:CCGC 17)
18951 (compare:CCGC (match_dup 0)
18952 (const_int 128)))
18953 (clobber (match_dup 0))])]
18954 "")
18955
18956 (define_peephole2
18957 [(set (reg 17)
18958 (compare (match_operand:HI 0 "register_operand" "")
18959 (const_int 128)))]
18960 "ix86_match_ccmode (insn, CCGCmode)
18961 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18962 [(parallel [(set (reg:CCGC 17)
18963 (compare:CCGC (match_dup 0)
18964 (const_int 128)))
18965 (clobber (match_dup 0))])]
18966 "")
18967 \f
18968 (define_peephole2
18969 [(match_scratch:DI 0 "r")
18970 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18971 (clobber (reg:CC 17))
18972 (clobber (mem:BLK (scratch)))])]
18973 "optimize_size || !TARGET_SUB_ESP_4"
18974 [(clobber (match_dup 0))
18975 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18976 (clobber (mem:BLK (scratch)))])])
18977
18978 (define_peephole2
18979 [(match_scratch:DI 0 "r")
18980 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18981 (clobber (reg:CC 17))
18982 (clobber (mem:BLK (scratch)))])]
18983 "optimize_size || !TARGET_SUB_ESP_8"
18984 [(clobber (match_dup 0))
18985 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18986 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18987 (clobber (mem:BLK (scratch)))])])
18988
18989 ;; Convert esp subtractions to push.
18990 (define_peephole2
18991 [(match_scratch:DI 0 "r")
18992 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18993 (clobber (reg:CC 17))])]
18994 "optimize_size || !TARGET_SUB_ESP_4"
18995 [(clobber (match_dup 0))
18996 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18997
18998 (define_peephole2
18999 [(match_scratch:DI 0 "r")
19000 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
19001 (clobber (reg:CC 17))])]
19002 "optimize_size || !TARGET_SUB_ESP_8"
19003 [(clobber (match_dup 0))
19004 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
19005 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
19006
19007 ;; Convert epilogue deallocator to pop.
19008 (define_peephole2
19009 [(match_scratch:DI 0 "r")
19010 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19011 (clobber (reg:CC 17))
19012 (clobber (mem:BLK (scratch)))])]
19013 "optimize_size || !TARGET_ADD_ESP_4"
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 "")
19018
19019 ;; Two pops case is tricky, since pop causes dependency on destination register.
19020 ;; We use two registers if available.
19021 (define_peephole2
19022 [(match_scratch:DI 0 "r")
19023 (match_scratch:DI 1 "r")
19024 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19025 (clobber (reg:CC 17))
19026 (clobber (mem:BLK (scratch)))])]
19027 "optimize_size || !TARGET_ADD_ESP_8"
19028 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19029 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19030 (clobber (mem:BLK (scratch)))])
19031 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
19032 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19033 "")
19034
19035 (define_peephole2
19036 [(match_scratch:DI 0 "r")
19037 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19038 (clobber (reg:CC 17))
19039 (clobber (mem:BLK (scratch)))])]
19040 "optimize_size"
19041 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19042 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19043 (clobber (mem:BLK (scratch)))])
19044 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19045 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19046 "")
19047
19048 ;; Convert esp additions to pop.
19049 (define_peephole2
19050 [(match_scratch:DI 0 "r")
19051 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19052 (clobber (reg:CC 17))])]
19053 ""
19054 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19055 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19056 "")
19057
19058 ;; Two pops case is tricky, since pop causes dependency on destination register.
19059 ;; We use two registers if available.
19060 (define_peephole2
19061 [(match_scratch:DI 0 "r")
19062 (match_scratch:DI 1 "r")
19063 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19064 (clobber (reg:CC 17))])]
19065 ""
19066 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19067 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
19068 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
19069 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19070 "")
19071
19072 (define_peephole2
19073 [(match_scratch:DI 0 "r")
19074 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19075 (clobber (reg:CC 17))])]
19076 "optimize_size"
19077 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19078 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
19079 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19080 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19081 "")
19082 \f
19083 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19084 ;; imul $32bit_imm, reg, reg is direct decoded.
19085 (define_peephole2
19086 [(match_scratch:DI 3 "r")
19087 (parallel [(set (match_operand:DI 0 "register_operand" "")
19088 (mult:DI (match_operand:DI 1 "memory_operand" "")
19089 (match_operand:DI 2 "immediate_operand" "")))
19090 (clobber (reg:CC 17))])]
19091 "TARGET_K8 && !optimize_size
19092 && (GET_CODE (operands[2]) != CONST_INT
19093 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19094 [(set (match_dup 3) (match_dup 1))
19095 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19096 (clobber (reg:CC 17))])]
19097 "")
19098
19099 (define_peephole2
19100 [(match_scratch:SI 3 "r")
19101 (parallel [(set (match_operand:SI 0 "register_operand" "")
19102 (mult:SI (match_operand:SI 1 "memory_operand" "")
19103 (match_operand:SI 2 "immediate_operand" "")))
19104 (clobber (reg:CC 17))])]
19105 "TARGET_K8 && !optimize_size
19106 && (GET_CODE (operands[2]) != CONST_INT
19107 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19108 [(set (match_dup 3) (match_dup 1))
19109 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19110 (clobber (reg:CC 17))])]
19111 "")
19112
19113 (define_peephole2
19114 [(match_scratch:SI 3 "r")
19115 (parallel [(set (match_operand:DI 0 "register_operand" "")
19116 (zero_extend:DI
19117 (mult:SI (match_operand:SI 1 "memory_operand" "")
19118 (match_operand:SI 2 "immediate_operand" ""))))
19119 (clobber (reg:CC 17))])]
19120 "TARGET_K8 && !optimize_size
19121 && (GET_CODE (operands[2]) != CONST_INT
19122 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19123 [(set (match_dup 3) (match_dup 1))
19124 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19125 (clobber (reg:CC 17))])]
19126 "")
19127
19128 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19129 ;; Convert it into imul reg, reg
19130 ;; It would be better to force assembler to encode instruction using long
19131 ;; immediate, but there is apparently no way to do so.
19132 (define_peephole2
19133 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19134 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19135 (match_operand:DI 2 "const_int_operand" "")))
19136 (clobber (reg:CC 17))])
19137 (match_scratch:DI 3 "r")]
19138 "TARGET_K8 && !optimize_size
19139 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19140 [(set (match_dup 3) (match_dup 2))
19141 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19142 (clobber (reg:CC 17))])]
19143 {
19144 if (!rtx_equal_p (operands[0], operands[1]))
19145 emit_move_insn (operands[0], operands[1]);
19146 })
19147
19148 (define_peephole2
19149 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19150 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19151 (match_operand:SI 2 "const_int_operand" "")))
19152 (clobber (reg:CC 17))])
19153 (match_scratch:SI 3 "r")]
19154 "TARGET_K8 && !optimize_size
19155 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19156 [(set (match_dup 3) (match_dup 2))
19157 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19158 (clobber (reg:CC 17))])]
19159 {
19160 if (!rtx_equal_p (operands[0], operands[1]))
19161 emit_move_insn (operands[0], operands[1]);
19162 })
19163
19164 (define_peephole2
19165 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19166 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19167 (match_operand:HI 2 "immediate_operand" "")))
19168 (clobber (reg:CC 17))])
19169 (match_scratch:HI 3 "r")]
19170 "TARGET_K8 && !optimize_size"
19171 [(set (match_dup 3) (match_dup 2))
19172 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19173 (clobber (reg:CC 17))])]
19174 {
19175 if (!rtx_equal_p (operands[0], operands[1]))
19176 emit_move_insn (operands[0], operands[1]);
19177 })
19178 \f
19179 ;; Call-value patterns last so that the wildcard operand does not
19180 ;; disrupt insn-recog's switch tables.
19181
19182 (define_insn "*call_value_pop_0"
19183 [(set (match_operand 0 "" "")
19184 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19185 (match_operand:SI 2 "" "")))
19186 (set (reg:SI 7) (plus:SI (reg:SI 7)
19187 (match_operand:SI 3 "immediate_operand" "")))]
19188 "!TARGET_64BIT"
19189 {
19190 if (SIBLING_CALL_P (insn))
19191 return "jmp\t%P1";
19192 else
19193 return "call\t%P1";
19194 }
19195 [(set_attr "type" "callv")])
19196
19197 (define_insn "*call_value_pop_1"
19198 [(set (match_operand 0 "" "")
19199 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19200 (match_operand:SI 2 "" "")))
19201 (set (reg:SI 7) (plus:SI (reg:SI 7)
19202 (match_operand:SI 3 "immediate_operand" "i")))]
19203 "!TARGET_64BIT"
19204 {
19205 if (constant_call_address_operand (operands[1], QImode))
19206 {
19207 if (SIBLING_CALL_P (insn))
19208 return "jmp\t%P1";
19209 else
19210 return "call\t%P1";
19211 }
19212 if (SIBLING_CALL_P (insn))
19213 return "jmp\t%A1";
19214 else
19215 return "call\t%A1";
19216 }
19217 [(set_attr "type" "callv")])
19218
19219 (define_insn "*call_value_0"
19220 [(set (match_operand 0 "" "")
19221 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19222 (match_operand:SI 2 "" "")))]
19223 "!TARGET_64BIT"
19224 {
19225 if (SIBLING_CALL_P (insn))
19226 return "jmp\t%P1";
19227 else
19228 return "call\t%P1";
19229 }
19230 [(set_attr "type" "callv")])
19231
19232 (define_insn "*call_value_0_rex64"
19233 [(set (match_operand 0 "" "")
19234 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19235 (match_operand:DI 2 "const_int_operand" "")))]
19236 "TARGET_64BIT"
19237 {
19238 if (SIBLING_CALL_P (insn))
19239 return "jmp\t%P1";
19240 else
19241 return "call\t%P1";
19242 }
19243 [(set_attr "type" "callv")])
19244
19245 (define_insn "*call_value_1"
19246 [(set (match_operand 0 "" "")
19247 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19248 (match_operand:SI 2 "" "")))]
19249 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19250 {
19251 if (constant_call_address_operand (operands[1], QImode))
19252 return "call\t%P1";
19253 return "call\t%*%1";
19254 }
19255 [(set_attr "type" "callv")])
19256
19257 (define_insn "*sibcall_value_1"
19258 [(set (match_operand 0 "" "")
19259 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19260 (match_operand:SI 2 "" "")))]
19261 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19262 {
19263 if (constant_call_address_operand (operands[1], QImode))
19264 return "jmp\t%P1";
19265 return "jmp\t%*%1";
19266 }
19267 [(set_attr "type" "callv")])
19268
19269 (define_insn "*call_value_1_rex64"
19270 [(set (match_operand 0 "" "")
19271 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19272 (match_operand:DI 2 "" "")))]
19273 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19274 {
19275 if (constant_call_address_operand (operands[1], QImode))
19276 return "call\t%P1";
19277 return "call\t%A1";
19278 }
19279 [(set_attr "type" "callv")])
19280
19281 (define_insn "*sibcall_value_1_rex64"
19282 [(set (match_operand 0 "" "")
19283 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19284 (match_operand:DI 2 "" "")))]
19285 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19286 "jmp\t%P1"
19287 [(set_attr "type" "callv")])
19288
19289 (define_insn "*sibcall_value_1_rex64_v"
19290 [(set (match_operand 0 "" "")
19291 (call (mem:QI (reg:DI 40))
19292 (match_operand:DI 1 "" "")))]
19293 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19294 "jmp\t*%%r11"
19295 [(set_attr "type" "callv")])
19296 \f
19297 (define_insn "trap"
19298 [(trap_if (const_int 1) (const_int 5))]
19299 ""
19300 "int\t$5")
19301
19302 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19303 ;;; for the sake of bounds checking. By emitting bounds checks as
19304 ;;; conditional traps rather than as conditional jumps around
19305 ;;; unconditional traps we avoid introducing spurious basic-block
19306 ;;; boundaries and facilitate elimination of redundant checks. In
19307 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19308 ;;; interrupt 5.
19309 ;;;
19310 ;;; FIXME: Static branch prediction rules for ix86 are such that
19311 ;;; forward conditional branches predict as untaken. As implemented
19312 ;;; below, pseudo conditional traps violate that rule. We should use
19313 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19314 ;;; section loaded at the end of the text segment and branch forward
19315 ;;; there on bounds-failure, and then jump back immediately (in case
19316 ;;; the system chooses to ignore bounds violations, or to report
19317 ;;; violations and continue execution).
19318
19319 (define_expand "conditional_trap"
19320 [(trap_if (match_operator 0 "comparison_operator"
19321 [(match_dup 2) (const_int 0)])
19322 (match_operand 1 "const_int_operand" ""))]
19323 ""
19324 {
19325 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19326 ix86_expand_compare (GET_CODE (operands[0]),
19327 NULL, NULL),
19328 operands[1]));
19329 DONE;
19330 })
19331
19332 (define_insn "*conditional_trap_1"
19333 [(trap_if (match_operator 0 "comparison_operator"
19334 [(reg 17) (const_int 0)])
19335 (match_operand 1 "const_int_operand" ""))]
19336 ""
19337 {
19338 operands[2] = gen_label_rtx ();
19339 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19340 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19341 CODE_LABEL_NUMBER (operands[2]));
19342 RET;
19343 })
19344
19345 ;; Pentium III SIMD instructions.
19346
19347 ;; Moves for SSE/MMX regs.
19348
19349 (define_insn "movv4sf_internal"
19350 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19351 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19352 "TARGET_SSE"
19353 "@
19354 xorps\t%0, %0
19355 movaps\t{%1, %0|%0, %1}
19356 movaps\t{%1, %0|%0, %1}"
19357 [(set_attr "type" "ssemov")
19358 (set_attr "mode" "V4SF")])
19359
19360 (define_split
19361 [(set (match_operand:V4SF 0 "register_operand" "")
19362 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19363 "TARGET_SSE"
19364 [(set (match_dup 0)
19365 (vec_merge:V4SF
19366 (vec_duplicate:V4SF (match_dup 1))
19367 (match_dup 2)
19368 (const_int 1)))]
19369 {
19370 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19371 operands[2] = CONST0_RTX (V4SFmode);
19372 })
19373
19374 (define_insn "movv4si_internal"
19375 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19376 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19377 "TARGET_SSE"
19378 {
19379 switch (which_alternative)
19380 {
19381 case 0:
19382 if (get_attr_mode (insn) == MODE_V4SF)
19383 return "xorps\t%0, %0";
19384 else
19385 return "pxor\t%0, %0";
19386 case 1:
19387 case 2:
19388 if (get_attr_mode (insn) == MODE_V4SF)
19389 return "movaps\t{%1, %0|%0, %1}";
19390 else
19391 return "movdqa\t{%1, %0|%0, %1}";
19392 default:
19393 abort ();
19394 }
19395 }
19396 [(set_attr "type" "ssemov")
19397 (set (attr "mode")
19398 (cond [(eq_attr "alternative" "0,1")
19399 (if_then_else
19400 (ne (symbol_ref "optimize_size")
19401 (const_int 0))
19402 (const_string "V4SF")
19403 (const_string "TI"))
19404 (eq_attr "alternative" "2")
19405 (if_then_else
19406 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19407 (const_int 0))
19408 (ne (symbol_ref "optimize_size")
19409 (const_int 0)))
19410 (const_string "V4SF")
19411 (const_string "TI"))]
19412 (const_string "TI")))])
19413
19414 (define_insn "movv2di_internal"
19415 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19416 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19417 "TARGET_SSE2"
19418 {
19419 switch (which_alternative)
19420 {
19421 case 0:
19422 if (get_attr_mode (insn) == MODE_V4SF)
19423 return "xorps\t%0, %0";
19424 else
19425 return "pxor\t%0, %0";
19426 case 1:
19427 case 2:
19428 if (get_attr_mode (insn) == MODE_V4SF)
19429 return "movaps\t{%1, %0|%0, %1}";
19430 else
19431 return "movdqa\t{%1, %0|%0, %1}";
19432 default:
19433 abort ();
19434 }
19435 }
19436 [(set_attr "type" "ssemov")
19437 (set (attr "mode")
19438 (cond [(eq_attr "alternative" "0,1")
19439 (if_then_else
19440 (ne (symbol_ref "optimize_size")
19441 (const_int 0))
19442 (const_string "V4SF")
19443 (const_string "TI"))
19444 (eq_attr "alternative" "2")
19445 (if_then_else
19446 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19447 (const_int 0))
19448 (ne (symbol_ref "optimize_size")
19449 (const_int 0)))
19450 (const_string "V4SF")
19451 (const_string "TI"))]
19452 (const_string "TI")))])
19453
19454 (define_split
19455 [(set (match_operand:V2DF 0 "register_operand" "")
19456 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19457 "TARGET_SSE2"
19458 [(set (match_dup 0)
19459 (vec_merge:V2DF
19460 (vec_duplicate:V2DF (match_dup 1))
19461 (match_dup 2)
19462 (const_int 1)))]
19463 {
19464 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19465 operands[2] = CONST0_RTX (V2DFmode);
19466 })
19467
19468 (define_insn "movv8qi_internal"
19469 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19470 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19471 "TARGET_MMX
19472 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19473 "@
19474 pxor\t%0, %0
19475 movq\t{%1, %0|%0, %1}
19476 movq\t{%1, %0|%0, %1}"
19477 [(set_attr "type" "mmxmov")
19478 (set_attr "mode" "DI")])
19479
19480 (define_insn "movv4hi_internal"
19481 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19482 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19483 "TARGET_MMX
19484 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19485 "@
19486 pxor\t%0, %0
19487 movq\t{%1, %0|%0, %1}
19488 movq\t{%1, %0|%0, %1}"
19489 [(set_attr "type" "mmxmov")
19490 (set_attr "mode" "DI")])
19491
19492 (define_insn "movv2si_internal"
19493 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19494 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19495 "TARGET_MMX
19496 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19497 "@
19498 pxor\t%0, %0
19499 movq\t{%1, %0|%0, %1}
19500 movq\t{%1, %0|%0, %1}"
19501 [(set_attr "type" "mmxcvt")
19502 (set_attr "mode" "DI")])
19503
19504 (define_insn "movv2sf_internal"
19505 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19506 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19507 "TARGET_3DNOW
19508 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19509 "@
19510 pxor\t%0, %0
19511 movq\t{%1, %0|%0, %1}
19512 movq\t{%1, %0|%0, %1}"
19513 [(set_attr "type" "mmxcvt")
19514 (set_attr "mode" "DI")])
19515
19516 (define_expand "movti"
19517 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19518 (match_operand:TI 1 "nonimmediate_operand" ""))]
19519 "TARGET_SSE || TARGET_64BIT"
19520 {
19521 if (TARGET_64BIT)
19522 ix86_expand_move (TImode, operands);
19523 else
19524 ix86_expand_vector_move (TImode, operands);
19525 DONE;
19526 })
19527
19528 (define_insn "movv2df_internal"
19529 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19530 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19531 "TARGET_SSE2
19532 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19533 {
19534 switch (which_alternative)
19535 {
19536 case 0:
19537 if (get_attr_mode (insn) == MODE_V4SF)
19538 return "xorps\t%0, %0";
19539 else
19540 return "xorpd\t%0, %0";
19541 case 1:
19542 case 2:
19543 if (get_attr_mode (insn) == MODE_V4SF)
19544 return "movaps\t{%1, %0|%0, %1}";
19545 else
19546 return "movapd\t{%1, %0|%0, %1}";
19547 default:
19548 abort ();
19549 }
19550 }
19551 [(set_attr "type" "ssemov")
19552 (set (attr "mode")
19553 (cond [(eq_attr "alternative" "0,1")
19554 (if_then_else
19555 (ne (symbol_ref "optimize_size")
19556 (const_int 0))
19557 (const_string "V4SF")
19558 (const_string "V2DF"))
19559 (eq_attr "alternative" "2")
19560 (if_then_else
19561 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19562 (const_int 0))
19563 (ne (symbol_ref "optimize_size")
19564 (const_int 0)))
19565 (const_string "V4SF")
19566 (const_string "V2DF"))]
19567 (const_string "V2DF")))])
19568
19569 (define_insn "movv8hi_internal"
19570 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19571 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19572 "TARGET_SSE2
19573 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19574 {
19575 switch (which_alternative)
19576 {
19577 case 0:
19578 if (get_attr_mode (insn) == MODE_V4SF)
19579 return "xorps\t%0, %0";
19580 else
19581 return "pxor\t%0, %0";
19582 case 1:
19583 case 2:
19584 if (get_attr_mode (insn) == MODE_V4SF)
19585 return "movaps\t{%1, %0|%0, %1}";
19586 else
19587 return "movdqa\t{%1, %0|%0, %1}";
19588 default:
19589 abort ();
19590 }
19591 }
19592 [(set_attr "type" "ssemov")
19593 (set (attr "mode")
19594 (cond [(eq_attr "alternative" "0,1")
19595 (if_then_else
19596 (ne (symbol_ref "optimize_size")
19597 (const_int 0))
19598 (const_string "V4SF")
19599 (const_string "TI"))
19600 (eq_attr "alternative" "2")
19601 (if_then_else
19602 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19603 (const_int 0))
19604 (ne (symbol_ref "optimize_size")
19605 (const_int 0)))
19606 (const_string "V4SF")
19607 (const_string "TI"))]
19608 (const_string "TI")))])
19609
19610 (define_insn "movv16qi_internal"
19611 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19612 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19613 "TARGET_SSE2
19614 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19615 {
19616 switch (which_alternative)
19617 {
19618 case 0:
19619 if (get_attr_mode (insn) == MODE_V4SF)
19620 return "xorps\t%0, %0";
19621 else
19622 return "pxor\t%0, %0";
19623 case 1:
19624 case 2:
19625 if (get_attr_mode (insn) == MODE_V4SF)
19626 return "movaps\t{%1, %0|%0, %1}";
19627 else
19628 return "movdqa\t{%1, %0|%0, %1}";
19629 default:
19630 abort ();
19631 }
19632 }
19633 [(set_attr "type" "ssemov")
19634 (set (attr "mode")
19635 (cond [(eq_attr "alternative" "0,1")
19636 (if_then_else
19637 (ne (symbol_ref "optimize_size")
19638 (const_int 0))
19639 (const_string "V4SF")
19640 (const_string "TI"))
19641 (eq_attr "alternative" "2")
19642 (if_then_else
19643 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19644 (const_int 0))
19645 (ne (symbol_ref "optimize_size")
19646 (const_int 0)))
19647 (const_string "V4SF")
19648 (const_string "TI"))]
19649 (const_string "TI")))])
19650
19651 (define_expand "movv2df"
19652 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19653 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19654 "TARGET_SSE2"
19655 {
19656 ix86_expand_vector_move (V2DFmode, operands);
19657 DONE;
19658 })
19659
19660 (define_expand "movv8hi"
19661 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19662 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19663 "TARGET_SSE2"
19664 {
19665 ix86_expand_vector_move (V8HImode, operands);
19666 DONE;
19667 })
19668
19669 (define_expand "movv16qi"
19670 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19671 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19672 "TARGET_SSE2"
19673 {
19674 ix86_expand_vector_move (V16QImode, operands);
19675 DONE;
19676 })
19677
19678 (define_expand "movv4sf"
19679 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19680 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19681 "TARGET_SSE"
19682 {
19683 ix86_expand_vector_move (V4SFmode, operands);
19684 DONE;
19685 })
19686
19687 (define_expand "movv4si"
19688 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19689 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19690 "TARGET_SSE"
19691 {
19692 ix86_expand_vector_move (V4SImode, operands);
19693 DONE;
19694 })
19695
19696 (define_expand "movv2di"
19697 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19698 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19699 "TARGET_SSE"
19700 {
19701 ix86_expand_vector_move (V2DImode, operands);
19702 DONE;
19703 })
19704
19705 (define_expand "movv2si"
19706 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19707 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19708 "TARGET_MMX"
19709 {
19710 ix86_expand_vector_move (V2SImode, operands);
19711 DONE;
19712 })
19713
19714 (define_expand "movv4hi"
19715 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19716 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19717 "TARGET_MMX"
19718 {
19719 ix86_expand_vector_move (V4HImode, operands);
19720 DONE;
19721 })
19722
19723 (define_expand "movv8qi"
19724 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19725 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19726 "TARGET_MMX"
19727 {
19728 ix86_expand_vector_move (V8QImode, operands);
19729 DONE;
19730 })
19731
19732 (define_expand "movv2sf"
19733 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19734 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19735 "TARGET_3DNOW"
19736 {
19737 ix86_expand_vector_move (V2SFmode, operands);
19738 DONE;
19739 })
19740
19741 (define_insn "*pushti"
19742 [(set (match_operand:TI 0 "push_operand" "=<")
19743 (match_operand:TI 1 "register_operand" "x"))]
19744 "TARGET_SSE"
19745 "#")
19746
19747 (define_insn "*pushv2df"
19748 [(set (match_operand:V2DF 0 "push_operand" "=<")
19749 (match_operand:V2DF 1 "register_operand" "x"))]
19750 "TARGET_SSE"
19751 "#")
19752
19753 (define_insn "*pushv2di"
19754 [(set (match_operand:V2DI 0 "push_operand" "=<")
19755 (match_operand:V2DI 1 "register_operand" "x"))]
19756 "TARGET_SSE2"
19757 "#")
19758
19759 (define_insn "*pushv8hi"
19760 [(set (match_operand:V8HI 0 "push_operand" "=<")
19761 (match_operand:V8HI 1 "register_operand" "x"))]
19762 "TARGET_SSE2"
19763 "#")
19764
19765 (define_insn "*pushv16qi"
19766 [(set (match_operand:V16QI 0 "push_operand" "=<")
19767 (match_operand:V16QI 1 "register_operand" "x"))]
19768 "TARGET_SSE2"
19769 "#")
19770
19771 (define_insn "*pushv4sf"
19772 [(set (match_operand:V4SF 0 "push_operand" "=<")
19773 (match_operand:V4SF 1 "register_operand" "x"))]
19774 "TARGET_SSE"
19775 "#")
19776
19777 (define_insn "*pushv4si"
19778 [(set (match_operand:V4SI 0 "push_operand" "=<")
19779 (match_operand:V4SI 1 "register_operand" "x"))]
19780 "TARGET_SSE2"
19781 "#")
19782
19783 (define_insn "*pushv2si"
19784 [(set (match_operand:V2SI 0 "push_operand" "=<")
19785 (match_operand:V2SI 1 "register_operand" "y"))]
19786 "TARGET_MMX"
19787 "#")
19788
19789 (define_insn "*pushv4hi"
19790 [(set (match_operand:V4HI 0 "push_operand" "=<")
19791 (match_operand:V4HI 1 "register_operand" "y"))]
19792 "TARGET_MMX"
19793 "#")
19794
19795 (define_insn "*pushv8qi"
19796 [(set (match_operand:V8QI 0 "push_operand" "=<")
19797 (match_operand:V8QI 1 "register_operand" "y"))]
19798 "TARGET_MMX"
19799 "#")
19800
19801 (define_insn "*pushv2sf"
19802 [(set (match_operand:V2SF 0 "push_operand" "=<")
19803 (match_operand:V2SF 1 "register_operand" "y"))]
19804 "TARGET_3DNOW"
19805 "#")
19806
19807 (define_split
19808 [(set (match_operand 0 "push_operand" "")
19809 (match_operand 1 "register_operand" ""))]
19810 "!TARGET_64BIT && reload_completed
19811 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19812 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19813 (set (match_dup 2) (match_dup 1))]
19814 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19815 stack_pointer_rtx);
19816 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19817
19818 (define_split
19819 [(set (match_operand 0 "push_operand" "")
19820 (match_operand 1 "register_operand" ""))]
19821 "TARGET_64BIT && reload_completed
19822 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19823 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19824 (set (match_dup 2) (match_dup 1))]
19825 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19826 stack_pointer_rtx);
19827 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19828
19829
19830 (define_insn "movti_internal"
19831 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19832 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19833 "TARGET_SSE && !TARGET_64BIT
19834 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19835 {
19836 switch (which_alternative)
19837 {
19838 case 0:
19839 if (get_attr_mode (insn) == MODE_V4SF)
19840 return "xorps\t%0, %0";
19841 else
19842 return "pxor\t%0, %0";
19843 case 1:
19844 case 2:
19845 if (get_attr_mode (insn) == MODE_V4SF)
19846 return "movaps\t{%1, %0|%0, %1}";
19847 else
19848 return "movdqa\t{%1, %0|%0, %1}";
19849 default:
19850 abort ();
19851 }
19852 }
19853 [(set_attr "type" "ssemov,ssemov,ssemov")
19854 (set (attr "mode")
19855 (cond [(eq_attr "alternative" "0,1")
19856 (if_then_else
19857 (ne (symbol_ref "optimize_size")
19858 (const_int 0))
19859 (const_string "V4SF")
19860 (const_string "TI"))
19861 (eq_attr "alternative" "2")
19862 (if_then_else
19863 (ne (symbol_ref "optimize_size")
19864 (const_int 0))
19865 (const_string "V4SF")
19866 (const_string "TI"))]
19867 (const_string "TI")))])
19868
19869 (define_insn "*movti_rex64"
19870 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19871 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19872 "TARGET_64BIT
19873 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19874 {
19875 switch (which_alternative)
19876 {
19877 case 0:
19878 case 1:
19879 return "#";
19880 case 2:
19881 if (get_attr_mode (insn) == MODE_V4SF)
19882 return "xorps\t%0, %0";
19883 else
19884 return "pxor\t%0, %0";
19885 case 3:
19886 case 4:
19887 if (get_attr_mode (insn) == MODE_V4SF)
19888 return "movaps\t{%1, %0|%0, %1}";
19889 else
19890 return "movdqa\t{%1, %0|%0, %1}";
19891 default:
19892 abort ();
19893 }
19894 }
19895 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19896 (set (attr "mode")
19897 (cond [(eq_attr "alternative" "2,3")
19898 (if_then_else
19899 (ne (symbol_ref "optimize_size")
19900 (const_int 0))
19901 (const_string "V4SF")
19902 (const_string "TI"))
19903 (eq_attr "alternative" "4")
19904 (if_then_else
19905 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19906 (const_int 0))
19907 (ne (symbol_ref "optimize_size")
19908 (const_int 0)))
19909 (const_string "V4SF")
19910 (const_string "TI"))]
19911 (const_string "DI")))])
19912
19913 (define_split
19914 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19915 (match_operand:TI 1 "general_operand" ""))]
19916 "reload_completed && !SSE_REG_P (operands[0])
19917 && !SSE_REG_P (operands[1])"
19918 [(const_int 0)]
19919 "ix86_split_long_move (operands); DONE;")
19920
19921 ;; These two patterns are useful for specifying exactly whether to use
19922 ;; movaps or movups
19923 (define_expand "sse_movaps"
19924 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19925 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19926 UNSPEC_MOVA))]
19927 "TARGET_SSE"
19928 {
19929 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19930 {
19931 rtx tmp = gen_reg_rtx (V4SFmode);
19932 emit_insn (gen_sse_movaps (tmp, operands[1]));
19933 emit_move_insn (operands[0], tmp);
19934 DONE;
19935 }
19936 })
19937
19938 (define_insn "*sse_movaps_1"
19939 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19940 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19941 UNSPEC_MOVA))]
19942 "TARGET_SSE
19943 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19944 "movaps\t{%1, %0|%0, %1}"
19945 [(set_attr "type" "ssemov,ssemov")
19946 (set_attr "mode" "V4SF")])
19947
19948 (define_expand "sse_movups"
19949 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19950 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19951 UNSPEC_MOVU))]
19952 "TARGET_SSE"
19953 {
19954 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19955 {
19956 rtx tmp = gen_reg_rtx (V4SFmode);
19957 emit_insn (gen_sse_movups (tmp, operands[1]));
19958 emit_move_insn (operands[0], tmp);
19959 DONE;
19960 }
19961 })
19962
19963 (define_insn "*sse_movups_1"
19964 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19965 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19966 UNSPEC_MOVU))]
19967 "TARGET_SSE
19968 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19969 "movups\t{%1, %0|%0, %1}"
19970 [(set_attr "type" "ssecvt,ssecvt")
19971 (set_attr "mode" "V4SF")])
19972
19973 ;; SSE Strange Moves.
19974
19975 (define_insn "sse_movmskps"
19976 [(set (match_operand:SI 0 "register_operand" "=r")
19977 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19978 UNSPEC_MOVMSK))]
19979 "TARGET_SSE"
19980 "movmskps\t{%1, %0|%0, %1}"
19981 [(set_attr "type" "ssecvt")
19982 (set_attr "mode" "V4SF")])
19983
19984 (define_insn "mmx_pmovmskb"
19985 [(set (match_operand:SI 0 "register_operand" "=r")
19986 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19987 UNSPEC_MOVMSK))]
19988 "TARGET_SSE || TARGET_3DNOW_A"
19989 "pmovmskb\t{%1, %0|%0, %1}"
19990 [(set_attr "type" "ssecvt")
19991 (set_attr "mode" "V4SF")])
19992
19993
19994 (define_insn "mmx_maskmovq"
19995 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19996 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19997 (match_operand:V8QI 2 "register_operand" "y")]
19998 UNSPEC_MASKMOV))]
19999 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20000 ;; @@@ check ordering of operands in intel/nonintel syntax
20001 "maskmovq\t{%2, %1|%1, %2}"
20002 [(set_attr "type" "mmxcvt")
20003 (set_attr "mode" "DI")])
20004
20005 (define_insn "mmx_maskmovq_rex"
20006 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20007 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20008 (match_operand:V8QI 2 "register_operand" "y")]
20009 UNSPEC_MASKMOV))]
20010 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20011 ;; @@@ check ordering of operands in intel/nonintel syntax
20012 "maskmovq\t{%2, %1|%1, %2}"
20013 [(set_attr "type" "mmxcvt")
20014 (set_attr "mode" "DI")])
20015
20016 (define_insn "sse_movntv4sf"
20017 [(set (match_operand:V4SF 0 "memory_operand" "=m")
20018 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20019 UNSPEC_MOVNT))]
20020 "TARGET_SSE"
20021 "movntps\t{%1, %0|%0, %1}"
20022 [(set_attr "type" "ssemov")
20023 (set_attr "mode" "V4SF")])
20024
20025 (define_insn "sse_movntdi"
20026 [(set (match_operand:DI 0 "memory_operand" "=m")
20027 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20028 UNSPEC_MOVNT))]
20029 "TARGET_SSE || TARGET_3DNOW_A"
20030 "movntq\t{%1, %0|%0, %1}"
20031 [(set_attr "type" "mmxmov")
20032 (set_attr "mode" "DI")])
20033
20034 (define_insn "sse_movhlps"
20035 [(set (match_operand:V4SF 0 "register_operand" "=x")
20036 (vec_merge:V4SF
20037 (match_operand:V4SF 1 "register_operand" "0")
20038 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20039 (parallel [(const_int 2)
20040 (const_int 3)
20041 (const_int 0)
20042 (const_int 1)]))
20043 (const_int 3)))]
20044 "TARGET_SSE"
20045 "movhlps\t{%2, %0|%0, %2}"
20046 [(set_attr "type" "ssecvt")
20047 (set_attr "mode" "V4SF")])
20048
20049 (define_insn "sse_movlhps"
20050 [(set (match_operand:V4SF 0 "register_operand" "=x")
20051 (vec_merge:V4SF
20052 (match_operand:V4SF 1 "register_operand" "0")
20053 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20054 (parallel [(const_int 2)
20055 (const_int 3)
20056 (const_int 0)
20057 (const_int 1)]))
20058 (const_int 12)))]
20059 "TARGET_SSE"
20060 "movlhps\t{%2, %0|%0, %2}"
20061 [(set_attr "type" "ssecvt")
20062 (set_attr "mode" "V4SF")])
20063
20064 (define_insn "sse_movhps"
20065 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20066 (vec_merge:V4SF
20067 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20068 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20069 (const_int 12)))]
20070 "TARGET_SSE
20071 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20072 "movhps\t{%2, %0|%0, %2}"
20073 [(set_attr "type" "ssecvt")
20074 (set_attr "mode" "V4SF")])
20075
20076 (define_insn "sse_movlps"
20077 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20078 (vec_merge:V4SF
20079 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20080 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20081 (const_int 3)))]
20082 "TARGET_SSE
20083 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20084 "movlps\t{%2, %0|%0, %2}"
20085 [(set_attr "type" "ssecvt")
20086 (set_attr "mode" "V4SF")])
20087
20088 (define_expand "sse_loadss"
20089 [(match_operand:V4SF 0 "register_operand" "")
20090 (match_operand:SF 1 "memory_operand" "")]
20091 "TARGET_SSE"
20092 {
20093 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20094 CONST0_RTX (V4SFmode)));
20095 DONE;
20096 })
20097
20098 (define_insn "sse_loadss_1"
20099 [(set (match_operand:V4SF 0 "register_operand" "=x")
20100 (vec_merge:V4SF
20101 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20102 (match_operand:V4SF 2 "const0_operand" "X")
20103 (const_int 1)))]
20104 "TARGET_SSE"
20105 "movss\t{%1, %0|%0, %1}"
20106 [(set_attr "type" "ssemov")
20107 (set_attr "mode" "SF")])
20108
20109 (define_insn "sse_movss"
20110 [(set (match_operand:V4SF 0 "register_operand" "=x")
20111 (vec_merge:V4SF
20112 (match_operand:V4SF 1 "register_operand" "0")
20113 (match_operand:V4SF 2 "register_operand" "x")
20114 (const_int 1)))]
20115 "TARGET_SSE"
20116 "movss\t{%2, %0|%0, %2}"
20117 [(set_attr "type" "ssemov")
20118 (set_attr "mode" "SF")])
20119
20120 (define_insn "sse_storess"
20121 [(set (match_operand:SF 0 "memory_operand" "=m")
20122 (vec_select:SF
20123 (match_operand:V4SF 1 "register_operand" "x")
20124 (parallel [(const_int 0)])))]
20125 "TARGET_SSE"
20126 "movss\t{%1, %0|%0, %1}"
20127 [(set_attr "type" "ssemov")
20128 (set_attr "mode" "SF")])
20129
20130 (define_insn "sse_shufps"
20131 [(set (match_operand:V4SF 0 "register_operand" "=x")
20132 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20133 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20134 (match_operand:SI 3 "immediate_operand" "i")]
20135 UNSPEC_SHUFFLE))]
20136 "TARGET_SSE"
20137 ;; @@@ check operand order for intel/nonintel syntax
20138 "shufps\t{%3, %2, %0|%0, %2, %3}"
20139 [(set_attr "type" "ssecvt")
20140 (set_attr "mode" "V4SF")])
20141
20142
20143 ;; SSE arithmetic
20144
20145 (define_insn "addv4sf3"
20146 [(set (match_operand:V4SF 0 "register_operand" "=x")
20147 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20148 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20149 "TARGET_SSE"
20150 "addps\t{%2, %0|%0, %2}"
20151 [(set_attr "type" "sseadd")
20152 (set_attr "mode" "V4SF")])
20153
20154 (define_insn "vmaddv4sf3"
20155 [(set (match_operand:V4SF 0 "register_operand" "=x")
20156 (vec_merge:V4SF
20157 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20158 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20159 (match_dup 1)
20160 (const_int 1)))]
20161 "TARGET_SSE"
20162 "addss\t{%2, %0|%0, %2}"
20163 [(set_attr "type" "sseadd")
20164 (set_attr "mode" "SF")])
20165
20166 (define_insn "subv4sf3"
20167 [(set (match_operand:V4SF 0 "register_operand" "=x")
20168 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20169 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20170 "TARGET_SSE"
20171 "subps\t{%2, %0|%0, %2}"
20172 [(set_attr "type" "sseadd")
20173 (set_attr "mode" "V4SF")])
20174
20175 (define_insn "vmsubv4sf3"
20176 [(set (match_operand:V4SF 0 "register_operand" "=x")
20177 (vec_merge:V4SF
20178 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20179 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20180 (match_dup 1)
20181 (const_int 1)))]
20182 "TARGET_SSE"
20183 "subss\t{%2, %0|%0, %2}"
20184 [(set_attr "type" "sseadd")
20185 (set_attr "mode" "SF")])
20186
20187 (define_insn "mulv4sf3"
20188 [(set (match_operand:V4SF 0 "register_operand" "=x")
20189 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20190 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20191 "TARGET_SSE"
20192 "mulps\t{%2, %0|%0, %2}"
20193 [(set_attr "type" "ssemul")
20194 (set_attr "mode" "V4SF")])
20195
20196 (define_insn "vmmulv4sf3"
20197 [(set (match_operand:V4SF 0 "register_operand" "=x")
20198 (vec_merge:V4SF
20199 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20200 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20201 (match_dup 1)
20202 (const_int 1)))]
20203 "TARGET_SSE"
20204 "mulss\t{%2, %0|%0, %2}"
20205 [(set_attr "type" "ssemul")
20206 (set_attr "mode" "SF")])
20207
20208 (define_insn "divv4sf3"
20209 [(set (match_operand:V4SF 0 "register_operand" "=x")
20210 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20211 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20212 "TARGET_SSE"
20213 "divps\t{%2, %0|%0, %2}"
20214 [(set_attr "type" "ssediv")
20215 (set_attr "mode" "V4SF")])
20216
20217 (define_insn "vmdivv4sf3"
20218 [(set (match_operand:V4SF 0 "register_operand" "=x")
20219 (vec_merge:V4SF
20220 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20221 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20222 (match_dup 1)
20223 (const_int 1)))]
20224 "TARGET_SSE"
20225 "divss\t{%2, %0|%0, %2}"
20226 [(set_attr "type" "ssediv")
20227 (set_attr "mode" "SF")])
20228
20229
20230 ;; SSE square root/reciprocal
20231
20232 (define_insn "rcpv4sf2"
20233 [(set (match_operand:V4SF 0 "register_operand" "=x")
20234 (unspec:V4SF
20235 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20236 "TARGET_SSE"
20237 "rcpps\t{%1, %0|%0, %1}"
20238 [(set_attr "type" "sse")
20239 (set_attr "mode" "V4SF")])
20240
20241 (define_insn "vmrcpv4sf2"
20242 [(set (match_operand:V4SF 0 "register_operand" "=x")
20243 (vec_merge:V4SF
20244 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20245 UNSPEC_RCP)
20246 (match_operand:V4SF 2 "register_operand" "0")
20247 (const_int 1)))]
20248 "TARGET_SSE"
20249 "rcpss\t{%1, %0|%0, %1}"
20250 [(set_attr "type" "sse")
20251 (set_attr "mode" "SF")])
20252
20253 (define_insn "rsqrtv4sf2"
20254 [(set (match_operand:V4SF 0 "register_operand" "=x")
20255 (unspec:V4SF
20256 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20257 "TARGET_SSE"
20258 "rsqrtps\t{%1, %0|%0, %1}"
20259 [(set_attr "type" "sse")
20260 (set_attr "mode" "V4SF")])
20261
20262 (define_insn "vmrsqrtv4sf2"
20263 [(set (match_operand:V4SF 0 "register_operand" "=x")
20264 (vec_merge:V4SF
20265 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20266 UNSPEC_RSQRT)
20267 (match_operand:V4SF 2 "register_operand" "0")
20268 (const_int 1)))]
20269 "TARGET_SSE"
20270 "rsqrtss\t{%1, %0|%0, %1}"
20271 [(set_attr "type" "sse")
20272 (set_attr "mode" "SF")])
20273
20274 (define_insn "sqrtv4sf2"
20275 [(set (match_operand:V4SF 0 "register_operand" "=x")
20276 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20277 "TARGET_SSE"
20278 "sqrtps\t{%1, %0|%0, %1}"
20279 [(set_attr "type" "sse")
20280 (set_attr "mode" "V4SF")])
20281
20282 (define_insn "vmsqrtv4sf2"
20283 [(set (match_operand:V4SF 0 "register_operand" "=x")
20284 (vec_merge:V4SF
20285 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20286 (match_operand:V4SF 2 "register_operand" "0")
20287 (const_int 1)))]
20288 "TARGET_SSE"
20289 "sqrtss\t{%1, %0|%0, %1}"
20290 [(set_attr "type" "sse")
20291 (set_attr "mode" "SF")])
20292
20293 ;; SSE logical operations.
20294
20295 ;; SSE defines logical operations on floating point values. This brings
20296 ;; interesting challenge to RTL representation where logicals are only valid
20297 ;; on integral types. We deal with this by representing the floating point
20298 ;; logical as logical on arguments casted to TImode as this is what hardware
20299 ;; really does. Unfortunately hardware requires the type information to be
20300 ;; present and thus we must avoid subregs from being simplified and eliminated
20301 ;; in later compilation phases.
20302 ;;
20303 ;; We have following variants from each instruction:
20304 ;; sse_andsf3 - the operation taking V4SF vector operands
20305 ;; and doing TImode cast on them
20306 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20307 ;; TImode, since backend insist on eliminating casts
20308 ;; on memory operands
20309 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20310 ;; We can not accept memory operand here as instruction reads
20311 ;; whole scalar. This is generated only post reload by GCC
20312 ;; scalar float operations that expands to logicals (fabs)
20313 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20314 ;; memory operand. Eventually combine can be able
20315 ;; to synthesize these using splitter.
20316 ;; sse2_anddf3, *sse2_anddf3_memory
20317 ;;
20318 ;;
20319 ;; These are not called andti3 etc. because we really really don't want
20320 ;; the compiler to widen DImode ands to TImode ands and then try to move
20321 ;; into DImode subregs of SSE registers, and them together, and move out
20322 ;; of DImode subregs again!
20323 ;; SSE1 single precision floating point logical operation
20324 (define_expand "sse_andv4sf3"
20325 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20326 (and: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_andv4sf3"
20332 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20333 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20334 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20335 "TARGET_SSE
20336 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20337 "andps\t{%2, %0|%0, %2}"
20338 [(set_attr "type" "sselog")
20339 (set_attr "mode" "V4SF")])
20340
20341 (define_insn "*sse_andsf3"
20342 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20343 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20344 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20345 "TARGET_SSE
20346 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20347 "andps\t{%2, %0|%0, %2}"
20348 [(set_attr "type" "sselog")
20349 (set_attr "mode" "V4SF")])
20350
20351 (define_expand "sse_nandv4sf3"
20352 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20353 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
20354 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20355 "TARGET_SSE"
20356 "")
20357
20358 (define_insn "*sse_nandv4sf3"
20359 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20360 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20361 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20362 "TARGET_SSE"
20363 "andnps\t{%2, %0|%0, %2}"
20364 [(set_attr "type" "sselog")
20365 (set_attr "mode" "V4SF")])
20366
20367 (define_insn "*sse_nandsf3"
20368 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20369 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20370 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20371 "TARGET_SSE"
20372 "andnps\t{%2, %0|%0, %2}"
20373 [(set_attr "type" "sselog")
20374 (set_attr "mode" "V4SF")])
20375
20376 (define_expand "sse_iorv4sf3"
20377 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20378 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20379 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20380 "TARGET_SSE"
20381 "")
20382
20383 (define_insn "*sse_iorv4sf3"
20384 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20385 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20386 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20387 "TARGET_SSE
20388 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20389 "orps\t{%2, %0|%0, %2}"
20390 [(set_attr "type" "sselog")
20391 (set_attr "mode" "V4SF")])
20392
20393 (define_insn "*sse_iorsf3"
20394 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20395 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20396 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20397 "TARGET_SSE
20398 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20399 "orps\t{%2, %0|%0, %2}"
20400 [(set_attr "type" "sselog")
20401 (set_attr "mode" "V4SF")])
20402
20403 (define_expand "sse_xorv4sf3"
20404 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20405 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20406 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20407 "TARGET_SSE
20408 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20409 "")
20410
20411 (define_insn "*sse_xorv4sf3"
20412 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20413 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20414 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20415 "TARGET_SSE
20416 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20417 "xorps\t{%2, %0|%0, %2}"
20418 [(set_attr "type" "sselog")
20419 (set_attr "mode" "V4SF")])
20420
20421 (define_insn "*sse_xorsf3"
20422 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20423 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20424 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20425 "TARGET_SSE
20426 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20427 "xorps\t{%2, %0|%0, %2}"
20428 [(set_attr "type" "sselog")
20429 (set_attr "mode" "V4SF")])
20430
20431 ;; SSE2 double precision floating point logical operation
20432
20433 (define_expand "sse2_andv2df3"
20434 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20435 (and: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_andv2df3"
20441 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20442 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20443 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20444 "TARGET_SSE2
20445 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20446 "andpd\t{%2, %0|%0, %2}"
20447 [(set_attr "type" "sselog")
20448 (set_attr "mode" "V2DF")])
20449
20450 (define_insn "*sse2_andv2df3"
20451 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20452 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20453 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20454 "TARGET_SSE2
20455 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20456 "andpd\t{%2, %0|%0, %2}"
20457 [(set_attr "type" "sselog")
20458 (set_attr "mode" "V2DF")])
20459
20460 (define_expand "sse2_nandv2df3"
20461 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20462 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
20463 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20464 "TARGET_SSE2"
20465 "")
20466
20467 (define_insn "*sse2_nandv2df3"
20468 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20469 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20470 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20471 "TARGET_SSE2"
20472 "andnpd\t{%2, %0|%0, %2}"
20473 [(set_attr "type" "sselog")
20474 (set_attr "mode" "V2DF")])
20475
20476 (define_insn "*sse_nandti3_df"
20477 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
20478 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20479 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
20480 "TARGET_SSE2"
20481 "andnpd\t{%2, %0|%0, %2}"
20482 [(set_attr "type" "sselog")
20483 (set_attr "mode" "V2DF")])
20484
20485 (define_expand "sse2_iorv2df3"
20486 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20487 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20488 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20489 "TARGET_SSE2"
20490 "")
20491
20492 (define_insn "*sse2_iorv2df3"
20493 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20494 (ior: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 "orpd\t{%2, %0|%0, %2}"
20499 [(set_attr "type" "sselog")
20500 (set_attr "mode" "V2DF")])
20501
20502 (define_insn "*sse2_iordf3"
20503 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20504 (ior: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 "orpd\t{%2, %0|%0, %2}"
20509 [(set_attr "type" "sselog")
20510 (set_attr "mode" "V2DF")])
20511
20512 (define_expand "sse2_xorv2df3"
20513 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20514 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
20515 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20516 "TARGET_SSE2"
20517 "")
20518
20519 (define_insn "*sse2_xorv2df3"
20520 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20521 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20522 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20523 "TARGET_SSE2
20524 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20525 "xorpd\t{%2, %0|%0, %2}"
20526 [(set_attr "type" "sselog")
20527 (set_attr "mode" "V2DF")])
20528
20529 (define_insn "*sse2_xordf3"
20530 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20531 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20532 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20533 "TARGET_SSE2
20534 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20535 "xorpd\t{%2, %0|%0, %2}"
20536 [(set_attr "type" "sselog")
20537 (set_attr "mode" "V2DF")])
20538
20539 ;; SSE2 integral logicals. These patterns must always come after floating
20540 ;; point ones since we don't want compiler to use integer opcodes on floating
20541 ;; point SSE values to avoid matching of subregs in the match_operand.
20542 (define_insn "*sse2_andti3"
20543 [(set (match_operand:TI 0 "register_operand" "=x")
20544 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20545 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20546 "TARGET_SSE2
20547 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20548 "pand\t{%2, %0|%0, %2}"
20549 [(set_attr "type" "sselog")
20550 (set_attr "mode" "TI")])
20551
20552 (define_insn "sse2_andv2di3"
20553 [(set (match_operand:V2DI 0 "register_operand" "=x")
20554 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20555 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20556 "TARGET_SSE2
20557 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20558 "pand\t{%2, %0|%0, %2}"
20559 [(set_attr "type" "sselog")
20560 (set_attr "mode" "TI")])
20561
20562 (define_insn "*sse2_nandti3"
20563 [(set (match_operand:TI 0 "register_operand" "=x")
20564 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20565 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20566 "TARGET_SSE2"
20567 "pandn\t{%2, %0|%0, %2}"
20568 [(set_attr "type" "sselog")
20569 (set_attr "mode" "TI")])
20570
20571 (define_insn "sse2_nandv2di3"
20572 [(set (match_operand:V2DI 0 "register_operand" "=x")
20573 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20574 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20575 "TARGET_SSE2
20576 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20577 "pandn\t{%2, %0|%0, %2}"
20578 [(set_attr "type" "sselog")
20579 (set_attr "mode" "TI")])
20580
20581 (define_insn "*sse2_iorti3"
20582 [(set (match_operand:TI 0 "register_operand" "=x")
20583 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20584 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20585 "TARGET_SSE2
20586 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20587 "por\t{%2, %0|%0, %2}"
20588 [(set_attr "type" "sselog")
20589 (set_attr "mode" "TI")])
20590
20591 (define_insn "sse2_iorv2di3"
20592 [(set (match_operand:V2DI 0 "register_operand" "=x")
20593 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20594 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20595 "TARGET_SSE2
20596 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20597 "por\t{%2, %0|%0, %2}"
20598 [(set_attr "type" "sselog")
20599 (set_attr "mode" "TI")])
20600
20601 (define_insn "*sse2_xorti3"
20602 [(set (match_operand:TI 0 "register_operand" "=x")
20603 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20604 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20605 "TARGET_SSE2
20606 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20607 "pxor\t{%2, %0|%0, %2}"
20608 [(set_attr "type" "sselog")
20609 (set_attr "mode" "TI")])
20610
20611 (define_insn "sse2_xorv2di3"
20612 [(set (match_operand:V2DI 0 "register_operand" "=x")
20613 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20614 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20615 "TARGET_SSE2
20616 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20617 "pxor\t{%2, %0|%0, %2}"
20618 [(set_attr "type" "sselog")
20619 (set_attr "mode" "TI")])
20620
20621 ;; Use xor, but don't show input operands so they aren't live before
20622 ;; this insn.
20623 (define_insn "sse_clrv4sf"
20624 [(set (match_operand:V4SF 0 "register_operand" "=x")
20625 (match_operand:V4SF 1 "const0_operand" "X"))]
20626 "TARGET_SSE"
20627 {
20628 if (get_attr_mode (insn) == MODE_TI)
20629 return "pxor\t{%0, %0|%0, %0}";
20630 else
20631 return "xorps\t{%0, %0|%0, %0}";
20632 }
20633 [(set_attr "type" "sselog")
20634 (set_attr "memory" "none")
20635 (set (attr "mode")
20636 (if_then_else
20637 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20638 (const_int 0))
20639 (ne (symbol_ref "TARGET_SSE2")
20640 (const_int 0)))
20641 (eq (symbol_ref "optimize_size")
20642 (const_int 0)))
20643 (const_string "TI")
20644 (const_string "V4SF")))])
20645
20646 ;; Use xor, but don't show input operands so they aren't live before
20647 ;; this insn.
20648 (define_insn "sse_clrv2df"
20649 [(set (match_operand:V2DF 0 "register_operand" "=x")
20650 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20651 "TARGET_SSE2"
20652 "xorpd\t{%0, %0|%0, %0}"
20653 [(set_attr "type" "sselog")
20654 (set_attr "memory" "none")
20655 (set_attr "mode" "V4SF")])
20656
20657 ;; SSE mask-generating compares
20658
20659 (define_insn "maskcmpv4sf3"
20660 [(set (match_operand:V4SI 0 "register_operand" "=x")
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 "TARGET_SSE"
20665 "cmp%D3ps\t{%2, %0|%0, %2}"
20666 [(set_attr "type" "ssecmp")
20667 (set_attr "mode" "V4SF")])
20668
20669 (define_insn "maskncmpv4sf3"
20670 [(set (match_operand:V4SI 0 "register_operand" "=x")
20671 (not:V4SI
20672 (match_operator:V4SI 3 "sse_comparison_operator"
20673 [(match_operand:V4SF 1 "register_operand" "0")
20674 (match_operand:V4SF 2 "register_operand" "x")])))]
20675 "TARGET_SSE"
20676 {
20677 if (GET_CODE (operands[3]) == UNORDERED)
20678 return "cmpordps\t{%2, %0|%0, %2}";
20679 else
20680 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20681 }
20682 [(set_attr "type" "ssecmp")
20683 (set_attr "mode" "V4SF")])
20684
20685 (define_insn "vmmaskcmpv4sf3"
20686 [(set (match_operand:V4SI 0 "register_operand" "=x")
20687 (vec_merge:V4SI
20688 (match_operator:V4SI 3 "sse_comparison_operator"
20689 [(match_operand:V4SF 1 "register_operand" "0")
20690 (match_operand:V4SF 2 "register_operand" "x")])
20691 (subreg:V4SI (match_dup 1) 0)
20692 (const_int 1)))]
20693 "TARGET_SSE"
20694 "cmp%D3ss\t{%2, %0|%0, %2}"
20695 [(set_attr "type" "ssecmp")
20696 (set_attr "mode" "SF")])
20697
20698 (define_insn "vmmaskncmpv4sf3"
20699 [(set (match_operand:V4SI 0 "register_operand" "=x")
20700 (vec_merge:V4SI
20701 (not:V4SI
20702 (match_operator:V4SI 3 "sse_comparison_operator"
20703 [(match_operand:V4SF 1 "register_operand" "0")
20704 (match_operand:V4SF 2 "register_operand" "x")]))
20705 (subreg:V4SI (match_dup 1) 0)
20706 (const_int 1)))]
20707 "TARGET_SSE"
20708 {
20709 if (GET_CODE (operands[3]) == UNORDERED)
20710 return "cmpordss\t{%2, %0|%0, %2}";
20711 else
20712 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20713 }
20714 [(set_attr "type" "ssecmp")
20715 (set_attr "mode" "SF")])
20716
20717 (define_insn "sse_comi"
20718 [(set (reg:CCFP 17)
20719 (compare:CCFP (vec_select:SF
20720 (match_operand:V4SF 0 "register_operand" "x")
20721 (parallel [(const_int 0)]))
20722 (vec_select:SF
20723 (match_operand:V4SF 1 "register_operand" "x")
20724 (parallel [(const_int 0)]))))]
20725 "TARGET_SSE"
20726 "comiss\t{%1, %0|%0, %1}"
20727 [(set_attr "type" "ssecomi")
20728 (set_attr "mode" "SF")])
20729
20730 (define_insn "sse_ucomi"
20731 [(set (reg:CCFPU 17)
20732 (compare:CCFPU (vec_select:SF
20733 (match_operand:V4SF 0 "register_operand" "x")
20734 (parallel [(const_int 0)]))
20735 (vec_select:SF
20736 (match_operand:V4SF 1 "register_operand" "x")
20737 (parallel [(const_int 0)]))))]
20738 "TARGET_SSE"
20739 "ucomiss\t{%1, %0|%0, %1}"
20740 [(set_attr "type" "ssecomi")
20741 (set_attr "mode" "SF")])
20742
20743
20744 ;; SSE unpack
20745
20746 (define_insn "sse_unpckhps"
20747 [(set (match_operand:V4SF 0 "register_operand" "=x")
20748 (vec_merge:V4SF
20749 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20750 (parallel [(const_int 2)
20751 (const_int 0)
20752 (const_int 3)
20753 (const_int 1)]))
20754 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20755 (parallel [(const_int 0)
20756 (const_int 2)
20757 (const_int 1)
20758 (const_int 3)]))
20759 (const_int 5)))]
20760 "TARGET_SSE"
20761 "unpckhps\t{%2, %0|%0, %2}"
20762 [(set_attr "type" "ssecvt")
20763 (set_attr "mode" "V4SF")])
20764
20765 (define_insn "sse_unpcklps"
20766 [(set (match_operand:V4SF 0 "register_operand" "=x")
20767 (vec_merge:V4SF
20768 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20769 (parallel [(const_int 0)
20770 (const_int 2)
20771 (const_int 1)
20772 (const_int 3)]))
20773 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20774 (parallel [(const_int 2)
20775 (const_int 0)
20776 (const_int 3)
20777 (const_int 1)]))
20778 (const_int 5)))]
20779 "TARGET_SSE"
20780 "unpcklps\t{%2, %0|%0, %2}"
20781 [(set_attr "type" "ssecvt")
20782 (set_attr "mode" "V4SF")])
20783
20784
20785 ;; SSE min/max
20786
20787 (define_insn "smaxv4sf3"
20788 [(set (match_operand:V4SF 0 "register_operand" "=x")
20789 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20790 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20791 "TARGET_SSE"
20792 "maxps\t{%2, %0|%0, %2}"
20793 [(set_attr "type" "sse")
20794 (set_attr "mode" "V4SF")])
20795
20796 (define_insn "vmsmaxv4sf3"
20797 [(set (match_operand:V4SF 0 "register_operand" "=x")
20798 (vec_merge:V4SF
20799 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20800 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20801 (match_dup 1)
20802 (const_int 1)))]
20803 "TARGET_SSE"
20804 "maxss\t{%2, %0|%0, %2}"
20805 [(set_attr "type" "sse")
20806 (set_attr "mode" "SF")])
20807
20808 (define_insn "sminv4sf3"
20809 [(set (match_operand:V4SF 0 "register_operand" "=x")
20810 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20811 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20812 "TARGET_SSE"
20813 "minps\t{%2, %0|%0, %2}"
20814 [(set_attr "type" "sse")
20815 (set_attr "mode" "V4SF")])
20816
20817 (define_insn "vmsminv4sf3"
20818 [(set (match_operand:V4SF 0 "register_operand" "=x")
20819 (vec_merge:V4SF
20820 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20821 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20822 (match_dup 1)
20823 (const_int 1)))]
20824 "TARGET_SSE"
20825 "minss\t{%2, %0|%0, %2}"
20826 [(set_attr "type" "sse")
20827 (set_attr "mode" "SF")])
20828
20829 ;; SSE <-> integer/MMX conversions
20830
20831 (define_insn "cvtpi2ps"
20832 [(set (match_operand:V4SF 0 "register_operand" "=x")
20833 (vec_merge:V4SF
20834 (match_operand:V4SF 1 "register_operand" "0")
20835 (vec_duplicate:V4SF
20836 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20837 (const_int 12)))]
20838 "TARGET_SSE"
20839 "cvtpi2ps\t{%2, %0|%0, %2}"
20840 [(set_attr "type" "ssecvt")
20841 (set_attr "mode" "V4SF")])
20842
20843 (define_insn "cvtps2pi"
20844 [(set (match_operand:V2SI 0 "register_operand" "=y")
20845 (vec_select:V2SI
20846 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20847 (parallel [(const_int 0) (const_int 1)])))]
20848 "TARGET_SSE"
20849 "cvtps2pi\t{%1, %0|%0, %1}"
20850 [(set_attr "type" "ssecvt")
20851 (set_attr "mode" "V4SF")])
20852
20853 (define_insn "cvttps2pi"
20854 [(set (match_operand:V2SI 0 "register_operand" "=y")
20855 (vec_select:V2SI
20856 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20857 UNSPEC_FIX)
20858 (parallel [(const_int 0) (const_int 1)])))]
20859 "TARGET_SSE"
20860 "cvttps2pi\t{%1, %0|%0, %1}"
20861 [(set_attr "type" "ssecvt")
20862 (set_attr "mode" "SF")])
20863
20864 (define_insn "cvtsi2ss"
20865 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20866 (vec_merge:V4SF
20867 (match_operand:V4SF 1 "register_operand" "0,0")
20868 (vec_duplicate:V4SF
20869 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20870 (const_int 14)))]
20871 "TARGET_SSE"
20872 "cvtsi2ss\t{%2, %0|%0, %2}"
20873 [(set_attr "type" "sseicvt")
20874 (set_attr "athlon_decode" "vector,double")
20875 (set_attr "mode" "SF")])
20876
20877 (define_insn "cvtsi2ssq"
20878 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20879 (vec_merge:V4SF
20880 (match_operand:V4SF 1 "register_operand" "0,0")
20881 (vec_duplicate:V4SF
20882 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20883 (const_int 14)))]
20884 "TARGET_SSE && TARGET_64BIT"
20885 "cvtsi2ssq\t{%2, %0|%0, %2}"
20886 [(set_attr "type" "sseicvt")
20887 (set_attr "athlon_decode" "vector,double")
20888 (set_attr "mode" "SF")])
20889
20890 (define_insn "cvtss2si"
20891 [(set (match_operand:SI 0 "register_operand" "=r,r")
20892 (vec_select:SI
20893 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20894 (parallel [(const_int 0)])))]
20895 "TARGET_SSE"
20896 "cvtss2si\t{%1, %0|%0, %1}"
20897 [(set_attr "type" "sseicvt")
20898 (set_attr "athlon_decode" "double,vector")
20899 (set_attr "mode" "SI")])
20900
20901 (define_insn "cvtss2siq"
20902 [(set (match_operand:DI 0 "register_operand" "=r,r")
20903 (vec_select:DI
20904 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20905 (parallel [(const_int 0)])))]
20906 "TARGET_SSE"
20907 "cvtss2siq\t{%1, %0|%0, %1}"
20908 [(set_attr "type" "sseicvt")
20909 (set_attr "athlon_decode" "double,vector")
20910 (set_attr "mode" "DI")])
20911
20912 (define_insn "cvttss2si"
20913 [(set (match_operand:SI 0 "register_operand" "=r,r")
20914 (vec_select:SI
20915 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20916 UNSPEC_FIX)
20917 (parallel [(const_int 0)])))]
20918 "TARGET_SSE"
20919 "cvttss2si\t{%1, %0|%0, %1}"
20920 [(set_attr "type" "sseicvt")
20921 (set_attr "mode" "SF")
20922 (set_attr "athlon_decode" "double,vector")])
20923
20924 (define_insn "cvttss2siq"
20925 [(set (match_operand:DI 0 "register_operand" "=r,r")
20926 (vec_select:DI
20927 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20928 UNSPEC_FIX)
20929 (parallel [(const_int 0)])))]
20930 "TARGET_SSE && TARGET_64BIT"
20931 "cvttss2siq\t{%1, %0|%0, %1}"
20932 [(set_attr "type" "sseicvt")
20933 (set_attr "mode" "SF")
20934 (set_attr "athlon_decode" "double,vector")])
20935
20936
20937 ;; MMX insns
20938
20939 ;; MMX arithmetic
20940
20941 (define_insn "addv8qi3"
20942 [(set (match_operand:V8QI 0 "register_operand" "=y")
20943 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20944 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20945 "TARGET_MMX"
20946 "paddb\t{%2, %0|%0, %2}"
20947 [(set_attr "type" "mmxadd")
20948 (set_attr "mode" "DI")])
20949
20950 (define_insn "addv4hi3"
20951 [(set (match_operand:V4HI 0 "register_operand" "=y")
20952 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20953 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20954 "TARGET_MMX"
20955 "paddw\t{%2, %0|%0, %2}"
20956 [(set_attr "type" "mmxadd")
20957 (set_attr "mode" "DI")])
20958
20959 (define_insn "addv2si3"
20960 [(set (match_operand:V2SI 0 "register_operand" "=y")
20961 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20962 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20963 "TARGET_MMX"
20964 "paddd\t{%2, %0|%0, %2}"
20965 [(set_attr "type" "mmxadd")
20966 (set_attr "mode" "DI")])
20967
20968 (define_insn "mmx_adddi3"
20969 [(set (match_operand:DI 0 "register_operand" "=y")
20970 (unspec:DI
20971 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20972 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20973 UNSPEC_NOP))]
20974 "TARGET_MMX"
20975 "paddq\t{%2, %0|%0, %2}"
20976 [(set_attr "type" "mmxadd")
20977 (set_attr "mode" "DI")])
20978
20979 (define_insn "ssaddv8qi3"
20980 [(set (match_operand:V8QI 0 "register_operand" "=y")
20981 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20982 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20983 "TARGET_MMX"
20984 "paddsb\t{%2, %0|%0, %2}"
20985 [(set_attr "type" "mmxadd")
20986 (set_attr "mode" "DI")])
20987
20988 (define_insn "ssaddv4hi3"
20989 [(set (match_operand:V4HI 0 "register_operand" "=y")
20990 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20991 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20992 "TARGET_MMX"
20993 "paddsw\t{%2, %0|%0, %2}"
20994 [(set_attr "type" "mmxadd")
20995 (set_attr "mode" "DI")])
20996
20997 (define_insn "usaddv8qi3"
20998 [(set (match_operand:V8QI 0 "register_operand" "=y")
20999 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21000 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21001 "TARGET_MMX"
21002 "paddusb\t{%2, %0|%0, %2}"
21003 [(set_attr "type" "mmxadd")
21004 (set_attr "mode" "DI")])
21005
21006 (define_insn "usaddv4hi3"
21007 [(set (match_operand:V4HI 0 "register_operand" "=y")
21008 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21009 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21010 "TARGET_MMX"
21011 "paddusw\t{%2, %0|%0, %2}"
21012 [(set_attr "type" "mmxadd")
21013 (set_attr "mode" "DI")])
21014
21015 (define_insn "subv8qi3"
21016 [(set (match_operand:V8QI 0 "register_operand" "=y")
21017 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21018 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21019 "TARGET_MMX"
21020 "psubb\t{%2, %0|%0, %2}"
21021 [(set_attr "type" "mmxadd")
21022 (set_attr "mode" "DI")])
21023
21024 (define_insn "subv4hi3"
21025 [(set (match_operand:V4HI 0 "register_operand" "=y")
21026 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21027 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21028 "TARGET_MMX"
21029 "psubw\t{%2, %0|%0, %2}"
21030 [(set_attr "type" "mmxadd")
21031 (set_attr "mode" "DI")])
21032
21033 (define_insn "subv2si3"
21034 [(set (match_operand:V2SI 0 "register_operand" "=y")
21035 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21036 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21037 "TARGET_MMX"
21038 "psubd\t{%2, %0|%0, %2}"
21039 [(set_attr "type" "mmxadd")
21040 (set_attr "mode" "DI")])
21041
21042 (define_insn "mmx_subdi3"
21043 [(set (match_operand:DI 0 "register_operand" "=y")
21044 (unspec:DI
21045 [(minus:DI (match_operand:DI 1 "register_operand" "0")
21046 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21047 UNSPEC_NOP))]
21048 "TARGET_MMX"
21049 "psubq\t{%2, %0|%0, %2}"
21050 [(set_attr "type" "mmxadd")
21051 (set_attr "mode" "DI")])
21052
21053 (define_insn "sssubv8qi3"
21054 [(set (match_operand:V8QI 0 "register_operand" "=y")
21055 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21056 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21057 "TARGET_MMX"
21058 "psubsb\t{%2, %0|%0, %2}"
21059 [(set_attr "type" "mmxadd")
21060 (set_attr "mode" "DI")])
21061
21062 (define_insn "sssubv4hi3"
21063 [(set (match_operand:V4HI 0 "register_operand" "=y")
21064 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21065 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21066 "TARGET_MMX"
21067 "psubsw\t{%2, %0|%0, %2}"
21068 [(set_attr "type" "mmxadd")
21069 (set_attr "mode" "DI")])
21070
21071 (define_insn "ussubv8qi3"
21072 [(set (match_operand:V8QI 0 "register_operand" "=y")
21073 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21074 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21075 "TARGET_MMX"
21076 "psubusb\t{%2, %0|%0, %2}"
21077 [(set_attr "type" "mmxadd")
21078 (set_attr "mode" "DI")])
21079
21080 (define_insn "ussubv4hi3"
21081 [(set (match_operand:V4HI 0 "register_operand" "=y")
21082 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21083 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21084 "TARGET_MMX"
21085 "psubusw\t{%2, %0|%0, %2}"
21086 [(set_attr "type" "mmxadd")
21087 (set_attr "mode" "DI")])
21088
21089 (define_insn "mulv4hi3"
21090 [(set (match_operand:V4HI 0 "register_operand" "=y")
21091 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21092 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21093 "TARGET_MMX"
21094 "pmullw\t{%2, %0|%0, %2}"
21095 [(set_attr "type" "mmxmul")
21096 (set_attr "mode" "DI")])
21097
21098 (define_insn "smulv4hi3_highpart"
21099 [(set (match_operand:V4HI 0 "register_operand" "=y")
21100 (truncate:V4HI
21101 (lshiftrt:V4SI
21102 (mult:V4SI (sign_extend:V4SI
21103 (match_operand:V4HI 1 "register_operand" "0"))
21104 (sign_extend:V4SI
21105 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21106 (const_int 16))))]
21107 "TARGET_MMX"
21108 "pmulhw\t{%2, %0|%0, %2}"
21109 [(set_attr "type" "mmxmul")
21110 (set_attr "mode" "DI")])
21111
21112 (define_insn "umulv4hi3_highpart"
21113 [(set (match_operand:V4HI 0 "register_operand" "=y")
21114 (truncate:V4HI
21115 (lshiftrt:V4SI
21116 (mult:V4SI (zero_extend:V4SI
21117 (match_operand:V4HI 1 "register_operand" "0"))
21118 (zero_extend:V4SI
21119 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21120 (const_int 16))))]
21121 "TARGET_SSE || TARGET_3DNOW_A"
21122 "pmulhuw\t{%2, %0|%0, %2}"
21123 [(set_attr "type" "mmxmul")
21124 (set_attr "mode" "DI")])
21125
21126 (define_insn "mmx_pmaddwd"
21127 [(set (match_operand:V2SI 0 "register_operand" "=y")
21128 (plus:V2SI
21129 (mult:V2SI
21130 (sign_extend:V2SI
21131 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21132 (parallel [(const_int 0) (const_int 2)])))
21133 (sign_extend:V2SI
21134 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21135 (parallel [(const_int 0) (const_int 2)]))))
21136 (mult:V2SI
21137 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21138 (parallel [(const_int 1)
21139 (const_int 3)])))
21140 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21141 (parallel [(const_int 1)
21142 (const_int 3)]))))))]
21143 "TARGET_MMX"
21144 "pmaddwd\t{%2, %0|%0, %2}"
21145 [(set_attr "type" "mmxmul")
21146 (set_attr "mode" "DI")])
21147
21148
21149 ;; MMX logical operations
21150 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21151 ;; normal code that also wants to use the FPU from getting broken.
21152 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21153 (define_insn "mmx_iordi3"
21154 [(set (match_operand:DI 0 "register_operand" "=y")
21155 (unspec:DI
21156 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21157 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21158 UNSPEC_NOP))]
21159 "TARGET_MMX"
21160 "por\t{%2, %0|%0, %2}"
21161 [(set_attr "type" "mmxadd")
21162 (set_attr "mode" "DI")])
21163
21164 (define_insn "mmx_xordi3"
21165 [(set (match_operand:DI 0 "register_operand" "=y")
21166 (unspec:DI
21167 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21168 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21169 UNSPEC_NOP))]
21170 "TARGET_MMX"
21171 "pxor\t{%2, %0|%0, %2}"
21172 [(set_attr "type" "mmxadd")
21173 (set_attr "mode" "DI")
21174 (set_attr "memory" "none")])
21175
21176 ;; Same as pxor, but don't show input operands so that we don't think
21177 ;; they are live.
21178 (define_insn "mmx_clrdi"
21179 [(set (match_operand:DI 0 "register_operand" "=y")
21180 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21181 "TARGET_MMX"
21182 "pxor\t{%0, %0|%0, %0}"
21183 [(set_attr "type" "mmxadd")
21184 (set_attr "mode" "DI")
21185 (set_attr "memory" "none")])
21186
21187 (define_insn "mmx_anddi3"
21188 [(set (match_operand:DI 0 "register_operand" "=y")
21189 (unspec:DI
21190 [(and:DI (match_operand:DI 1 "register_operand" "%0")
21191 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21192 UNSPEC_NOP))]
21193 "TARGET_MMX"
21194 "pand\t{%2, %0|%0, %2}"
21195 [(set_attr "type" "mmxadd")
21196 (set_attr "mode" "DI")])
21197
21198 (define_insn "mmx_nanddi3"
21199 [(set (match_operand:DI 0 "register_operand" "=y")
21200 (unspec:DI
21201 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21202 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21203 UNSPEC_NOP))]
21204 "TARGET_MMX"
21205 "pandn\t{%2, %0|%0, %2}"
21206 [(set_attr "type" "mmxadd")
21207 (set_attr "mode" "DI")])
21208
21209
21210 ;; MMX unsigned averages/sum of absolute differences
21211
21212 (define_insn "mmx_uavgv8qi3"
21213 [(set (match_operand:V8QI 0 "register_operand" "=y")
21214 (ashiftrt:V8QI
21215 (plus:V8QI (plus:V8QI
21216 (match_operand:V8QI 1 "register_operand" "0")
21217 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21218 (const_vector:V8QI [(const_int 1)
21219 (const_int 1)
21220 (const_int 1)
21221 (const_int 1)
21222 (const_int 1)
21223 (const_int 1)
21224 (const_int 1)
21225 (const_int 1)]))
21226 (const_int 1)))]
21227 "TARGET_SSE || TARGET_3DNOW_A"
21228 "pavgb\t{%2, %0|%0, %2}"
21229 [(set_attr "type" "mmxshft")
21230 (set_attr "mode" "DI")])
21231
21232 (define_insn "mmx_uavgv4hi3"
21233 [(set (match_operand:V4HI 0 "register_operand" "=y")
21234 (ashiftrt:V4HI
21235 (plus:V4HI (plus:V4HI
21236 (match_operand:V4HI 1 "register_operand" "0")
21237 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21238 (const_vector:V4HI [(const_int 1)
21239 (const_int 1)
21240 (const_int 1)
21241 (const_int 1)]))
21242 (const_int 1)))]
21243 "TARGET_SSE || TARGET_3DNOW_A"
21244 "pavgw\t{%2, %0|%0, %2}"
21245 [(set_attr "type" "mmxshft")
21246 (set_attr "mode" "DI")])
21247
21248 (define_insn "mmx_psadbw"
21249 [(set (match_operand:DI 0 "register_operand" "=y")
21250 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21251 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21252 UNSPEC_PSADBW))]
21253 "TARGET_SSE || TARGET_3DNOW_A"
21254 "psadbw\t{%2, %0|%0, %2}"
21255 [(set_attr "type" "mmxshft")
21256 (set_attr "mode" "DI")])
21257
21258
21259 ;; MMX insert/extract/shuffle
21260
21261 (define_insn "mmx_pinsrw"
21262 [(set (match_operand:V4HI 0 "register_operand" "=y")
21263 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21264 (vec_duplicate:V4HI
21265 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21266 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21267 "TARGET_SSE || TARGET_3DNOW_A"
21268 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21269 [(set_attr "type" "mmxcvt")
21270 (set_attr "mode" "DI")])
21271
21272 (define_insn "mmx_pextrw"
21273 [(set (match_operand:SI 0 "register_operand" "=r")
21274 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21275 (parallel
21276 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21277 "TARGET_SSE || TARGET_3DNOW_A"
21278 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21279 [(set_attr "type" "mmxcvt")
21280 (set_attr "mode" "DI")])
21281
21282 (define_insn "mmx_pshufw"
21283 [(set (match_operand:V4HI 0 "register_operand" "=y")
21284 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
21285 (match_operand:SI 2 "immediate_operand" "i")]
21286 UNSPEC_SHUFFLE))]
21287 "TARGET_SSE || TARGET_3DNOW_A"
21288 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21289 [(set_attr "type" "mmxcvt")
21290 (set_attr "mode" "DI")])
21291
21292
21293 ;; MMX mask-generating comparisons
21294
21295 (define_insn "eqv8qi3"
21296 [(set (match_operand:V8QI 0 "register_operand" "=y")
21297 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21298 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21299 "TARGET_MMX"
21300 "pcmpeqb\t{%2, %0|%0, %2}"
21301 [(set_attr "type" "mmxcmp")
21302 (set_attr "mode" "DI")])
21303
21304 (define_insn "eqv4hi3"
21305 [(set (match_operand:V4HI 0 "register_operand" "=y")
21306 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21307 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21308 "TARGET_MMX"
21309 "pcmpeqw\t{%2, %0|%0, %2}"
21310 [(set_attr "type" "mmxcmp")
21311 (set_attr "mode" "DI")])
21312
21313 (define_insn "eqv2si3"
21314 [(set (match_operand:V2SI 0 "register_operand" "=y")
21315 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21316 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21317 "TARGET_MMX"
21318 "pcmpeqd\t{%2, %0|%0, %2}"
21319 [(set_attr "type" "mmxcmp")
21320 (set_attr "mode" "DI")])
21321
21322 (define_insn "gtv8qi3"
21323 [(set (match_operand:V8QI 0 "register_operand" "=y")
21324 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21325 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21326 "TARGET_MMX"
21327 "pcmpgtb\t{%2, %0|%0, %2}"
21328 [(set_attr "type" "mmxcmp")
21329 (set_attr "mode" "DI")])
21330
21331 (define_insn "gtv4hi3"
21332 [(set (match_operand:V4HI 0 "register_operand" "=y")
21333 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21334 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21335 "TARGET_MMX"
21336 "pcmpgtw\t{%2, %0|%0, %2}"
21337 [(set_attr "type" "mmxcmp")
21338 (set_attr "mode" "DI")])
21339
21340 (define_insn "gtv2si3"
21341 [(set (match_operand:V2SI 0 "register_operand" "=y")
21342 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21343 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21344 "TARGET_MMX"
21345 "pcmpgtd\t{%2, %0|%0, %2}"
21346 [(set_attr "type" "mmxcmp")
21347 (set_attr "mode" "DI")])
21348
21349
21350 ;; MMX max/min insns
21351
21352 (define_insn "umaxv8qi3"
21353 [(set (match_operand:V8QI 0 "register_operand" "=y")
21354 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21355 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21356 "TARGET_SSE || TARGET_3DNOW_A"
21357 "pmaxub\t{%2, %0|%0, %2}"
21358 [(set_attr "type" "mmxadd")
21359 (set_attr "mode" "DI")])
21360
21361 (define_insn "smaxv4hi3"
21362 [(set (match_operand:V4HI 0 "register_operand" "=y")
21363 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21364 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21365 "TARGET_SSE || TARGET_3DNOW_A"
21366 "pmaxsw\t{%2, %0|%0, %2}"
21367 [(set_attr "type" "mmxadd")
21368 (set_attr "mode" "DI")])
21369
21370 (define_insn "uminv8qi3"
21371 [(set (match_operand:V8QI 0 "register_operand" "=y")
21372 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21373 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21374 "TARGET_SSE || TARGET_3DNOW_A"
21375 "pminub\t{%2, %0|%0, %2}"
21376 [(set_attr "type" "mmxadd")
21377 (set_attr "mode" "DI")])
21378
21379 (define_insn "sminv4hi3"
21380 [(set (match_operand:V4HI 0 "register_operand" "=y")
21381 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21382 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21383 "TARGET_SSE || TARGET_3DNOW_A"
21384 "pminsw\t{%2, %0|%0, %2}"
21385 [(set_attr "type" "mmxadd")
21386 (set_attr "mode" "DI")])
21387
21388
21389 ;; MMX shifts
21390
21391 (define_insn "ashrv4hi3"
21392 [(set (match_operand:V4HI 0 "register_operand" "=y")
21393 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21394 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21395 "TARGET_MMX"
21396 "psraw\t{%2, %0|%0, %2}"
21397 [(set_attr "type" "mmxshft")
21398 (set_attr "mode" "DI")])
21399
21400 (define_insn "ashrv2si3"
21401 [(set (match_operand:V2SI 0 "register_operand" "=y")
21402 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21403 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21404 "TARGET_MMX"
21405 "psrad\t{%2, %0|%0, %2}"
21406 [(set_attr "type" "mmxshft")
21407 (set_attr "mode" "DI")])
21408
21409 (define_insn "lshrv4hi3"
21410 [(set (match_operand:V4HI 0 "register_operand" "=y")
21411 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21412 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21413 "TARGET_MMX"
21414 "psrlw\t{%2, %0|%0, %2}"
21415 [(set_attr "type" "mmxshft")
21416 (set_attr "mode" "DI")])
21417
21418 (define_insn "lshrv2si3"
21419 [(set (match_operand:V2SI 0 "register_operand" "=y")
21420 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21421 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21422 "TARGET_MMX"
21423 "psrld\t{%2, %0|%0, %2}"
21424 [(set_attr "type" "mmxshft")
21425 (set_attr "mode" "DI")])
21426
21427 ;; See logical MMX insns.
21428 (define_insn "mmx_lshrdi3"
21429 [(set (match_operand:DI 0 "register_operand" "=y")
21430 (unspec:DI
21431 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21432 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21433 UNSPEC_NOP))]
21434 "TARGET_MMX"
21435 "psrlq\t{%2, %0|%0, %2}"
21436 [(set_attr "type" "mmxshft")
21437 (set_attr "mode" "DI")])
21438
21439 (define_insn "ashlv4hi3"
21440 [(set (match_operand:V4HI 0 "register_operand" "=y")
21441 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21442 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21443 "TARGET_MMX"
21444 "psllw\t{%2, %0|%0, %2}"
21445 [(set_attr "type" "mmxshft")
21446 (set_attr "mode" "DI")])
21447
21448 (define_insn "ashlv2si3"
21449 [(set (match_operand:V2SI 0 "register_operand" "=y")
21450 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21451 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21452 "TARGET_MMX"
21453 "pslld\t{%2, %0|%0, %2}"
21454 [(set_attr "type" "mmxshft")
21455 (set_attr "mode" "DI")])
21456
21457 ;; See logical MMX insns.
21458 (define_insn "mmx_ashldi3"
21459 [(set (match_operand:DI 0 "register_operand" "=y")
21460 (unspec:DI
21461 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21462 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21463 UNSPEC_NOP))]
21464 "TARGET_MMX"
21465 "psllq\t{%2, %0|%0, %2}"
21466 [(set_attr "type" "mmxshft")
21467 (set_attr "mode" "DI")])
21468
21469
21470 ;; MMX pack/unpack insns.
21471
21472 (define_insn "mmx_packsswb"
21473 [(set (match_operand:V8QI 0 "register_operand" "=y")
21474 (vec_concat:V8QI
21475 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21476 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21477 "TARGET_MMX"
21478 "packsswb\t{%2, %0|%0, %2}"
21479 [(set_attr "type" "mmxshft")
21480 (set_attr "mode" "DI")])
21481
21482 (define_insn "mmx_packssdw"
21483 [(set (match_operand:V4HI 0 "register_operand" "=y")
21484 (vec_concat:V4HI
21485 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21486 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21487 "TARGET_MMX"
21488 "packssdw\t{%2, %0|%0, %2}"
21489 [(set_attr "type" "mmxshft")
21490 (set_attr "mode" "DI")])
21491
21492 (define_insn "mmx_packuswb"
21493 [(set (match_operand:V8QI 0 "register_operand" "=y")
21494 (vec_concat:V8QI
21495 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21496 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21497 "TARGET_MMX"
21498 "packuswb\t{%2, %0|%0, %2}"
21499 [(set_attr "type" "mmxshft")
21500 (set_attr "mode" "DI")])
21501
21502 (define_insn "mmx_punpckhbw"
21503 [(set (match_operand:V8QI 0 "register_operand" "=y")
21504 (vec_merge:V8QI
21505 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21506 (parallel [(const_int 4)
21507 (const_int 0)
21508 (const_int 5)
21509 (const_int 1)
21510 (const_int 6)
21511 (const_int 2)
21512 (const_int 7)
21513 (const_int 3)]))
21514 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21515 (parallel [(const_int 0)
21516 (const_int 4)
21517 (const_int 1)
21518 (const_int 5)
21519 (const_int 2)
21520 (const_int 6)
21521 (const_int 3)
21522 (const_int 7)]))
21523 (const_int 85)))]
21524 "TARGET_MMX"
21525 "punpckhbw\t{%2, %0|%0, %2}"
21526 [(set_attr "type" "mmxcvt")
21527 (set_attr "mode" "DI")])
21528
21529 (define_insn "mmx_punpckhwd"
21530 [(set (match_operand:V4HI 0 "register_operand" "=y")
21531 (vec_merge:V4HI
21532 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21533 (parallel [(const_int 0)
21534 (const_int 2)
21535 (const_int 1)
21536 (const_int 3)]))
21537 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21538 (parallel [(const_int 2)
21539 (const_int 0)
21540 (const_int 3)
21541 (const_int 1)]))
21542 (const_int 5)))]
21543 "TARGET_MMX"
21544 "punpckhwd\t{%2, %0|%0, %2}"
21545 [(set_attr "type" "mmxcvt")
21546 (set_attr "mode" "DI")])
21547
21548 (define_insn "mmx_punpckhdq"
21549 [(set (match_operand:V2SI 0 "register_operand" "=y")
21550 (vec_merge:V2SI
21551 (match_operand:V2SI 1 "register_operand" "0")
21552 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21553 (parallel [(const_int 1)
21554 (const_int 0)]))
21555 (const_int 1)))]
21556 "TARGET_MMX"
21557 "punpckhdq\t{%2, %0|%0, %2}"
21558 [(set_attr "type" "mmxcvt")
21559 (set_attr "mode" "DI")])
21560
21561 (define_insn "mmx_punpcklbw"
21562 [(set (match_operand:V8QI 0 "register_operand" "=y")
21563 (vec_merge:V8QI
21564 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21565 (parallel [(const_int 0)
21566 (const_int 4)
21567 (const_int 1)
21568 (const_int 5)
21569 (const_int 2)
21570 (const_int 6)
21571 (const_int 3)
21572 (const_int 7)]))
21573 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21574 (parallel [(const_int 4)
21575 (const_int 0)
21576 (const_int 5)
21577 (const_int 1)
21578 (const_int 6)
21579 (const_int 2)
21580 (const_int 7)
21581 (const_int 3)]))
21582 (const_int 85)))]
21583 "TARGET_MMX"
21584 "punpcklbw\t{%2, %0|%0, %2}"
21585 [(set_attr "type" "mmxcvt")
21586 (set_attr "mode" "DI")])
21587
21588 (define_insn "mmx_punpcklwd"
21589 [(set (match_operand:V4HI 0 "register_operand" "=y")
21590 (vec_merge:V4HI
21591 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21592 (parallel [(const_int 2)
21593 (const_int 0)
21594 (const_int 3)
21595 (const_int 1)]))
21596 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21597 (parallel [(const_int 0)
21598 (const_int 2)
21599 (const_int 1)
21600 (const_int 3)]))
21601 (const_int 5)))]
21602 "TARGET_MMX"
21603 "punpcklwd\t{%2, %0|%0, %2}"
21604 [(set_attr "type" "mmxcvt")
21605 (set_attr "mode" "DI")])
21606
21607 (define_insn "mmx_punpckldq"
21608 [(set (match_operand:V2SI 0 "register_operand" "=y")
21609 (vec_merge:V2SI
21610 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21611 (parallel [(const_int 1)
21612 (const_int 0)]))
21613 (match_operand:V2SI 2 "register_operand" "y")
21614 (const_int 1)))]
21615 "TARGET_MMX"
21616 "punpckldq\t{%2, %0|%0, %2}"
21617 [(set_attr "type" "mmxcvt")
21618 (set_attr "mode" "DI")])
21619
21620
21621 ;; Miscellaneous stuff
21622
21623 (define_insn "emms"
21624 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21625 (clobber (reg:XF 8))
21626 (clobber (reg:XF 9))
21627 (clobber (reg:XF 10))
21628 (clobber (reg:XF 11))
21629 (clobber (reg:XF 12))
21630 (clobber (reg:XF 13))
21631 (clobber (reg:XF 14))
21632 (clobber (reg:XF 15))
21633 (clobber (reg:DI 29))
21634 (clobber (reg:DI 30))
21635 (clobber (reg:DI 31))
21636 (clobber (reg:DI 32))
21637 (clobber (reg:DI 33))
21638 (clobber (reg:DI 34))
21639 (clobber (reg:DI 35))
21640 (clobber (reg:DI 36))]
21641 "TARGET_MMX"
21642 "emms"
21643 [(set_attr "type" "mmx")
21644 (set_attr "memory" "unknown")])
21645
21646 (define_insn "ldmxcsr"
21647 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21648 UNSPECV_LDMXCSR)]
21649 "TARGET_SSE"
21650 "ldmxcsr\t%0"
21651 [(set_attr "type" "sse")
21652 (set_attr "memory" "load")])
21653
21654 (define_insn "stmxcsr"
21655 [(set (match_operand:SI 0 "memory_operand" "=m")
21656 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21657 "TARGET_SSE"
21658 "stmxcsr\t%0"
21659 [(set_attr "type" "sse")
21660 (set_attr "memory" "store")])
21661
21662 (define_expand "sfence"
21663 [(set (match_dup 0)
21664 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21665 "TARGET_SSE || TARGET_3DNOW_A"
21666 {
21667 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21668 MEM_VOLATILE_P (operands[0]) = 1;
21669 })
21670
21671 (define_insn "*sfence_insn"
21672 [(set (match_operand:BLK 0 "" "")
21673 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21674 "TARGET_SSE || TARGET_3DNOW_A"
21675 "sfence"
21676 [(set_attr "type" "sse")
21677 (set_attr "memory" "unknown")])
21678
21679 (define_expand "sse_prologue_save"
21680 [(parallel [(set (match_operand:BLK 0 "" "")
21681 (unspec:BLK [(reg:DI 21)
21682 (reg:DI 22)
21683 (reg:DI 23)
21684 (reg:DI 24)
21685 (reg:DI 25)
21686 (reg:DI 26)
21687 (reg:DI 27)
21688 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21689 (use (match_operand:DI 1 "register_operand" ""))
21690 (use (match_operand:DI 2 "immediate_operand" ""))
21691 (use (label_ref:DI (match_operand 3 "" "")))])]
21692 "TARGET_64BIT"
21693 "")
21694
21695 (define_insn "*sse_prologue_save_insn"
21696 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21697 (match_operand:DI 4 "const_int_operand" "n")))
21698 (unspec:BLK [(reg:DI 21)
21699 (reg:DI 22)
21700 (reg:DI 23)
21701 (reg:DI 24)
21702 (reg:DI 25)
21703 (reg:DI 26)
21704 (reg:DI 27)
21705 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21706 (use (match_operand:DI 1 "register_operand" "r"))
21707 (use (match_operand:DI 2 "const_int_operand" "i"))
21708 (use (label_ref:DI (match_operand 3 "" "X")))]
21709 "TARGET_64BIT
21710 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21711 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21712 "*
21713 {
21714 int i;
21715 operands[0] = gen_rtx_MEM (Pmode,
21716 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21717 output_asm_insn (\"jmp\\t%A1\", operands);
21718 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21719 {
21720 operands[4] = adjust_address (operands[0], DImode, i*16);
21721 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21722 PUT_MODE (operands[4], TImode);
21723 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21724 output_asm_insn (\"rex\", operands);
21725 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21726 }
21727 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21728 CODE_LABEL_NUMBER (operands[3]));
21729 RET;
21730 }
21731 "
21732 [(set_attr "type" "other")
21733 (set_attr "length_immediate" "0")
21734 (set_attr "length_address" "0")
21735 (set_attr "length" "135")
21736 (set_attr "memory" "store")
21737 (set_attr "modrm" "0")
21738 (set_attr "mode" "DI")])
21739
21740 ;; 3Dnow! instructions
21741
21742 (define_insn "addv2sf3"
21743 [(set (match_operand:V2SF 0 "register_operand" "=y")
21744 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21745 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21746 "TARGET_3DNOW"
21747 "pfadd\\t{%2, %0|%0, %2}"
21748 [(set_attr "type" "mmxadd")
21749 (set_attr "mode" "V2SF")])
21750
21751 (define_insn "subv2sf3"
21752 [(set (match_operand:V2SF 0 "register_operand" "=y")
21753 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21754 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21755 "TARGET_3DNOW"
21756 "pfsub\\t{%2, %0|%0, %2}"
21757 [(set_attr "type" "mmxadd")
21758 (set_attr "mode" "V2SF")])
21759
21760 (define_insn "subrv2sf3"
21761 [(set (match_operand:V2SF 0 "register_operand" "=y")
21762 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21763 (match_operand:V2SF 1 "register_operand" "0")))]
21764 "TARGET_3DNOW"
21765 "pfsubr\\t{%2, %0|%0, %2}"
21766 [(set_attr "type" "mmxadd")
21767 (set_attr "mode" "V2SF")])
21768
21769 (define_insn "gtv2sf3"
21770 [(set (match_operand:V2SI 0 "register_operand" "=y")
21771 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21772 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21773 "TARGET_3DNOW"
21774 "pfcmpgt\\t{%2, %0|%0, %2}"
21775 [(set_attr "type" "mmxcmp")
21776 (set_attr "mode" "V2SF")])
21777
21778 (define_insn "gev2sf3"
21779 [(set (match_operand:V2SI 0 "register_operand" "=y")
21780 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21781 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21782 "TARGET_3DNOW"
21783 "pfcmpge\\t{%2, %0|%0, %2}"
21784 [(set_attr "type" "mmxcmp")
21785 (set_attr "mode" "V2SF")])
21786
21787 (define_insn "eqv2sf3"
21788 [(set (match_operand:V2SI 0 "register_operand" "=y")
21789 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21790 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21791 "TARGET_3DNOW"
21792 "pfcmpeq\\t{%2, %0|%0, %2}"
21793 [(set_attr "type" "mmxcmp")
21794 (set_attr "mode" "V2SF")])
21795
21796 (define_insn "pfmaxv2sf3"
21797 [(set (match_operand:V2SF 0 "register_operand" "=y")
21798 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21799 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21800 "TARGET_3DNOW"
21801 "pfmax\\t{%2, %0|%0, %2}"
21802 [(set_attr "type" "mmxadd")
21803 (set_attr "mode" "V2SF")])
21804
21805 (define_insn "pfminv2sf3"
21806 [(set (match_operand:V2SF 0 "register_operand" "=y")
21807 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21808 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21809 "TARGET_3DNOW"
21810 "pfmin\\t{%2, %0|%0, %2}"
21811 [(set_attr "type" "mmxadd")
21812 (set_attr "mode" "V2SF")])
21813
21814 (define_insn "mulv2sf3"
21815 [(set (match_operand:V2SF 0 "register_operand" "=y")
21816 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21817 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21818 "TARGET_3DNOW"
21819 "pfmul\\t{%2, %0|%0, %2}"
21820 [(set_attr "type" "mmxmul")
21821 (set_attr "mode" "V2SF")])
21822
21823 (define_insn "femms"
21824 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21825 (clobber (reg:XF 8))
21826 (clobber (reg:XF 9))
21827 (clobber (reg:XF 10))
21828 (clobber (reg:XF 11))
21829 (clobber (reg:XF 12))
21830 (clobber (reg:XF 13))
21831 (clobber (reg:XF 14))
21832 (clobber (reg:XF 15))
21833 (clobber (reg:DI 29))
21834 (clobber (reg:DI 30))
21835 (clobber (reg:DI 31))
21836 (clobber (reg:DI 32))
21837 (clobber (reg:DI 33))
21838 (clobber (reg:DI 34))
21839 (clobber (reg:DI 35))
21840 (clobber (reg:DI 36))]
21841 "TARGET_3DNOW"
21842 "femms"
21843 [(set_attr "type" "mmx")
21844 (set_attr "memory" "none")])
21845
21846 (define_insn "pf2id"
21847 [(set (match_operand:V2SI 0 "register_operand" "=y")
21848 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21849 "TARGET_3DNOW"
21850 "pf2id\\t{%1, %0|%0, %1}"
21851 [(set_attr "type" "mmxcvt")
21852 (set_attr "mode" "V2SF")])
21853
21854 (define_insn "pf2iw"
21855 [(set (match_operand:V2SI 0 "register_operand" "=y")
21856 (sign_extend:V2SI
21857 (ss_truncate:V2HI
21858 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21859 "TARGET_3DNOW_A"
21860 "pf2iw\\t{%1, %0|%0, %1}"
21861 [(set_attr "type" "mmxcvt")
21862 (set_attr "mode" "V2SF")])
21863
21864 (define_insn "pfacc"
21865 [(set (match_operand:V2SF 0 "register_operand" "=y")
21866 (vec_concat:V2SF
21867 (plus:SF
21868 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21869 (parallel [(const_int 0)]))
21870 (vec_select:SF (match_dup 1)
21871 (parallel [(const_int 1)])))
21872 (plus:SF
21873 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21874 (parallel [(const_int 0)]))
21875 (vec_select:SF (match_dup 2)
21876 (parallel [(const_int 1)])))))]
21877 "TARGET_3DNOW"
21878 "pfacc\\t{%2, %0|%0, %2}"
21879 [(set_attr "type" "mmxadd")
21880 (set_attr "mode" "V2SF")])
21881
21882 (define_insn "pfnacc"
21883 [(set (match_operand:V2SF 0 "register_operand" "=y")
21884 (vec_concat:V2SF
21885 (minus:SF
21886 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21887 (parallel [(const_int 0)]))
21888 (vec_select:SF (match_dup 1)
21889 (parallel [(const_int 1)])))
21890 (minus:SF
21891 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21892 (parallel [(const_int 0)]))
21893 (vec_select:SF (match_dup 2)
21894 (parallel [(const_int 1)])))))]
21895 "TARGET_3DNOW_A"
21896 "pfnacc\\t{%2, %0|%0, %2}"
21897 [(set_attr "type" "mmxadd")
21898 (set_attr "mode" "V2SF")])
21899
21900 (define_insn "pfpnacc"
21901 [(set (match_operand:V2SF 0 "register_operand" "=y")
21902 (vec_concat:V2SF
21903 (minus:SF
21904 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21905 (parallel [(const_int 0)]))
21906 (vec_select:SF (match_dup 1)
21907 (parallel [(const_int 1)])))
21908 (plus:SF
21909 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21910 (parallel [(const_int 0)]))
21911 (vec_select:SF (match_dup 2)
21912 (parallel [(const_int 1)])))))]
21913 "TARGET_3DNOW_A"
21914 "pfpnacc\\t{%2, %0|%0, %2}"
21915 [(set_attr "type" "mmxadd")
21916 (set_attr "mode" "V2SF")])
21917
21918 (define_insn "pi2fw"
21919 [(set (match_operand:V2SF 0 "register_operand" "=y")
21920 (float:V2SF
21921 (vec_concat:V2SI
21922 (sign_extend:SI
21923 (truncate:HI
21924 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21925 (parallel [(const_int 0)]))))
21926 (sign_extend:SI
21927 (truncate:HI
21928 (vec_select:SI (match_dup 1)
21929 (parallel [(const_int 1)])))))))]
21930 "TARGET_3DNOW_A"
21931 "pi2fw\\t{%1, %0|%0, %1}"
21932 [(set_attr "type" "mmxcvt")
21933 (set_attr "mode" "V2SF")])
21934
21935 (define_insn "floatv2si2"
21936 [(set (match_operand:V2SF 0 "register_operand" "=y")
21937 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21938 "TARGET_3DNOW"
21939 "pi2fd\\t{%1, %0|%0, %1}"
21940 [(set_attr "type" "mmxcvt")
21941 (set_attr "mode" "V2SF")])
21942
21943 ;; This insn is identical to pavgb in operation, but the opcode is
21944 ;; different. To avoid accidentally matching pavgb, use an unspec.
21945
21946 (define_insn "pavgusb"
21947 [(set (match_operand:V8QI 0 "register_operand" "=y")
21948 (unspec:V8QI
21949 [(match_operand:V8QI 1 "register_operand" "0")
21950 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21951 UNSPEC_PAVGUSB))]
21952 "TARGET_3DNOW"
21953 "pavgusb\\t{%2, %0|%0, %2}"
21954 [(set_attr "type" "mmxshft")
21955 (set_attr "mode" "TI")])
21956
21957 ;; 3DNow reciprocal and sqrt
21958
21959 (define_insn "pfrcpv2sf2"
21960 [(set (match_operand:V2SF 0 "register_operand" "=y")
21961 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21962 UNSPEC_PFRCP))]
21963 "TARGET_3DNOW"
21964 "pfrcp\\t{%1, %0|%0, %1}"
21965 [(set_attr "type" "mmx")
21966 (set_attr "mode" "TI")])
21967
21968 (define_insn "pfrcpit1v2sf3"
21969 [(set (match_operand:V2SF 0 "register_operand" "=y")
21970 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21971 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21972 UNSPEC_PFRCPIT1))]
21973 "TARGET_3DNOW"
21974 "pfrcpit1\\t{%2, %0|%0, %2}"
21975 [(set_attr "type" "mmx")
21976 (set_attr "mode" "TI")])
21977
21978 (define_insn "pfrcpit2v2sf3"
21979 [(set (match_operand:V2SF 0 "register_operand" "=y")
21980 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21981 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21982 UNSPEC_PFRCPIT2))]
21983 "TARGET_3DNOW"
21984 "pfrcpit2\\t{%2, %0|%0, %2}"
21985 [(set_attr "type" "mmx")
21986 (set_attr "mode" "TI")])
21987
21988 (define_insn "pfrsqrtv2sf2"
21989 [(set (match_operand:V2SF 0 "register_operand" "=y")
21990 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21991 UNSPEC_PFRSQRT))]
21992 "TARGET_3DNOW"
21993 "pfrsqrt\\t{%1, %0|%0, %1}"
21994 [(set_attr "type" "mmx")
21995 (set_attr "mode" "TI")])
21996
21997 (define_insn "pfrsqit1v2sf3"
21998 [(set (match_operand:V2SF 0 "register_operand" "=y")
21999 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22000 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22001 UNSPEC_PFRSQIT1))]
22002 "TARGET_3DNOW"
22003 "pfrsqit1\\t{%2, %0|%0, %2}"
22004 [(set_attr "type" "mmx")
22005 (set_attr "mode" "TI")])
22006
22007 (define_insn "pmulhrwv4hi3"
22008 [(set (match_operand:V4HI 0 "register_operand" "=y")
22009 (truncate:V4HI
22010 (lshiftrt:V4SI
22011 (plus:V4SI
22012 (mult:V4SI
22013 (sign_extend:V4SI
22014 (match_operand:V4HI 1 "register_operand" "0"))
22015 (sign_extend:V4SI
22016 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22017 (const_vector:V4SI [(const_int 32768)
22018 (const_int 32768)
22019 (const_int 32768)
22020 (const_int 32768)]))
22021 (const_int 16))))]
22022 "TARGET_3DNOW"
22023 "pmulhrw\\t{%2, %0|%0, %2}"
22024 [(set_attr "type" "mmxmul")
22025 (set_attr "mode" "TI")])
22026
22027 (define_insn "pswapdv2si2"
22028 [(set (match_operand:V2SI 0 "register_operand" "=y")
22029 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22030 (parallel [(const_int 1) (const_int 0)])))]
22031 "TARGET_3DNOW_A"
22032 "pswapd\\t{%1, %0|%0, %1}"
22033 [(set_attr "type" "mmxcvt")
22034 (set_attr "mode" "TI")])
22035
22036 (define_insn "pswapdv2sf2"
22037 [(set (match_operand:V2SF 0 "register_operand" "=y")
22038 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22039 (parallel [(const_int 1) (const_int 0)])))]
22040 "TARGET_3DNOW_A"
22041 "pswapd\\t{%1, %0|%0, %1}"
22042 [(set_attr "type" "mmxcvt")
22043 (set_attr "mode" "TI")])
22044
22045 (define_expand "prefetch"
22046 [(prefetch (match_operand 0 "address_operand" "")
22047 (match_operand:SI 1 "const_int_operand" "")
22048 (match_operand:SI 2 "const_int_operand" ""))]
22049 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22050 {
22051 int rw = INTVAL (operands[1]);
22052 int locality = INTVAL (operands[2]);
22053
22054 if (rw != 0 && rw != 1)
22055 abort ();
22056 if (locality < 0 || locality > 3)
22057 abort ();
22058 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22059 abort ();
22060
22061 /* Use 3dNOW prefetch in case we are asking for write prefetch not
22062 suported by SSE counterpart or the SSE prefetch is not available
22063 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22064 of locality. */
22065 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22066 operands[2] = GEN_INT (3);
22067 else
22068 operands[1] = const0_rtx;
22069 })
22070
22071 (define_insn "*prefetch_sse"
22072 [(prefetch (match_operand:SI 0 "address_operand" "p")
22073 (const_int 0)
22074 (match_operand:SI 1 "const_int_operand" ""))]
22075 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22076 {
22077 static const char * const patterns[4] = {
22078 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22079 };
22080
22081 int locality = INTVAL (operands[1]);
22082 if (locality < 0 || locality > 3)
22083 abort ();
22084
22085 return patterns[locality];
22086 }
22087 [(set_attr "type" "sse")
22088 (set_attr "memory" "none")])
22089
22090 (define_insn "*prefetch_sse_rex"
22091 [(prefetch (match_operand:DI 0 "address_operand" "p")
22092 (const_int 0)
22093 (match_operand:SI 1 "const_int_operand" ""))]
22094 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22095 {
22096 static const char * const patterns[4] = {
22097 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22098 };
22099
22100 int locality = INTVAL (operands[1]);
22101 if (locality < 0 || locality > 3)
22102 abort ();
22103
22104 return patterns[locality];
22105 }
22106 [(set_attr "type" "sse")
22107 (set_attr "memory" "none")])
22108
22109 (define_insn "*prefetch_3dnow"
22110 [(prefetch (match_operand:SI 0 "address_operand" "p")
22111 (match_operand:SI 1 "const_int_operand" "n")
22112 (const_int 3))]
22113 "TARGET_3DNOW && !TARGET_64BIT"
22114 {
22115 if (INTVAL (operands[1]) == 0)
22116 return "prefetch\t%a0";
22117 else
22118 return "prefetchw\t%a0";
22119 }
22120 [(set_attr "type" "mmx")
22121 (set_attr "memory" "none")])
22122
22123 (define_insn "*prefetch_3dnow_rex"
22124 [(prefetch (match_operand:DI 0 "address_operand" "p")
22125 (match_operand:SI 1 "const_int_operand" "n")
22126 (const_int 3))]
22127 "TARGET_3DNOW && TARGET_64BIT"
22128 {
22129 if (INTVAL (operands[1]) == 0)
22130 return "prefetch\t%a0";
22131 else
22132 return "prefetchw\t%a0";
22133 }
22134 [(set_attr "type" "mmx")
22135 (set_attr "memory" "none")])
22136
22137 ;; SSE2 support
22138
22139 (define_insn "addv2df3"
22140 [(set (match_operand:V2DF 0 "register_operand" "=x")
22141 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22142 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22143 "TARGET_SSE2"
22144 "addpd\t{%2, %0|%0, %2}"
22145 [(set_attr "type" "sseadd")
22146 (set_attr "mode" "V2DF")])
22147
22148 (define_insn "vmaddv2df3"
22149 [(set (match_operand:V2DF 0 "register_operand" "=x")
22150 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22151 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22152 (match_dup 1)
22153 (const_int 1)))]
22154 "TARGET_SSE2"
22155 "addsd\t{%2, %0|%0, %2}"
22156 [(set_attr "type" "sseadd")
22157 (set_attr "mode" "DF")])
22158
22159 (define_insn "subv2df3"
22160 [(set (match_operand:V2DF 0 "register_operand" "=x")
22161 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22162 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22163 "TARGET_SSE2"
22164 "subpd\t{%2, %0|%0, %2}"
22165 [(set_attr "type" "sseadd")
22166 (set_attr "mode" "V2DF")])
22167
22168 (define_insn "vmsubv2df3"
22169 [(set (match_operand:V2DF 0 "register_operand" "=x")
22170 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22171 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22172 (match_dup 1)
22173 (const_int 1)))]
22174 "TARGET_SSE2"
22175 "subsd\t{%2, %0|%0, %2}"
22176 [(set_attr "type" "sseadd")
22177 (set_attr "mode" "DF")])
22178
22179 (define_insn "mulv2df3"
22180 [(set (match_operand:V2DF 0 "register_operand" "=x")
22181 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22182 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22183 "TARGET_SSE2"
22184 "mulpd\t{%2, %0|%0, %2}"
22185 [(set_attr "type" "ssemul")
22186 (set_attr "mode" "V2DF")])
22187
22188 (define_insn "vmmulv2df3"
22189 [(set (match_operand:V2DF 0 "register_operand" "=x")
22190 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22191 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22192 (match_dup 1)
22193 (const_int 1)))]
22194 "TARGET_SSE2"
22195 "mulsd\t{%2, %0|%0, %2}"
22196 [(set_attr "type" "ssemul")
22197 (set_attr "mode" "DF")])
22198
22199 (define_insn "divv2df3"
22200 [(set (match_operand:V2DF 0 "register_operand" "=x")
22201 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22202 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22203 "TARGET_SSE2"
22204 "divpd\t{%2, %0|%0, %2}"
22205 [(set_attr "type" "ssediv")
22206 (set_attr "mode" "V2DF")])
22207
22208 (define_insn "vmdivv2df3"
22209 [(set (match_operand:V2DF 0 "register_operand" "=x")
22210 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22211 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22212 (match_dup 1)
22213 (const_int 1)))]
22214 "TARGET_SSE2"
22215 "divsd\t{%2, %0|%0, %2}"
22216 [(set_attr "type" "ssediv")
22217 (set_attr "mode" "DF")])
22218
22219 ;; SSE min/max
22220
22221 (define_insn "smaxv2df3"
22222 [(set (match_operand:V2DF 0 "register_operand" "=x")
22223 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22224 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22225 "TARGET_SSE2"
22226 "maxpd\t{%2, %0|%0, %2}"
22227 [(set_attr "type" "sseadd")
22228 (set_attr "mode" "V2DF")])
22229
22230 (define_insn "vmsmaxv2df3"
22231 [(set (match_operand:V2DF 0 "register_operand" "=x")
22232 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22233 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22234 (match_dup 1)
22235 (const_int 1)))]
22236 "TARGET_SSE2"
22237 "maxsd\t{%2, %0|%0, %2}"
22238 [(set_attr "type" "sseadd")
22239 (set_attr "mode" "DF")])
22240
22241 (define_insn "sminv2df3"
22242 [(set (match_operand:V2DF 0 "register_operand" "=x")
22243 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22244 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22245 "TARGET_SSE2"
22246 "minpd\t{%2, %0|%0, %2}"
22247 [(set_attr "type" "sseadd")
22248 (set_attr "mode" "V2DF")])
22249
22250 (define_insn "vmsminv2df3"
22251 [(set (match_operand:V2DF 0 "register_operand" "=x")
22252 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22253 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22254 (match_dup 1)
22255 (const_int 1)))]
22256 "TARGET_SSE2"
22257 "minsd\t{%2, %0|%0, %2}"
22258 [(set_attr "type" "sseadd")
22259 (set_attr "mode" "DF")])
22260 ;; SSE2 square root. There doesn't appear to be an extension for the
22261 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22262
22263 (define_insn "sqrtv2df2"
22264 [(set (match_operand:V2DF 0 "register_operand" "=x")
22265 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22266 "TARGET_SSE2"
22267 "sqrtpd\t{%1, %0|%0, %1}"
22268 [(set_attr "type" "sse")
22269 (set_attr "mode" "V2DF")])
22270
22271 (define_insn "vmsqrtv2df2"
22272 [(set (match_operand:V2DF 0 "register_operand" "=x")
22273 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22274 (match_operand:V2DF 2 "register_operand" "0")
22275 (const_int 1)))]
22276 "TARGET_SSE2"
22277 "sqrtsd\t{%1, %0|%0, %1}"
22278 [(set_attr "type" "sse")
22279 (set_attr "mode" "SF")])
22280
22281 ;; SSE mask-generating compares
22282
22283 (define_insn "maskcmpv2df3"
22284 [(set (match_operand:V2DI 0 "register_operand" "=x")
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 "TARGET_SSE2"
22289 "cmp%D3pd\t{%2, %0|%0, %2}"
22290 [(set_attr "type" "ssecmp")
22291 (set_attr "mode" "V2DF")])
22292
22293 (define_insn "maskncmpv2df3"
22294 [(set (match_operand:V2DI 0 "register_operand" "=x")
22295 (not:V2DI
22296 (match_operator:V2DI 3 "sse_comparison_operator"
22297 [(match_operand:V2DF 1 "register_operand" "0")
22298 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22299 "TARGET_SSE2"
22300 {
22301 if (GET_CODE (operands[3]) == UNORDERED)
22302 return "cmpordps\t{%2, %0|%0, %2}";
22303 else
22304 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22305 }
22306 [(set_attr "type" "ssecmp")
22307 (set_attr "mode" "V2DF")])
22308
22309 (define_insn "vmmaskcmpv2df3"
22310 [(set (match_operand:V2DI 0 "register_operand" "=x")
22311 (vec_merge:V2DI
22312 (match_operator:V2DI 3 "sse_comparison_operator"
22313 [(match_operand:V2DF 1 "register_operand" "0")
22314 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22315 (subreg:V2DI (match_dup 1) 0)
22316 (const_int 1)))]
22317 "TARGET_SSE2"
22318 "cmp%D3sd\t{%2, %0|%0, %2}"
22319 [(set_attr "type" "ssecmp")
22320 (set_attr "mode" "DF")])
22321
22322 (define_insn "vmmaskncmpv2df3"
22323 [(set (match_operand:V2DI 0 "register_operand" "=x")
22324 (vec_merge:V2DI
22325 (not:V2DI
22326 (match_operator:V2DI 3 "sse_comparison_operator"
22327 [(match_operand:V2DF 1 "register_operand" "0")
22328 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22329 (subreg:V2DI (match_dup 1) 0)
22330 (const_int 1)))]
22331 "TARGET_SSE2"
22332 {
22333 if (GET_CODE (operands[3]) == UNORDERED)
22334 return "cmpordsd\t{%2, %0|%0, %2}";
22335 else
22336 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22337 }
22338 [(set_attr "type" "ssecmp")
22339 (set_attr "mode" "DF")])
22340
22341 (define_insn "sse2_comi"
22342 [(set (reg:CCFP 17)
22343 (compare:CCFP (vec_select:DF
22344 (match_operand:V2DF 0 "register_operand" "x")
22345 (parallel [(const_int 0)]))
22346 (vec_select:DF
22347 (match_operand:V2DF 1 "register_operand" "x")
22348 (parallel [(const_int 0)]))))]
22349 "TARGET_SSE2"
22350 "comisd\t{%1, %0|%0, %1}"
22351 [(set_attr "type" "ssecomi")
22352 (set_attr "mode" "DF")])
22353
22354 (define_insn "sse2_ucomi"
22355 [(set (reg:CCFPU 17)
22356 (compare:CCFPU (vec_select:DF
22357 (match_operand:V2DF 0 "register_operand" "x")
22358 (parallel [(const_int 0)]))
22359 (vec_select:DF
22360 (match_operand:V2DF 1 "register_operand" "x")
22361 (parallel [(const_int 0)]))))]
22362 "TARGET_SSE2"
22363 "ucomisd\t{%1, %0|%0, %1}"
22364 [(set_attr "type" "ssecomi")
22365 (set_attr "mode" "DF")])
22366
22367 ;; SSE Strange Moves.
22368
22369 (define_insn "sse2_movmskpd"
22370 [(set (match_operand:SI 0 "register_operand" "=r")
22371 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22372 UNSPEC_MOVMSK))]
22373 "TARGET_SSE2"
22374 "movmskpd\t{%1, %0|%0, %1}"
22375 [(set_attr "type" "ssecvt")
22376 (set_attr "mode" "V2DF")])
22377
22378 (define_insn "sse2_pmovmskb"
22379 [(set (match_operand:SI 0 "register_operand" "=r")
22380 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22381 UNSPEC_MOVMSK))]
22382 "TARGET_SSE2"
22383 "pmovmskb\t{%1, %0|%0, %1}"
22384 [(set_attr "type" "ssecvt")
22385 (set_attr "mode" "V2DF")])
22386
22387 (define_insn "sse2_maskmovdqu"
22388 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22389 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22390 (match_operand:V16QI 2 "register_operand" "x")]
22391 UNSPEC_MASKMOV))]
22392 "TARGET_SSE2"
22393 ;; @@@ check ordering of operands in intel/nonintel syntax
22394 "maskmovdqu\t{%2, %1|%1, %2}"
22395 [(set_attr "type" "ssecvt")
22396 (set_attr "mode" "TI")])
22397
22398 (define_insn "sse2_maskmovdqu_rex64"
22399 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22400 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22401 (match_operand:V16QI 2 "register_operand" "x")]
22402 UNSPEC_MASKMOV))]
22403 "TARGET_SSE2"
22404 ;; @@@ check ordering of operands in intel/nonintel syntax
22405 "maskmovdqu\t{%2, %1|%1, %2}"
22406 [(set_attr "type" "ssecvt")
22407 (set_attr "mode" "TI")])
22408
22409 (define_insn "sse2_movntv2df"
22410 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22411 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22412 UNSPEC_MOVNT))]
22413 "TARGET_SSE2"
22414 "movntpd\t{%1, %0|%0, %1}"
22415 [(set_attr "type" "ssecvt")
22416 (set_attr "mode" "V2DF")])
22417
22418 (define_insn "sse2_movntv2di"
22419 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22420 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22421 UNSPEC_MOVNT))]
22422 "TARGET_SSE2"
22423 "movntdq\t{%1, %0|%0, %1}"
22424 [(set_attr "type" "ssecvt")
22425 (set_attr "mode" "TI")])
22426
22427 (define_insn "sse2_movntsi"
22428 [(set (match_operand:SI 0 "memory_operand" "=m")
22429 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22430 UNSPEC_MOVNT))]
22431 "TARGET_SSE2"
22432 "movnti\t{%1, %0|%0, %1}"
22433 [(set_attr "type" "ssecvt")
22434 (set_attr "mode" "V2DF")])
22435
22436 ;; SSE <-> integer/MMX conversions
22437
22438 ;; Conversions between SI and SF
22439
22440 (define_insn "cvtdq2ps"
22441 [(set (match_operand:V4SF 0 "register_operand" "=x")
22442 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22443 "TARGET_SSE2"
22444 "cvtdq2ps\t{%1, %0|%0, %1}"
22445 [(set_attr "type" "ssecvt")
22446 (set_attr "mode" "V2DF")])
22447
22448 (define_insn "cvtps2dq"
22449 [(set (match_operand:V4SI 0 "register_operand" "=x")
22450 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22451 "TARGET_SSE2"
22452 "cvtps2dq\t{%1, %0|%0, %1}"
22453 [(set_attr "type" "ssecvt")
22454 (set_attr "mode" "TI")])
22455
22456 (define_insn "cvttps2dq"
22457 [(set (match_operand:V4SI 0 "register_operand" "=x")
22458 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22459 UNSPEC_FIX))]
22460 "TARGET_SSE2"
22461 "cvttps2dq\t{%1, %0|%0, %1}"
22462 [(set_attr "type" "ssecvt")
22463 (set_attr "mode" "TI")])
22464
22465 ;; Conversions between SI and DF
22466
22467 (define_insn "cvtdq2pd"
22468 [(set (match_operand:V2DF 0 "register_operand" "=x")
22469 (float:V2DF (vec_select:V2SI
22470 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22471 (parallel
22472 [(const_int 0)
22473 (const_int 1)]))))]
22474 "TARGET_SSE2"
22475 "cvtdq2pd\t{%1, %0|%0, %1}"
22476 [(set_attr "type" "ssecvt")
22477 (set_attr "mode" "V2DF")])
22478
22479 (define_insn "cvtpd2dq"
22480 [(set (match_operand:V4SI 0 "register_operand" "=x")
22481 (vec_concat:V4SI
22482 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22483 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22484 "TARGET_SSE2"
22485 "cvtpd2dq\t{%1, %0|%0, %1}"
22486 [(set_attr "type" "ssecvt")
22487 (set_attr "mode" "TI")])
22488
22489 (define_insn "cvttpd2dq"
22490 [(set (match_operand:V4SI 0 "register_operand" "=x")
22491 (vec_concat:V4SI
22492 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22493 UNSPEC_FIX)
22494 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22495 "TARGET_SSE2"
22496 "cvttpd2dq\t{%1, %0|%0, %1}"
22497 [(set_attr "type" "ssecvt")
22498 (set_attr "mode" "TI")])
22499
22500 (define_insn "cvtpd2pi"
22501 [(set (match_operand:V2SI 0 "register_operand" "=y")
22502 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22503 "TARGET_SSE2"
22504 "cvtpd2pi\t{%1, %0|%0, %1}"
22505 [(set_attr "type" "ssecvt")
22506 (set_attr "mode" "TI")])
22507
22508 (define_insn "cvttpd2pi"
22509 [(set (match_operand:V2SI 0 "register_operand" "=y")
22510 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22511 UNSPEC_FIX))]
22512 "TARGET_SSE2"
22513 "cvttpd2pi\t{%1, %0|%0, %1}"
22514 [(set_attr "type" "ssecvt")
22515 (set_attr "mode" "TI")])
22516
22517 (define_insn "cvtpi2pd"
22518 [(set (match_operand:V2DF 0 "register_operand" "=x")
22519 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22520 "TARGET_SSE2"
22521 "cvtpi2pd\t{%1, %0|%0, %1}"
22522 [(set_attr "type" "ssecvt")
22523 (set_attr "mode" "TI")])
22524
22525 ;; Conversions between SI and DF
22526
22527 (define_insn "cvtsd2si"
22528 [(set (match_operand:SI 0 "register_operand" "=r,r")
22529 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22530 (parallel [(const_int 0)]))))]
22531 "TARGET_SSE2"
22532 "cvtsd2si\t{%1, %0|%0, %1}"
22533 [(set_attr "type" "sseicvt")
22534 (set_attr "athlon_decode" "double,vector")
22535 (set_attr "mode" "SI")])
22536
22537 (define_insn "cvtsd2siq"
22538 [(set (match_operand:DI 0 "register_operand" "=r,r")
22539 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22540 (parallel [(const_int 0)]))))]
22541 "TARGET_SSE2 && TARGET_64BIT"
22542 "cvtsd2siq\t{%1, %0|%0, %1}"
22543 [(set_attr "type" "sseicvt")
22544 (set_attr "athlon_decode" "double,vector")
22545 (set_attr "mode" "DI")])
22546
22547 (define_insn "cvttsd2si"
22548 [(set (match_operand:SI 0 "register_operand" "=r,r")
22549 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22550 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22551 "TARGET_SSE2"
22552 "cvttsd2si\t{%1, %0|%0, %1}"
22553 [(set_attr "type" "sseicvt")
22554 (set_attr "mode" "SI")
22555 (set_attr "athlon_decode" "double,vector")])
22556
22557 (define_insn "cvttsd2siq"
22558 [(set (match_operand:DI 0 "register_operand" "=r,r")
22559 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22560 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22561 "TARGET_SSE2 && TARGET_64BIT"
22562 "cvttsd2siq\t{%1, %0|%0, %1}"
22563 [(set_attr "type" "sseicvt")
22564 (set_attr "mode" "DI")
22565 (set_attr "athlon_decode" "double,vector")])
22566
22567 (define_insn "cvtsi2sd"
22568 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22569 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22570 (vec_duplicate:V2DF
22571 (float:DF
22572 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22573 (const_int 2)))]
22574 "TARGET_SSE2"
22575 "cvtsi2sd\t{%2, %0|%0, %2}"
22576 [(set_attr "type" "sseicvt")
22577 (set_attr "mode" "DF")
22578 (set_attr "athlon_decode" "double,direct")])
22579
22580 (define_insn "cvtsi2sdq"
22581 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22582 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22583 (vec_duplicate:V2DF
22584 (float:DF
22585 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22586 (const_int 2)))]
22587 "TARGET_SSE2 && TARGET_64BIT"
22588 "cvtsi2sdq\t{%2, %0|%0, %2}"
22589 [(set_attr "type" "sseicvt")
22590 (set_attr "mode" "DF")
22591 (set_attr "athlon_decode" "double,direct")])
22592
22593 ;; Conversions between SF and DF
22594
22595 (define_insn "cvtsd2ss"
22596 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22597 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22598 (vec_duplicate:V4SF
22599 (float_truncate:V2SF
22600 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22601 (const_int 14)))]
22602 "TARGET_SSE2"
22603 "cvtsd2ss\t{%2, %0|%0, %2}"
22604 [(set_attr "type" "ssecvt")
22605 (set_attr "athlon_decode" "vector,double")
22606 (set_attr "mode" "SF")])
22607
22608 (define_insn "cvtss2sd"
22609 [(set (match_operand:V2DF 0 "register_operand" "=x")
22610 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22611 (float_extend:V2DF
22612 (vec_select:V2SF
22613 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22614 (parallel [(const_int 0)
22615 (const_int 1)])))
22616 (const_int 2)))]
22617 "TARGET_SSE2"
22618 "cvtss2sd\t{%2, %0|%0, %2}"
22619 [(set_attr "type" "ssecvt")
22620 (set_attr "mode" "DF")])
22621
22622 (define_insn "cvtpd2ps"
22623 [(set (match_operand:V4SF 0 "register_operand" "=x")
22624 (subreg:V4SF
22625 (vec_concat:V4SI
22626 (subreg:V2SI (float_truncate:V2SF
22627 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22628 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22629 "TARGET_SSE2"
22630 "cvtpd2ps\t{%1, %0|%0, %1}"
22631 [(set_attr "type" "ssecvt")
22632 (set_attr "mode" "V4SF")])
22633
22634 (define_insn "cvtps2pd"
22635 [(set (match_operand:V2DF 0 "register_operand" "=x")
22636 (float_extend:V2DF
22637 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22638 (parallel [(const_int 0)
22639 (const_int 1)]))))]
22640 "TARGET_SSE2"
22641 "cvtps2pd\t{%1, %0|%0, %1}"
22642 [(set_attr "type" "ssecvt")
22643 (set_attr "mode" "V2DF")])
22644
22645 ;; SSE2 variants of MMX insns
22646
22647 ;; MMX arithmetic
22648
22649 (define_insn "addv16qi3"
22650 [(set (match_operand:V16QI 0 "register_operand" "=x")
22651 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22652 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22653 "TARGET_SSE2"
22654 "paddb\t{%2, %0|%0, %2}"
22655 [(set_attr "type" "sseiadd")
22656 (set_attr "mode" "TI")])
22657
22658 (define_insn "addv8hi3"
22659 [(set (match_operand:V8HI 0 "register_operand" "=x")
22660 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22661 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22662 "TARGET_SSE2"
22663 "paddw\t{%2, %0|%0, %2}"
22664 [(set_attr "type" "sseiadd")
22665 (set_attr "mode" "TI")])
22666
22667 (define_insn "addv4si3"
22668 [(set (match_operand:V4SI 0 "register_operand" "=x")
22669 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22670 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22671 "TARGET_SSE2"
22672 "paddd\t{%2, %0|%0, %2}"
22673 [(set_attr "type" "sseiadd")
22674 (set_attr "mode" "TI")])
22675
22676 (define_insn "addv2di3"
22677 [(set (match_operand:V2DI 0 "register_operand" "=x")
22678 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22679 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22680 "TARGET_SSE2"
22681 "paddq\t{%2, %0|%0, %2}"
22682 [(set_attr "type" "sseiadd")
22683 (set_attr "mode" "TI")])
22684
22685 (define_insn "ssaddv16qi3"
22686 [(set (match_operand:V16QI 0 "register_operand" "=x")
22687 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22688 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22689 "TARGET_SSE2"
22690 "paddsb\t{%2, %0|%0, %2}"
22691 [(set_attr "type" "sseiadd")
22692 (set_attr "mode" "TI")])
22693
22694 (define_insn "ssaddv8hi3"
22695 [(set (match_operand:V8HI 0 "register_operand" "=x")
22696 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22697 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22698 "TARGET_SSE2"
22699 "paddsw\t{%2, %0|%0, %2}"
22700 [(set_attr "type" "sseiadd")
22701 (set_attr "mode" "TI")])
22702
22703 (define_insn "usaddv16qi3"
22704 [(set (match_operand:V16QI 0 "register_operand" "=x")
22705 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22706 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22707 "TARGET_SSE2"
22708 "paddusb\t{%2, %0|%0, %2}"
22709 [(set_attr "type" "sseiadd")
22710 (set_attr "mode" "TI")])
22711
22712 (define_insn "usaddv8hi3"
22713 [(set (match_operand:V8HI 0 "register_operand" "=x")
22714 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22715 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22716 "TARGET_SSE2"
22717 "paddusw\t{%2, %0|%0, %2}"
22718 [(set_attr "type" "sseiadd")
22719 (set_attr "mode" "TI")])
22720
22721 (define_insn "subv16qi3"
22722 [(set (match_operand:V16QI 0 "register_operand" "=x")
22723 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22724 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22725 "TARGET_SSE2"
22726 "psubb\t{%2, %0|%0, %2}"
22727 [(set_attr "type" "sseiadd")
22728 (set_attr "mode" "TI")])
22729
22730 (define_insn "subv8hi3"
22731 [(set (match_operand:V8HI 0 "register_operand" "=x")
22732 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22733 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22734 "TARGET_SSE2"
22735 "psubw\t{%2, %0|%0, %2}"
22736 [(set_attr "type" "sseiadd")
22737 (set_attr "mode" "TI")])
22738
22739 (define_insn "subv4si3"
22740 [(set (match_operand:V4SI 0 "register_operand" "=x")
22741 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22742 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22743 "TARGET_SSE2"
22744 "psubd\t{%2, %0|%0, %2}"
22745 [(set_attr "type" "sseiadd")
22746 (set_attr "mode" "TI")])
22747
22748 (define_insn "subv2di3"
22749 [(set (match_operand:V2DI 0 "register_operand" "=x")
22750 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22751 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22752 "TARGET_SSE2"
22753 "psubq\t{%2, %0|%0, %2}"
22754 [(set_attr "type" "sseiadd")
22755 (set_attr "mode" "TI")])
22756
22757 (define_insn "sssubv16qi3"
22758 [(set (match_operand:V16QI 0 "register_operand" "=x")
22759 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22760 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22761 "TARGET_SSE2"
22762 "psubsb\t{%2, %0|%0, %2}"
22763 [(set_attr "type" "sseiadd")
22764 (set_attr "mode" "TI")])
22765
22766 (define_insn "sssubv8hi3"
22767 [(set (match_operand:V8HI 0 "register_operand" "=x")
22768 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22769 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22770 "TARGET_SSE2"
22771 "psubsw\t{%2, %0|%0, %2}"
22772 [(set_attr "type" "sseiadd")
22773 (set_attr "mode" "TI")])
22774
22775 (define_insn "ussubv16qi3"
22776 [(set (match_operand:V16QI 0 "register_operand" "=x")
22777 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22778 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22779 "TARGET_SSE2"
22780 "psubusb\t{%2, %0|%0, %2}"
22781 [(set_attr "type" "sseiadd")
22782 (set_attr "mode" "TI")])
22783
22784 (define_insn "ussubv8hi3"
22785 [(set (match_operand:V8HI 0 "register_operand" "=x")
22786 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22787 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22788 "TARGET_SSE2"
22789 "psubusw\t{%2, %0|%0, %2}"
22790 [(set_attr "type" "sseiadd")
22791 (set_attr "mode" "TI")])
22792
22793 (define_insn "mulv8hi3"
22794 [(set (match_operand:V8HI 0 "register_operand" "=x")
22795 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22796 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22797 "TARGET_SSE2"
22798 "pmullw\t{%2, %0|%0, %2}"
22799 [(set_attr "type" "sseimul")
22800 (set_attr "mode" "TI")])
22801
22802 (define_insn "smulv8hi3_highpart"
22803 [(set (match_operand:V8HI 0 "register_operand" "=x")
22804 (truncate:V8HI
22805 (lshiftrt:V8SI
22806 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22807 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22808 (const_int 16))))]
22809 "TARGET_SSE2"
22810 "pmulhw\t{%2, %0|%0, %2}"
22811 [(set_attr "type" "sseimul")
22812 (set_attr "mode" "TI")])
22813
22814 (define_insn "umulv8hi3_highpart"
22815 [(set (match_operand:V8HI 0 "register_operand" "=x")
22816 (truncate:V8HI
22817 (lshiftrt:V8SI
22818 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22819 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22820 (const_int 16))))]
22821 "TARGET_SSE2"
22822 "pmulhuw\t{%2, %0|%0, %2}"
22823 [(set_attr "type" "sseimul")
22824 (set_attr "mode" "TI")])
22825
22826 (define_insn "sse2_umulsidi3"
22827 [(set (match_operand:DI 0 "register_operand" "=y")
22828 (mult:DI (zero_extend:DI (vec_select:SI
22829 (match_operand:V2SI 1 "register_operand" "0")
22830 (parallel [(const_int 0)])))
22831 (zero_extend:DI (vec_select:SI
22832 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22833 (parallel [(const_int 0)])))))]
22834 "TARGET_SSE2"
22835 "pmuludq\t{%2, %0|%0, %2}"
22836 [(set_attr "type" "sseimul")
22837 (set_attr "mode" "TI")])
22838
22839 (define_insn "sse2_umulv2siv2di3"
22840 [(set (match_operand:V2DI 0 "register_operand" "=x")
22841 (mult:V2DI (zero_extend:V2DI
22842 (vec_select:V2SI
22843 (match_operand:V4SI 1 "register_operand" "0")
22844 (parallel [(const_int 0) (const_int 2)])))
22845 (zero_extend:V2DI
22846 (vec_select:V2SI
22847 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22848 (parallel [(const_int 0) (const_int 2)])))))]
22849 "TARGET_SSE2"
22850 "pmuludq\t{%2, %0|%0, %2}"
22851 [(set_attr "type" "sseimul")
22852 (set_attr "mode" "TI")])
22853
22854 (define_insn "sse2_pmaddwd"
22855 [(set (match_operand:V4SI 0 "register_operand" "=x")
22856 (plus:V4SI
22857 (mult:V4SI
22858 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22859 (parallel [(const_int 0)
22860 (const_int 2)
22861 (const_int 4)
22862 (const_int 6)])))
22863 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22864 (parallel [(const_int 0)
22865 (const_int 2)
22866 (const_int 4)
22867 (const_int 6)]))))
22868 (mult:V4SI
22869 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22870 (parallel [(const_int 1)
22871 (const_int 3)
22872 (const_int 5)
22873 (const_int 7)])))
22874 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22875 (parallel [(const_int 1)
22876 (const_int 3)
22877 (const_int 5)
22878 (const_int 7)]))))))]
22879 "TARGET_SSE2"
22880 "pmaddwd\t{%2, %0|%0, %2}"
22881 [(set_attr "type" "sseiadd")
22882 (set_attr "mode" "TI")])
22883
22884 ;; Same as pxor, but don't show input operands so that we don't think
22885 ;; they are live.
22886 (define_insn "sse2_clrti"
22887 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22888 "TARGET_SSE2"
22889 {
22890 if (get_attr_mode (insn) == MODE_TI)
22891 return "pxor\t%0, %0";
22892 else
22893 return "xorps\t%0, %0";
22894 }
22895 [(set_attr "type" "ssemov")
22896 (set_attr "memory" "none")
22897 (set (attr "mode")
22898 (if_then_else
22899 (ne (symbol_ref "optimize_size")
22900 (const_int 0))
22901 (const_string "V4SF")
22902 (const_string "TI")))])
22903
22904 ;; MMX unsigned averages/sum of absolute differences
22905
22906 (define_insn "sse2_uavgv16qi3"
22907 [(set (match_operand:V16QI 0 "register_operand" "=x")
22908 (ashiftrt:V16QI
22909 (plus:V16QI (plus:V16QI
22910 (match_operand:V16QI 1 "register_operand" "0")
22911 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22912 (const_vector:V16QI [(const_int 1) (const_int 1)
22913 (const_int 1) (const_int 1)
22914 (const_int 1) (const_int 1)
22915 (const_int 1) (const_int 1)
22916 (const_int 1) (const_int 1)
22917 (const_int 1) (const_int 1)
22918 (const_int 1) (const_int 1)
22919 (const_int 1) (const_int 1)]))
22920 (const_int 1)))]
22921 "TARGET_SSE2"
22922 "pavgb\t{%2, %0|%0, %2}"
22923 [(set_attr "type" "sseiadd")
22924 (set_attr "mode" "TI")])
22925
22926 (define_insn "sse2_uavgv8hi3"
22927 [(set (match_operand:V8HI 0 "register_operand" "=x")
22928 (ashiftrt:V8HI
22929 (plus:V8HI (plus:V8HI
22930 (match_operand:V8HI 1 "register_operand" "0")
22931 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22932 (const_vector:V8HI [(const_int 1) (const_int 1)
22933 (const_int 1) (const_int 1)
22934 (const_int 1) (const_int 1)
22935 (const_int 1) (const_int 1)]))
22936 (const_int 1)))]
22937 "TARGET_SSE2"
22938 "pavgw\t{%2, %0|%0, %2}"
22939 [(set_attr "type" "sseiadd")
22940 (set_attr "mode" "TI")])
22941
22942 ;; @@@ this isn't the right representation.
22943 (define_insn "sse2_psadbw"
22944 [(set (match_operand:V2DI 0 "register_operand" "=x")
22945 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22946 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22947 UNSPEC_PSADBW))]
22948 "TARGET_SSE2"
22949 "psadbw\t{%2, %0|%0, %2}"
22950 [(set_attr "type" "sseiadd")
22951 (set_attr "mode" "TI")])
22952
22953
22954 ;; MMX insert/extract/shuffle
22955
22956 (define_insn "sse2_pinsrw"
22957 [(set (match_operand:V8HI 0 "register_operand" "=x")
22958 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22959 (vec_duplicate:V8HI
22960 (truncate:HI
22961 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22962 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22963 "TARGET_SSE2"
22964 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22965 [(set_attr "type" "ssecvt")
22966 (set_attr "mode" "TI")])
22967
22968 (define_insn "sse2_pextrw"
22969 [(set (match_operand:SI 0 "register_operand" "=r")
22970 (zero_extend:SI
22971 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22972 (parallel
22973 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22974 "TARGET_SSE2"
22975 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22976 [(set_attr "type" "ssecvt")
22977 (set_attr "mode" "TI")])
22978
22979 (define_insn "sse2_pshufd"
22980 [(set (match_operand:V4SI 0 "register_operand" "=x")
22981 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22982 (match_operand:SI 2 "immediate_operand" "i")]
22983 UNSPEC_SHUFFLE))]
22984 "TARGET_SSE2"
22985 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22986 [(set_attr "type" "ssecvt")
22987 (set_attr "mode" "TI")])
22988
22989 (define_insn "sse2_pshuflw"
22990 [(set (match_operand:V8HI 0 "register_operand" "=x")
22991 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22992 (match_operand:SI 2 "immediate_operand" "i")]
22993 UNSPEC_PSHUFLW))]
22994 "TARGET_SSE2"
22995 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22996 [(set_attr "type" "ssecvt")
22997 (set_attr "mode" "TI")])
22998
22999 (define_insn "sse2_pshufhw"
23000 [(set (match_operand:V8HI 0 "register_operand" "=x")
23001 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
23002 (match_operand:SI 2 "immediate_operand" "i")]
23003 UNSPEC_PSHUFHW))]
23004 "TARGET_SSE2"
23005 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23006 [(set_attr "type" "ssecvt")
23007 (set_attr "mode" "TI")])
23008
23009 ;; MMX mask-generating comparisons
23010
23011 (define_insn "eqv16qi3"
23012 [(set (match_operand:V16QI 0 "register_operand" "=x")
23013 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23014 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23015 "TARGET_SSE2"
23016 "pcmpeqb\t{%2, %0|%0, %2}"
23017 [(set_attr "type" "ssecmp")
23018 (set_attr "mode" "TI")])
23019
23020 (define_insn "eqv8hi3"
23021 [(set (match_operand:V8HI 0 "register_operand" "=x")
23022 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23023 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23024 "TARGET_SSE2"
23025 "pcmpeqw\t{%2, %0|%0, %2}"
23026 [(set_attr "type" "ssecmp")
23027 (set_attr "mode" "TI")])
23028
23029 (define_insn "eqv4si3"
23030 [(set (match_operand:V4SI 0 "register_operand" "=x")
23031 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23032 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23033 "TARGET_SSE2"
23034 "pcmpeqd\t{%2, %0|%0, %2}"
23035 [(set_attr "type" "ssecmp")
23036 (set_attr "mode" "TI")])
23037
23038 (define_insn "gtv16qi3"
23039 [(set (match_operand:V16QI 0 "register_operand" "=x")
23040 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23041 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23042 "TARGET_SSE2"
23043 "pcmpgtb\t{%2, %0|%0, %2}"
23044 [(set_attr "type" "ssecmp")
23045 (set_attr "mode" "TI")])
23046
23047 (define_insn "gtv8hi3"
23048 [(set (match_operand:V8HI 0 "register_operand" "=x")
23049 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23050 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23051 "TARGET_SSE2"
23052 "pcmpgtw\t{%2, %0|%0, %2}"
23053 [(set_attr "type" "ssecmp")
23054 (set_attr "mode" "TI")])
23055
23056 (define_insn "gtv4si3"
23057 [(set (match_operand:V4SI 0 "register_operand" "=x")
23058 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23059 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23060 "TARGET_SSE2"
23061 "pcmpgtd\t{%2, %0|%0, %2}"
23062 [(set_attr "type" "ssecmp")
23063 (set_attr "mode" "TI")])
23064
23065
23066 ;; MMX max/min insns
23067
23068 (define_insn "umaxv16qi3"
23069 [(set (match_operand:V16QI 0 "register_operand" "=x")
23070 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23071 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23072 "TARGET_SSE2"
23073 "pmaxub\t{%2, %0|%0, %2}"
23074 [(set_attr "type" "sseiadd")
23075 (set_attr "mode" "TI")])
23076
23077 (define_insn "smaxv8hi3"
23078 [(set (match_operand:V8HI 0 "register_operand" "=x")
23079 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23080 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23081 "TARGET_SSE2"
23082 "pmaxsw\t{%2, %0|%0, %2}"
23083 [(set_attr "type" "sseiadd")
23084 (set_attr "mode" "TI")])
23085
23086 (define_insn "uminv16qi3"
23087 [(set (match_operand:V16QI 0 "register_operand" "=x")
23088 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23089 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23090 "TARGET_SSE2"
23091 "pminub\t{%2, %0|%0, %2}"
23092 [(set_attr "type" "sseiadd")
23093 (set_attr "mode" "TI")])
23094
23095 (define_insn "sminv8hi3"
23096 [(set (match_operand:V8HI 0 "register_operand" "=x")
23097 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23098 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23099 "TARGET_SSE2"
23100 "pminsw\t{%2, %0|%0, %2}"
23101 [(set_attr "type" "sseiadd")
23102 (set_attr "mode" "TI")])
23103
23104
23105 ;; MMX shifts
23106
23107 (define_insn "ashrv8hi3"
23108 [(set (match_operand:V8HI 0 "register_operand" "=x")
23109 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23110 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23111 "TARGET_SSE2"
23112 "psraw\t{%2, %0|%0, %2}"
23113 [(set_attr "type" "sseishft")
23114 (set_attr "mode" "TI")])
23115
23116 (define_insn "ashrv4si3"
23117 [(set (match_operand:V4SI 0 "register_operand" "=x")
23118 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23119 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23120 "TARGET_SSE2"
23121 "psrad\t{%2, %0|%0, %2}"
23122 [(set_attr "type" "sseishft")
23123 (set_attr "mode" "TI")])
23124
23125 (define_insn "lshrv8hi3"
23126 [(set (match_operand:V8HI 0 "register_operand" "=x")
23127 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23128 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23129 "TARGET_SSE2"
23130 "psrlw\t{%2, %0|%0, %2}"
23131 [(set_attr "type" "sseishft")
23132 (set_attr "mode" "TI")])
23133
23134 (define_insn "lshrv4si3"
23135 [(set (match_operand:V4SI 0 "register_operand" "=x")
23136 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23137 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23138 "TARGET_SSE2"
23139 "psrld\t{%2, %0|%0, %2}"
23140 [(set_attr "type" "sseishft")
23141 (set_attr "mode" "TI")])
23142
23143 (define_insn "lshrv2di3"
23144 [(set (match_operand:V2DI 0 "register_operand" "=x")
23145 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23146 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23147 "TARGET_SSE2"
23148 "psrlq\t{%2, %0|%0, %2}"
23149 [(set_attr "type" "sseishft")
23150 (set_attr "mode" "TI")])
23151
23152 (define_insn "ashlv8hi3"
23153 [(set (match_operand:V8HI 0 "register_operand" "=x")
23154 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23155 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23156 "TARGET_SSE2"
23157 "psllw\t{%2, %0|%0, %2}"
23158 [(set_attr "type" "sseishft")
23159 (set_attr "mode" "TI")])
23160
23161 (define_insn "ashlv4si3"
23162 [(set (match_operand:V4SI 0 "register_operand" "=x")
23163 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23164 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23165 "TARGET_SSE2"
23166 "pslld\t{%2, %0|%0, %2}"
23167 [(set_attr "type" "sseishft")
23168 (set_attr "mode" "TI")])
23169
23170 (define_insn "ashlv2di3"
23171 [(set (match_operand:V2DI 0 "register_operand" "=x")
23172 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23173 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23174 "TARGET_SSE2"
23175 "psllq\t{%2, %0|%0, %2}"
23176 [(set_attr "type" "sseishft")
23177 (set_attr "mode" "TI")])
23178
23179 (define_insn "ashrv8hi3_ti"
23180 [(set (match_operand:V8HI 0 "register_operand" "=x")
23181 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23182 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23183 "TARGET_SSE2"
23184 "psraw\t{%2, %0|%0, %2}"
23185 [(set_attr "type" "sseishft")
23186 (set_attr "mode" "TI")])
23187
23188 (define_insn "ashrv4si3_ti"
23189 [(set (match_operand:V4SI 0 "register_operand" "=x")
23190 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23191 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23192 "TARGET_SSE2"
23193 "psrad\t{%2, %0|%0, %2}"
23194 [(set_attr "type" "sseishft")
23195 (set_attr "mode" "TI")])
23196
23197 (define_insn "lshrv8hi3_ti"
23198 [(set (match_operand:V8HI 0 "register_operand" "=x")
23199 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23200 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23201 "TARGET_SSE2"
23202 "psrlw\t{%2, %0|%0, %2}"
23203 [(set_attr "type" "sseishft")
23204 (set_attr "mode" "TI")])
23205
23206 (define_insn "lshrv4si3_ti"
23207 [(set (match_operand:V4SI 0 "register_operand" "=x")
23208 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23209 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23210 "TARGET_SSE2"
23211 "psrld\t{%2, %0|%0, %2}"
23212 [(set_attr "type" "sseishft")
23213 (set_attr "mode" "TI")])
23214
23215 (define_insn "lshrv2di3_ti"
23216 [(set (match_operand:V2DI 0 "register_operand" "=x")
23217 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23218 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23219 "TARGET_SSE2"
23220 "psrlq\t{%2, %0|%0, %2}"
23221 [(set_attr "type" "sseishft")
23222 (set_attr "mode" "TI")])
23223
23224 (define_insn "ashlv8hi3_ti"
23225 [(set (match_operand:V8HI 0 "register_operand" "=x")
23226 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23227 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23228 "TARGET_SSE2"
23229 "psllw\t{%2, %0|%0, %2}"
23230 [(set_attr "type" "sseishft")
23231 (set_attr "mode" "TI")])
23232
23233 (define_insn "ashlv4si3_ti"
23234 [(set (match_operand:V4SI 0 "register_operand" "=x")
23235 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23236 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23237 "TARGET_SSE2"
23238 "pslld\t{%2, %0|%0, %2}"
23239 [(set_attr "type" "sseishft")
23240 (set_attr "mode" "TI")])
23241
23242 (define_insn "ashlv2di3_ti"
23243 [(set (match_operand:V2DI 0 "register_operand" "=x")
23244 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23245 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23246 "TARGET_SSE2"
23247 "psllq\t{%2, %0|%0, %2}"
23248 [(set_attr "type" "sseishft")
23249 (set_attr "mode" "TI")])
23250
23251 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23252 ;; we wouldn't need here it since we never generate TImode arithmetic.
23253
23254 ;; There has to be some kind of prize for the weirdest new instruction...
23255 (define_insn "sse2_ashlti3"
23256 [(set (match_operand:TI 0 "register_operand" "=x")
23257 (unspec:TI
23258 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23259 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23260 (const_int 8)))] UNSPEC_NOP))]
23261 "TARGET_SSE2"
23262 "pslldq\t{%2, %0|%0, %2}"
23263 [(set_attr "type" "sseishft")
23264 (set_attr "mode" "TI")])
23265
23266 (define_insn "sse2_lshrti3"
23267 [(set (match_operand:TI 0 "register_operand" "=x")
23268 (unspec:TI
23269 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23270 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23271 (const_int 8)))] UNSPEC_NOP))]
23272 "TARGET_SSE2"
23273 "psrldq\t{%2, %0|%0, %2}"
23274 [(set_attr "type" "sseishft")
23275 (set_attr "mode" "TI")])
23276
23277 ;; SSE unpack
23278
23279 (define_insn "sse2_unpckhpd"
23280 [(set (match_operand:V2DF 0 "register_operand" "=x")
23281 (vec_concat:V2DF
23282 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23283 (parallel [(const_int 1)]))
23284 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23285 (parallel [(const_int 0)]))))]
23286 "TARGET_SSE2"
23287 "unpckhpd\t{%2, %0|%0, %2}"
23288 [(set_attr "type" "ssecvt")
23289 (set_attr "mode" "TI")])
23290
23291 (define_insn "sse2_unpcklpd"
23292 [(set (match_operand:V2DF 0 "register_operand" "=x")
23293 (vec_concat:V2DF
23294 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23295 (parallel [(const_int 0)]))
23296 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23297 (parallel [(const_int 1)]))))]
23298 "TARGET_SSE2"
23299 "unpcklpd\t{%2, %0|%0, %2}"
23300 [(set_attr "type" "ssecvt")
23301 (set_attr "mode" "TI")])
23302
23303 ;; MMX pack/unpack insns.
23304
23305 (define_insn "sse2_packsswb"
23306 [(set (match_operand:V16QI 0 "register_operand" "=x")
23307 (vec_concat:V16QI
23308 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23309 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23310 "TARGET_SSE2"
23311 "packsswb\t{%2, %0|%0, %2}"
23312 [(set_attr "type" "ssecvt")
23313 (set_attr "mode" "TI")])
23314
23315 (define_insn "sse2_packssdw"
23316 [(set (match_operand:V8HI 0 "register_operand" "=x")
23317 (vec_concat:V8HI
23318 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23319 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23320 "TARGET_SSE2"
23321 "packssdw\t{%2, %0|%0, %2}"
23322 [(set_attr "type" "ssecvt")
23323 (set_attr "mode" "TI")])
23324
23325 (define_insn "sse2_packuswb"
23326 [(set (match_operand:V16QI 0 "register_operand" "=x")
23327 (vec_concat:V16QI
23328 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23329 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23330 "TARGET_SSE2"
23331 "packuswb\t{%2, %0|%0, %2}"
23332 [(set_attr "type" "ssecvt")
23333 (set_attr "mode" "TI")])
23334
23335 (define_insn "sse2_punpckhbw"
23336 [(set (match_operand:V16QI 0 "register_operand" "=x")
23337 (vec_merge:V16QI
23338 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23339 (parallel [(const_int 8) (const_int 0)
23340 (const_int 9) (const_int 1)
23341 (const_int 10) (const_int 2)
23342 (const_int 11) (const_int 3)
23343 (const_int 12) (const_int 4)
23344 (const_int 13) (const_int 5)
23345 (const_int 14) (const_int 6)
23346 (const_int 15) (const_int 7)]))
23347 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23348 (parallel [(const_int 0) (const_int 8)
23349 (const_int 1) (const_int 9)
23350 (const_int 2) (const_int 10)
23351 (const_int 3) (const_int 11)
23352 (const_int 4) (const_int 12)
23353 (const_int 5) (const_int 13)
23354 (const_int 6) (const_int 14)
23355 (const_int 7) (const_int 15)]))
23356 (const_int 21845)))]
23357 "TARGET_SSE2"
23358 "punpckhbw\t{%2, %0|%0, %2}"
23359 [(set_attr "type" "ssecvt")
23360 (set_attr "mode" "TI")])
23361
23362 (define_insn "sse2_punpckhwd"
23363 [(set (match_operand:V8HI 0 "register_operand" "=x")
23364 (vec_merge:V8HI
23365 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23366 (parallel [(const_int 4) (const_int 0)
23367 (const_int 5) (const_int 1)
23368 (const_int 6) (const_int 2)
23369 (const_int 7) (const_int 3)]))
23370 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23371 (parallel [(const_int 0) (const_int 4)
23372 (const_int 1) (const_int 5)
23373 (const_int 2) (const_int 6)
23374 (const_int 3) (const_int 7)]))
23375 (const_int 85)))]
23376 "TARGET_SSE2"
23377 "punpckhwd\t{%2, %0|%0, %2}"
23378 [(set_attr "type" "ssecvt")
23379 (set_attr "mode" "TI")])
23380
23381 (define_insn "sse2_punpckhdq"
23382 [(set (match_operand:V4SI 0 "register_operand" "=x")
23383 (vec_merge:V4SI
23384 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23385 (parallel [(const_int 2) (const_int 0)
23386 (const_int 3) (const_int 1)]))
23387 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23388 (parallel [(const_int 0) (const_int 2)
23389 (const_int 1) (const_int 3)]))
23390 (const_int 5)))]
23391 "TARGET_SSE2"
23392 "punpckhdq\t{%2, %0|%0, %2}"
23393 [(set_attr "type" "ssecvt")
23394 (set_attr "mode" "TI")])
23395
23396 (define_insn "sse2_punpcklbw"
23397 [(set (match_operand:V16QI 0 "register_operand" "=x")
23398 (vec_merge:V16QI
23399 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23400 (parallel [(const_int 0) (const_int 8)
23401 (const_int 1) (const_int 9)
23402 (const_int 2) (const_int 10)
23403 (const_int 3) (const_int 11)
23404 (const_int 4) (const_int 12)
23405 (const_int 5) (const_int 13)
23406 (const_int 6) (const_int 14)
23407 (const_int 7) (const_int 15)]))
23408 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23409 (parallel [(const_int 8) (const_int 0)
23410 (const_int 9) (const_int 1)
23411 (const_int 10) (const_int 2)
23412 (const_int 11) (const_int 3)
23413 (const_int 12) (const_int 4)
23414 (const_int 13) (const_int 5)
23415 (const_int 14) (const_int 6)
23416 (const_int 15) (const_int 7)]))
23417 (const_int 21845)))]
23418 "TARGET_SSE2"
23419 "punpcklbw\t{%2, %0|%0, %2}"
23420 [(set_attr "type" "ssecvt")
23421 (set_attr "mode" "TI")])
23422
23423 (define_insn "sse2_punpcklwd"
23424 [(set (match_operand:V8HI 0 "register_operand" "=x")
23425 (vec_merge:V8HI
23426 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23427 (parallel [(const_int 0) (const_int 4)
23428 (const_int 1) (const_int 5)
23429 (const_int 2) (const_int 6)
23430 (const_int 3) (const_int 7)]))
23431 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23432 (parallel [(const_int 4) (const_int 0)
23433 (const_int 5) (const_int 1)
23434 (const_int 6) (const_int 2)
23435 (const_int 7) (const_int 3)]))
23436 (const_int 85)))]
23437 "TARGET_SSE2"
23438 "punpcklwd\t{%2, %0|%0, %2}"
23439 [(set_attr "type" "ssecvt")
23440 (set_attr "mode" "TI")])
23441
23442 (define_insn "sse2_punpckldq"
23443 [(set (match_operand:V4SI 0 "register_operand" "=x")
23444 (vec_merge:V4SI
23445 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23446 (parallel [(const_int 0) (const_int 2)
23447 (const_int 1) (const_int 3)]))
23448 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23449 (parallel [(const_int 2) (const_int 0)
23450 (const_int 3) (const_int 1)]))
23451 (const_int 5)))]
23452 "TARGET_SSE2"
23453 "punpckldq\t{%2, %0|%0, %2}"
23454 [(set_attr "type" "ssecvt")
23455 (set_attr "mode" "TI")])
23456
23457 (define_insn "sse2_punpcklqdq"
23458 [(set (match_operand:V2DI 0 "register_operand" "=x")
23459 (vec_merge:V2DI
23460 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23461 (parallel [(const_int 1)
23462 (const_int 0)]))
23463 (match_operand:V2DI 1 "register_operand" "0")
23464 (const_int 1)))]
23465 "TARGET_SSE2"
23466 "punpcklqdq\t{%2, %0|%0, %2}"
23467 [(set_attr "type" "ssecvt")
23468 (set_attr "mode" "TI")])
23469
23470 (define_insn "sse2_punpckhqdq"
23471 [(set (match_operand:V2DI 0 "register_operand" "=x")
23472 (vec_merge:V2DI
23473 (match_operand:V2DI 1 "register_operand" "0")
23474 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23475 (parallel [(const_int 1)
23476 (const_int 0)]))
23477 (const_int 1)))]
23478 "TARGET_SSE2"
23479 "punpckhqdq\t{%2, %0|%0, %2}"
23480 [(set_attr "type" "ssecvt")
23481 (set_attr "mode" "TI")])
23482
23483 ;; SSE2 moves
23484
23485 (define_insn "sse2_movapd"
23486 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23487 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23488 UNSPEC_MOVA))]
23489 "TARGET_SSE2
23490 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23491 "movapd\t{%1, %0|%0, %1}"
23492 [(set_attr "type" "ssemov")
23493 (set_attr "mode" "V2DF")])
23494
23495 (define_insn "sse2_movupd"
23496 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23497 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23498 UNSPEC_MOVU))]
23499 "TARGET_SSE2
23500 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23501 "movupd\t{%1, %0|%0, %1}"
23502 [(set_attr "type" "ssecvt")
23503 (set_attr "mode" "V2DF")])
23504
23505 (define_insn "sse2_movdqa"
23506 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23507 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23508 UNSPEC_MOVA))]
23509 "TARGET_SSE2
23510 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23511 "movdqa\t{%1, %0|%0, %1}"
23512 [(set_attr "type" "ssemov")
23513 (set_attr "mode" "TI")])
23514
23515 (define_insn "sse2_movdqu"
23516 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23517 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23518 UNSPEC_MOVU))]
23519 "TARGET_SSE2
23520 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23521 "movdqu\t{%1, %0|%0, %1}"
23522 [(set_attr "type" "ssecvt")
23523 (set_attr "mode" "TI")])
23524
23525 (define_insn "sse2_movdq2q"
23526 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23527 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23528 (parallel [(const_int 0)])))]
23529 "TARGET_SSE2 && !TARGET_64BIT"
23530 "@
23531 movq\t{%1, %0|%0, %1}
23532 movdq2q\t{%1, %0|%0, %1}"
23533 [(set_attr "type" "ssecvt")
23534 (set_attr "mode" "TI")])
23535
23536 (define_insn "sse2_movdq2q_rex64"
23537 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23538 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23539 (parallel [(const_int 0)])))]
23540 "TARGET_SSE2 && TARGET_64BIT"
23541 "@
23542 movq\t{%1, %0|%0, %1}
23543 movdq2q\t{%1, %0|%0, %1}
23544 movd\t{%1, %0|%0, %1}"
23545 [(set_attr "type" "ssecvt")
23546 (set_attr "mode" "TI")])
23547
23548 (define_insn "sse2_movq2dq"
23549 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23550 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23551 (const_int 0)))]
23552 "TARGET_SSE2 && !TARGET_64BIT"
23553 "@
23554 movq\t{%1, %0|%0, %1}
23555 movq2dq\t{%1, %0|%0, %1}"
23556 [(set_attr "type" "ssecvt,ssemov")
23557 (set_attr "mode" "TI")])
23558
23559 (define_insn "sse2_movq2dq_rex64"
23560 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23561 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23562 (const_int 0)))]
23563 "TARGET_SSE2 && TARGET_64BIT"
23564 "@
23565 movq\t{%1, %0|%0, %1}
23566 movq2dq\t{%1, %0|%0, %1}
23567 movd\t{%1, %0|%0, %1}"
23568 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23569 (set_attr "mode" "TI")])
23570
23571 (define_insn "sse2_movq"
23572 [(set (match_operand:V2DI 0 "register_operand" "=x")
23573 (vec_concat:V2DI (vec_select:DI
23574 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23575 (parallel [(const_int 0)]))
23576 (const_int 0)))]
23577 "TARGET_SSE2"
23578 "movq\t{%1, %0|%0, %1}"
23579 [(set_attr "type" "ssemov")
23580 (set_attr "mode" "TI")])
23581
23582 (define_insn "sse2_loadd"
23583 [(set (match_operand:V4SI 0 "register_operand" "=x")
23584 (vec_merge:V4SI
23585 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23586 (const_vector:V4SI [(const_int 0)
23587 (const_int 0)
23588 (const_int 0)
23589 (const_int 0)])
23590 (const_int 1)))]
23591 "TARGET_SSE2"
23592 "movd\t{%1, %0|%0, %1}"
23593 [(set_attr "type" "ssemov")
23594 (set_attr "mode" "TI")])
23595
23596 (define_insn "sse2_stored"
23597 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23598 (vec_select:SI
23599 (match_operand:V4SI 1 "register_operand" "x")
23600 (parallel [(const_int 0)])))]
23601 "TARGET_SSE2"
23602 "movd\t{%1, %0|%0, %1}"
23603 [(set_attr "type" "ssemov")
23604 (set_attr "mode" "TI")])
23605
23606 (define_insn "sse2_movhpd"
23607 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23608 (vec_merge:V2DF
23609 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23610 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23611 (const_int 2)))]
23612 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23613 "movhpd\t{%2, %0|%0, %2}"
23614 [(set_attr "type" "ssecvt")
23615 (set_attr "mode" "V2DF")])
23616
23617 (define_insn "sse2_movlpd"
23618 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23619 (vec_merge:V2DF
23620 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23621 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23622 (const_int 1)))]
23623 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23624 "movlpd\t{%2, %0|%0, %2}"
23625 [(set_attr "type" "ssecvt")
23626 (set_attr "mode" "V2DF")])
23627
23628 (define_expand "sse2_loadsd"
23629 [(match_operand:V2DF 0 "register_operand" "")
23630 (match_operand:DF 1 "memory_operand" "")]
23631 "TARGET_SSE2"
23632 {
23633 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23634 CONST0_RTX (V2DFmode)));
23635 DONE;
23636 })
23637
23638 (define_insn "sse2_loadsd_1"
23639 [(set (match_operand:V2DF 0 "register_operand" "=x")
23640 (vec_merge:V2DF
23641 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23642 (match_operand:V2DF 2 "const0_operand" "X")
23643 (const_int 1)))]
23644 "TARGET_SSE2"
23645 "movsd\t{%1, %0|%0, %1}"
23646 [(set_attr "type" "ssecvt")
23647 (set_attr "mode" "DF")])
23648
23649 (define_insn "sse2_movsd"
23650 [(set (match_operand:V2DF 0 "register_operand" "=x")
23651 (vec_merge:V2DF
23652 (match_operand:V2DF 1 "register_operand" "0")
23653 (match_operand:V2DF 2 "register_operand" "x")
23654 (const_int 1)))]
23655 "TARGET_SSE2"
23656 "movsd\t{%2, %0|%0, %2}"
23657 [(set_attr "type" "ssecvt")
23658 (set_attr "mode" "DF")])
23659
23660 (define_insn "sse2_storesd"
23661 [(set (match_operand:DF 0 "memory_operand" "=m")
23662 (vec_select:DF
23663 (match_operand:V2DF 1 "register_operand" "x")
23664 (parallel [(const_int 0)])))]
23665 "TARGET_SSE2"
23666 "movsd\t{%1, %0|%0, %1}"
23667 [(set_attr "type" "ssecvt")
23668 (set_attr "mode" "DF")])
23669
23670 (define_insn "sse2_shufpd"
23671 [(set (match_operand:V2DF 0 "register_operand" "=x")
23672 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23673 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23674 (match_operand:SI 3 "immediate_operand" "i")]
23675 UNSPEC_SHUFFLE))]
23676 "TARGET_SSE2"
23677 ;; @@@ check operand order for intel/nonintel syntax
23678 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23679 [(set_attr "type" "ssecvt")
23680 (set_attr "mode" "V2DF")])
23681
23682 (define_insn "sse2_clflush"
23683 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23684 UNSPECV_CLFLUSH)]
23685 "TARGET_SSE2"
23686 "clflush %0"
23687 [(set_attr "type" "sse")
23688 (set_attr "memory" "unknown")])
23689
23690 (define_expand "sse2_mfence"
23691 [(set (match_dup 0)
23692 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23693 "TARGET_SSE2"
23694 {
23695 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23696 MEM_VOLATILE_P (operands[0]) = 1;
23697 })
23698
23699 (define_insn "*mfence_insn"
23700 [(set (match_operand:BLK 0 "" "")
23701 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23702 "TARGET_SSE2"
23703 "mfence"
23704 [(set_attr "type" "sse")
23705 (set_attr "memory" "unknown")])
23706
23707 (define_expand "sse2_lfence"
23708 [(set (match_dup 0)
23709 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23710 "TARGET_SSE2"
23711 {
23712 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23713 MEM_VOLATILE_P (operands[0]) = 1;
23714 })
23715
23716 (define_insn "*lfence_insn"
23717 [(set (match_operand:BLK 0 "" "")
23718 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23719 "TARGET_SSE2"
23720 "lfence"
23721 [(set_attr "type" "sse")
23722 (set_attr "memory" "unknown")])
23723
23724 ;; PNI
23725
23726 (define_insn "mwait"
23727 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23728 (match_operand:SI 1 "register_operand" "c")]
23729 UNSPECV_MWAIT)]
23730 "TARGET_PNI"
23731 "mwait\t%0, %1"
23732 [(set_attr "length" "3")])
23733
23734 (define_insn "monitor"
23735 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23736 (match_operand:SI 1 "register_operand" "c")
23737 (match_operand:SI 2 "register_operand" "d")]
23738 UNSPECV_MONITOR)]
23739 "TARGET_PNI"
23740 "monitor\t%0, %1, %2"
23741 [(set_attr "length" "3")])
23742
23743 ;; PNI arithmetic
23744
23745 (define_insn "addsubv4sf3"
23746 [(set (match_operand:V4SF 0 "register_operand" "=x")
23747 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23748 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23749 UNSPEC_ADDSUB))]
23750 "TARGET_PNI"
23751 "addsubps\t{%2, %0|%0, %2}"
23752 [(set_attr "type" "sseadd")
23753 (set_attr "mode" "V4SF")])
23754
23755 (define_insn "addsubv2df3"
23756 [(set (match_operand:V2DF 0 "register_operand" "=x")
23757 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23758 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23759 UNSPEC_ADDSUB))]
23760 "TARGET_PNI"
23761 "addsubpd\t{%2, %0|%0, %2}"
23762 [(set_attr "type" "sseadd")
23763 (set_attr "mode" "V2DF")])
23764
23765 (define_insn "haddv4sf3"
23766 [(set (match_operand:V4SF 0 "register_operand" "=x")
23767 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23768 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23769 UNSPEC_HADD))]
23770 "TARGET_PNI"
23771 "haddps\t{%2, %0|%0, %2}"
23772 [(set_attr "type" "sseadd")
23773 (set_attr "mode" "V4SF")])
23774
23775 (define_insn "haddv2df3"
23776 [(set (match_operand:V2DF 0 "register_operand" "=x")
23777 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23778 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23779 UNSPEC_HADD))]
23780 "TARGET_PNI"
23781 "haddpd\t{%2, %0|%0, %2}"
23782 [(set_attr "type" "sseadd")
23783 (set_attr "mode" "V2DF")])
23784
23785 (define_insn "hsubv4sf3"
23786 [(set (match_operand:V4SF 0 "register_operand" "=x")
23787 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23788 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23789 UNSPEC_HSUB))]
23790 "TARGET_PNI"
23791 "hsubps\t{%2, %0|%0, %2}"
23792 [(set_attr "type" "sseadd")
23793 (set_attr "mode" "V4SF")])
23794
23795 (define_insn "hsubv2df3"
23796 [(set (match_operand:V2DF 0 "register_operand" "=x")
23797 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23798 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23799 UNSPEC_HSUB))]
23800 "TARGET_PNI"
23801 "hsubpd\t{%2, %0|%0, %2}"
23802 [(set_attr "type" "sseadd")
23803 (set_attr "mode" "V2DF")])
23804
23805 (define_insn "movshdup"
23806 [(set (match_operand:V4SF 0 "register_operand" "=x")
23807 (unspec:V4SF
23808 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23809 "TARGET_PNI"
23810 "movshdup\t{%1, %0|%0, %1}"
23811 [(set_attr "type" "sse")
23812 (set_attr "mode" "V4SF")])
23813
23814 (define_insn "movsldup"
23815 [(set (match_operand:V4SF 0 "register_operand" "=x")
23816 (unspec:V4SF
23817 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23818 "TARGET_PNI"
23819 "movsldup\t{%1, %0|%0, %1}"
23820 [(set_attr "type" "sse")
23821 (set_attr "mode" "V4SF")])
23822
23823 (define_insn "lddqu"
23824 [(set (match_operand:V16QI 0 "register_operand" "=x")
23825 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23826 UNSPEC_LDQQU))]
23827 "TARGET_PNI"
23828 "lddqu\t{%1, %0|%0, %1}"
23829 [(set_attr "type" "ssecvt")
23830 (set_attr "mode" "TI")])
23831
23832 (define_insn "loadddup"
23833 [(set (match_operand:V2DF 0 "register_operand" "=x")
23834 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23835 "TARGET_PNI"
23836 "movddup\t{%1, %0|%0, %1}"
23837 [(set_attr "type" "ssecvt")
23838 (set_attr "mode" "DF")])
23839
23840 (define_insn "movddup"
23841 [(set (match_operand:V2DF 0 "register_operand" "=x")
23842 (vec_duplicate:V2DF
23843 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23844 (parallel [(const_int 0)]))))]
23845 "TARGET_PNI"
23846 "movddup\t{%1, %0|%0, %1}"
23847 [(set_attr "type" "ssecvt")
23848 (set_attr "mode" "DF")])