toplev.c (rest_of_compilation): Fix webizer pass ordering.
[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 (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14459 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14460 (set (strict_low_part (match_dup 3))
14461 (eq:QI (reg:CCZ 17) (const_int 0)))
14462 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14463 (clobber (reg:CC 17))])
14464 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14465 (clobber (reg:CC 17))])
14466 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14467 (clobber (reg:CC 17))])]
14468 {
14469 operands[3] = gen_lowpart (QImode, operands[2]);
14470 ix86_expand_clear (operands[2]);
14471 })
14472
14473 (define_insn "*ffssi_1"
14474 [(set (reg:CCZ 17)
14475 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14476 (const_int 0)))
14477 (set (match_operand:SI 0 "register_operand" "=r")
14478 (ctz:SI (match_dup 1)))]
14479 ""
14480 "bsf{l}\t{%1, %0|%0, %1}"
14481 [(set_attr "prefix_0f" "1")
14482 (set_attr "ppro_uops" "few")])
14483
14484 (define_insn "ctzsi2"
14485 [(set (match_operand:SI 0 "register_operand" "=r")
14486 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14487 (clobber (reg:CC 17))]
14488 ""
14489 "bsf{l}\t{%1, %0|%0, %1}"
14490 [(set_attr "prefix_0f" "1")
14491 (set_attr "ppro_uops" "few")])
14492
14493 (define_expand "clzsi2"
14494 [(parallel
14495 [(set (match_operand:SI 0 "register_operand" "")
14496 (minus:SI (const_int 31)
14497 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14498 (clobber (reg:CC 17))])
14499 (parallel
14500 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14501 (clobber (reg:CC 17))])]
14502 ""
14503 "")
14504
14505 (define_insn "*bsr"
14506 [(set (match_operand:SI 0 "register_operand" "=r")
14507 (minus:SI (const_int 31)
14508 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14509 (clobber (reg:CC 17))]
14510 ""
14511 "bsr{l}\t{%1, %0|%0, %1}"
14512 [(set_attr "prefix_0f" "1")
14513 (set_attr "ppro_uops" "few")])
14514 \f
14515 ;; Thread-local storage patterns for ELF.
14516 ;;
14517 ;; Note that these code sequences must appear exactly as shown
14518 ;; in order to allow linker relaxation.
14519
14520 (define_insn "*tls_global_dynamic_32_gnu"
14521 [(set (match_operand:SI 0 "register_operand" "=a")
14522 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14523 (match_operand:SI 2 "tls_symbolic_operand" "")
14524 (match_operand:SI 3 "call_insn_operand" "")]
14525 UNSPEC_TLS_GD))
14526 (clobber (match_scratch:SI 4 "=d"))
14527 (clobber (match_scratch:SI 5 "=c"))
14528 (clobber (reg:CC 17))]
14529 "!TARGET_64BIT && TARGET_GNU_TLS"
14530 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14531 [(set_attr "type" "multi")
14532 (set_attr "length" "12")])
14533
14534 (define_insn "*tls_global_dynamic_32_sun"
14535 [(set (match_operand:SI 0 "register_operand" "=a")
14536 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14537 (match_operand:SI 2 "tls_symbolic_operand" "")
14538 (match_operand:SI 3 "call_insn_operand" "")]
14539 UNSPEC_TLS_GD))
14540 (clobber (match_scratch:SI 4 "=d"))
14541 (clobber (match_scratch:SI 5 "=c"))
14542 (clobber (reg:CC 17))]
14543 "!TARGET_64BIT && TARGET_SUN_TLS"
14544 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14545 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14546 [(set_attr "type" "multi")
14547 (set_attr "length" "14")])
14548
14549 (define_expand "tls_global_dynamic_32"
14550 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14551 (unspec:SI
14552 [(match_dup 2)
14553 (match_operand:SI 1 "tls_symbolic_operand" "")
14554 (match_dup 3)]
14555 UNSPEC_TLS_GD))
14556 (clobber (match_scratch:SI 4 ""))
14557 (clobber (match_scratch:SI 5 ""))
14558 (clobber (reg:CC 17))])]
14559 ""
14560 {
14561 if (flag_pic)
14562 operands[2] = pic_offset_table_rtx;
14563 else
14564 {
14565 operands[2] = gen_reg_rtx (Pmode);
14566 emit_insn (gen_set_got (operands[2]));
14567 }
14568 operands[3] = ix86_tls_get_addr ();
14569 })
14570
14571 (define_insn "*tls_global_dynamic_64"
14572 [(set (match_operand:DI 0 "register_operand" "=a")
14573 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14574 (match_operand:DI 3 "" "")))
14575 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14576 UNSPEC_TLS_GD)]
14577 "TARGET_64BIT"
14578 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14579 [(set_attr "type" "multi")
14580 (set_attr "length" "16")])
14581
14582 (define_expand "tls_global_dynamic_64"
14583 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14584 (call (mem:QI (match_dup 2)) (const_int 0)))
14585 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14586 UNSPEC_TLS_GD)])]
14587 ""
14588 {
14589 operands[2] = ix86_tls_get_addr ();
14590 })
14591
14592 (define_insn "*tls_local_dynamic_base_32_gnu"
14593 [(set (match_operand:SI 0 "register_operand" "=a")
14594 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14595 (match_operand:SI 2 "call_insn_operand" "")]
14596 UNSPEC_TLS_LD_BASE))
14597 (clobber (match_scratch:SI 3 "=d"))
14598 (clobber (match_scratch:SI 4 "=c"))
14599 (clobber (reg:CC 17))]
14600 "!TARGET_64BIT && TARGET_GNU_TLS"
14601 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14602 [(set_attr "type" "multi")
14603 (set_attr "length" "11")])
14604
14605 (define_insn "*tls_local_dynamic_base_32_sun"
14606 [(set (match_operand:SI 0 "register_operand" "=a")
14607 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14608 (match_operand:SI 2 "call_insn_operand" "")]
14609 UNSPEC_TLS_LD_BASE))
14610 (clobber (match_scratch:SI 3 "=d"))
14611 (clobber (match_scratch:SI 4 "=c"))
14612 (clobber (reg:CC 17))]
14613 "!TARGET_64BIT && TARGET_SUN_TLS"
14614 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14615 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14616 [(set_attr "type" "multi")
14617 (set_attr "length" "13")])
14618
14619 (define_expand "tls_local_dynamic_base_32"
14620 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14621 (unspec:SI [(match_dup 1) (match_dup 2)]
14622 UNSPEC_TLS_LD_BASE))
14623 (clobber (match_scratch:SI 3 ""))
14624 (clobber (match_scratch:SI 4 ""))
14625 (clobber (reg:CC 17))])]
14626 ""
14627 {
14628 if (flag_pic)
14629 operands[1] = pic_offset_table_rtx;
14630 else
14631 {
14632 operands[1] = gen_reg_rtx (Pmode);
14633 emit_insn (gen_set_got (operands[1]));
14634 }
14635 operands[2] = ix86_tls_get_addr ();
14636 })
14637
14638 (define_insn "*tls_local_dynamic_base_64"
14639 [(set (match_operand:DI 0 "register_operand" "=a")
14640 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14641 (match_operand:DI 2 "" "")))
14642 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14643 "TARGET_64BIT"
14644 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14645 [(set_attr "type" "multi")
14646 (set_attr "length" "12")])
14647
14648 (define_expand "tls_local_dynamic_base_64"
14649 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14650 (call (mem:QI (match_dup 1)) (const_int 0)))
14651 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14652 ""
14653 {
14654 operands[1] = ix86_tls_get_addr ();
14655 })
14656
14657 ;; Local dynamic of a single variable is a lose. Show combine how
14658 ;; to convert that back to global dynamic.
14659
14660 (define_insn_and_split "*tls_local_dynamic_32_once"
14661 [(set (match_operand:SI 0 "register_operand" "=a")
14662 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14663 (match_operand:SI 2 "call_insn_operand" "")]
14664 UNSPEC_TLS_LD_BASE)
14665 (const:SI (unspec:SI
14666 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14667 UNSPEC_DTPOFF))))
14668 (clobber (match_scratch:SI 4 "=d"))
14669 (clobber (match_scratch:SI 5 "=c"))
14670 (clobber (reg:CC 17))]
14671 ""
14672 "#"
14673 ""
14674 [(parallel [(set (match_dup 0)
14675 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14676 UNSPEC_TLS_GD))
14677 (clobber (match_dup 4))
14678 (clobber (match_dup 5))
14679 (clobber (reg:CC 17))])]
14680 "")
14681
14682 ;; Load and add the thread base pointer from %gs:0.
14683
14684 (define_insn "*load_tp_si"
14685 [(set (match_operand:SI 0 "register_operand" "=r")
14686 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14687 "!TARGET_64BIT"
14688 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14689 [(set_attr "type" "imov")
14690 (set_attr "modrm" "0")
14691 (set_attr "length" "7")
14692 (set_attr "memory" "load")
14693 (set_attr "imm_disp" "false")])
14694
14695 (define_insn "*add_tp_si"
14696 [(set (match_operand:SI 0 "register_operand" "=r")
14697 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14698 (match_operand:SI 1 "register_operand" "0")))
14699 (clobber (reg:CC 17))]
14700 "!TARGET_64BIT"
14701 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14702 [(set_attr "type" "alu")
14703 (set_attr "modrm" "0")
14704 (set_attr "length" "7")
14705 (set_attr "memory" "load")
14706 (set_attr "imm_disp" "false")])
14707
14708 (define_insn "*load_tp_di"
14709 [(set (match_operand:DI 0 "register_operand" "=r")
14710 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14711 "TARGET_64BIT"
14712 "mov{l}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14713 [(set_attr "type" "imov")
14714 (set_attr "modrm" "0")
14715 (set_attr "length" "7")
14716 (set_attr "memory" "load")
14717 (set_attr "imm_disp" "false")])
14718
14719 (define_insn "*add_tp_di"
14720 [(set (match_operand:DI 0 "register_operand" "=r")
14721 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14722 (match_operand:DI 1 "register_operand" "0")))
14723 (clobber (reg:CC 17))]
14724 "TARGET_64BIT"
14725 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14726 [(set_attr "type" "alu")
14727 (set_attr "modrm" "0")
14728 (set_attr "length" "7")
14729 (set_attr "memory" "load")
14730 (set_attr "imm_disp" "false")])
14731 \f
14732 ;; These patterns match the binary 387 instructions for addM3, subM3,
14733 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14734 ;; SFmode. The first is the normal insn, the second the same insn but
14735 ;; with one operand a conversion, and the third the same insn but with
14736 ;; the other operand a conversion. The conversion may be SFmode or
14737 ;; SImode if the target mode DFmode, but only SImode if the target mode
14738 ;; is SFmode.
14739
14740 ;; Gcc is slightly more smart about handling normal two address instructions
14741 ;; so use special patterns for add and mull.
14742 (define_insn "*fop_sf_comm_nosse"
14743 [(set (match_operand:SF 0 "register_operand" "=f")
14744 (match_operator:SF 3 "binary_fp_operator"
14745 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14746 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14747 "TARGET_80387 && !TARGET_SSE_MATH
14748 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14749 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14750 "* return output_387_binary_op (insn, operands);"
14751 [(set (attr "type")
14752 (if_then_else (match_operand:SF 3 "mult_operator" "")
14753 (const_string "fmul")
14754 (const_string "fop")))
14755 (set_attr "mode" "SF")])
14756
14757 (define_insn "*fop_sf_comm"
14758 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14759 (match_operator:SF 3 "binary_fp_operator"
14760 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14761 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14762 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14763 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14764 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14765 "* return output_387_binary_op (insn, operands);"
14766 [(set (attr "type")
14767 (if_then_else (eq_attr "alternative" "1")
14768 (if_then_else (match_operand:SF 3 "mult_operator" "")
14769 (const_string "ssemul")
14770 (const_string "sseadd"))
14771 (if_then_else (match_operand:SF 3 "mult_operator" "")
14772 (const_string "fmul")
14773 (const_string "fop"))))
14774 (set_attr "mode" "SF")])
14775
14776 (define_insn "*fop_sf_comm_sse"
14777 [(set (match_operand:SF 0 "register_operand" "=x")
14778 (match_operator:SF 3 "binary_fp_operator"
14779 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14780 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14781 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14782 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14783 "* return output_387_binary_op (insn, operands);"
14784 [(set (attr "type")
14785 (if_then_else (match_operand:SF 3 "mult_operator" "")
14786 (const_string "ssemul")
14787 (const_string "sseadd")))
14788 (set_attr "mode" "SF")])
14789
14790 (define_insn "*fop_df_comm_nosse"
14791 [(set (match_operand:DF 0 "register_operand" "=f")
14792 (match_operator:DF 3 "binary_fp_operator"
14793 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14794 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14795 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14796 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14797 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14798 "* return output_387_binary_op (insn, operands);"
14799 [(set (attr "type")
14800 (if_then_else (match_operand:SF 3 "mult_operator" "")
14801 (const_string "fmul")
14802 (const_string "fop")))
14803 (set_attr "mode" "DF")])
14804
14805 (define_insn "*fop_df_comm"
14806 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14807 (match_operator:DF 3 "binary_fp_operator"
14808 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14809 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14810 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14811 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14812 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14813 "* return output_387_binary_op (insn, operands);"
14814 [(set (attr "type")
14815 (if_then_else (eq_attr "alternative" "1")
14816 (if_then_else (match_operand:SF 3 "mult_operator" "")
14817 (const_string "ssemul")
14818 (const_string "sseadd"))
14819 (if_then_else (match_operand:SF 3 "mult_operator" "")
14820 (const_string "fmul")
14821 (const_string "fop"))))
14822 (set_attr "mode" "DF")])
14823
14824 (define_insn "*fop_df_comm_sse"
14825 [(set (match_operand:DF 0 "register_operand" "=Y")
14826 (match_operator:DF 3 "binary_fp_operator"
14827 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14828 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14829 "TARGET_SSE2 && TARGET_SSE_MATH
14830 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14831 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14832 "* return output_387_binary_op (insn, operands);"
14833 [(set (attr "type")
14834 (if_then_else (match_operand:SF 3 "mult_operator" "")
14835 (const_string "ssemul")
14836 (const_string "sseadd")))
14837 (set_attr "mode" "DF")])
14838
14839 (define_insn "*fop_xf_comm"
14840 [(set (match_operand:XF 0 "register_operand" "=f")
14841 (match_operator:XF 3 "binary_fp_operator"
14842 [(match_operand:XF 1 "register_operand" "%0")
14843 (match_operand:XF 2 "register_operand" "f")]))]
14844 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
14845 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14846 "* return output_387_binary_op (insn, operands);"
14847 [(set (attr "type")
14848 (if_then_else (match_operand:XF 3 "mult_operator" "")
14849 (const_string "fmul")
14850 (const_string "fop")))
14851 (set_attr "mode" "XF")])
14852
14853 (define_insn "*fop_tf_comm"
14854 [(set (match_operand:TF 0 "register_operand" "=f")
14855 (match_operator:TF 3 "binary_fp_operator"
14856 [(match_operand:TF 1 "register_operand" "%0")
14857 (match_operand:TF 2 "register_operand" "f")]))]
14858 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14859 "* return output_387_binary_op (insn, operands);"
14860 [(set (attr "type")
14861 (if_then_else (match_operand:TF 3 "mult_operator" "")
14862 (const_string "fmul")
14863 (const_string "fop")))
14864 (set_attr "mode" "XF")])
14865
14866 (define_insn "*fop_sf_1_nosse"
14867 [(set (match_operand:SF 0 "register_operand" "=f,f")
14868 (match_operator:SF 3 "binary_fp_operator"
14869 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14870 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14871 "TARGET_80387 && !TARGET_SSE_MATH
14872 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14873 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14874 "* return output_387_binary_op (insn, operands);"
14875 [(set (attr "type")
14876 (cond [(match_operand:SF 3 "mult_operator" "")
14877 (const_string "fmul")
14878 (match_operand:SF 3 "div_operator" "")
14879 (const_string "fdiv")
14880 ]
14881 (const_string "fop")))
14882 (set_attr "mode" "SF")])
14883
14884 (define_insn "*fop_sf_1"
14885 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14886 (match_operator:SF 3 "binary_fp_operator"
14887 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14888 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14889 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14890 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14891 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14892 "* return output_387_binary_op (insn, operands);"
14893 [(set (attr "type")
14894 (cond [(and (eq_attr "alternative" "2")
14895 (match_operand:SF 3 "mult_operator" ""))
14896 (const_string "ssemul")
14897 (and (eq_attr "alternative" "2")
14898 (match_operand:SF 3 "div_operator" ""))
14899 (const_string "ssediv")
14900 (eq_attr "alternative" "2")
14901 (const_string "sseadd")
14902 (match_operand:SF 3 "mult_operator" "")
14903 (const_string "fmul")
14904 (match_operand:SF 3 "div_operator" "")
14905 (const_string "fdiv")
14906 ]
14907 (const_string "fop")))
14908 (set_attr "mode" "SF")])
14909
14910 (define_insn "*fop_sf_1_sse"
14911 [(set (match_operand:SF 0 "register_operand" "=x")
14912 (match_operator:SF 3 "binary_fp_operator"
14913 [(match_operand:SF 1 "register_operand" "0")
14914 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14915 "TARGET_SSE_MATH
14916 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14917 "* return output_387_binary_op (insn, operands);"
14918 [(set (attr "type")
14919 (cond [(match_operand:SF 3 "mult_operator" "")
14920 (const_string "ssemul")
14921 (match_operand:SF 3 "div_operator" "")
14922 (const_string "ssediv")
14923 ]
14924 (const_string "sseadd")))
14925 (set_attr "mode" "SF")])
14926
14927 ;; ??? Add SSE splitters for these!
14928 (define_insn "*fop_sf_2"
14929 [(set (match_operand:SF 0 "register_operand" "=f,f")
14930 (match_operator:SF 3 "binary_fp_operator"
14931 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14932 (match_operand:SF 2 "register_operand" "0,0")]))]
14933 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14934 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14935 [(set (attr "type")
14936 (cond [(match_operand:SF 3 "mult_operator" "")
14937 (const_string "fmul")
14938 (match_operand:SF 3 "div_operator" "")
14939 (const_string "fdiv")
14940 ]
14941 (const_string "fop")))
14942 (set_attr "fp_int_src" "true")
14943 (set_attr "ppro_uops" "many")
14944 (set_attr "mode" "SI")])
14945
14946 (define_insn "*fop_sf_3"
14947 [(set (match_operand:SF 0 "register_operand" "=f,f")
14948 (match_operator:SF 3 "binary_fp_operator"
14949 [(match_operand:SF 1 "register_operand" "0,0")
14950 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14951 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14952 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14953 [(set (attr "type")
14954 (cond [(match_operand:SF 3 "mult_operator" "")
14955 (const_string "fmul")
14956 (match_operand:SF 3 "div_operator" "")
14957 (const_string "fdiv")
14958 ]
14959 (const_string "fop")))
14960 (set_attr "fp_int_src" "true")
14961 (set_attr "ppro_uops" "many")
14962 (set_attr "mode" "SI")])
14963
14964 (define_insn "*fop_df_1_nosse"
14965 [(set (match_operand:DF 0 "register_operand" "=f,f")
14966 (match_operator:DF 3 "binary_fp_operator"
14967 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14968 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14969 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14970 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14971 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14972 "* return output_387_binary_op (insn, operands);"
14973 [(set (attr "type")
14974 (cond [(match_operand:DF 3 "mult_operator" "")
14975 (const_string "fmul")
14976 (match_operand:DF 3 "div_operator" "")
14977 (const_string "fdiv")
14978 ]
14979 (const_string "fop")))
14980 (set_attr "mode" "DF")])
14981
14982
14983 (define_insn "*fop_df_1"
14984 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14985 (match_operator:DF 3 "binary_fp_operator"
14986 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14987 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14988 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14989 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14990 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14991 "* return output_387_binary_op (insn, operands);"
14992 [(set (attr "type")
14993 (cond [(and (eq_attr "alternative" "2")
14994 (match_operand:SF 3 "mult_operator" ""))
14995 (const_string "ssemul")
14996 (and (eq_attr "alternative" "2")
14997 (match_operand:SF 3 "div_operator" ""))
14998 (const_string "ssediv")
14999 (eq_attr "alternative" "2")
15000 (const_string "sseadd")
15001 (match_operand:DF 3 "mult_operator" "")
15002 (const_string "fmul")
15003 (match_operand:DF 3 "div_operator" "")
15004 (const_string "fdiv")
15005 ]
15006 (const_string "fop")))
15007 (set_attr "mode" "DF")])
15008
15009 (define_insn "*fop_df_1_sse"
15010 [(set (match_operand:DF 0 "register_operand" "=Y")
15011 (match_operator:DF 3 "binary_fp_operator"
15012 [(match_operand:DF 1 "register_operand" "0")
15013 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15014 "TARGET_SSE2 && TARGET_SSE_MATH
15015 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15016 "* return output_387_binary_op (insn, operands);"
15017 [(set_attr "mode" "DF")
15018 (set (attr "type")
15019 (cond [(match_operand:SF 3 "mult_operator" "")
15020 (const_string "ssemul")
15021 (match_operand:SF 3 "div_operator" "")
15022 (const_string "ssediv")
15023 ]
15024 (const_string "sseadd")))])
15025
15026 ;; ??? Add SSE splitters for these!
15027 (define_insn "*fop_df_2"
15028 [(set (match_operand:DF 0 "register_operand" "=f,f")
15029 (match_operator:DF 3 "binary_fp_operator"
15030 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15031 (match_operand:DF 2 "register_operand" "0,0")]))]
15032 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15033 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15034 [(set (attr "type")
15035 (cond [(match_operand:DF 3 "mult_operator" "")
15036 (const_string "fmul")
15037 (match_operand:DF 3 "div_operator" "")
15038 (const_string "fdiv")
15039 ]
15040 (const_string "fop")))
15041 (set_attr "fp_int_src" "true")
15042 (set_attr "ppro_uops" "many")
15043 (set_attr "mode" "SI")])
15044
15045 (define_insn "*fop_df_3"
15046 [(set (match_operand:DF 0 "register_operand" "=f,f")
15047 (match_operator:DF 3 "binary_fp_operator"
15048 [(match_operand:DF 1 "register_operand" "0,0")
15049 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15050 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15051 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15052 [(set (attr "type")
15053 (cond [(match_operand:DF 3 "mult_operator" "")
15054 (const_string "fmul")
15055 (match_operand:DF 3 "div_operator" "")
15056 (const_string "fdiv")
15057 ]
15058 (const_string "fop")))
15059 (set_attr "fp_int_src" "true")
15060 (set_attr "ppro_uops" "many")
15061 (set_attr "mode" "SI")])
15062
15063 (define_insn "*fop_df_4"
15064 [(set (match_operand:DF 0 "register_operand" "=f,f")
15065 (match_operator:DF 3 "binary_fp_operator"
15066 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15067 (match_operand:DF 2 "register_operand" "0,f")]))]
15068 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
15069 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15070 "* return output_387_binary_op (insn, operands);"
15071 [(set (attr "type")
15072 (cond [(match_operand:DF 3 "mult_operator" "")
15073 (const_string "fmul")
15074 (match_operand:DF 3 "div_operator" "")
15075 (const_string "fdiv")
15076 ]
15077 (const_string "fop")))
15078 (set_attr "mode" "SF")])
15079
15080 (define_insn "*fop_df_5"
15081 [(set (match_operand:DF 0 "register_operand" "=f,f")
15082 (match_operator:DF 3 "binary_fp_operator"
15083 [(match_operand:DF 1 "register_operand" "0,f")
15084 (float_extend:DF
15085 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15086 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15087 "* return output_387_binary_op (insn, operands);"
15088 [(set (attr "type")
15089 (cond [(match_operand:DF 3 "mult_operator" "")
15090 (const_string "fmul")
15091 (match_operand:DF 3 "div_operator" "")
15092 (const_string "fdiv")
15093 ]
15094 (const_string "fop")))
15095 (set_attr "mode" "SF")])
15096
15097 (define_insn "*fop_df_6"
15098 [(set (match_operand:DF 0 "register_operand" "=f,f")
15099 (match_operator:DF 3 "binary_fp_operator"
15100 [(float_extend:DF
15101 (match_operand:SF 1 "register_operand" "0,f"))
15102 (float_extend:DF
15103 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15104 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15105 "* return output_387_binary_op (insn, operands);"
15106 [(set (attr "type")
15107 (cond [(match_operand:DF 3 "mult_operator" "")
15108 (const_string "fmul")
15109 (match_operand:DF 3 "div_operator" "")
15110 (const_string "fdiv")
15111 ]
15112 (const_string "fop")))
15113 (set_attr "mode" "SF")])
15114
15115 (define_insn "*fop_xf_1"
15116 [(set (match_operand:XF 0 "register_operand" "=f,f")
15117 (match_operator:XF 3 "binary_fp_operator"
15118 [(match_operand:XF 1 "register_operand" "0,f")
15119 (match_operand:XF 2 "register_operand" "f,0")]))]
15120 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
15121 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15122 "* return output_387_binary_op (insn, operands);"
15123 [(set (attr "type")
15124 (cond [(match_operand:XF 3 "mult_operator" "")
15125 (const_string "fmul")
15126 (match_operand:XF 3 "div_operator" "")
15127 (const_string "fdiv")
15128 ]
15129 (const_string "fop")))
15130 (set_attr "mode" "XF")])
15131
15132 (define_insn "*fop_tf_1"
15133 [(set (match_operand:TF 0 "register_operand" "=f,f")
15134 (match_operator:TF 3 "binary_fp_operator"
15135 [(match_operand:TF 1 "register_operand" "0,f")
15136 (match_operand:TF 2 "register_operand" "f,0")]))]
15137 "TARGET_80387
15138 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15139 "* return output_387_binary_op (insn, operands);"
15140 [(set (attr "type")
15141 (cond [(match_operand:TF 3 "mult_operator" "")
15142 (const_string "fmul")
15143 (match_operand:TF 3 "div_operator" "")
15144 (const_string "fdiv")
15145 ]
15146 (const_string "fop")))
15147 (set_attr "mode" "XF")])
15148
15149 (define_insn "*fop_xf_2"
15150 [(set (match_operand:XF 0 "register_operand" "=f,f")
15151 (match_operator:XF 3 "binary_fp_operator"
15152 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15153 (match_operand:XF 2 "register_operand" "0,0")]))]
15154 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15155 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15156 [(set (attr "type")
15157 (cond [(match_operand:XF 3 "mult_operator" "")
15158 (const_string "fmul")
15159 (match_operand:XF 3 "div_operator" "")
15160 (const_string "fdiv")
15161 ]
15162 (const_string "fop")))
15163 (set_attr "fp_int_src" "true")
15164 (set_attr "mode" "SI")
15165 (set_attr "ppro_uops" "many")])
15166
15167 (define_insn "*fop_tf_2"
15168 [(set (match_operand:TF 0 "register_operand" "=f,f")
15169 (match_operator:TF 3 "binary_fp_operator"
15170 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15171 (match_operand:TF 2 "register_operand" "0,0")]))]
15172 "TARGET_80387 && TARGET_USE_FIOP"
15173 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15174 [(set (attr "type")
15175 (cond [(match_operand:TF 3 "mult_operator" "")
15176 (const_string "fmul")
15177 (match_operand:TF 3 "div_operator" "")
15178 (const_string "fdiv")
15179 ]
15180 (const_string "fop")))
15181 (set_attr "fp_int_src" "true")
15182 (set_attr "mode" "SI")
15183 (set_attr "ppro_uops" "many")])
15184
15185 (define_insn "*fop_xf_3"
15186 [(set (match_operand:XF 0 "register_operand" "=f,f")
15187 (match_operator:XF 3 "binary_fp_operator"
15188 [(match_operand:XF 1 "register_operand" "0,0")
15189 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15190 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15191 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15192 [(set (attr "type")
15193 (cond [(match_operand:XF 3 "mult_operator" "")
15194 (const_string "fmul")
15195 (match_operand:XF 3 "div_operator" "")
15196 (const_string "fdiv")
15197 ]
15198 (const_string "fop")))
15199 (set_attr "fp_int_src" "true")
15200 (set_attr "mode" "SI")
15201 (set_attr "ppro_uops" "many")])
15202
15203 (define_insn "*fop_tf_3"
15204 [(set (match_operand:TF 0 "register_operand" "=f,f")
15205 (match_operator:TF 3 "binary_fp_operator"
15206 [(match_operand:TF 1 "register_operand" "0,0")
15207 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15208 "TARGET_80387 && TARGET_USE_FIOP"
15209 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15210 [(set (attr "type")
15211 (cond [(match_operand:TF 3 "mult_operator" "")
15212 (const_string "fmul")
15213 (match_operand:TF 3 "div_operator" "")
15214 (const_string "fdiv")
15215 ]
15216 (const_string "fop")))
15217 (set_attr "fp_int_src" "true")
15218 (set_attr "mode" "SI")
15219 (set_attr "ppro_uops" "many")])
15220
15221 (define_insn "*fop_xf_4"
15222 [(set (match_operand:XF 0 "register_operand" "=f,f")
15223 (match_operator:XF 3 "binary_fp_operator"
15224 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15225 (match_operand:XF 2 "register_operand" "0,f")]))]
15226 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15227 "* return output_387_binary_op (insn, operands);"
15228 [(set (attr "type")
15229 (cond [(match_operand:XF 3 "mult_operator" "")
15230 (const_string "fmul")
15231 (match_operand:XF 3 "div_operator" "")
15232 (const_string "fdiv")
15233 ]
15234 (const_string "fop")))
15235 (set_attr "mode" "SF")])
15236
15237 (define_insn "*fop_tf_4"
15238 [(set (match_operand:TF 0 "register_operand" "=f,f")
15239 (match_operator:TF 3 "binary_fp_operator"
15240 [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
15241 (match_operand:TF 2 "register_operand" "0,f")]))]
15242 "TARGET_80387"
15243 "* return output_387_binary_op (insn, operands);"
15244 [(set (attr "type")
15245 (cond [(match_operand:TF 3 "mult_operator" "")
15246 (const_string "fmul")
15247 (match_operand:TF 3 "div_operator" "")
15248 (const_string "fdiv")
15249 ]
15250 (const_string "fop")))
15251 (set_attr "mode" "SF")])
15252
15253 (define_insn "*fop_xf_5"
15254 [(set (match_operand:XF 0 "register_operand" "=f,f")
15255 (match_operator:XF 3 "binary_fp_operator"
15256 [(match_operand:XF 1 "register_operand" "0,f")
15257 (float_extend:XF
15258 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15259 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15260 "* return output_387_binary_op (insn, operands);"
15261 [(set (attr "type")
15262 (cond [(match_operand:XF 3 "mult_operator" "")
15263 (const_string "fmul")
15264 (match_operand:XF 3 "div_operator" "")
15265 (const_string "fdiv")
15266 ]
15267 (const_string "fop")))
15268 (set_attr "mode" "SF")])
15269
15270 (define_insn "*fop_tf_5"
15271 [(set (match_operand:TF 0 "register_operand" "=f,f")
15272 (match_operator:TF 3 "binary_fp_operator"
15273 [(match_operand:TF 1 "register_operand" "0,f")
15274 (float_extend:TF
15275 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15276 "TARGET_80387"
15277 "* return output_387_binary_op (insn, operands);"
15278 [(set (attr "type")
15279 (cond [(match_operand:TF 3 "mult_operator" "")
15280 (const_string "fmul")
15281 (match_operand:TF 3 "div_operator" "")
15282 (const_string "fdiv")
15283 ]
15284 (const_string "fop")))
15285 (set_attr "mode" "SF")])
15286
15287 (define_insn "*fop_xf_6"
15288 [(set (match_operand:XF 0 "register_operand" "=f,f")
15289 (match_operator:XF 3 "binary_fp_operator"
15290 [(float_extend:XF
15291 (match_operand 1 "register_operand" "0,f"))
15292 (float_extend:XF
15293 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15294 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15295 "* return output_387_binary_op (insn, operands);"
15296 [(set (attr "type")
15297 (cond [(match_operand:XF 3 "mult_operator" "")
15298 (const_string "fmul")
15299 (match_operand:XF 3 "div_operator" "")
15300 (const_string "fdiv")
15301 ]
15302 (const_string "fop")))
15303 (set_attr "mode" "SF")])
15304
15305 (define_insn "*fop_tf_6"
15306 [(set (match_operand:TF 0 "register_operand" "=f,f")
15307 (match_operator:TF 3 "binary_fp_operator"
15308 [(float_extend:TF
15309 (match_operand 1 "register_operand" "0,f"))
15310 (float_extend:TF
15311 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15312 "TARGET_80387"
15313 "* return output_387_binary_op (insn, operands);"
15314 [(set (attr "type")
15315 (cond [(match_operand:TF 3 "mult_operator" "")
15316 (const_string "fmul")
15317 (match_operand:TF 3 "div_operator" "")
15318 (const_string "fdiv")
15319 ]
15320 (const_string "fop")))
15321 (set_attr "mode" "SF")])
15322
15323 (define_split
15324 [(set (match_operand 0 "register_operand" "")
15325 (match_operator 3 "binary_fp_operator"
15326 [(float (match_operand:SI 1 "register_operand" ""))
15327 (match_operand 2 "register_operand" "")]))]
15328 "TARGET_80387 && reload_completed
15329 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15330 [(const_int 0)]
15331 {
15332 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15333 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15334 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15335 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15336 GET_MODE (operands[3]),
15337 operands[4],
15338 operands[2])));
15339 ix86_free_from_memory (GET_MODE (operands[1]));
15340 DONE;
15341 })
15342
15343 (define_split
15344 [(set (match_operand 0 "register_operand" "")
15345 (match_operator 3 "binary_fp_operator"
15346 [(match_operand 1 "register_operand" "")
15347 (float (match_operand:SI 2 "register_operand" ""))]))]
15348 "TARGET_80387 && reload_completed
15349 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15350 [(const_int 0)]
15351 {
15352 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15353 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15354 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15355 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15356 GET_MODE (operands[3]),
15357 operands[1],
15358 operands[4])));
15359 ix86_free_from_memory (GET_MODE (operands[2]));
15360 DONE;
15361 })
15362 \f
15363 ;; FPU special functions.
15364
15365 (define_expand "sqrtsf2"
15366 [(set (match_operand:SF 0 "register_operand" "")
15367 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15368 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
15369 {
15370 if (!TARGET_SSE_MATH)
15371 operands[1] = force_reg (SFmode, operands[1]);
15372 })
15373
15374 (define_insn "sqrtsf2_1"
15375 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15376 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15377 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15378 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15379 "@
15380 fsqrt
15381 sqrtss\t{%1, %0|%0, %1}"
15382 [(set_attr "type" "fpspc,sse")
15383 (set_attr "mode" "SF,SF")
15384 (set_attr "athlon_decode" "direct,*")])
15385
15386 (define_insn "sqrtsf2_1_sse_only"
15387 [(set (match_operand:SF 0 "register_operand" "=x")
15388 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15389 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15390 "sqrtss\t{%1, %0|%0, %1}"
15391 [(set_attr "type" "sse")
15392 (set_attr "mode" "SF")
15393 (set_attr "athlon_decode" "*")])
15394
15395 (define_insn "sqrtsf2_i387"
15396 [(set (match_operand:SF 0 "register_operand" "=f")
15397 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15398 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15399 && !TARGET_SSE_MATH"
15400 "fsqrt"
15401 [(set_attr "type" "fpspc")
15402 (set_attr "mode" "SF")
15403 (set_attr "athlon_decode" "direct")])
15404
15405 (define_expand "sqrtdf2"
15406 [(set (match_operand:DF 0 "register_operand" "")
15407 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15408 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
15409 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15410 {
15411 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
15412 operands[1] = force_reg (DFmode, operands[1]);
15413 })
15414
15415 (define_insn "sqrtdf2_1"
15416 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15417 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15418 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15419 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15420 "@
15421 fsqrt
15422 sqrtsd\t{%1, %0|%0, %1}"
15423 [(set_attr "type" "fpspc,sse")
15424 (set_attr "mode" "DF,DF")
15425 (set_attr "athlon_decode" "direct,*")])
15426
15427 (define_insn "sqrtdf2_1_sse_only"
15428 [(set (match_operand:DF 0 "register_operand" "=Y")
15429 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15430 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15431 "sqrtsd\t{%1, %0|%0, %1}"
15432 [(set_attr "type" "sse")
15433 (set_attr "mode" "DF")
15434 (set_attr "athlon_decode" "*")])
15435
15436 (define_insn "sqrtdf2_i387"
15437 [(set (match_operand:DF 0 "register_operand" "=f")
15438 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15439 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15440 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
15441 "fsqrt"
15442 [(set_attr "type" "fpspc")
15443 (set_attr "mode" "DF")
15444 (set_attr "athlon_decode" "direct")])
15445
15446 (define_insn "*sqrtextendsfdf2"
15447 [(set (match_operand:DF 0 "register_operand" "=f")
15448 (sqrt:DF (float_extend:DF
15449 (match_operand:SF 1 "register_operand" "0"))))]
15450 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15451 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15452 "fsqrt"
15453 [(set_attr "type" "fpspc")
15454 (set_attr "mode" "DF")
15455 (set_attr "athlon_decode" "direct")])
15456
15457 (define_insn "sqrtxf2"
15458 [(set (match_operand:XF 0 "register_operand" "=f")
15459 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15460 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15461 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15462 "fsqrt"
15463 [(set_attr "type" "fpspc")
15464 (set_attr "mode" "XF")
15465 (set_attr "athlon_decode" "direct")])
15466
15467 (define_insn "sqrttf2"
15468 [(set (match_operand:TF 0 "register_operand" "=f")
15469 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
15470 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15471 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15472 "fsqrt"
15473 [(set_attr "type" "fpspc")
15474 (set_attr "mode" "XF")
15475 (set_attr "athlon_decode" "direct")])
15476
15477 (define_insn "*sqrtextenddfxf2"
15478 [(set (match_operand:XF 0 "register_operand" "=f")
15479 (sqrt:XF (float_extend:XF
15480 (match_operand:DF 1 "register_operand" "0"))))]
15481 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15482 "fsqrt"
15483 [(set_attr "type" "fpspc")
15484 (set_attr "mode" "XF")
15485 (set_attr "athlon_decode" "direct")])
15486
15487 (define_insn "*sqrtextenddftf2"
15488 [(set (match_operand:TF 0 "register_operand" "=f")
15489 (sqrt:TF (float_extend:TF
15490 (match_operand:DF 1 "register_operand" "0"))))]
15491 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15492 "fsqrt"
15493 [(set_attr "type" "fpspc")
15494 (set_attr "mode" "XF")
15495 (set_attr "athlon_decode" "direct")])
15496
15497 (define_insn "*sqrtextendsfxf2"
15498 [(set (match_operand:XF 0 "register_operand" "=f")
15499 (sqrt:XF (float_extend:XF
15500 (match_operand:SF 1 "register_operand" "0"))))]
15501 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15502 "fsqrt"
15503 [(set_attr "type" "fpspc")
15504 (set_attr "mode" "XF")
15505 (set_attr "athlon_decode" "direct")])
15506
15507 (define_insn "*sqrtextendsftf2"
15508 [(set (match_operand:TF 0 "register_operand" "=f")
15509 (sqrt:TF (float_extend:TF
15510 (match_operand:SF 1 "register_operand" "0"))))]
15511 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15512 "fsqrt"
15513 [(set_attr "type" "fpspc")
15514 (set_attr "mode" "XF")
15515 (set_attr "athlon_decode" "direct")])
15516
15517 (define_insn "sindf2"
15518 [(set (match_operand:DF 0 "register_operand" "=f")
15519 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15520 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15521 && flag_unsafe_math_optimizations"
15522 "fsin"
15523 [(set_attr "type" "fpspc")
15524 (set_attr "mode" "DF")])
15525
15526 (define_insn "sinsf2"
15527 [(set (match_operand:SF 0 "register_operand" "=f")
15528 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15529 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15530 && flag_unsafe_math_optimizations"
15531 "fsin"
15532 [(set_attr "type" "fpspc")
15533 (set_attr "mode" "SF")])
15534
15535 (define_insn "*sinextendsfdf2"
15536 [(set (match_operand:DF 0 "register_operand" "=f")
15537 (unspec:DF [(float_extend:DF
15538 (match_operand:SF 1 "register_operand" "0"))]
15539 UNSPEC_SIN))]
15540 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15541 && flag_unsafe_math_optimizations"
15542 "fsin"
15543 [(set_attr "type" "fpspc")
15544 (set_attr "mode" "DF")])
15545
15546 (define_insn "sinxf2"
15547 [(set (match_operand:XF 0 "register_operand" "=f")
15548 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15549 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15550 && flag_unsafe_math_optimizations"
15551 "fsin"
15552 [(set_attr "type" "fpspc")
15553 (set_attr "mode" "XF")])
15554
15555 (define_insn "sintf2"
15556 [(set (match_operand:TF 0 "register_operand" "=f")
15557 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15558 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15559 && flag_unsafe_math_optimizations"
15560 "fsin"
15561 [(set_attr "type" "fpspc")
15562 (set_attr "mode" "XF")])
15563
15564 (define_insn "cosdf2"
15565 [(set (match_operand:DF 0 "register_operand" "=f")
15566 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15567 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15568 && flag_unsafe_math_optimizations"
15569 "fcos"
15570 [(set_attr "type" "fpspc")
15571 (set_attr "mode" "DF")])
15572
15573 (define_insn "cossf2"
15574 [(set (match_operand:SF 0 "register_operand" "=f")
15575 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15576 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15577 && flag_unsafe_math_optimizations"
15578 "fcos"
15579 [(set_attr "type" "fpspc")
15580 (set_attr "mode" "SF")])
15581
15582 (define_insn "*cosextendsfdf2"
15583 [(set (match_operand:DF 0 "register_operand" "=f")
15584 (unspec:DF [(float_extend:DF
15585 (match_operand:SF 1 "register_operand" "0"))]
15586 UNSPEC_COS))]
15587 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15588 && flag_unsafe_math_optimizations"
15589 "fcos"
15590 [(set_attr "type" "fpspc")
15591 (set_attr "mode" "DF")])
15592
15593 (define_insn "cosxf2"
15594 [(set (match_operand:XF 0 "register_operand" "=f")
15595 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15596 "!TARGET_128BIT_LONG_DOUBLE && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15597 && flag_unsafe_math_optimizations"
15598 "fcos"
15599 [(set_attr "type" "fpspc")
15600 (set_attr "mode" "XF")])
15601
15602 (define_insn "costf2"
15603 [(set (match_operand:TF 0 "register_operand" "=f")
15604 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15605 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15606 && flag_unsafe_math_optimizations"
15607 "fcos"
15608 [(set_attr "type" "fpspc")
15609 (set_attr "mode" "XF")])
15610
15611 (define_insn "atan2df3_1"
15612 [(set (match_operand:DF 0 "register_operand" "=f")
15613 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15614 (match_operand:DF 1 "register_operand" "u")]
15615 UNSPEC_FPATAN))
15616 (clobber (match_scratch:DF 3 "=1"))]
15617 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15618 && flag_unsafe_math_optimizations"
15619 "fpatan"
15620 [(set_attr "type" "fpspc")
15621 (set_attr "mode" "DF")])
15622
15623 (define_expand "atan2df3"
15624 [(use (match_operand:DF 0 "register_operand" "=f"))
15625 (use (match_operand:DF 2 "register_operand" "0"))
15626 (use (match_operand:DF 1 "register_operand" "u"))]
15627 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15628 && flag_unsafe_math_optimizations"
15629 {
15630 rtx copy = gen_reg_rtx (DFmode);
15631 emit_move_insn (copy, operands[1]);
15632 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15633 DONE;
15634 })
15635
15636 (define_insn "atan2sf3_1"
15637 [(set (match_operand:SF 0 "register_operand" "=f")
15638 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15639 (match_operand:SF 1 "register_operand" "u")]
15640 UNSPEC_FPATAN))
15641 (clobber (match_scratch:SF 3 "=1"))]
15642 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15643 && flag_unsafe_math_optimizations"
15644 "fpatan"
15645 [(set_attr "type" "fpspc")
15646 (set_attr "mode" "SF")])
15647
15648 (define_expand "atan2sf3"
15649 [(use (match_operand:SF 0 "register_operand" "=f"))
15650 (use (match_operand:SF 2 "register_operand" "0"))
15651 (use (match_operand:SF 1 "register_operand" "u"))]
15652 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15653 && flag_unsafe_math_optimizations"
15654 {
15655 rtx copy = gen_reg_rtx (SFmode);
15656 emit_move_insn (copy, operands[1]);
15657 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15658 DONE;
15659 })
15660
15661 (define_insn "atan2xf3_1"
15662 [(set (match_operand:XF 0 "register_operand" "=f")
15663 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15664 (match_operand:XF 1 "register_operand" "u")]
15665 UNSPEC_FPATAN))
15666 (clobber (match_scratch:XF 3 "=1"))]
15667 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15668 && flag_unsafe_math_optimizations && ! TARGET_128BIT_LONG_DOUBLE"
15669 "fpatan"
15670 [(set_attr "type" "fpspc")
15671 (set_attr "mode" "XF")])
15672
15673 (define_expand "atan2xf3"
15674 [(use (match_operand:XF 0 "register_operand" "=f"))
15675 (use (match_operand:XF 2 "register_operand" "0"))
15676 (use (match_operand:XF 1 "register_operand" "u"))]
15677 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15678 && flag_unsafe_math_optimizations && ! TARGET_128BIT_LONG_DOUBLE"
15679 {
15680 rtx copy = gen_reg_rtx (XFmode);
15681 emit_move_insn (copy, operands[1]);
15682 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15683 DONE;
15684 })
15685
15686 (define_insn "atan2tf3_1"
15687 [(set (match_operand:TF 0 "register_operand" "=f")
15688 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15689 (match_operand:TF 1 "register_operand" "u")]
15690 UNSPEC_FPATAN))
15691 (clobber (match_scratch:TF 3 "=1"))]
15692 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15693 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15694 "fpatan"
15695 [(set_attr "type" "fpspc")
15696 (set_attr "mode" "XF")])
15697
15698 (define_expand "atan2tf3"
15699 [(use (match_operand:TF 0 "register_operand" "=f"))
15700 (use (match_operand:TF 2 "register_operand" "0"))
15701 (use (match_operand:TF 1 "register_operand" "u"))]
15702 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15703 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15704 {
15705 rtx copy = gen_reg_rtx (TFmode);
15706 emit_move_insn (copy, operands[1]);
15707 emit_insn (gen_atan2tf3_1 (operands[0], copy, operands[2]));
15708 DONE;
15709 })
15710
15711 (define_insn "*fyl2x_sfxf3"
15712 [(set (match_operand:SF 0 "register_operand" "=f")
15713 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15714 (match_operand 1 "register_operand" "u")]
15715 UNSPEC_FYL2X))
15716 (clobber (match_scratch:SF 3 "=1"))]
15717 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15718 && flag_unsafe_math_optimizations
15719 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15720 "fyl2x"
15721 [(set_attr "type" "fpspc")
15722 (set_attr "mode" "SF")])
15723
15724 (define_insn "*fyl2x_dfxf3"
15725 [(set (match_operand:DF 0 "register_operand" "=f")
15726 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15727 (match_operand 1 "register_operand" "u")]
15728 UNSPEC_FYL2X))
15729 (clobber (match_scratch:DF 3 "=1"))]
15730 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15731 && flag_unsafe_math_optimizations
15732 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15733 "fyl2x"
15734 [(set_attr "type" "fpspc")
15735 (set_attr "mode" "DF")])
15736
15737 (define_insn "*fyl2x_xf3"
15738 [(set (match_operand:XF 0 "register_operand" "=f")
15739 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15740 (match_operand:XF 1 "register_operand" "u")]
15741 UNSPEC_FYL2X))
15742 (clobber (match_scratch:XF 3 "=1"))]
15743 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15744 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15745 "fyl2x"
15746 [(set_attr "type" "fpspc")
15747 (set_attr "mode" "XF")])
15748
15749 (define_insn "*fyl2x_tfxf3"
15750 [(set (match_operand:TF 0 "register_operand" "=f")
15751 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15752 (match_operand:TF 1 "register_operand" "u")]
15753 UNSPEC_FYL2X))
15754 (clobber (match_scratch:TF 3 "=1"))]
15755 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15756 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15757 "fyl2x"
15758 [(set_attr "type" "fpspc")
15759 (set_attr "mode" "XF")])
15760
15761 (define_expand "logsf2"
15762 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15763 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15764 (match_dup 2)] UNSPEC_FYL2X))
15765 (clobber (match_scratch:SF 3 ""))])]
15766 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15767 && flag_unsafe_math_optimizations"
15768 {
15769 rtx temp;
15770
15771 operands[2] = gen_reg_rtx (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode);
15772 temp = standard_80387_constant_rtx (4); /* fldln2 */
15773 emit_move_insn (operands[2], temp);
15774 })
15775
15776 (define_expand "logdf2"
15777 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15778 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15779 (match_dup 2)] UNSPEC_FYL2X))
15780 (clobber (match_scratch:DF 3 ""))])]
15781 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15782 && flag_unsafe_math_optimizations"
15783 {
15784 rtx temp;
15785
15786 operands[2] = gen_reg_rtx (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode);
15787 temp = standard_80387_constant_rtx (4); /* fldln2 */
15788 emit_move_insn (operands[2], temp);
15789 })
15790
15791 (define_expand "logxf2"
15792 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15793 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15794 (match_dup 2)] UNSPEC_FYL2X))
15795 (clobber (match_scratch:XF 3 ""))])]
15796 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15797 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15798 {
15799 rtx temp;
15800
15801 operands[2] = gen_reg_rtx (XFmode);
15802 temp = standard_80387_constant_rtx (4); /* fldln2 */
15803 emit_move_insn (operands[2], temp);
15804 })
15805
15806 (define_expand "logtf2"
15807 [(parallel [(set (match_operand:TF 0 "register_operand" "")
15808 (unspec:TF [(match_operand:TF 1 "register_operand" "")
15809 (match_dup 2)] UNSPEC_FYL2X))
15810 (clobber (match_scratch:TF 3 ""))])]
15811 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15812 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15813 {
15814 rtx temp;
15815
15816 operands[2] = gen_reg_rtx (TFmode);
15817 temp = standard_80387_constant_rtx (4); /* fldln2 */
15818 emit_move_insn (operands[2], temp);
15819 })
15820
15821 (define_insn "*fscale_sfxf3"
15822 [(set (match_operand:SF 0 "register_operand" "=f")
15823 (unspec:SF [(match_operand 2 "register_operand" "0")
15824 (match_operand 1 "register_operand" "u")]
15825 UNSPEC_FSCALE))
15826 (clobber (match_scratch:SF 3 "=1"))]
15827 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15828 && flag_unsafe_math_optimizations
15829 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)
15830 && GET_MODE (operands[2]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15831 "fscale\;fstp\t%y1"
15832 [(set_attr "type" "fpspc")
15833 (set_attr "mode" "SF")])
15834
15835 (define_insn "*fscale_dfxf3"
15836 [(set (match_operand:DF 0 "register_operand" "=f")
15837 (unspec:DF [(match_operand 2 "register_operand" "0")
15838 (match_operand 1 "register_operand" "u")]
15839 UNSPEC_FSCALE))
15840 (clobber (match_scratch:DF 3 "=1"))]
15841 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15842 && flag_unsafe_math_optimizations
15843 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)
15844 && GET_MODE (operands[2]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15845 "fscale\;fstp\t%y1"
15846 [(set_attr "type" "fpspc")
15847 (set_attr "mode" "DF")])
15848
15849 (define_insn "*fscale_xf3"
15850 [(set (match_operand:XF 0 "register_operand" "=f")
15851 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15852 (match_operand:XF 1 "register_operand" "u")]
15853 UNSPEC_FSCALE))
15854 (clobber (match_scratch:XF 3 "=1"))]
15855 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15856 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15857 "fscale\;fstp\t%y1"
15858 [(set_attr "type" "fpspc")
15859 (set_attr "mode" "XF")])
15860
15861 (define_insn "*fscale_tf3"
15862 [(set (match_operand:TF 0 "register_operand" "=f")
15863 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15864 (match_operand:TF 1 "register_operand" "u")]
15865 UNSPEC_FSCALE))
15866 (clobber (match_scratch:TF 3 "=1"))]
15867 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15868 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15869 "fscale\;fstp\t%y1"
15870 [(set_attr "type" "fpspc")
15871 (set_attr "mode" "XF")])
15872
15873 (define_insn "*frndintxf2"
15874 [(set (match_operand:XF 0 "register_operand" "=f")
15875 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15876 UNSPEC_FRNDINT))]
15877 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15878 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15879 "frndint"
15880 [(set_attr "type" "fpspc")
15881 (set_attr "mode" "XF")])
15882
15883 (define_insn "*frndinttf2"
15884 [(set (match_operand:TF 0 "register_operand" "=f")
15885 (unspec:TF [(match_operand:TF 1 "register_operand" "0")]
15886 UNSPEC_FRNDINT))]
15887 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15888 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15889 "frndint"
15890 [(set_attr "type" "fpspc")
15891 (set_attr "mode" "XF")])
15892
15893 (define_insn "*f2xm1xf2"
15894 [(set (match_operand:XF 0 "register_operand" "=f")
15895 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15896 UNSPEC_F2XM1))]
15897 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15898 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15899 "f2xm1"
15900 [(set_attr "type" "fpspc")
15901 (set_attr "mode" "XF")])
15902
15903 (define_insn "*f2xm1tf2"
15904 [(set (match_operand:TF 0 "register_operand" "=f")
15905 (unspec:TF [(match_operand:TF 1 "register_operand" "0")]
15906 UNSPEC_F2XM1))]
15907 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15908 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15909 "f2xm1"
15910 [(set_attr "type" "fpspc")
15911 (set_attr "mode" "XF")])
15912
15913 (define_expand "expsf2"
15914 [(set (match_dup 2)
15915 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15916 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15917 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15918 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15919 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15920 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15921 (parallel [(set (match_operand:SF 0 "register_operand" "")
15922 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15923 (clobber (match_scratch:SF 5 ""))])]
15924 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15925 && flag_unsafe_math_optimizations"
15926 {
15927 rtx temp;
15928 int i;
15929
15930 if (TARGET_128BIT_LONG_DOUBLE)
15931 {
15932 emit_insn (gen_expsf2_tf (operands[0], operands[1]));
15933 DONE;
15934 }
15935
15936 for (i=2; i<10; i++)
15937 operands[i] = gen_reg_rtx (XFmode);
15938 temp = standard_80387_constant_rtx (5); /* fldl2e */
15939 emit_move_insn (operands[3], temp);
15940 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15941 })
15942
15943 (define_expand "expsf2_tf"
15944 [(set (match_dup 2)
15945 (float_extend:TF (match_operand:SF 1 "register_operand" "")))
15946 (set (match_dup 4) (mult:TF (match_dup 2) (match_dup 3)))
15947 (set (match_dup 5) (unspec:TF [(match_dup 4)] UNSPEC_FRNDINT))
15948 (set (match_dup 6) (minus:TF (match_dup 4) (match_dup 5)))
15949 (set (match_dup 7) (unspec:TF [(match_dup 6)] UNSPEC_F2XM1))
15950 (set (match_dup 9) (plus:TF (match_dup 7) (match_dup 8)))
15951 (parallel [(set (match_operand:SF 0 "register_operand" "")
15952 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15953 (clobber (match_scratch:SF 5 ""))])]
15954 ""
15955 {
15956 rtx temp;
15957 int i;
15958
15959 for (i=2; i<10; i++)
15960 operands[i] = gen_reg_rtx (TFmode);
15961 temp = standard_80387_constant_rtx (5); /* fldl2e */
15962 emit_move_insn (operands[3], temp);
15963 emit_move_insn (operands[8], CONST1_RTX (TFmode)); /* fld1 */
15964 })
15965
15966 (define_expand "expdf2"
15967 [(set (match_dup 2)
15968 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15969 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15970 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15971 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15972 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15973 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15974 (parallel [(set (match_operand:DF 0 "register_operand" "")
15975 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15976 (clobber (match_scratch:DF 5 ""))])]
15977 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15978 && flag_unsafe_math_optimizations"
15979 {
15980 rtx temp;
15981 int i;
15982
15983 if (TARGET_128BIT_LONG_DOUBLE)
15984 {
15985 emit_insn (gen_expdf2_tf (operands[0], operands[1]));
15986 DONE;
15987 }
15988
15989 for (i=2; i<10; i++)
15990 operands[i] = gen_reg_rtx (XFmode);
15991 temp = standard_80387_constant_rtx (5); /* fldl2e */
15992 emit_move_insn (operands[3], temp);
15993 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15994 })
15995
15996
15997 (define_expand "expdf2_tf"
15998 [(set (match_dup 2)
15999 (float_extend:TF (match_operand:DF 1 "register_operand" "")))
16000 (set (match_dup 4) (mult:TF (match_dup 2) (match_dup 3)))
16001 (set (match_dup 5) (unspec:TF [(match_dup 4)] UNSPEC_FRNDINT))
16002 (set (match_dup 6) (minus:TF (match_dup 4) (match_dup 5)))
16003 (set (match_dup 7) (unspec:TF [(match_dup 6)] UNSPEC_F2XM1))
16004 (set (match_dup 9) (plus:TF (match_dup 7) (match_dup 8)))
16005 (parallel [(set (match_operand:DF 0 "register_operand" "")
16006 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
16007 (clobber (match_scratch:DF 5 ""))])]
16008 ""
16009 {
16010 rtx temp;
16011 int i;
16012
16013 for (i=2; i<10; i++)
16014 operands[i] = gen_reg_rtx (TFmode);
16015 temp = standard_80387_constant_rtx (5); /* fldl2e */
16016 emit_move_insn (operands[3], temp);
16017 emit_move_insn (operands[8], CONST1_RTX (TFmode)); /* fld1 */
16018 })
16019
16020 (define_expand "expxf2"
16021 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16022 (match_dup 2)))
16023 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16024 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16025 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16026 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16027 (parallel [(set (match_operand:XF 0 "register_operand" "")
16028 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
16029 (clobber (match_scratch:XF 5 ""))])]
16030 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16031 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
16032 {
16033 rtx temp;
16034 int i;
16035
16036 for (i=2; i<9; i++)
16037 operands[i] = gen_reg_rtx (XFmode);
16038 temp = standard_80387_constant_rtx (5); /* fldl2e */
16039 emit_move_insn (operands[2], temp);
16040 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16041 })
16042
16043 (define_expand "atansf2"
16044 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16045 (unspec:SF [(match_dup 2)
16046 (match_operand:SF 1 "register_operand" "")]
16047 UNSPEC_FPATAN))
16048 (clobber (match_scratch:SF 3 ""))])]
16049 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16050 && flag_unsafe_math_optimizations"
16051 {
16052 operands[2] = gen_reg_rtx (SFmode);
16053 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16054 })
16055
16056 (define_expand "exptf2"
16057 [(set (match_dup 3) (mult:TF (match_operand:TF 1 "register_operand" "")
16058 (match_dup 2)))
16059 (set (match_dup 4) (unspec:TF [(match_dup 3)] UNSPEC_FRNDINT))
16060 (set (match_dup 5) (minus:TF (match_dup 3) (match_dup 4)))
16061 (set (match_dup 6) (unspec:TF [(match_dup 5)] UNSPEC_F2XM1))
16062 (set (match_dup 8) (plus:TF (match_dup 6) (match_dup 7)))
16063 (parallel [(set (match_operand:TF 0 "register_operand" "")
16064 (unspec:TF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
16065 (clobber (match_scratch:TF 5 ""))])]
16066 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16067 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
16068 {
16069 rtx temp;
16070 int i;
16071
16072 for (i=2; i<9; i++)
16073 operands[i] = gen_reg_rtx (TFmode);
16074 temp = standard_80387_constant_rtx (5); /* fldl2e */
16075 emit_move_insn (operands[2], temp);
16076 emit_move_insn (operands[7], CONST1_RTX (TFmode)); /* fld1 */
16077 })
16078
16079 (define_expand "atandf2"
16080 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16081 (unspec:DF [(match_dup 2)
16082 (match_operand:DF 1 "register_operand" "")]
16083 UNSPEC_FPATAN))
16084 (clobber (match_scratch:DF 3 ""))])]
16085 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16086 && flag_unsafe_math_optimizations"
16087 {
16088 operands[2] = gen_reg_rtx (DFmode);
16089 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16090 })
16091
16092 (define_expand "atanxf2"
16093 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16094 (unspec:XF [(match_dup 2)
16095 (match_operand:XF 1 "register_operand" "")]
16096 UNSPEC_FPATAN))
16097 (clobber (match_scratch:XF 3 ""))])]
16098 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16099 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
16100 {
16101 operands[2] = gen_reg_rtx (XFmode);
16102 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16103 })
16104
16105 (define_expand "atantf2"
16106 [(parallel [(set (match_operand:TF 0 "register_operand" "")
16107 (unspec:TF [(match_dup 2)
16108 (match_operand:TF 1 "register_operand" "")]
16109 UNSPEC_FPATAN))
16110 (clobber (match_scratch:TF 3 ""))])]
16111 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16112 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
16113 {
16114 operands[2] = gen_reg_rtx (TFmode);
16115 emit_move_insn (operands[2], CONST1_RTX (TFmode)); /* fld1 */
16116 })
16117 \f
16118 ;; Block operation instructions
16119
16120 (define_insn "cld"
16121 [(set (reg:SI 19) (const_int 0))]
16122 ""
16123 "cld"
16124 [(set_attr "type" "cld")])
16125
16126 (define_expand "movstrsi"
16127 [(use (match_operand:BLK 0 "memory_operand" ""))
16128 (use (match_operand:BLK 1 "memory_operand" ""))
16129 (use (match_operand:SI 2 "nonmemory_operand" ""))
16130 (use (match_operand:SI 3 "const_int_operand" ""))]
16131 "! optimize_size"
16132 {
16133 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16134 DONE;
16135 else
16136 FAIL;
16137 })
16138
16139 (define_expand "movstrdi"
16140 [(use (match_operand:BLK 0 "memory_operand" ""))
16141 (use (match_operand:BLK 1 "memory_operand" ""))
16142 (use (match_operand:DI 2 "nonmemory_operand" ""))
16143 (use (match_operand:DI 3 "const_int_operand" ""))]
16144 "TARGET_64BIT"
16145 {
16146 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16147 DONE;
16148 else
16149 FAIL;
16150 })
16151
16152 ;; Most CPUs don't like single string operations
16153 ;; Handle this case here to simplify previous expander.
16154
16155 (define_expand "strmovdi_rex64"
16156 [(set (match_dup 2)
16157 (mem:DI (match_operand:DI 1 "register_operand" "")))
16158 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
16159 (match_dup 2))
16160 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16161 (clobber (reg:CC 17))])
16162 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
16163 (clobber (reg:CC 17))])]
16164 "TARGET_64BIT"
16165 {
16166 if (TARGET_SINGLE_STRINGOP || optimize_size)
16167 {
16168 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
16169 operands[1]));
16170 DONE;
16171 }
16172 else
16173 operands[2] = gen_reg_rtx (DImode);
16174 })
16175
16176
16177 (define_expand "strmovsi"
16178 [(set (match_dup 2)
16179 (mem:SI (match_operand:SI 1 "register_operand" "")))
16180 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
16181 (match_dup 2))
16182 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16183 (clobber (reg:CC 17))])
16184 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
16185 (clobber (reg:CC 17))])]
16186 ""
16187 {
16188 if (TARGET_64BIT)
16189 {
16190 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
16191 DONE;
16192 }
16193 if (TARGET_SINGLE_STRINGOP || optimize_size)
16194 {
16195 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
16196 operands[1]));
16197 DONE;
16198 }
16199 else
16200 operands[2] = gen_reg_rtx (SImode);
16201 })
16202
16203 (define_expand "strmovsi_rex64"
16204 [(set (match_dup 2)
16205 (mem:SI (match_operand:DI 1 "register_operand" "")))
16206 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
16207 (match_dup 2))
16208 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16209 (clobber (reg:CC 17))])
16210 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
16211 (clobber (reg:CC 17))])]
16212 "TARGET_64BIT"
16213 {
16214 if (TARGET_SINGLE_STRINGOP || optimize_size)
16215 {
16216 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
16217 operands[1]));
16218 DONE;
16219 }
16220 else
16221 operands[2] = gen_reg_rtx (SImode);
16222 })
16223
16224 (define_expand "strmovhi"
16225 [(set (match_dup 2)
16226 (mem:HI (match_operand:SI 1 "register_operand" "")))
16227 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
16228 (match_dup 2))
16229 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16230 (clobber (reg:CC 17))])
16231 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
16232 (clobber (reg:CC 17))])]
16233 ""
16234 {
16235 if (TARGET_64BIT)
16236 {
16237 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
16238 DONE;
16239 }
16240 if (TARGET_SINGLE_STRINGOP || optimize_size)
16241 {
16242 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
16243 operands[1]));
16244 DONE;
16245 }
16246 else
16247 operands[2] = gen_reg_rtx (HImode);
16248 })
16249
16250 (define_expand "strmovhi_rex64"
16251 [(set (match_dup 2)
16252 (mem:HI (match_operand:DI 1 "register_operand" "")))
16253 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
16254 (match_dup 2))
16255 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16256 (clobber (reg:CC 17))])
16257 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
16258 (clobber (reg:CC 17))])]
16259 "TARGET_64BIT"
16260 {
16261 if (TARGET_SINGLE_STRINGOP || optimize_size)
16262 {
16263 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
16264 operands[1]));
16265 DONE;
16266 }
16267 else
16268 operands[2] = gen_reg_rtx (HImode);
16269 })
16270
16271 (define_expand "strmovqi"
16272 [(set (match_dup 2)
16273 (mem:QI (match_operand:SI 1 "register_operand" "")))
16274 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
16275 (match_dup 2))
16276 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16277 (clobber (reg:CC 17))])
16278 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
16279 (clobber (reg:CC 17))])]
16280 ""
16281 {
16282 if (TARGET_64BIT)
16283 {
16284 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
16285 DONE;
16286 }
16287 if (TARGET_SINGLE_STRINGOP || optimize_size)
16288 {
16289 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
16290 operands[1]));
16291 DONE;
16292 }
16293 else
16294 operands[2] = gen_reg_rtx (QImode);
16295 })
16296
16297 (define_expand "strmovqi_rex64"
16298 [(set (match_dup 2)
16299 (mem:QI (match_operand:DI 1 "register_operand" "")))
16300 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
16301 (match_dup 2))
16302 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16303 (clobber (reg:CC 17))])
16304 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
16305 (clobber (reg:CC 17))])]
16306 "TARGET_64BIT"
16307 {
16308 if (TARGET_SINGLE_STRINGOP || optimize_size)
16309 {
16310 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
16311 operands[1]));
16312 DONE;
16313 }
16314 else
16315 operands[2] = gen_reg_rtx (QImode);
16316 })
16317
16318 (define_insn "strmovdi_rex_1"
16319 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16320 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16321 (set (match_operand:DI 0 "register_operand" "=D")
16322 (plus:DI (match_dup 2)
16323 (const_int 8)))
16324 (set (match_operand:DI 1 "register_operand" "=S")
16325 (plus:DI (match_dup 3)
16326 (const_int 8)))
16327 (use (reg:SI 19))]
16328 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16329 "movsq"
16330 [(set_attr "type" "str")
16331 (set_attr "mode" "DI")
16332 (set_attr "memory" "both")])
16333
16334 (define_insn "strmovsi_1"
16335 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16336 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16337 (set (match_operand:SI 0 "register_operand" "=D")
16338 (plus:SI (match_dup 2)
16339 (const_int 4)))
16340 (set (match_operand:SI 1 "register_operand" "=S")
16341 (plus:SI (match_dup 3)
16342 (const_int 4)))
16343 (use (reg:SI 19))]
16344 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16345 "{movsl|movsd}"
16346 [(set_attr "type" "str")
16347 (set_attr "mode" "SI")
16348 (set_attr "memory" "both")])
16349
16350 (define_insn "strmovsi_rex_1"
16351 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16352 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16353 (set (match_operand:DI 0 "register_operand" "=D")
16354 (plus:DI (match_dup 2)
16355 (const_int 4)))
16356 (set (match_operand:DI 1 "register_operand" "=S")
16357 (plus:DI (match_dup 3)
16358 (const_int 4)))
16359 (use (reg:SI 19))]
16360 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16361 "{movsl|movsd}"
16362 [(set_attr "type" "str")
16363 (set_attr "mode" "SI")
16364 (set_attr "memory" "both")])
16365
16366 (define_insn "strmovhi_1"
16367 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16368 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16369 (set (match_operand:SI 0 "register_operand" "=D")
16370 (plus:SI (match_dup 2)
16371 (const_int 2)))
16372 (set (match_operand:SI 1 "register_operand" "=S")
16373 (plus:SI (match_dup 3)
16374 (const_int 2)))
16375 (use (reg:SI 19))]
16376 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16377 "movsw"
16378 [(set_attr "type" "str")
16379 (set_attr "memory" "both")
16380 (set_attr "mode" "HI")])
16381
16382 (define_insn "strmovhi_rex_1"
16383 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16384 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16385 (set (match_operand:DI 0 "register_operand" "=D")
16386 (plus:DI (match_dup 2)
16387 (const_int 2)))
16388 (set (match_operand:DI 1 "register_operand" "=S")
16389 (plus:DI (match_dup 3)
16390 (const_int 2)))
16391 (use (reg:SI 19))]
16392 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16393 "movsw"
16394 [(set_attr "type" "str")
16395 (set_attr "memory" "both")
16396 (set_attr "mode" "HI")])
16397
16398 (define_insn "strmovqi_1"
16399 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16400 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16401 (set (match_operand:SI 0 "register_operand" "=D")
16402 (plus:SI (match_dup 2)
16403 (const_int 1)))
16404 (set (match_operand:SI 1 "register_operand" "=S")
16405 (plus:SI (match_dup 3)
16406 (const_int 1)))
16407 (use (reg:SI 19))]
16408 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16409 "movsb"
16410 [(set_attr "type" "str")
16411 (set_attr "memory" "both")
16412 (set_attr "mode" "QI")])
16413
16414 (define_insn "strmovqi_rex_1"
16415 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16416 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16417 (set (match_operand:DI 0 "register_operand" "=D")
16418 (plus:DI (match_dup 2)
16419 (const_int 1)))
16420 (set (match_operand:DI 1 "register_operand" "=S")
16421 (plus:DI (match_dup 3)
16422 (const_int 1)))
16423 (use (reg:SI 19))]
16424 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16425 "movsb"
16426 [(set_attr "type" "str")
16427 (set_attr "memory" "both")
16428 (set_attr "mode" "QI")])
16429
16430 (define_insn "rep_movdi_rex64"
16431 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16432 (set (match_operand:DI 0 "register_operand" "=D")
16433 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16434 (const_int 3))
16435 (match_operand:DI 3 "register_operand" "0")))
16436 (set (match_operand:DI 1 "register_operand" "=S")
16437 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16438 (match_operand:DI 4 "register_operand" "1")))
16439 (set (mem:BLK (match_dup 3))
16440 (mem:BLK (match_dup 4)))
16441 (use (match_dup 5))
16442 (use (reg:SI 19))]
16443 "TARGET_64BIT"
16444 "{rep\;movsq|rep movsq}"
16445 [(set_attr "type" "str")
16446 (set_attr "prefix_rep" "1")
16447 (set_attr "memory" "both")
16448 (set_attr "mode" "DI")])
16449
16450 (define_insn "rep_movsi"
16451 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16452 (set (match_operand:SI 0 "register_operand" "=D")
16453 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16454 (const_int 2))
16455 (match_operand:SI 3 "register_operand" "0")))
16456 (set (match_operand:SI 1 "register_operand" "=S")
16457 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16458 (match_operand:SI 4 "register_operand" "1")))
16459 (set (mem:BLK (match_dup 3))
16460 (mem:BLK (match_dup 4)))
16461 (use (match_dup 5))
16462 (use (reg:SI 19))]
16463 "!TARGET_64BIT"
16464 "{rep\;movsl|rep movsd}"
16465 [(set_attr "type" "str")
16466 (set_attr "prefix_rep" "1")
16467 (set_attr "memory" "both")
16468 (set_attr "mode" "SI")])
16469
16470 (define_insn "rep_movsi_rex64"
16471 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16472 (set (match_operand:DI 0 "register_operand" "=D")
16473 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16474 (const_int 2))
16475 (match_operand:DI 3 "register_operand" "0")))
16476 (set (match_operand:DI 1 "register_operand" "=S")
16477 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16478 (match_operand:DI 4 "register_operand" "1")))
16479 (set (mem:BLK (match_dup 3))
16480 (mem:BLK (match_dup 4)))
16481 (use (match_dup 5))
16482 (use (reg:SI 19))]
16483 "TARGET_64BIT"
16484 "{rep\;movsl|rep movsd}"
16485 [(set_attr "type" "str")
16486 (set_attr "prefix_rep" "1")
16487 (set_attr "memory" "both")
16488 (set_attr "mode" "SI")])
16489
16490 (define_insn "rep_movqi"
16491 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16492 (set (match_operand:SI 0 "register_operand" "=D")
16493 (plus:SI (match_operand:SI 3 "register_operand" "0")
16494 (match_operand:SI 5 "register_operand" "2")))
16495 (set (match_operand:SI 1 "register_operand" "=S")
16496 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16497 (set (mem:BLK (match_dup 3))
16498 (mem:BLK (match_dup 4)))
16499 (use (match_dup 5))
16500 (use (reg:SI 19))]
16501 "!TARGET_64BIT"
16502 "{rep\;movsb|rep movsb}"
16503 [(set_attr "type" "str")
16504 (set_attr "prefix_rep" "1")
16505 (set_attr "memory" "both")
16506 (set_attr "mode" "SI")])
16507
16508 (define_insn "rep_movqi_rex64"
16509 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16510 (set (match_operand:DI 0 "register_operand" "=D")
16511 (plus:DI (match_operand:DI 3 "register_operand" "0")
16512 (match_operand:DI 5 "register_operand" "2")))
16513 (set (match_operand:DI 1 "register_operand" "=S")
16514 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16515 (set (mem:BLK (match_dup 3))
16516 (mem:BLK (match_dup 4)))
16517 (use (match_dup 5))
16518 (use (reg:SI 19))]
16519 "TARGET_64BIT"
16520 "{rep\;movsb|rep movsb}"
16521 [(set_attr "type" "str")
16522 (set_attr "prefix_rep" "1")
16523 (set_attr "memory" "both")
16524 (set_attr "mode" "SI")])
16525
16526 (define_expand "clrstrsi"
16527 [(use (match_operand:BLK 0 "memory_operand" ""))
16528 (use (match_operand:SI 1 "nonmemory_operand" ""))
16529 (use (match_operand 2 "const_int_operand" ""))]
16530 ""
16531 {
16532 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16533 DONE;
16534 else
16535 FAIL;
16536 })
16537
16538 (define_expand "clrstrdi"
16539 [(use (match_operand:BLK 0 "memory_operand" ""))
16540 (use (match_operand:DI 1 "nonmemory_operand" ""))
16541 (use (match_operand 2 "const_int_operand" ""))]
16542 "TARGET_64BIT"
16543 {
16544 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16545 DONE;
16546 else
16547 FAIL;
16548 })
16549
16550 ;; Most CPUs don't like single string operations
16551 ;; Handle this case here to simplify previous expander.
16552
16553 (define_expand "strsetdi_rex64"
16554 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
16555 (match_operand:DI 1 "register_operand" ""))
16556 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16557 (clobber (reg:CC 17))])]
16558 "TARGET_64BIT"
16559 {
16560 if (TARGET_SINGLE_STRINGOP || optimize_size)
16561 {
16562 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
16563 DONE;
16564 }
16565 })
16566
16567 (define_expand "strsetsi"
16568 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
16569 (match_operand:SI 1 "register_operand" ""))
16570 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16571 (clobber (reg:CC 17))])]
16572 ""
16573 {
16574 if (TARGET_64BIT)
16575 {
16576 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
16577 DONE;
16578 }
16579 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16580 {
16581 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
16582 DONE;
16583 }
16584 })
16585
16586 (define_expand "strsetsi_rex64"
16587 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
16588 (match_operand:SI 1 "register_operand" ""))
16589 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16590 (clobber (reg:CC 17))])]
16591 "TARGET_64BIT"
16592 {
16593 if (TARGET_SINGLE_STRINGOP || optimize_size)
16594 {
16595 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
16596 DONE;
16597 }
16598 })
16599
16600 (define_expand "strsethi"
16601 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
16602 (match_operand:HI 1 "register_operand" ""))
16603 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16604 (clobber (reg:CC 17))])]
16605 ""
16606 {
16607 if (TARGET_64BIT)
16608 {
16609 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
16610 DONE;
16611 }
16612 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16613 {
16614 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
16615 DONE;
16616 }
16617 })
16618
16619 (define_expand "strsethi_rex64"
16620 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
16621 (match_operand:HI 1 "register_operand" ""))
16622 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16623 (clobber (reg:CC 17))])]
16624 "TARGET_64BIT"
16625 {
16626 if (TARGET_SINGLE_STRINGOP || optimize_size)
16627 {
16628 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
16629 DONE;
16630 }
16631 })
16632
16633 (define_expand "strsetqi"
16634 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
16635 (match_operand:QI 1 "register_operand" ""))
16636 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16637 (clobber (reg:CC 17))])]
16638 ""
16639 {
16640 if (TARGET_64BIT)
16641 {
16642 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
16643 DONE;
16644 }
16645 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16646 {
16647 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
16648 DONE;
16649 }
16650 })
16651
16652 (define_expand "strsetqi_rex64"
16653 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
16654 (match_operand:QI 1 "register_operand" ""))
16655 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16656 (clobber (reg:CC 17))])]
16657 "TARGET_64BIT"
16658 {
16659 if (TARGET_SINGLE_STRINGOP || optimize_size)
16660 {
16661 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
16662 DONE;
16663 }
16664 })
16665
16666 (define_insn "strsetdi_rex_1"
16667 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16668 (match_operand:SI 2 "register_operand" "a"))
16669 (set (match_operand:DI 0 "register_operand" "=D")
16670 (plus:DI (match_dup 1)
16671 (const_int 8)))
16672 (use (reg:SI 19))]
16673 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16674 "stosq"
16675 [(set_attr "type" "str")
16676 (set_attr "memory" "store")
16677 (set_attr "mode" "DI")])
16678
16679 (define_insn "strsetsi_1"
16680 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16681 (match_operand:SI 2 "register_operand" "a"))
16682 (set (match_operand:SI 0 "register_operand" "=D")
16683 (plus:SI (match_dup 1)
16684 (const_int 4)))
16685 (use (reg:SI 19))]
16686 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16687 "{stosl|stosd}"
16688 [(set_attr "type" "str")
16689 (set_attr "memory" "store")
16690 (set_attr "mode" "SI")])
16691
16692 (define_insn "strsetsi_rex_1"
16693 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16694 (match_operand:SI 2 "register_operand" "a"))
16695 (set (match_operand:DI 0 "register_operand" "=D")
16696 (plus:DI (match_dup 1)
16697 (const_int 4)))
16698 (use (reg:SI 19))]
16699 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16700 "{stosl|stosd}"
16701 [(set_attr "type" "str")
16702 (set_attr "memory" "store")
16703 (set_attr "mode" "SI")])
16704
16705 (define_insn "strsethi_1"
16706 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16707 (match_operand:HI 2 "register_operand" "a"))
16708 (set (match_operand:SI 0 "register_operand" "=D")
16709 (plus:SI (match_dup 1)
16710 (const_int 2)))
16711 (use (reg:SI 19))]
16712 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16713 "stosw"
16714 [(set_attr "type" "str")
16715 (set_attr "memory" "store")
16716 (set_attr "mode" "HI")])
16717
16718 (define_insn "strsethi_rex_1"
16719 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16720 (match_operand:HI 2 "register_operand" "a"))
16721 (set (match_operand:DI 0 "register_operand" "=D")
16722 (plus:DI (match_dup 1)
16723 (const_int 2)))
16724 (use (reg:SI 19))]
16725 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16726 "stosw"
16727 [(set_attr "type" "str")
16728 (set_attr "memory" "store")
16729 (set_attr "mode" "HI")])
16730
16731 (define_insn "strsetqi_1"
16732 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16733 (match_operand:QI 2 "register_operand" "a"))
16734 (set (match_operand:SI 0 "register_operand" "=D")
16735 (plus:SI (match_dup 1)
16736 (const_int 1)))
16737 (use (reg:SI 19))]
16738 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16739 "stosb"
16740 [(set_attr "type" "str")
16741 (set_attr "memory" "store")
16742 (set_attr "mode" "QI")])
16743
16744 (define_insn "strsetqi_rex_1"
16745 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16746 (match_operand:QI 2 "register_operand" "a"))
16747 (set (match_operand:DI 0 "register_operand" "=D")
16748 (plus:DI (match_dup 1)
16749 (const_int 1)))
16750 (use (reg:SI 19))]
16751 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16752 "stosb"
16753 [(set_attr "type" "str")
16754 (set_attr "memory" "store")
16755 (set_attr "mode" "QI")])
16756
16757 (define_insn "rep_stosdi_rex64"
16758 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16759 (set (match_operand:DI 0 "register_operand" "=D")
16760 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16761 (const_int 3))
16762 (match_operand:DI 3 "register_operand" "0")))
16763 (set (mem:BLK (match_dup 3))
16764 (const_int 0))
16765 (use (match_operand:DI 2 "register_operand" "a"))
16766 (use (match_dup 4))
16767 (use (reg:SI 19))]
16768 "TARGET_64BIT"
16769 "{rep\;stosq|rep stosq}"
16770 [(set_attr "type" "str")
16771 (set_attr "prefix_rep" "1")
16772 (set_attr "memory" "store")
16773 (set_attr "mode" "DI")])
16774
16775 (define_insn "rep_stossi"
16776 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16777 (set (match_operand:SI 0 "register_operand" "=D")
16778 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16779 (const_int 2))
16780 (match_operand:SI 3 "register_operand" "0")))
16781 (set (mem:BLK (match_dup 3))
16782 (const_int 0))
16783 (use (match_operand:SI 2 "register_operand" "a"))
16784 (use (match_dup 4))
16785 (use (reg:SI 19))]
16786 "!TARGET_64BIT"
16787 "{rep\;stosl|rep stosd}"
16788 [(set_attr "type" "str")
16789 (set_attr "prefix_rep" "1")
16790 (set_attr "memory" "store")
16791 (set_attr "mode" "SI")])
16792
16793 (define_insn "rep_stossi_rex64"
16794 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16795 (set (match_operand:DI 0 "register_operand" "=D")
16796 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16797 (const_int 2))
16798 (match_operand:DI 3 "register_operand" "0")))
16799 (set (mem:BLK (match_dup 3))
16800 (const_int 0))
16801 (use (match_operand:SI 2 "register_operand" "a"))
16802 (use (match_dup 4))
16803 (use (reg:SI 19))]
16804 "TARGET_64BIT"
16805 "{rep\;stosl|rep stosd}"
16806 [(set_attr "type" "str")
16807 (set_attr "prefix_rep" "1")
16808 (set_attr "memory" "store")
16809 (set_attr "mode" "SI")])
16810
16811 (define_insn "rep_stosqi"
16812 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16813 (set (match_operand:SI 0 "register_operand" "=D")
16814 (plus:SI (match_operand:SI 3 "register_operand" "0")
16815 (match_operand:SI 4 "register_operand" "1")))
16816 (set (mem:BLK (match_dup 3))
16817 (const_int 0))
16818 (use (match_operand:QI 2 "register_operand" "a"))
16819 (use (match_dup 4))
16820 (use (reg:SI 19))]
16821 "!TARGET_64BIT"
16822 "{rep\;stosb|rep stosb}"
16823 [(set_attr "type" "str")
16824 (set_attr "prefix_rep" "1")
16825 (set_attr "memory" "store")
16826 (set_attr "mode" "QI")])
16827
16828 (define_insn "rep_stosqi_rex64"
16829 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16830 (set (match_operand:DI 0 "register_operand" "=D")
16831 (plus:DI (match_operand:DI 3 "register_operand" "0")
16832 (match_operand:DI 4 "register_operand" "1")))
16833 (set (mem:BLK (match_dup 3))
16834 (const_int 0))
16835 (use (match_operand:QI 2 "register_operand" "a"))
16836 (use (match_dup 4))
16837 (use (reg:DI 19))]
16838 "TARGET_64BIT"
16839 "{rep\;stosb|rep stosb}"
16840 [(set_attr "type" "str")
16841 (set_attr "prefix_rep" "1")
16842 (set_attr "memory" "store")
16843 (set_attr "mode" "QI")])
16844
16845 (define_expand "cmpstrsi"
16846 [(set (match_operand:SI 0 "register_operand" "")
16847 (compare:SI (match_operand:BLK 1 "general_operand" "")
16848 (match_operand:BLK 2 "general_operand" "")))
16849 (use (match_operand 3 "general_operand" ""))
16850 (use (match_operand 4 "immediate_operand" ""))]
16851 "! optimize_size"
16852 {
16853 rtx addr1, addr2, out, outlow, count, countreg, align;
16854
16855 /* Can't use this if the user has appropriated esi or edi. */
16856 if (global_regs[4] || global_regs[5])
16857 FAIL;
16858
16859 out = operands[0];
16860 if (GET_CODE (out) != REG)
16861 out = gen_reg_rtx (SImode);
16862
16863 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16864 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16865
16866 count = operands[3];
16867 countreg = ix86_zero_extend_to_Pmode (count);
16868
16869 /* %%% Iff we are testing strict equality, we can use known alignment
16870 to good advantage. This may be possible with combine, particularly
16871 once cc0 is dead. */
16872 align = operands[4];
16873
16874 emit_insn (gen_cld ());
16875 if (GET_CODE (count) == CONST_INT)
16876 {
16877 if (INTVAL (count) == 0)
16878 {
16879 emit_move_insn (operands[0], const0_rtx);
16880 DONE;
16881 }
16882 if (TARGET_64BIT)
16883 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16884 addr1, addr2, countreg));
16885 else
16886 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16887 addr1, addr2, countreg));
16888 }
16889 else
16890 {
16891 if (TARGET_64BIT)
16892 {
16893 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16894 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16895 addr1, addr2, countreg));
16896 }
16897 else
16898 {
16899 emit_insn (gen_cmpsi_1 (countreg, countreg));
16900 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16901 addr1, addr2, countreg));
16902 }
16903 }
16904
16905 outlow = gen_lowpart (QImode, out);
16906 emit_insn (gen_cmpintqi (outlow));
16907 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16908
16909 if (operands[0] != out)
16910 emit_move_insn (operands[0], out);
16911
16912 DONE;
16913 })
16914
16915 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16916
16917 (define_expand "cmpintqi"
16918 [(set (match_dup 1)
16919 (gtu:QI (reg:CC 17) (const_int 0)))
16920 (set (match_dup 2)
16921 (ltu:QI (reg:CC 17) (const_int 0)))
16922 (parallel [(set (match_operand:QI 0 "register_operand" "")
16923 (minus:QI (match_dup 1)
16924 (match_dup 2)))
16925 (clobber (reg:CC 17))])]
16926 ""
16927 "operands[1] = gen_reg_rtx (QImode);
16928 operands[2] = gen_reg_rtx (QImode);")
16929
16930 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16931 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16932
16933 (define_insn "cmpstrqi_nz_1"
16934 [(set (reg:CC 17)
16935 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16936 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16937 (use (match_operand:SI 6 "register_operand" "2"))
16938 (use (match_operand:SI 3 "immediate_operand" "i"))
16939 (use (reg:SI 19))
16940 (clobber (match_operand:SI 0 "register_operand" "=S"))
16941 (clobber (match_operand:SI 1 "register_operand" "=D"))
16942 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16943 "!TARGET_64BIT"
16944 "repz{\;| }cmpsb"
16945 [(set_attr "type" "str")
16946 (set_attr "mode" "QI")
16947 (set_attr "prefix_rep" "1")])
16948
16949 (define_insn "cmpstrqi_nz_rex_1"
16950 [(set (reg:CC 17)
16951 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16952 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16953 (use (match_operand:DI 6 "register_operand" "2"))
16954 (use (match_operand:SI 3 "immediate_operand" "i"))
16955 (use (reg:SI 19))
16956 (clobber (match_operand:DI 0 "register_operand" "=S"))
16957 (clobber (match_operand:DI 1 "register_operand" "=D"))
16958 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16959 "TARGET_64BIT"
16960 "repz{\;| }cmpsb"
16961 [(set_attr "type" "str")
16962 (set_attr "mode" "QI")
16963 (set_attr "prefix_rep" "1")])
16964
16965 ;; The same, but the count is not known to not be zero.
16966
16967 (define_insn "cmpstrqi_1"
16968 [(set (reg:CC 17)
16969 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16970 (const_int 0))
16971 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16972 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16973 (const_int 0)))
16974 (use (match_operand:SI 3 "immediate_operand" "i"))
16975 (use (reg:CC 17))
16976 (use (reg:SI 19))
16977 (clobber (match_operand:SI 0 "register_operand" "=S"))
16978 (clobber (match_operand:SI 1 "register_operand" "=D"))
16979 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16980 "!TARGET_64BIT"
16981 "repz{\;| }cmpsb"
16982 [(set_attr "type" "str")
16983 (set_attr "mode" "QI")
16984 (set_attr "prefix_rep" "1")])
16985
16986 (define_insn "cmpstrqi_rex_1"
16987 [(set (reg:CC 17)
16988 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16989 (const_int 0))
16990 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16991 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16992 (const_int 0)))
16993 (use (match_operand:SI 3 "immediate_operand" "i"))
16994 (use (reg:CC 17))
16995 (use (reg:SI 19))
16996 (clobber (match_operand:DI 0 "register_operand" "=S"))
16997 (clobber (match_operand:DI 1 "register_operand" "=D"))
16998 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16999 "TARGET_64BIT"
17000 "repz{\;| }cmpsb"
17001 [(set_attr "type" "str")
17002 (set_attr "mode" "QI")
17003 (set_attr "prefix_rep" "1")])
17004
17005 (define_expand "strlensi"
17006 [(set (match_operand:SI 0 "register_operand" "")
17007 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17008 (match_operand:QI 2 "immediate_operand" "")
17009 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17010 ""
17011 {
17012 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17013 DONE;
17014 else
17015 FAIL;
17016 })
17017
17018 (define_expand "strlendi"
17019 [(set (match_operand:DI 0 "register_operand" "")
17020 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17021 (match_operand:QI 2 "immediate_operand" "")
17022 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17023 ""
17024 {
17025 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17026 DONE;
17027 else
17028 FAIL;
17029 })
17030
17031 (define_insn "strlenqi_1"
17032 [(set (match_operand:SI 0 "register_operand" "=&c")
17033 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17034 (match_operand:QI 2 "register_operand" "a")
17035 (match_operand:SI 3 "immediate_operand" "i")
17036 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17037 (use (reg:SI 19))
17038 (clobber (match_operand:SI 1 "register_operand" "=D"))
17039 (clobber (reg:CC 17))]
17040 "!TARGET_64BIT"
17041 "repnz{\;| }scasb"
17042 [(set_attr "type" "str")
17043 (set_attr "mode" "QI")
17044 (set_attr "prefix_rep" "1")])
17045
17046 (define_insn "strlenqi_rex_1"
17047 [(set (match_operand:DI 0 "register_operand" "=&c")
17048 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17049 (match_operand:QI 2 "register_operand" "a")
17050 (match_operand:DI 3 "immediate_operand" "i")
17051 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17052 (use (reg:SI 19))
17053 (clobber (match_operand:DI 1 "register_operand" "=D"))
17054 (clobber (reg:CC 17))]
17055 "TARGET_64BIT"
17056 "repnz{\;| }scasb"
17057 [(set_attr "type" "str")
17058 (set_attr "mode" "QI")
17059 (set_attr "prefix_rep" "1")])
17060
17061 ;; Peephole optimizations to clean up after cmpstr*. This should be
17062 ;; handled in combine, but it is not currently up to the task.
17063 ;; When used for their truth value, the cmpstr* expanders generate
17064 ;; code like this:
17065 ;;
17066 ;; repz cmpsb
17067 ;; seta %al
17068 ;; setb %dl
17069 ;; cmpb %al, %dl
17070 ;; jcc label
17071 ;;
17072 ;; The intermediate three instructions are unnecessary.
17073
17074 ;; This one handles cmpstr*_nz_1...
17075 (define_peephole2
17076 [(parallel[
17077 (set (reg:CC 17)
17078 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17079 (mem:BLK (match_operand 5 "register_operand" ""))))
17080 (use (match_operand 6 "register_operand" ""))
17081 (use (match_operand:SI 3 "immediate_operand" ""))
17082 (use (reg:SI 19))
17083 (clobber (match_operand 0 "register_operand" ""))
17084 (clobber (match_operand 1 "register_operand" ""))
17085 (clobber (match_operand 2 "register_operand" ""))])
17086 (set (match_operand:QI 7 "register_operand" "")
17087 (gtu:QI (reg:CC 17) (const_int 0)))
17088 (set (match_operand:QI 8 "register_operand" "")
17089 (ltu:QI (reg:CC 17) (const_int 0)))
17090 (set (reg 17)
17091 (compare (match_dup 7) (match_dup 8)))
17092 ]
17093 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17094 [(parallel[
17095 (set (reg:CC 17)
17096 (compare:CC (mem:BLK (match_dup 4))
17097 (mem:BLK (match_dup 5))))
17098 (use (match_dup 6))
17099 (use (match_dup 3))
17100 (use (reg:SI 19))
17101 (clobber (match_dup 0))
17102 (clobber (match_dup 1))
17103 (clobber (match_dup 2))])]
17104 "")
17105
17106 ;; ...and this one handles cmpstr*_1.
17107 (define_peephole2
17108 [(parallel[
17109 (set (reg:CC 17)
17110 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17111 (const_int 0))
17112 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17113 (mem:BLK (match_operand 5 "register_operand" "")))
17114 (const_int 0)))
17115 (use (match_operand:SI 3 "immediate_operand" ""))
17116 (use (reg:CC 17))
17117 (use (reg:SI 19))
17118 (clobber (match_operand 0 "register_operand" ""))
17119 (clobber (match_operand 1 "register_operand" ""))
17120 (clobber (match_operand 2 "register_operand" ""))])
17121 (set (match_operand:QI 7 "register_operand" "")
17122 (gtu:QI (reg:CC 17) (const_int 0)))
17123 (set (match_operand:QI 8 "register_operand" "")
17124 (ltu:QI (reg:CC 17) (const_int 0)))
17125 (set (reg 17)
17126 (compare (match_dup 7) (match_dup 8)))
17127 ]
17128 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17129 [(parallel[
17130 (set (reg:CC 17)
17131 (if_then_else:CC (ne (match_dup 6)
17132 (const_int 0))
17133 (compare:CC (mem:BLK (match_dup 4))
17134 (mem:BLK (match_dup 5)))
17135 (const_int 0)))
17136 (use (match_dup 3))
17137 (use (reg:CC 17))
17138 (use (reg:SI 19))
17139 (clobber (match_dup 0))
17140 (clobber (match_dup 1))
17141 (clobber (match_dup 2))])]
17142 "")
17143
17144
17145 \f
17146 ;; Conditional move instructions.
17147
17148 (define_expand "movdicc"
17149 [(set (match_operand:DI 0 "register_operand" "")
17150 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17151 (match_operand:DI 2 "general_operand" "")
17152 (match_operand:DI 3 "general_operand" "")))]
17153 "TARGET_64BIT"
17154 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17155
17156 (define_insn "x86_movdicc_0_m1_rex64"
17157 [(set (match_operand:DI 0 "register_operand" "=r")
17158 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17159 (const_int -1)
17160 (const_int 0)))
17161 (clobber (reg:CC 17))]
17162 "TARGET_64BIT"
17163 "sbb{q}\t%0, %0"
17164 ; Since we don't have the proper number of operands for an alu insn,
17165 ; fill in all the blanks.
17166 [(set_attr "type" "alu")
17167 (set_attr "pent_pair" "pu")
17168 (set_attr "memory" "none")
17169 (set_attr "imm_disp" "false")
17170 (set_attr "mode" "DI")
17171 (set_attr "length_immediate" "0")])
17172
17173 (define_insn "movdicc_c_rex64"
17174 [(set (match_operand:DI 0 "register_operand" "=r,r")
17175 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17176 [(reg 17) (const_int 0)])
17177 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17178 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17179 "TARGET_64BIT && TARGET_CMOVE
17180 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17181 "@
17182 cmov%O2%C1\t{%2, %0|%0, %2}
17183 cmov%O2%c1\t{%3, %0|%0, %3}"
17184 [(set_attr "type" "icmov")
17185 (set_attr "mode" "DI")])
17186
17187 (define_expand "movsicc"
17188 [(set (match_operand:SI 0 "register_operand" "")
17189 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17190 (match_operand:SI 2 "general_operand" "")
17191 (match_operand:SI 3 "general_operand" "")))]
17192 ""
17193 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17194
17195 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17196 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17197 ;; So just document what we're doing explicitly.
17198
17199 (define_insn "x86_movsicc_0_m1"
17200 [(set (match_operand:SI 0 "register_operand" "=r")
17201 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17202 (const_int -1)
17203 (const_int 0)))
17204 (clobber (reg:CC 17))]
17205 ""
17206 "sbb{l}\t%0, %0"
17207 ; Since we don't have the proper number of operands for an alu insn,
17208 ; fill in all the blanks.
17209 [(set_attr "type" "alu")
17210 (set_attr "pent_pair" "pu")
17211 (set_attr "memory" "none")
17212 (set_attr "imm_disp" "false")
17213 (set_attr "mode" "SI")
17214 (set_attr "length_immediate" "0")])
17215
17216 (define_insn "*movsicc_noc"
17217 [(set (match_operand:SI 0 "register_operand" "=r,r")
17218 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17219 [(reg 17) (const_int 0)])
17220 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17221 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17222 "TARGET_CMOVE
17223 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17224 "@
17225 cmov%O2%C1\t{%2, %0|%0, %2}
17226 cmov%O2%c1\t{%3, %0|%0, %3}"
17227 [(set_attr "type" "icmov")
17228 (set_attr "mode" "SI")])
17229
17230 (define_expand "movhicc"
17231 [(set (match_operand:HI 0 "register_operand" "")
17232 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17233 (match_operand:HI 2 "general_operand" "")
17234 (match_operand:HI 3 "general_operand" "")))]
17235 "TARGET_HIMODE_MATH"
17236 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17237
17238 (define_insn "*movhicc_noc"
17239 [(set (match_operand:HI 0 "register_operand" "=r,r")
17240 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17241 [(reg 17) (const_int 0)])
17242 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17243 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17244 "TARGET_CMOVE
17245 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17246 "@
17247 cmov%O2%C1\t{%2, %0|%0, %2}
17248 cmov%O2%c1\t{%3, %0|%0, %3}"
17249 [(set_attr "type" "icmov")
17250 (set_attr "mode" "HI")])
17251
17252 (define_expand "movqicc"
17253 [(set (match_operand:QI 0 "register_operand" "")
17254 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17255 (match_operand:QI 2 "general_operand" "")
17256 (match_operand:QI 3 "general_operand" "")))]
17257 "TARGET_QIMODE_MATH"
17258 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17259
17260 (define_insn_and_split "*movqicc_noc"
17261 [(set (match_operand:QI 0 "register_operand" "=r,r")
17262 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17263 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17264 (match_operand:QI 2 "register_operand" "r,0")
17265 (match_operand:QI 3 "register_operand" "0,r")))]
17266 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17267 "#"
17268 "&& reload_completed"
17269 [(set (match_dup 0)
17270 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17271 (match_dup 2)
17272 (match_dup 3)))]
17273 "operands[0] = gen_lowpart (SImode, operands[0]);
17274 operands[2] = gen_lowpart (SImode, operands[2]);
17275 operands[3] = gen_lowpart (SImode, operands[3]);"
17276 [(set_attr "type" "icmov")
17277 (set_attr "mode" "SI")])
17278
17279 (define_expand "movsfcc"
17280 [(set (match_operand:SF 0 "register_operand" "")
17281 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17282 (match_operand:SF 2 "register_operand" "")
17283 (match_operand:SF 3 "register_operand" "")))]
17284 "TARGET_CMOVE"
17285 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17286
17287 (define_insn "*movsfcc_1"
17288 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17289 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17290 [(reg 17) (const_int 0)])
17291 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17292 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17293 "TARGET_CMOVE
17294 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17295 "@
17296 fcmov%F1\t{%2, %0|%0, %2}
17297 fcmov%f1\t{%3, %0|%0, %3}
17298 cmov%O2%C1\t{%2, %0|%0, %2}
17299 cmov%O2%c1\t{%3, %0|%0, %3}"
17300 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17301 (set_attr "mode" "SF,SF,SI,SI")])
17302
17303 (define_expand "movdfcc"
17304 [(set (match_operand:DF 0 "register_operand" "")
17305 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17306 (match_operand:DF 2 "register_operand" "")
17307 (match_operand:DF 3 "register_operand" "")))]
17308 "TARGET_CMOVE"
17309 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17310
17311 (define_insn "*movdfcc_1"
17312 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17313 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17314 [(reg 17) (const_int 0)])
17315 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17316 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17317 "!TARGET_64BIT && TARGET_CMOVE
17318 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17319 "@
17320 fcmov%F1\t{%2, %0|%0, %2}
17321 fcmov%f1\t{%3, %0|%0, %3}
17322 #
17323 #"
17324 [(set_attr "type" "fcmov,fcmov,multi,multi")
17325 (set_attr "mode" "DF")])
17326
17327 (define_insn "*movdfcc_1_rex64"
17328 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17329 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17330 [(reg 17) (const_int 0)])
17331 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17332 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17333 "TARGET_64BIT && TARGET_CMOVE
17334 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17335 "@
17336 fcmov%F1\t{%2, %0|%0, %2}
17337 fcmov%f1\t{%3, %0|%0, %3}
17338 cmov%O2%C1\t{%2, %0|%0, %2}
17339 cmov%O2%c1\t{%3, %0|%0, %3}"
17340 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17341 (set_attr "mode" "DF")])
17342
17343 (define_split
17344 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17345 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17346 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17347 (match_operand:DF 2 "nonimmediate_operand" "")
17348 (match_operand:DF 3 "nonimmediate_operand" "")))]
17349 "!TARGET_64BIT && reload_completed"
17350 [(set (match_dup 2)
17351 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17352 (match_dup 5)
17353 (match_dup 7)))
17354 (set (match_dup 3)
17355 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17356 (match_dup 6)
17357 (match_dup 8)))]
17358 "split_di (operands+2, 1, operands+5, operands+6);
17359 split_di (operands+3, 1, operands+7, operands+8);
17360 split_di (operands, 1, operands+2, operands+3);")
17361
17362 (define_expand "movxfcc"
17363 [(set (match_operand:XF 0 "register_operand" "")
17364 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17365 (match_operand:XF 2 "register_operand" "")
17366 (match_operand:XF 3 "register_operand" "")))]
17367 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17368 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17369
17370 (define_expand "movtfcc"
17371 [(set (match_operand:TF 0 "register_operand" "")
17372 (if_then_else:TF (match_operand 1 "comparison_operator" "")
17373 (match_operand:TF 2 "register_operand" "")
17374 (match_operand:TF 3 "register_operand" "")))]
17375 "TARGET_CMOVE"
17376 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17377
17378 (define_insn "*movxfcc_1"
17379 [(set (match_operand:XF 0 "register_operand" "=f,f")
17380 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17381 [(reg 17) (const_int 0)])
17382 (match_operand:XF 2 "register_operand" "f,0")
17383 (match_operand:XF 3 "register_operand" "0,f")))]
17384 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17385 "@
17386 fcmov%F1\t{%2, %0|%0, %2}
17387 fcmov%f1\t{%3, %0|%0, %3}"
17388 [(set_attr "type" "fcmov")
17389 (set_attr "mode" "XF")])
17390
17391 (define_insn "*movtfcc_1"
17392 [(set (match_operand:TF 0 "register_operand" "=f,f")
17393 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
17394 [(reg 17) (const_int 0)])
17395 (match_operand:TF 2 "register_operand" "f,0")
17396 (match_operand:TF 3 "register_operand" "0,f")))]
17397 "TARGET_CMOVE"
17398 "@
17399 fcmov%F1\t{%2, %0|%0, %2}
17400 fcmov%f1\t{%3, %0|%0, %3}"
17401 [(set_attr "type" "fcmov")
17402 (set_attr "mode" "XF")])
17403
17404 (define_expand "minsf3"
17405 [(parallel [
17406 (set (match_operand:SF 0 "register_operand" "")
17407 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17408 (match_operand:SF 2 "nonimmediate_operand" ""))
17409 (match_dup 1)
17410 (match_dup 2)))
17411 (clobber (reg:CC 17))])]
17412 "TARGET_SSE"
17413 "")
17414
17415 (define_insn "*minsf"
17416 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17417 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17418 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17419 (match_dup 1)
17420 (match_dup 2)))
17421 (clobber (reg:CC 17))]
17422 "TARGET_SSE && TARGET_IEEE_FP"
17423 "#")
17424
17425 (define_insn "*minsf_nonieee"
17426 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17427 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17428 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17429 (match_dup 1)
17430 (match_dup 2)))
17431 (clobber (reg:CC 17))]
17432 "TARGET_SSE && !TARGET_IEEE_FP
17433 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17434 "#")
17435
17436 (define_split
17437 [(set (match_operand:SF 0 "register_operand" "")
17438 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17439 (match_operand:SF 2 "nonimmediate_operand" ""))
17440 (match_operand:SF 3 "register_operand" "")
17441 (match_operand:SF 4 "nonimmediate_operand" "")))
17442 (clobber (reg:CC 17))]
17443 "SSE_REG_P (operands[0]) && reload_completed
17444 && ((operands_match_p (operands[1], operands[3])
17445 && operands_match_p (operands[2], operands[4]))
17446 || (operands_match_p (operands[1], operands[4])
17447 && operands_match_p (operands[2], operands[3])))"
17448 [(set (match_dup 0)
17449 (if_then_else:SF (lt (match_dup 1)
17450 (match_dup 2))
17451 (match_dup 1)
17452 (match_dup 2)))])
17453
17454 ;; Conditional addition patterns
17455 (define_expand "addqicc"
17456 [(match_operand:QI 0 "register_operand" "")
17457 (match_operand 1 "comparison_operator" "")
17458 (match_operand:QI 2 "register_operand" "")
17459 (match_operand:QI 3 "const_int_operand" "")]
17460 ""
17461 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17462
17463 (define_expand "addhicc"
17464 [(match_operand:HI 0 "register_operand" "")
17465 (match_operand 1 "comparison_operator" "")
17466 (match_operand:HI 2 "register_operand" "")
17467 (match_operand:HI 3 "const_int_operand" "")]
17468 ""
17469 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17470
17471 (define_expand "addsicc"
17472 [(match_operand:SI 0 "register_operand" "")
17473 (match_operand 1 "comparison_operator" "")
17474 (match_operand:SI 2 "register_operand" "")
17475 (match_operand:SI 3 "const_int_operand" "")]
17476 ""
17477 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17478
17479 (define_expand "adddicc"
17480 [(match_operand:DI 0 "register_operand" "")
17481 (match_operand 1 "comparison_operator" "")
17482 (match_operand:DI 2 "register_operand" "")
17483 (match_operand:DI 3 "const_int_operand" "")]
17484 "TARGET_64BIT"
17485 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17486
17487 ;; We can't represent the LT test directly. Do this by swapping the operands.
17488
17489 (define_split
17490 [(set (match_operand:SF 0 "fp_register_operand" "")
17491 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17492 (match_operand:SF 2 "register_operand" ""))
17493 (match_operand:SF 3 "register_operand" "")
17494 (match_operand:SF 4 "register_operand" "")))
17495 (clobber (reg:CC 17))]
17496 "reload_completed
17497 && ((operands_match_p (operands[1], operands[3])
17498 && operands_match_p (operands[2], operands[4]))
17499 || (operands_match_p (operands[1], operands[4])
17500 && operands_match_p (operands[2], operands[3])))"
17501 [(set (reg:CCFP 17)
17502 (compare:CCFP (match_dup 2)
17503 (match_dup 1)))
17504 (set (match_dup 0)
17505 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17506 (match_dup 1)
17507 (match_dup 2)))])
17508
17509 (define_insn "*minsf_sse"
17510 [(set (match_operand:SF 0 "register_operand" "=x")
17511 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17512 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17513 (match_dup 1)
17514 (match_dup 2)))]
17515 "TARGET_SSE && reload_completed"
17516 "minss\t{%2, %0|%0, %2}"
17517 [(set_attr "type" "sse")
17518 (set_attr "mode" "SF")])
17519
17520 (define_expand "mindf3"
17521 [(parallel [
17522 (set (match_operand:DF 0 "register_operand" "")
17523 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17524 (match_operand:DF 2 "nonimmediate_operand" ""))
17525 (match_dup 1)
17526 (match_dup 2)))
17527 (clobber (reg:CC 17))])]
17528 "TARGET_SSE2 && TARGET_SSE_MATH"
17529 "#")
17530
17531 (define_insn "*mindf"
17532 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17533 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17534 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17535 (match_dup 1)
17536 (match_dup 2)))
17537 (clobber (reg:CC 17))]
17538 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17539 "#")
17540
17541 (define_insn "*mindf_nonieee"
17542 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17543 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17544 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17545 (match_dup 1)
17546 (match_dup 2)))
17547 (clobber (reg:CC 17))]
17548 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17549 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17550 "#")
17551
17552 (define_split
17553 [(set (match_operand:DF 0 "register_operand" "")
17554 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17555 (match_operand:DF 2 "nonimmediate_operand" ""))
17556 (match_operand:DF 3 "register_operand" "")
17557 (match_operand:DF 4 "nonimmediate_operand" "")))
17558 (clobber (reg:CC 17))]
17559 "SSE_REG_P (operands[0]) && reload_completed
17560 && ((operands_match_p (operands[1], operands[3])
17561 && operands_match_p (operands[2], operands[4]))
17562 || (operands_match_p (operands[1], operands[4])
17563 && operands_match_p (operands[2], operands[3])))"
17564 [(set (match_dup 0)
17565 (if_then_else:DF (lt (match_dup 1)
17566 (match_dup 2))
17567 (match_dup 1)
17568 (match_dup 2)))])
17569
17570 ;; We can't represent the LT test directly. Do this by swapping the operands.
17571 (define_split
17572 [(set (match_operand:DF 0 "fp_register_operand" "")
17573 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17574 (match_operand:DF 2 "register_operand" ""))
17575 (match_operand:DF 3 "register_operand" "")
17576 (match_operand:DF 4 "register_operand" "")))
17577 (clobber (reg:CC 17))]
17578 "reload_completed
17579 && ((operands_match_p (operands[1], operands[3])
17580 && operands_match_p (operands[2], operands[4]))
17581 || (operands_match_p (operands[1], operands[4])
17582 && operands_match_p (operands[2], operands[3])))"
17583 [(set (reg:CCFP 17)
17584 (compare:CCFP (match_dup 2)
17585 (match_dup 2)))
17586 (set (match_dup 0)
17587 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17588 (match_dup 1)
17589 (match_dup 2)))])
17590
17591 (define_insn "*mindf_sse"
17592 [(set (match_operand:DF 0 "register_operand" "=Y")
17593 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17594 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17595 (match_dup 1)
17596 (match_dup 2)))]
17597 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17598 "minsd\t{%2, %0|%0, %2}"
17599 [(set_attr "type" "sse")
17600 (set_attr "mode" "DF")])
17601
17602 (define_expand "maxsf3"
17603 [(parallel [
17604 (set (match_operand:SF 0 "register_operand" "")
17605 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17606 (match_operand:SF 2 "nonimmediate_operand" ""))
17607 (match_dup 1)
17608 (match_dup 2)))
17609 (clobber (reg:CC 17))])]
17610 "TARGET_SSE"
17611 "#")
17612
17613 (define_insn "*maxsf"
17614 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17615 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17616 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17617 (match_dup 1)
17618 (match_dup 2)))
17619 (clobber (reg:CC 17))]
17620 "TARGET_SSE && TARGET_IEEE_FP"
17621 "#")
17622
17623 (define_insn "*maxsf_nonieee"
17624 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17625 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17626 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17627 (match_dup 1)
17628 (match_dup 2)))
17629 (clobber (reg:CC 17))]
17630 "TARGET_SSE && !TARGET_IEEE_FP
17631 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17632 "#")
17633
17634 (define_split
17635 [(set (match_operand:SF 0 "register_operand" "")
17636 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17637 (match_operand:SF 2 "nonimmediate_operand" ""))
17638 (match_operand:SF 3 "register_operand" "")
17639 (match_operand:SF 4 "nonimmediate_operand" "")))
17640 (clobber (reg:CC 17))]
17641 "SSE_REG_P (operands[0]) && reload_completed
17642 && ((operands_match_p (operands[1], operands[3])
17643 && operands_match_p (operands[2], operands[4]))
17644 || (operands_match_p (operands[1], operands[4])
17645 && operands_match_p (operands[2], operands[3])))"
17646 [(set (match_dup 0)
17647 (if_then_else:SF (gt (match_dup 1)
17648 (match_dup 2))
17649 (match_dup 1)
17650 (match_dup 2)))])
17651
17652 (define_split
17653 [(set (match_operand:SF 0 "fp_register_operand" "")
17654 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17655 (match_operand:SF 2 "register_operand" ""))
17656 (match_operand:SF 3 "register_operand" "")
17657 (match_operand:SF 4 "register_operand" "")))
17658 (clobber (reg:CC 17))]
17659 "reload_completed
17660 && ((operands_match_p (operands[1], operands[3])
17661 && operands_match_p (operands[2], operands[4]))
17662 || (operands_match_p (operands[1], operands[4])
17663 && operands_match_p (operands[2], operands[3])))"
17664 [(set (reg:CCFP 17)
17665 (compare:CCFP (match_dup 1)
17666 (match_dup 2)))
17667 (set (match_dup 0)
17668 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17669 (match_dup 1)
17670 (match_dup 2)))])
17671
17672 (define_insn "*maxsf_sse"
17673 [(set (match_operand:SF 0 "register_operand" "=x")
17674 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17675 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17676 (match_dup 1)
17677 (match_dup 2)))]
17678 "TARGET_SSE && reload_completed"
17679 "maxss\t{%2, %0|%0, %2}"
17680 [(set_attr "type" "sse")
17681 (set_attr "mode" "SF")])
17682
17683 (define_expand "maxdf3"
17684 [(parallel [
17685 (set (match_operand:DF 0 "register_operand" "")
17686 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17687 (match_operand:DF 2 "nonimmediate_operand" ""))
17688 (match_dup 1)
17689 (match_dup 2)))
17690 (clobber (reg:CC 17))])]
17691 "TARGET_SSE2 && TARGET_SSE_MATH"
17692 "#")
17693
17694 (define_insn "*maxdf"
17695 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17696 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17697 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17698 (match_dup 1)
17699 (match_dup 2)))
17700 (clobber (reg:CC 17))]
17701 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17702 "#")
17703
17704 (define_insn "*maxdf_nonieee"
17705 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17706 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17707 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17708 (match_dup 1)
17709 (match_dup 2)))
17710 (clobber (reg:CC 17))]
17711 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17712 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17713 "#")
17714
17715 (define_split
17716 [(set (match_operand:DF 0 "register_operand" "")
17717 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17718 (match_operand:DF 2 "nonimmediate_operand" ""))
17719 (match_operand:DF 3 "register_operand" "")
17720 (match_operand:DF 4 "nonimmediate_operand" "")))
17721 (clobber (reg:CC 17))]
17722 "SSE_REG_P (operands[0]) && reload_completed
17723 && ((operands_match_p (operands[1], operands[3])
17724 && operands_match_p (operands[2], operands[4]))
17725 || (operands_match_p (operands[1], operands[4])
17726 && operands_match_p (operands[2], operands[3])))"
17727 [(set (match_dup 0)
17728 (if_then_else:DF (gt (match_dup 1)
17729 (match_dup 2))
17730 (match_dup 1)
17731 (match_dup 2)))])
17732
17733 (define_split
17734 [(set (match_operand:DF 0 "fp_register_operand" "")
17735 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17736 (match_operand:DF 2 "register_operand" ""))
17737 (match_operand:DF 3 "register_operand" "")
17738 (match_operand:DF 4 "register_operand" "")))
17739 (clobber (reg:CC 17))]
17740 "reload_completed
17741 && ((operands_match_p (operands[1], operands[3])
17742 && operands_match_p (operands[2], operands[4]))
17743 || (operands_match_p (operands[1], operands[4])
17744 && operands_match_p (operands[2], operands[3])))"
17745 [(set (reg:CCFP 17)
17746 (compare:CCFP (match_dup 1)
17747 (match_dup 2)))
17748 (set (match_dup 0)
17749 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17750 (match_dup 1)
17751 (match_dup 2)))])
17752
17753 (define_insn "*maxdf_sse"
17754 [(set (match_operand:DF 0 "register_operand" "=Y")
17755 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17756 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17757 (match_dup 1)
17758 (match_dup 2)))]
17759 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17760 "maxsd\t{%2, %0|%0, %2}"
17761 [(set_attr "type" "sse")
17762 (set_attr "mode" "DF")])
17763 \f
17764 ;; Misc patterns (?)
17765
17766 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17767 ;; Otherwise there will be nothing to keep
17768 ;;
17769 ;; [(set (reg ebp) (reg esp))]
17770 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17771 ;; (clobber (eflags)]
17772 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17773 ;;
17774 ;; in proper program order.
17775 (define_expand "pro_epilogue_adjust_stack"
17776 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
17777 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17778 (match_operand:SI 2 "immediate_operand" "i,i")))
17779 (clobber (reg:CC 17))
17780 (clobber (mem:BLK (scratch)))])]
17781 ""
17782 {
17783 if (TARGET_64BIT)
17784 {
17785 emit_insn (gen_pro_epilogue_adjust_stack_rex64
17786 (operands[0], operands[1], operands[2]));
17787 DONE;
17788 }
17789 })
17790
17791 (define_insn "*pro_epilogue_adjust_stack_1"
17792 [(set (match_operand:SI 0 "register_operand" "=r,r")
17793 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17794 (match_operand:SI 2 "immediate_operand" "i,i")))
17795 (clobber (reg:CC 17))
17796 (clobber (mem:BLK (scratch)))]
17797 "!TARGET_64BIT"
17798 {
17799 switch (get_attr_type (insn))
17800 {
17801 case TYPE_IMOV:
17802 return "mov{l}\t{%1, %0|%0, %1}";
17803
17804 case TYPE_ALU:
17805 if (GET_CODE (operands[2]) == CONST_INT
17806 && (INTVAL (operands[2]) == 128
17807 || (INTVAL (operands[2]) < 0
17808 && INTVAL (operands[2]) != -128)))
17809 {
17810 operands[2] = GEN_INT (-INTVAL (operands[2]));
17811 return "sub{l}\t{%2, %0|%0, %2}";
17812 }
17813 return "add{l}\t{%2, %0|%0, %2}";
17814
17815 case TYPE_LEA:
17816 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17817 return "lea{l}\t{%a2, %0|%0, %a2}";
17818
17819 default:
17820 abort ();
17821 }
17822 }
17823 [(set (attr "type")
17824 (cond [(eq_attr "alternative" "0")
17825 (const_string "alu")
17826 (match_operand:SI 2 "const0_operand" "")
17827 (const_string "imov")
17828 ]
17829 (const_string "lea")))
17830 (set_attr "mode" "SI")])
17831
17832 (define_insn "pro_epilogue_adjust_stack_rex64"
17833 [(set (match_operand:DI 0 "register_operand" "=r,r")
17834 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17835 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17836 (clobber (reg:CC 17))
17837 (clobber (mem:BLK (scratch)))]
17838 "TARGET_64BIT"
17839 {
17840 switch (get_attr_type (insn))
17841 {
17842 case TYPE_IMOV:
17843 return "mov{q}\t{%1, %0|%0, %1}";
17844
17845 case TYPE_ALU:
17846 if (GET_CODE (operands[2]) == CONST_INT
17847 && (INTVAL (operands[2]) == 128
17848 || (INTVAL (operands[2]) < 0
17849 && INTVAL (operands[2]) != -128)))
17850 {
17851 operands[2] = GEN_INT (-INTVAL (operands[2]));
17852 return "sub{q}\t{%2, %0|%0, %2}";
17853 }
17854 return "add{q}\t{%2, %0|%0, %2}";
17855
17856 case TYPE_LEA:
17857 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17858 return "lea{q}\t{%a2, %0|%0, %a2}";
17859
17860 default:
17861 abort ();
17862 }
17863 }
17864 [(set (attr "type")
17865 (cond [(eq_attr "alternative" "0")
17866 (const_string "alu")
17867 (match_operand:DI 2 "const0_operand" "")
17868 (const_string "imov")
17869 ]
17870 (const_string "lea")))
17871 (set_attr "mode" "DI")])
17872
17873
17874 ;; Placeholder for the conditional moves. This one is split either to SSE
17875 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17876 ;; fact is that compares supported by the cmp??ss instructions are exactly
17877 ;; swapped of those supported by cmove sequence.
17878 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17879 ;; supported by i387 comparisons and we do need to emit two conditional moves
17880 ;; in tandem.
17881
17882 (define_insn "sse_movsfcc"
17883 [(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")
17884 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17885 [(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")
17886 (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")])
17887 (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")
17888 (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")))
17889 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17890 (clobber (reg:CC 17))]
17891 "TARGET_SSE
17892 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17893 /* Avoid combine from being smart and converting min/max
17894 instruction patterns into conditional moves. */
17895 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17896 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17897 || !rtx_equal_p (operands[4], operands[2])
17898 || !rtx_equal_p (operands[5], operands[3]))
17899 && (!TARGET_IEEE_FP
17900 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17901 "#")
17902
17903 (define_insn "sse_movsfcc_eq"
17904 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17905 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17906 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17907 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17908 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17909 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17910 (clobber (reg:CC 17))]
17911 "TARGET_SSE
17912 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17913 "#")
17914
17915 (define_insn "sse_movdfcc"
17916 [(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")
17917 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17918 [(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")
17919 (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")])
17920 (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")
17921 (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")))
17922 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17923 (clobber (reg:CC 17))]
17924 "TARGET_SSE2
17925 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17926 /* Avoid combine from being smart and converting min/max
17927 instruction patterns into conditional moves. */
17928 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17929 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17930 || !rtx_equal_p (operands[4], operands[2])
17931 || !rtx_equal_p (operands[5], operands[3]))
17932 && (!TARGET_IEEE_FP
17933 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17934 "#")
17935
17936 (define_insn "sse_movdfcc_eq"
17937 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17938 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17939 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17940 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17941 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17942 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17943 (clobber (reg:CC 17))]
17944 "TARGET_SSE
17945 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17946 "#")
17947
17948 ;; For non-sse moves just expand the usual cmove sequence.
17949 (define_split
17950 [(set (match_operand 0 "register_operand" "")
17951 (if_then_else (match_operator 1 "comparison_operator"
17952 [(match_operand 4 "nonimmediate_operand" "")
17953 (match_operand 5 "register_operand" "")])
17954 (match_operand 2 "nonimmediate_operand" "")
17955 (match_operand 3 "nonimmediate_operand" "")))
17956 (clobber (match_operand 6 "" ""))
17957 (clobber (reg:CC 17))]
17958 "!SSE_REG_P (operands[0]) && reload_completed
17959 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17960 [(const_int 0)]
17961 {
17962 ix86_compare_op0 = operands[5];
17963 ix86_compare_op1 = operands[4];
17964 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17965 VOIDmode, operands[5], operands[4]);
17966 ix86_expand_fp_movcc (operands);
17967 DONE;
17968 })
17969
17970 ;; Split SSE based conditional move into sequence:
17971 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17972 ;; and op2, op0 - zero op2 if comparison was false
17973 ;; nand op0, op3 - load op3 to op0 if comparison was false
17974 ;; or op2, op0 - get the nonzero one into the result.
17975 (define_split
17976 [(set (match_operand 0 "register_operand" "")
17977 (if_then_else (match_operator 1 "sse_comparison_operator"
17978 [(match_operand 4 "register_operand" "")
17979 (match_operand 5 "nonimmediate_operand" "")])
17980 (match_operand 2 "register_operand" "")
17981 (match_operand 3 "register_operand" "")))
17982 (clobber (match_operand 6 "" ""))
17983 (clobber (reg:CC 17))]
17984 "SSE_REG_P (operands[0]) && reload_completed"
17985 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17986 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17987 (subreg:TI (match_dup 4) 0)))
17988 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17989 (subreg:TI (match_dup 3) 0)))
17990 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17991 (subreg:TI (match_dup 7) 0)))]
17992 {
17993 if (GET_MODE (operands[2]) == DFmode
17994 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17995 {
17996 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17997 emit_insn (gen_sse2_unpcklpd (op, op, op));
17998 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17999 emit_insn (gen_sse2_unpcklpd (op, op, op));
18000 }
18001
18002 /* If op2 == op3, op3 would be clobbered before it is used. */
18003 if (operands_match_p (operands[2], operands[3]))
18004 {
18005 emit_move_insn (operands[0], operands[2]);
18006 DONE;
18007 }
18008
18009 PUT_MODE (operands[1], GET_MODE (operands[0]));
18010 if (operands_match_p (operands[0], operands[4]))
18011 operands[6] = operands[4], operands[7] = operands[2];
18012 else
18013 operands[6] = operands[2], operands[7] = operands[4];
18014 })
18015
18016 ;; Special case of conditional move we can handle effectively.
18017 ;; Do not brother with the integer/floating point case, since these are
18018 ;; bot considerably slower, unlike in the generic case.
18019 (define_insn "*sse_movsfcc_const0_1"
18020 [(set (match_operand:SF 0 "register_operand" "=&x")
18021 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18022 [(match_operand:SF 4 "register_operand" "0")
18023 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18024 (match_operand:SF 2 "register_operand" "x")
18025 (match_operand:SF 3 "const0_operand" "X")))]
18026 "TARGET_SSE"
18027 "#")
18028
18029 (define_insn "*sse_movsfcc_const0_2"
18030 [(set (match_operand:SF 0 "register_operand" "=&x")
18031 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18032 [(match_operand:SF 4 "register_operand" "0")
18033 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18034 (match_operand:SF 2 "const0_operand" "X")
18035 (match_operand:SF 3 "register_operand" "x")))]
18036 "TARGET_SSE"
18037 "#")
18038
18039 (define_insn "*sse_movsfcc_const0_3"
18040 [(set (match_operand:SF 0 "register_operand" "=&x")
18041 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18042 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18043 (match_operand:SF 5 "register_operand" "0")])
18044 (match_operand:SF 2 "register_operand" "x")
18045 (match_operand:SF 3 "const0_operand" "X")))]
18046 "TARGET_SSE"
18047 "#")
18048
18049 (define_insn "*sse_movsfcc_const0_4"
18050 [(set (match_operand:SF 0 "register_operand" "=&x")
18051 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18052 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18053 (match_operand:SF 5 "register_operand" "0")])
18054 (match_operand:SF 2 "const0_operand" "X")
18055 (match_operand:SF 3 "register_operand" "x")))]
18056 "TARGET_SSE"
18057 "#")
18058
18059 (define_insn "*sse_movdfcc_const0_1"
18060 [(set (match_operand:DF 0 "register_operand" "=&Y")
18061 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18062 [(match_operand:DF 4 "register_operand" "0")
18063 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18064 (match_operand:DF 2 "register_operand" "Y")
18065 (match_operand:DF 3 "const0_operand" "X")))]
18066 "TARGET_SSE2"
18067 "#")
18068
18069 (define_insn "*sse_movdfcc_const0_2"
18070 [(set (match_operand:DF 0 "register_operand" "=&Y")
18071 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18072 [(match_operand:DF 4 "register_operand" "0")
18073 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18074 (match_operand:DF 2 "const0_operand" "X")
18075 (match_operand:DF 3 "register_operand" "Y")))]
18076 "TARGET_SSE2"
18077 "#")
18078
18079 (define_insn "*sse_movdfcc_const0_3"
18080 [(set (match_operand:DF 0 "register_operand" "=&Y")
18081 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18082 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18083 (match_operand:DF 5 "register_operand" "0")])
18084 (match_operand:DF 2 "register_operand" "Y")
18085 (match_operand:DF 3 "const0_operand" "X")))]
18086 "TARGET_SSE2"
18087 "#")
18088
18089 (define_insn "*sse_movdfcc_const0_4"
18090 [(set (match_operand:DF 0 "register_operand" "=&Y")
18091 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18092 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18093 (match_operand:DF 5 "register_operand" "0")])
18094 (match_operand:DF 2 "const0_operand" "X")
18095 (match_operand:DF 3 "register_operand" "Y")))]
18096 "TARGET_SSE2"
18097 "#")
18098
18099 (define_split
18100 [(set (match_operand 0 "register_operand" "")
18101 (if_then_else (match_operator 1 "comparison_operator"
18102 [(match_operand 4 "nonimmediate_operand" "")
18103 (match_operand 5 "nonimmediate_operand" "")])
18104 (match_operand 2 "nonmemory_operand" "")
18105 (match_operand 3 "nonmemory_operand" "")))]
18106 "SSE_REG_P (operands[0]) && reload_completed
18107 && (const0_operand (operands[2], GET_MODE (operands[0]))
18108 || const0_operand (operands[3], GET_MODE (operands[0])))"
18109 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18110 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
18111 (match_dup 7)))]
18112 {
18113 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18114 && GET_MODE (operands[2]) == DFmode)
18115 {
18116 if (REG_P (operands[2]))
18117 {
18118 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18119 emit_insn (gen_sse2_unpcklpd (op, op, op));
18120 }
18121 if (REG_P (operands[3]))
18122 {
18123 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18124 emit_insn (gen_sse2_unpcklpd (op, op, op));
18125 }
18126 }
18127 PUT_MODE (operands[1], GET_MODE (operands[0]));
18128 if (!sse_comparison_operator (operands[1], VOIDmode)
18129 || !rtx_equal_p (operands[0], operands[4]))
18130 {
18131 rtx tmp = operands[5];
18132 operands[5] = operands[4];
18133 operands[4] = tmp;
18134 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18135 }
18136 if (!rtx_equal_p (operands[0], operands[4]))
18137 abort ();
18138 if (const0_operand (operands[2], GET_MODE (operands[0])))
18139 {
18140 operands[7] = operands[3];
18141 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
18142 0));
18143 }
18144 else
18145 {
18146 operands[7] = operands[2];
18147 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
18148 }
18149 operands[7] = simplify_gen_subreg (TImode, operands[7],
18150 GET_MODE (operands[7]), 0);
18151 })
18152
18153 (define_expand "allocate_stack_worker"
18154 [(match_operand:SI 0 "register_operand" "")]
18155 "TARGET_STACK_PROBE"
18156 {
18157 if (TARGET_64BIT)
18158 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18159 else
18160 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18161 DONE;
18162 })
18163
18164 (define_insn "allocate_stack_worker_1"
18165 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18166 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
18167 (clobber (match_dup 0))
18168 (clobber (reg:CC 17))]
18169 "!TARGET_64BIT && TARGET_STACK_PROBE"
18170 "call\t__alloca"
18171 [(set_attr "type" "multi")
18172 (set_attr "length" "5")])
18173
18174 (define_insn "allocate_stack_worker_rex64"
18175 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18176 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
18177 (clobber (match_dup 0))
18178 (clobber (reg:CC 17))]
18179 "TARGET_64BIT && TARGET_STACK_PROBE"
18180 "call\t__alloca"
18181 [(set_attr "type" "multi")
18182 (set_attr "length" "5")])
18183
18184 (define_expand "allocate_stack"
18185 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18186 (minus:SI (reg:SI 7)
18187 (match_operand:SI 1 "general_operand" "")))
18188 (clobber (reg:CC 17))])
18189 (parallel [(set (reg:SI 7)
18190 (minus:SI (reg:SI 7) (match_dup 1)))
18191 (clobber (reg:CC 17))])]
18192 "TARGET_STACK_PROBE"
18193 {
18194 #ifdef CHECK_STACK_LIMIT
18195 if (GET_CODE (operands[1]) == CONST_INT
18196 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18197 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18198 operands[1]));
18199 else
18200 #endif
18201 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18202 operands[1])));
18203
18204 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18205 DONE;
18206 })
18207
18208 (define_expand "builtin_setjmp_receiver"
18209 [(label_ref (match_operand 0 "" ""))]
18210 "!TARGET_64BIT && flag_pic"
18211 {
18212 emit_insn (gen_set_got (pic_offset_table_rtx));
18213 DONE;
18214 })
18215 \f
18216 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18217
18218 (define_split
18219 [(set (match_operand 0 "register_operand" "")
18220 (match_operator 3 "promotable_binary_operator"
18221 [(match_operand 1 "register_operand" "")
18222 (match_operand 2 "aligned_operand" "")]))
18223 (clobber (reg:CC 17))]
18224 "! TARGET_PARTIAL_REG_STALL && reload_completed
18225 && ((GET_MODE (operands[0]) == HImode
18226 && ((!optimize_size && !TARGET_FAST_PREFIX)
18227 || GET_CODE (operands[2]) != CONST_INT
18228 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18229 || (GET_MODE (operands[0]) == QImode
18230 && (TARGET_PROMOTE_QImode || optimize_size)))"
18231 [(parallel [(set (match_dup 0)
18232 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18233 (clobber (reg:CC 17))])]
18234 "operands[0] = gen_lowpart (SImode, operands[0]);
18235 operands[1] = gen_lowpart (SImode, operands[1]);
18236 if (GET_CODE (operands[3]) != ASHIFT)
18237 operands[2] = gen_lowpart (SImode, operands[2]);
18238 PUT_MODE (operands[3], SImode);")
18239
18240 ; Promote the QImode tests, as i386 has encoding of the AND
18241 ; instruction with 32-bit sign-extended immediate and thus the
18242 ; instruction size is unchanged, except in the %eax case for
18243 ; which it is increased by one byte, hence the ! optimize_size.
18244 (define_split
18245 [(set (reg 17)
18246 (compare (and (match_operand 1 "aligned_operand" "")
18247 (match_operand 2 "const_int_operand" ""))
18248 (const_int 0)))
18249 (set (match_operand 0 "register_operand" "")
18250 (and (match_dup 1) (match_dup 2)))]
18251 "! TARGET_PARTIAL_REG_STALL && reload_completed
18252 /* Ensure that the operand will remain sign-extended immediate. */
18253 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18254 && ! optimize_size
18255 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18256 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18257 [(parallel [(set (reg:CCNO 17)
18258 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18259 (const_int 0)))
18260 (set (match_dup 0)
18261 (and:SI (match_dup 1) (match_dup 2)))])]
18262 "operands[2]
18263 = gen_int_mode (INTVAL (operands[2])
18264 & GET_MODE_MASK (GET_MODE (operands[0])),
18265 SImode);
18266 operands[0] = gen_lowpart (SImode, operands[0]);
18267 operands[1] = gen_lowpart (SImode, operands[1]);")
18268
18269 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18270 ; the TEST instruction with 32-bit sign-extended immediate and thus
18271 ; the instruction size would at least double, which is not what we
18272 ; want even with ! optimize_size.
18273 (define_split
18274 [(set (reg 17)
18275 (compare (and (match_operand:HI 0 "aligned_operand" "")
18276 (match_operand:HI 1 "const_int_operand" ""))
18277 (const_int 0)))]
18278 "! TARGET_PARTIAL_REG_STALL && reload_completed
18279 /* Ensure that the operand will remain sign-extended immediate. */
18280 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18281 && ! TARGET_FAST_PREFIX
18282 && ! optimize_size"
18283 [(set (reg:CCNO 17)
18284 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18285 (const_int 0)))]
18286 "operands[1]
18287 = gen_int_mode (INTVAL (operands[1])
18288 & GET_MODE_MASK (GET_MODE (operands[0])),
18289 SImode);
18290 operands[0] = gen_lowpart (SImode, operands[0]);")
18291
18292 (define_split
18293 [(set (match_operand 0 "register_operand" "")
18294 (neg (match_operand 1 "register_operand" "")))
18295 (clobber (reg:CC 17))]
18296 "! TARGET_PARTIAL_REG_STALL && reload_completed
18297 && (GET_MODE (operands[0]) == HImode
18298 || (GET_MODE (operands[0]) == QImode
18299 && (TARGET_PROMOTE_QImode || optimize_size)))"
18300 [(parallel [(set (match_dup 0)
18301 (neg:SI (match_dup 1)))
18302 (clobber (reg:CC 17))])]
18303 "operands[0] = gen_lowpart (SImode, operands[0]);
18304 operands[1] = gen_lowpart (SImode, operands[1]);")
18305
18306 (define_split
18307 [(set (match_operand 0 "register_operand" "")
18308 (not (match_operand 1 "register_operand" "")))]
18309 "! TARGET_PARTIAL_REG_STALL && reload_completed
18310 && (GET_MODE (operands[0]) == HImode
18311 || (GET_MODE (operands[0]) == QImode
18312 && (TARGET_PROMOTE_QImode || optimize_size)))"
18313 [(set (match_dup 0)
18314 (not:SI (match_dup 1)))]
18315 "operands[0] = gen_lowpart (SImode, operands[0]);
18316 operands[1] = gen_lowpart (SImode, operands[1]);")
18317
18318 (define_split
18319 [(set (match_operand 0 "register_operand" "")
18320 (if_then_else (match_operator 1 "comparison_operator"
18321 [(reg 17) (const_int 0)])
18322 (match_operand 2 "register_operand" "")
18323 (match_operand 3 "register_operand" "")))]
18324 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18325 && (GET_MODE (operands[0]) == HImode
18326 || (GET_MODE (operands[0]) == QImode
18327 && (TARGET_PROMOTE_QImode || optimize_size)))"
18328 [(set (match_dup 0)
18329 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18330 "operands[0] = gen_lowpart (SImode, operands[0]);
18331 operands[2] = gen_lowpart (SImode, operands[2]);
18332 operands[3] = gen_lowpart (SImode, operands[3]);")
18333
18334 \f
18335 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18336 ;; transform a complex memory operation into two memory to register operations.
18337
18338 ;; Don't push memory operands
18339 (define_peephole2
18340 [(set (match_operand:SI 0 "push_operand" "")
18341 (match_operand:SI 1 "memory_operand" ""))
18342 (match_scratch:SI 2 "r")]
18343 "! optimize_size && ! TARGET_PUSH_MEMORY"
18344 [(set (match_dup 2) (match_dup 1))
18345 (set (match_dup 0) (match_dup 2))]
18346 "")
18347
18348 (define_peephole2
18349 [(set (match_operand:DI 0 "push_operand" "")
18350 (match_operand:DI 1 "memory_operand" ""))
18351 (match_scratch:DI 2 "r")]
18352 "! optimize_size && ! TARGET_PUSH_MEMORY"
18353 [(set (match_dup 2) (match_dup 1))
18354 (set (match_dup 0) (match_dup 2))]
18355 "")
18356
18357 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18358 ;; SImode pushes.
18359 (define_peephole2
18360 [(set (match_operand:SF 0 "push_operand" "")
18361 (match_operand:SF 1 "memory_operand" ""))
18362 (match_scratch:SF 2 "r")]
18363 "! optimize_size && ! TARGET_PUSH_MEMORY"
18364 [(set (match_dup 2) (match_dup 1))
18365 (set (match_dup 0) (match_dup 2))]
18366 "")
18367
18368 (define_peephole2
18369 [(set (match_operand:HI 0 "push_operand" "")
18370 (match_operand:HI 1 "memory_operand" ""))
18371 (match_scratch:HI 2 "r")]
18372 "! optimize_size && ! TARGET_PUSH_MEMORY"
18373 [(set (match_dup 2) (match_dup 1))
18374 (set (match_dup 0) (match_dup 2))]
18375 "")
18376
18377 (define_peephole2
18378 [(set (match_operand:QI 0 "push_operand" "")
18379 (match_operand:QI 1 "memory_operand" ""))
18380 (match_scratch:QI 2 "q")]
18381 "! optimize_size && ! TARGET_PUSH_MEMORY"
18382 [(set (match_dup 2) (match_dup 1))
18383 (set (match_dup 0) (match_dup 2))]
18384 "")
18385
18386 ;; Don't move an immediate directly to memory when the instruction
18387 ;; gets too big.
18388 (define_peephole2
18389 [(match_scratch:SI 1 "r")
18390 (set (match_operand:SI 0 "memory_operand" "")
18391 (const_int 0))]
18392 "! optimize_size
18393 && ! TARGET_USE_MOV0
18394 && TARGET_SPLIT_LONG_MOVES
18395 && get_attr_length (insn) >= ix86_cost->large_insn
18396 && peep2_regno_dead_p (0, FLAGS_REG)"
18397 [(parallel [(set (match_dup 1) (const_int 0))
18398 (clobber (reg:CC 17))])
18399 (set (match_dup 0) (match_dup 1))]
18400 "")
18401
18402 (define_peephole2
18403 [(match_scratch:HI 1 "r")
18404 (set (match_operand:HI 0 "memory_operand" "")
18405 (const_int 0))]
18406 "! optimize_size
18407 && ! TARGET_USE_MOV0
18408 && TARGET_SPLIT_LONG_MOVES
18409 && get_attr_length (insn) >= ix86_cost->large_insn
18410 && peep2_regno_dead_p (0, FLAGS_REG)"
18411 [(parallel [(set (match_dup 2) (const_int 0))
18412 (clobber (reg:CC 17))])
18413 (set (match_dup 0) (match_dup 1))]
18414 "operands[2] = gen_lowpart (SImode, operands[1]);")
18415
18416 (define_peephole2
18417 [(match_scratch:QI 1 "q")
18418 (set (match_operand:QI 0 "memory_operand" "")
18419 (const_int 0))]
18420 "! optimize_size
18421 && ! TARGET_USE_MOV0
18422 && TARGET_SPLIT_LONG_MOVES
18423 && get_attr_length (insn) >= ix86_cost->large_insn
18424 && peep2_regno_dead_p (0, FLAGS_REG)"
18425 [(parallel [(set (match_dup 2) (const_int 0))
18426 (clobber (reg:CC 17))])
18427 (set (match_dup 0) (match_dup 1))]
18428 "operands[2] = gen_lowpart (SImode, operands[1]);")
18429
18430 (define_peephole2
18431 [(match_scratch:SI 2 "r")
18432 (set (match_operand:SI 0 "memory_operand" "")
18433 (match_operand:SI 1 "immediate_operand" ""))]
18434 "! optimize_size
18435 && get_attr_length (insn) >= ix86_cost->large_insn
18436 && TARGET_SPLIT_LONG_MOVES"
18437 [(set (match_dup 2) (match_dup 1))
18438 (set (match_dup 0) (match_dup 2))]
18439 "")
18440
18441 (define_peephole2
18442 [(match_scratch:HI 2 "r")
18443 (set (match_operand:HI 0 "memory_operand" "")
18444 (match_operand:HI 1 "immediate_operand" ""))]
18445 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18446 && TARGET_SPLIT_LONG_MOVES"
18447 [(set (match_dup 2) (match_dup 1))
18448 (set (match_dup 0) (match_dup 2))]
18449 "")
18450
18451 (define_peephole2
18452 [(match_scratch:QI 2 "q")
18453 (set (match_operand:QI 0 "memory_operand" "")
18454 (match_operand:QI 1 "immediate_operand" ""))]
18455 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18456 && TARGET_SPLIT_LONG_MOVES"
18457 [(set (match_dup 2) (match_dup 1))
18458 (set (match_dup 0) (match_dup 2))]
18459 "")
18460
18461 ;; Don't compare memory with zero, load and use a test instead.
18462 (define_peephole2
18463 [(set (reg 17)
18464 (compare (match_operand:SI 0 "memory_operand" "")
18465 (const_int 0)))
18466 (match_scratch:SI 3 "r")]
18467 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18468 [(set (match_dup 3) (match_dup 0))
18469 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18470 "")
18471
18472 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18473 ;; Don't split NOTs with a displacement operand, because resulting XOR
18474 ;; will not be pairable anyway.
18475 ;;
18476 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18477 ;; represented using a modRM byte. The XOR replacement is long decoded,
18478 ;; so this split helps here as well.
18479 ;;
18480 ;; Note: Can't do this as a regular split because we can't get proper
18481 ;; lifetime information then.
18482
18483 (define_peephole2
18484 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18485 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18486 "!optimize_size
18487 && peep2_regno_dead_p (0, FLAGS_REG)
18488 && ((TARGET_PENTIUM
18489 && (GET_CODE (operands[0]) != MEM
18490 || !memory_displacement_operand (operands[0], SImode)))
18491 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18492 [(parallel [(set (match_dup 0)
18493 (xor:SI (match_dup 1) (const_int -1)))
18494 (clobber (reg:CC 17))])]
18495 "")
18496
18497 (define_peephole2
18498 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18499 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18500 "!optimize_size
18501 && peep2_regno_dead_p (0, FLAGS_REG)
18502 && ((TARGET_PENTIUM
18503 && (GET_CODE (operands[0]) != MEM
18504 || !memory_displacement_operand (operands[0], HImode)))
18505 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18506 [(parallel [(set (match_dup 0)
18507 (xor:HI (match_dup 1) (const_int -1)))
18508 (clobber (reg:CC 17))])]
18509 "")
18510
18511 (define_peephole2
18512 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18513 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18514 "!optimize_size
18515 && peep2_regno_dead_p (0, FLAGS_REG)
18516 && ((TARGET_PENTIUM
18517 && (GET_CODE (operands[0]) != MEM
18518 || !memory_displacement_operand (operands[0], QImode)))
18519 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18520 [(parallel [(set (match_dup 0)
18521 (xor:QI (match_dup 1) (const_int -1)))
18522 (clobber (reg:CC 17))])]
18523 "")
18524
18525 ;; Non pairable "test imm, reg" instructions can be translated to
18526 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18527 ;; byte opcode instead of two, have a short form for byte operands),
18528 ;; so do it for other CPUs as well. Given that the value was dead,
18529 ;; this should not create any new dependencies. Pass on the sub-word
18530 ;; versions if we're concerned about partial register stalls.
18531
18532 (define_peephole2
18533 [(set (reg 17)
18534 (compare (and:SI (match_operand:SI 0 "register_operand" "")
18535 (match_operand:SI 1 "immediate_operand" ""))
18536 (const_int 0)))]
18537 "ix86_match_ccmode (insn, CCNOmode)
18538 && (true_regnum (operands[0]) != 0
18539 || (GET_CODE (operands[1]) == CONST_INT
18540 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18541 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18542 [(parallel
18543 [(set (reg:CCNO 17)
18544 (compare:CCNO (and:SI (match_dup 0)
18545 (match_dup 1))
18546 (const_int 0)))
18547 (set (match_dup 0)
18548 (and:SI (match_dup 0) (match_dup 1)))])]
18549 "")
18550
18551 ;; We don't need to handle HImode case, because it will be promoted to SImode
18552 ;; on ! TARGET_PARTIAL_REG_STALL
18553
18554 (define_peephole2
18555 [(set (reg 17)
18556 (compare (and:QI (match_operand:QI 0 "register_operand" "")
18557 (match_operand:QI 1 "immediate_operand" ""))
18558 (const_int 0)))]
18559 "! TARGET_PARTIAL_REG_STALL
18560 && ix86_match_ccmode (insn, CCNOmode)
18561 && true_regnum (operands[0]) != 0
18562 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18563 [(parallel
18564 [(set (reg:CCNO 17)
18565 (compare:CCNO (and:QI (match_dup 0)
18566 (match_dup 1))
18567 (const_int 0)))
18568 (set (match_dup 0)
18569 (and:QI (match_dup 0) (match_dup 1)))])]
18570 "")
18571
18572 (define_peephole2
18573 [(set (reg 17)
18574 (compare
18575 (and:SI
18576 (zero_extract:SI
18577 (match_operand 0 "ext_register_operand" "")
18578 (const_int 8)
18579 (const_int 8))
18580 (match_operand 1 "const_int_operand" ""))
18581 (const_int 0)))]
18582 "! TARGET_PARTIAL_REG_STALL
18583 && ix86_match_ccmode (insn, CCNOmode)
18584 && true_regnum (operands[0]) != 0
18585 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18586 [(parallel [(set (reg:CCNO 17)
18587 (compare:CCNO
18588 (and:SI
18589 (zero_extract:SI
18590 (match_dup 0)
18591 (const_int 8)
18592 (const_int 8))
18593 (match_dup 1))
18594 (const_int 0)))
18595 (set (zero_extract:SI (match_dup 0)
18596 (const_int 8)
18597 (const_int 8))
18598 (and:SI
18599 (zero_extract:SI
18600 (match_dup 0)
18601 (const_int 8)
18602 (const_int 8))
18603 (match_dup 1)))])]
18604 "")
18605
18606 ;; Don't do logical operations with memory inputs.
18607 (define_peephole2
18608 [(match_scratch:SI 2 "r")
18609 (parallel [(set (match_operand:SI 0 "register_operand" "")
18610 (match_operator:SI 3 "arith_or_logical_operator"
18611 [(match_dup 0)
18612 (match_operand:SI 1 "memory_operand" "")]))
18613 (clobber (reg:CC 17))])]
18614 "! optimize_size && ! TARGET_READ_MODIFY"
18615 [(set (match_dup 2) (match_dup 1))
18616 (parallel [(set (match_dup 0)
18617 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18618 (clobber (reg:CC 17))])]
18619 "")
18620
18621 (define_peephole2
18622 [(match_scratch:SI 2 "r")
18623 (parallel [(set (match_operand:SI 0 "register_operand" "")
18624 (match_operator:SI 3 "arith_or_logical_operator"
18625 [(match_operand:SI 1 "memory_operand" "")
18626 (match_dup 0)]))
18627 (clobber (reg:CC 17))])]
18628 "! optimize_size && ! TARGET_READ_MODIFY"
18629 [(set (match_dup 2) (match_dup 1))
18630 (parallel [(set (match_dup 0)
18631 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18632 (clobber (reg:CC 17))])]
18633 "")
18634
18635 ; Don't do logical operations with memory outputs
18636 ;
18637 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18638 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18639 ; the same decoder scheduling characteristics as the original.
18640
18641 (define_peephole2
18642 [(match_scratch:SI 2 "r")
18643 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18644 (match_operator:SI 3 "arith_or_logical_operator"
18645 [(match_dup 0)
18646 (match_operand:SI 1 "nonmemory_operand" "")]))
18647 (clobber (reg:CC 17))])]
18648 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18649 [(set (match_dup 2) (match_dup 0))
18650 (parallel [(set (match_dup 2)
18651 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18652 (clobber (reg:CC 17))])
18653 (set (match_dup 0) (match_dup 2))]
18654 "")
18655
18656 (define_peephole2
18657 [(match_scratch:SI 2 "r")
18658 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18659 (match_operator:SI 3 "arith_or_logical_operator"
18660 [(match_operand:SI 1 "nonmemory_operand" "")
18661 (match_dup 0)]))
18662 (clobber (reg:CC 17))])]
18663 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18664 [(set (match_dup 2) (match_dup 0))
18665 (parallel [(set (match_dup 2)
18666 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18667 (clobber (reg:CC 17))])
18668 (set (match_dup 0) (match_dup 2))]
18669 "")
18670
18671 ;; Attempt to always use XOR for zeroing registers.
18672 (define_peephole2
18673 [(set (match_operand 0 "register_operand" "")
18674 (const_int 0))]
18675 "(GET_MODE (operands[0]) == QImode
18676 || GET_MODE (operands[0]) == HImode
18677 || GET_MODE (operands[0]) == SImode
18678 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18679 && (! TARGET_USE_MOV0 || optimize_size)
18680 && peep2_regno_dead_p (0, FLAGS_REG)"
18681 [(parallel [(set (match_dup 0) (const_int 0))
18682 (clobber (reg:CC 17))])]
18683 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18684 operands[0]);")
18685
18686 (define_peephole2
18687 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18688 (const_int 0))]
18689 "(GET_MODE (operands[0]) == QImode
18690 || GET_MODE (operands[0]) == HImode)
18691 && (! TARGET_USE_MOV0 || optimize_size)
18692 && peep2_regno_dead_p (0, FLAGS_REG)"
18693 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18694 (clobber (reg:CC 17))])])
18695
18696 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18697 (define_peephole2
18698 [(set (match_operand 0 "register_operand" "")
18699 (const_int -1))]
18700 "(GET_MODE (operands[0]) == HImode
18701 || GET_MODE (operands[0]) == SImode
18702 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18703 && (optimize_size || TARGET_PENTIUM)
18704 && peep2_regno_dead_p (0, FLAGS_REG)"
18705 [(parallel [(set (match_dup 0) (const_int -1))
18706 (clobber (reg:CC 17))])]
18707 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18708 operands[0]);")
18709
18710 ;; Attempt to convert simple leas to adds. These can be created by
18711 ;; move expanders.
18712 (define_peephole2
18713 [(set (match_operand:SI 0 "register_operand" "")
18714 (plus:SI (match_dup 0)
18715 (match_operand:SI 1 "nonmemory_operand" "")))]
18716 "peep2_regno_dead_p (0, FLAGS_REG)"
18717 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18718 (clobber (reg:CC 17))])]
18719 "")
18720
18721 (define_peephole2
18722 [(set (match_operand:SI 0 "register_operand" "")
18723 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18724 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18725 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18726 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18727 (clobber (reg:CC 17))])]
18728 "operands[2] = gen_lowpart (SImode, operands[2]);")
18729
18730 (define_peephole2
18731 [(set (match_operand:DI 0 "register_operand" "")
18732 (plus:DI (match_dup 0)
18733 (match_operand:DI 1 "x86_64_general_operand" "")))]
18734 "peep2_regno_dead_p (0, FLAGS_REG)"
18735 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18736 (clobber (reg:CC 17))])]
18737 "")
18738
18739 (define_peephole2
18740 [(set (match_operand:SI 0 "register_operand" "")
18741 (mult:SI (match_dup 0)
18742 (match_operand:SI 1 "const_int_operand" "")))]
18743 "exact_log2 (INTVAL (operands[1])) >= 0
18744 && peep2_regno_dead_p (0, FLAGS_REG)"
18745 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18746 (clobber (reg:CC 17))])]
18747 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18748
18749 (define_peephole2
18750 [(set (match_operand:DI 0 "register_operand" "")
18751 (mult:DI (match_dup 0)
18752 (match_operand:DI 1 "const_int_operand" "")))]
18753 "exact_log2 (INTVAL (operands[1])) >= 0
18754 && peep2_regno_dead_p (0, FLAGS_REG)"
18755 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18756 (clobber (reg:CC 17))])]
18757 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18758
18759 (define_peephole2
18760 [(set (match_operand:SI 0 "register_operand" "")
18761 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18762 (match_operand:DI 2 "const_int_operand" "")) 0))]
18763 "exact_log2 (INTVAL (operands[2])) >= 0
18764 && REGNO (operands[0]) == REGNO (operands[1])
18765 && peep2_regno_dead_p (0, FLAGS_REG)"
18766 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18767 (clobber (reg:CC 17))])]
18768 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18769
18770 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18771 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18772 ;; many CPUs it is also faster, since special hardware to avoid esp
18773 ;; dependencies is present.
18774
18775 ;; While some of these conversions may be done using splitters, we use peepholes
18776 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18777
18778 ;; Convert prologue esp subtractions to push.
18779 ;; We need register to push. In order to keep verify_flow_info happy we have
18780 ;; two choices
18781 ;; - use scratch and clobber it in order to avoid dependencies
18782 ;; - use already live register
18783 ;; We can't use the second way right now, since there is no reliable way how to
18784 ;; verify that given register is live. First choice will also most likely in
18785 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18786 ;; call clobbered registers are dead. We may want to use base pointer as an
18787 ;; alternative when no register is available later.
18788
18789 (define_peephole2
18790 [(match_scratch:SI 0 "r")
18791 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18792 (clobber (reg:CC 17))
18793 (clobber (mem:BLK (scratch)))])]
18794 "optimize_size || !TARGET_SUB_ESP_4"
18795 [(clobber (match_dup 0))
18796 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18797 (clobber (mem:BLK (scratch)))])])
18798
18799 (define_peephole2
18800 [(match_scratch:SI 0 "r")
18801 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18802 (clobber (reg:CC 17))
18803 (clobber (mem:BLK (scratch)))])]
18804 "optimize_size || !TARGET_SUB_ESP_8"
18805 [(clobber (match_dup 0))
18806 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18807 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18808 (clobber (mem:BLK (scratch)))])])
18809
18810 ;; Convert esp subtractions to push.
18811 (define_peephole2
18812 [(match_scratch:SI 0 "r")
18813 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18814 (clobber (reg:CC 17))])]
18815 "optimize_size || !TARGET_SUB_ESP_4"
18816 [(clobber (match_dup 0))
18817 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18818
18819 (define_peephole2
18820 [(match_scratch:SI 0 "r")
18821 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18822 (clobber (reg:CC 17))])]
18823 "optimize_size || !TARGET_SUB_ESP_8"
18824 [(clobber (match_dup 0))
18825 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18826 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18827
18828 ;; Convert epilogue deallocator to pop.
18829 (define_peephole2
18830 [(match_scratch:SI 0 "r")
18831 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18832 (clobber (reg:CC 17))
18833 (clobber (mem:BLK (scratch)))])]
18834 "optimize_size || !TARGET_ADD_ESP_4"
18835 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18836 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18837 (clobber (mem:BLK (scratch)))])]
18838 "")
18839
18840 ;; Two pops case is tricky, since pop causes dependency on destination register.
18841 ;; We use two registers if available.
18842 (define_peephole2
18843 [(match_scratch:SI 0 "r")
18844 (match_scratch:SI 1 "r")
18845 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18846 (clobber (reg:CC 17))
18847 (clobber (mem:BLK (scratch)))])]
18848 "optimize_size || !TARGET_ADD_ESP_8"
18849 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18850 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18851 (clobber (mem:BLK (scratch)))])
18852 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18853 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18854 "")
18855
18856 (define_peephole2
18857 [(match_scratch:SI 0 "r")
18858 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18859 (clobber (reg:CC 17))
18860 (clobber (mem:BLK (scratch)))])]
18861 "optimize_size"
18862 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18863 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18864 (clobber (mem:BLK (scratch)))])
18865 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18866 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18867 "")
18868
18869 ;; Convert esp additions to pop.
18870 (define_peephole2
18871 [(match_scratch:SI 0 "r")
18872 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18873 (clobber (reg:CC 17))])]
18874 ""
18875 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18876 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18877 "")
18878
18879 ;; Two pops case is tricky, since pop causes dependency on destination register.
18880 ;; We use two registers if available.
18881 (define_peephole2
18882 [(match_scratch:SI 0 "r")
18883 (match_scratch:SI 1 "r")
18884 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18885 (clobber (reg:CC 17))])]
18886 ""
18887 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18888 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18889 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18890 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18891 "")
18892
18893 (define_peephole2
18894 [(match_scratch:SI 0 "r")
18895 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18896 (clobber (reg:CC 17))])]
18897 "optimize_size"
18898 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18899 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18900 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18901 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18902 "")
18903 \f
18904 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18905 ;; required and register dies.
18906 (define_peephole2
18907 [(set (reg 17)
18908 (compare (match_operand:SI 0 "register_operand" "")
18909 (match_operand:SI 1 "incdec_operand" "")))]
18910 "ix86_match_ccmode (insn, CCGCmode)
18911 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18912 [(parallel [(set (reg:CCGC 17)
18913 (compare:CCGC (match_dup 0)
18914 (match_dup 1)))
18915 (clobber (match_dup 0))])]
18916 "")
18917
18918 (define_peephole2
18919 [(set (reg 17)
18920 (compare (match_operand:HI 0 "register_operand" "")
18921 (match_operand:HI 1 "incdec_operand" "")))]
18922 "ix86_match_ccmode (insn, CCGCmode)
18923 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18924 [(parallel [(set (reg:CCGC 17)
18925 (compare:CCGC (match_dup 0)
18926 (match_dup 1)))
18927 (clobber (match_dup 0))])]
18928 "")
18929
18930 (define_peephole2
18931 [(set (reg 17)
18932 (compare (match_operand:QI 0 "register_operand" "")
18933 (match_operand:QI 1 "incdec_operand" "")))]
18934 "ix86_match_ccmode (insn, CCGCmode)
18935 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18936 [(parallel [(set (reg:CCGC 17)
18937 (compare:CCGC (match_dup 0)
18938 (match_dup 1)))
18939 (clobber (match_dup 0))])]
18940 "")
18941
18942 ;; Convert compares with 128 to shorter add -128
18943 (define_peephole2
18944 [(set (reg 17)
18945 (compare (match_operand:SI 0 "register_operand" "")
18946 (const_int 128)))]
18947 "ix86_match_ccmode (insn, CCGCmode)
18948 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18949 [(parallel [(set (reg:CCGC 17)
18950 (compare:CCGC (match_dup 0)
18951 (const_int 128)))
18952 (clobber (match_dup 0))])]
18953 "")
18954
18955 (define_peephole2
18956 [(set (reg 17)
18957 (compare (match_operand:HI 0 "register_operand" "")
18958 (const_int 128)))]
18959 "ix86_match_ccmode (insn, CCGCmode)
18960 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18961 [(parallel [(set (reg:CCGC 17)
18962 (compare:CCGC (match_dup 0)
18963 (const_int 128)))
18964 (clobber (match_dup 0))])]
18965 "")
18966 \f
18967 (define_peephole2
18968 [(match_scratch:DI 0 "r")
18969 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18970 (clobber (reg:CC 17))
18971 (clobber (mem:BLK (scratch)))])]
18972 "optimize_size || !TARGET_SUB_ESP_4"
18973 [(clobber (match_dup 0))
18974 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18975 (clobber (mem:BLK (scratch)))])])
18976
18977 (define_peephole2
18978 [(match_scratch:DI 0 "r")
18979 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18980 (clobber (reg:CC 17))
18981 (clobber (mem:BLK (scratch)))])]
18982 "optimize_size || !TARGET_SUB_ESP_8"
18983 [(clobber (match_dup 0))
18984 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18985 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18986 (clobber (mem:BLK (scratch)))])])
18987
18988 ;; Convert esp subtractions to push.
18989 (define_peephole2
18990 [(match_scratch:DI 0 "r")
18991 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18992 (clobber (reg:CC 17))])]
18993 "optimize_size || !TARGET_SUB_ESP_4"
18994 [(clobber (match_dup 0))
18995 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18996
18997 (define_peephole2
18998 [(match_scratch:DI 0 "r")
18999 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
19000 (clobber (reg:CC 17))])]
19001 "optimize_size || !TARGET_SUB_ESP_8"
19002 [(clobber (match_dup 0))
19003 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
19004 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
19005
19006 ;; Convert epilogue deallocator to pop.
19007 (define_peephole2
19008 [(match_scratch:DI 0 "r")
19009 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19010 (clobber (reg:CC 17))
19011 (clobber (mem:BLK (scratch)))])]
19012 "optimize_size || !TARGET_ADD_ESP_4"
19013 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19014 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19015 (clobber (mem:BLK (scratch)))])]
19016 "")
19017
19018 ;; Two pops case is tricky, since pop causes dependency on destination register.
19019 ;; We use two registers if available.
19020 (define_peephole2
19021 [(match_scratch:DI 0 "r")
19022 (match_scratch:DI 1 "r")
19023 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19024 (clobber (reg:CC 17))
19025 (clobber (mem:BLK (scratch)))])]
19026 "optimize_size || !TARGET_ADD_ESP_8"
19027 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19028 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19029 (clobber (mem:BLK (scratch)))])
19030 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
19031 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19032 "")
19033
19034 (define_peephole2
19035 [(match_scratch:DI 0 "r")
19036 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19037 (clobber (reg:CC 17))
19038 (clobber (mem:BLK (scratch)))])]
19039 "optimize_size"
19040 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19041 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19042 (clobber (mem:BLK (scratch)))])
19043 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19044 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19045 "")
19046
19047 ;; Convert esp additions to pop.
19048 (define_peephole2
19049 [(match_scratch:DI 0 "r")
19050 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
19051 (clobber (reg:CC 17))])]
19052 ""
19053 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19054 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19055 "")
19056
19057 ;; Two pops case is tricky, since pop causes dependency on destination register.
19058 ;; We use two registers if available.
19059 (define_peephole2
19060 [(match_scratch:DI 0 "r")
19061 (match_scratch:DI 1 "r")
19062 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19063 (clobber (reg:CC 17))])]
19064 ""
19065 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19066 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
19067 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
19068 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19069 "")
19070
19071 (define_peephole2
19072 [(match_scratch:DI 0 "r")
19073 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
19074 (clobber (reg:CC 17))])]
19075 "optimize_size"
19076 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19077 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
19078 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19079 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19080 "")
19081 \f
19082 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19083 ;; imul $32bit_imm, reg, reg is direct decoded.
19084 (define_peephole2
19085 [(match_scratch:DI 3 "r")
19086 (parallel [(set (match_operand:DI 0 "register_operand" "")
19087 (mult:DI (match_operand:DI 1 "memory_operand" "")
19088 (match_operand:DI 2 "immediate_operand" "")))
19089 (clobber (reg:CC 17))])]
19090 "TARGET_K8 && !optimize_size
19091 && (GET_CODE (operands[2]) != CONST_INT
19092 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19093 [(set (match_dup 3) (match_dup 1))
19094 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19095 (clobber (reg:CC 17))])]
19096 "")
19097
19098 (define_peephole2
19099 [(match_scratch:SI 3 "r")
19100 (parallel [(set (match_operand:SI 0 "register_operand" "")
19101 (mult:SI (match_operand:SI 1 "memory_operand" "")
19102 (match_operand:SI 2 "immediate_operand" "")))
19103 (clobber (reg:CC 17))])]
19104 "TARGET_K8 && !optimize_size
19105 && (GET_CODE (operands[2]) != CONST_INT
19106 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19107 [(set (match_dup 3) (match_dup 1))
19108 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19109 (clobber (reg:CC 17))])]
19110 "")
19111
19112 (define_peephole2
19113 [(match_scratch:SI 3 "r")
19114 (parallel [(set (match_operand:DI 0 "register_operand" "")
19115 (zero_extend:DI
19116 (mult:SI (match_operand:SI 1 "memory_operand" "")
19117 (match_operand:SI 2 "immediate_operand" ""))))
19118 (clobber (reg:CC 17))])]
19119 "TARGET_K8 && !optimize_size
19120 && (GET_CODE (operands[2]) != CONST_INT
19121 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19122 [(set (match_dup 3) (match_dup 1))
19123 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19124 (clobber (reg:CC 17))])]
19125 "")
19126
19127 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19128 ;; Convert it into imul reg, reg
19129 ;; It would be better to force assembler to encode instruction using long
19130 ;; immediate, but there is apparently no way to do so.
19131 (define_peephole2
19132 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19133 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19134 (match_operand:DI 2 "const_int_operand" "")))
19135 (clobber (reg:CC 17))])
19136 (match_scratch:DI 3 "r")]
19137 "TARGET_K8 && !optimize_size
19138 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19139 [(set (match_dup 3) (match_dup 2))
19140 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19141 (clobber (reg:CC 17))])]
19142 {
19143 if (!rtx_equal_p (operands[0], operands[1]))
19144 emit_move_insn (operands[0], operands[1]);
19145 })
19146
19147 (define_peephole2
19148 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19149 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19150 (match_operand:SI 2 "const_int_operand" "")))
19151 (clobber (reg:CC 17))])
19152 (match_scratch:SI 3 "r")]
19153 "TARGET_K8 && !optimize_size
19154 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19155 [(set (match_dup 3) (match_dup 2))
19156 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19157 (clobber (reg:CC 17))])]
19158 {
19159 if (!rtx_equal_p (operands[0], operands[1]))
19160 emit_move_insn (operands[0], operands[1]);
19161 })
19162
19163 (define_peephole2
19164 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19165 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19166 (match_operand:HI 2 "immediate_operand" "")))
19167 (clobber (reg:CC 17))])
19168 (match_scratch:HI 3 "r")]
19169 "TARGET_K8 && !optimize_size"
19170 [(set (match_dup 3) (match_dup 2))
19171 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19172 (clobber (reg:CC 17))])]
19173 {
19174 if (!rtx_equal_p (operands[0], operands[1]))
19175 emit_move_insn (operands[0], operands[1]);
19176 })
19177 \f
19178 ;; Call-value patterns last so that the wildcard operand does not
19179 ;; disrupt insn-recog's switch tables.
19180
19181 (define_insn "*call_value_pop_0"
19182 [(set (match_operand 0 "" "")
19183 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19184 (match_operand:SI 2 "" "")))
19185 (set (reg:SI 7) (plus:SI (reg:SI 7)
19186 (match_operand:SI 3 "immediate_operand" "")))]
19187 "!TARGET_64BIT"
19188 {
19189 if (SIBLING_CALL_P (insn))
19190 return "jmp\t%P1";
19191 else
19192 return "call\t%P1";
19193 }
19194 [(set_attr "type" "callv")])
19195
19196 (define_insn "*call_value_pop_1"
19197 [(set (match_operand 0 "" "")
19198 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19199 (match_operand:SI 2 "" "")))
19200 (set (reg:SI 7) (plus:SI (reg:SI 7)
19201 (match_operand:SI 3 "immediate_operand" "i")))]
19202 "!TARGET_64BIT"
19203 {
19204 if (constant_call_address_operand (operands[1], QImode))
19205 {
19206 if (SIBLING_CALL_P (insn))
19207 return "jmp\t%P1";
19208 else
19209 return "call\t%P1";
19210 }
19211 if (SIBLING_CALL_P (insn))
19212 return "jmp\t%A1";
19213 else
19214 return "call\t%A1";
19215 }
19216 [(set_attr "type" "callv")])
19217
19218 (define_insn "*call_value_0"
19219 [(set (match_operand 0 "" "")
19220 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19221 (match_operand:SI 2 "" "")))]
19222 "!TARGET_64BIT"
19223 {
19224 if (SIBLING_CALL_P (insn))
19225 return "jmp\t%P1";
19226 else
19227 return "call\t%P1";
19228 }
19229 [(set_attr "type" "callv")])
19230
19231 (define_insn "*call_value_0_rex64"
19232 [(set (match_operand 0 "" "")
19233 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19234 (match_operand:DI 2 "const_int_operand" "")))]
19235 "TARGET_64BIT"
19236 {
19237 if (SIBLING_CALL_P (insn))
19238 return "jmp\t%P1";
19239 else
19240 return "call\t%P1";
19241 }
19242 [(set_attr "type" "callv")])
19243
19244 (define_insn "*call_value_1"
19245 [(set (match_operand 0 "" "")
19246 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19247 (match_operand:SI 2 "" "")))]
19248 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19249 {
19250 if (constant_call_address_operand (operands[1], QImode))
19251 return "call\t%P1";
19252 return "call\t%*%1";
19253 }
19254 [(set_attr "type" "callv")])
19255
19256 (define_insn "*sibcall_value_1"
19257 [(set (match_operand 0 "" "")
19258 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19259 (match_operand:SI 2 "" "")))]
19260 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19261 {
19262 if (constant_call_address_operand (operands[1], QImode))
19263 return "jmp\t%P1";
19264 return "jmp\t%*%1";
19265 }
19266 [(set_attr "type" "callv")])
19267
19268 (define_insn "*call_value_1_rex64"
19269 [(set (match_operand 0 "" "")
19270 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19271 (match_operand:DI 2 "" "")))]
19272 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19273 {
19274 if (constant_call_address_operand (operands[1], QImode))
19275 return "call\t%P1";
19276 return "call\t%A1";
19277 }
19278 [(set_attr "type" "callv")])
19279
19280 (define_insn "*sibcall_value_1_rex64"
19281 [(set (match_operand 0 "" "")
19282 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19283 (match_operand:DI 2 "" "")))]
19284 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19285 "jmp\t%P1"
19286 [(set_attr "type" "callv")])
19287
19288 (define_insn "*sibcall_value_1_rex64_v"
19289 [(set (match_operand 0 "" "")
19290 (call (mem:QI (reg:DI 40))
19291 (match_operand:DI 1 "" "")))]
19292 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19293 "jmp\t*%%r11"
19294 [(set_attr "type" "callv")])
19295 \f
19296 (define_insn "trap"
19297 [(trap_if (const_int 1) (const_int 5))]
19298 ""
19299 "int\t$5")
19300
19301 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19302 ;;; for the sake of bounds checking. By emitting bounds checks as
19303 ;;; conditional traps rather than as conditional jumps around
19304 ;;; unconditional traps we avoid introducing spurious basic-block
19305 ;;; boundaries and facilitate elimination of redundant checks. In
19306 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19307 ;;; interrupt 5.
19308 ;;;
19309 ;;; FIXME: Static branch prediction rules for ix86 are such that
19310 ;;; forward conditional branches predict as untaken. As implemented
19311 ;;; below, pseudo conditional traps violate that rule. We should use
19312 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19313 ;;; section loaded at the end of the text segment and branch forward
19314 ;;; there on bounds-failure, and then jump back immediately (in case
19315 ;;; the system chooses to ignore bounds violations, or to report
19316 ;;; violations and continue execution).
19317
19318 (define_expand "conditional_trap"
19319 [(trap_if (match_operator 0 "comparison_operator"
19320 [(match_dup 2) (const_int 0)])
19321 (match_operand 1 "const_int_operand" ""))]
19322 ""
19323 {
19324 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19325 ix86_expand_compare (GET_CODE (operands[0]),
19326 NULL, NULL),
19327 operands[1]));
19328 DONE;
19329 })
19330
19331 (define_insn "*conditional_trap_1"
19332 [(trap_if (match_operator 0 "comparison_operator"
19333 [(reg 17) (const_int 0)])
19334 (match_operand 1 "const_int_operand" ""))]
19335 ""
19336 {
19337 operands[2] = gen_label_rtx ();
19338 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19339 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19340 CODE_LABEL_NUMBER (operands[2]));
19341 RET;
19342 })
19343
19344 ;; Pentium III SIMD instructions.
19345
19346 ;; Moves for SSE/MMX regs.
19347
19348 (define_insn "movv4sf_internal"
19349 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19350 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19351 "TARGET_SSE"
19352 "@
19353 xorps\t%0, %0
19354 movaps\t{%1, %0|%0, %1}
19355 movaps\t{%1, %0|%0, %1}"
19356 [(set_attr "type" "ssemov")
19357 (set_attr "mode" "V4SF")])
19358
19359 (define_split
19360 [(set (match_operand:V4SF 0 "register_operand" "")
19361 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19362 "TARGET_SSE"
19363 [(set (match_dup 0)
19364 (vec_merge:V4SF
19365 (vec_duplicate:V4SF (match_dup 1))
19366 (match_dup 2)
19367 (const_int 1)))]
19368 {
19369 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19370 operands[2] = CONST0_RTX (V4SFmode);
19371 })
19372
19373 (define_insn "movv4si_internal"
19374 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19375 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19376 "TARGET_SSE"
19377 {
19378 switch (which_alternative)
19379 {
19380 case 0:
19381 if (get_attr_mode (insn) == MODE_V4SF)
19382 return "xorps\t%0, %0";
19383 else
19384 return "pxor\t%0, %0";
19385 case 1:
19386 case 2:
19387 if (get_attr_mode (insn) == MODE_V4SF)
19388 return "movaps\t{%1, %0|%0, %1}";
19389 else
19390 return "movdqa\t{%1, %0|%0, %1}";
19391 default:
19392 abort ();
19393 }
19394 }
19395 [(set_attr "type" "ssemov")
19396 (set (attr "mode")
19397 (cond [(eq_attr "alternative" "0,1")
19398 (if_then_else
19399 (ne (symbol_ref "optimize_size")
19400 (const_int 0))
19401 (const_string "V4SF")
19402 (const_string "TI"))
19403 (eq_attr "alternative" "2")
19404 (if_then_else
19405 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19406 (const_int 0))
19407 (ne (symbol_ref "optimize_size")
19408 (const_int 0)))
19409 (const_string "V4SF")
19410 (const_string "TI"))]
19411 (const_string "TI")))])
19412
19413 (define_insn "movv2di_internal"
19414 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19415 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19416 "TARGET_SSE2"
19417 {
19418 switch (which_alternative)
19419 {
19420 case 0:
19421 if (get_attr_mode (insn) == MODE_V4SF)
19422 return "xorps\t%0, %0";
19423 else
19424 return "pxor\t%0, %0";
19425 case 1:
19426 case 2:
19427 if (get_attr_mode (insn) == MODE_V4SF)
19428 return "movaps\t{%1, %0|%0, %1}";
19429 else
19430 return "movdqa\t{%1, %0|%0, %1}";
19431 default:
19432 abort ();
19433 }
19434 }
19435 [(set_attr "type" "ssemov")
19436 (set (attr "mode")
19437 (cond [(eq_attr "alternative" "0,1")
19438 (if_then_else
19439 (ne (symbol_ref "optimize_size")
19440 (const_int 0))
19441 (const_string "V4SF")
19442 (const_string "TI"))
19443 (eq_attr "alternative" "2")
19444 (if_then_else
19445 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19446 (const_int 0))
19447 (ne (symbol_ref "optimize_size")
19448 (const_int 0)))
19449 (const_string "V4SF")
19450 (const_string "TI"))]
19451 (const_string "TI")))])
19452
19453 (define_split
19454 [(set (match_operand:V2DF 0 "register_operand" "")
19455 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19456 "TARGET_SSE2"
19457 [(set (match_dup 0)
19458 (vec_merge:V2DF
19459 (vec_duplicate:V2DF (match_dup 1))
19460 (match_dup 2)
19461 (const_int 1)))]
19462 {
19463 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19464 operands[2] = CONST0_RTX (V2DFmode);
19465 })
19466
19467 (define_insn "movv8qi_internal"
19468 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19469 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19470 "TARGET_MMX
19471 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19472 "@
19473 pxor\t%0, %0
19474 movq\t{%1, %0|%0, %1}
19475 movq\t{%1, %0|%0, %1}"
19476 [(set_attr "type" "mmxmov")
19477 (set_attr "mode" "DI")])
19478
19479 (define_insn "movv4hi_internal"
19480 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19481 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19482 "TARGET_MMX
19483 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19484 "@
19485 pxor\t%0, %0
19486 movq\t{%1, %0|%0, %1}
19487 movq\t{%1, %0|%0, %1}"
19488 [(set_attr "type" "mmxmov")
19489 (set_attr "mode" "DI")])
19490
19491 (define_insn "movv2si_internal"
19492 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19493 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19494 "TARGET_MMX
19495 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19496 "@
19497 pxor\t%0, %0
19498 movq\t{%1, %0|%0, %1}
19499 movq\t{%1, %0|%0, %1}"
19500 [(set_attr "type" "mmxcvt")
19501 (set_attr "mode" "DI")])
19502
19503 (define_insn "movv2sf_internal"
19504 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19505 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19506 "TARGET_3DNOW
19507 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19508 "@
19509 pxor\t%0, %0
19510 movq\t{%1, %0|%0, %1}
19511 movq\t{%1, %0|%0, %1}"
19512 [(set_attr "type" "mmxcvt")
19513 (set_attr "mode" "DI")])
19514
19515 (define_expand "movti"
19516 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19517 (match_operand:TI 1 "nonimmediate_operand" ""))]
19518 "TARGET_SSE || TARGET_64BIT"
19519 {
19520 if (TARGET_64BIT)
19521 ix86_expand_move (TImode, operands);
19522 else
19523 ix86_expand_vector_move (TImode, operands);
19524 DONE;
19525 })
19526
19527 (define_insn "movv2df_internal"
19528 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19529 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19530 "TARGET_SSE2
19531 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19532 {
19533 switch (which_alternative)
19534 {
19535 case 0:
19536 if (get_attr_mode (insn) == MODE_V4SF)
19537 return "xorps\t%0, %0";
19538 else
19539 return "xorpd\t%0, %0";
19540 case 1:
19541 case 2:
19542 if (get_attr_mode (insn) == MODE_V4SF)
19543 return "movaps\t{%1, %0|%0, %1}";
19544 else
19545 return "movapd\t{%1, %0|%0, %1}";
19546 default:
19547 abort ();
19548 }
19549 }
19550 [(set_attr "type" "ssemov")
19551 (set (attr "mode")
19552 (cond [(eq_attr "alternative" "0,1")
19553 (if_then_else
19554 (ne (symbol_ref "optimize_size")
19555 (const_int 0))
19556 (const_string "V4SF")
19557 (const_string "V2DF"))
19558 (eq_attr "alternative" "2")
19559 (if_then_else
19560 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19561 (const_int 0))
19562 (ne (symbol_ref "optimize_size")
19563 (const_int 0)))
19564 (const_string "V4SF")
19565 (const_string "V2DF"))]
19566 (const_string "V2DF")))])
19567
19568 (define_insn "movv8hi_internal"
19569 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19570 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19571 "TARGET_SSE2
19572 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19573 {
19574 switch (which_alternative)
19575 {
19576 case 0:
19577 if (get_attr_mode (insn) == MODE_V4SF)
19578 return "xorps\t%0, %0";
19579 else
19580 return "pxor\t%0, %0";
19581 case 1:
19582 case 2:
19583 if (get_attr_mode (insn) == MODE_V4SF)
19584 return "movaps\t{%1, %0|%0, %1}";
19585 else
19586 return "movdqa\t{%1, %0|%0, %1}";
19587 default:
19588 abort ();
19589 }
19590 }
19591 [(set_attr "type" "ssemov")
19592 (set (attr "mode")
19593 (cond [(eq_attr "alternative" "0,1")
19594 (if_then_else
19595 (ne (symbol_ref "optimize_size")
19596 (const_int 0))
19597 (const_string "V4SF")
19598 (const_string "TI"))
19599 (eq_attr "alternative" "2")
19600 (if_then_else
19601 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19602 (const_int 0))
19603 (ne (symbol_ref "optimize_size")
19604 (const_int 0)))
19605 (const_string "V4SF")
19606 (const_string "TI"))]
19607 (const_string "TI")))])
19608
19609 (define_insn "movv16qi_internal"
19610 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19611 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19612 "TARGET_SSE2
19613 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19614 {
19615 switch (which_alternative)
19616 {
19617 case 0:
19618 if (get_attr_mode (insn) == MODE_V4SF)
19619 return "xorps\t%0, %0";
19620 else
19621 return "pxor\t%0, %0";
19622 case 1:
19623 case 2:
19624 if (get_attr_mode (insn) == MODE_V4SF)
19625 return "movaps\t{%1, %0|%0, %1}";
19626 else
19627 return "movdqa\t{%1, %0|%0, %1}";
19628 default:
19629 abort ();
19630 }
19631 }
19632 [(set_attr "type" "ssemov")
19633 (set (attr "mode")
19634 (cond [(eq_attr "alternative" "0,1")
19635 (if_then_else
19636 (ne (symbol_ref "optimize_size")
19637 (const_int 0))
19638 (const_string "V4SF")
19639 (const_string "TI"))
19640 (eq_attr "alternative" "2")
19641 (if_then_else
19642 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19643 (const_int 0))
19644 (ne (symbol_ref "optimize_size")
19645 (const_int 0)))
19646 (const_string "V4SF")
19647 (const_string "TI"))]
19648 (const_string "TI")))])
19649
19650 (define_expand "movv2df"
19651 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19652 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19653 "TARGET_SSE2"
19654 {
19655 ix86_expand_vector_move (V2DFmode, operands);
19656 DONE;
19657 })
19658
19659 (define_expand "movv8hi"
19660 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19661 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19662 "TARGET_SSE2"
19663 {
19664 ix86_expand_vector_move (V8HImode, operands);
19665 DONE;
19666 })
19667
19668 (define_expand "movv16qi"
19669 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19670 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19671 "TARGET_SSE2"
19672 {
19673 ix86_expand_vector_move (V16QImode, operands);
19674 DONE;
19675 })
19676
19677 (define_expand "movv4sf"
19678 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19679 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19680 "TARGET_SSE"
19681 {
19682 ix86_expand_vector_move (V4SFmode, operands);
19683 DONE;
19684 })
19685
19686 (define_expand "movv4si"
19687 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19688 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19689 "TARGET_SSE"
19690 {
19691 ix86_expand_vector_move (V4SImode, operands);
19692 DONE;
19693 })
19694
19695 (define_expand "movv2di"
19696 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19697 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19698 "TARGET_SSE"
19699 {
19700 ix86_expand_vector_move (V2DImode, operands);
19701 DONE;
19702 })
19703
19704 (define_expand "movv2si"
19705 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19706 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19707 "TARGET_MMX"
19708 {
19709 ix86_expand_vector_move (V2SImode, operands);
19710 DONE;
19711 })
19712
19713 (define_expand "movv4hi"
19714 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19715 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19716 "TARGET_MMX"
19717 {
19718 ix86_expand_vector_move (V4HImode, operands);
19719 DONE;
19720 })
19721
19722 (define_expand "movv8qi"
19723 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19724 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19725 "TARGET_MMX"
19726 {
19727 ix86_expand_vector_move (V8QImode, operands);
19728 DONE;
19729 })
19730
19731 (define_expand "movv2sf"
19732 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19733 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19734 "TARGET_3DNOW"
19735 {
19736 ix86_expand_vector_move (V2SFmode, operands);
19737 DONE;
19738 })
19739
19740 (define_insn "*pushti"
19741 [(set (match_operand:TI 0 "push_operand" "=<")
19742 (match_operand:TI 1 "register_operand" "x"))]
19743 "TARGET_SSE"
19744 "#")
19745
19746 (define_insn "*pushv2df"
19747 [(set (match_operand:V2DF 0 "push_operand" "=<")
19748 (match_operand:V2DF 1 "register_operand" "x"))]
19749 "TARGET_SSE"
19750 "#")
19751
19752 (define_insn "*pushv2di"
19753 [(set (match_operand:V2DI 0 "push_operand" "=<")
19754 (match_operand:V2DI 1 "register_operand" "x"))]
19755 "TARGET_SSE2"
19756 "#")
19757
19758 (define_insn "*pushv8hi"
19759 [(set (match_operand:V8HI 0 "push_operand" "=<")
19760 (match_operand:V8HI 1 "register_operand" "x"))]
19761 "TARGET_SSE2"
19762 "#")
19763
19764 (define_insn "*pushv16qi"
19765 [(set (match_operand:V16QI 0 "push_operand" "=<")
19766 (match_operand:V16QI 1 "register_operand" "x"))]
19767 "TARGET_SSE2"
19768 "#")
19769
19770 (define_insn "*pushv4sf"
19771 [(set (match_operand:V4SF 0 "push_operand" "=<")
19772 (match_operand:V4SF 1 "register_operand" "x"))]
19773 "TARGET_SSE"
19774 "#")
19775
19776 (define_insn "*pushv4si"
19777 [(set (match_operand:V4SI 0 "push_operand" "=<")
19778 (match_operand:V4SI 1 "register_operand" "x"))]
19779 "TARGET_SSE2"
19780 "#")
19781
19782 (define_insn "*pushv2si"
19783 [(set (match_operand:V2SI 0 "push_operand" "=<")
19784 (match_operand:V2SI 1 "register_operand" "y"))]
19785 "TARGET_MMX"
19786 "#")
19787
19788 (define_insn "*pushv4hi"
19789 [(set (match_operand:V4HI 0 "push_operand" "=<")
19790 (match_operand:V4HI 1 "register_operand" "y"))]
19791 "TARGET_MMX"
19792 "#")
19793
19794 (define_insn "*pushv8qi"
19795 [(set (match_operand:V8QI 0 "push_operand" "=<")
19796 (match_operand:V8QI 1 "register_operand" "y"))]
19797 "TARGET_MMX"
19798 "#")
19799
19800 (define_insn "*pushv2sf"
19801 [(set (match_operand:V2SF 0 "push_operand" "=<")
19802 (match_operand:V2SF 1 "register_operand" "y"))]
19803 "TARGET_3DNOW"
19804 "#")
19805
19806 (define_split
19807 [(set (match_operand 0 "push_operand" "")
19808 (match_operand 1 "register_operand" ""))]
19809 "!TARGET_64BIT && reload_completed
19810 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19811 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19812 (set (match_dup 2) (match_dup 1))]
19813 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19814 stack_pointer_rtx);
19815 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19816
19817 (define_split
19818 [(set (match_operand 0 "push_operand" "")
19819 (match_operand 1 "register_operand" ""))]
19820 "TARGET_64BIT && reload_completed
19821 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19822 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19823 (set (match_dup 2) (match_dup 1))]
19824 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19825 stack_pointer_rtx);
19826 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19827
19828
19829 (define_insn "movti_internal"
19830 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19831 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19832 "TARGET_SSE && !TARGET_64BIT
19833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19834 {
19835 switch (which_alternative)
19836 {
19837 case 0:
19838 if (get_attr_mode (insn) == MODE_V4SF)
19839 return "xorps\t%0, %0";
19840 else
19841 return "pxor\t%0, %0";
19842 case 1:
19843 case 2:
19844 if (get_attr_mode (insn) == MODE_V4SF)
19845 return "movaps\t{%1, %0|%0, %1}";
19846 else
19847 return "movdqa\t{%1, %0|%0, %1}";
19848 default:
19849 abort ();
19850 }
19851 }
19852 [(set_attr "type" "ssemov,ssemov,ssemov")
19853 (set (attr "mode")
19854 (cond [(eq_attr "alternative" "0,1")
19855 (if_then_else
19856 (ne (symbol_ref "optimize_size")
19857 (const_int 0))
19858 (const_string "V4SF")
19859 (const_string "TI"))
19860 (eq_attr "alternative" "2")
19861 (if_then_else
19862 (ne (symbol_ref "optimize_size")
19863 (const_int 0))
19864 (const_string "V4SF")
19865 (const_string "TI"))]
19866 (const_string "TI")))])
19867
19868 (define_insn "*movti_rex64"
19869 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19870 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19871 "TARGET_64BIT
19872 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19873 {
19874 switch (which_alternative)
19875 {
19876 case 0:
19877 case 1:
19878 return "#";
19879 case 2:
19880 if (get_attr_mode (insn) == MODE_V4SF)
19881 return "xorps\t%0, %0";
19882 else
19883 return "pxor\t%0, %0";
19884 case 3:
19885 case 4:
19886 if (get_attr_mode (insn) == MODE_V4SF)
19887 return "movaps\t{%1, %0|%0, %1}";
19888 else
19889 return "movdqa\t{%1, %0|%0, %1}";
19890 default:
19891 abort ();
19892 }
19893 }
19894 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19895 (set (attr "mode")
19896 (cond [(eq_attr "alternative" "2,3")
19897 (if_then_else
19898 (ne (symbol_ref "optimize_size")
19899 (const_int 0))
19900 (const_string "V4SF")
19901 (const_string "TI"))
19902 (eq_attr "alternative" "4")
19903 (if_then_else
19904 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19905 (const_int 0))
19906 (ne (symbol_ref "optimize_size")
19907 (const_int 0)))
19908 (const_string "V4SF")
19909 (const_string "TI"))]
19910 (const_string "DI")))])
19911
19912 (define_split
19913 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19914 (match_operand:TI 1 "general_operand" ""))]
19915 "reload_completed && !SSE_REG_P (operands[0])
19916 && !SSE_REG_P (operands[1])"
19917 [(const_int 0)]
19918 "ix86_split_long_move (operands); DONE;")
19919
19920 ;; These two patterns are useful for specifying exactly whether to use
19921 ;; movaps or movups
19922 (define_expand "sse_movaps"
19923 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19924 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19925 UNSPEC_MOVA))]
19926 "TARGET_SSE"
19927 {
19928 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19929 {
19930 rtx tmp = gen_reg_rtx (V4SFmode);
19931 emit_insn (gen_sse_movaps (tmp, operands[1]));
19932 emit_move_insn (operands[0], tmp);
19933 DONE;
19934 }
19935 })
19936
19937 (define_insn "*sse_movaps_1"
19938 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19939 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19940 UNSPEC_MOVA))]
19941 "TARGET_SSE
19942 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19943 "movaps\t{%1, %0|%0, %1}"
19944 [(set_attr "type" "ssemov,ssemov")
19945 (set_attr "mode" "V4SF")])
19946
19947 (define_expand "sse_movups"
19948 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19949 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19950 UNSPEC_MOVU))]
19951 "TARGET_SSE"
19952 {
19953 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19954 {
19955 rtx tmp = gen_reg_rtx (V4SFmode);
19956 emit_insn (gen_sse_movups (tmp, operands[1]));
19957 emit_move_insn (operands[0], tmp);
19958 DONE;
19959 }
19960 })
19961
19962 (define_insn "*sse_movups_1"
19963 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19964 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19965 UNSPEC_MOVU))]
19966 "TARGET_SSE
19967 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19968 "movups\t{%1, %0|%0, %1}"
19969 [(set_attr "type" "ssecvt,ssecvt")
19970 (set_attr "mode" "V4SF")])
19971
19972 ;; SSE Strange Moves.
19973
19974 (define_insn "sse_movmskps"
19975 [(set (match_operand:SI 0 "register_operand" "=r")
19976 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19977 UNSPEC_MOVMSK))]
19978 "TARGET_SSE"
19979 "movmskps\t{%1, %0|%0, %1}"
19980 [(set_attr "type" "ssecvt")
19981 (set_attr "mode" "V4SF")])
19982
19983 (define_insn "mmx_pmovmskb"
19984 [(set (match_operand:SI 0 "register_operand" "=r")
19985 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19986 UNSPEC_MOVMSK))]
19987 "TARGET_SSE || TARGET_3DNOW_A"
19988 "pmovmskb\t{%1, %0|%0, %1}"
19989 [(set_attr "type" "ssecvt")
19990 (set_attr "mode" "V4SF")])
19991
19992
19993 (define_insn "mmx_maskmovq"
19994 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19995 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19996 (match_operand:V8QI 2 "register_operand" "y")]
19997 UNSPEC_MASKMOV))]
19998 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19999 ;; @@@ check ordering of operands in intel/nonintel syntax
20000 "maskmovq\t{%2, %1|%1, %2}"
20001 [(set_attr "type" "mmxcvt")
20002 (set_attr "mode" "DI")])
20003
20004 (define_insn "mmx_maskmovq_rex"
20005 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20006 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20007 (match_operand:V8QI 2 "register_operand" "y")]
20008 UNSPEC_MASKMOV))]
20009 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20010 ;; @@@ check ordering of operands in intel/nonintel syntax
20011 "maskmovq\t{%2, %1|%1, %2}"
20012 [(set_attr "type" "mmxcvt")
20013 (set_attr "mode" "DI")])
20014
20015 (define_insn "sse_movntv4sf"
20016 [(set (match_operand:V4SF 0 "memory_operand" "=m")
20017 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20018 UNSPEC_MOVNT))]
20019 "TARGET_SSE"
20020 "movntps\t{%1, %0|%0, %1}"
20021 [(set_attr "type" "ssemov")
20022 (set_attr "mode" "V4SF")])
20023
20024 (define_insn "sse_movntdi"
20025 [(set (match_operand:DI 0 "memory_operand" "=m")
20026 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20027 UNSPEC_MOVNT))]
20028 "TARGET_SSE || TARGET_3DNOW_A"
20029 "movntq\t{%1, %0|%0, %1}"
20030 [(set_attr "type" "mmxmov")
20031 (set_attr "mode" "DI")])
20032
20033 (define_insn "sse_movhlps"
20034 [(set (match_operand:V4SF 0 "register_operand" "=x")
20035 (vec_merge:V4SF
20036 (match_operand:V4SF 1 "register_operand" "0")
20037 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20038 (parallel [(const_int 2)
20039 (const_int 3)
20040 (const_int 0)
20041 (const_int 1)]))
20042 (const_int 3)))]
20043 "TARGET_SSE"
20044 "movhlps\t{%2, %0|%0, %2}"
20045 [(set_attr "type" "ssecvt")
20046 (set_attr "mode" "V4SF")])
20047
20048 (define_insn "sse_movlhps"
20049 [(set (match_operand:V4SF 0 "register_operand" "=x")
20050 (vec_merge:V4SF
20051 (match_operand:V4SF 1 "register_operand" "0")
20052 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20053 (parallel [(const_int 2)
20054 (const_int 3)
20055 (const_int 0)
20056 (const_int 1)]))
20057 (const_int 12)))]
20058 "TARGET_SSE"
20059 "movlhps\t{%2, %0|%0, %2}"
20060 [(set_attr "type" "ssecvt")
20061 (set_attr "mode" "V4SF")])
20062
20063 (define_insn "sse_movhps"
20064 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20065 (vec_merge:V4SF
20066 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20067 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20068 (const_int 12)))]
20069 "TARGET_SSE
20070 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20071 "movhps\t{%2, %0|%0, %2}"
20072 [(set_attr "type" "ssecvt")
20073 (set_attr "mode" "V4SF")])
20074
20075 (define_insn "sse_movlps"
20076 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20077 (vec_merge:V4SF
20078 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20079 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20080 (const_int 3)))]
20081 "TARGET_SSE
20082 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20083 "movlps\t{%2, %0|%0, %2}"
20084 [(set_attr "type" "ssecvt")
20085 (set_attr "mode" "V4SF")])
20086
20087 (define_expand "sse_loadss"
20088 [(match_operand:V4SF 0 "register_operand" "")
20089 (match_operand:SF 1 "memory_operand" "")]
20090 "TARGET_SSE"
20091 {
20092 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20093 CONST0_RTX (V4SFmode)));
20094 DONE;
20095 })
20096
20097 (define_insn "sse_loadss_1"
20098 [(set (match_operand:V4SF 0 "register_operand" "=x")
20099 (vec_merge:V4SF
20100 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20101 (match_operand:V4SF 2 "const0_operand" "X")
20102 (const_int 1)))]
20103 "TARGET_SSE"
20104 "movss\t{%1, %0|%0, %1}"
20105 [(set_attr "type" "ssemov")
20106 (set_attr "mode" "SF")])
20107
20108 (define_insn "sse_movss"
20109 [(set (match_operand:V4SF 0 "register_operand" "=x")
20110 (vec_merge:V4SF
20111 (match_operand:V4SF 1 "register_operand" "0")
20112 (match_operand:V4SF 2 "register_operand" "x")
20113 (const_int 1)))]
20114 "TARGET_SSE"
20115 "movss\t{%2, %0|%0, %2}"
20116 [(set_attr "type" "ssemov")
20117 (set_attr "mode" "SF")])
20118
20119 (define_insn "sse_storess"
20120 [(set (match_operand:SF 0 "memory_operand" "=m")
20121 (vec_select:SF
20122 (match_operand:V4SF 1 "register_operand" "x")
20123 (parallel [(const_int 0)])))]
20124 "TARGET_SSE"
20125 "movss\t{%1, %0|%0, %1}"
20126 [(set_attr "type" "ssemov")
20127 (set_attr "mode" "SF")])
20128
20129 (define_insn "sse_shufps"
20130 [(set (match_operand:V4SF 0 "register_operand" "=x")
20131 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20132 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20133 (match_operand:SI 3 "immediate_operand" "i")]
20134 UNSPEC_SHUFFLE))]
20135 "TARGET_SSE"
20136 ;; @@@ check operand order for intel/nonintel syntax
20137 "shufps\t{%3, %2, %0|%0, %2, %3}"
20138 [(set_attr "type" "ssecvt")
20139 (set_attr "mode" "V4SF")])
20140
20141
20142 ;; SSE arithmetic
20143
20144 (define_insn "addv4sf3"
20145 [(set (match_operand:V4SF 0 "register_operand" "=x")
20146 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20147 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20148 "TARGET_SSE"
20149 "addps\t{%2, %0|%0, %2}"
20150 [(set_attr "type" "sseadd")
20151 (set_attr "mode" "V4SF")])
20152
20153 (define_insn "vmaddv4sf3"
20154 [(set (match_operand:V4SF 0 "register_operand" "=x")
20155 (vec_merge:V4SF
20156 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20157 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20158 (match_dup 1)
20159 (const_int 1)))]
20160 "TARGET_SSE"
20161 "addss\t{%2, %0|%0, %2}"
20162 [(set_attr "type" "sseadd")
20163 (set_attr "mode" "SF")])
20164
20165 (define_insn "subv4sf3"
20166 [(set (match_operand:V4SF 0 "register_operand" "=x")
20167 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20168 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20169 "TARGET_SSE"
20170 "subps\t{%2, %0|%0, %2}"
20171 [(set_attr "type" "sseadd")
20172 (set_attr "mode" "V4SF")])
20173
20174 (define_insn "vmsubv4sf3"
20175 [(set (match_operand:V4SF 0 "register_operand" "=x")
20176 (vec_merge:V4SF
20177 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20178 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20179 (match_dup 1)
20180 (const_int 1)))]
20181 "TARGET_SSE"
20182 "subss\t{%2, %0|%0, %2}"
20183 [(set_attr "type" "sseadd")
20184 (set_attr "mode" "SF")])
20185
20186 (define_insn "mulv4sf3"
20187 [(set (match_operand:V4SF 0 "register_operand" "=x")
20188 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20189 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20190 "TARGET_SSE"
20191 "mulps\t{%2, %0|%0, %2}"
20192 [(set_attr "type" "ssemul")
20193 (set_attr "mode" "V4SF")])
20194
20195 (define_insn "vmmulv4sf3"
20196 [(set (match_operand:V4SF 0 "register_operand" "=x")
20197 (vec_merge:V4SF
20198 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20199 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20200 (match_dup 1)
20201 (const_int 1)))]
20202 "TARGET_SSE"
20203 "mulss\t{%2, %0|%0, %2}"
20204 [(set_attr "type" "ssemul")
20205 (set_attr "mode" "SF")])
20206
20207 (define_insn "divv4sf3"
20208 [(set (match_operand:V4SF 0 "register_operand" "=x")
20209 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20210 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20211 "TARGET_SSE"
20212 "divps\t{%2, %0|%0, %2}"
20213 [(set_attr "type" "ssediv")
20214 (set_attr "mode" "V4SF")])
20215
20216 (define_insn "vmdivv4sf3"
20217 [(set (match_operand:V4SF 0 "register_operand" "=x")
20218 (vec_merge:V4SF
20219 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20220 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20221 (match_dup 1)
20222 (const_int 1)))]
20223 "TARGET_SSE"
20224 "divss\t{%2, %0|%0, %2}"
20225 [(set_attr "type" "ssediv")
20226 (set_attr "mode" "SF")])
20227
20228
20229 ;; SSE square root/reciprocal
20230
20231 (define_insn "rcpv4sf2"
20232 [(set (match_operand:V4SF 0 "register_operand" "=x")
20233 (unspec:V4SF
20234 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20235 "TARGET_SSE"
20236 "rcpps\t{%1, %0|%0, %1}"
20237 [(set_attr "type" "sse")
20238 (set_attr "mode" "V4SF")])
20239
20240 (define_insn "vmrcpv4sf2"
20241 [(set (match_operand:V4SF 0 "register_operand" "=x")
20242 (vec_merge:V4SF
20243 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20244 UNSPEC_RCP)
20245 (match_operand:V4SF 2 "register_operand" "0")
20246 (const_int 1)))]
20247 "TARGET_SSE"
20248 "rcpss\t{%1, %0|%0, %1}"
20249 [(set_attr "type" "sse")
20250 (set_attr "mode" "SF")])
20251
20252 (define_insn "rsqrtv4sf2"
20253 [(set (match_operand:V4SF 0 "register_operand" "=x")
20254 (unspec:V4SF
20255 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20256 "TARGET_SSE"
20257 "rsqrtps\t{%1, %0|%0, %1}"
20258 [(set_attr "type" "sse")
20259 (set_attr "mode" "V4SF")])
20260
20261 (define_insn "vmrsqrtv4sf2"
20262 [(set (match_operand:V4SF 0 "register_operand" "=x")
20263 (vec_merge:V4SF
20264 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20265 UNSPEC_RSQRT)
20266 (match_operand:V4SF 2 "register_operand" "0")
20267 (const_int 1)))]
20268 "TARGET_SSE"
20269 "rsqrtss\t{%1, %0|%0, %1}"
20270 [(set_attr "type" "sse")
20271 (set_attr "mode" "SF")])
20272
20273 (define_insn "sqrtv4sf2"
20274 [(set (match_operand:V4SF 0 "register_operand" "=x")
20275 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20276 "TARGET_SSE"
20277 "sqrtps\t{%1, %0|%0, %1}"
20278 [(set_attr "type" "sse")
20279 (set_attr "mode" "V4SF")])
20280
20281 (define_insn "vmsqrtv4sf2"
20282 [(set (match_operand:V4SF 0 "register_operand" "=x")
20283 (vec_merge:V4SF
20284 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20285 (match_operand:V4SF 2 "register_operand" "0")
20286 (const_int 1)))]
20287 "TARGET_SSE"
20288 "sqrtss\t{%1, %0|%0, %1}"
20289 [(set_attr "type" "sse")
20290 (set_attr "mode" "SF")])
20291
20292 ;; SSE logical operations.
20293
20294 ;; SSE defines logical operations on floating point values. This brings
20295 ;; interesting challenge to RTL representation where logicals are only valid
20296 ;; on integral types. We deal with this by representing the floating point
20297 ;; logical as logical on arguments casted to TImode as this is what hardware
20298 ;; really does. Unfortunately hardware requires the type information to be
20299 ;; present and thus we must avoid subregs from being simplified and eliminated
20300 ;; in later compilation phases.
20301 ;;
20302 ;; We have following variants from each instruction:
20303 ;; sse_andsf3 - the operation taking V4SF vector operands
20304 ;; and doing TImode cast on them
20305 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20306 ;; TImode, since backend insist on eliminating casts
20307 ;; on memory operands
20308 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20309 ;; We can not accept memory operand here as instruction reads
20310 ;; whole scalar. This is generated only post reload by GCC
20311 ;; scalar float operations that expands to logicals (fabs)
20312 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20313 ;; memory operand. Eventually combine can be able
20314 ;; to synthesize these using splitter.
20315 ;; sse2_anddf3, *sse2_anddf3_memory
20316 ;;
20317 ;;
20318 ;; These are not called andti3 etc. because we really really don't want
20319 ;; the compiler to widen DImode ands to TImode ands and then try to move
20320 ;; into DImode subregs of SSE registers, and them together, and move out
20321 ;; of DImode subregs again!
20322 ;; SSE1 single precision floating point logical operation
20323 (define_expand "sse_andv4sf3"
20324 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20325 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20326 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20327 "TARGET_SSE"
20328 "")
20329
20330 (define_insn "*sse_andv4sf3"
20331 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20332 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20333 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20334 "TARGET_SSE
20335 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20336 "andps\t{%2, %0|%0, %2}"
20337 [(set_attr "type" "sselog")
20338 (set_attr "mode" "V4SF")])
20339
20340 (define_insn "*sse_andsf3"
20341 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20342 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20343 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20344 "TARGET_SSE
20345 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20346 "andps\t{%2, %0|%0, %2}"
20347 [(set_attr "type" "sselog")
20348 (set_attr "mode" "V4SF")])
20349
20350 (define_expand "sse_nandv4sf3"
20351 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20352 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
20353 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20354 "TARGET_SSE"
20355 "")
20356
20357 (define_insn "*sse_nandv4sf3"
20358 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20359 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20360 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20361 "TARGET_SSE"
20362 "andnps\t{%2, %0|%0, %2}"
20363 [(set_attr "type" "sselog")
20364 (set_attr "mode" "V4SF")])
20365
20366 (define_insn "*sse_nandsf3"
20367 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20368 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20369 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20370 "TARGET_SSE"
20371 "andnps\t{%2, %0|%0, %2}"
20372 [(set_attr "type" "sselog")
20373 (set_attr "mode" "V4SF")])
20374
20375 (define_expand "sse_iorv4sf3"
20376 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20377 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20378 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20379 "TARGET_SSE"
20380 "")
20381
20382 (define_insn "*sse_iorv4sf3"
20383 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20384 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20385 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20386 "TARGET_SSE
20387 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20388 "orps\t{%2, %0|%0, %2}"
20389 [(set_attr "type" "sselog")
20390 (set_attr "mode" "V4SF")])
20391
20392 (define_insn "*sse_iorsf3"
20393 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20394 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20395 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20396 "TARGET_SSE
20397 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20398 "orps\t{%2, %0|%0, %2}"
20399 [(set_attr "type" "sselog")
20400 (set_attr "mode" "V4SF")])
20401
20402 (define_expand "sse_xorv4sf3"
20403 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20404 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20405 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20406 "TARGET_SSE
20407 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20408 "")
20409
20410 (define_insn "*sse_xorv4sf3"
20411 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20412 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20413 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20414 "TARGET_SSE
20415 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20416 "xorps\t{%2, %0|%0, %2}"
20417 [(set_attr "type" "sselog")
20418 (set_attr "mode" "V4SF")])
20419
20420 (define_insn "*sse_xorsf3"
20421 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20422 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20423 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20424 "TARGET_SSE
20425 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20426 "xorps\t{%2, %0|%0, %2}"
20427 [(set_attr "type" "sselog")
20428 (set_attr "mode" "V4SF")])
20429
20430 ;; SSE2 double precision floating point logical operation
20431
20432 (define_expand "sse2_andv2df3"
20433 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20434 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20435 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20436 "TARGET_SSE2"
20437 "")
20438
20439 (define_insn "*sse2_andv2df3"
20440 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20441 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20442 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20443 "TARGET_SSE2
20444 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20445 "andpd\t{%2, %0|%0, %2}"
20446 [(set_attr "type" "sselog")
20447 (set_attr "mode" "V2DF")])
20448
20449 (define_insn "*sse2_andv2df3"
20450 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20451 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20452 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20453 "TARGET_SSE2
20454 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20455 "andpd\t{%2, %0|%0, %2}"
20456 [(set_attr "type" "sselog")
20457 (set_attr "mode" "V2DF")])
20458
20459 (define_expand "sse2_nandv2df3"
20460 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20461 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
20462 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20463 "TARGET_SSE2"
20464 "")
20465
20466 (define_insn "*sse2_nandv2df3"
20467 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20468 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20469 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20470 "TARGET_SSE2"
20471 "andnpd\t{%2, %0|%0, %2}"
20472 [(set_attr "type" "sselog")
20473 (set_attr "mode" "V2DF")])
20474
20475 (define_insn "*sse_nandti3_df"
20476 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
20477 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20478 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
20479 "TARGET_SSE2"
20480 "andnpd\t{%2, %0|%0, %2}"
20481 [(set_attr "type" "sselog")
20482 (set_attr "mode" "V2DF")])
20483
20484 (define_expand "sse2_iorv2df3"
20485 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20486 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20487 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20488 "TARGET_SSE2"
20489 "")
20490
20491 (define_insn "*sse2_iorv2df3"
20492 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20493 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20494 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20495 "TARGET_SSE2
20496 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20497 "orpd\t{%2, %0|%0, %2}"
20498 [(set_attr "type" "sselog")
20499 (set_attr "mode" "V2DF")])
20500
20501 (define_insn "*sse2_iordf3"
20502 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20503 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20504 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20505 "TARGET_SSE2
20506 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20507 "orpd\t{%2, %0|%0, %2}"
20508 [(set_attr "type" "sselog")
20509 (set_attr "mode" "V2DF")])
20510
20511 (define_expand "sse2_xorv2df3"
20512 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20513 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
20514 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20515 "TARGET_SSE2"
20516 "")
20517
20518 (define_insn "*sse2_xorv2df3"
20519 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20520 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20521 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20522 "TARGET_SSE2
20523 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20524 "xorpd\t{%2, %0|%0, %2}"
20525 [(set_attr "type" "sselog")
20526 (set_attr "mode" "V2DF")])
20527
20528 (define_insn "*sse2_xordf3"
20529 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20530 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20531 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20532 "TARGET_SSE2
20533 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20534 "xorpd\t{%2, %0|%0, %2}"
20535 [(set_attr "type" "sselog")
20536 (set_attr "mode" "V2DF")])
20537
20538 ;; SSE2 integral logicals. These patterns must always come after floating
20539 ;; point ones since we don't want compiler to use integer opcodes on floating
20540 ;; point SSE values to avoid matching of subregs in the match_operand.
20541 (define_insn "*sse2_andti3"
20542 [(set (match_operand:TI 0 "register_operand" "=x")
20543 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20544 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20545 "TARGET_SSE2
20546 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20547 "pand\t{%2, %0|%0, %2}"
20548 [(set_attr "type" "sselog")
20549 (set_attr "mode" "TI")])
20550
20551 (define_insn "sse2_andv2di3"
20552 [(set (match_operand:V2DI 0 "register_operand" "=x")
20553 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20554 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20555 "TARGET_SSE2
20556 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20557 "pand\t{%2, %0|%0, %2}"
20558 [(set_attr "type" "sselog")
20559 (set_attr "mode" "TI")])
20560
20561 (define_insn "*sse2_nandti3"
20562 [(set (match_operand:TI 0 "register_operand" "=x")
20563 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20564 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20565 "TARGET_SSE2"
20566 "pandn\t{%2, %0|%0, %2}"
20567 [(set_attr "type" "sselog")
20568 (set_attr "mode" "TI")])
20569
20570 (define_insn "sse2_nandv2di3"
20571 [(set (match_operand:V2DI 0 "register_operand" "=x")
20572 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20573 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20574 "TARGET_SSE2
20575 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20576 "pandn\t{%2, %0|%0, %2}"
20577 [(set_attr "type" "sselog")
20578 (set_attr "mode" "TI")])
20579
20580 (define_insn "*sse2_iorti3"
20581 [(set (match_operand:TI 0 "register_operand" "=x")
20582 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20583 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20584 "TARGET_SSE2
20585 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20586 "por\t{%2, %0|%0, %2}"
20587 [(set_attr "type" "sselog")
20588 (set_attr "mode" "TI")])
20589
20590 (define_insn "sse2_iorv2di3"
20591 [(set (match_operand:V2DI 0 "register_operand" "=x")
20592 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20593 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20594 "TARGET_SSE2
20595 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20596 "por\t{%2, %0|%0, %2}"
20597 [(set_attr "type" "sselog")
20598 (set_attr "mode" "TI")])
20599
20600 (define_insn "*sse2_xorti3"
20601 [(set (match_operand:TI 0 "register_operand" "=x")
20602 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20603 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20604 "TARGET_SSE2
20605 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20606 "pxor\t{%2, %0|%0, %2}"
20607 [(set_attr "type" "sselog")
20608 (set_attr "mode" "TI")])
20609
20610 (define_insn "sse2_xorv2di3"
20611 [(set (match_operand:V2DI 0 "register_operand" "=x")
20612 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20613 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20614 "TARGET_SSE2
20615 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20616 "pxor\t{%2, %0|%0, %2}"
20617 [(set_attr "type" "sselog")
20618 (set_attr "mode" "TI")])
20619
20620 ;; Use xor, but don't show input operands so they aren't live before
20621 ;; this insn.
20622 (define_insn "sse_clrv4sf"
20623 [(set (match_operand:V4SF 0 "register_operand" "=x")
20624 (match_operand:V4SF 1 "const0_operand" "X"))]
20625 "TARGET_SSE"
20626 {
20627 if (get_attr_mode (insn) == MODE_TI)
20628 return "pxor\t{%0, %0|%0, %0}";
20629 else
20630 return "xorps\t{%0, %0|%0, %0}";
20631 }
20632 [(set_attr "type" "sselog")
20633 (set_attr "memory" "none")
20634 (set (attr "mode")
20635 (if_then_else
20636 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20637 (const_int 0))
20638 (ne (symbol_ref "TARGET_SSE2")
20639 (const_int 0)))
20640 (eq (symbol_ref "optimize_size")
20641 (const_int 0)))
20642 (const_string "TI")
20643 (const_string "V4SF")))])
20644
20645 ;; Use xor, but don't show input operands so they aren't live before
20646 ;; this insn.
20647 (define_insn "sse_clrv2df"
20648 [(set (match_operand:V2DF 0 "register_operand" "=x")
20649 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20650 "TARGET_SSE2"
20651 "xorpd\t{%0, %0|%0, %0}"
20652 [(set_attr "type" "sselog")
20653 (set_attr "memory" "none")
20654 (set_attr "mode" "V4SF")])
20655
20656 ;; SSE mask-generating compares
20657
20658 (define_insn "maskcmpv4sf3"
20659 [(set (match_operand:V4SI 0 "register_operand" "=x")
20660 (match_operator:V4SI 3 "sse_comparison_operator"
20661 [(match_operand:V4SF 1 "register_operand" "0")
20662 (match_operand:V4SF 2 "register_operand" "x")]))]
20663 "TARGET_SSE"
20664 "cmp%D3ps\t{%2, %0|%0, %2}"
20665 [(set_attr "type" "ssecmp")
20666 (set_attr "mode" "V4SF")])
20667
20668 (define_insn "maskncmpv4sf3"
20669 [(set (match_operand:V4SI 0 "register_operand" "=x")
20670 (not:V4SI
20671 (match_operator:V4SI 3 "sse_comparison_operator"
20672 [(match_operand:V4SF 1 "register_operand" "0")
20673 (match_operand:V4SF 2 "register_operand" "x")])))]
20674 "TARGET_SSE"
20675 {
20676 if (GET_CODE (operands[3]) == UNORDERED)
20677 return "cmpordps\t{%2, %0|%0, %2}";
20678 else
20679 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20680 }
20681 [(set_attr "type" "ssecmp")
20682 (set_attr "mode" "V4SF")])
20683
20684 (define_insn "vmmaskcmpv4sf3"
20685 [(set (match_operand:V4SI 0 "register_operand" "=x")
20686 (vec_merge:V4SI
20687 (match_operator:V4SI 3 "sse_comparison_operator"
20688 [(match_operand:V4SF 1 "register_operand" "0")
20689 (match_operand:V4SF 2 "register_operand" "x")])
20690 (subreg:V4SI (match_dup 1) 0)
20691 (const_int 1)))]
20692 "TARGET_SSE"
20693 "cmp%D3ss\t{%2, %0|%0, %2}"
20694 [(set_attr "type" "ssecmp")
20695 (set_attr "mode" "SF")])
20696
20697 (define_insn "vmmaskncmpv4sf3"
20698 [(set (match_operand:V4SI 0 "register_operand" "=x")
20699 (vec_merge:V4SI
20700 (not:V4SI
20701 (match_operator:V4SI 3 "sse_comparison_operator"
20702 [(match_operand:V4SF 1 "register_operand" "0")
20703 (match_operand:V4SF 2 "register_operand" "x")]))
20704 (subreg:V4SI (match_dup 1) 0)
20705 (const_int 1)))]
20706 "TARGET_SSE"
20707 {
20708 if (GET_CODE (operands[3]) == UNORDERED)
20709 return "cmpordss\t{%2, %0|%0, %2}";
20710 else
20711 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20712 }
20713 [(set_attr "type" "ssecmp")
20714 (set_attr "mode" "SF")])
20715
20716 (define_insn "sse_comi"
20717 [(set (reg:CCFP 17)
20718 (compare:CCFP (vec_select:SF
20719 (match_operand:V4SF 0 "register_operand" "x")
20720 (parallel [(const_int 0)]))
20721 (vec_select:SF
20722 (match_operand:V4SF 1 "register_operand" "x")
20723 (parallel [(const_int 0)]))))]
20724 "TARGET_SSE"
20725 "comiss\t{%1, %0|%0, %1}"
20726 [(set_attr "type" "ssecomi")
20727 (set_attr "mode" "SF")])
20728
20729 (define_insn "sse_ucomi"
20730 [(set (reg:CCFPU 17)
20731 (compare:CCFPU (vec_select:SF
20732 (match_operand:V4SF 0 "register_operand" "x")
20733 (parallel [(const_int 0)]))
20734 (vec_select:SF
20735 (match_operand:V4SF 1 "register_operand" "x")
20736 (parallel [(const_int 0)]))))]
20737 "TARGET_SSE"
20738 "ucomiss\t{%1, %0|%0, %1}"
20739 [(set_attr "type" "ssecomi")
20740 (set_attr "mode" "SF")])
20741
20742
20743 ;; SSE unpack
20744
20745 (define_insn "sse_unpckhps"
20746 [(set (match_operand:V4SF 0 "register_operand" "=x")
20747 (vec_merge:V4SF
20748 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20749 (parallel [(const_int 2)
20750 (const_int 0)
20751 (const_int 3)
20752 (const_int 1)]))
20753 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20754 (parallel [(const_int 0)
20755 (const_int 2)
20756 (const_int 1)
20757 (const_int 3)]))
20758 (const_int 5)))]
20759 "TARGET_SSE"
20760 "unpckhps\t{%2, %0|%0, %2}"
20761 [(set_attr "type" "ssecvt")
20762 (set_attr "mode" "V4SF")])
20763
20764 (define_insn "sse_unpcklps"
20765 [(set (match_operand:V4SF 0 "register_operand" "=x")
20766 (vec_merge:V4SF
20767 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20768 (parallel [(const_int 0)
20769 (const_int 2)
20770 (const_int 1)
20771 (const_int 3)]))
20772 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20773 (parallel [(const_int 2)
20774 (const_int 0)
20775 (const_int 3)
20776 (const_int 1)]))
20777 (const_int 5)))]
20778 "TARGET_SSE"
20779 "unpcklps\t{%2, %0|%0, %2}"
20780 [(set_attr "type" "ssecvt")
20781 (set_attr "mode" "V4SF")])
20782
20783
20784 ;; SSE min/max
20785
20786 (define_insn "smaxv4sf3"
20787 [(set (match_operand:V4SF 0 "register_operand" "=x")
20788 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20789 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20790 "TARGET_SSE"
20791 "maxps\t{%2, %0|%0, %2}"
20792 [(set_attr "type" "sse")
20793 (set_attr "mode" "V4SF")])
20794
20795 (define_insn "vmsmaxv4sf3"
20796 [(set (match_operand:V4SF 0 "register_operand" "=x")
20797 (vec_merge:V4SF
20798 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20799 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20800 (match_dup 1)
20801 (const_int 1)))]
20802 "TARGET_SSE"
20803 "maxss\t{%2, %0|%0, %2}"
20804 [(set_attr "type" "sse")
20805 (set_attr "mode" "SF")])
20806
20807 (define_insn "sminv4sf3"
20808 [(set (match_operand:V4SF 0 "register_operand" "=x")
20809 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20810 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20811 "TARGET_SSE"
20812 "minps\t{%2, %0|%0, %2}"
20813 [(set_attr "type" "sse")
20814 (set_attr "mode" "V4SF")])
20815
20816 (define_insn "vmsminv4sf3"
20817 [(set (match_operand:V4SF 0 "register_operand" "=x")
20818 (vec_merge:V4SF
20819 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20820 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20821 (match_dup 1)
20822 (const_int 1)))]
20823 "TARGET_SSE"
20824 "minss\t{%2, %0|%0, %2}"
20825 [(set_attr "type" "sse")
20826 (set_attr "mode" "SF")])
20827
20828 ;; SSE <-> integer/MMX conversions
20829
20830 (define_insn "cvtpi2ps"
20831 [(set (match_operand:V4SF 0 "register_operand" "=x")
20832 (vec_merge:V4SF
20833 (match_operand:V4SF 1 "register_operand" "0")
20834 (vec_duplicate:V4SF
20835 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20836 (const_int 12)))]
20837 "TARGET_SSE"
20838 "cvtpi2ps\t{%2, %0|%0, %2}"
20839 [(set_attr "type" "ssecvt")
20840 (set_attr "mode" "V4SF")])
20841
20842 (define_insn "cvtps2pi"
20843 [(set (match_operand:V2SI 0 "register_operand" "=y")
20844 (vec_select:V2SI
20845 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20846 (parallel [(const_int 0) (const_int 1)])))]
20847 "TARGET_SSE"
20848 "cvtps2pi\t{%1, %0|%0, %1}"
20849 [(set_attr "type" "ssecvt")
20850 (set_attr "mode" "V4SF")])
20851
20852 (define_insn "cvttps2pi"
20853 [(set (match_operand:V2SI 0 "register_operand" "=y")
20854 (vec_select:V2SI
20855 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20856 UNSPEC_FIX)
20857 (parallel [(const_int 0) (const_int 1)])))]
20858 "TARGET_SSE"
20859 "cvttps2pi\t{%1, %0|%0, %1}"
20860 [(set_attr "type" "ssecvt")
20861 (set_attr "mode" "SF")])
20862
20863 (define_insn "cvtsi2ss"
20864 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20865 (vec_merge:V4SF
20866 (match_operand:V4SF 1 "register_operand" "0,0")
20867 (vec_duplicate:V4SF
20868 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20869 (const_int 14)))]
20870 "TARGET_SSE"
20871 "cvtsi2ss\t{%2, %0|%0, %2}"
20872 [(set_attr "type" "sseicvt")
20873 (set_attr "athlon_decode" "vector,double")
20874 (set_attr "mode" "SF")])
20875
20876 (define_insn "cvtsi2ssq"
20877 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20878 (vec_merge:V4SF
20879 (match_operand:V4SF 1 "register_operand" "0,0")
20880 (vec_duplicate:V4SF
20881 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20882 (const_int 14)))]
20883 "TARGET_SSE && TARGET_64BIT"
20884 "cvtsi2ssq\t{%2, %0|%0, %2}"
20885 [(set_attr "type" "sseicvt")
20886 (set_attr "athlon_decode" "vector,double")
20887 (set_attr "mode" "SF")])
20888
20889 (define_insn "cvtss2si"
20890 [(set (match_operand:SI 0 "register_operand" "=r,r")
20891 (vec_select:SI
20892 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20893 (parallel [(const_int 0)])))]
20894 "TARGET_SSE"
20895 "cvtss2si\t{%1, %0|%0, %1}"
20896 [(set_attr "type" "sseicvt")
20897 (set_attr "athlon_decode" "double,vector")
20898 (set_attr "mode" "SI")])
20899
20900 (define_insn "cvtss2siq"
20901 [(set (match_operand:DI 0 "register_operand" "=r,r")
20902 (vec_select:DI
20903 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20904 (parallel [(const_int 0)])))]
20905 "TARGET_SSE"
20906 "cvtss2siq\t{%1, %0|%0, %1}"
20907 [(set_attr "type" "sseicvt")
20908 (set_attr "athlon_decode" "double,vector")
20909 (set_attr "mode" "DI")])
20910
20911 (define_insn "cvttss2si"
20912 [(set (match_operand:SI 0 "register_operand" "=r,r")
20913 (vec_select:SI
20914 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20915 UNSPEC_FIX)
20916 (parallel [(const_int 0)])))]
20917 "TARGET_SSE"
20918 "cvttss2si\t{%1, %0|%0, %1}"
20919 [(set_attr "type" "sseicvt")
20920 (set_attr "mode" "SF")
20921 (set_attr "athlon_decode" "double,vector")])
20922
20923 (define_insn "cvttss2siq"
20924 [(set (match_operand:DI 0 "register_operand" "=r,r")
20925 (vec_select:DI
20926 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20927 UNSPEC_FIX)
20928 (parallel [(const_int 0)])))]
20929 "TARGET_SSE && TARGET_64BIT"
20930 "cvttss2siq\t{%1, %0|%0, %1}"
20931 [(set_attr "type" "sseicvt")
20932 (set_attr "mode" "SF")
20933 (set_attr "athlon_decode" "double,vector")])
20934
20935
20936 ;; MMX insns
20937
20938 ;; MMX arithmetic
20939
20940 (define_insn "addv8qi3"
20941 [(set (match_operand:V8QI 0 "register_operand" "=y")
20942 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20943 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20944 "TARGET_MMX"
20945 "paddb\t{%2, %0|%0, %2}"
20946 [(set_attr "type" "mmxadd")
20947 (set_attr "mode" "DI")])
20948
20949 (define_insn "addv4hi3"
20950 [(set (match_operand:V4HI 0 "register_operand" "=y")
20951 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20952 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20953 "TARGET_MMX"
20954 "paddw\t{%2, %0|%0, %2}"
20955 [(set_attr "type" "mmxadd")
20956 (set_attr "mode" "DI")])
20957
20958 (define_insn "addv2si3"
20959 [(set (match_operand:V2SI 0 "register_operand" "=y")
20960 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20961 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20962 "TARGET_MMX"
20963 "paddd\t{%2, %0|%0, %2}"
20964 [(set_attr "type" "mmxadd")
20965 (set_attr "mode" "DI")])
20966
20967 (define_insn "mmx_adddi3"
20968 [(set (match_operand:DI 0 "register_operand" "=y")
20969 (unspec:DI
20970 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20971 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20972 UNSPEC_NOP))]
20973 "TARGET_MMX"
20974 "paddq\t{%2, %0|%0, %2}"
20975 [(set_attr "type" "mmxadd")
20976 (set_attr "mode" "DI")])
20977
20978 (define_insn "ssaddv8qi3"
20979 [(set (match_operand:V8QI 0 "register_operand" "=y")
20980 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20981 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20982 "TARGET_MMX"
20983 "paddsb\t{%2, %0|%0, %2}"
20984 [(set_attr "type" "mmxadd")
20985 (set_attr "mode" "DI")])
20986
20987 (define_insn "ssaddv4hi3"
20988 [(set (match_operand:V4HI 0 "register_operand" "=y")
20989 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20990 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20991 "TARGET_MMX"
20992 "paddsw\t{%2, %0|%0, %2}"
20993 [(set_attr "type" "mmxadd")
20994 (set_attr "mode" "DI")])
20995
20996 (define_insn "usaddv8qi3"
20997 [(set (match_operand:V8QI 0 "register_operand" "=y")
20998 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20999 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21000 "TARGET_MMX"
21001 "paddusb\t{%2, %0|%0, %2}"
21002 [(set_attr "type" "mmxadd")
21003 (set_attr "mode" "DI")])
21004
21005 (define_insn "usaddv4hi3"
21006 [(set (match_operand:V4HI 0 "register_operand" "=y")
21007 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21008 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21009 "TARGET_MMX"
21010 "paddusw\t{%2, %0|%0, %2}"
21011 [(set_attr "type" "mmxadd")
21012 (set_attr "mode" "DI")])
21013
21014 (define_insn "subv8qi3"
21015 [(set (match_operand:V8QI 0 "register_operand" "=y")
21016 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21017 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21018 "TARGET_MMX"
21019 "psubb\t{%2, %0|%0, %2}"
21020 [(set_attr "type" "mmxadd")
21021 (set_attr "mode" "DI")])
21022
21023 (define_insn "subv4hi3"
21024 [(set (match_operand:V4HI 0 "register_operand" "=y")
21025 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21026 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21027 "TARGET_MMX"
21028 "psubw\t{%2, %0|%0, %2}"
21029 [(set_attr "type" "mmxadd")
21030 (set_attr "mode" "DI")])
21031
21032 (define_insn "subv2si3"
21033 [(set (match_operand:V2SI 0 "register_operand" "=y")
21034 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21035 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21036 "TARGET_MMX"
21037 "psubd\t{%2, %0|%0, %2}"
21038 [(set_attr "type" "mmxadd")
21039 (set_attr "mode" "DI")])
21040
21041 (define_insn "mmx_subdi3"
21042 [(set (match_operand:DI 0 "register_operand" "=y")
21043 (unspec:DI
21044 [(minus:DI (match_operand:DI 1 "register_operand" "0")
21045 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21046 UNSPEC_NOP))]
21047 "TARGET_MMX"
21048 "psubq\t{%2, %0|%0, %2}"
21049 [(set_attr "type" "mmxadd")
21050 (set_attr "mode" "DI")])
21051
21052 (define_insn "sssubv8qi3"
21053 [(set (match_operand:V8QI 0 "register_operand" "=y")
21054 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21055 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21056 "TARGET_MMX"
21057 "psubsb\t{%2, %0|%0, %2}"
21058 [(set_attr "type" "mmxadd")
21059 (set_attr "mode" "DI")])
21060
21061 (define_insn "sssubv4hi3"
21062 [(set (match_operand:V4HI 0 "register_operand" "=y")
21063 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21064 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21065 "TARGET_MMX"
21066 "psubsw\t{%2, %0|%0, %2}"
21067 [(set_attr "type" "mmxadd")
21068 (set_attr "mode" "DI")])
21069
21070 (define_insn "ussubv8qi3"
21071 [(set (match_operand:V8QI 0 "register_operand" "=y")
21072 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21073 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21074 "TARGET_MMX"
21075 "psubusb\t{%2, %0|%0, %2}"
21076 [(set_attr "type" "mmxadd")
21077 (set_attr "mode" "DI")])
21078
21079 (define_insn "ussubv4hi3"
21080 [(set (match_operand:V4HI 0 "register_operand" "=y")
21081 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21082 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21083 "TARGET_MMX"
21084 "psubusw\t{%2, %0|%0, %2}"
21085 [(set_attr "type" "mmxadd")
21086 (set_attr "mode" "DI")])
21087
21088 (define_insn "mulv4hi3"
21089 [(set (match_operand:V4HI 0 "register_operand" "=y")
21090 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21091 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21092 "TARGET_MMX"
21093 "pmullw\t{%2, %0|%0, %2}"
21094 [(set_attr "type" "mmxmul")
21095 (set_attr "mode" "DI")])
21096
21097 (define_insn "smulv4hi3_highpart"
21098 [(set (match_operand:V4HI 0 "register_operand" "=y")
21099 (truncate:V4HI
21100 (lshiftrt:V4SI
21101 (mult:V4SI (sign_extend:V4SI
21102 (match_operand:V4HI 1 "register_operand" "0"))
21103 (sign_extend:V4SI
21104 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21105 (const_int 16))))]
21106 "TARGET_MMX"
21107 "pmulhw\t{%2, %0|%0, %2}"
21108 [(set_attr "type" "mmxmul")
21109 (set_attr "mode" "DI")])
21110
21111 (define_insn "umulv4hi3_highpart"
21112 [(set (match_operand:V4HI 0 "register_operand" "=y")
21113 (truncate:V4HI
21114 (lshiftrt:V4SI
21115 (mult:V4SI (zero_extend:V4SI
21116 (match_operand:V4HI 1 "register_operand" "0"))
21117 (zero_extend:V4SI
21118 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21119 (const_int 16))))]
21120 "TARGET_SSE || TARGET_3DNOW_A"
21121 "pmulhuw\t{%2, %0|%0, %2}"
21122 [(set_attr "type" "mmxmul")
21123 (set_attr "mode" "DI")])
21124
21125 (define_insn "mmx_pmaddwd"
21126 [(set (match_operand:V2SI 0 "register_operand" "=y")
21127 (plus:V2SI
21128 (mult:V2SI
21129 (sign_extend:V2SI
21130 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21131 (parallel [(const_int 0) (const_int 2)])))
21132 (sign_extend:V2SI
21133 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21134 (parallel [(const_int 0) (const_int 2)]))))
21135 (mult:V2SI
21136 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21137 (parallel [(const_int 1)
21138 (const_int 3)])))
21139 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21140 (parallel [(const_int 1)
21141 (const_int 3)]))))))]
21142 "TARGET_MMX"
21143 "pmaddwd\t{%2, %0|%0, %2}"
21144 [(set_attr "type" "mmxmul")
21145 (set_attr "mode" "DI")])
21146
21147
21148 ;; MMX logical operations
21149 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21150 ;; normal code that also wants to use the FPU from getting broken.
21151 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21152 (define_insn "mmx_iordi3"
21153 [(set (match_operand:DI 0 "register_operand" "=y")
21154 (unspec:DI
21155 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21156 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21157 UNSPEC_NOP))]
21158 "TARGET_MMX"
21159 "por\t{%2, %0|%0, %2}"
21160 [(set_attr "type" "mmxadd")
21161 (set_attr "mode" "DI")])
21162
21163 (define_insn "mmx_xordi3"
21164 [(set (match_operand:DI 0 "register_operand" "=y")
21165 (unspec:DI
21166 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21167 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21168 UNSPEC_NOP))]
21169 "TARGET_MMX"
21170 "pxor\t{%2, %0|%0, %2}"
21171 [(set_attr "type" "mmxadd")
21172 (set_attr "mode" "DI")
21173 (set_attr "memory" "none")])
21174
21175 ;; Same as pxor, but don't show input operands so that we don't think
21176 ;; they are live.
21177 (define_insn "mmx_clrdi"
21178 [(set (match_operand:DI 0 "register_operand" "=y")
21179 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21180 "TARGET_MMX"
21181 "pxor\t{%0, %0|%0, %0}"
21182 [(set_attr "type" "mmxadd")
21183 (set_attr "mode" "DI")
21184 (set_attr "memory" "none")])
21185
21186 (define_insn "mmx_anddi3"
21187 [(set (match_operand:DI 0 "register_operand" "=y")
21188 (unspec:DI
21189 [(and:DI (match_operand:DI 1 "register_operand" "%0")
21190 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21191 UNSPEC_NOP))]
21192 "TARGET_MMX"
21193 "pand\t{%2, %0|%0, %2}"
21194 [(set_attr "type" "mmxadd")
21195 (set_attr "mode" "DI")])
21196
21197 (define_insn "mmx_nanddi3"
21198 [(set (match_operand:DI 0 "register_operand" "=y")
21199 (unspec:DI
21200 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21201 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21202 UNSPEC_NOP))]
21203 "TARGET_MMX"
21204 "pandn\t{%2, %0|%0, %2}"
21205 [(set_attr "type" "mmxadd")
21206 (set_attr "mode" "DI")])
21207
21208
21209 ;; MMX unsigned averages/sum of absolute differences
21210
21211 (define_insn "mmx_uavgv8qi3"
21212 [(set (match_operand:V8QI 0 "register_operand" "=y")
21213 (ashiftrt:V8QI
21214 (plus:V8QI (plus:V8QI
21215 (match_operand:V8QI 1 "register_operand" "0")
21216 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21217 (const_vector:V8QI [(const_int 1)
21218 (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 "TARGET_SSE || TARGET_3DNOW_A"
21227 "pavgb\t{%2, %0|%0, %2}"
21228 [(set_attr "type" "mmxshft")
21229 (set_attr "mode" "DI")])
21230
21231 (define_insn "mmx_uavgv4hi3"
21232 [(set (match_operand:V4HI 0 "register_operand" "=y")
21233 (ashiftrt:V4HI
21234 (plus:V4HI (plus:V4HI
21235 (match_operand:V4HI 1 "register_operand" "0")
21236 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21237 (const_vector:V4HI [(const_int 1)
21238 (const_int 1)
21239 (const_int 1)
21240 (const_int 1)]))
21241 (const_int 1)))]
21242 "TARGET_SSE || TARGET_3DNOW_A"
21243 "pavgw\t{%2, %0|%0, %2}"
21244 [(set_attr "type" "mmxshft")
21245 (set_attr "mode" "DI")])
21246
21247 (define_insn "mmx_psadbw"
21248 [(set (match_operand:DI 0 "register_operand" "=y")
21249 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21250 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21251 UNSPEC_PSADBW))]
21252 "TARGET_SSE || TARGET_3DNOW_A"
21253 "psadbw\t{%2, %0|%0, %2}"
21254 [(set_attr "type" "mmxshft")
21255 (set_attr "mode" "DI")])
21256
21257
21258 ;; MMX insert/extract/shuffle
21259
21260 (define_insn "mmx_pinsrw"
21261 [(set (match_operand:V4HI 0 "register_operand" "=y")
21262 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21263 (vec_duplicate:V4HI
21264 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21265 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21266 "TARGET_SSE || TARGET_3DNOW_A"
21267 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21268 [(set_attr "type" "mmxcvt")
21269 (set_attr "mode" "DI")])
21270
21271 (define_insn "mmx_pextrw"
21272 [(set (match_operand:SI 0 "register_operand" "=r")
21273 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21274 (parallel
21275 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21276 "TARGET_SSE || TARGET_3DNOW_A"
21277 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21278 [(set_attr "type" "mmxcvt")
21279 (set_attr "mode" "DI")])
21280
21281 (define_insn "mmx_pshufw"
21282 [(set (match_operand:V4HI 0 "register_operand" "=y")
21283 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
21284 (match_operand:SI 2 "immediate_operand" "i")]
21285 UNSPEC_SHUFFLE))]
21286 "TARGET_SSE || TARGET_3DNOW_A"
21287 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21288 [(set_attr "type" "mmxcvt")
21289 (set_attr "mode" "DI")])
21290
21291
21292 ;; MMX mask-generating comparisons
21293
21294 (define_insn "eqv8qi3"
21295 [(set (match_operand:V8QI 0 "register_operand" "=y")
21296 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21297 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21298 "TARGET_MMX"
21299 "pcmpeqb\t{%2, %0|%0, %2}"
21300 [(set_attr "type" "mmxcmp")
21301 (set_attr "mode" "DI")])
21302
21303 (define_insn "eqv4hi3"
21304 [(set (match_operand:V4HI 0 "register_operand" "=y")
21305 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21306 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21307 "TARGET_MMX"
21308 "pcmpeqw\t{%2, %0|%0, %2}"
21309 [(set_attr "type" "mmxcmp")
21310 (set_attr "mode" "DI")])
21311
21312 (define_insn "eqv2si3"
21313 [(set (match_operand:V2SI 0 "register_operand" "=y")
21314 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21315 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21316 "TARGET_MMX"
21317 "pcmpeqd\t{%2, %0|%0, %2}"
21318 [(set_attr "type" "mmxcmp")
21319 (set_attr "mode" "DI")])
21320
21321 (define_insn "gtv8qi3"
21322 [(set (match_operand:V8QI 0 "register_operand" "=y")
21323 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21324 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21325 "TARGET_MMX"
21326 "pcmpgtb\t{%2, %0|%0, %2}"
21327 [(set_attr "type" "mmxcmp")
21328 (set_attr "mode" "DI")])
21329
21330 (define_insn "gtv4hi3"
21331 [(set (match_operand:V4HI 0 "register_operand" "=y")
21332 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21333 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21334 "TARGET_MMX"
21335 "pcmpgtw\t{%2, %0|%0, %2}"
21336 [(set_attr "type" "mmxcmp")
21337 (set_attr "mode" "DI")])
21338
21339 (define_insn "gtv2si3"
21340 [(set (match_operand:V2SI 0 "register_operand" "=y")
21341 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21342 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21343 "TARGET_MMX"
21344 "pcmpgtd\t{%2, %0|%0, %2}"
21345 [(set_attr "type" "mmxcmp")
21346 (set_attr "mode" "DI")])
21347
21348
21349 ;; MMX max/min insns
21350
21351 (define_insn "umaxv8qi3"
21352 [(set (match_operand:V8QI 0 "register_operand" "=y")
21353 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21354 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21355 "TARGET_SSE || TARGET_3DNOW_A"
21356 "pmaxub\t{%2, %0|%0, %2}"
21357 [(set_attr "type" "mmxadd")
21358 (set_attr "mode" "DI")])
21359
21360 (define_insn "smaxv4hi3"
21361 [(set (match_operand:V4HI 0 "register_operand" "=y")
21362 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21363 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21364 "TARGET_SSE || TARGET_3DNOW_A"
21365 "pmaxsw\t{%2, %0|%0, %2}"
21366 [(set_attr "type" "mmxadd")
21367 (set_attr "mode" "DI")])
21368
21369 (define_insn "uminv8qi3"
21370 [(set (match_operand:V8QI 0 "register_operand" "=y")
21371 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21372 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21373 "TARGET_SSE || TARGET_3DNOW_A"
21374 "pminub\t{%2, %0|%0, %2}"
21375 [(set_attr "type" "mmxadd")
21376 (set_attr "mode" "DI")])
21377
21378 (define_insn "sminv4hi3"
21379 [(set (match_operand:V4HI 0 "register_operand" "=y")
21380 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21381 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21382 "TARGET_SSE || TARGET_3DNOW_A"
21383 "pminsw\t{%2, %0|%0, %2}"
21384 [(set_attr "type" "mmxadd")
21385 (set_attr "mode" "DI")])
21386
21387
21388 ;; MMX shifts
21389
21390 (define_insn "ashrv4hi3"
21391 [(set (match_operand:V4HI 0 "register_operand" "=y")
21392 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21393 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21394 "TARGET_MMX"
21395 "psraw\t{%2, %0|%0, %2}"
21396 [(set_attr "type" "mmxshft")
21397 (set_attr "mode" "DI")])
21398
21399 (define_insn "ashrv2si3"
21400 [(set (match_operand:V2SI 0 "register_operand" "=y")
21401 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21402 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21403 "TARGET_MMX"
21404 "psrad\t{%2, %0|%0, %2}"
21405 [(set_attr "type" "mmxshft")
21406 (set_attr "mode" "DI")])
21407
21408 (define_insn "lshrv4hi3"
21409 [(set (match_operand:V4HI 0 "register_operand" "=y")
21410 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21411 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21412 "TARGET_MMX"
21413 "psrlw\t{%2, %0|%0, %2}"
21414 [(set_attr "type" "mmxshft")
21415 (set_attr "mode" "DI")])
21416
21417 (define_insn "lshrv2si3"
21418 [(set (match_operand:V2SI 0 "register_operand" "=y")
21419 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21420 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21421 "TARGET_MMX"
21422 "psrld\t{%2, %0|%0, %2}"
21423 [(set_attr "type" "mmxshft")
21424 (set_attr "mode" "DI")])
21425
21426 ;; See logical MMX insns.
21427 (define_insn "mmx_lshrdi3"
21428 [(set (match_operand:DI 0 "register_operand" "=y")
21429 (unspec:DI
21430 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21431 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21432 UNSPEC_NOP))]
21433 "TARGET_MMX"
21434 "psrlq\t{%2, %0|%0, %2}"
21435 [(set_attr "type" "mmxshft")
21436 (set_attr "mode" "DI")])
21437
21438 (define_insn "ashlv4hi3"
21439 [(set (match_operand:V4HI 0 "register_operand" "=y")
21440 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21441 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21442 "TARGET_MMX"
21443 "psllw\t{%2, %0|%0, %2}"
21444 [(set_attr "type" "mmxshft")
21445 (set_attr "mode" "DI")])
21446
21447 (define_insn "ashlv2si3"
21448 [(set (match_operand:V2SI 0 "register_operand" "=y")
21449 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21450 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21451 "TARGET_MMX"
21452 "pslld\t{%2, %0|%0, %2}"
21453 [(set_attr "type" "mmxshft")
21454 (set_attr "mode" "DI")])
21455
21456 ;; See logical MMX insns.
21457 (define_insn "mmx_ashldi3"
21458 [(set (match_operand:DI 0 "register_operand" "=y")
21459 (unspec:DI
21460 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21461 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21462 UNSPEC_NOP))]
21463 "TARGET_MMX"
21464 "psllq\t{%2, %0|%0, %2}"
21465 [(set_attr "type" "mmxshft")
21466 (set_attr "mode" "DI")])
21467
21468
21469 ;; MMX pack/unpack insns.
21470
21471 (define_insn "mmx_packsswb"
21472 [(set (match_operand:V8QI 0 "register_operand" "=y")
21473 (vec_concat:V8QI
21474 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21475 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21476 "TARGET_MMX"
21477 "packsswb\t{%2, %0|%0, %2}"
21478 [(set_attr "type" "mmxshft")
21479 (set_attr "mode" "DI")])
21480
21481 (define_insn "mmx_packssdw"
21482 [(set (match_operand:V4HI 0 "register_operand" "=y")
21483 (vec_concat:V4HI
21484 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21485 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21486 "TARGET_MMX"
21487 "packssdw\t{%2, %0|%0, %2}"
21488 [(set_attr "type" "mmxshft")
21489 (set_attr "mode" "DI")])
21490
21491 (define_insn "mmx_packuswb"
21492 [(set (match_operand:V8QI 0 "register_operand" "=y")
21493 (vec_concat:V8QI
21494 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21495 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21496 "TARGET_MMX"
21497 "packuswb\t{%2, %0|%0, %2}"
21498 [(set_attr "type" "mmxshft")
21499 (set_attr "mode" "DI")])
21500
21501 (define_insn "mmx_punpckhbw"
21502 [(set (match_operand:V8QI 0 "register_operand" "=y")
21503 (vec_merge:V8QI
21504 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21505 (parallel [(const_int 4)
21506 (const_int 0)
21507 (const_int 5)
21508 (const_int 1)
21509 (const_int 6)
21510 (const_int 2)
21511 (const_int 7)
21512 (const_int 3)]))
21513 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21514 (parallel [(const_int 0)
21515 (const_int 4)
21516 (const_int 1)
21517 (const_int 5)
21518 (const_int 2)
21519 (const_int 6)
21520 (const_int 3)
21521 (const_int 7)]))
21522 (const_int 85)))]
21523 "TARGET_MMX"
21524 "punpckhbw\t{%2, %0|%0, %2}"
21525 [(set_attr "type" "mmxcvt")
21526 (set_attr "mode" "DI")])
21527
21528 (define_insn "mmx_punpckhwd"
21529 [(set (match_operand:V4HI 0 "register_operand" "=y")
21530 (vec_merge:V4HI
21531 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21532 (parallel [(const_int 0)
21533 (const_int 2)
21534 (const_int 1)
21535 (const_int 3)]))
21536 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21537 (parallel [(const_int 2)
21538 (const_int 0)
21539 (const_int 3)
21540 (const_int 1)]))
21541 (const_int 5)))]
21542 "TARGET_MMX"
21543 "punpckhwd\t{%2, %0|%0, %2}"
21544 [(set_attr "type" "mmxcvt")
21545 (set_attr "mode" "DI")])
21546
21547 (define_insn "mmx_punpckhdq"
21548 [(set (match_operand:V2SI 0 "register_operand" "=y")
21549 (vec_merge:V2SI
21550 (match_operand:V2SI 1 "register_operand" "0")
21551 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21552 (parallel [(const_int 1)
21553 (const_int 0)]))
21554 (const_int 1)))]
21555 "TARGET_MMX"
21556 "punpckhdq\t{%2, %0|%0, %2}"
21557 [(set_attr "type" "mmxcvt")
21558 (set_attr "mode" "DI")])
21559
21560 (define_insn "mmx_punpcklbw"
21561 [(set (match_operand:V8QI 0 "register_operand" "=y")
21562 (vec_merge:V8QI
21563 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21564 (parallel [(const_int 0)
21565 (const_int 4)
21566 (const_int 1)
21567 (const_int 5)
21568 (const_int 2)
21569 (const_int 6)
21570 (const_int 3)
21571 (const_int 7)]))
21572 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21573 (parallel [(const_int 4)
21574 (const_int 0)
21575 (const_int 5)
21576 (const_int 1)
21577 (const_int 6)
21578 (const_int 2)
21579 (const_int 7)
21580 (const_int 3)]))
21581 (const_int 85)))]
21582 "TARGET_MMX"
21583 "punpcklbw\t{%2, %0|%0, %2}"
21584 [(set_attr "type" "mmxcvt")
21585 (set_attr "mode" "DI")])
21586
21587 (define_insn "mmx_punpcklwd"
21588 [(set (match_operand:V4HI 0 "register_operand" "=y")
21589 (vec_merge:V4HI
21590 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21591 (parallel [(const_int 2)
21592 (const_int 0)
21593 (const_int 3)
21594 (const_int 1)]))
21595 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21596 (parallel [(const_int 0)
21597 (const_int 2)
21598 (const_int 1)
21599 (const_int 3)]))
21600 (const_int 5)))]
21601 "TARGET_MMX"
21602 "punpcklwd\t{%2, %0|%0, %2}"
21603 [(set_attr "type" "mmxcvt")
21604 (set_attr "mode" "DI")])
21605
21606 (define_insn "mmx_punpckldq"
21607 [(set (match_operand:V2SI 0 "register_operand" "=y")
21608 (vec_merge:V2SI
21609 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21610 (parallel [(const_int 1)
21611 (const_int 0)]))
21612 (match_operand:V2SI 2 "register_operand" "y")
21613 (const_int 1)))]
21614 "TARGET_MMX"
21615 "punpckldq\t{%2, %0|%0, %2}"
21616 [(set_attr "type" "mmxcvt")
21617 (set_attr "mode" "DI")])
21618
21619
21620 ;; Miscellaneous stuff
21621
21622 (define_insn "emms"
21623 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21624 (clobber (reg:XF 8))
21625 (clobber (reg:XF 9))
21626 (clobber (reg:XF 10))
21627 (clobber (reg:XF 11))
21628 (clobber (reg:XF 12))
21629 (clobber (reg:XF 13))
21630 (clobber (reg:XF 14))
21631 (clobber (reg:XF 15))
21632 (clobber (reg:DI 29))
21633 (clobber (reg:DI 30))
21634 (clobber (reg:DI 31))
21635 (clobber (reg:DI 32))
21636 (clobber (reg:DI 33))
21637 (clobber (reg:DI 34))
21638 (clobber (reg:DI 35))
21639 (clobber (reg:DI 36))]
21640 "TARGET_MMX"
21641 "emms"
21642 [(set_attr "type" "mmx")
21643 (set_attr "memory" "unknown")])
21644
21645 (define_insn "ldmxcsr"
21646 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21647 UNSPECV_LDMXCSR)]
21648 "TARGET_SSE"
21649 "ldmxcsr\t%0"
21650 [(set_attr "type" "sse")
21651 (set_attr "memory" "load")])
21652
21653 (define_insn "stmxcsr"
21654 [(set (match_operand:SI 0 "memory_operand" "=m")
21655 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21656 "TARGET_SSE"
21657 "stmxcsr\t%0"
21658 [(set_attr "type" "sse")
21659 (set_attr "memory" "store")])
21660
21661 (define_expand "sfence"
21662 [(set (match_dup 0)
21663 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21664 "TARGET_SSE || TARGET_3DNOW_A"
21665 {
21666 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21667 MEM_VOLATILE_P (operands[0]) = 1;
21668 })
21669
21670 (define_insn "*sfence_insn"
21671 [(set (match_operand:BLK 0 "" "")
21672 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21673 "TARGET_SSE || TARGET_3DNOW_A"
21674 "sfence"
21675 [(set_attr "type" "sse")
21676 (set_attr "memory" "unknown")])
21677
21678 (define_expand "sse_prologue_save"
21679 [(parallel [(set (match_operand:BLK 0 "" "")
21680 (unspec:BLK [(reg:DI 21)
21681 (reg:DI 22)
21682 (reg:DI 23)
21683 (reg:DI 24)
21684 (reg:DI 25)
21685 (reg:DI 26)
21686 (reg:DI 27)
21687 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21688 (use (match_operand:DI 1 "register_operand" ""))
21689 (use (match_operand:DI 2 "immediate_operand" ""))
21690 (use (label_ref:DI (match_operand 3 "" "")))])]
21691 "TARGET_64BIT"
21692 "")
21693
21694 (define_insn "*sse_prologue_save_insn"
21695 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21696 (match_operand:DI 4 "const_int_operand" "n")))
21697 (unspec:BLK [(reg:DI 21)
21698 (reg:DI 22)
21699 (reg:DI 23)
21700 (reg:DI 24)
21701 (reg:DI 25)
21702 (reg:DI 26)
21703 (reg:DI 27)
21704 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21705 (use (match_operand:DI 1 "register_operand" "r"))
21706 (use (match_operand:DI 2 "const_int_operand" "i"))
21707 (use (label_ref:DI (match_operand 3 "" "X")))]
21708 "TARGET_64BIT
21709 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21710 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21711 "*
21712 {
21713 int i;
21714 operands[0] = gen_rtx_MEM (Pmode,
21715 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21716 output_asm_insn (\"jmp\\t%A1\", operands);
21717 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21718 {
21719 operands[4] = adjust_address (operands[0], DImode, i*16);
21720 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21721 PUT_MODE (operands[4], TImode);
21722 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21723 output_asm_insn (\"rex\", operands);
21724 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21725 }
21726 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21727 CODE_LABEL_NUMBER (operands[3]));
21728 RET;
21729 }
21730 "
21731 [(set_attr "type" "other")
21732 (set_attr "length_immediate" "0")
21733 (set_attr "length_address" "0")
21734 (set_attr "length" "135")
21735 (set_attr "memory" "store")
21736 (set_attr "modrm" "0")
21737 (set_attr "mode" "DI")])
21738
21739 ;; 3Dnow! instructions
21740
21741 (define_insn "addv2sf3"
21742 [(set (match_operand:V2SF 0 "register_operand" "=y")
21743 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21744 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21745 "TARGET_3DNOW"
21746 "pfadd\\t{%2, %0|%0, %2}"
21747 [(set_attr "type" "mmxadd")
21748 (set_attr "mode" "V2SF")])
21749
21750 (define_insn "subv2sf3"
21751 [(set (match_operand:V2SF 0 "register_operand" "=y")
21752 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21753 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21754 "TARGET_3DNOW"
21755 "pfsub\\t{%2, %0|%0, %2}"
21756 [(set_attr "type" "mmxadd")
21757 (set_attr "mode" "V2SF")])
21758
21759 (define_insn "subrv2sf3"
21760 [(set (match_operand:V2SF 0 "register_operand" "=y")
21761 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21762 (match_operand:V2SF 1 "register_operand" "0")))]
21763 "TARGET_3DNOW"
21764 "pfsubr\\t{%2, %0|%0, %2}"
21765 [(set_attr "type" "mmxadd")
21766 (set_attr "mode" "V2SF")])
21767
21768 (define_insn "gtv2sf3"
21769 [(set (match_operand:V2SI 0 "register_operand" "=y")
21770 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21771 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21772 "TARGET_3DNOW"
21773 "pfcmpgt\\t{%2, %0|%0, %2}"
21774 [(set_attr "type" "mmxcmp")
21775 (set_attr "mode" "V2SF")])
21776
21777 (define_insn "gev2sf3"
21778 [(set (match_operand:V2SI 0 "register_operand" "=y")
21779 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21780 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21781 "TARGET_3DNOW"
21782 "pfcmpge\\t{%2, %0|%0, %2}"
21783 [(set_attr "type" "mmxcmp")
21784 (set_attr "mode" "V2SF")])
21785
21786 (define_insn "eqv2sf3"
21787 [(set (match_operand:V2SI 0 "register_operand" "=y")
21788 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21789 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21790 "TARGET_3DNOW"
21791 "pfcmpeq\\t{%2, %0|%0, %2}"
21792 [(set_attr "type" "mmxcmp")
21793 (set_attr "mode" "V2SF")])
21794
21795 (define_insn "pfmaxv2sf3"
21796 [(set (match_operand:V2SF 0 "register_operand" "=y")
21797 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21798 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21799 "TARGET_3DNOW"
21800 "pfmax\\t{%2, %0|%0, %2}"
21801 [(set_attr "type" "mmxadd")
21802 (set_attr "mode" "V2SF")])
21803
21804 (define_insn "pfminv2sf3"
21805 [(set (match_operand:V2SF 0 "register_operand" "=y")
21806 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21807 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21808 "TARGET_3DNOW"
21809 "pfmin\\t{%2, %0|%0, %2}"
21810 [(set_attr "type" "mmxadd")
21811 (set_attr "mode" "V2SF")])
21812
21813 (define_insn "mulv2sf3"
21814 [(set (match_operand:V2SF 0 "register_operand" "=y")
21815 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21816 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21817 "TARGET_3DNOW"
21818 "pfmul\\t{%2, %0|%0, %2}"
21819 [(set_attr "type" "mmxmul")
21820 (set_attr "mode" "V2SF")])
21821
21822 (define_insn "femms"
21823 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21824 (clobber (reg:XF 8))
21825 (clobber (reg:XF 9))
21826 (clobber (reg:XF 10))
21827 (clobber (reg:XF 11))
21828 (clobber (reg:XF 12))
21829 (clobber (reg:XF 13))
21830 (clobber (reg:XF 14))
21831 (clobber (reg:XF 15))
21832 (clobber (reg:DI 29))
21833 (clobber (reg:DI 30))
21834 (clobber (reg:DI 31))
21835 (clobber (reg:DI 32))
21836 (clobber (reg:DI 33))
21837 (clobber (reg:DI 34))
21838 (clobber (reg:DI 35))
21839 (clobber (reg:DI 36))]
21840 "TARGET_3DNOW"
21841 "femms"
21842 [(set_attr "type" "mmx")
21843 (set_attr "memory" "none")])
21844
21845 (define_insn "pf2id"
21846 [(set (match_operand:V2SI 0 "register_operand" "=y")
21847 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21848 "TARGET_3DNOW"
21849 "pf2id\\t{%1, %0|%0, %1}"
21850 [(set_attr "type" "mmxcvt")
21851 (set_attr "mode" "V2SF")])
21852
21853 (define_insn "pf2iw"
21854 [(set (match_operand:V2SI 0 "register_operand" "=y")
21855 (sign_extend:V2SI
21856 (ss_truncate:V2HI
21857 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21858 "TARGET_3DNOW_A"
21859 "pf2iw\\t{%1, %0|%0, %1}"
21860 [(set_attr "type" "mmxcvt")
21861 (set_attr "mode" "V2SF")])
21862
21863 (define_insn "pfacc"
21864 [(set (match_operand:V2SF 0 "register_operand" "=y")
21865 (vec_concat:V2SF
21866 (plus:SF
21867 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21868 (parallel [(const_int 0)]))
21869 (vec_select:SF (match_dup 1)
21870 (parallel [(const_int 1)])))
21871 (plus:SF
21872 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21873 (parallel [(const_int 0)]))
21874 (vec_select:SF (match_dup 2)
21875 (parallel [(const_int 1)])))))]
21876 "TARGET_3DNOW"
21877 "pfacc\\t{%2, %0|%0, %2}"
21878 [(set_attr "type" "mmxadd")
21879 (set_attr "mode" "V2SF")])
21880
21881 (define_insn "pfnacc"
21882 [(set (match_operand:V2SF 0 "register_operand" "=y")
21883 (vec_concat:V2SF
21884 (minus:SF
21885 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21886 (parallel [(const_int 0)]))
21887 (vec_select:SF (match_dup 1)
21888 (parallel [(const_int 1)])))
21889 (minus:SF
21890 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21891 (parallel [(const_int 0)]))
21892 (vec_select:SF (match_dup 2)
21893 (parallel [(const_int 1)])))))]
21894 "TARGET_3DNOW_A"
21895 "pfnacc\\t{%2, %0|%0, %2}"
21896 [(set_attr "type" "mmxadd")
21897 (set_attr "mode" "V2SF")])
21898
21899 (define_insn "pfpnacc"
21900 [(set (match_operand:V2SF 0 "register_operand" "=y")
21901 (vec_concat:V2SF
21902 (minus:SF
21903 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21904 (parallel [(const_int 0)]))
21905 (vec_select:SF (match_dup 1)
21906 (parallel [(const_int 1)])))
21907 (plus:SF
21908 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21909 (parallel [(const_int 0)]))
21910 (vec_select:SF (match_dup 2)
21911 (parallel [(const_int 1)])))))]
21912 "TARGET_3DNOW_A"
21913 "pfpnacc\\t{%2, %0|%0, %2}"
21914 [(set_attr "type" "mmxadd")
21915 (set_attr "mode" "V2SF")])
21916
21917 (define_insn "pi2fw"
21918 [(set (match_operand:V2SF 0 "register_operand" "=y")
21919 (float:V2SF
21920 (vec_concat:V2SI
21921 (sign_extend:SI
21922 (truncate:HI
21923 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21924 (parallel [(const_int 0)]))))
21925 (sign_extend:SI
21926 (truncate:HI
21927 (vec_select:SI (match_dup 1)
21928 (parallel [(const_int 1)])))))))]
21929 "TARGET_3DNOW_A"
21930 "pi2fw\\t{%1, %0|%0, %1}"
21931 [(set_attr "type" "mmxcvt")
21932 (set_attr "mode" "V2SF")])
21933
21934 (define_insn "floatv2si2"
21935 [(set (match_operand:V2SF 0 "register_operand" "=y")
21936 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21937 "TARGET_3DNOW"
21938 "pi2fd\\t{%1, %0|%0, %1}"
21939 [(set_attr "type" "mmxcvt")
21940 (set_attr "mode" "V2SF")])
21941
21942 ;; This insn is identical to pavgb in operation, but the opcode is
21943 ;; different. To avoid accidentally matching pavgb, use an unspec.
21944
21945 (define_insn "pavgusb"
21946 [(set (match_operand:V8QI 0 "register_operand" "=y")
21947 (unspec:V8QI
21948 [(match_operand:V8QI 1 "register_operand" "0")
21949 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21950 UNSPEC_PAVGUSB))]
21951 "TARGET_3DNOW"
21952 "pavgusb\\t{%2, %0|%0, %2}"
21953 [(set_attr "type" "mmxshft")
21954 (set_attr "mode" "TI")])
21955
21956 ;; 3DNow reciprocal and sqrt
21957
21958 (define_insn "pfrcpv2sf2"
21959 [(set (match_operand:V2SF 0 "register_operand" "=y")
21960 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21961 UNSPEC_PFRCP))]
21962 "TARGET_3DNOW"
21963 "pfrcp\\t{%1, %0|%0, %1}"
21964 [(set_attr "type" "mmx")
21965 (set_attr "mode" "TI")])
21966
21967 (define_insn "pfrcpit1v2sf3"
21968 [(set (match_operand:V2SF 0 "register_operand" "=y")
21969 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21970 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21971 UNSPEC_PFRCPIT1))]
21972 "TARGET_3DNOW"
21973 "pfrcpit1\\t{%2, %0|%0, %2}"
21974 [(set_attr "type" "mmx")
21975 (set_attr "mode" "TI")])
21976
21977 (define_insn "pfrcpit2v2sf3"
21978 [(set (match_operand:V2SF 0 "register_operand" "=y")
21979 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21980 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21981 UNSPEC_PFRCPIT2))]
21982 "TARGET_3DNOW"
21983 "pfrcpit2\\t{%2, %0|%0, %2}"
21984 [(set_attr "type" "mmx")
21985 (set_attr "mode" "TI")])
21986
21987 (define_insn "pfrsqrtv2sf2"
21988 [(set (match_operand:V2SF 0 "register_operand" "=y")
21989 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21990 UNSPEC_PFRSQRT))]
21991 "TARGET_3DNOW"
21992 "pfrsqrt\\t{%1, %0|%0, %1}"
21993 [(set_attr "type" "mmx")
21994 (set_attr "mode" "TI")])
21995
21996 (define_insn "pfrsqit1v2sf3"
21997 [(set (match_operand:V2SF 0 "register_operand" "=y")
21998 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21999 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22000 UNSPEC_PFRSQIT1))]
22001 "TARGET_3DNOW"
22002 "pfrsqit1\\t{%2, %0|%0, %2}"
22003 [(set_attr "type" "mmx")
22004 (set_attr "mode" "TI")])
22005
22006 (define_insn "pmulhrwv4hi3"
22007 [(set (match_operand:V4HI 0 "register_operand" "=y")
22008 (truncate:V4HI
22009 (lshiftrt:V4SI
22010 (plus:V4SI
22011 (mult:V4SI
22012 (sign_extend:V4SI
22013 (match_operand:V4HI 1 "register_operand" "0"))
22014 (sign_extend:V4SI
22015 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22016 (const_vector:V4SI [(const_int 32768)
22017 (const_int 32768)
22018 (const_int 32768)
22019 (const_int 32768)]))
22020 (const_int 16))))]
22021 "TARGET_3DNOW"
22022 "pmulhrw\\t{%2, %0|%0, %2}"
22023 [(set_attr "type" "mmxmul")
22024 (set_attr "mode" "TI")])
22025
22026 (define_insn "pswapdv2si2"
22027 [(set (match_operand:V2SI 0 "register_operand" "=y")
22028 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22029 (parallel [(const_int 1) (const_int 0)])))]
22030 "TARGET_3DNOW_A"
22031 "pswapd\\t{%1, %0|%0, %1}"
22032 [(set_attr "type" "mmxcvt")
22033 (set_attr "mode" "TI")])
22034
22035 (define_insn "pswapdv2sf2"
22036 [(set (match_operand:V2SF 0 "register_operand" "=y")
22037 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22038 (parallel [(const_int 1) (const_int 0)])))]
22039 "TARGET_3DNOW_A"
22040 "pswapd\\t{%1, %0|%0, %1}"
22041 [(set_attr "type" "mmxcvt")
22042 (set_attr "mode" "TI")])
22043
22044 (define_expand "prefetch"
22045 [(prefetch (match_operand 0 "address_operand" "")
22046 (match_operand:SI 1 "const_int_operand" "")
22047 (match_operand:SI 2 "const_int_operand" ""))]
22048 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22049 {
22050 int rw = INTVAL (operands[1]);
22051 int locality = INTVAL (operands[2]);
22052
22053 if (rw != 0 && rw != 1)
22054 abort ();
22055 if (locality < 0 || locality > 3)
22056 abort ();
22057 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22058 abort ();
22059
22060 /* Use 3dNOW prefetch in case we are asking for write prefetch not
22061 suported by SSE counterpart or the SSE prefetch is not available
22062 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22063 of locality. */
22064 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22065 operands[2] = GEN_INT (3);
22066 else
22067 operands[1] = const0_rtx;
22068 })
22069
22070 (define_insn "*prefetch_sse"
22071 [(prefetch (match_operand:SI 0 "address_operand" "p")
22072 (const_int 0)
22073 (match_operand:SI 1 "const_int_operand" ""))]
22074 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22075 {
22076 static const char * const patterns[4] = {
22077 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22078 };
22079
22080 int locality = INTVAL (operands[1]);
22081 if (locality < 0 || locality > 3)
22082 abort ();
22083
22084 return patterns[locality];
22085 }
22086 [(set_attr "type" "sse")
22087 (set_attr "memory" "none")])
22088
22089 (define_insn "*prefetch_sse_rex"
22090 [(prefetch (match_operand:DI 0 "address_operand" "p")
22091 (const_int 0)
22092 (match_operand:SI 1 "const_int_operand" ""))]
22093 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22094 {
22095 static const char * const patterns[4] = {
22096 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22097 };
22098
22099 int locality = INTVAL (operands[1]);
22100 if (locality < 0 || locality > 3)
22101 abort ();
22102
22103 return patterns[locality];
22104 }
22105 [(set_attr "type" "sse")
22106 (set_attr "memory" "none")])
22107
22108 (define_insn "*prefetch_3dnow"
22109 [(prefetch (match_operand:SI 0 "address_operand" "p")
22110 (match_operand:SI 1 "const_int_operand" "n")
22111 (const_int 3))]
22112 "TARGET_3DNOW && !TARGET_64BIT"
22113 {
22114 if (INTVAL (operands[1]) == 0)
22115 return "prefetch\t%a0";
22116 else
22117 return "prefetchw\t%a0";
22118 }
22119 [(set_attr "type" "mmx")
22120 (set_attr "memory" "none")])
22121
22122 (define_insn "*prefetch_3dnow_rex"
22123 [(prefetch (match_operand:DI 0 "address_operand" "p")
22124 (match_operand:SI 1 "const_int_operand" "n")
22125 (const_int 3))]
22126 "TARGET_3DNOW && TARGET_64BIT"
22127 {
22128 if (INTVAL (operands[1]) == 0)
22129 return "prefetch\t%a0";
22130 else
22131 return "prefetchw\t%a0";
22132 }
22133 [(set_attr "type" "mmx")
22134 (set_attr "memory" "none")])
22135
22136 ;; SSE2 support
22137
22138 (define_insn "addv2df3"
22139 [(set (match_operand:V2DF 0 "register_operand" "=x")
22140 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22141 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22142 "TARGET_SSE2"
22143 "addpd\t{%2, %0|%0, %2}"
22144 [(set_attr "type" "sseadd")
22145 (set_attr "mode" "V2DF")])
22146
22147 (define_insn "vmaddv2df3"
22148 [(set (match_operand:V2DF 0 "register_operand" "=x")
22149 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22150 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22151 (match_dup 1)
22152 (const_int 1)))]
22153 "TARGET_SSE2"
22154 "addsd\t{%2, %0|%0, %2}"
22155 [(set_attr "type" "sseadd")
22156 (set_attr "mode" "DF")])
22157
22158 (define_insn "subv2df3"
22159 [(set (match_operand:V2DF 0 "register_operand" "=x")
22160 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22161 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22162 "TARGET_SSE2"
22163 "subpd\t{%2, %0|%0, %2}"
22164 [(set_attr "type" "sseadd")
22165 (set_attr "mode" "V2DF")])
22166
22167 (define_insn "vmsubv2df3"
22168 [(set (match_operand:V2DF 0 "register_operand" "=x")
22169 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22170 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22171 (match_dup 1)
22172 (const_int 1)))]
22173 "TARGET_SSE2"
22174 "subsd\t{%2, %0|%0, %2}"
22175 [(set_attr "type" "sseadd")
22176 (set_attr "mode" "DF")])
22177
22178 (define_insn "mulv2df3"
22179 [(set (match_operand:V2DF 0 "register_operand" "=x")
22180 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22181 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22182 "TARGET_SSE2"
22183 "mulpd\t{%2, %0|%0, %2}"
22184 [(set_attr "type" "ssemul")
22185 (set_attr "mode" "V2DF")])
22186
22187 (define_insn "vmmulv2df3"
22188 [(set (match_operand:V2DF 0 "register_operand" "=x")
22189 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22190 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22191 (match_dup 1)
22192 (const_int 1)))]
22193 "TARGET_SSE2"
22194 "mulsd\t{%2, %0|%0, %2}"
22195 [(set_attr "type" "ssemul")
22196 (set_attr "mode" "DF")])
22197
22198 (define_insn "divv2df3"
22199 [(set (match_operand:V2DF 0 "register_operand" "=x")
22200 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22201 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22202 "TARGET_SSE2"
22203 "divpd\t{%2, %0|%0, %2}"
22204 [(set_attr "type" "ssediv")
22205 (set_attr "mode" "V2DF")])
22206
22207 (define_insn "vmdivv2df3"
22208 [(set (match_operand:V2DF 0 "register_operand" "=x")
22209 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22210 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22211 (match_dup 1)
22212 (const_int 1)))]
22213 "TARGET_SSE2"
22214 "divsd\t{%2, %0|%0, %2}"
22215 [(set_attr "type" "ssediv")
22216 (set_attr "mode" "DF")])
22217
22218 ;; SSE min/max
22219
22220 (define_insn "smaxv2df3"
22221 [(set (match_operand:V2DF 0 "register_operand" "=x")
22222 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22223 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22224 "TARGET_SSE2"
22225 "maxpd\t{%2, %0|%0, %2}"
22226 [(set_attr "type" "sseadd")
22227 (set_attr "mode" "V2DF")])
22228
22229 (define_insn "vmsmaxv2df3"
22230 [(set (match_operand:V2DF 0 "register_operand" "=x")
22231 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22232 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22233 (match_dup 1)
22234 (const_int 1)))]
22235 "TARGET_SSE2"
22236 "maxsd\t{%2, %0|%0, %2}"
22237 [(set_attr "type" "sseadd")
22238 (set_attr "mode" "DF")])
22239
22240 (define_insn "sminv2df3"
22241 [(set (match_operand:V2DF 0 "register_operand" "=x")
22242 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22243 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22244 "TARGET_SSE2"
22245 "minpd\t{%2, %0|%0, %2}"
22246 [(set_attr "type" "sseadd")
22247 (set_attr "mode" "V2DF")])
22248
22249 (define_insn "vmsminv2df3"
22250 [(set (match_operand:V2DF 0 "register_operand" "=x")
22251 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22252 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22253 (match_dup 1)
22254 (const_int 1)))]
22255 "TARGET_SSE2"
22256 "minsd\t{%2, %0|%0, %2}"
22257 [(set_attr "type" "sseadd")
22258 (set_attr "mode" "DF")])
22259 ;; SSE2 square root. There doesn't appear to be an extension for the
22260 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22261
22262 (define_insn "sqrtv2df2"
22263 [(set (match_operand:V2DF 0 "register_operand" "=x")
22264 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22265 "TARGET_SSE2"
22266 "sqrtpd\t{%1, %0|%0, %1}"
22267 [(set_attr "type" "sse")
22268 (set_attr "mode" "V2DF")])
22269
22270 (define_insn "vmsqrtv2df2"
22271 [(set (match_operand:V2DF 0 "register_operand" "=x")
22272 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22273 (match_operand:V2DF 2 "register_operand" "0")
22274 (const_int 1)))]
22275 "TARGET_SSE2"
22276 "sqrtsd\t{%1, %0|%0, %1}"
22277 [(set_attr "type" "sse")
22278 (set_attr "mode" "SF")])
22279
22280 ;; SSE mask-generating compares
22281
22282 (define_insn "maskcmpv2df3"
22283 [(set (match_operand:V2DI 0 "register_operand" "=x")
22284 (match_operator:V2DI 3 "sse_comparison_operator"
22285 [(match_operand:V2DF 1 "register_operand" "0")
22286 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22287 "TARGET_SSE2"
22288 "cmp%D3pd\t{%2, %0|%0, %2}"
22289 [(set_attr "type" "ssecmp")
22290 (set_attr "mode" "V2DF")])
22291
22292 (define_insn "maskncmpv2df3"
22293 [(set (match_operand:V2DI 0 "register_operand" "=x")
22294 (not:V2DI
22295 (match_operator:V2DI 3 "sse_comparison_operator"
22296 [(match_operand:V2DF 1 "register_operand" "0")
22297 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22298 "TARGET_SSE2"
22299 {
22300 if (GET_CODE (operands[3]) == UNORDERED)
22301 return "cmpordps\t{%2, %0|%0, %2}";
22302 else
22303 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22304 }
22305 [(set_attr "type" "ssecmp")
22306 (set_attr "mode" "V2DF")])
22307
22308 (define_insn "vmmaskcmpv2df3"
22309 [(set (match_operand:V2DI 0 "register_operand" "=x")
22310 (vec_merge:V2DI
22311 (match_operator:V2DI 3 "sse_comparison_operator"
22312 [(match_operand:V2DF 1 "register_operand" "0")
22313 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22314 (subreg:V2DI (match_dup 1) 0)
22315 (const_int 1)))]
22316 "TARGET_SSE2"
22317 "cmp%D3sd\t{%2, %0|%0, %2}"
22318 [(set_attr "type" "ssecmp")
22319 (set_attr "mode" "DF")])
22320
22321 (define_insn "vmmaskncmpv2df3"
22322 [(set (match_operand:V2DI 0 "register_operand" "=x")
22323 (vec_merge:V2DI
22324 (not:V2DI
22325 (match_operator:V2DI 3 "sse_comparison_operator"
22326 [(match_operand:V2DF 1 "register_operand" "0")
22327 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22328 (subreg:V2DI (match_dup 1) 0)
22329 (const_int 1)))]
22330 "TARGET_SSE2"
22331 {
22332 if (GET_CODE (operands[3]) == UNORDERED)
22333 return "cmpordsd\t{%2, %0|%0, %2}";
22334 else
22335 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22336 }
22337 [(set_attr "type" "ssecmp")
22338 (set_attr "mode" "DF")])
22339
22340 (define_insn "sse2_comi"
22341 [(set (reg:CCFP 17)
22342 (compare:CCFP (vec_select:DF
22343 (match_operand:V2DF 0 "register_operand" "x")
22344 (parallel [(const_int 0)]))
22345 (vec_select:DF
22346 (match_operand:V2DF 1 "register_operand" "x")
22347 (parallel [(const_int 0)]))))]
22348 "TARGET_SSE2"
22349 "comisd\t{%1, %0|%0, %1}"
22350 [(set_attr "type" "ssecomi")
22351 (set_attr "mode" "DF")])
22352
22353 (define_insn "sse2_ucomi"
22354 [(set (reg:CCFPU 17)
22355 (compare:CCFPU (vec_select:DF
22356 (match_operand:V2DF 0 "register_operand" "x")
22357 (parallel [(const_int 0)]))
22358 (vec_select:DF
22359 (match_operand:V2DF 1 "register_operand" "x")
22360 (parallel [(const_int 0)]))))]
22361 "TARGET_SSE2"
22362 "ucomisd\t{%1, %0|%0, %1}"
22363 [(set_attr "type" "ssecomi")
22364 (set_attr "mode" "DF")])
22365
22366 ;; SSE Strange Moves.
22367
22368 (define_insn "sse2_movmskpd"
22369 [(set (match_operand:SI 0 "register_operand" "=r")
22370 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22371 UNSPEC_MOVMSK))]
22372 "TARGET_SSE2"
22373 "movmskpd\t{%1, %0|%0, %1}"
22374 [(set_attr "type" "ssecvt")
22375 (set_attr "mode" "V2DF")])
22376
22377 (define_insn "sse2_pmovmskb"
22378 [(set (match_operand:SI 0 "register_operand" "=r")
22379 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22380 UNSPEC_MOVMSK))]
22381 "TARGET_SSE2"
22382 "pmovmskb\t{%1, %0|%0, %1}"
22383 [(set_attr "type" "ssecvt")
22384 (set_attr "mode" "V2DF")])
22385
22386 (define_insn "sse2_maskmovdqu"
22387 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22388 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22389 (match_operand:V16QI 2 "register_operand" "x")]
22390 UNSPEC_MASKMOV))]
22391 "TARGET_SSE2"
22392 ;; @@@ check ordering of operands in intel/nonintel syntax
22393 "maskmovdqu\t{%2, %1|%1, %2}"
22394 [(set_attr "type" "ssecvt")
22395 (set_attr "mode" "TI")])
22396
22397 (define_insn "sse2_maskmovdqu_rex64"
22398 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22399 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22400 (match_operand:V16QI 2 "register_operand" "x")]
22401 UNSPEC_MASKMOV))]
22402 "TARGET_SSE2"
22403 ;; @@@ check ordering of operands in intel/nonintel syntax
22404 "maskmovdqu\t{%2, %1|%1, %2}"
22405 [(set_attr "type" "ssecvt")
22406 (set_attr "mode" "TI")])
22407
22408 (define_insn "sse2_movntv2df"
22409 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22410 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22411 UNSPEC_MOVNT))]
22412 "TARGET_SSE2"
22413 "movntpd\t{%1, %0|%0, %1}"
22414 [(set_attr "type" "ssecvt")
22415 (set_attr "mode" "V2DF")])
22416
22417 (define_insn "sse2_movntv2di"
22418 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22419 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22420 UNSPEC_MOVNT))]
22421 "TARGET_SSE2"
22422 "movntdq\t{%1, %0|%0, %1}"
22423 [(set_attr "type" "ssecvt")
22424 (set_attr "mode" "TI")])
22425
22426 (define_insn "sse2_movntsi"
22427 [(set (match_operand:SI 0 "memory_operand" "=m")
22428 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22429 UNSPEC_MOVNT))]
22430 "TARGET_SSE2"
22431 "movnti\t{%1, %0|%0, %1}"
22432 [(set_attr "type" "ssecvt")
22433 (set_attr "mode" "V2DF")])
22434
22435 ;; SSE <-> integer/MMX conversions
22436
22437 ;; Conversions between SI and SF
22438
22439 (define_insn "cvtdq2ps"
22440 [(set (match_operand:V4SF 0 "register_operand" "=x")
22441 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22442 "TARGET_SSE2"
22443 "cvtdq2ps\t{%1, %0|%0, %1}"
22444 [(set_attr "type" "ssecvt")
22445 (set_attr "mode" "V2DF")])
22446
22447 (define_insn "cvtps2dq"
22448 [(set (match_operand:V4SI 0 "register_operand" "=x")
22449 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22450 "TARGET_SSE2"
22451 "cvtps2dq\t{%1, %0|%0, %1}"
22452 [(set_attr "type" "ssecvt")
22453 (set_attr "mode" "TI")])
22454
22455 (define_insn "cvttps2dq"
22456 [(set (match_operand:V4SI 0 "register_operand" "=x")
22457 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22458 UNSPEC_FIX))]
22459 "TARGET_SSE2"
22460 "cvttps2dq\t{%1, %0|%0, %1}"
22461 [(set_attr "type" "ssecvt")
22462 (set_attr "mode" "TI")])
22463
22464 ;; Conversions between SI and DF
22465
22466 (define_insn "cvtdq2pd"
22467 [(set (match_operand:V2DF 0 "register_operand" "=x")
22468 (float:V2DF (vec_select:V2SI
22469 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22470 (parallel
22471 [(const_int 0)
22472 (const_int 1)]))))]
22473 "TARGET_SSE2"
22474 "cvtdq2pd\t{%1, %0|%0, %1}"
22475 [(set_attr "type" "ssecvt")
22476 (set_attr "mode" "V2DF")])
22477
22478 (define_insn "cvtpd2dq"
22479 [(set (match_operand:V4SI 0 "register_operand" "=x")
22480 (vec_concat:V4SI
22481 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22482 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22483 "TARGET_SSE2"
22484 "cvtpd2dq\t{%1, %0|%0, %1}"
22485 [(set_attr "type" "ssecvt")
22486 (set_attr "mode" "TI")])
22487
22488 (define_insn "cvttpd2dq"
22489 [(set (match_operand:V4SI 0 "register_operand" "=x")
22490 (vec_concat:V4SI
22491 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22492 UNSPEC_FIX)
22493 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22494 "TARGET_SSE2"
22495 "cvttpd2dq\t{%1, %0|%0, %1}"
22496 [(set_attr "type" "ssecvt")
22497 (set_attr "mode" "TI")])
22498
22499 (define_insn "cvtpd2pi"
22500 [(set (match_operand:V2SI 0 "register_operand" "=y")
22501 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22502 "TARGET_SSE2"
22503 "cvtpd2pi\t{%1, %0|%0, %1}"
22504 [(set_attr "type" "ssecvt")
22505 (set_attr "mode" "TI")])
22506
22507 (define_insn "cvttpd2pi"
22508 [(set (match_operand:V2SI 0 "register_operand" "=y")
22509 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22510 UNSPEC_FIX))]
22511 "TARGET_SSE2"
22512 "cvttpd2pi\t{%1, %0|%0, %1}"
22513 [(set_attr "type" "ssecvt")
22514 (set_attr "mode" "TI")])
22515
22516 (define_insn "cvtpi2pd"
22517 [(set (match_operand:V2DF 0 "register_operand" "=x")
22518 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22519 "TARGET_SSE2"
22520 "cvtpi2pd\t{%1, %0|%0, %1}"
22521 [(set_attr "type" "ssecvt")
22522 (set_attr "mode" "TI")])
22523
22524 ;; Conversions between SI and DF
22525
22526 (define_insn "cvtsd2si"
22527 [(set (match_operand:SI 0 "register_operand" "=r,r")
22528 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22529 (parallel [(const_int 0)]))))]
22530 "TARGET_SSE2"
22531 "cvtsd2si\t{%1, %0|%0, %1}"
22532 [(set_attr "type" "sseicvt")
22533 (set_attr "athlon_decode" "double,vector")
22534 (set_attr "mode" "SI")])
22535
22536 (define_insn "cvtsd2siq"
22537 [(set (match_operand:DI 0 "register_operand" "=r,r")
22538 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22539 (parallel [(const_int 0)]))))]
22540 "TARGET_SSE2 && TARGET_64BIT"
22541 "cvtsd2siq\t{%1, %0|%0, %1}"
22542 [(set_attr "type" "sseicvt")
22543 (set_attr "athlon_decode" "double,vector")
22544 (set_attr "mode" "DI")])
22545
22546 (define_insn "cvttsd2si"
22547 [(set (match_operand:SI 0 "register_operand" "=r,r")
22548 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22549 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22550 "TARGET_SSE2"
22551 "cvttsd2si\t{%1, %0|%0, %1}"
22552 [(set_attr "type" "sseicvt")
22553 (set_attr "mode" "SI")
22554 (set_attr "athlon_decode" "double,vector")])
22555
22556 (define_insn "cvttsd2siq"
22557 [(set (match_operand:DI 0 "register_operand" "=r,r")
22558 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22559 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22560 "TARGET_SSE2 && TARGET_64BIT"
22561 "cvttsd2siq\t{%1, %0|%0, %1}"
22562 [(set_attr "type" "sseicvt")
22563 (set_attr "mode" "DI")
22564 (set_attr "athlon_decode" "double,vector")])
22565
22566 (define_insn "cvtsi2sd"
22567 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22568 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22569 (vec_duplicate:V2DF
22570 (float:DF
22571 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22572 (const_int 2)))]
22573 "TARGET_SSE2"
22574 "cvtsi2sd\t{%2, %0|%0, %2}"
22575 [(set_attr "type" "sseicvt")
22576 (set_attr "mode" "DF")
22577 (set_attr "athlon_decode" "double,direct")])
22578
22579 (define_insn "cvtsi2sdq"
22580 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22581 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22582 (vec_duplicate:V2DF
22583 (float:DF
22584 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22585 (const_int 2)))]
22586 "TARGET_SSE2 && TARGET_64BIT"
22587 "cvtsi2sdq\t{%2, %0|%0, %2}"
22588 [(set_attr "type" "sseicvt")
22589 (set_attr "mode" "DF")
22590 (set_attr "athlon_decode" "double,direct")])
22591
22592 ;; Conversions between SF and DF
22593
22594 (define_insn "cvtsd2ss"
22595 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22596 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22597 (vec_duplicate:V4SF
22598 (float_truncate:V2SF
22599 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22600 (const_int 14)))]
22601 "TARGET_SSE2"
22602 "cvtsd2ss\t{%2, %0|%0, %2}"
22603 [(set_attr "type" "ssecvt")
22604 (set_attr "athlon_decode" "vector,double")
22605 (set_attr "mode" "SF")])
22606
22607 (define_insn "cvtss2sd"
22608 [(set (match_operand:V2DF 0 "register_operand" "=x")
22609 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22610 (float_extend:V2DF
22611 (vec_select:V2SF
22612 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22613 (parallel [(const_int 0)
22614 (const_int 1)])))
22615 (const_int 2)))]
22616 "TARGET_SSE2"
22617 "cvtss2sd\t{%2, %0|%0, %2}"
22618 [(set_attr "type" "ssecvt")
22619 (set_attr "mode" "DF")])
22620
22621 (define_insn "cvtpd2ps"
22622 [(set (match_operand:V4SF 0 "register_operand" "=x")
22623 (subreg:V4SF
22624 (vec_concat:V4SI
22625 (subreg:V2SI (float_truncate:V2SF
22626 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22627 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22628 "TARGET_SSE2"
22629 "cvtpd2ps\t{%1, %0|%0, %1}"
22630 [(set_attr "type" "ssecvt")
22631 (set_attr "mode" "V4SF")])
22632
22633 (define_insn "cvtps2pd"
22634 [(set (match_operand:V2DF 0 "register_operand" "=x")
22635 (float_extend:V2DF
22636 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22637 (parallel [(const_int 0)
22638 (const_int 1)]))))]
22639 "TARGET_SSE2"
22640 "cvtps2pd\t{%1, %0|%0, %1}"
22641 [(set_attr "type" "ssecvt")
22642 (set_attr "mode" "V2DF")])
22643
22644 ;; SSE2 variants of MMX insns
22645
22646 ;; MMX arithmetic
22647
22648 (define_insn "addv16qi3"
22649 [(set (match_operand:V16QI 0 "register_operand" "=x")
22650 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22651 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22652 "TARGET_SSE2"
22653 "paddb\t{%2, %0|%0, %2}"
22654 [(set_attr "type" "sseiadd")
22655 (set_attr "mode" "TI")])
22656
22657 (define_insn "addv8hi3"
22658 [(set (match_operand:V8HI 0 "register_operand" "=x")
22659 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22660 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22661 "TARGET_SSE2"
22662 "paddw\t{%2, %0|%0, %2}"
22663 [(set_attr "type" "sseiadd")
22664 (set_attr "mode" "TI")])
22665
22666 (define_insn "addv4si3"
22667 [(set (match_operand:V4SI 0 "register_operand" "=x")
22668 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22669 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22670 "TARGET_SSE2"
22671 "paddd\t{%2, %0|%0, %2}"
22672 [(set_attr "type" "sseiadd")
22673 (set_attr "mode" "TI")])
22674
22675 (define_insn "addv2di3"
22676 [(set (match_operand:V2DI 0 "register_operand" "=x")
22677 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22678 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22679 "TARGET_SSE2"
22680 "paddq\t{%2, %0|%0, %2}"
22681 [(set_attr "type" "sseiadd")
22682 (set_attr "mode" "TI")])
22683
22684 (define_insn "ssaddv16qi3"
22685 [(set (match_operand:V16QI 0 "register_operand" "=x")
22686 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22687 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22688 "TARGET_SSE2"
22689 "paddsb\t{%2, %0|%0, %2}"
22690 [(set_attr "type" "sseiadd")
22691 (set_attr "mode" "TI")])
22692
22693 (define_insn "ssaddv8hi3"
22694 [(set (match_operand:V8HI 0 "register_operand" "=x")
22695 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22696 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22697 "TARGET_SSE2"
22698 "paddsw\t{%2, %0|%0, %2}"
22699 [(set_attr "type" "sseiadd")
22700 (set_attr "mode" "TI")])
22701
22702 (define_insn "usaddv16qi3"
22703 [(set (match_operand:V16QI 0 "register_operand" "=x")
22704 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22705 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22706 "TARGET_SSE2"
22707 "paddusb\t{%2, %0|%0, %2}"
22708 [(set_attr "type" "sseiadd")
22709 (set_attr "mode" "TI")])
22710
22711 (define_insn "usaddv8hi3"
22712 [(set (match_operand:V8HI 0 "register_operand" "=x")
22713 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22714 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22715 "TARGET_SSE2"
22716 "paddusw\t{%2, %0|%0, %2}"
22717 [(set_attr "type" "sseiadd")
22718 (set_attr "mode" "TI")])
22719
22720 (define_insn "subv16qi3"
22721 [(set (match_operand:V16QI 0 "register_operand" "=x")
22722 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22723 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22724 "TARGET_SSE2"
22725 "psubb\t{%2, %0|%0, %2}"
22726 [(set_attr "type" "sseiadd")
22727 (set_attr "mode" "TI")])
22728
22729 (define_insn "subv8hi3"
22730 [(set (match_operand:V8HI 0 "register_operand" "=x")
22731 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22732 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22733 "TARGET_SSE2"
22734 "psubw\t{%2, %0|%0, %2}"
22735 [(set_attr "type" "sseiadd")
22736 (set_attr "mode" "TI")])
22737
22738 (define_insn "subv4si3"
22739 [(set (match_operand:V4SI 0 "register_operand" "=x")
22740 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22741 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22742 "TARGET_SSE2"
22743 "psubd\t{%2, %0|%0, %2}"
22744 [(set_attr "type" "sseiadd")
22745 (set_attr "mode" "TI")])
22746
22747 (define_insn "subv2di3"
22748 [(set (match_operand:V2DI 0 "register_operand" "=x")
22749 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22750 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22751 "TARGET_SSE2"
22752 "psubq\t{%2, %0|%0, %2}"
22753 [(set_attr "type" "sseiadd")
22754 (set_attr "mode" "TI")])
22755
22756 (define_insn "sssubv16qi3"
22757 [(set (match_operand:V16QI 0 "register_operand" "=x")
22758 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22759 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22760 "TARGET_SSE2"
22761 "psubsb\t{%2, %0|%0, %2}"
22762 [(set_attr "type" "sseiadd")
22763 (set_attr "mode" "TI")])
22764
22765 (define_insn "sssubv8hi3"
22766 [(set (match_operand:V8HI 0 "register_operand" "=x")
22767 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22768 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22769 "TARGET_SSE2"
22770 "psubsw\t{%2, %0|%0, %2}"
22771 [(set_attr "type" "sseiadd")
22772 (set_attr "mode" "TI")])
22773
22774 (define_insn "ussubv16qi3"
22775 [(set (match_operand:V16QI 0 "register_operand" "=x")
22776 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22777 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22778 "TARGET_SSE2"
22779 "psubusb\t{%2, %0|%0, %2}"
22780 [(set_attr "type" "sseiadd")
22781 (set_attr "mode" "TI")])
22782
22783 (define_insn "ussubv8hi3"
22784 [(set (match_operand:V8HI 0 "register_operand" "=x")
22785 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22786 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22787 "TARGET_SSE2"
22788 "psubusw\t{%2, %0|%0, %2}"
22789 [(set_attr "type" "sseiadd")
22790 (set_attr "mode" "TI")])
22791
22792 (define_insn "mulv8hi3"
22793 [(set (match_operand:V8HI 0 "register_operand" "=x")
22794 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22795 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22796 "TARGET_SSE2"
22797 "pmullw\t{%2, %0|%0, %2}"
22798 [(set_attr "type" "sseimul")
22799 (set_attr "mode" "TI")])
22800
22801 (define_insn "smulv8hi3_highpart"
22802 [(set (match_operand:V8HI 0 "register_operand" "=x")
22803 (truncate:V8HI
22804 (lshiftrt:V8SI
22805 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22806 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22807 (const_int 16))))]
22808 "TARGET_SSE2"
22809 "pmulhw\t{%2, %0|%0, %2}"
22810 [(set_attr "type" "sseimul")
22811 (set_attr "mode" "TI")])
22812
22813 (define_insn "umulv8hi3_highpart"
22814 [(set (match_operand:V8HI 0 "register_operand" "=x")
22815 (truncate:V8HI
22816 (lshiftrt:V8SI
22817 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22818 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22819 (const_int 16))))]
22820 "TARGET_SSE2"
22821 "pmulhuw\t{%2, %0|%0, %2}"
22822 [(set_attr "type" "sseimul")
22823 (set_attr "mode" "TI")])
22824
22825 (define_insn "sse2_umulsidi3"
22826 [(set (match_operand:DI 0 "register_operand" "=y")
22827 (mult:DI (zero_extend:DI (vec_select:SI
22828 (match_operand:V2SI 1 "register_operand" "0")
22829 (parallel [(const_int 0)])))
22830 (zero_extend:DI (vec_select:SI
22831 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22832 (parallel [(const_int 0)])))))]
22833 "TARGET_SSE2"
22834 "pmuludq\t{%2, %0|%0, %2}"
22835 [(set_attr "type" "sseimul")
22836 (set_attr "mode" "TI")])
22837
22838 (define_insn "sse2_umulv2siv2di3"
22839 [(set (match_operand:V2DI 0 "register_operand" "=x")
22840 (mult:V2DI (zero_extend:V2DI
22841 (vec_select:V2SI
22842 (match_operand:V4SI 1 "register_operand" "0")
22843 (parallel [(const_int 0) (const_int 2)])))
22844 (zero_extend:V2DI
22845 (vec_select:V2SI
22846 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22847 (parallel [(const_int 0) (const_int 2)])))))]
22848 "TARGET_SSE2"
22849 "pmuludq\t{%2, %0|%0, %2}"
22850 [(set_attr "type" "sseimul")
22851 (set_attr "mode" "TI")])
22852
22853 (define_insn "sse2_pmaddwd"
22854 [(set (match_operand:V4SI 0 "register_operand" "=x")
22855 (plus:V4SI
22856 (mult:V4SI
22857 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22858 (parallel [(const_int 0)
22859 (const_int 2)
22860 (const_int 4)
22861 (const_int 6)])))
22862 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22863 (parallel [(const_int 0)
22864 (const_int 2)
22865 (const_int 4)
22866 (const_int 6)]))))
22867 (mult:V4SI
22868 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22869 (parallel [(const_int 1)
22870 (const_int 3)
22871 (const_int 5)
22872 (const_int 7)])))
22873 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22874 (parallel [(const_int 1)
22875 (const_int 3)
22876 (const_int 5)
22877 (const_int 7)]))))))]
22878 "TARGET_SSE2"
22879 "pmaddwd\t{%2, %0|%0, %2}"
22880 [(set_attr "type" "sseiadd")
22881 (set_attr "mode" "TI")])
22882
22883 ;; Same as pxor, but don't show input operands so that we don't think
22884 ;; they are live.
22885 (define_insn "sse2_clrti"
22886 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22887 "TARGET_SSE2"
22888 {
22889 if (get_attr_mode (insn) == MODE_TI)
22890 return "pxor\t%0, %0";
22891 else
22892 return "xorps\t%0, %0";
22893 }
22894 [(set_attr "type" "ssemov")
22895 (set_attr "memory" "none")
22896 (set (attr "mode")
22897 (if_then_else
22898 (ne (symbol_ref "optimize_size")
22899 (const_int 0))
22900 (const_string "V4SF")
22901 (const_string "TI")))])
22902
22903 ;; MMX unsigned averages/sum of absolute differences
22904
22905 (define_insn "sse2_uavgv16qi3"
22906 [(set (match_operand:V16QI 0 "register_operand" "=x")
22907 (ashiftrt:V16QI
22908 (plus:V16QI (plus:V16QI
22909 (match_operand:V16QI 1 "register_operand" "0")
22910 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22911 (const_vector:V16QI [(const_int 1) (const_int 1)
22912 (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)))]
22920 "TARGET_SSE2"
22921 "pavgb\t{%2, %0|%0, %2}"
22922 [(set_attr "type" "sseiadd")
22923 (set_attr "mode" "TI")])
22924
22925 (define_insn "sse2_uavgv8hi3"
22926 [(set (match_operand:V8HI 0 "register_operand" "=x")
22927 (ashiftrt:V8HI
22928 (plus:V8HI (plus:V8HI
22929 (match_operand:V8HI 1 "register_operand" "0")
22930 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22931 (const_vector:V8HI [(const_int 1) (const_int 1)
22932 (const_int 1) (const_int 1)
22933 (const_int 1) (const_int 1)
22934 (const_int 1) (const_int 1)]))
22935 (const_int 1)))]
22936 "TARGET_SSE2"
22937 "pavgw\t{%2, %0|%0, %2}"
22938 [(set_attr "type" "sseiadd")
22939 (set_attr "mode" "TI")])
22940
22941 ;; @@@ this isn't the right representation.
22942 (define_insn "sse2_psadbw"
22943 [(set (match_operand:V2DI 0 "register_operand" "=x")
22944 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22945 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22946 UNSPEC_PSADBW))]
22947 "TARGET_SSE2"
22948 "psadbw\t{%2, %0|%0, %2}"
22949 [(set_attr "type" "sseiadd")
22950 (set_attr "mode" "TI")])
22951
22952
22953 ;; MMX insert/extract/shuffle
22954
22955 (define_insn "sse2_pinsrw"
22956 [(set (match_operand:V8HI 0 "register_operand" "=x")
22957 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22958 (vec_duplicate:V8HI
22959 (truncate:HI
22960 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22961 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22962 "TARGET_SSE2"
22963 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22964 [(set_attr "type" "ssecvt")
22965 (set_attr "mode" "TI")])
22966
22967 (define_insn "sse2_pextrw"
22968 [(set (match_operand:SI 0 "register_operand" "=r")
22969 (zero_extend:SI
22970 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22971 (parallel
22972 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22973 "TARGET_SSE2"
22974 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22975 [(set_attr "type" "ssecvt")
22976 (set_attr "mode" "TI")])
22977
22978 (define_insn "sse2_pshufd"
22979 [(set (match_operand:V4SI 0 "register_operand" "=x")
22980 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22981 (match_operand:SI 2 "immediate_operand" "i")]
22982 UNSPEC_SHUFFLE))]
22983 "TARGET_SSE2"
22984 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22985 [(set_attr "type" "ssecvt")
22986 (set_attr "mode" "TI")])
22987
22988 (define_insn "sse2_pshuflw"
22989 [(set (match_operand:V8HI 0 "register_operand" "=x")
22990 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22991 (match_operand:SI 2 "immediate_operand" "i")]
22992 UNSPEC_PSHUFLW))]
22993 "TARGET_SSE2"
22994 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22995 [(set_attr "type" "ssecvt")
22996 (set_attr "mode" "TI")])
22997
22998 (define_insn "sse2_pshufhw"
22999 [(set (match_operand:V8HI 0 "register_operand" "=x")
23000 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
23001 (match_operand:SI 2 "immediate_operand" "i")]
23002 UNSPEC_PSHUFHW))]
23003 "TARGET_SSE2"
23004 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23005 [(set_attr "type" "ssecvt")
23006 (set_attr "mode" "TI")])
23007
23008 ;; MMX mask-generating comparisons
23009
23010 (define_insn "eqv16qi3"
23011 [(set (match_operand:V16QI 0 "register_operand" "=x")
23012 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23013 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23014 "TARGET_SSE2"
23015 "pcmpeqb\t{%2, %0|%0, %2}"
23016 [(set_attr "type" "ssecmp")
23017 (set_attr "mode" "TI")])
23018
23019 (define_insn "eqv8hi3"
23020 [(set (match_operand:V8HI 0 "register_operand" "=x")
23021 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23022 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23023 "TARGET_SSE2"
23024 "pcmpeqw\t{%2, %0|%0, %2}"
23025 [(set_attr "type" "ssecmp")
23026 (set_attr "mode" "TI")])
23027
23028 (define_insn "eqv4si3"
23029 [(set (match_operand:V4SI 0 "register_operand" "=x")
23030 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23031 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23032 "TARGET_SSE2"
23033 "pcmpeqd\t{%2, %0|%0, %2}"
23034 [(set_attr "type" "ssecmp")
23035 (set_attr "mode" "TI")])
23036
23037 (define_insn "gtv16qi3"
23038 [(set (match_operand:V16QI 0 "register_operand" "=x")
23039 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23040 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23041 "TARGET_SSE2"
23042 "pcmpgtb\t{%2, %0|%0, %2}"
23043 [(set_attr "type" "ssecmp")
23044 (set_attr "mode" "TI")])
23045
23046 (define_insn "gtv8hi3"
23047 [(set (match_operand:V8HI 0 "register_operand" "=x")
23048 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23049 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23050 "TARGET_SSE2"
23051 "pcmpgtw\t{%2, %0|%0, %2}"
23052 [(set_attr "type" "ssecmp")
23053 (set_attr "mode" "TI")])
23054
23055 (define_insn "gtv4si3"
23056 [(set (match_operand:V4SI 0 "register_operand" "=x")
23057 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23058 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23059 "TARGET_SSE2"
23060 "pcmpgtd\t{%2, %0|%0, %2}"
23061 [(set_attr "type" "ssecmp")
23062 (set_attr "mode" "TI")])
23063
23064
23065 ;; MMX max/min insns
23066
23067 (define_insn "umaxv16qi3"
23068 [(set (match_operand:V16QI 0 "register_operand" "=x")
23069 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23070 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23071 "TARGET_SSE2"
23072 "pmaxub\t{%2, %0|%0, %2}"
23073 [(set_attr "type" "sseiadd")
23074 (set_attr "mode" "TI")])
23075
23076 (define_insn "smaxv8hi3"
23077 [(set (match_operand:V8HI 0 "register_operand" "=x")
23078 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23079 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23080 "TARGET_SSE2"
23081 "pmaxsw\t{%2, %0|%0, %2}"
23082 [(set_attr "type" "sseiadd")
23083 (set_attr "mode" "TI")])
23084
23085 (define_insn "uminv16qi3"
23086 [(set (match_operand:V16QI 0 "register_operand" "=x")
23087 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23088 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23089 "TARGET_SSE2"
23090 "pminub\t{%2, %0|%0, %2}"
23091 [(set_attr "type" "sseiadd")
23092 (set_attr "mode" "TI")])
23093
23094 (define_insn "sminv8hi3"
23095 [(set (match_operand:V8HI 0 "register_operand" "=x")
23096 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23097 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23098 "TARGET_SSE2"
23099 "pminsw\t{%2, %0|%0, %2}"
23100 [(set_attr "type" "sseiadd")
23101 (set_attr "mode" "TI")])
23102
23103
23104 ;; MMX shifts
23105
23106 (define_insn "ashrv8hi3"
23107 [(set (match_operand:V8HI 0 "register_operand" "=x")
23108 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23109 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23110 "TARGET_SSE2"
23111 "psraw\t{%2, %0|%0, %2}"
23112 [(set_attr "type" "sseishft")
23113 (set_attr "mode" "TI")])
23114
23115 (define_insn "ashrv4si3"
23116 [(set (match_operand:V4SI 0 "register_operand" "=x")
23117 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23118 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23119 "TARGET_SSE2"
23120 "psrad\t{%2, %0|%0, %2}"
23121 [(set_attr "type" "sseishft")
23122 (set_attr "mode" "TI")])
23123
23124 (define_insn "lshrv8hi3"
23125 [(set (match_operand:V8HI 0 "register_operand" "=x")
23126 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23127 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23128 "TARGET_SSE2"
23129 "psrlw\t{%2, %0|%0, %2}"
23130 [(set_attr "type" "sseishft")
23131 (set_attr "mode" "TI")])
23132
23133 (define_insn "lshrv4si3"
23134 [(set (match_operand:V4SI 0 "register_operand" "=x")
23135 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23136 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23137 "TARGET_SSE2"
23138 "psrld\t{%2, %0|%0, %2}"
23139 [(set_attr "type" "sseishft")
23140 (set_attr "mode" "TI")])
23141
23142 (define_insn "lshrv2di3"
23143 [(set (match_operand:V2DI 0 "register_operand" "=x")
23144 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23145 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23146 "TARGET_SSE2"
23147 "psrlq\t{%2, %0|%0, %2}"
23148 [(set_attr "type" "sseishft")
23149 (set_attr "mode" "TI")])
23150
23151 (define_insn "ashlv8hi3"
23152 [(set (match_operand:V8HI 0 "register_operand" "=x")
23153 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23154 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23155 "TARGET_SSE2"
23156 "psllw\t{%2, %0|%0, %2}"
23157 [(set_attr "type" "sseishft")
23158 (set_attr "mode" "TI")])
23159
23160 (define_insn "ashlv4si3"
23161 [(set (match_operand:V4SI 0 "register_operand" "=x")
23162 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23163 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23164 "TARGET_SSE2"
23165 "pslld\t{%2, %0|%0, %2}"
23166 [(set_attr "type" "sseishft")
23167 (set_attr "mode" "TI")])
23168
23169 (define_insn "ashlv2di3"
23170 [(set (match_operand:V2DI 0 "register_operand" "=x")
23171 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23172 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23173 "TARGET_SSE2"
23174 "psllq\t{%2, %0|%0, %2}"
23175 [(set_attr "type" "sseishft")
23176 (set_attr "mode" "TI")])
23177
23178 (define_insn "ashrv8hi3_ti"
23179 [(set (match_operand:V8HI 0 "register_operand" "=x")
23180 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23181 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23182 "TARGET_SSE2"
23183 "psraw\t{%2, %0|%0, %2}"
23184 [(set_attr "type" "sseishft")
23185 (set_attr "mode" "TI")])
23186
23187 (define_insn "ashrv4si3_ti"
23188 [(set (match_operand:V4SI 0 "register_operand" "=x")
23189 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23190 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23191 "TARGET_SSE2"
23192 "psrad\t{%2, %0|%0, %2}"
23193 [(set_attr "type" "sseishft")
23194 (set_attr "mode" "TI")])
23195
23196 (define_insn "lshrv8hi3_ti"
23197 [(set (match_operand:V8HI 0 "register_operand" "=x")
23198 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23199 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23200 "TARGET_SSE2"
23201 "psrlw\t{%2, %0|%0, %2}"
23202 [(set_attr "type" "sseishft")
23203 (set_attr "mode" "TI")])
23204
23205 (define_insn "lshrv4si3_ti"
23206 [(set (match_operand:V4SI 0 "register_operand" "=x")
23207 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23208 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23209 "TARGET_SSE2"
23210 "psrld\t{%2, %0|%0, %2}"
23211 [(set_attr "type" "sseishft")
23212 (set_attr "mode" "TI")])
23213
23214 (define_insn "lshrv2di3_ti"
23215 [(set (match_operand:V2DI 0 "register_operand" "=x")
23216 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23217 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23218 "TARGET_SSE2"
23219 "psrlq\t{%2, %0|%0, %2}"
23220 [(set_attr "type" "sseishft")
23221 (set_attr "mode" "TI")])
23222
23223 (define_insn "ashlv8hi3_ti"
23224 [(set (match_operand:V8HI 0 "register_operand" "=x")
23225 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23226 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23227 "TARGET_SSE2"
23228 "psllw\t{%2, %0|%0, %2}"
23229 [(set_attr "type" "sseishft")
23230 (set_attr "mode" "TI")])
23231
23232 (define_insn "ashlv4si3_ti"
23233 [(set (match_operand:V4SI 0 "register_operand" "=x")
23234 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23235 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23236 "TARGET_SSE2"
23237 "pslld\t{%2, %0|%0, %2}"
23238 [(set_attr "type" "sseishft")
23239 (set_attr "mode" "TI")])
23240
23241 (define_insn "ashlv2di3_ti"
23242 [(set (match_operand:V2DI 0 "register_operand" "=x")
23243 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23244 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23245 "TARGET_SSE2"
23246 "psllq\t{%2, %0|%0, %2}"
23247 [(set_attr "type" "sseishft")
23248 (set_attr "mode" "TI")])
23249
23250 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23251 ;; we wouldn't need here it since we never generate TImode arithmetic.
23252
23253 ;; There has to be some kind of prize for the weirdest new instruction...
23254 (define_insn "sse2_ashlti3"
23255 [(set (match_operand:TI 0 "register_operand" "=x")
23256 (unspec:TI
23257 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23258 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23259 (const_int 8)))] UNSPEC_NOP))]
23260 "TARGET_SSE2"
23261 "pslldq\t{%2, %0|%0, %2}"
23262 [(set_attr "type" "sseishft")
23263 (set_attr "mode" "TI")])
23264
23265 (define_insn "sse2_lshrti3"
23266 [(set (match_operand:TI 0 "register_operand" "=x")
23267 (unspec:TI
23268 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23269 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23270 (const_int 8)))] UNSPEC_NOP))]
23271 "TARGET_SSE2"
23272 "psrldq\t{%2, %0|%0, %2}"
23273 [(set_attr "type" "sseishft")
23274 (set_attr "mode" "TI")])
23275
23276 ;; SSE unpack
23277
23278 (define_insn "sse2_unpckhpd"
23279 [(set (match_operand:V2DF 0 "register_operand" "=x")
23280 (vec_concat:V2DF
23281 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23282 (parallel [(const_int 1)]))
23283 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23284 (parallel [(const_int 0)]))))]
23285 "TARGET_SSE2"
23286 "unpckhpd\t{%2, %0|%0, %2}"
23287 [(set_attr "type" "ssecvt")
23288 (set_attr "mode" "TI")])
23289
23290 (define_insn "sse2_unpcklpd"
23291 [(set (match_operand:V2DF 0 "register_operand" "=x")
23292 (vec_concat:V2DF
23293 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23294 (parallel [(const_int 0)]))
23295 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23296 (parallel [(const_int 1)]))))]
23297 "TARGET_SSE2"
23298 "unpcklpd\t{%2, %0|%0, %2}"
23299 [(set_attr "type" "ssecvt")
23300 (set_attr "mode" "TI")])
23301
23302 ;; MMX pack/unpack insns.
23303
23304 (define_insn "sse2_packsswb"
23305 [(set (match_operand:V16QI 0 "register_operand" "=x")
23306 (vec_concat:V16QI
23307 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23308 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23309 "TARGET_SSE2"
23310 "packsswb\t{%2, %0|%0, %2}"
23311 [(set_attr "type" "ssecvt")
23312 (set_attr "mode" "TI")])
23313
23314 (define_insn "sse2_packssdw"
23315 [(set (match_operand:V8HI 0 "register_operand" "=x")
23316 (vec_concat:V8HI
23317 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23318 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23319 "TARGET_SSE2"
23320 "packssdw\t{%2, %0|%0, %2}"
23321 [(set_attr "type" "ssecvt")
23322 (set_attr "mode" "TI")])
23323
23324 (define_insn "sse2_packuswb"
23325 [(set (match_operand:V16QI 0 "register_operand" "=x")
23326 (vec_concat:V16QI
23327 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23328 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23329 "TARGET_SSE2"
23330 "packuswb\t{%2, %0|%0, %2}"
23331 [(set_attr "type" "ssecvt")
23332 (set_attr "mode" "TI")])
23333
23334 (define_insn "sse2_punpckhbw"
23335 [(set (match_operand:V16QI 0 "register_operand" "=x")
23336 (vec_merge:V16QI
23337 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23338 (parallel [(const_int 8) (const_int 0)
23339 (const_int 9) (const_int 1)
23340 (const_int 10) (const_int 2)
23341 (const_int 11) (const_int 3)
23342 (const_int 12) (const_int 4)
23343 (const_int 13) (const_int 5)
23344 (const_int 14) (const_int 6)
23345 (const_int 15) (const_int 7)]))
23346 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23347 (parallel [(const_int 0) (const_int 8)
23348 (const_int 1) (const_int 9)
23349 (const_int 2) (const_int 10)
23350 (const_int 3) (const_int 11)
23351 (const_int 4) (const_int 12)
23352 (const_int 5) (const_int 13)
23353 (const_int 6) (const_int 14)
23354 (const_int 7) (const_int 15)]))
23355 (const_int 21845)))]
23356 "TARGET_SSE2"
23357 "punpckhbw\t{%2, %0|%0, %2}"
23358 [(set_attr "type" "ssecvt")
23359 (set_attr "mode" "TI")])
23360
23361 (define_insn "sse2_punpckhwd"
23362 [(set (match_operand:V8HI 0 "register_operand" "=x")
23363 (vec_merge:V8HI
23364 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23365 (parallel [(const_int 4) (const_int 0)
23366 (const_int 5) (const_int 1)
23367 (const_int 6) (const_int 2)
23368 (const_int 7) (const_int 3)]))
23369 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23370 (parallel [(const_int 0) (const_int 4)
23371 (const_int 1) (const_int 5)
23372 (const_int 2) (const_int 6)
23373 (const_int 3) (const_int 7)]))
23374 (const_int 85)))]
23375 "TARGET_SSE2"
23376 "punpckhwd\t{%2, %0|%0, %2}"
23377 [(set_attr "type" "ssecvt")
23378 (set_attr "mode" "TI")])
23379
23380 (define_insn "sse2_punpckhdq"
23381 [(set (match_operand:V4SI 0 "register_operand" "=x")
23382 (vec_merge:V4SI
23383 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23384 (parallel [(const_int 2) (const_int 0)
23385 (const_int 3) (const_int 1)]))
23386 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23387 (parallel [(const_int 0) (const_int 2)
23388 (const_int 1) (const_int 3)]))
23389 (const_int 5)))]
23390 "TARGET_SSE2"
23391 "punpckhdq\t{%2, %0|%0, %2}"
23392 [(set_attr "type" "ssecvt")
23393 (set_attr "mode" "TI")])
23394
23395 (define_insn "sse2_punpcklbw"
23396 [(set (match_operand:V16QI 0 "register_operand" "=x")
23397 (vec_merge:V16QI
23398 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23399 (parallel [(const_int 0) (const_int 8)
23400 (const_int 1) (const_int 9)
23401 (const_int 2) (const_int 10)
23402 (const_int 3) (const_int 11)
23403 (const_int 4) (const_int 12)
23404 (const_int 5) (const_int 13)
23405 (const_int 6) (const_int 14)
23406 (const_int 7) (const_int 15)]))
23407 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23408 (parallel [(const_int 8) (const_int 0)
23409 (const_int 9) (const_int 1)
23410 (const_int 10) (const_int 2)
23411 (const_int 11) (const_int 3)
23412 (const_int 12) (const_int 4)
23413 (const_int 13) (const_int 5)
23414 (const_int 14) (const_int 6)
23415 (const_int 15) (const_int 7)]))
23416 (const_int 21845)))]
23417 "TARGET_SSE2"
23418 "punpcklbw\t{%2, %0|%0, %2}"
23419 [(set_attr "type" "ssecvt")
23420 (set_attr "mode" "TI")])
23421
23422 (define_insn "sse2_punpcklwd"
23423 [(set (match_operand:V8HI 0 "register_operand" "=x")
23424 (vec_merge:V8HI
23425 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23426 (parallel [(const_int 0) (const_int 4)
23427 (const_int 1) (const_int 5)
23428 (const_int 2) (const_int 6)
23429 (const_int 3) (const_int 7)]))
23430 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23431 (parallel [(const_int 4) (const_int 0)
23432 (const_int 5) (const_int 1)
23433 (const_int 6) (const_int 2)
23434 (const_int 7) (const_int 3)]))
23435 (const_int 85)))]
23436 "TARGET_SSE2"
23437 "punpcklwd\t{%2, %0|%0, %2}"
23438 [(set_attr "type" "ssecvt")
23439 (set_attr "mode" "TI")])
23440
23441 (define_insn "sse2_punpckldq"
23442 [(set (match_operand:V4SI 0 "register_operand" "=x")
23443 (vec_merge:V4SI
23444 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23445 (parallel [(const_int 0) (const_int 2)
23446 (const_int 1) (const_int 3)]))
23447 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23448 (parallel [(const_int 2) (const_int 0)
23449 (const_int 3) (const_int 1)]))
23450 (const_int 5)))]
23451 "TARGET_SSE2"
23452 "punpckldq\t{%2, %0|%0, %2}"
23453 [(set_attr "type" "ssecvt")
23454 (set_attr "mode" "TI")])
23455
23456 (define_insn "sse2_punpcklqdq"
23457 [(set (match_operand:V2DI 0 "register_operand" "=x")
23458 (vec_merge:V2DI
23459 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23460 (parallel [(const_int 1)
23461 (const_int 0)]))
23462 (match_operand:V2DI 1 "register_operand" "0")
23463 (const_int 1)))]
23464 "TARGET_SSE2"
23465 "punpcklqdq\t{%2, %0|%0, %2}"
23466 [(set_attr "type" "ssecvt")
23467 (set_attr "mode" "TI")])
23468
23469 (define_insn "sse2_punpckhqdq"
23470 [(set (match_operand:V2DI 0 "register_operand" "=x")
23471 (vec_merge:V2DI
23472 (match_operand:V2DI 1 "register_operand" "0")
23473 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23474 (parallel [(const_int 1)
23475 (const_int 0)]))
23476 (const_int 1)))]
23477 "TARGET_SSE2"
23478 "punpckhqdq\t{%2, %0|%0, %2}"
23479 [(set_attr "type" "ssecvt")
23480 (set_attr "mode" "TI")])
23481
23482 ;; SSE2 moves
23483
23484 (define_insn "sse2_movapd"
23485 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23486 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23487 UNSPEC_MOVA))]
23488 "TARGET_SSE2
23489 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23490 "movapd\t{%1, %0|%0, %1}"
23491 [(set_attr "type" "ssemov")
23492 (set_attr "mode" "V2DF")])
23493
23494 (define_insn "sse2_movupd"
23495 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23496 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23497 UNSPEC_MOVU))]
23498 "TARGET_SSE2
23499 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23500 "movupd\t{%1, %0|%0, %1}"
23501 [(set_attr "type" "ssecvt")
23502 (set_attr "mode" "V2DF")])
23503
23504 (define_insn "sse2_movdqa"
23505 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23506 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23507 UNSPEC_MOVA))]
23508 "TARGET_SSE2
23509 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23510 "movdqa\t{%1, %0|%0, %1}"
23511 [(set_attr "type" "ssemov")
23512 (set_attr "mode" "TI")])
23513
23514 (define_insn "sse2_movdqu"
23515 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23516 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23517 UNSPEC_MOVU))]
23518 "TARGET_SSE2
23519 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23520 "movdqu\t{%1, %0|%0, %1}"
23521 [(set_attr "type" "ssecvt")
23522 (set_attr "mode" "TI")])
23523
23524 (define_insn "sse2_movdq2q"
23525 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23526 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23527 (parallel [(const_int 0)])))]
23528 "TARGET_SSE2 && !TARGET_64BIT"
23529 "@
23530 movq\t{%1, %0|%0, %1}
23531 movdq2q\t{%1, %0|%0, %1}"
23532 [(set_attr "type" "ssecvt")
23533 (set_attr "mode" "TI")])
23534
23535 (define_insn "sse2_movdq2q_rex64"
23536 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23537 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23538 (parallel [(const_int 0)])))]
23539 "TARGET_SSE2 && TARGET_64BIT"
23540 "@
23541 movq\t{%1, %0|%0, %1}
23542 movdq2q\t{%1, %0|%0, %1}
23543 movd\t{%1, %0|%0, %1}"
23544 [(set_attr "type" "ssecvt")
23545 (set_attr "mode" "TI")])
23546
23547 (define_insn "sse2_movq2dq"
23548 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23549 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23550 (const_int 0)))]
23551 "TARGET_SSE2 && !TARGET_64BIT"
23552 "@
23553 movq\t{%1, %0|%0, %1}
23554 movq2dq\t{%1, %0|%0, %1}"
23555 [(set_attr "type" "ssecvt,ssemov")
23556 (set_attr "mode" "TI")])
23557
23558 (define_insn "sse2_movq2dq_rex64"
23559 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23560 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23561 (const_int 0)))]
23562 "TARGET_SSE2 && TARGET_64BIT"
23563 "@
23564 movq\t{%1, %0|%0, %1}
23565 movq2dq\t{%1, %0|%0, %1}
23566 movd\t{%1, %0|%0, %1}"
23567 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23568 (set_attr "mode" "TI")])
23569
23570 (define_insn "sse2_movq"
23571 [(set (match_operand:V2DI 0 "register_operand" "=x")
23572 (vec_concat:V2DI (vec_select:DI
23573 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23574 (parallel [(const_int 0)]))
23575 (const_int 0)))]
23576 "TARGET_SSE2"
23577 "movq\t{%1, %0|%0, %1}"
23578 [(set_attr "type" "ssemov")
23579 (set_attr "mode" "TI")])
23580
23581 (define_insn "sse2_loadd"
23582 [(set (match_operand:V4SI 0 "register_operand" "=x")
23583 (vec_merge:V4SI
23584 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23585 (const_vector:V4SI [(const_int 0)
23586 (const_int 0)
23587 (const_int 0)
23588 (const_int 0)])
23589 (const_int 1)))]
23590 "TARGET_SSE2"
23591 "movd\t{%1, %0|%0, %1}"
23592 [(set_attr "type" "ssemov")
23593 (set_attr "mode" "TI")])
23594
23595 (define_insn "sse2_stored"
23596 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23597 (vec_select:SI
23598 (match_operand:V4SI 1 "register_operand" "x")
23599 (parallel [(const_int 0)])))]
23600 "TARGET_SSE2"
23601 "movd\t{%1, %0|%0, %1}"
23602 [(set_attr "type" "ssemov")
23603 (set_attr "mode" "TI")])
23604
23605 (define_insn "sse2_movhpd"
23606 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23607 (vec_merge:V2DF
23608 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23609 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23610 (const_int 2)))]
23611 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23612 "movhpd\t{%2, %0|%0, %2}"
23613 [(set_attr "type" "ssecvt")
23614 (set_attr "mode" "V2DF")])
23615
23616 (define_insn "sse2_movlpd"
23617 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23618 (vec_merge:V2DF
23619 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23620 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23621 (const_int 1)))]
23622 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23623 "movlpd\t{%2, %0|%0, %2}"
23624 [(set_attr "type" "ssecvt")
23625 (set_attr "mode" "V2DF")])
23626
23627 (define_expand "sse2_loadsd"
23628 [(match_operand:V2DF 0 "register_operand" "")
23629 (match_operand:DF 1 "memory_operand" "")]
23630 "TARGET_SSE2"
23631 {
23632 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23633 CONST0_RTX (V2DFmode)));
23634 DONE;
23635 })
23636
23637 (define_insn "sse2_loadsd_1"
23638 [(set (match_operand:V2DF 0 "register_operand" "=x")
23639 (vec_merge:V2DF
23640 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23641 (match_operand:V2DF 2 "const0_operand" "X")
23642 (const_int 1)))]
23643 "TARGET_SSE2"
23644 "movsd\t{%1, %0|%0, %1}"
23645 [(set_attr "type" "ssecvt")
23646 (set_attr "mode" "DF")])
23647
23648 (define_insn "sse2_movsd"
23649 [(set (match_operand:V2DF 0 "register_operand" "=x")
23650 (vec_merge:V2DF
23651 (match_operand:V2DF 1 "register_operand" "0")
23652 (match_operand:V2DF 2 "register_operand" "x")
23653 (const_int 1)))]
23654 "TARGET_SSE2"
23655 "movsd\t{%2, %0|%0, %2}"
23656 [(set_attr "type" "ssecvt")
23657 (set_attr "mode" "DF")])
23658
23659 (define_insn "sse2_storesd"
23660 [(set (match_operand:DF 0 "memory_operand" "=m")
23661 (vec_select:DF
23662 (match_operand:V2DF 1 "register_operand" "x")
23663 (parallel [(const_int 0)])))]
23664 "TARGET_SSE2"
23665 "movsd\t{%1, %0|%0, %1}"
23666 [(set_attr "type" "ssecvt")
23667 (set_attr "mode" "DF")])
23668
23669 (define_insn "sse2_shufpd"
23670 [(set (match_operand:V2DF 0 "register_operand" "=x")
23671 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23672 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23673 (match_operand:SI 3 "immediate_operand" "i")]
23674 UNSPEC_SHUFFLE))]
23675 "TARGET_SSE2"
23676 ;; @@@ check operand order for intel/nonintel syntax
23677 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23678 [(set_attr "type" "ssecvt")
23679 (set_attr "mode" "V2DF")])
23680
23681 (define_insn "sse2_clflush"
23682 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23683 UNSPECV_CLFLUSH)]
23684 "TARGET_SSE2"
23685 "clflush %0"
23686 [(set_attr "type" "sse")
23687 (set_attr "memory" "unknown")])
23688
23689 (define_expand "sse2_mfence"
23690 [(set (match_dup 0)
23691 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23692 "TARGET_SSE2"
23693 {
23694 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23695 MEM_VOLATILE_P (operands[0]) = 1;
23696 })
23697
23698 (define_insn "*mfence_insn"
23699 [(set (match_operand:BLK 0 "" "")
23700 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23701 "TARGET_SSE2"
23702 "mfence"
23703 [(set_attr "type" "sse")
23704 (set_attr "memory" "unknown")])
23705
23706 (define_expand "sse2_lfence"
23707 [(set (match_dup 0)
23708 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23709 "TARGET_SSE2"
23710 {
23711 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23712 MEM_VOLATILE_P (operands[0]) = 1;
23713 })
23714
23715 (define_insn "*lfence_insn"
23716 [(set (match_operand:BLK 0 "" "")
23717 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23718 "TARGET_SSE2"
23719 "lfence"
23720 [(set_attr "type" "sse")
23721 (set_attr "memory" "unknown")])
23722
23723 ;; PNI
23724
23725 (define_insn "mwait"
23726 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23727 (match_operand:SI 1 "register_operand" "c")]
23728 UNSPECV_MWAIT)]
23729 "TARGET_PNI"
23730 "mwait\t%0, %1"
23731 [(set_attr "length" "3")])
23732
23733 (define_insn "monitor"
23734 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23735 (match_operand:SI 1 "register_operand" "c")
23736 (match_operand:SI 2 "register_operand" "d")]
23737 UNSPECV_MONITOR)]
23738 "TARGET_PNI"
23739 "monitor\t%0, %1, %2"
23740 [(set_attr "length" "3")])
23741
23742 ;; PNI arithmetic
23743
23744 (define_insn "addsubv4sf3"
23745 [(set (match_operand:V4SF 0 "register_operand" "=x")
23746 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23747 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23748 UNSPEC_ADDSUB))]
23749 "TARGET_PNI"
23750 "addsubps\t{%2, %0|%0, %2}"
23751 [(set_attr "type" "sseadd")
23752 (set_attr "mode" "V4SF")])
23753
23754 (define_insn "addsubv2df3"
23755 [(set (match_operand:V2DF 0 "register_operand" "=x")
23756 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23757 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23758 UNSPEC_ADDSUB))]
23759 "TARGET_PNI"
23760 "addsubpd\t{%2, %0|%0, %2}"
23761 [(set_attr "type" "sseadd")
23762 (set_attr "mode" "V2DF")])
23763
23764 (define_insn "haddv4sf3"
23765 [(set (match_operand:V4SF 0 "register_operand" "=x")
23766 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23767 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23768 UNSPEC_HADD))]
23769 "TARGET_PNI"
23770 "haddps\t{%2, %0|%0, %2}"
23771 [(set_attr "type" "sseadd")
23772 (set_attr "mode" "V4SF")])
23773
23774 (define_insn "haddv2df3"
23775 [(set (match_operand:V2DF 0 "register_operand" "=x")
23776 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23777 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23778 UNSPEC_HADD))]
23779 "TARGET_PNI"
23780 "haddpd\t{%2, %0|%0, %2}"
23781 [(set_attr "type" "sseadd")
23782 (set_attr "mode" "V2DF")])
23783
23784 (define_insn "hsubv4sf3"
23785 [(set (match_operand:V4SF 0 "register_operand" "=x")
23786 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23787 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23788 UNSPEC_HSUB))]
23789 "TARGET_PNI"
23790 "hsubps\t{%2, %0|%0, %2}"
23791 [(set_attr "type" "sseadd")
23792 (set_attr "mode" "V4SF")])
23793
23794 (define_insn "hsubv2df3"
23795 [(set (match_operand:V2DF 0 "register_operand" "=x")
23796 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23797 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23798 UNSPEC_HSUB))]
23799 "TARGET_PNI"
23800 "hsubpd\t{%2, %0|%0, %2}"
23801 [(set_attr "type" "sseadd")
23802 (set_attr "mode" "V2DF")])
23803
23804 (define_insn "movshdup"
23805 [(set (match_operand:V4SF 0 "register_operand" "=x")
23806 (unspec:V4SF
23807 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23808 "TARGET_PNI"
23809 "movshdup\t{%1, %0|%0, %1}"
23810 [(set_attr "type" "sse")
23811 (set_attr "mode" "V4SF")])
23812
23813 (define_insn "movsldup"
23814 [(set (match_operand:V4SF 0 "register_operand" "=x")
23815 (unspec:V4SF
23816 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23817 "TARGET_PNI"
23818 "movsldup\t{%1, %0|%0, %1}"
23819 [(set_attr "type" "sse")
23820 (set_attr "mode" "V4SF")])
23821
23822 (define_insn "lddqu"
23823 [(set (match_operand:V16QI 0 "register_operand" "=x")
23824 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23825 UNSPEC_LDQQU))]
23826 "TARGET_PNI"
23827 "lddqu\t{%1, %0|%0, %1}"
23828 [(set_attr "type" "ssecvt")
23829 (set_attr "mode" "TI")])
23830
23831 (define_insn "loadddup"
23832 [(set (match_operand:V2DF 0 "register_operand" "=x")
23833 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23834 "TARGET_PNI"
23835 "movddup\t{%1, %0|%0, %1}"
23836 [(set_attr "type" "ssecvt")
23837 (set_attr "mode" "DF")])
23838
23839 (define_insn "movddup"
23840 [(set (match_operand:V2DF 0 "register_operand" "=x")
23841 (vec_duplicate:V2DF
23842 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23843 (parallel [(const_int 0)]))))]
23844 "TARGET_PNI"
23845 "movddup\t{%1, %0|%0, %1}"
23846 [(set_attr "type" "ssecvt")
23847 (set_attr "mode" "DF")])