optabs.h (enum optab_index): Add new OTI_tan and OTI_atan.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GNU CC.
9 ;;
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
31 ;; updates for most instructions.
32 ;;
33 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
34 ;; constraint letters.
35 ;;
36 ;; The special asm out single letter directives following a '%' are:
37 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
38 ;; operands[1].
39 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
40 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
41 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
42 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
43 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
44 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
45 ;; 'J' Print the appropriate jump operand.
46 ;;
47 ;; 'b' Print the QImode name of the register for the indicated operand.
48 ;; %b0 would print %al if operands[0] is reg 0.
49 ;; 'w' Likewise, print the HImode name of the register.
50 ;; 'k' Likewise, print the SImode name of the register.
51 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; 'y' Print "st(0)" instead of "st" as a register.
53
54 ;; UNSPEC usage:
55
56 (define_constants
57 [; Relocation specifiers
58 (UNSPEC_GOT 0)
59 (UNSPEC_GOTOFF 1)
60 (UNSPEC_GOTPCREL 2)
61 (UNSPEC_GOTTPOFF 3)
62 (UNSPEC_TPOFF 4)
63 (UNSPEC_NTPOFF 5)
64 (UNSPEC_DTPOFF 6)
65 (UNSPEC_GOTNTPOFF 7)
66 (UNSPEC_INDNTPOFF 8)
67
68 ; Prologue support
69 (UNSPEC_STACK_PROBE 10)
70 (UNSPEC_STACK_ALLOC 11)
71 (UNSPEC_SET_GOT 12)
72 (UNSPEC_SSE_PROLOGUE_SAVE 13)
73
74 ; TLS support
75 (UNSPEC_TP 15)
76 (UNSPEC_TLS_GD 16)
77 (UNSPEC_TLS_LD_BASE 17)
78
79 ; Other random patterns
80 (UNSPEC_SCAS 20)
81 (UNSPEC_SIN 21)
82 (UNSPEC_COS 22)
83 (UNSPEC_FNSTSW 24)
84 (UNSPEC_SAHF 25)
85 (UNSPEC_FSTCW 26)
86 (UNSPEC_ADD_CARRY 27)
87 (UNSPEC_FLDCW 28)
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX 30)
91 (UNSPEC_MASKMOV 32)
92 (UNSPEC_MOVMSK 33)
93 (UNSPEC_MOVNT 34)
94 (UNSPEC_MOVA 38)
95 (UNSPEC_MOVU 39)
96 (UNSPEC_SHUFFLE 41)
97 (UNSPEC_RCP 42)
98 (UNSPEC_RSQRT 43)
99 (UNSPEC_SFENCE 44)
100 (UNSPEC_NOP 45) ; prevents combiner cleverness
101 (UNSPEC_PAVGUSB 49)
102 (UNSPEC_PFRCP 50)
103 (UNSPEC_PFRCPIT1 51)
104 (UNSPEC_PFRCPIT2 52)
105 (UNSPEC_PFRSQRT 53)
106 (UNSPEC_PFRSQIT1 54)
107 (UNSPEC_PSHUFLW 55)
108 (UNSPEC_PSHUFHW 56)
109 (UNSPEC_MFENCE 59)
110 (UNSPEC_LFENCE 60)
111 (UNSPEC_PSADBW 61)
112
113 ; x87 Floating point
114 (UNSPEC_FPATAN 65)
115 (UNSPEC_FYL2X 66)
116 (UNSPEC_FSCALE 67)
117 (UNSPEC_FRNDINT 68)
118 (UNSPEC_F2XM1 69)
119
120 ; REP instruction
121 (UNSPEC_REP 75)
122 ])
123
124 (define_constants
125 [(UNSPECV_BLOCKAGE 0)
126 (UNSPECV_EH_RETURN 13)
127 (UNSPECV_EMMS 31)
128 (UNSPECV_LDMXCSR 37)
129 (UNSPECV_STMXCSR 40)
130 (UNSPECV_FEMMS 46)
131 (UNSPECV_CLFLUSH 57)
132 (UNSPECV_ALIGN 68)
133 ])
134
135 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
136 ;; from i386.c.
137
138 ;; In C guard expressions, put expressions which may be compile-time
139 ;; constants first. This allows for better optimization. For
140 ;; example, write "TARGET_64BIT && reload_completed", not
141 ;; "reload_completed && TARGET_64BIT".
142
143 \f
144 ;; Processor type. This attribute must exactly match the processor_type
145 ;; enumeration in i386.h.
146 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
147 (const (symbol_ref "ix86_tune")))
148
149 ;; A basic instruction type. Refinements due to arguments to be
150 ;; provided in other attributes.
151 (define_attr "type"
152 "other,multi,
153 alu,alu1,negnot,imov,imovx,lea,
154 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
155 icmp,test,ibr,setcc,icmov,
156 push,pop,call,callv,leave,
157 str,cld,
158 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
159 sselog,sseiadd,sseishft,sseimul,
160 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
161 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
162 (const_string "other"))
163
164 ;; Main data type used by the insn
165 (define_attr "mode"
166 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
167 (const_string "unknown"))
168
169 ;; The CPU unit operations uses.
170 (define_attr "unit" "integer,i387,sse,mmx,unknown"
171 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
172 (const_string "i387")
173 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
174 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
175 (const_string "sse")
176 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
177 (const_string "mmx")
178 (eq_attr "type" "other")
179 (const_string "unknown")]
180 (const_string "integer")))
181
182 ;; The (bounding maximum) length of an instruction immediate.
183 (define_attr "length_immediate" ""
184 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
185 (const_int 0)
186 (eq_attr "unit" "i387,sse,mmx")
187 (const_int 0)
188 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
189 imul,icmp,push,pop")
190 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
191 (eq_attr "type" "imov,test")
192 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
193 (eq_attr "type" "call")
194 (if_then_else (match_operand 0 "constant_call_address_operand" "")
195 (const_int 4)
196 (const_int 0))
197 (eq_attr "type" "callv")
198 (if_then_else (match_operand 1 "constant_call_address_operand" "")
199 (const_int 4)
200 (const_int 0))
201 ;; We don't know the size before shorten_branches. Expect
202 ;; the instruction to fit for better scheduling.
203 (eq_attr "type" "ibr")
204 (const_int 1)
205 ]
206 (symbol_ref "/* Update immediate_length and other attributes! */
207 abort(),1")))
208
209 ;; The (bounding maximum) length of an instruction address.
210 (define_attr "length_address" ""
211 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
212 (const_int 0)
213 (and (eq_attr "type" "call")
214 (match_operand 0 "constant_call_address_operand" ""))
215 (const_int 0)
216 (and (eq_attr "type" "callv")
217 (match_operand 1 "constant_call_address_operand" ""))
218 (const_int 0)
219 ]
220 (symbol_ref "ix86_attr_length_address_default (insn)")))
221
222 ;; Set when length prefix is used.
223 (define_attr "prefix_data16" ""
224 (if_then_else (ior (eq_attr "mode" "HI")
225 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
226 (const_int 1)
227 (const_int 0)))
228
229 ;; Set when string REP prefix is used.
230 (define_attr "prefix_rep" ""
231 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
232 (const_int 1)
233 (const_int 0)))
234
235 ;; Set when 0f opcode prefix is used.
236 (define_attr "prefix_0f" ""
237 (if_then_else
238 (ior (eq_attr "type" "imovx,setcc,icmov")
239 (eq_attr "unit" "sse,mmx"))
240 (const_int 1)
241 (const_int 0)))
242
243 ;; Set when 0f opcode prefix is used.
244 (define_attr "prefix_rex" ""
245 (cond [(and (eq_attr "mode" "DI")
246 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
247 (const_int 1)
248 (and (eq_attr "mode" "QI")
249 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
250 (const_int 0)))
251 (const_int 1)
252 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
253 (const_int 0))
254 (const_int 1)
255 ]
256 (const_int 0)))
257
258 ;; Set when modrm byte is used.
259 (define_attr "modrm" ""
260 (cond [(eq_attr "type" "str,cld,leave")
261 (const_int 0)
262 (eq_attr "unit" "i387")
263 (const_int 0)
264 (and (eq_attr "type" "incdec")
265 (ior (match_operand:SI 1 "register_operand" "")
266 (match_operand:HI 1 "register_operand" "")))
267 (const_int 0)
268 (and (eq_attr "type" "push")
269 (not (match_operand 1 "memory_operand" "")))
270 (const_int 0)
271 (and (eq_attr "type" "pop")
272 (not (match_operand 0 "memory_operand" "")))
273 (const_int 0)
274 (and (eq_attr "type" "imov")
275 (and (match_operand 0 "register_operand" "")
276 (match_operand 1 "immediate_operand" "")))
277 (const_int 0)
278 (and (eq_attr "type" "call")
279 (match_operand 0 "constant_call_address_operand" ""))
280 (const_int 0)
281 (and (eq_attr "type" "callv")
282 (match_operand 1 "constant_call_address_operand" ""))
283 (const_int 0)
284 ]
285 (const_int 1)))
286
287 ;; The (bounding maximum) length of an instruction in bytes.
288 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
289 ;; to split it and compute proper length as for other insns.
290 (define_attr "length" ""
291 (cond [(eq_attr "type" "other,multi,fistp")
292 (const_int 16)
293 (eq_attr "type" "fcmp")
294 (const_int 4)
295 (eq_attr "unit" "i387")
296 (plus (const_int 2)
297 (plus (attr "prefix_data16")
298 (attr "length_address")))]
299 (plus (plus (attr "modrm")
300 (plus (attr "prefix_0f")
301 (plus (attr "prefix_rex")
302 (const_int 1))))
303 (plus (attr "prefix_rep")
304 (plus (attr "prefix_data16")
305 (plus (attr "length_immediate")
306 (attr "length_address")))))))
307
308 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
309 ;; `store' if there is a simple memory reference therein, or `unknown'
310 ;; if the instruction is complex.
311
312 (define_attr "memory" "none,load,store,both,unknown"
313 (cond [(eq_attr "type" "other,multi,str")
314 (const_string "unknown")
315 (eq_attr "type" "lea,fcmov,fpspc,cld")
316 (const_string "none")
317 (eq_attr "type" "fistp,leave")
318 (const_string "both")
319 (eq_attr "type" "push")
320 (if_then_else (match_operand 1 "memory_operand" "")
321 (const_string "both")
322 (const_string "store"))
323 (eq_attr "type" "pop")
324 (if_then_else (match_operand 0 "memory_operand" "")
325 (const_string "both")
326 (const_string "load"))
327 (eq_attr "type" "setcc")
328 (if_then_else (match_operand 0 "memory_operand" "")
329 (const_string "store")
330 (const_string "none"))
331 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
332 (if_then_else (ior (match_operand 0 "memory_operand" "")
333 (match_operand 1 "memory_operand" ""))
334 (const_string "load")
335 (const_string "none"))
336 (eq_attr "type" "ibr")
337 (if_then_else (match_operand 0 "memory_operand" "")
338 (const_string "load")
339 (const_string "none"))
340 (eq_attr "type" "call")
341 (if_then_else (match_operand 0 "constant_call_address_operand" "")
342 (const_string "none")
343 (const_string "load"))
344 (eq_attr "type" "callv")
345 (if_then_else (match_operand 1 "constant_call_address_operand" "")
346 (const_string "none")
347 (const_string "load"))
348 (and (eq_attr "type" "alu1,negnot")
349 (match_operand 1 "memory_operand" ""))
350 (const_string "both")
351 (and (match_operand 0 "memory_operand" "")
352 (match_operand 1 "memory_operand" ""))
353 (const_string "both")
354 (match_operand 0 "memory_operand" "")
355 (const_string "store")
356 (match_operand 1 "memory_operand" "")
357 (const_string "load")
358 (and (eq_attr "type"
359 "!alu1,negnot,
360 imov,imovx,icmp,test,
361 fmov,fcmp,fsgn,
362 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
363 mmx,mmxmov,mmxcmp,mmxcvt")
364 (match_operand 2 "memory_operand" ""))
365 (const_string "load")
366 (and (eq_attr "type" "icmov")
367 (match_operand 3 "memory_operand" ""))
368 (const_string "load")
369 ]
370 (const_string "none")))
371
372 ;; Indicates if an instruction has both an immediate and a displacement.
373
374 (define_attr "imm_disp" "false,true,unknown"
375 (cond [(eq_attr "type" "other,multi")
376 (const_string "unknown")
377 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
378 (and (match_operand 0 "memory_displacement_operand" "")
379 (match_operand 1 "immediate_operand" "")))
380 (const_string "true")
381 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
382 (and (match_operand 0 "memory_displacement_operand" "")
383 (match_operand 2 "immediate_operand" "")))
384 (const_string "true")
385 ]
386 (const_string "false")))
387
388 ;; Indicates if an FP operation has an integer source.
389
390 (define_attr "fp_int_src" "false,true"
391 (const_string "false"))
392
393 ;; Describe a user's asm statement.
394 (define_asm_attributes
395 [(set_attr "length" "128")
396 (set_attr "type" "multi")])
397 \f
398 (include "pentium.md")
399 (include "ppro.md")
400 (include "k6.md")
401 (include "athlon.md")
402 \f
403 ;; Compare instructions.
404
405 ;; All compare insns have expanders that save the operands away without
406 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
407 ;; after the cmp) will actually emit the cmpM.
408
409 (define_expand "cmpdi"
410 [(set (reg:CC 17)
411 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
412 (match_operand:DI 1 "x86_64_general_operand" "")))]
413 ""
414 {
415 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
416 operands[0] = force_reg (DImode, operands[0]);
417 ix86_compare_op0 = operands[0];
418 ix86_compare_op1 = operands[1];
419 DONE;
420 })
421
422 (define_expand "cmpsi"
423 [(set (reg:CC 17)
424 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
425 (match_operand:SI 1 "general_operand" "")))]
426 ""
427 {
428 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
429 operands[0] = force_reg (SImode, operands[0]);
430 ix86_compare_op0 = operands[0];
431 ix86_compare_op1 = operands[1];
432 DONE;
433 })
434
435 (define_expand "cmphi"
436 [(set (reg:CC 17)
437 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
438 (match_operand:HI 1 "general_operand" "")))]
439 ""
440 {
441 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
442 operands[0] = force_reg (HImode, operands[0]);
443 ix86_compare_op0 = operands[0];
444 ix86_compare_op1 = operands[1];
445 DONE;
446 })
447
448 (define_expand "cmpqi"
449 [(set (reg:CC 17)
450 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
451 (match_operand:QI 1 "general_operand" "")))]
452 "TARGET_QIMODE_MATH"
453 {
454 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
455 operands[0] = force_reg (QImode, operands[0]);
456 ix86_compare_op0 = operands[0];
457 ix86_compare_op1 = operands[1];
458 DONE;
459 })
460
461 (define_insn "cmpdi_ccno_1_rex64"
462 [(set (reg 17)
463 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
464 (match_operand:DI 1 "const0_operand" "n,n")))]
465 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
466 "@
467 test{q}\t{%0, %0|%0, %0}
468 cmp{q}\t{%1, %0|%0, %1}"
469 [(set_attr "type" "test,icmp")
470 (set_attr "length_immediate" "0,1")
471 (set_attr "mode" "DI")])
472
473 (define_insn "*cmpdi_minus_1_rex64"
474 [(set (reg 17)
475 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
476 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
477 (const_int 0)))]
478 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
479 "cmp{q}\t{%1, %0|%0, %1}"
480 [(set_attr "type" "icmp")
481 (set_attr "mode" "DI")])
482
483 (define_expand "cmpdi_1_rex64"
484 [(set (reg:CC 17)
485 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
486 (match_operand:DI 1 "general_operand" "")))]
487 "TARGET_64BIT"
488 "")
489
490 (define_insn "cmpdi_1_insn_rex64"
491 [(set (reg 17)
492 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
493 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
494 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
495 "cmp{q}\t{%1, %0|%0, %1}"
496 [(set_attr "type" "icmp")
497 (set_attr "mode" "DI")])
498
499
500 (define_insn "*cmpsi_ccno_1"
501 [(set (reg 17)
502 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
503 (match_operand:SI 1 "const0_operand" "n,n")))]
504 "ix86_match_ccmode (insn, CCNOmode)"
505 "@
506 test{l}\t{%0, %0|%0, %0}
507 cmp{l}\t{%1, %0|%0, %1}"
508 [(set_attr "type" "test,icmp")
509 (set_attr "length_immediate" "0,1")
510 (set_attr "mode" "SI")])
511
512 (define_insn "*cmpsi_minus_1"
513 [(set (reg 17)
514 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
515 (match_operand:SI 1 "general_operand" "ri,mr"))
516 (const_int 0)))]
517 "ix86_match_ccmode (insn, CCGOCmode)"
518 "cmp{l}\t{%1, %0|%0, %1}"
519 [(set_attr "type" "icmp")
520 (set_attr "mode" "SI")])
521
522 (define_expand "cmpsi_1"
523 [(set (reg:CC 17)
524 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
525 (match_operand:SI 1 "general_operand" "ri,mr")))]
526 ""
527 "")
528
529 (define_insn "*cmpsi_1_insn"
530 [(set (reg 17)
531 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
532 (match_operand:SI 1 "general_operand" "ri,mr")))]
533 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
534 && ix86_match_ccmode (insn, CCmode)"
535 "cmp{l}\t{%1, %0|%0, %1}"
536 [(set_attr "type" "icmp")
537 (set_attr "mode" "SI")])
538
539 (define_insn "*cmphi_ccno_1"
540 [(set (reg 17)
541 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
542 (match_operand:HI 1 "const0_operand" "n,n")))]
543 "ix86_match_ccmode (insn, CCNOmode)"
544 "@
545 test{w}\t{%0, %0|%0, %0}
546 cmp{w}\t{%1, %0|%0, %1}"
547 [(set_attr "type" "test,icmp")
548 (set_attr "length_immediate" "0,1")
549 (set_attr "mode" "HI")])
550
551 (define_insn "*cmphi_minus_1"
552 [(set (reg 17)
553 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
554 (match_operand:HI 1 "general_operand" "ri,mr"))
555 (const_int 0)))]
556 "ix86_match_ccmode (insn, CCGOCmode)"
557 "cmp{w}\t{%1, %0|%0, %1}"
558 [(set_attr "type" "icmp")
559 (set_attr "mode" "HI")])
560
561 (define_insn "*cmphi_1"
562 [(set (reg 17)
563 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
564 (match_operand:HI 1 "general_operand" "ri,mr")))]
565 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
566 && ix86_match_ccmode (insn, CCmode)"
567 "cmp{w}\t{%1, %0|%0, %1}"
568 [(set_attr "type" "icmp")
569 (set_attr "mode" "HI")])
570
571 (define_insn "*cmpqi_ccno_1"
572 [(set (reg 17)
573 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
574 (match_operand:QI 1 "const0_operand" "n,n")))]
575 "ix86_match_ccmode (insn, CCNOmode)"
576 "@
577 test{b}\t{%0, %0|%0, %0}
578 cmp{b}\t{$0, %0|%0, 0}"
579 [(set_attr "type" "test,icmp")
580 (set_attr "length_immediate" "0,1")
581 (set_attr "mode" "QI")])
582
583 (define_insn "*cmpqi_1"
584 [(set (reg 17)
585 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
586 (match_operand:QI 1 "general_operand" "qi,mq")))]
587 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
588 && ix86_match_ccmode (insn, CCmode)"
589 "cmp{b}\t{%1, %0|%0, %1}"
590 [(set_attr "type" "icmp")
591 (set_attr "mode" "QI")])
592
593 (define_insn "*cmpqi_minus_1"
594 [(set (reg 17)
595 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
596 (match_operand:QI 1 "general_operand" "qi,mq"))
597 (const_int 0)))]
598 "ix86_match_ccmode (insn, CCGOCmode)"
599 "cmp{b}\t{%1, %0|%0, %1}"
600 [(set_attr "type" "icmp")
601 (set_attr "mode" "QI")])
602
603 (define_insn "*cmpqi_ext_1"
604 [(set (reg 17)
605 (compare
606 (match_operand:QI 0 "general_operand" "Qm")
607 (subreg:QI
608 (zero_extract:SI
609 (match_operand 1 "ext_register_operand" "Q")
610 (const_int 8)
611 (const_int 8)) 0)))]
612 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
613 "cmp{b}\t{%h1, %0|%0, %h1}"
614 [(set_attr "type" "icmp")
615 (set_attr "mode" "QI")])
616
617 (define_insn "*cmpqi_ext_1_rex64"
618 [(set (reg 17)
619 (compare
620 (match_operand:QI 0 "register_operand" "Q")
621 (subreg:QI
622 (zero_extract:SI
623 (match_operand 1 "ext_register_operand" "Q")
624 (const_int 8)
625 (const_int 8)) 0)))]
626 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
627 "cmp{b}\t{%h1, %0|%0, %h1}"
628 [(set_attr "type" "icmp")
629 (set_attr "mode" "QI")])
630
631 (define_insn "*cmpqi_ext_2"
632 [(set (reg 17)
633 (compare
634 (subreg:QI
635 (zero_extract:SI
636 (match_operand 0 "ext_register_operand" "Q")
637 (const_int 8)
638 (const_int 8)) 0)
639 (match_operand:QI 1 "const0_operand" "n")))]
640 "ix86_match_ccmode (insn, CCNOmode)"
641 "test{b}\t%h0, %h0"
642 [(set_attr "type" "test")
643 (set_attr "length_immediate" "0")
644 (set_attr "mode" "QI")])
645
646 (define_expand "cmpqi_ext_3"
647 [(set (reg:CC 17)
648 (compare:CC
649 (subreg:QI
650 (zero_extract:SI
651 (match_operand 0 "ext_register_operand" "")
652 (const_int 8)
653 (const_int 8)) 0)
654 (match_operand:QI 1 "general_operand" "")))]
655 ""
656 "")
657
658 (define_insn "cmpqi_ext_3_insn"
659 [(set (reg 17)
660 (compare
661 (subreg:QI
662 (zero_extract:SI
663 (match_operand 0 "ext_register_operand" "Q")
664 (const_int 8)
665 (const_int 8)) 0)
666 (match_operand:QI 1 "general_operand" "Qmn")))]
667 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
668 "cmp{b}\t{%1, %h0|%h0, %1}"
669 [(set_attr "type" "icmp")
670 (set_attr "mode" "QI")])
671
672 (define_insn "cmpqi_ext_3_insn_rex64"
673 [(set (reg 17)
674 (compare
675 (subreg:QI
676 (zero_extract:SI
677 (match_operand 0 "ext_register_operand" "Q")
678 (const_int 8)
679 (const_int 8)) 0)
680 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
681 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
682 "cmp{b}\t{%1, %h0|%h0, %1}"
683 [(set_attr "type" "icmp")
684 (set_attr "mode" "QI")])
685
686 (define_insn "*cmpqi_ext_4"
687 [(set (reg 17)
688 (compare
689 (subreg:QI
690 (zero_extract:SI
691 (match_operand 0 "ext_register_operand" "Q")
692 (const_int 8)
693 (const_int 8)) 0)
694 (subreg:QI
695 (zero_extract:SI
696 (match_operand 1 "ext_register_operand" "Q")
697 (const_int 8)
698 (const_int 8)) 0)))]
699 "ix86_match_ccmode (insn, CCmode)"
700 "cmp{b}\t{%h1, %h0|%h0, %h1}"
701 [(set_attr "type" "icmp")
702 (set_attr "mode" "QI")])
703
704 ;; These implement float point compares.
705 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
706 ;; which would allow mix and match FP modes on the compares. Which is what
707 ;; the old patterns did, but with many more of them.
708
709 (define_expand "cmpxf"
710 [(set (reg:CC 17)
711 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
712 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
713 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
714 {
715 ix86_compare_op0 = operands[0];
716 ix86_compare_op1 = operands[1];
717 DONE;
718 })
719
720 (define_expand "cmptf"
721 [(set (reg:CC 17)
722 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
723 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
724 "TARGET_80387"
725 {
726 ix86_compare_op0 = operands[0];
727 ix86_compare_op1 = operands[1];
728 DONE;
729 })
730
731 (define_expand "cmpdf"
732 [(set (reg:CC 17)
733 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
734 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
735 "TARGET_80387 || TARGET_SSE2"
736 {
737 ix86_compare_op0 = operands[0];
738 ix86_compare_op1 = operands[1];
739 DONE;
740 })
741
742 (define_expand "cmpsf"
743 [(set (reg:CC 17)
744 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
745 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
746 "TARGET_80387 || TARGET_SSE"
747 {
748 ix86_compare_op0 = operands[0];
749 ix86_compare_op1 = operands[1];
750 DONE;
751 })
752
753 ;; FP compares, step 1:
754 ;; Set the FP condition codes.
755 ;;
756 ;; CCFPmode compare with exceptions
757 ;; CCFPUmode compare with no exceptions
758
759 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
760 ;; and that fp moves clobber the condition codes, and that there is
761 ;; currently no way to describe this fact to reg-stack. So there are
762 ;; no splitters yet for this.
763
764 ;; %%% YIKES! This scheme does not retain a strong connection between
765 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
766 ;; work! Only allow tos/mem with tos in op 0.
767 ;;
768 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
769 ;; things aren't as bad as they sound...
770
771 (define_insn "*cmpfp_0"
772 [(set (match_operand:HI 0 "register_operand" "=a")
773 (unspec:HI
774 [(compare:CCFP (match_operand 1 "register_operand" "f")
775 (match_operand 2 "const0_operand" "X"))]
776 UNSPEC_FNSTSW))]
777 "TARGET_80387
778 && FLOAT_MODE_P (GET_MODE (operands[1]))
779 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
780 {
781 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
782 return "ftst\;fnstsw\t%0\;fstp\t%y0";
783 else
784 return "ftst\;fnstsw\t%0";
785 }
786 [(set_attr "type" "multi")
787 (set (attr "mode")
788 (cond [(match_operand:SF 1 "" "")
789 (const_string "SF")
790 (match_operand:DF 1 "" "")
791 (const_string "DF")
792 ]
793 (const_string "XF")))])
794
795 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
796 ;; used to manage the reg stack popping would not be preserved.
797
798 (define_insn "*cmpfp_2_sf"
799 [(set (reg:CCFP 18)
800 (compare:CCFP
801 (match_operand:SF 0 "register_operand" "f")
802 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
803 "TARGET_80387"
804 "* return output_fp_compare (insn, operands, 0, 0);"
805 [(set_attr "type" "fcmp")
806 (set_attr "mode" "SF")])
807
808 (define_insn "*cmpfp_2_sf_1"
809 [(set (match_operand:HI 0 "register_operand" "=a")
810 (unspec:HI
811 [(compare:CCFP
812 (match_operand:SF 1 "register_operand" "f")
813 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
814 UNSPEC_FNSTSW))]
815 "TARGET_80387"
816 "* return output_fp_compare (insn, operands, 2, 0);"
817 [(set_attr "type" "fcmp")
818 (set_attr "mode" "SF")])
819
820 (define_insn "*cmpfp_2_df"
821 [(set (reg:CCFP 18)
822 (compare:CCFP
823 (match_operand:DF 0 "register_operand" "f")
824 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
825 "TARGET_80387"
826 "* return output_fp_compare (insn, operands, 0, 0);"
827 [(set_attr "type" "fcmp")
828 (set_attr "mode" "DF")])
829
830 (define_insn "*cmpfp_2_df_1"
831 [(set (match_operand:HI 0 "register_operand" "=a")
832 (unspec:HI
833 [(compare:CCFP
834 (match_operand:DF 1 "register_operand" "f")
835 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
836 UNSPEC_FNSTSW))]
837 "TARGET_80387"
838 "* return output_fp_compare (insn, operands, 2, 0);"
839 [(set_attr "type" "multi")
840 (set_attr "mode" "DF")])
841
842 (define_insn "*cmpfp_2_xf"
843 [(set (reg:CCFP 18)
844 (compare:CCFP
845 (match_operand:XF 0 "register_operand" "f")
846 (match_operand:XF 1 "register_operand" "f")))]
847 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
848 "* return output_fp_compare (insn, operands, 0, 0);"
849 [(set_attr "type" "fcmp")
850 (set_attr "mode" "XF")])
851
852 (define_insn "*cmpfp_2_tf"
853 [(set (reg:CCFP 18)
854 (compare:CCFP
855 (match_operand:TF 0 "register_operand" "f")
856 (match_operand:TF 1 "register_operand" "f")))]
857 "TARGET_80387"
858 "* return output_fp_compare (insn, operands, 0, 0);"
859 [(set_attr "type" "fcmp")
860 (set_attr "mode" "XF")])
861
862 (define_insn "*cmpfp_2_xf_1"
863 [(set (match_operand:HI 0 "register_operand" "=a")
864 (unspec:HI
865 [(compare:CCFP
866 (match_operand:XF 1 "register_operand" "f")
867 (match_operand:XF 2 "register_operand" "f"))]
868 UNSPEC_FNSTSW))]
869 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
870 "* return output_fp_compare (insn, operands, 2, 0);"
871 [(set_attr "type" "multi")
872 (set_attr "mode" "XF")])
873
874 (define_insn "*cmpfp_2_tf_1"
875 [(set (match_operand:HI 0 "register_operand" "=a")
876 (unspec:HI
877 [(compare:CCFP
878 (match_operand:TF 1 "register_operand" "f")
879 (match_operand:TF 2 "register_operand" "f"))]
880 UNSPEC_FNSTSW))]
881 "TARGET_80387"
882 "* return output_fp_compare (insn, operands, 2, 0);"
883 [(set_attr "type" "multi")
884 (set_attr "mode" "XF")])
885
886 (define_insn "*cmpfp_2u"
887 [(set (reg:CCFPU 18)
888 (compare:CCFPU
889 (match_operand 0 "register_operand" "f")
890 (match_operand 1 "register_operand" "f")))]
891 "TARGET_80387
892 && FLOAT_MODE_P (GET_MODE (operands[0]))
893 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
894 "* return output_fp_compare (insn, operands, 0, 1);"
895 [(set_attr "type" "fcmp")
896 (set (attr "mode")
897 (cond [(match_operand:SF 1 "" "")
898 (const_string "SF")
899 (match_operand:DF 1 "" "")
900 (const_string "DF")
901 ]
902 (const_string "XF")))])
903
904 (define_insn "*cmpfp_2u_1"
905 [(set (match_operand:HI 0 "register_operand" "=a")
906 (unspec:HI
907 [(compare:CCFPU
908 (match_operand 1 "register_operand" "f")
909 (match_operand 2 "register_operand" "f"))]
910 UNSPEC_FNSTSW))]
911 "TARGET_80387
912 && FLOAT_MODE_P (GET_MODE (operands[1]))
913 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
914 "* return output_fp_compare (insn, operands, 2, 1);"
915 [(set_attr "type" "multi")
916 (set (attr "mode")
917 (cond [(match_operand:SF 1 "" "")
918 (const_string "SF")
919 (match_operand:DF 1 "" "")
920 (const_string "DF")
921 ]
922 (const_string "XF")))])
923
924 ;; Patterns to match the SImode-in-memory ficom instructions.
925 ;;
926 ;; %%% Play games with accepting gp registers, as otherwise we have to
927 ;; force them to memory during rtl generation, which is no good. We
928 ;; can get rid of this once we teach reload to do memory input reloads
929 ;; via pushes.
930
931 (define_insn "*ficom_1"
932 [(set (reg:CCFP 18)
933 (compare:CCFP
934 (match_operand 0 "register_operand" "f,f")
935 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
936 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
937 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
938 "#")
939
940 ;; Split the not-really-implemented gp register case into a
941 ;; push-op-pop sequence.
942 ;;
943 ;; %%% This is most efficient, but am I gonna get in trouble
944 ;; for separating cc0_setter and cc0_user?
945
946 (define_split
947 [(set (reg:CCFP 18)
948 (compare:CCFP
949 (match_operand:SF 0 "register_operand" "")
950 (float (match_operand:SI 1 "register_operand" ""))))]
951 "0 && TARGET_80387 && reload_completed"
952 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
953 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
954 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
955 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
956 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
957 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
958
959 ;; FP compares, step 2
960 ;; Move the fpsw to ax.
961
962 (define_insn "*x86_fnstsw_1"
963 [(set (match_operand:HI 0 "register_operand" "=a")
964 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
965 "TARGET_80387"
966 "fnstsw\t%0"
967 [(set_attr "length" "2")
968 (set_attr "mode" "SI")
969 (set_attr "unit" "i387")
970 (set_attr "ppro_uops" "few")])
971
972 ;; FP compares, step 3
973 ;; Get ax into flags, general case.
974
975 (define_insn "x86_sahf_1"
976 [(set (reg:CC 17)
977 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
978 "!TARGET_64BIT"
979 "sahf"
980 [(set_attr "length" "1")
981 (set_attr "athlon_decode" "vector")
982 (set_attr "mode" "SI")
983 (set_attr "ppro_uops" "one")])
984
985 ;; Pentium Pro can do steps 1 through 3 in one go.
986
987 (define_insn "*cmpfp_i"
988 [(set (reg:CCFP 17)
989 (compare:CCFP (match_operand 0 "register_operand" "f")
990 (match_operand 1 "register_operand" "f")))]
991 "TARGET_80387 && TARGET_CMOVE
992 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
993 && FLOAT_MODE_P (GET_MODE (operands[0]))
994 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
995 "* return output_fp_compare (insn, operands, 1, 0);"
996 [(set_attr "type" "fcmp")
997 (set (attr "mode")
998 (cond [(match_operand:SF 1 "" "")
999 (const_string "SF")
1000 (match_operand:DF 1 "" "")
1001 (const_string "DF")
1002 ]
1003 (const_string "XF")))
1004 (set_attr "athlon_decode" "vector")])
1005
1006 (define_insn "*cmpfp_i_sse"
1007 [(set (reg:CCFP 17)
1008 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1009 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1010 "TARGET_80387
1011 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1012 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1013 "* return output_fp_compare (insn, operands, 1, 0);"
1014 [(set_attr "type" "fcmp,ssecomi")
1015 (set (attr "mode")
1016 (if_then_else (match_operand:SF 1 "" "")
1017 (const_string "SF")
1018 (const_string "DF")))
1019 (set_attr "athlon_decode" "vector")])
1020
1021 (define_insn "*cmpfp_i_sse_only"
1022 [(set (reg:CCFP 17)
1023 (compare:CCFP (match_operand 0 "register_operand" "x")
1024 (match_operand 1 "nonimmediate_operand" "xm")))]
1025 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1026 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1027 "* return output_fp_compare (insn, operands, 1, 0);"
1028 [(set_attr "type" "ssecomi")
1029 (set (attr "mode")
1030 (if_then_else (match_operand:SF 1 "" "")
1031 (const_string "SF")
1032 (const_string "DF")))
1033 (set_attr "athlon_decode" "vector")])
1034
1035 (define_insn "*cmpfp_iu"
1036 [(set (reg:CCFPU 17)
1037 (compare:CCFPU (match_operand 0 "register_operand" "f")
1038 (match_operand 1 "register_operand" "f")))]
1039 "TARGET_80387 && TARGET_CMOVE
1040 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1041 && FLOAT_MODE_P (GET_MODE (operands[0]))
1042 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1043 "* return output_fp_compare (insn, operands, 1, 1);"
1044 [(set_attr "type" "fcmp")
1045 (set (attr "mode")
1046 (cond [(match_operand:SF 1 "" "")
1047 (const_string "SF")
1048 (match_operand:DF 1 "" "")
1049 (const_string "DF")
1050 ]
1051 (const_string "XF")))
1052 (set_attr "athlon_decode" "vector")])
1053
1054 (define_insn "*cmpfp_iu_sse"
1055 [(set (reg:CCFPU 17)
1056 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1057 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1058 "TARGET_80387
1059 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1060 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1061 "* return output_fp_compare (insn, operands, 1, 1);"
1062 [(set_attr "type" "fcmp,ssecomi")
1063 (set (attr "mode")
1064 (if_then_else (match_operand:SF 1 "" "")
1065 (const_string "SF")
1066 (const_string "DF")))
1067 (set_attr "athlon_decode" "vector")])
1068
1069 (define_insn "*cmpfp_iu_sse_only"
1070 [(set (reg:CCFPU 17)
1071 (compare:CCFPU (match_operand 0 "register_operand" "x")
1072 (match_operand 1 "nonimmediate_operand" "xm")))]
1073 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1074 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1075 "* return output_fp_compare (insn, operands, 1, 1);"
1076 [(set_attr "type" "ssecomi")
1077 (set (attr "mode")
1078 (if_then_else (match_operand:SF 1 "" "")
1079 (const_string "SF")
1080 (const_string "DF")))
1081 (set_attr "athlon_decode" "vector")])
1082 \f
1083 ;; Move instructions.
1084
1085 ;; General case of fullword move.
1086
1087 (define_expand "movsi"
1088 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1089 (match_operand:SI 1 "general_operand" ""))]
1090 ""
1091 "ix86_expand_move (SImode, operands); DONE;")
1092
1093 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1094 ;; general_operand.
1095 ;;
1096 ;; %%% We don't use a post-inc memory reference because x86 is not a
1097 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1098 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1099 ;; targets without our curiosities, and it is just as easy to represent
1100 ;; this differently.
1101
1102 (define_insn "*pushsi2"
1103 [(set (match_operand:SI 0 "push_operand" "=<")
1104 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1105 "!TARGET_64BIT"
1106 "push{l}\t%1"
1107 [(set_attr "type" "push")
1108 (set_attr "mode" "SI")])
1109
1110 ;; For 64BIT abi we always round up to 8 bytes.
1111 (define_insn "*pushsi2_rex64"
1112 [(set (match_operand:SI 0 "push_operand" "=X")
1113 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1114 "TARGET_64BIT"
1115 "push{q}\t%q1"
1116 [(set_attr "type" "push")
1117 (set_attr "mode" "SI")])
1118
1119 (define_insn "*pushsi2_prologue"
1120 [(set (match_operand:SI 0 "push_operand" "=<")
1121 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1122 (clobber (mem:BLK (scratch)))]
1123 "!TARGET_64BIT"
1124 "push{l}\t%1"
1125 [(set_attr "type" "push")
1126 (set_attr "mode" "SI")])
1127
1128 (define_insn "*popsi1_epilogue"
1129 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1130 (mem:SI (reg:SI 7)))
1131 (set (reg:SI 7)
1132 (plus:SI (reg:SI 7) (const_int 4)))
1133 (clobber (mem:BLK (scratch)))]
1134 "!TARGET_64BIT"
1135 "pop{l}\t%0"
1136 [(set_attr "type" "pop")
1137 (set_attr "mode" "SI")])
1138
1139 (define_insn "popsi1"
1140 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1141 (mem:SI (reg:SI 7)))
1142 (set (reg:SI 7)
1143 (plus:SI (reg:SI 7) (const_int 4)))]
1144 "!TARGET_64BIT"
1145 "pop{l}\t%0"
1146 [(set_attr "type" "pop")
1147 (set_attr "mode" "SI")])
1148
1149 (define_insn "*movsi_xor"
1150 [(set (match_operand:SI 0 "register_operand" "=r")
1151 (match_operand:SI 1 "const0_operand" "i"))
1152 (clobber (reg:CC 17))]
1153 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1154 "xor{l}\t{%0, %0|%0, %0}"
1155 [(set_attr "type" "alu1")
1156 (set_attr "mode" "SI")
1157 (set_attr "length_immediate" "0")])
1158
1159 (define_insn "*movsi_or"
1160 [(set (match_operand:SI 0 "register_operand" "=r")
1161 (match_operand:SI 1 "immediate_operand" "i"))
1162 (clobber (reg:CC 17))]
1163 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1164 && INTVAL (operands[1]) == -1
1165 && (TARGET_PENTIUM || optimize_size)"
1166 {
1167 operands[1] = constm1_rtx;
1168 return "or{l}\t{%1, %0|%0, %1}";
1169 }
1170 [(set_attr "type" "alu1")
1171 (set_attr "mode" "SI")
1172 (set_attr "length_immediate" "1")])
1173
1174 (define_insn "*movsi_1"
1175 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1176 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1177 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1178 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1179 {
1180 switch (get_attr_type (insn))
1181 {
1182 case TYPE_SSEMOV:
1183 if (get_attr_mode (insn) == MODE_TI)
1184 return "movdqa\t{%1, %0|%0, %1}";
1185 return "movd\t{%1, %0|%0, %1}";
1186
1187 case TYPE_MMXMOV:
1188 if (get_attr_mode (insn) == MODE_DI)
1189 return "movq\t{%1, %0|%0, %1}";
1190 return "movd\t{%1, %0|%0, %1}";
1191
1192 case TYPE_LEA:
1193 return "lea{l}\t{%1, %0|%0, %1}";
1194
1195 default:
1196 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1197 abort();
1198 return "mov{l}\t{%1, %0|%0, %1}";
1199 }
1200 }
1201 [(set (attr "type")
1202 (cond [(eq_attr "alternative" "2,3,4")
1203 (const_string "mmxmov")
1204 (eq_attr "alternative" "5,6,7")
1205 (const_string "ssemov")
1206 (and (ne (symbol_ref "flag_pic") (const_int 0))
1207 (match_operand:SI 1 "symbolic_operand" ""))
1208 (const_string "lea")
1209 ]
1210 (const_string "imov")))
1211 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1212
1213 (define_insn "*movsi_1_nointernunit"
1214 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1215 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1216 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1217 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1218 {
1219 switch (get_attr_type (insn))
1220 {
1221 case TYPE_SSEMOV:
1222 if (get_attr_mode (insn) == MODE_TI)
1223 return "movdqa\t{%1, %0|%0, %1}";
1224 return "movd\t{%1, %0|%0, %1}";
1225
1226 case TYPE_MMXMOV:
1227 if (get_attr_mode (insn) == MODE_DI)
1228 return "movq\t{%1, %0|%0, %1}";
1229 return "movd\t{%1, %0|%0, %1}";
1230
1231 case TYPE_LEA:
1232 return "lea{l}\t{%1, %0|%0, %1}";
1233
1234 default:
1235 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1236 abort();
1237 return "mov{l}\t{%1, %0|%0, %1}";
1238 }
1239 }
1240 [(set (attr "type")
1241 (cond [(eq_attr "alternative" "2,3,4")
1242 (const_string "mmxmov")
1243 (eq_attr "alternative" "5,6,7")
1244 (const_string "ssemov")
1245 (and (ne (symbol_ref "flag_pic") (const_int 0))
1246 (match_operand:SI 1 "symbolic_operand" ""))
1247 (const_string "lea")
1248 ]
1249 (const_string "imov")))
1250 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1251
1252 ;; Stores and loads of ax to arbitrary constant address.
1253 ;; We fake an second form of instruction to force reload to load address
1254 ;; into register when rax is not available
1255 (define_insn "*movabssi_1_rex64"
1256 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1257 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1258 "TARGET_64BIT"
1259 "@
1260 movabs{l}\t{%1, %P0|%P0, %1}
1261 mov{l}\t{%1, %a0|%a0, %1}
1262 movabs{l}\t{%1, %a0|%a0, %1}"
1263 [(set_attr "type" "imov")
1264 (set_attr "modrm" "0,*,*")
1265 (set_attr "length_address" "8,0,0")
1266 (set_attr "length_immediate" "0,*,*")
1267 (set_attr "memory" "store")
1268 (set_attr "mode" "SI")])
1269
1270 (define_insn "*movabssi_2_rex64"
1271 [(set (match_operand:SI 0 "register_operand" "=a,r")
1272 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1273 "TARGET_64BIT"
1274 "@
1275 movabs{l}\t{%P1, %0|%0, %P1}
1276 mov{l}\t{%a1, %0|%0, %a1}"
1277 [(set_attr "type" "imov")
1278 (set_attr "modrm" "0,*")
1279 (set_attr "length_address" "8,0")
1280 (set_attr "length_immediate" "0")
1281 (set_attr "memory" "load")
1282 (set_attr "mode" "SI")])
1283
1284 (define_insn "*swapsi"
1285 [(set (match_operand:SI 0 "register_operand" "+r")
1286 (match_operand:SI 1 "register_operand" "+r"))
1287 (set (match_dup 1)
1288 (match_dup 0))]
1289 ""
1290 "xchg{l}\t%1, %0"
1291 [(set_attr "type" "imov")
1292 (set_attr "pent_pair" "np")
1293 (set_attr "athlon_decode" "vector")
1294 (set_attr "mode" "SI")
1295 (set_attr "modrm" "0")
1296 (set_attr "ppro_uops" "few")])
1297
1298 (define_expand "movhi"
1299 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1300 (match_operand:HI 1 "general_operand" ""))]
1301 ""
1302 "ix86_expand_move (HImode, operands); DONE;")
1303
1304 (define_insn "*pushhi2"
1305 [(set (match_operand:HI 0 "push_operand" "=<,<")
1306 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1307 "!TARGET_64BIT"
1308 "@
1309 push{w}\t{|WORD PTR }%1
1310 push{w}\t%1"
1311 [(set_attr "type" "push")
1312 (set_attr "mode" "HI")])
1313
1314 ;; For 64BIT abi we always round up to 8 bytes.
1315 (define_insn "*pushhi2_rex64"
1316 [(set (match_operand:HI 0 "push_operand" "=X")
1317 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1318 "TARGET_64BIT"
1319 "push{q}\t%q1"
1320 [(set_attr "type" "push")
1321 (set_attr "mode" "QI")])
1322
1323 (define_insn "*movhi_1"
1324 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1325 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1326 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1327 {
1328 switch (get_attr_type (insn))
1329 {
1330 case TYPE_IMOVX:
1331 /* movzwl is faster than movw on p2 due to partial word stalls,
1332 though not as fast as an aligned movl. */
1333 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1334 default:
1335 if (get_attr_mode (insn) == MODE_SI)
1336 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1337 else
1338 return "mov{w}\t{%1, %0|%0, %1}";
1339 }
1340 }
1341 [(set (attr "type")
1342 (cond [(and (eq_attr "alternative" "0")
1343 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1344 (const_int 0))
1345 (eq (symbol_ref "TARGET_HIMODE_MATH")
1346 (const_int 0))))
1347 (const_string "imov")
1348 (and (eq_attr "alternative" "1,2")
1349 (match_operand:HI 1 "aligned_operand" ""))
1350 (const_string "imov")
1351 (and (ne (symbol_ref "TARGET_MOVX")
1352 (const_int 0))
1353 (eq_attr "alternative" "0,2"))
1354 (const_string "imovx")
1355 ]
1356 (const_string "imov")))
1357 (set (attr "mode")
1358 (cond [(eq_attr "type" "imovx")
1359 (const_string "SI")
1360 (and (eq_attr "alternative" "1,2")
1361 (match_operand:HI 1 "aligned_operand" ""))
1362 (const_string "SI")
1363 (and (eq_attr "alternative" "0")
1364 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1365 (const_int 0))
1366 (eq (symbol_ref "TARGET_HIMODE_MATH")
1367 (const_int 0))))
1368 (const_string "SI")
1369 ]
1370 (const_string "HI")))])
1371
1372 ;; Stores and loads of ax to arbitrary constant address.
1373 ;; We fake an second form of instruction to force reload to load address
1374 ;; into register when rax is not available
1375 (define_insn "*movabshi_1_rex64"
1376 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1377 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1378 "TARGET_64BIT"
1379 "@
1380 movabs{w}\t{%1, %P0|%P0, %1}
1381 mov{w}\t{%1, %a0|%a0, %1}
1382 movabs{w}\t{%1, %a0|%a0, %1}"
1383 [(set_attr "type" "imov")
1384 (set_attr "modrm" "0,*,*")
1385 (set_attr "length_address" "8,0,0")
1386 (set_attr "length_immediate" "0,*,*")
1387 (set_attr "memory" "store")
1388 (set_attr "mode" "HI")])
1389
1390 (define_insn "*movabshi_2_rex64"
1391 [(set (match_operand:HI 0 "register_operand" "=a,r")
1392 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1393 "TARGET_64BIT"
1394 "@
1395 movabs{w}\t{%P1, %0|%0, %P1}
1396 mov{w}\t{%a1, %0|%0, %a1}"
1397 [(set_attr "type" "imov")
1398 (set_attr "modrm" "0,*")
1399 (set_attr "length_address" "8,0")
1400 (set_attr "length_immediate" "0")
1401 (set_attr "memory" "load")
1402 (set_attr "mode" "HI")])
1403
1404 (define_insn "*swaphi_1"
1405 [(set (match_operand:HI 0 "register_operand" "+r")
1406 (match_operand:HI 1 "register_operand" "+r"))
1407 (set (match_dup 1)
1408 (match_dup 0))]
1409 "TARGET_PARTIAL_REG_STALL"
1410 "xchg{w}\t%1, %0"
1411 [(set_attr "type" "imov")
1412 (set_attr "pent_pair" "np")
1413 (set_attr "mode" "HI")
1414 (set_attr "modrm" "0")
1415 (set_attr "ppro_uops" "few")])
1416
1417 (define_insn "*swaphi_2"
1418 [(set (match_operand:HI 0 "register_operand" "+r")
1419 (match_operand:HI 1 "register_operand" "+r"))
1420 (set (match_dup 1)
1421 (match_dup 0))]
1422 "! TARGET_PARTIAL_REG_STALL"
1423 "xchg{l}\t%k1, %k0"
1424 [(set_attr "type" "imov")
1425 (set_attr "pent_pair" "np")
1426 (set_attr "mode" "SI")
1427 (set_attr "modrm" "0")
1428 (set_attr "ppro_uops" "few")])
1429
1430 (define_expand "movstricthi"
1431 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1432 (match_operand:HI 1 "general_operand" ""))]
1433 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1434 {
1435 /* Don't generate memory->memory moves, go through a register */
1436 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1437 operands[1] = force_reg (HImode, operands[1]);
1438 })
1439
1440 (define_insn "*movstricthi_1"
1441 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1442 (match_operand:HI 1 "general_operand" "rn,m"))]
1443 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1444 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1445 "mov{w}\t{%1, %0|%0, %1}"
1446 [(set_attr "type" "imov")
1447 (set_attr "mode" "HI")])
1448
1449 (define_insn "*movstricthi_xor"
1450 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1451 (match_operand:HI 1 "const0_operand" "i"))
1452 (clobber (reg:CC 17))]
1453 "reload_completed
1454 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1455 "xor{w}\t{%0, %0|%0, %0}"
1456 [(set_attr "type" "alu1")
1457 (set_attr "mode" "HI")
1458 (set_attr "length_immediate" "0")])
1459
1460 (define_expand "movqi"
1461 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1462 (match_operand:QI 1 "general_operand" ""))]
1463 ""
1464 "ix86_expand_move (QImode, operands); DONE;")
1465
1466 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1467 ;; "push a byte". But actually we use pushw, which has the effect
1468 ;; of rounding the amount pushed up to a halfword.
1469
1470 (define_insn "*pushqi2"
1471 [(set (match_operand:QI 0 "push_operand" "=X,X")
1472 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1473 "!TARGET_64BIT"
1474 "@
1475 push{w}\t{|word ptr }%1
1476 push{w}\t%w1"
1477 [(set_attr "type" "push")
1478 (set_attr "mode" "HI")])
1479
1480 ;; For 64BIT abi we always round up to 8 bytes.
1481 (define_insn "*pushqi2_rex64"
1482 [(set (match_operand:QI 0 "push_operand" "=X")
1483 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1484 "TARGET_64BIT"
1485 "push{q}\t%q1"
1486 [(set_attr "type" "push")
1487 (set_attr "mode" "QI")])
1488
1489 ;; Situation is quite tricky about when to choose full sized (SImode) move
1490 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1491 ;; partial register dependency machines (such as AMD Athlon), where QImode
1492 ;; moves issue extra dependency and for partial register stalls machines
1493 ;; that don't use QImode patterns (and QImode move cause stall on the next
1494 ;; instruction).
1495 ;;
1496 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1497 ;; register stall machines with, where we use QImode instructions, since
1498 ;; partial register stall can be caused there. Then we use movzx.
1499 (define_insn "*movqi_1"
1500 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1501 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1502 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1503 {
1504 switch (get_attr_type (insn))
1505 {
1506 case TYPE_IMOVX:
1507 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1508 abort ();
1509 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1510 default:
1511 if (get_attr_mode (insn) == MODE_SI)
1512 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1513 else
1514 return "mov{b}\t{%1, %0|%0, %1}";
1515 }
1516 }
1517 [(set (attr "type")
1518 (cond [(and (eq_attr "alternative" "3")
1519 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1520 (const_int 0))
1521 (eq (symbol_ref "TARGET_QIMODE_MATH")
1522 (const_int 0))))
1523 (const_string "imov")
1524 (eq_attr "alternative" "3,5")
1525 (const_string "imovx")
1526 (and (ne (symbol_ref "TARGET_MOVX")
1527 (const_int 0))
1528 (eq_attr "alternative" "2"))
1529 (const_string "imovx")
1530 ]
1531 (const_string "imov")))
1532 (set (attr "mode")
1533 (cond [(eq_attr "alternative" "3,4,5")
1534 (const_string "SI")
1535 (eq_attr "alternative" "6")
1536 (const_string "QI")
1537 (eq_attr "type" "imovx")
1538 (const_string "SI")
1539 (and (eq_attr "type" "imov")
1540 (and (eq_attr "alternative" "0,1,2")
1541 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1542 (const_int 0))))
1543 (const_string "SI")
1544 ;; Avoid partial register stalls when not using QImode arithmetic
1545 (and (eq_attr "type" "imov")
1546 (and (eq_attr "alternative" "0,1,2")
1547 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1548 (const_int 0))
1549 (eq (symbol_ref "TARGET_QIMODE_MATH")
1550 (const_int 0)))))
1551 (const_string "SI")
1552 ]
1553 (const_string "QI")))])
1554
1555 (define_expand "reload_outqi"
1556 [(parallel [(match_operand:QI 0 "" "=m")
1557 (match_operand:QI 1 "register_operand" "r")
1558 (match_operand:QI 2 "register_operand" "=&q")])]
1559 ""
1560 {
1561 rtx op0, op1, op2;
1562 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1563
1564 if (reg_overlap_mentioned_p (op2, op0))
1565 abort ();
1566 if (! q_regs_operand (op1, QImode))
1567 {
1568 emit_insn (gen_movqi (op2, op1));
1569 op1 = op2;
1570 }
1571 emit_insn (gen_movqi (op0, op1));
1572 DONE;
1573 })
1574
1575 (define_insn "*swapqi"
1576 [(set (match_operand:QI 0 "register_operand" "+r")
1577 (match_operand:QI 1 "register_operand" "+r"))
1578 (set (match_dup 1)
1579 (match_dup 0))]
1580 ""
1581 "xchg{b}\t%1, %0"
1582 [(set_attr "type" "imov")
1583 (set_attr "pent_pair" "np")
1584 (set_attr "mode" "QI")
1585 (set_attr "modrm" "0")
1586 (set_attr "ppro_uops" "few")])
1587
1588 (define_expand "movstrictqi"
1589 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1590 (match_operand:QI 1 "general_operand" ""))]
1591 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1592 {
1593 /* Don't generate memory->memory moves, go through a register. */
1594 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1595 operands[1] = force_reg (QImode, operands[1]);
1596 })
1597
1598 (define_insn "*movstrictqi_1"
1599 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1600 (match_operand:QI 1 "general_operand" "*qn,m"))]
1601 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1602 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1603 "mov{b}\t{%1, %0|%0, %1}"
1604 [(set_attr "type" "imov")
1605 (set_attr "mode" "QI")])
1606
1607 (define_insn "*movstrictqi_xor"
1608 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1609 (match_operand:QI 1 "const0_operand" "i"))
1610 (clobber (reg:CC 17))]
1611 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1612 "xor{b}\t{%0, %0|%0, %0}"
1613 [(set_attr "type" "alu1")
1614 (set_attr "mode" "QI")
1615 (set_attr "length_immediate" "0")])
1616
1617 (define_insn "*movsi_extv_1"
1618 [(set (match_operand:SI 0 "register_operand" "=R")
1619 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1620 (const_int 8)
1621 (const_int 8)))]
1622 ""
1623 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1624 [(set_attr "type" "imovx")
1625 (set_attr "mode" "SI")])
1626
1627 (define_insn "*movhi_extv_1"
1628 [(set (match_operand:HI 0 "register_operand" "=R")
1629 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1630 (const_int 8)
1631 (const_int 8)))]
1632 ""
1633 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1634 [(set_attr "type" "imovx")
1635 (set_attr "mode" "SI")])
1636
1637 (define_insn "*movqi_extv_1"
1638 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1639 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1640 (const_int 8)
1641 (const_int 8)))]
1642 "!TARGET_64BIT"
1643 {
1644 switch (get_attr_type (insn))
1645 {
1646 case TYPE_IMOVX:
1647 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1648 default:
1649 return "mov{b}\t{%h1, %0|%0, %h1}";
1650 }
1651 }
1652 [(set (attr "type")
1653 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1654 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1655 (ne (symbol_ref "TARGET_MOVX")
1656 (const_int 0))))
1657 (const_string "imovx")
1658 (const_string "imov")))
1659 (set (attr "mode")
1660 (if_then_else (eq_attr "type" "imovx")
1661 (const_string "SI")
1662 (const_string "QI")))])
1663
1664 (define_insn "*movqi_extv_1_rex64"
1665 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1666 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1667 (const_int 8)
1668 (const_int 8)))]
1669 "TARGET_64BIT"
1670 {
1671 switch (get_attr_type (insn))
1672 {
1673 case TYPE_IMOVX:
1674 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1675 default:
1676 return "mov{b}\t{%h1, %0|%0, %h1}";
1677 }
1678 }
1679 [(set (attr "type")
1680 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1681 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1682 (ne (symbol_ref "TARGET_MOVX")
1683 (const_int 0))))
1684 (const_string "imovx")
1685 (const_string "imov")))
1686 (set (attr "mode")
1687 (if_then_else (eq_attr "type" "imovx")
1688 (const_string "SI")
1689 (const_string "QI")))])
1690
1691 ;; Stores and loads of ax to arbitrary constant address.
1692 ;; We fake an second form of instruction to force reload to load address
1693 ;; into register when rax is not available
1694 (define_insn "*movabsqi_1_rex64"
1695 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1696 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1697 "TARGET_64BIT"
1698 "@
1699 movabs{b}\t{%1, %P0|%P0, %1}
1700 mov{b}\t{%1, %a0|%a0, %1}
1701 movabs{b}\t{%1, %a0|%a0, %1}"
1702 [(set_attr "type" "imov")
1703 (set_attr "modrm" "0,*,*")
1704 (set_attr "length_address" "8,0,0")
1705 (set_attr "length_immediate" "0,*,*")
1706 (set_attr "memory" "store")
1707 (set_attr "mode" "QI")])
1708
1709 (define_insn "*movabsqi_2_rex64"
1710 [(set (match_operand:QI 0 "register_operand" "=a,r")
1711 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1712 "TARGET_64BIT"
1713 "@
1714 movabs{b}\t{%P1, %0|%0, %P1}
1715 mov{b}\t{%a1, %0|%0, %a1}"
1716 [(set_attr "type" "imov")
1717 (set_attr "modrm" "0,*")
1718 (set_attr "length_address" "8,0")
1719 (set_attr "length_immediate" "0")
1720 (set_attr "memory" "load")
1721 (set_attr "mode" "QI")])
1722
1723 (define_insn "*movsi_extzv_1"
1724 [(set (match_operand:SI 0 "register_operand" "=R")
1725 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1726 (const_int 8)
1727 (const_int 8)))]
1728 ""
1729 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1730 [(set_attr "type" "imovx")
1731 (set_attr "mode" "SI")])
1732
1733 (define_insn "*movqi_extzv_2"
1734 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1735 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1736 (const_int 8)
1737 (const_int 8)) 0))]
1738 "!TARGET_64BIT"
1739 {
1740 switch (get_attr_type (insn))
1741 {
1742 case TYPE_IMOVX:
1743 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1744 default:
1745 return "mov{b}\t{%h1, %0|%0, %h1}";
1746 }
1747 }
1748 [(set (attr "type")
1749 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1750 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1751 (ne (symbol_ref "TARGET_MOVX")
1752 (const_int 0))))
1753 (const_string "imovx")
1754 (const_string "imov")))
1755 (set (attr "mode")
1756 (if_then_else (eq_attr "type" "imovx")
1757 (const_string "SI")
1758 (const_string "QI")))])
1759
1760 (define_insn "*movqi_extzv_2_rex64"
1761 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1762 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1763 (const_int 8)
1764 (const_int 8)) 0))]
1765 "TARGET_64BIT"
1766 {
1767 switch (get_attr_type (insn))
1768 {
1769 case TYPE_IMOVX:
1770 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1771 default:
1772 return "mov{b}\t{%h1, %0|%0, %h1}";
1773 }
1774 }
1775 [(set (attr "type")
1776 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1777 (ne (symbol_ref "TARGET_MOVX")
1778 (const_int 0)))
1779 (const_string "imovx")
1780 (const_string "imov")))
1781 (set (attr "mode")
1782 (if_then_else (eq_attr "type" "imovx")
1783 (const_string "SI")
1784 (const_string "QI")))])
1785
1786 (define_insn "movsi_insv_1"
1787 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1788 (const_int 8)
1789 (const_int 8))
1790 (match_operand:SI 1 "general_operand" "Qmn"))]
1791 "!TARGET_64BIT"
1792 "mov{b}\t{%b1, %h0|%h0, %b1}"
1793 [(set_attr "type" "imov")
1794 (set_attr "mode" "QI")])
1795
1796 (define_insn "*movsi_insv_1_rex64"
1797 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1798 (const_int 8)
1799 (const_int 8))
1800 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1801 "TARGET_64BIT"
1802 "mov{b}\t{%b1, %h0|%h0, %b1}"
1803 [(set_attr "type" "imov")
1804 (set_attr "mode" "QI")])
1805
1806 (define_insn "*movqi_insv_2"
1807 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1808 (const_int 8)
1809 (const_int 8))
1810 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1811 (const_int 8))
1812 (const_int 255)))]
1813 ""
1814 "mov{b}\t{%h1, %h0|%h0, %h1}"
1815 [(set_attr "type" "imov")
1816 (set_attr "mode" "QI")])
1817
1818 (define_expand "movdi"
1819 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1820 (match_operand:DI 1 "general_operand" ""))]
1821 ""
1822 "ix86_expand_move (DImode, operands); DONE;")
1823
1824 (define_insn "*pushdi"
1825 [(set (match_operand:DI 0 "push_operand" "=<")
1826 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1827 "!TARGET_64BIT"
1828 "#")
1829
1830 (define_insn "pushdi2_rex64"
1831 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1832 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1833 "TARGET_64BIT"
1834 "@
1835 push{q}\t%1
1836 #"
1837 [(set_attr "type" "push,multi")
1838 (set_attr "mode" "DI")])
1839
1840 ;; Convert impossible pushes of immediate to existing instructions.
1841 ;; First try to get scratch register and go through it. In case this
1842 ;; fails, push sign extended lower part first and then overwrite
1843 ;; upper part by 32bit move.
1844 (define_peephole2
1845 [(match_scratch:DI 2 "r")
1846 (set (match_operand:DI 0 "push_operand" "")
1847 (match_operand:DI 1 "immediate_operand" ""))]
1848 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1849 && !x86_64_immediate_operand (operands[1], DImode)"
1850 [(set (match_dup 2) (match_dup 1))
1851 (set (match_dup 0) (match_dup 2))]
1852 "")
1853
1854 ;; We need to define this as both peepholer and splitter for case
1855 ;; peephole2 pass is not run.
1856 (define_peephole2
1857 [(set (match_operand:DI 0 "push_operand" "")
1858 (match_operand:DI 1 "immediate_operand" ""))]
1859 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1860 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1861 [(set (match_dup 0) (match_dup 1))
1862 (set (match_dup 2) (match_dup 3))]
1863 "split_di (operands + 1, 1, operands + 2, operands + 3);
1864 operands[1] = gen_lowpart (DImode, operands[2]);
1865 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1866 GEN_INT (4)));
1867 ")
1868
1869 (define_split
1870 [(set (match_operand:DI 0 "push_operand" "")
1871 (match_operand:DI 1 "immediate_operand" ""))]
1872 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1873 && !symbolic_operand (operands[1], DImode)
1874 && !x86_64_immediate_operand (operands[1], DImode)"
1875 [(set (match_dup 0) (match_dup 1))
1876 (set (match_dup 2) (match_dup 3))]
1877 "split_di (operands + 1, 1, operands + 2, operands + 3);
1878 operands[1] = gen_lowpart (DImode, operands[2]);
1879 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1880 GEN_INT (4)));
1881 ")
1882
1883 (define_insn "*pushdi2_prologue_rex64"
1884 [(set (match_operand:DI 0 "push_operand" "=<")
1885 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1886 (clobber (mem:BLK (scratch)))]
1887 "TARGET_64BIT"
1888 "push{q}\t%1"
1889 [(set_attr "type" "push")
1890 (set_attr "mode" "DI")])
1891
1892 (define_insn "*popdi1_epilogue_rex64"
1893 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1894 (mem:DI (reg:DI 7)))
1895 (set (reg:DI 7)
1896 (plus:DI (reg:DI 7) (const_int 8)))
1897 (clobber (mem:BLK (scratch)))]
1898 "TARGET_64BIT"
1899 "pop{q}\t%0"
1900 [(set_attr "type" "pop")
1901 (set_attr "mode" "DI")])
1902
1903 (define_insn "popdi1"
1904 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1905 (mem:DI (reg:DI 7)))
1906 (set (reg:DI 7)
1907 (plus:DI (reg:DI 7) (const_int 8)))]
1908 "TARGET_64BIT"
1909 "pop{q}\t%0"
1910 [(set_attr "type" "pop")
1911 (set_attr "mode" "DI")])
1912
1913 (define_insn "*movdi_xor_rex64"
1914 [(set (match_operand:DI 0 "register_operand" "=r")
1915 (match_operand:DI 1 "const0_operand" "i"))
1916 (clobber (reg:CC 17))]
1917 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1918 && reload_completed"
1919 "xor{l}\t{%k0, %k0|%k0, %k0}"
1920 [(set_attr "type" "alu1")
1921 (set_attr "mode" "SI")
1922 (set_attr "length_immediate" "0")])
1923
1924 (define_insn "*movdi_or_rex64"
1925 [(set (match_operand:DI 0 "register_operand" "=r")
1926 (match_operand:DI 1 "const_int_operand" "i"))
1927 (clobber (reg:CC 17))]
1928 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1929 && reload_completed
1930 && GET_CODE (operands[1]) == CONST_INT
1931 && INTVAL (operands[1]) == -1"
1932 {
1933 operands[1] = constm1_rtx;
1934 return "or{q}\t{%1, %0|%0, %1}";
1935 }
1936 [(set_attr "type" "alu1")
1937 (set_attr "mode" "DI")
1938 (set_attr "length_immediate" "1")])
1939
1940 (define_insn "*movdi_2"
1941 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1942 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1943 "!TARGET_64BIT
1944 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1945 "@
1946 #
1947 #
1948 movq\t{%1, %0|%0, %1}
1949 movq\t{%1, %0|%0, %1}
1950 movq\t{%1, %0|%0, %1}
1951 movdqa\t{%1, %0|%0, %1}
1952 movq\t{%1, %0|%0, %1}"
1953 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1954 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1955
1956 (define_split
1957 [(set (match_operand:DI 0 "push_operand" "")
1958 (match_operand:DI 1 "general_operand" ""))]
1959 "!TARGET_64BIT && reload_completed
1960 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1961 [(const_int 0)]
1962 "ix86_split_long_move (operands); DONE;")
1963
1964 ;; %%% This multiword shite has got to go.
1965 (define_split
1966 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1967 (match_operand:DI 1 "general_operand" ""))]
1968 "!TARGET_64BIT && reload_completed
1969 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1970 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1971 [(const_int 0)]
1972 "ix86_split_long_move (operands); DONE;")
1973
1974 (define_insn "*movdi_1_rex64"
1975 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1976 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1977 "TARGET_64BIT
1978 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1979 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1980 {
1981 switch (get_attr_type (insn))
1982 {
1983 case TYPE_SSEMOV:
1984 if (get_attr_mode (insn) == MODE_TI)
1985 return "movdqa\t{%1, %0|%0, %1}";
1986 /* FALLTHRU */
1987 case TYPE_MMXMOV:
1988 /* Moves from and into integer register is done using movd opcode with
1989 REX prefix. */
1990 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1991 return "movd\t{%1, %0|%0, %1}";
1992 return "movq\t{%1, %0|%0, %1}";
1993 case TYPE_MULTI:
1994 return "#";
1995 case TYPE_LEA:
1996 return "lea{q}\t{%a1, %0|%0, %a1}";
1997 default:
1998 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1999 abort ();
2000 if (get_attr_mode (insn) == MODE_SI)
2001 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2002 else if (which_alternative == 2)
2003 return "movabs{q}\t{%1, %0|%0, %1}";
2004 else
2005 return "mov{q}\t{%1, %0|%0, %1}";
2006 }
2007 }
2008 [(set (attr "type")
2009 (cond [(eq_attr "alternative" "5,6,7")
2010 (const_string "mmxmov")
2011 (eq_attr "alternative" "8,9,10")
2012 (const_string "ssemov")
2013 (eq_attr "alternative" "4")
2014 (const_string "multi")
2015 (and (ne (symbol_ref "flag_pic") (const_int 0))
2016 (match_operand:DI 1 "symbolic_operand" ""))
2017 (const_string "lea")
2018 ]
2019 (const_string "imov")))
2020 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2021 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2022 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2023
2024 (define_insn "*movdi_1_rex64_nointerunit"
2025 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2026 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2027 "TARGET_64BIT
2028 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2029 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2030 {
2031 switch (get_attr_type (insn))
2032 {
2033 case TYPE_SSEMOV:
2034 if (get_attr_mode (insn) == MODE_TI)
2035 return "movdqa\t{%1, %0|%0, %1}";
2036 /* FALLTHRU */
2037 case TYPE_MMXMOV:
2038 return "movq\t{%1, %0|%0, %1}";
2039 case TYPE_MULTI:
2040 return "#";
2041 case TYPE_LEA:
2042 return "lea{q}\t{%a1, %0|%0, %a1}";
2043 default:
2044 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2045 abort ();
2046 if (get_attr_mode (insn) == MODE_SI)
2047 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2048 else if (which_alternative == 2)
2049 return "movabs{q}\t{%1, %0|%0, %1}";
2050 else
2051 return "mov{q}\t{%1, %0|%0, %1}";
2052 }
2053 }
2054 [(set (attr "type")
2055 (cond [(eq_attr "alternative" "5,6,7")
2056 (const_string "mmxmov")
2057 (eq_attr "alternative" "8,9,10")
2058 (const_string "ssemov")
2059 (eq_attr "alternative" "4")
2060 (const_string "multi")
2061 (and (ne (symbol_ref "flag_pic") (const_int 0))
2062 (match_operand:DI 1 "symbolic_operand" ""))
2063 (const_string "lea")
2064 ]
2065 (const_string "imov")))
2066 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2067 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2068 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2069
2070 ;; Stores and loads of ax to arbitrary constant address.
2071 ;; We fake an second form of instruction to force reload to load address
2072 ;; into register when rax is not available
2073 (define_insn "*movabsdi_1_rex64"
2074 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2075 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2076 "TARGET_64BIT"
2077 "@
2078 movabs{q}\t{%1, %P0|%P0, %1}
2079 mov{q}\t{%1, %a0|%a0, %1}
2080 movabs{q}\t{%1, %a0|%a0, %1}"
2081 [(set_attr "type" "imov")
2082 (set_attr "modrm" "0,*,*")
2083 (set_attr "length_address" "8,0,0")
2084 (set_attr "length_immediate" "0,*,*")
2085 (set_attr "memory" "store")
2086 (set_attr "mode" "DI")])
2087
2088 (define_insn "*movabsdi_2_rex64"
2089 [(set (match_operand:DI 0 "register_operand" "=a,r")
2090 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2091 "TARGET_64BIT"
2092 "@
2093 movabs{q}\t{%P1, %0|%0, %P1}
2094 mov{q}\t{%a1, %0|%0, %a1}"
2095 [(set_attr "type" "imov")
2096 (set_attr "modrm" "0,*")
2097 (set_attr "length_address" "8,0")
2098 (set_attr "length_immediate" "0")
2099 (set_attr "memory" "load")
2100 (set_attr "mode" "DI")])
2101
2102 ;; Convert impossible stores of immediate to existing instructions.
2103 ;; First try to get scratch register and go through it. In case this
2104 ;; fails, move by 32bit parts.
2105 (define_peephole2
2106 [(match_scratch:DI 2 "r")
2107 (set (match_operand:DI 0 "memory_operand" "")
2108 (match_operand:DI 1 "immediate_operand" ""))]
2109 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2110 && !x86_64_immediate_operand (operands[1], DImode)"
2111 [(set (match_dup 2) (match_dup 1))
2112 (set (match_dup 0) (match_dup 2))]
2113 "")
2114
2115 ;; We need to define this as both peepholer and splitter for case
2116 ;; peephole2 pass is not run.
2117 (define_peephole2
2118 [(set (match_operand:DI 0 "memory_operand" "")
2119 (match_operand:DI 1 "immediate_operand" ""))]
2120 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2121 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2122 [(set (match_dup 2) (match_dup 3))
2123 (set (match_dup 4) (match_dup 5))]
2124 "split_di (operands, 2, operands + 2, operands + 4);")
2125
2126 (define_split
2127 [(set (match_operand:DI 0 "memory_operand" "")
2128 (match_operand:DI 1 "immediate_operand" ""))]
2129 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2130 && !symbolic_operand (operands[1], DImode)
2131 && !x86_64_immediate_operand (operands[1], DImode)"
2132 [(set (match_dup 2) (match_dup 3))
2133 (set (match_dup 4) (match_dup 5))]
2134 "split_di (operands, 2, operands + 2, operands + 4);")
2135
2136 (define_insn "*swapdi_rex64"
2137 [(set (match_operand:DI 0 "register_operand" "+r")
2138 (match_operand:DI 1 "register_operand" "+r"))
2139 (set (match_dup 1)
2140 (match_dup 0))]
2141 "TARGET_64BIT"
2142 "xchg{q}\t%1, %0"
2143 [(set_attr "type" "imov")
2144 (set_attr "pent_pair" "np")
2145 (set_attr "athlon_decode" "vector")
2146 (set_attr "mode" "DI")
2147 (set_attr "modrm" "0")
2148 (set_attr "ppro_uops" "few")])
2149
2150
2151 (define_expand "movsf"
2152 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2153 (match_operand:SF 1 "general_operand" ""))]
2154 ""
2155 "ix86_expand_move (SFmode, operands); DONE;")
2156
2157 (define_insn "*pushsf"
2158 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2159 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2160 "!TARGET_64BIT"
2161 {
2162 switch (which_alternative)
2163 {
2164 case 1:
2165 return "push{l}\t%1";
2166
2167 default:
2168 /* This insn should be already splitted before reg-stack. */
2169 abort ();
2170 }
2171 }
2172 [(set_attr "type" "multi,push,multi")
2173 (set_attr "mode" "SF,SI,SF")])
2174
2175 (define_insn "*pushsf_rex64"
2176 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2177 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2178 "TARGET_64BIT"
2179 {
2180 switch (which_alternative)
2181 {
2182 case 1:
2183 return "push{q}\t%q1";
2184
2185 default:
2186 /* This insn should be already splitted before reg-stack. */
2187 abort ();
2188 }
2189 }
2190 [(set_attr "type" "multi,push,multi")
2191 (set_attr "mode" "SF,DI,SF")])
2192
2193 (define_split
2194 [(set (match_operand:SF 0 "push_operand" "")
2195 (match_operand:SF 1 "memory_operand" ""))]
2196 "reload_completed
2197 && GET_CODE (operands[1]) == MEM
2198 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2199 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2200 [(set (match_dup 0)
2201 (match_dup 1))]
2202 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2203
2204
2205 ;; %%% Kill this when call knows how to work this out.
2206 (define_split
2207 [(set (match_operand:SF 0 "push_operand" "")
2208 (match_operand:SF 1 "any_fp_register_operand" ""))]
2209 "!TARGET_64BIT"
2210 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2211 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2212
2213 (define_split
2214 [(set (match_operand:SF 0 "push_operand" "")
2215 (match_operand:SF 1 "any_fp_register_operand" ""))]
2216 "TARGET_64BIT"
2217 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2218 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2219
2220 (define_insn "*movsf_1"
2221 [(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")
2222 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2223 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2224 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2225 && (reload_in_progress || reload_completed
2226 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2227 || GET_CODE (operands[1]) != CONST_DOUBLE
2228 || memory_operand (operands[0], SFmode))"
2229 {
2230 switch (which_alternative)
2231 {
2232 case 0:
2233 if (REG_P (operands[1])
2234 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2235 return "fstp\t%y0";
2236 else if (STACK_TOP_P (operands[0]))
2237 return "fld%z1\t%y1";
2238 else
2239 return "fst\t%y0";
2240
2241 case 1:
2242 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2243 return "fstp%z0\t%y0";
2244 else
2245 return "fst%z0\t%y0";
2246
2247 case 2:
2248 return standard_80387_constant_opcode (operands[1]);
2249
2250 case 3:
2251 case 4:
2252 return "mov{l}\t{%1, %0|%0, %1}";
2253 case 5:
2254 if (get_attr_mode (insn) == MODE_TI)
2255 return "pxor\t%0, %0";
2256 else
2257 return "xorps\t%0, %0";
2258 case 6:
2259 if (get_attr_mode (insn) == MODE_V4SF)
2260 return "movaps\t{%1, %0|%0, %1}";
2261 else
2262 return "movss\t{%1, %0|%0, %1}";
2263 case 7:
2264 case 8:
2265 return "movss\t{%1, %0|%0, %1}";
2266
2267 case 9:
2268 case 10:
2269 return "movd\t{%1, %0|%0, %1}";
2270
2271 case 11:
2272 return "movq\t{%1, %0|%0, %1}";
2273
2274 default:
2275 abort();
2276 }
2277 }
2278 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2279 (set (attr "mode")
2280 (cond [(eq_attr "alternative" "3,4,9,10")
2281 (const_string "SI")
2282 (eq_attr "alternative" "5")
2283 (if_then_else
2284 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2285 (const_int 0))
2286 (ne (symbol_ref "TARGET_SSE2")
2287 (const_int 0)))
2288 (eq (symbol_ref "optimize_size")
2289 (const_int 0)))
2290 (const_string "TI")
2291 (const_string "V4SF"))
2292 /* For architectures resolving dependencies on
2293 whole SSE registers use APS move to break dependency
2294 chains, otherwise use short move to avoid extra work.
2295
2296 Do the same for architectures resolving dependencies on
2297 the parts. While in DF mode it is better to always handle
2298 just register parts, the SF mode is different due to lack
2299 of instructions to load just part of the register. It is
2300 better to maintain the whole registers in single format
2301 to avoid problems on using packed logical operations. */
2302 (eq_attr "alternative" "6")
2303 (if_then_else
2304 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2305 (const_int 0))
2306 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2307 (const_int 0)))
2308 (const_string "V4SF")
2309 (const_string "SF"))
2310 (eq_attr "alternative" "11")
2311 (const_string "DI")]
2312 (const_string "SF")))])
2313
2314 (define_insn "*movsf_1_nointerunit"
2315 [(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")
2316 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2317 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2318 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2319 && (reload_in_progress || reload_completed
2320 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2321 || GET_CODE (operands[1]) != CONST_DOUBLE
2322 || memory_operand (operands[0], SFmode))"
2323 {
2324 switch (which_alternative)
2325 {
2326 case 0:
2327 if (REG_P (operands[1])
2328 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2329 {
2330 if (REGNO (operands[0]) == FIRST_STACK_REG
2331 && TARGET_USE_FFREEP)
2332 return "ffreep\t%y0";
2333 return "fstp\t%y0";
2334 }
2335 else if (STACK_TOP_P (operands[0]))
2336 return "fld%z1\t%y1";
2337 else
2338 return "fst\t%y0";
2339
2340 case 1:
2341 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2342 return "fstp%z0\t%y0";
2343 else
2344 return "fst%z0\t%y0";
2345
2346 case 2:
2347 return standard_80387_constant_opcode (operands[1]);
2348
2349 case 3:
2350 case 4:
2351 return "mov{l}\t{%1, %0|%0, %1}";
2352 case 5:
2353 if (get_attr_mode (insn) == MODE_TI)
2354 return "pxor\t%0, %0";
2355 else
2356 return "xorps\t%0, %0";
2357 case 6:
2358 if (get_attr_mode (insn) == MODE_V4SF)
2359 return "movaps\t{%1, %0|%0, %1}";
2360 else
2361 return "movss\t{%1, %0|%0, %1}";
2362 case 7:
2363 case 8:
2364 return "movss\t{%1, %0|%0, %1}";
2365
2366 case 9:
2367 case 10:
2368 return "movd\t{%1, %0|%0, %1}";
2369
2370 case 11:
2371 return "movq\t{%1, %0|%0, %1}";
2372
2373 default:
2374 abort();
2375 }
2376 }
2377 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2378 (set (attr "mode")
2379 (cond [(eq_attr "alternative" "3,4,9,10")
2380 (const_string "SI")
2381 (eq_attr "alternative" "5")
2382 (if_then_else
2383 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2384 (const_int 0))
2385 (ne (symbol_ref "TARGET_SSE2")
2386 (const_int 0)))
2387 (eq (symbol_ref "optimize_size")
2388 (const_int 0)))
2389 (const_string "TI")
2390 (const_string "V4SF"))
2391 /* For architectures resolving dependencies on
2392 whole SSE registers use APS move to break dependency
2393 chains, otherwise use short move to avoid extra work.
2394
2395 Do the same for architectures resolving dependencies on
2396 the parts. While in DF mode it is better to always handle
2397 just register parts, the SF mode is different due to lack
2398 of instructions to load just part of the register. It is
2399 better to maintain the whole registers in single format
2400 to avoid problems on using packed logical operations. */
2401 (eq_attr "alternative" "6")
2402 (if_then_else
2403 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2404 (const_int 0))
2405 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2406 (const_int 0)))
2407 (const_string "V4SF")
2408 (const_string "SF"))
2409 (eq_attr "alternative" "11")
2410 (const_string "DI")]
2411 (const_string "SF")))])
2412
2413 (define_insn "*swapsf"
2414 [(set (match_operand:SF 0 "register_operand" "+f")
2415 (match_operand:SF 1 "register_operand" "+f"))
2416 (set (match_dup 1)
2417 (match_dup 0))]
2418 "reload_completed || !TARGET_SSE"
2419 {
2420 if (STACK_TOP_P (operands[0]))
2421 return "fxch\t%1";
2422 else
2423 return "fxch\t%0";
2424 }
2425 [(set_attr "type" "fxch")
2426 (set_attr "mode" "SF")])
2427
2428 (define_expand "movdf"
2429 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2430 (match_operand:DF 1 "general_operand" ""))]
2431 ""
2432 "ix86_expand_move (DFmode, operands); DONE;")
2433
2434 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2435 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2436 ;; On the average, pushdf using integers can be still shorter. Allow this
2437 ;; pattern for optimize_size too.
2438
2439 (define_insn "*pushdf_nointeger"
2440 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2441 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2442 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2443 {
2444 /* This insn should be already splitted before reg-stack. */
2445 abort ();
2446 }
2447 [(set_attr "type" "multi")
2448 (set_attr "mode" "DF,SI,SI,DF")])
2449
2450 (define_insn "*pushdf_integer"
2451 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2452 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2453 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2454 {
2455 /* This insn should be already splitted before reg-stack. */
2456 abort ();
2457 }
2458 [(set_attr "type" "multi")
2459 (set_attr "mode" "DF,SI,DF")])
2460
2461 ;; %%% Kill this when call knows how to work this out.
2462 (define_split
2463 [(set (match_operand:DF 0 "push_operand" "")
2464 (match_operand:DF 1 "any_fp_register_operand" ""))]
2465 "!TARGET_64BIT && reload_completed"
2466 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2467 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2468 "")
2469
2470 (define_split
2471 [(set (match_operand:DF 0 "push_operand" "")
2472 (match_operand:DF 1 "any_fp_register_operand" ""))]
2473 "TARGET_64BIT && reload_completed"
2474 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2475 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2476 "")
2477
2478 (define_split
2479 [(set (match_operand:DF 0 "push_operand" "")
2480 (match_operand:DF 1 "general_operand" ""))]
2481 "reload_completed"
2482 [(const_int 0)]
2483 "ix86_split_long_move (operands); DONE;")
2484
2485 ;; Moving is usually shorter when only FP registers are used. This separate
2486 ;; movdf pattern avoids the use of integer registers for FP operations
2487 ;; when optimizing for size.
2488
2489 (define_insn "*movdf_nointeger"
2490 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2491 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2492 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2493 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2494 && (reload_in_progress || reload_completed
2495 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2496 || GET_CODE (operands[1]) != CONST_DOUBLE
2497 || memory_operand (operands[0], DFmode))"
2498 {
2499 switch (which_alternative)
2500 {
2501 case 0:
2502 if (REG_P (operands[1])
2503 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2504 {
2505 if (REGNO (operands[0]) == FIRST_STACK_REG
2506 && TARGET_USE_FFREEP)
2507 return "ffreep\t%y0";
2508 return "fstp\t%y0";
2509 }
2510 else if (STACK_TOP_P (operands[0]))
2511 return "fld%z1\t%y1";
2512 else
2513 return "fst\t%y0";
2514
2515 case 1:
2516 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2517 return "fstp%z0\t%y0";
2518 else
2519 return "fst%z0\t%y0";
2520
2521 case 2:
2522 return standard_80387_constant_opcode (operands[1]);
2523
2524 case 3:
2525 case 4:
2526 return "#";
2527 case 5:
2528 switch (get_attr_mode (insn))
2529 {
2530 case MODE_V4SF:
2531 return "xorps\t%0, %0";
2532 case MODE_V2DF:
2533 return "xorpd\t%0, %0";
2534 case MODE_TI:
2535 return "pxor\t%0, %0";
2536 default:
2537 abort ();
2538 }
2539 case 6:
2540 switch (get_attr_mode (insn))
2541 {
2542 case MODE_V4SF:
2543 return "movaps\t{%1, %0|%0, %1}";
2544 case MODE_V2DF:
2545 return "movapd\t{%1, %0|%0, %1}";
2546 case MODE_DF:
2547 return "movsd\t{%1, %0|%0, %1}";
2548 default:
2549 abort ();
2550 }
2551 case 7:
2552 if (get_attr_mode (insn) == MODE_V2DF)
2553 return "movlpd\t{%1, %0|%0, %1}";
2554 else
2555 return "movsd\t{%1, %0|%0, %1}";
2556 case 8:
2557 return "movsd\t{%1, %0|%0, %1}";
2558
2559 default:
2560 abort();
2561 }
2562 }
2563 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2564 (set (attr "mode")
2565 (cond [(eq_attr "alternative" "3,4")
2566 (const_string "SI")
2567 /* xorps is one byte shorter. */
2568 (eq_attr "alternative" "5")
2569 (cond [(ne (symbol_ref "optimize_size")
2570 (const_int 0))
2571 (const_string "V4SF")
2572 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2573 (const_int 0))
2574 (const_string "TI")]
2575 (const_string "V2DF"))
2576 /* For architectures resolving dependencies on
2577 whole SSE registers use APD move to break dependency
2578 chains, otherwise use short move to avoid extra work.
2579
2580 movaps encodes one byte shorter. */
2581 (eq_attr "alternative" "6")
2582 (cond
2583 [(ne (symbol_ref "optimize_size")
2584 (const_int 0))
2585 (const_string "V4SF")
2586 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2587 (const_int 0))
2588 (const_string "V2DF")]
2589 (const_string "DF"))
2590 /* For architectures resolving dependencies on register
2591 parts we may avoid extra work to zero out upper part
2592 of register. */
2593 (eq_attr "alternative" "7")
2594 (if_then_else
2595 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2596 (const_int 0))
2597 (const_string "V2DF")
2598 (const_string "DF"))]
2599 (const_string "DF")))])
2600
2601 (define_insn "*movdf_integer"
2602 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2603 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2604 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2605 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2606 && (reload_in_progress || reload_completed
2607 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2608 || GET_CODE (operands[1]) != CONST_DOUBLE
2609 || memory_operand (operands[0], DFmode))"
2610 {
2611 switch (which_alternative)
2612 {
2613 case 0:
2614 if (REG_P (operands[1])
2615 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2616 {
2617 if (REGNO (operands[0]) == FIRST_STACK_REG
2618 && TARGET_USE_FFREEP)
2619 return "ffreep\t%y0";
2620 return "fstp\t%y0";
2621 }
2622 else if (STACK_TOP_P (operands[0]))
2623 return "fld%z1\t%y1";
2624 else
2625 return "fst\t%y0";
2626
2627 case 1:
2628 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2629 return "fstp%z0\t%y0";
2630 else
2631 return "fst%z0\t%y0";
2632
2633 case 2:
2634 return standard_80387_constant_opcode (operands[1]);
2635
2636 case 3:
2637 case 4:
2638 return "#";
2639
2640 case 5:
2641 switch (get_attr_mode (insn))
2642 {
2643 case MODE_V4SF:
2644 return "xorps\t%0, %0";
2645 case MODE_V2DF:
2646 return "xorpd\t%0, %0";
2647 case MODE_TI:
2648 return "pxor\t%0, %0";
2649 default:
2650 abort ();
2651 }
2652 case 6:
2653 switch (get_attr_mode (insn))
2654 {
2655 case MODE_V4SF:
2656 return "movaps\t{%1, %0|%0, %1}";
2657 case MODE_V2DF:
2658 return "movapd\t{%1, %0|%0, %1}";
2659 case MODE_DF:
2660 return "movsd\t{%1, %0|%0, %1}";
2661 default:
2662 abort ();
2663 }
2664 case 7:
2665 if (get_attr_mode (insn) == MODE_V2DF)
2666 return "movlpd\t{%1, %0|%0, %1}";
2667 else
2668 return "movsd\t{%1, %0|%0, %1}";
2669 case 8:
2670 return "movsd\t{%1, %0|%0, %1}";
2671
2672 default:
2673 abort();
2674 }
2675 }
2676 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2677 (set (attr "mode")
2678 (cond [(eq_attr "alternative" "3,4")
2679 (const_string "SI")
2680 /* xorps is one byte shorter. */
2681 (eq_attr "alternative" "5")
2682 (cond [(ne (symbol_ref "optimize_size")
2683 (const_int 0))
2684 (const_string "V4SF")
2685 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2686 (const_int 0))
2687 (const_string "TI")]
2688 (const_string "V2DF"))
2689 /* For architectures resolving dependencies on
2690 whole SSE registers use APD move to break dependency
2691 chains, otherwise use short move to avoid extra work.
2692
2693 movaps encodes one byte shorter. */
2694 (eq_attr "alternative" "6")
2695 (cond
2696 [(ne (symbol_ref "optimize_size")
2697 (const_int 0))
2698 (const_string "V4SF")
2699 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2700 (const_int 0))
2701 (const_string "V2DF")]
2702 (const_string "DF"))
2703 /* For architectures resolving dependencies on register
2704 parts we may avoid extra work to zero out upper part
2705 of register. */
2706 (eq_attr "alternative" "7")
2707 (if_then_else
2708 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2709 (const_int 0))
2710 (const_string "V2DF")
2711 (const_string "DF"))]
2712 (const_string "DF")))])
2713
2714 (define_split
2715 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2716 (match_operand:DF 1 "general_operand" ""))]
2717 "reload_completed
2718 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2719 && ! (ANY_FP_REG_P (operands[0]) ||
2720 (GET_CODE (operands[0]) == SUBREG
2721 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2722 && ! (ANY_FP_REG_P (operands[1]) ||
2723 (GET_CODE (operands[1]) == SUBREG
2724 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2725 [(const_int 0)]
2726 "ix86_split_long_move (operands); DONE;")
2727
2728 (define_insn "*swapdf"
2729 [(set (match_operand:DF 0 "register_operand" "+f")
2730 (match_operand:DF 1 "register_operand" "+f"))
2731 (set (match_dup 1)
2732 (match_dup 0))]
2733 "reload_completed || !TARGET_SSE2"
2734 {
2735 if (STACK_TOP_P (operands[0]))
2736 return "fxch\t%1";
2737 else
2738 return "fxch\t%0";
2739 }
2740 [(set_attr "type" "fxch")
2741 (set_attr "mode" "DF")])
2742
2743 (define_expand "movxf"
2744 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2745 (match_operand:XF 1 "general_operand" ""))]
2746 "!TARGET_128BIT_LONG_DOUBLE"
2747 "ix86_expand_move (XFmode, operands); DONE;")
2748
2749 (define_expand "movtf"
2750 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2751 (match_operand:TF 1 "general_operand" ""))]
2752 ""
2753 "ix86_expand_move (TFmode, operands); DONE;")
2754
2755 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2756 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2757 ;; Pushing using integer instructions is longer except for constants
2758 ;; and direct memory references.
2759 ;; (assuming that any given constant is pushed only once, but this ought to be
2760 ;; handled elsewhere).
2761
2762 (define_insn "*pushxf_nointeger"
2763 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2764 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2765 "!TARGET_128BIT_LONG_DOUBLE && optimize_size"
2766 {
2767 /* This insn should be already splitted before reg-stack. */
2768 abort ();
2769 }
2770 [(set_attr "type" "multi")
2771 (set_attr "mode" "XF,SI,SI")])
2772
2773 (define_insn "*pushtf_nointeger"
2774 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2775 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2776 "optimize_size"
2777 {
2778 /* This insn should be already splitted before reg-stack. */
2779 abort ();
2780 }
2781 [(set_attr "type" "multi")
2782 (set_attr "mode" "XF,SI,SI")])
2783
2784 (define_insn "*pushxf_integer"
2785 [(set (match_operand:XF 0 "push_operand" "=<,<")
2786 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2787 "!TARGET_128BIT_LONG_DOUBLE && !optimize_size"
2788 {
2789 /* This insn should be already splitted before reg-stack. */
2790 abort ();
2791 }
2792 [(set_attr "type" "multi")
2793 (set_attr "mode" "XF,SI")])
2794
2795 (define_insn "*pushtf_integer"
2796 [(set (match_operand:TF 0 "push_operand" "=<,<")
2797 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2798 "!optimize_size"
2799 {
2800 /* This insn should be already splitted before reg-stack. */
2801 abort ();
2802 }
2803 [(set_attr "type" "multi")
2804 (set_attr "mode" "XF,SI")])
2805
2806 (define_split
2807 [(set (match_operand 0 "push_operand" "")
2808 (match_operand 1 "general_operand" ""))]
2809 "reload_completed
2810 && (GET_MODE (operands[0]) == XFmode
2811 || GET_MODE (operands[0]) == TFmode
2812 || GET_MODE (operands[0]) == DFmode)
2813 && !ANY_FP_REG_P (operands[1])"
2814 [(const_int 0)]
2815 "ix86_split_long_move (operands); DONE;")
2816
2817 (define_split
2818 [(set (match_operand:XF 0 "push_operand" "")
2819 (match_operand:XF 1 "any_fp_register_operand" ""))]
2820 "!TARGET_128BIT_LONG_DOUBLE"
2821 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2822 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2823
2824 (define_split
2825 [(set (match_operand:TF 0 "push_operand" "")
2826 (match_operand:TF 1 "any_fp_register_operand" ""))]
2827 "!TARGET_64BIT"
2828 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2829 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2830
2831 (define_split
2832 [(set (match_operand:TF 0 "push_operand" "")
2833 (match_operand:TF 1 "any_fp_register_operand" ""))]
2834 "TARGET_64BIT"
2835 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2836 (set (mem:TF (reg:DI 7)) (match_dup 1))])
2837
2838 ;; Do not use integer registers when optimizing for size
2839 (define_insn "*movxf_nointeger"
2840 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2841 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2842 "!TARGET_128BIT_LONG_DOUBLE
2843 && optimize_size
2844 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2845 && (reload_in_progress || reload_completed
2846 || GET_CODE (operands[1]) != CONST_DOUBLE
2847 || memory_operand (operands[0], XFmode))"
2848 {
2849 switch (which_alternative)
2850 {
2851 case 0:
2852 if (REG_P (operands[1])
2853 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2854 {
2855 if (REGNO (operands[0]) == FIRST_STACK_REG
2856 && TARGET_USE_FFREEP)
2857 return "ffreep\t%y0";
2858 return "fstp\t%y0";
2859 }
2860 else if (STACK_TOP_P (operands[0]))
2861 return "fld%z1\t%y1";
2862 else
2863 return "fst\t%y0";
2864
2865 case 1:
2866 /* There is no non-popping store to memory for XFmode. So if
2867 we need one, follow the store with a load. */
2868 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2869 return "fstp%z0\t%y0\;fld%z0\t%y0";
2870 else
2871 return "fstp%z0\t%y0";
2872
2873 case 2:
2874 return standard_80387_constant_opcode (operands[1]);
2875
2876 case 3: case 4:
2877 return "#";
2878 }
2879 abort();
2880 }
2881 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2882 (set_attr "mode" "XF,XF,XF,SI,SI")])
2883
2884 (define_insn "*movtf_nointeger"
2885 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2886 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2887 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2888 && optimize_size
2889 && (reload_in_progress || reload_completed
2890 || GET_CODE (operands[1]) != CONST_DOUBLE
2891 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2892 || memory_operand (operands[0], TFmode))"
2893 {
2894 switch (which_alternative)
2895 {
2896 case 0:
2897 if (REG_P (operands[1])
2898 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2899 {
2900 if (REGNO (operands[0]) == FIRST_STACK_REG
2901 && TARGET_USE_FFREEP)
2902 return "ffreep\t%y0";
2903 return "fstp\t%y0";
2904 }
2905 else if (STACK_TOP_P (operands[0]))
2906 return "fld%z1\t%y1";
2907 else
2908 return "fst\t%y0";
2909
2910 case 1:
2911 /* There is no non-popping store to memory for XFmode. So if
2912 we need one, follow the store with a load. */
2913 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2914 return "fstp%z0\t%y0\;fld%z0\t%y0";
2915 else
2916 return "fstp%z0\t%y0";
2917
2918 case 2:
2919 return standard_80387_constant_opcode (operands[1]);
2920
2921 case 3: case 4:
2922 return "#";
2923 }
2924 abort();
2925 }
2926 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2927 (set_attr "mode" "XF,XF,XF,SI,SI")])
2928
2929 (define_insn "*movxf_integer"
2930 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2931 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2932 "!TARGET_128BIT_LONG_DOUBLE
2933 && !optimize_size
2934 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2935 && (reload_in_progress || reload_completed
2936 || GET_CODE (operands[1]) != CONST_DOUBLE
2937 || memory_operand (operands[0], XFmode))"
2938 {
2939 switch (which_alternative)
2940 {
2941 case 0:
2942 if (REG_P (operands[1])
2943 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2944 {
2945 if (REGNO (operands[0]) == FIRST_STACK_REG
2946 && TARGET_USE_FFREEP)
2947 return "ffreep\t%y0";
2948 return "fstp\t%y0";
2949 }
2950 else if (STACK_TOP_P (operands[0]))
2951 return "fld%z1\t%y1";
2952 else
2953 return "fst\t%y0";
2954
2955 case 1:
2956 /* There is no non-popping store to memory for XFmode. So if
2957 we need one, follow the store with a load. */
2958 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2959 return "fstp%z0\t%y0\;fld%z0\t%y0";
2960 else
2961 return "fstp%z0\t%y0";
2962
2963 case 2:
2964 return standard_80387_constant_opcode (operands[1]);
2965
2966 case 3: case 4:
2967 return "#";
2968 }
2969 abort();
2970 }
2971 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2972 (set_attr "mode" "XF,XF,XF,SI,SI")])
2973
2974 (define_insn "*movtf_integer"
2975 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2976 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2977 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2978 && !optimize_size
2979 && (reload_in_progress || reload_completed
2980 || GET_CODE (operands[1]) != CONST_DOUBLE
2981 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2982 || memory_operand (operands[0], TFmode))"
2983 {
2984 switch (which_alternative)
2985 {
2986 case 0:
2987 if (REG_P (operands[1])
2988 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2989 {
2990 if (REGNO (operands[0]) == FIRST_STACK_REG
2991 && TARGET_USE_FFREEP)
2992 return "ffreep\t%y0";
2993 return "fstp\t%y0";
2994 }
2995 else if (STACK_TOP_P (operands[0]))
2996 return "fld%z1\t%y1";
2997 else
2998 return "fst\t%y0";
2999
3000 case 1:
3001 /* There is no non-popping store to memory for XFmode. So if
3002 we need one, follow the store with a load. */
3003 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3004 return "fstp%z0\t%y0\;fld%z0\t%y0";
3005 else
3006 return "fstp%z0\t%y0";
3007
3008 case 2:
3009 return standard_80387_constant_opcode (operands[1]);
3010
3011 case 3: case 4:
3012 return "#";
3013 }
3014 abort();
3015 }
3016 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3017 (set_attr "mode" "XF,XF,XF,SI,SI")])
3018
3019 (define_split
3020 [(set (match_operand 0 "nonimmediate_operand" "")
3021 (match_operand 1 "general_operand" ""))]
3022 "reload_completed
3023 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3024 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3025 && ! (ANY_FP_REG_P (operands[0]) ||
3026 (GET_CODE (operands[0]) == SUBREG
3027 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3028 && ! (ANY_FP_REG_P (operands[1]) ||
3029 (GET_CODE (operands[1]) == SUBREG
3030 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3031 [(const_int 0)]
3032 "ix86_split_long_move (operands); DONE;")
3033
3034 (define_split
3035 [(set (match_operand 0 "register_operand" "")
3036 (match_operand 1 "memory_operand" ""))]
3037 "reload_completed
3038 && GET_CODE (operands[1]) == MEM
3039 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3040 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3041 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3042 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3043 && (!(SSE_REG_P (operands[0]) ||
3044 (GET_CODE (operands[0]) == SUBREG
3045 && SSE_REG_P (SUBREG_REG (operands[0]))))
3046 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3047 && (!(FP_REG_P (operands[0]) ||
3048 (GET_CODE (operands[0]) == SUBREG
3049 && FP_REG_P (SUBREG_REG (operands[0]))))
3050 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3051 [(set (match_dup 0)
3052 (match_dup 1))]
3053 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3054
3055 (define_insn "swapxf"
3056 [(set (match_operand:XF 0 "register_operand" "+f")
3057 (match_operand:XF 1 "register_operand" "+f"))
3058 (set (match_dup 1)
3059 (match_dup 0))]
3060 ""
3061 {
3062 if (STACK_TOP_P (operands[0]))
3063 return "fxch\t%1";
3064 else
3065 return "fxch\t%0";
3066 }
3067 [(set_attr "type" "fxch")
3068 (set_attr "mode" "XF")])
3069
3070 (define_insn "swaptf"
3071 [(set (match_operand:TF 0 "register_operand" "+f")
3072 (match_operand:TF 1 "register_operand" "+f"))
3073 (set (match_dup 1)
3074 (match_dup 0))]
3075 ""
3076 {
3077 if (STACK_TOP_P (operands[0]))
3078 return "fxch\t%1";
3079 else
3080 return "fxch\t%0";
3081 }
3082 [(set_attr "type" "fxch")
3083 (set_attr "mode" "XF")])
3084 \f
3085 ;; Zero extension instructions
3086
3087 (define_expand "zero_extendhisi2"
3088 [(set (match_operand:SI 0 "register_operand" "")
3089 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3090 ""
3091 {
3092 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3093 {
3094 operands[1] = force_reg (HImode, operands[1]);
3095 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3096 DONE;
3097 }
3098 })
3099
3100 (define_insn "zero_extendhisi2_and"
3101 [(set (match_operand:SI 0 "register_operand" "=r")
3102 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3103 (clobber (reg:CC 17))]
3104 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3105 "#"
3106 [(set_attr "type" "alu1")
3107 (set_attr "mode" "SI")])
3108
3109 (define_split
3110 [(set (match_operand:SI 0 "register_operand" "")
3111 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3112 (clobber (reg:CC 17))]
3113 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3114 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3115 (clobber (reg:CC 17))])]
3116 "")
3117
3118 (define_insn "*zero_extendhisi2_movzwl"
3119 [(set (match_operand:SI 0 "register_operand" "=r")
3120 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3121 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3122 "movz{wl|x}\t{%1, %0|%0, %1}"
3123 [(set_attr "type" "imovx")
3124 (set_attr "mode" "SI")])
3125
3126 (define_expand "zero_extendqihi2"
3127 [(parallel
3128 [(set (match_operand:HI 0 "register_operand" "")
3129 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3130 (clobber (reg:CC 17))])]
3131 ""
3132 "")
3133
3134 (define_insn "*zero_extendqihi2_and"
3135 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3136 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3137 (clobber (reg:CC 17))]
3138 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3139 "#"
3140 [(set_attr "type" "alu1")
3141 (set_attr "mode" "HI")])
3142
3143 (define_insn "*zero_extendqihi2_movzbw_and"
3144 [(set (match_operand:HI 0 "register_operand" "=r,r")
3145 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3146 (clobber (reg:CC 17))]
3147 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3148 "#"
3149 [(set_attr "type" "imovx,alu1")
3150 (set_attr "mode" "HI")])
3151
3152 (define_insn "*zero_extendqihi2_movzbw"
3153 [(set (match_operand:HI 0 "register_operand" "=r")
3154 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3155 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3156 "movz{bw|x}\t{%1, %0|%0, %1}"
3157 [(set_attr "type" "imovx")
3158 (set_attr "mode" "HI")])
3159
3160 ;; For the movzbw case strip only the clobber
3161 (define_split
3162 [(set (match_operand:HI 0 "register_operand" "")
3163 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3164 (clobber (reg:CC 17))]
3165 "reload_completed
3166 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3167 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3168 [(set (match_operand:HI 0 "register_operand" "")
3169 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3170
3171 ;; When source and destination does not overlap, clear destination
3172 ;; first and then do the movb
3173 (define_split
3174 [(set (match_operand:HI 0 "register_operand" "")
3175 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3176 (clobber (reg:CC 17))]
3177 "reload_completed
3178 && ANY_QI_REG_P (operands[0])
3179 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3180 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3181 [(set (match_dup 0) (const_int 0))
3182 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3183 "operands[2] = gen_lowpart (QImode, operands[0]);")
3184
3185 ;; Rest is handled by single and.
3186 (define_split
3187 [(set (match_operand:HI 0 "register_operand" "")
3188 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3189 (clobber (reg:CC 17))]
3190 "reload_completed
3191 && true_regnum (operands[0]) == true_regnum (operands[1])"
3192 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3193 (clobber (reg:CC 17))])]
3194 "")
3195
3196 (define_expand "zero_extendqisi2"
3197 [(parallel
3198 [(set (match_operand:SI 0 "register_operand" "")
3199 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3200 (clobber (reg:CC 17))])]
3201 ""
3202 "")
3203
3204 (define_insn "*zero_extendqisi2_and"
3205 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3206 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3207 (clobber (reg:CC 17))]
3208 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3209 "#"
3210 [(set_attr "type" "alu1")
3211 (set_attr "mode" "SI")])
3212
3213 (define_insn "*zero_extendqisi2_movzbw_and"
3214 [(set (match_operand:SI 0 "register_operand" "=r,r")
3215 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3216 (clobber (reg:CC 17))]
3217 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3218 "#"
3219 [(set_attr "type" "imovx,alu1")
3220 (set_attr "mode" "SI")])
3221
3222 (define_insn "*zero_extendqisi2_movzbw"
3223 [(set (match_operand:SI 0 "register_operand" "=r")
3224 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3225 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3226 "movz{bl|x}\t{%1, %0|%0, %1}"
3227 [(set_attr "type" "imovx")
3228 (set_attr "mode" "SI")])
3229
3230 ;; For the movzbl case strip only the clobber
3231 (define_split
3232 [(set (match_operand:SI 0 "register_operand" "")
3233 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3234 (clobber (reg:CC 17))]
3235 "reload_completed
3236 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3237 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3238 [(set (match_dup 0)
3239 (zero_extend:SI (match_dup 1)))])
3240
3241 ;; When source and destination does not overlap, clear destination
3242 ;; first and then do the movb
3243 (define_split
3244 [(set (match_operand:SI 0 "register_operand" "")
3245 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3246 (clobber (reg:CC 17))]
3247 "reload_completed
3248 && ANY_QI_REG_P (operands[0])
3249 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3250 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3251 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3252 [(set (match_dup 0) (const_int 0))
3253 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3254 "operands[2] = gen_lowpart (QImode, operands[0]);")
3255
3256 ;; Rest is handled by single and.
3257 (define_split
3258 [(set (match_operand:SI 0 "register_operand" "")
3259 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3260 (clobber (reg:CC 17))]
3261 "reload_completed
3262 && true_regnum (operands[0]) == true_regnum (operands[1])"
3263 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3264 (clobber (reg:CC 17))])]
3265 "")
3266
3267 ;; %%% Kill me once multi-word ops are sane.
3268 (define_expand "zero_extendsidi2"
3269 [(set (match_operand:DI 0 "register_operand" "=r")
3270 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3271 ""
3272 "if (!TARGET_64BIT)
3273 {
3274 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3275 DONE;
3276 }
3277 ")
3278
3279 (define_insn "zero_extendsidi2_32"
3280 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3281 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3282 (clobber (reg:CC 17))]
3283 "!TARGET_64BIT"
3284 "#"
3285 [(set_attr "mode" "SI")])
3286
3287 (define_insn "zero_extendsidi2_rex64"
3288 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3289 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3290 "TARGET_64BIT"
3291 "@
3292 mov\t{%k1, %k0|%k0, %k1}
3293 #"
3294 [(set_attr "type" "imovx,imov")
3295 (set_attr "mode" "SI,DI")])
3296
3297 (define_split
3298 [(set (match_operand:DI 0 "memory_operand" "")
3299 (zero_extend:DI (match_dup 0)))]
3300 "TARGET_64BIT"
3301 [(set (match_dup 4) (const_int 0))]
3302 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3303
3304 (define_split
3305 [(set (match_operand:DI 0 "register_operand" "")
3306 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3307 (clobber (reg:CC 17))]
3308 "!TARGET_64BIT && reload_completed
3309 && true_regnum (operands[0]) == true_regnum (operands[1])"
3310 [(set (match_dup 4) (const_int 0))]
3311 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3312
3313 (define_split
3314 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3315 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3316 (clobber (reg:CC 17))]
3317 "!TARGET_64BIT && reload_completed"
3318 [(set (match_dup 3) (match_dup 1))
3319 (set (match_dup 4) (const_int 0))]
3320 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3321
3322 (define_insn "zero_extendhidi2"
3323 [(set (match_operand:DI 0 "register_operand" "=r,r")
3324 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3325 "TARGET_64BIT"
3326 "@
3327 movz{wl|x}\t{%1, %k0|%k0, %1}
3328 movz{wq|x}\t{%1, %0|%0, %1}"
3329 [(set_attr "type" "imovx")
3330 (set_attr "mode" "SI,DI")])
3331
3332 (define_insn "zero_extendqidi2"
3333 [(set (match_operand:DI 0 "register_operand" "=r,r")
3334 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3335 "TARGET_64BIT"
3336 "@
3337 movz{bl|x}\t{%1, %k0|%k0, %1}
3338 movz{bq|x}\t{%1, %0|%0, %1}"
3339 [(set_attr "type" "imovx")
3340 (set_attr "mode" "SI,DI")])
3341 \f
3342 ;; Sign extension instructions
3343
3344 (define_expand "extendsidi2"
3345 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3346 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3347 (clobber (reg:CC 17))
3348 (clobber (match_scratch:SI 2 ""))])]
3349 ""
3350 {
3351 if (TARGET_64BIT)
3352 {
3353 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3354 DONE;
3355 }
3356 })
3357
3358 (define_insn "*extendsidi2_1"
3359 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3360 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3361 (clobber (reg:CC 17))
3362 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3363 "!TARGET_64BIT"
3364 "#")
3365
3366 (define_insn "extendsidi2_rex64"
3367 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3368 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3369 "TARGET_64BIT"
3370 "@
3371 {cltq|cdqe}
3372 movs{lq|x}\t{%1,%0|%0, %1}"
3373 [(set_attr "type" "imovx")
3374 (set_attr "mode" "DI")
3375 (set_attr "prefix_0f" "0")
3376 (set_attr "modrm" "0,1")])
3377
3378 (define_insn "extendhidi2"
3379 [(set (match_operand:DI 0 "register_operand" "=r")
3380 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3381 "TARGET_64BIT"
3382 "movs{wq|x}\t{%1,%0|%0, %1}"
3383 [(set_attr "type" "imovx")
3384 (set_attr "mode" "DI")])
3385
3386 (define_insn "extendqidi2"
3387 [(set (match_operand:DI 0 "register_operand" "=r")
3388 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3389 "TARGET_64BIT"
3390 "movs{bq|x}\t{%1,%0|%0, %1}"
3391 [(set_attr "type" "imovx")
3392 (set_attr "mode" "DI")])
3393
3394 ;; Extend to memory case when source register does die.
3395 (define_split
3396 [(set (match_operand:DI 0 "memory_operand" "")
3397 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3398 (clobber (reg:CC 17))
3399 (clobber (match_operand:SI 2 "register_operand" ""))]
3400 "(reload_completed
3401 && dead_or_set_p (insn, operands[1])
3402 && !reg_mentioned_p (operands[1], operands[0]))"
3403 [(set (match_dup 3) (match_dup 1))
3404 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3405 (clobber (reg:CC 17))])
3406 (set (match_dup 4) (match_dup 1))]
3407 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3408
3409 ;; Extend to memory case when source register does not die.
3410 (define_split
3411 [(set (match_operand:DI 0 "memory_operand" "")
3412 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3413 (clobber (reg:CC 17))
3414 (clobber (match_operand:SI 2 "register_operand" ""))]
3415 "reload_completed"
3416 [(const_int 0)]
3417 {
3418 split_di (&operands[0], 1, &operands[3], &operands[4]);
3419
3420 emit_move_insn (operands[3], operands[1]);
3421
3422 /* Generate a cltd if possible and doing so it profitable. */
3423 if (true_regnum (operands[1]) == 0
3424 && true_regnum (operands[2]) == 1
3425 && (optimize_size || TARGET_USE_CLTD))
3426 {
3427 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3428 }
3429 else
3430 {
3431 emit_move_insn (operands[2], operands[1]);
3432 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3433 }
3434 emit_move_insn (operands[4], operands[2]);
3435 DONE;
3436 })
3437
3438 ;; Extend to register case. Optimize case where source and destination
3439 ;; registers match and cases where we can use cltd.
3440 (define_split
3441 [(set (match_operand:DI 0 "register_operand" "")
3442 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3443 (clobber (reg:CC 17))
3444 (clobber (match_scratch:SI 2 ""))]
3445 "reload_completed"
3446 [(const_int 0)]
3447 {
3448 split_di (&operands[0], 1, &operands[3], &operands[4]);
3449
3450 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3451 emit_move_insn (operands[3], operands[1]);
3452
3453 /* Generate a cltd if possible and doing so it profitable. */
3454 if (true_regnum (operands[3]) == 0
3455 && (optimize_size || TARGET_USE_CLTD))
3456 {
3457 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3458 DONE;
3459 }
3460
3461 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3462 emit_move_insn (operands[4], operands[1]);
3463
3464 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3465 DONE;
3466 })
3467
3468 (define_insn "extendhisi2"
3469 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3470 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3471 ""
3472 {
3473 switch (get_attr_prefix_0f (insn))
3474 {
3475 case 0:
3476 return "{cwtl|cwde}";
3477 default:
3478 return "movs{wl|x}\t{%1,%0|%0, %1}";
3479 }
3480 }
3481 [(set_attr "type" "imovx")
3482 (set_attr "mode" "SI")
3483 (set (attr "prefix_0f")
3484 ;; movsx is short decodable while cwtl is vector decoded.
3485 (if_then_else (and (eq_attr "cpu" "!k6")
3486 (eq_attr "alternative" "0"))
3487 (const_string "0")
3488 (const_string "1")))
3489 (set (attr "modrm")
3490 (if_then_else (eq_attr "prefix_0f" "0")
3491 (const_string "0")
3492 (const_string "1")))])
3493
3494 (define_insn "*extendhisi2_zext"
3495 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3496 (zero_extend:DI
3497 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3498 "TARGET_64BIT"
3499 {
3500 switch (get_attr_prefix_0f (insn))
3501 {
3502 case 0:
3503 return "{cwtl|cwde}";
3504 default:
3505 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3506 }
3507 }
3508 [(set_attr "type" "imovx")
3509 (set_attr "mode" "SI")
3510 (set (attr "prefix_0f")
3511 ;; movsx is short decodable while cwtl is vector decoded.
3512 (if_then_else (and (eq_attr "cpu" "!k6")
3513 (eq_attr "alternative" "0"))
3514 (const_string "0")
3515 (const_string "1")))
3516 (set (attr "modrm")
3517 (if_then_else (eq_attr "prefix_0f" "0")
3518 (const_string "0")
3519 (const_string "1")))])
3520
3521 (define_insn "extendqihi2"
3522 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3523 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3524 ""
3525 {
3526 switch (get_attr_prefix_0f (insn))
3527 {
3528 case 0:
3529 return "{cbtw|cbw}";
3530 default:
3531 return "movs{bw|x}\t{%1,%0|%0, %1}";
3532 }
3533 }
3534 [(set_attr "type" "imovx")
3535 (set_attr "mode" "HI")
3536 (set (attr "prefix_0f")
3537 ;; movsx is short decodable while cwtl is vector decoded.
3538 (if_then_else (and (eq_attr "cpu" "!k6")
3539 (eq_attr "alternative" "0"))
3540 (const_string "0")
3541 (const_string "1")))
3542 (set (attr "modrm")
3543 (if_then_else (eq_attr "prefix_0f" "0")
3544 (const_string "0")
3545 (const_string "1")))])
3546
3547 (define_insn "extendqisi2"
3548 [(set (match_operand:SI 0 "register_operand" "=r")
3549 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3550 ""
3551 "movs{bl|x}\t{%1,%0|%0, %1}"
3552 [(set_attr "type" "imovx")
3553 (set_attr "mode" "SI")])
3554
3555 (define_insn "*extendqisi2_zext"
3556 [(set (match_operand:DI 0 "register_operand" "=r")
3557 (zero_extend:DI
3558 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3559 "TARGET_64BIT"
3560 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3561 [(set_attr "type" "imovx")
3562 (set_attr "mode" "SI")])
3563 \f
3564 ;; Conversions between float and double.
3565
3566 ;; These are all no-ops in the model used for the 80387. So just
3567 ;; emit moves.
3568
3569 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3570 (define_insn "*dummy_extendsfdf2"
3571 [(set (match_operand:DF 0 "push_operand" "=<")
3572 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3573 "0"
3574 "#")
3575
3576 (define_split
3577 [(set (match_operand:DF 0 "push_operand" "")
3578 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3579 "!TARGET_64BIT"
3580 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3581 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3582
3583 (define_split
3584 [(set (match_operand:DF 0 "push_operand" "")
3585 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3586 "TARGET_64BIT"
3587 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3588 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3589
3590 (define_insn "*dummy_extendsfxf2"
3591 [(set (match_operand:XF 0 "push_operand" "=<")
3592 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3593 "0"
3594 "#")
3595
3596 (define_split
3597 [(set (match_operand:XF 0 "push_operand" "")
3598 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3599 "!TARGET_128BIT_LONG_DOUBLE"
3600 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3601 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3602
3603 (define_insn "*dummy_extendsftf2"
3604 [(set (match_operand:TF 0 "push_operand" "=<")
3605 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3606 "0"
3607 "#")
3608
3609 (define_split
3610 [(set (match_operand:TF 0 "push_operand" "")
3611 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3612 "!TARGET_64BIT"
3613 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3614 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3615
3616 (define_split
3617 [(set (match_operand:TF 0 "push_operand" "")
3618 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3619 "TARGET_64BIT"
3620 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3621 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3622
3623 (define_insn "*dummy_extenddfxf2"
3624 [(set (match_operand:XF 0 "push_operand" "=<")
3625 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3626 "0"
3627 "#")
3628
3629 (define_split
3630 [(set (match_operand:XF 0 "push_operand" "")
3631 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3632 "!TARGET_128BIT_LONG_DOUBLE"
3633 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3634 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3635
3636 (define_insn "*dummy_extenddftf2"
3637 [(set (match_operand:TF 0 "push_operand" "=<")
3638 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3639 "0"
3640 "#")
3641
3642 (define_split
3643 [(set (match_operand:TF 0 "push_operand" "")
3644 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3645 "!TARGET_64BIT"
3646 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3647 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3648
3649 (define_split
3650 [(set (match_operand:TF 0 "push_operand" "")
3651 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3652 "TARGET_64BIT"
3653 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3654 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3655
3656 (define_expand "extendsfdf2"
3657 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3658 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3659 "TARGET_80387 || TARGET_SSE2"
3660 {
3661 /* ??? Needed for compress_float_constant since all fp constants
3662 are LEGITIMATE_CONSTANT_P. */
3663 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3664 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3665 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3666 operands[1] = force_reg (SFmode, operands[1]);
3667 })
3668
3669 (define_insn "*extendsfdf2_1"
3670 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3671 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3672 "(TARGET_80387 || TARGET_SSE2)
3673 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3674 {
3675 switch (which_alternative)
3676 {
3677 case 0:
3678 if (REG_P (operands[1])
3679 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3680 return "fstp\t%y0";
3681 else if (STACK_TOP_P (operands[0]))
3682 return "fld%z1\t%y1";
3683 else
3684 return "fst\t%y0";
3685
3686 case 1:
3687 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3688 return "fstp%z0\t%y0";
3689
3690 else
3691 return "fst%z0\t%y0";
3692 case 2:
3693 return "cvtss2sd\t{%1, %0|%0, %1}";
3694
3695 default:
3696 abort ();
3697 }
3698 }
3699 [(set_attr "type" "fmov,fmov,ssecvt")
3700 (set_attr "mode" "SF,XF,DF")])
3701
3702 (define_insn "*extendsfdf2_1_sse_only"
3703 [(set (match_operand:DF 0 "register_operand" "=Y")
3704 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3705 "!TARGET_80387 && TARGET_SSE2
3706 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3707 "cvtss2sd\t{%1, %0|%0, %1}"
3708 [(set_attr "type" "ssecvt")
3709 (set_attr "mode" "DF")])
3710
3711 (define_expand "extendsfxf2"
3712 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3713 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3714 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3715 {
3716 /* ??? Needed for compress_float_constant since all fp constants
3717 are LEGITIMATE_CONSTANT_P. */
3718 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3719 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3720 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3721 operands[1] = force_reg (SFmode, operands[1]);
3722 })
3723
3724 (define_insn "*extendsfxf2_1"
3725 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3726 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3727 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3728 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3729 {
3730 switch (which_alternative)
3731 {
3732 case 0:
3733 if (REG_P (operands[1])
3734 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3735 return "fstp\t%y0";
3736 else if (STACK_TOP_P (operands[0]))
3737 return "fld%z1\t%y1";
3738 else
3739 return "fst\t%y0";
3740
3741 case 1:
3742 /* There is no non-popping store to memory for XFmode. So if
3743 we need one, follow the store with a load. */
3744 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3745 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3746 else
3747 return "fstp%z0\t%y0";
3748
3749 default:
3750 abort ();
3751 }
3752 }
3753 [(set_attr "type" "fmov")
3754 (set_attr "mode" "SF,XF")])
3755
3756 (define_expand "extendsftf2"
3757 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3758 (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3759 "TARGET_80387"
3760 {
3761 /* ??? Needed for compress_float_constant since all fp constants
3762 are LEGITIMATE_CONSTANT_P. */
3763 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3764 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3765 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3766 operands[1] = force_reg (SFmode, operands[1]);
3767 })
3768
3769 (define_insn "*extendsftf2_1"
3770 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3771 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3772 "TARGET_80387
3773 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3774 {
3775 switch (which_alternative)
3776 {
3777 case 0:
3778 if (REG_P (operands[1])
3779 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3780 return "fstp\t%y0";
3781 else if (STACK_TOP_P (operands[0]))
3782 return "fld%z1\t%y1";
3783 else
3784 return "fst\t%y0";
3785
3786 case 1:
3787 /* There is no non-popping store to memory for XFmode. So if
3788 we need one, follow the store with a load. */
3789 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3790 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3791 else
3792 return "fstp%z0\t%y0";
3793
3794 default:
3795 abort ();
3796 }
3797 }
3798 [(set_attr "type" "fmov")
3799 (set_attr "mode" "SF,XF")])
3800
3801 (define_expand "extenddfxf2"
3802 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3803 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3804 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3805 {
3806 /* ??? Needed for compress_float_constant since all fp constants
3807 are LEGITIMATE_CONSTANT_P. */
3808 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3809 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3810 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3811 operands[1] = force_reg (DFmode, operands[1]);
3812 })
3813
3814 (define_insn "*extenddfxf2_1"
3815 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3816 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3817 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3818 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3819 {
3820 switch (which_alternative)
3821 {
3822 case 0:
3823 if (REG_P (operands[1])
3824 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3825 return "fstp\t%y0";
3826 else if (STACK_TOP_P (operands[0]))
3827 return "fld%z1\t%y1";
3828 else
3829 return "fst\t%y0";
3830
3831 case 1:
3832 /* There is no non-popping store to memory for XFmode. So if
3833 we need one, follow the store with a load. */
3834 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3835 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3836 else
3837 return "fstp%z0\t%y0";
3838
3839 default:
3840 abort ();
3841 }
3842 }
3843 [(set_attr "type" "fmov")
3844 (set_attr "mode" "DF,XF")])
3845
3846 (define_expand "extenddftf2"
3847 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3848 (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3849 "TARGET_80387"
3850 {
3851 /* ??? Needed for compress_float_constant since all fp constants
3852 are LEGITIMATE_CONSTANT_P. */
3853 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3854 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3855 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3856 operands[1] = force_reg (DFmode, operands[1]);
3857 })
3858
3859 (define_insn "*extenddftf2_1"
3860 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3861 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3862 "TARGET_80387
3863 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3864 {
3865 switch (which_alternative)
3866 {
3867 case 0:
3868 if (REG_P (operands[1])
3869 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3870 return "fstp\t%y0";
3871 else if (STACK_TOP_P (operands[0]))
3872 return "fld%z1\t%y1";
3873 else
3874 return "fst\t%y0";
3875
3876 case 1:
3877 /* There is no non-popping store to memory for XFmode. So if
3878 we need one, follow the store with a load. */
3879 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3880 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3881 else
3882 return "fstp%z0\t%y0";
3883
3884 default:
3885 abort ();
3886 }
3887 }
3888 [(set_attr "type" "fmov")
3889 (set_attr "mode" "DF,XF")])
3890
3891 ;; %%% This seems bad bad news.
3892 ;; This cannot output into an f-reg because there is no way to be sure
3893 ;; of truncating in that case. Otherwise this is just like a simple move
3894 ;; insn. So we pretend we can output to a reg in order to get better
3895 ;; register preferencing, but we really use a stack slot.
3896
3897 (define_expand "truncdfsf2"
3898 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3899 (float_truncate:SF
3900 (match_operand:DF 1 "register_operand" "")))
3901 (clobber (match_dup 2))])]
3902 "TARGET_80387 || TARGET_SSE2"
3903 "
3904 if (TARGET_80387)
3905 operands[2] = assign_386_stack_local (SFmode, 0);
3906 else
3907 {
3908 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3909 DONE;
3910 }
3911 ")
3912
3913 (define_insn "*truncdfsf2_1"
3914 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3915 (float_truncate:SF
3916 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3917 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3918 "TARGET_80387 && !TARGET_SSE2"
3919 {
3920 switch (which_alternative)
3921 {
3922 case 0:
3923 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3924 return "fstp%z0\t%y0";
3925 else
3926 return "fst%z0\t%y0";
3927 default:
3928 abort ();
3929 }
3930 }
3931 [(set_attr "type" "fmov,multi,multi,multi")
3932 (set_attr "mode" "SF,SF,SF,SF")])
3933
3934 (define_insn "*truncdfsf2_1_sse"
3935 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3936 (float_truncate:SF
3937 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3938 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3939 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3940 {
3941 switch (which_alternative)
3942 {
3943 case 0:
3944 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3945 return "fstp%z0\t%y0";
3946 else
3947 return "fst%z0\t%y0";
3948 case 4:
3949 return "#";
3950 default:
3951 abort ();
3952 }
3953 }
3954 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3955 (set_attr "mode" "SF,SF,SF,SF,DF")])
3956
3957 (define_insn "*truncdfsf2_1_sse_nooverlap"
3958 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3959 (float_truncate:SF
3960 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3961 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3962 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3963 {
3964 switch (which_alternative)
3965 {
3966 case 0:
3967 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3968 return "fstp%z0\t%y0";
3969 else
3970 return "fst%z0\t%y0";
3971 case 4:
3972 return "#";
3973 default:
3974 abort ();
3975 }
3976 }
3977 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3978 (set_attr "mode" "SF,SF,SF,SF,DF")])
3979
3980 (define_insn "*truncdfsf2_2"
3981 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3982 (float_truncate:SF
3983 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3984 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3985 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3986 {
3987 switch (which_alternative)
3988 {
3989 case 0:
3990 case 1:
3991 return "cvtsd2ss\t{%1, %0|%0, %1}";
3992 case 2:
3993 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994 return "fstp%z0\t%y0";
3995 else
3996 return "fst%z0\t%y0";
3997 default:
3998 abort ();
3999 }
4000 }
4001 [(set_attr "type" "ssecvt,ssecvt,fmov")
4002 (set_attr "athlon_decode" "vector,double,*")
4003 (set_attr "mode" "SF,SF,SF")])
4004
4005 (define_insn "*truncdfsf2_2_nooverlap"
4006 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
4007 (float_truncate:SF
4008 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4009 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
4010 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4011 {
4012 switch (which_alternative)
4013 {
4014 case 0:
4015 return "#";
4016 case 1:
4017 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4018 return "fstp%z0\t%y0";
4019 else
4020 return "fst%z0\t%y0";
4021 default:
4022 abort ();
4023 }
4024 }
4025 [(set_attr "type" "ssecvt,fmov")
4026 (set_attr "mode" "DF,SF")])
4027
4028 (define_insn "*truncdfsf2_3"
4029 [(set (match_operand:SF 0 "memory_operand" "=m")
4030 (float_truncate:SF
4031 (match_operand:DF 1 "register_operand" "f")))]
4032 "TARGET_80387"
4033 {
4034 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4035 return "fstp%z0\t%y0";
4036 else
4037 return "fst%z0\t%y0";
4038 }
4039 [(set_attr "type" "fmov")
4040 (set_attr "mode" "SF")])
4041
4042 (define_insn "truncdfsf2_sse_only"
4043 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
4044 (float_truncate:SF
4045 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
4046 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4047 "cvtsd2ss\t{%1, %0|%0, %1}"
4048 [(set_attr "type" "ssecvt")
4049 (set_attr "athlon_decode" "vector,double")
4050 (set_attr "mode" "SF")])
4051
4052 (define_insn "*truncdfsf2_sse_only_nooverlap"
4053 [(set (match_operand:SF 0 "register_operand" "=&Y")
4054 (float_truncate:SF
4055 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4056 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4057 "#"
4058 [(set_attr "type" "ssecvt")
4059 (set_attr "mode" "DF")])
4060
4061 (define_split
4062 [(set (match_operand:SF 0 "memory_operand" "")
4063 (float_truncate:SF
4064 (match_operand:DF 1 "register_operand" "")))
4065 (clobber (match_operand:SF 2 "memory_operand" ""))]
4066 "TARGET_80387"
4067 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4068 "")
4069
4070 ; Avoid possible reformatting penalty on the destination by first
4071 ; zeroing it out
4072 (define_split
4073 [(set (match_operand:SF 0 "register_operand" "")
4074 (float_truncate:SF
4075 (match_operand:DF 1 "nonimmediate_operand" "")))
4076 (clobber (match_operand 2 "" ""))]
4077 "TARGET_80387 && reload_completed
4078 && SSE_REG_P (operands[0])
4079 && !STACK_REG_P (operands[1])"
4080 [(const_int 0)]
4081 {
4082 rtx src, dest;
4083 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
4084 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4085 else
4086 {
4087 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4088 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4089 /* simplify_gen_subreg refuses to widen memory references. */
4090 if (GET_CODE (src) == SUBREG)
4091 alter_subreg (&src);
4092 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4093 abort ();
4094 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4095 emit_insn (gen_cvtsd2ss (dest, dest, src));
4096 }
4097 DONE;
4098 })
4099
4100 (define_split
4101 [(set (match_operand:SF 0 "register_operand" "")
4102 (float_truncate:SF
4103 (match_operand:DF 1 "nonimmediate_operand" "")))]
4104 "TARGET_80387 && reload_completed
4105 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4106 [(const_int 0)]
4107 {
4108 rtx src, dest;
4109 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4110 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4111 /* simplify_gen_subreg refuses to widen memory references. */
4112 if (GET_CODE (src) == SUBREG)
4113 alter_subreg (&src);
4114 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4115 abort ();
4116 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4117 emit_insn (gen_cvtsd2ss (dest, dest, src));
4118 DONE;
4119 })
4120
4121 (define_split
4122 [(set (match_operand:SF 0 "register_operand" "")
4123 (float_truncate:SF
4124 (match_operand:DF 1 "fp_register_operand" "")))
4125 (clobber (match_operand:SF 2 "memory_operand" ""))]
4126 "TARGET_80387 && reload_completed"
4127 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4128 (set (match_dup 0) (match_dup 2))]
4129 "")
4130
4131 (define_expand "truncxfsf2"
4132 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4133 (float_truncate:SF
4134 (match_operand:XF 1 "register_operand" "")))
4135 (clobber (match_dup 2))])]
4136 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4137 "operands[2] = assign_386_stack_local (SFmode, 0);")
4138
4139 (define_insn "*truncxfsf2_1"
4140 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4141 (float_truncate:SF
4142 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4143 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4144 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4145 {
4146 switch (which_alternative)
4147 {
4148 case 0:
4149 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4150 return "fstp%z0\t%y0";
4151 else
4152 return "fst%z0\t%y0";
4153 default:
4154 abort();
4155 }
4156 }
4157 [(set_attr "type" "fmov,multi,multi,multi")
4158 (set_attr "mode" "SF")])
4159
4160 (define_insn "*truncxfsf2_2"
4161 [(set (match_operand:SF 0 "memory_operand" "=m")
4162 (float_truncate:SF
4163 (match_operand:XF 1 "register_operand" "f")))]
4164 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4165 {
4166 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4167 return "fstp%z0\t%y0";
4168 else
4169 return "fst%z0\t%y0";
4170 }
4171 [(set_attr "type" "fmov")
4172 (set_attr "mode" "SF")])
4173
4174 (define_split
4175 [(set (match_operand:SF 0 "memory_operand" "")
4176 (float_truncate:SF
4177 (match_operand:XF 1 "register_operand" "")))
4178 (clobber (match_operand:SF 2 "memory_operand" ""))]
4179 "TARGET_80387"
4180 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4181 "")
4182
4183 (define_split
4184 [(set (match_operand:SF 0 "register_operand" "")
4185 (float_truncate:SF
4186 (match_operand:XF 1 "register_operand" "")))
4187 (clobber (match_operand:SF 2 "memory_operand" ""))]
4188 "TARGET_80387 && reload_completed"
4189 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4190 (set (match_dup 0) (match_dup 2))]
4191 "")
4192
4193 (define_expand "trunctfsf2"
4194 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4195 (float_truncate:SF
4196 (match_operand:TF 1 "register_operand" "")))
4197 (clobber (match_dup 2))])]
4198 "TARGET_80387"
4199 "operands[2] = assign_386_stack_local (SFmode, 0);")
4200
4201 (define_insn "*trunctfsf2_1"
4202 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4203 (float_truncate:SF
4204 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4205 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4206 "TARGET_80387"
4207 {
4208 switch (which_alternative)
4209 {
4210 case 0:
4211 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4212 return "fstp%z0\t%y0";
4213 else
4214 return "fst%z0\t%y0";
4215 default:
4216 abort();
4217 }
4218 }
4219 [(set_attr "type" "fmov,multi,multi,multi")
4220 (set_attr "mode" "SF")])
4221
4222 (define_insn "*trunctfsf2_2"
4223 [(set (match_operand:SF 0 "memory_operand" "=m")
4224 (float_truncate:SF
4225 (match_operand:TF 1 "register_operand" "f")))]
4226 "TARGET_80387"
4227 {
4228 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4229 return "fstp%z0\t%y0";
4230 else
4231 return "fst%z0\t%y0";
4232 }
4233 [(set_attr "type" "fmov")
4234 (set_attr "mode" "SF")])
4235
4236 (define_split
4237 [(set (match_operand:SF 0 "memory_operand" "")
4238 (float_truncate:SF
4239 (match_operand:TF 1 "register_operand" "")))
4240 (clobber (match_operand:SF 2 "memory_operand" ""))]
4241 "TARGET_80387"
4242 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4243 "")
4244
4245 (define_split
4246 [(set (match_operand:SF 0 "register_operand" "")
4247 (float_truncate:SF
4248 (match_operand:TF 1 "register_operand" "")))
4249 (clobber (match_operand:SF 2 "memory_operand" ""))]
4250 "TARGET_80387 && reload_completed"
4251 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4252 (set (match_dup 0) (match_dup 2))]
4253 "")
4254
4255
4256 (define_expand "truncxfdf2"
4257 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4258 (float_truncate:DF
4259 (match_operand:XF 1 "register_operand" "")))
4260 (clobber (match_dup 2))])]
4261 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4262 "operands[2] = assign_386_stack_local (DFmode, 0);")
4263
4264 (define_insn "*truncxfdf2_1"
4265 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4266 (float_truncate:DF
4267 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4268 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4269 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4270 {
4271 switch (which_alternative)
4272 {
4273 case 0:
4274 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4275 return "fstp%z0\t%y0";
4276 else
4277 return "fst%z0\t%y0";
4278 default:
4279 abort();
4280 }
4281 abort ();
4282 }
4283 [(set_attr "type" "fmov,multi,multi,multi")
4284 (set_attr "mode" "DF")])
4285
4286 (define_insn "*truncxfdf2_2"
4287 [(set (match_operand:DF 0 "memory_operand" "=m")
4288 (float_truncate:DF
4289 (match_operand:XF 1 "register_operand" "f")))]
4290 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4291 {
4292 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4293 return "fstp%z0\t%y0";
4294 else
4295 return "fst%z0\t%y0";
4296 }
4297 [(set_attr "type" "fmov")
4298 (set_attr "mode" "DF")])
4299
4300 (define_split
4301 [(set (match_operand:DF 0 "memory_operand" "")
4302 (float_truncate:DF
4303 (match_operand:XF 1 "register_operand" "")))
4304 (clobber (match_operand:DF 2 "memory_operand" ""))]
4305 "TARGET_80387"
4306 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4307 "")
4308
4309 (define_split
4310 [(set (match_operand:DF 0 "register_operand" "")
4311 (float_truncate:DF
4312 (match_operand:XF 1 "register_operand" "")))
4313 (clobber (match_operand:DF 2 "memory_operand" ""))]
4314 "TARGET_80387 && reload_completed"
4315 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4316 (set (match_dup 0) (match_dup 2))]
4317 "")
4318
4319 (define_expand "trunctfdf2"
4320 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4321 (float_truncate:DF
4322 (match_operand:TF 1 "register_operand" "")))
4323 (clobber (match_dup 2))])]
4324 "TARGET_80387"
4325 "operands[2] = assign_386_stack_local (DFmode, 0);")
4326
4327 (define_insn "*trunctfdf2_1"
4328 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4329 (float_truncate:DF
4330 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4331 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4332 "TARGET_80387"
4333 {
4334 switch (which_alternative)
4335 {
4336 case 0:
4337 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4338 return "fstp%z0\t%y0";
4339 else
4340 return "fst%z0\t%y0";
4341 default:
4342 abort();
4343 }
4344 abort ();
4345 }
4346 [(set_attr "type" "fmov,multi,multi,multi")
4347 (set_attr "mode" "DF")])
4348
4349 (define_insn "*trunctfdf2_2"
4350 [(set (match_operand:DF 0 "memory_operand" "=m")
4351 (float_truncate:DF
4352 (match_operand:TF 1 "register_operand" "f")))]
4353 "TARGET_80387"
4354 {
4355 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4356 return "fstp%z0\t%y0";
4357 else
4358 return "fst%z0\t%y0";
4359 }
4360 [(set_attr "type" "fmov")
4361 (set_attr "mode" "DF")])
4362
4363 (define_split
4364 [(set (match_operand:DF 0 "memory_operand" "")
4365 (float_truncate:DF
4366 (match_operand:TF 1 "register_operand" "")))
4367 (clobber (match_operand:DF 2 "memory_operand" ""))]
4368 "TARGET_80387"
4369 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4370 "")
4371
4372 (define_split
4373 [(set (match_operand:DF 0 "register_operand" "")
4374 (float_truncate:DF
4375 (match_operand:TF 1 "register_operand" "")))
4376 (clobber (match_operand:DF 2 "memory_operand" ""))]
4377 "TARGET_80387 && reload_completed"
4378 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4379 (set (match_dup 0) (match_dup 2))]
4380 "")
4381
4382 \f
4383 ;; %%% Break up all these bad boys.
4384
4385 ;; Signed conversion to DImode.
4386
4387 (define_expand "fix_truncxfdi2"
4388 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4389 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4390 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4391 "")
4392
4393 (define_expand "fix_trunctfdi2"
4394 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4395 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4396 "TARGET_80387"
4397 "")
4398
4399 (define_expand "fix_truncdfdi2"
4400 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4401 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4402 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4403 {
4404 if (TARGET_64BIT && TARGET_SSE2)
4405 {
4406 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4407 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4408 if (out != operands[0])
4409 emit_move_insn (operands[0], out);
4410 DONE;
4411 }
4412 })
4413
4414 (define_expand "fix_truncsfdi2"
4415 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4416 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4417 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4418 {
4419 if (TARGET_SSE && TARGET_64BIT)
4420 {
4421 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4422 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4423 if (out != operands[0])
4424 emit_move_insn (operands[0], out);
4425 DONE;
4426 }
4427 })
4428
4429 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4430 ;; of the machinery.
4431 (define_insn_and_split "*fix_truncdi_1"
4432 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4433 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4434 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4435 && !reload_completed && !reload_in_progress
4436 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4437 "#"
4438 "&& 1"
4439 [(const_int 0)]
4440 {
4441 ix86_optimize_mode_switching = 1;
4442 operands[2] = assign_386_stack_local (HImode, 1);
4443 operands[3] = assign_386_stack_local (HImode, 2);
4444 if (memory_operand (operands[0], VOIDmode))
4445 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4446 operands[2], operands[3]));
4447 else
4448 {
4449 operands[4] = assign_386_stack_local (DImode, 0);
4450 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4451 operands[2], operands[3],
4452 operands[4]));
4453 }
4454 DONE;
4455 }
4456 [(set_attr "type" "fistp")
4457 (set_attr "mode" "DI")])
4458
4459 (define_insn "fix_truncdi_nomemory"
4460 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4461 (fix:DI (match_operand 1 "register_operand" "f,f")))
4462 (use (match_operand:HI 2 "memory_operand" "m,m"))
4463 (use (match_operand:HI 3 "memory_operand" "m,m"))
4464 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4465 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4466 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4467 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4468 "#"
4469 [(set_attr "type" "fistp")
4470 (set_attr "mode" "DI")])
4471
4472 (define_insn "fix_truncdi_memory"
4473 [(set (match_operand:DI 0 "memory_operand" "=m")
4474 (fix:DI (match_operand 1 "register_operand" "f")))
4475 (use (match_operand:HI 2 "memory_operand" "m"))
4476 (use (match_operand:HI 3 "memory_operand" "m"))
4477 (clobber (match_scratch:DF 4 "=&1f"))]
4478 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4479 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4480 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4481 [(set_attr "type" "fistp")
4482 (set_attr "mode" "DI")])
4483
4484 (define_split
4485 [(set (match_operand:DI 0 "register_operand" "")
4486 (fix:DI (match_operand 1 "register_operand" "")))
4487 (use (match_operand:HI 2 "memory_operand" ""))
4488 (use (match_operand:HI 3 "memory_operand" ""))
4489 (clobber (match_operand:DI 4 "memory_operand" ""))
4490 (clobber (match_scratch 5 ""))]
4491 "reload_completed"
4492 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4493 (use (match_dup 2))
4494 (use (match_dup 3))
4495 (clobber (match_dup 5))])
4496 (set (match_dup 0) (match_dup 4))]
4497 "")
4498
4499 (define_split
4500 [(set (match_operand:DI 0 "memory_operand" "")
4501 (fix:DI (match_operand 1 "register_operand" "")))
4502 (use (match_operand:HI 2 "memory_operand" ""))
4503 (use (match_operand:HI 3 "memory_operand" ""))
4504 (clobber (match_operand:DI 4 "memory_operand" ""))
4505 (clobber (match_scratch 5 ""))]
4506 "reload_completed"
4507 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4508 (use (match_dup 2))
4509 (use (match_dup 3))
4510 (clobber (match_dup 5))])]
4511 "")
4512
4513 ;; When SSE available, it is always faster to use it!
4514 (define_insn "fix_truncsfdi_sse"
4515 [(set (match_operand:DI 0 "register_operand" "=r,r")
4516 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4517 "TARGET_64BIT && TARGET_SSE"
4518 "cvttss2si{q}\t{%1, %0|%0, %1}"
4519 [(set_attr "type" "sseicvt")
4520 (set_attr "mode" "SF")
4521 (set_attr "athlon_decode" "double,vector")])
4522
4523 ;; Avoid vector decoded form of the instruction.
4524 (define_peephole2
4525 [(match_scratch:SF 2 "x")
4526 (set (match_operand:DI 0 "register_operand" "")
4527 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4528 "TARGET_K8 && !optimize_size"
4529 [(set (match_dup 2) (match_dup 1))
4530 (set (match_dup 0) (fix:DI (match_dup 2)))]
4531 "")
4532
4533 (define_insn "fix_truncdfdi_sse"
4534 [(set (match_operand:DI 0 "register_operand" "=r,r")
4535 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4536 "TARGET_64BIT && TARGET_SSE2"
4537 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4538 [(set_attr "type" "sseicvt,sseicvt")
4539 (set_attr "mode" "DF")
4540 (set_attr "athlon_decode" "double,vector")])
4541
4542 ;; Avoid vector decoded form of the instruction.
4543 (define_peephole2
4544 [(match_scratch:DF 2 "Y")
4545 (set (match_operand:DI 0 "register_operand" "")
4546 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4547 "TARGET_K8 && !optimize_size"
4548 [(set (match_dup 2) (match_dup 1))
4549 (set (match_dup 0) (fix:DI (match_dup 2)))]
4550 "")
4551
4552 ;; Signed conversion to SImode.
4553
4554 (define_expand "fix_truncxfsi2"
4555 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4556 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4557 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4558 "")
4559
4560 (define_expand "fix_trunctfsi2"
4561 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4562 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4563 "TARGET_80387"
4564 "")
4565
4566 (define_expand "fix_truncdfsi2"
4567 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4568 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4569 "TARGET_80387 || TARGET_SSE2"
4570 {
4571 if (TARGET_SSE2)
4572 {
4573 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4574 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4575 if (out != operands[0])
4576 emit_move_insn (operands[0], out);
4577 DONE;
4578 }
4579 })
4580
4581 (define_expand "fix_truncsfsi2"
4582 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4583 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4584 "TARGET_80387 || TARGET_SSE"
4585 {
4586 if (TARGET_SSE)
4587 {
4588 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4589 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4590 if (out != operands[0])
4591 emit_move_insn (operands[0], out);
4592 DONE;
4593 }
4594 })
4595
4596 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4597 ;; of the machinery.
4598 (define_insn_and_split "*fix_truncsi_1"
4599 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4600 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4601 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4602 && !reload_completed && !reload_in_progress
4603 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4604 "#"
4605 "&& 1"
4606 [(const_int 0)]
4607 {
4608 ix86_optimize_mode_switching = 1;
4609 operands[2] = assign_386_stack_local (HImode, 1);
4610 operands[3] = assign_386_stack_local (HImode, 2);
4611 if (memory_operand (operands[0], VOIDmode))
4612 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4613 operands[2], operands[3]));
4614 else
4615 {
4616 operands[4] = assign_386_stack_local (SImode, 0);
4617 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4618 operands[2], operands[3],
4619 operands[4]));
4620 }
4621 DONE;
4622 }
4623 [(set_attr "type" "fistp")
4624 (set_attr "mode" "SI")])
4625
4626 (define_insn "fix_truncsi_nomemory"
4627 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4628 (fix:SI (match_operand 1 "register_operand" "f,f")))
4629 (use (match_operand:HI 2 "memory_operand" "m,m"))
4630 (use (match_operand:HI 3 "memory_operand" "m,m"))
4631 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4632 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4633 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4634 "#"
4635 [(set_attr "type" "fistp")
4636 (set_attr "mode" "SI")])
4637
4638 (define_insn "fix_truncsi_memory"
4639 [(set (match_operand:SI 0 "memory_operand" "=m")
4640 (fix:SI (match_operand 1 "register_operand" "f")))
4641 (use (match_operand:HI 2 "memory_operand" "m"))
4642 (use (match_operand:HI 3 "memory_operand" "m"))]
4643 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4644 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4645 "* return output_fix_trunc (insn, operands);"
4646 [(set_attr "type" "fistp")
4647 (set_attr "mode" "SI")])
4648
4649 ;; When SSE available, it is always faster to use it!
4650 (define_insn "fix_truncsfsi_sse"
4651 [(set (match_operand:SI 0 "register_operand" "=r,r")
4652 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4653 "TARGET_SSE"
4654 "cvttss2si\t{%1, %0|%0, %1}"
4655 [(set_attr "type" "sseicvt")
4656 (set_attr "mode" "DF")
4657 (set_attr "athlon_decode" "double,vector")])
4658
4659 ;; Avoid vector decoded form of the instruction.
4660 (define_peephole2
4661 [(match_scratch:SF 2 "x")
4662 (set (match_operand:SI 0 "register_operand" "")
4663 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4664 "TARGET_K8 && !optimize_size"
4665 [(set (match_dup 2) (match_dup 1))
4666 (set (match_dup 0) (fix:SI (match_dup 2)))]
4667 "")
4668
4669 (define_insn "fix_truncdfsi_sse"
4670 [(set (match_operand:SI 0 "register_operand" "=r,r")
4671 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4672 "TARGET_SSE2"
4673 "cvttsd2si\t{%1, %0|%0, %1}"
4674 [(set_attr "type" "sseicvt")
4675 (set_attr "mode" "DF")
4676 (set_attr "athlon_decode" "double,vector")])
4677
4678 ;; Avoid vector decoded form of the instruction.
4679 (define_peephole2
4680 [(match_scratch:DF 2 "Y")
4681 (set (match_operand:SI 0 "register_operand" "")
4682 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4683 "TARGET_K8 && !optimize_size"
4684 [(set (match_dup 2) (match_dup 1))
4685 (set (match_dup 0) (fix:SI (match_dup 2)))]
4686 "")
4687
4688 (define_split
4689 [(set (match_operand:SI 0 "register_operand" "")
4690 (fix:SI (match_operand 1 "register_operand" "")))
4691 (use (match_operand:HI 2 "memory_operand" ""))
4692 (use (match_operand:HI 3 "memory_operand" ""))
4693 (clobber (match_operand:SI 4 "memory_operand" ""))]
4694 "reload_completed"
4695 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4696 (use (match_dup 2))
4697 (use (match_dup 3))])
4698 (set (match_dup 0) (match_dup 4))]
4699 "")
4700
4701 (define_split
4702 [(set (match_operand:SI 0 "memory_operand" "")
4703 (fix:SI (match_operand 1 "register_operand" "")))
4704 (use (match_operand:HI 2 "memory_operand" ""))
4705 (use (match_operand:HI 3 "memory_operand" ""))
4706 (clobber (match_operand:SI 4 "memory_operand" ""))]
4707 "reload_completed"
4708 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4709 (use (match_dup 2))
4710 (use (match_dup 3))])]
4711 "")
4712
4713 ;; Signed conversion to HImode.
4714
4715 (define_expand "fix_truncxfhi2"
4716 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4717 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4718 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4719 "")
4720
4721 (define_expand "fix_trunctfhi2"
4722 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4723 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4724 "TARGET_80387"
4725 "")
4726
4727 (define_expand "fix_truncdfhi2"
4728 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4729 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4730 "TARGET_80387 && !TARGET_SSE2"
4731 "")
4732
4733 (define_expand "fix_truncsfhi2"
4734 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4735 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4736 "TARGET_80387 && !TARGET_SSE"
4737 "")
4738
4739 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4740 ;; of the machinery.
4741 (define_insn_and_split "*fix_trunchi_1"
4742 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4743 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4744 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4745 && !reload_completed && !reload_in_progress
4746 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4747 "#"
4748 ""
4749 [(const_int 0)]
4750 {
4751 ix86_optimize_mode_switching = 1;
4752 operands[2] = assign_386_stack_local (HImode, 1);
4753 operands[3] = assign_386_stack_local (HImode, 2);
4754 if (memory_operand (operands[0], VOIDmode))
4755 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4756 operands[2], operands[3]));
4757 else
4758 {
4759 operands[4] = assign_386_stack_local (HImode, 0);
4760 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4761 operands[2], operands[3],
4762 operands[4]));
4763 }
4764 DONE;
4765 }
4766 [(set_attr "type" "fistp")
4767 (set_attr "mode" "HI")])
4768
4769 (define_insn "fix_trunchi_nomemory"
4770 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4771 (fix:HI (match_operand 1 "register_operand" "f,f")))
4772 (use (match_operand:HI 2 "memory_operand" "m,m"))
4773 (use (match_operand:HI 3 "memory_operand" "m,m"))
4774 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4775 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4776 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4777 "#"
4778 [(set_attr "type" "fistp")
4779 (set_attr "mode" "HI")])
4780
4781 (define_insn "fix_trunchi_memory"
4782 [(set (match_operand:HI 0 "memory_operand" "=m")
4783 (fix:HI (match_operand 1 "register_operand" "f")))
4784 (use (match_operand:HI 2 "memory_operand" "m"))
4785 (use (match_operand:HI 3 "memory_operand" "m"))]
4786 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4787 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4788 "* return output_fix_trunc (insn, operands);"
4789 [(set_attr "type" "fistp")
4790 (set_attr "mode" "HI")])
4791
4792 (define_split
4793 [(set (match_operand:HI 0 "memory_operand" "")
4794 (fix:HI (match_operand 1 "register_operand" "")))
4795 (use (match_operand:HI 2 "memory_operand" ""))
4796 (use (match_operand:HI 3 "memory_operand" ""))
4797 (clobber (match_operand:HI 4 "memory_operand" ""))]
4798 "reload_completed"
4799 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4800 (use (match_dup 2))
4801 (use (match_dup 3))])]
4802 "")
4803
4804 (define_split
4805 [(set (match_operand:HI 0 "register_operand" "")
4806 (fix:HI (match_operand 1 "register_operand" "")))
4807 (use (match_operand:HI 2 "memory_operand" ""))
4808 (use (match_operand:HI 3 "memory_operand" ""))
4809 (clobber (match_operand:HI 4 "memory_operand" ""))]
4810 "reload_completed"
4811 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4812 (use (match_dup 2))
4813 (use (match_dup 3))
4814 (clobber (match_dup 4))])
4815 (set (match_dup 0) (match_dup 4))]
4816 "")
4817
4818 ;; %% Not used yet.
4819 (define_insn "x86_fnstcw_1"
4820 [(set (match_operand:HI 0 "memory_operand" "=m")
4821 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4822 "TARGET_80387"
4823 "fnstcw\t%0"
4824 [(set_attr "length" "2")
4825 (set_attr "mode" "HI")
4826 (set_attr "unit" "i387")
4827 (set_attr "ppro_uops" "few")])
4828
4829 (define_insn "x86_fldcw_1"
4830 [(set (reg:HI 18)
4831 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4832 "TARGET_80387"
4833 "fldcw\t%0"
4834 [(set_attr "length" "2")
4835 (set_attr "mode" "HI")
4836 (set_attr "unit" "i387")
4837 (set_attr "athlon_decode" "vector")
4838 (set_attr "ppro_uops" "few")])
4839 \f
4840 ;; Conversion between fixed point and floating point.
4841
4842 ;; Even though we only accept memory inputs, the backend _really_
4843 ;; wants to be able to do this between registers.
4844
4845 (define_expand "floathisf2"
4846 [(set (match_operand:SF 0 "register_operand" "")
4847 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4848 "TARGET_SSE || TARGET_80387"
4849 {
4850 if (TARGET_SSE && TARGET_SSE_MATH)
4851 {
4852 emit_insn (gen_floatsisf2 (operands[0],
4853 convert_to_mode (SImode, operands[1], 0)));
4854 DONE;
4855 }
4856 })
4857
4858 (define_insn "*floathisf2_1"
4859 [(set (match_operand:SF 0 "register_operand" "=f,f")
4860 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4861 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4862 "@
4863 fild%z1\t%1
4864 #"
4865 [(set_attr "type" "fmov,multi")
4866 (set_attr "mode" "SF")
4867 (set_attr "fp_int_src" "true")])
4868
4869 (define_expand "floatsisf2"
4870 [(set (match_operand:SF 0 "register_operand" "")
4871 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4872 "TARGET_SSE || TARGET_80387"
4873 "")
4874
4875 (define_insn "*floatsisf2_i387"
4876 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4877 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4878 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4879 "@
4880 fild%z1\t%1
4881 #
4882 cvtsi2ss\t{%1, %0|%0, %1}
4883 cvtsi2ss\t{%1, %0|%0, %1}"
4884 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4885 (set_attr "mode" "SF")
4886 (set_attr "athlon_decode" "*,*,vector,double")
4887 (set_attr "fp_int_src" "true")])
4888
4889 (define_insn "*floatsisf2_sse"
4890 [(set (match_operand:SF 0 "register_operand" "=x,x")
4891 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4892 "TARGET_SSE"
4893 "cvtsi2ss\t{%1, %0|%0, %1}"
4894 [(set_attr "type" "sseicvt")
4895 (set_attr "mode" "SF")
4896 (set_attr "athlon_decode" "vector,double")
4897 (set_attr "fp_int_src" "true")])
4898
4899 ; Avoid possible reformatting penalty on the destination by first
4900 ; zeroing it out
4901 (define_split
4902 [(set (match_operand:SF 0 "register_operand" "")
4903 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4904 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4905 && SSE_REG_P (operands[0])"
4906 [(const_int 0)]
4907 {
4908 rtx dest;
4909 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4910 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4911 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4912 DONE;
4913 })
4914
4915 (define_expand "floatdisf2"
4916 [(set (match_operand:SF 0 "register_operand" "")
4917 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4918 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4919 "")
4920
4921 (define_insn "*floatdisf2_i387_only"
4922 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4923 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4924 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4925 "@
4926 fild%z1\t%1
4927 #"
4928 [(set_attr "type" "fmov,multi")
4929 (set_attr "mode" "SF")
4930 (set_attr "fp_int_src" "true")])
4931
4932 (define_insn "*floatdisf2_i387"
4933 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4934 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4935 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4936 "@
4937 fild%z1\t%1
4938 #
4939 cvtsi2ss{q}\t{%1, %0|%0, %1}
4940 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4941 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4942 (set_attr "mode" "SF")
4943 (set_attr "athlon_decode" "*,*,vector,double")
4944 (set_attr "fp_int_src" "true")])
4945
4946 (define_insn "*floatdisf2_sse"
4947 [(set (match_operand:SF 0 "register_operand" "=x,x")
4948 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4949 "TARGET_64BIT && TARGET_SSE"
4950 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4951 [(set_attr "type" "sseicvt")
4952 (set_attr "mode" "SF")
4953 (set_attr "athlon_decode" "vector,double")
4954 (set_attr "fp_int_src" "true")])
4955
4956 ; Avoid possible reformatting penalty on the destination by first
4957 ; zeroing it out
4958 (define_split
4959 [(set (match_operand:SF 0 "register_operand" "")
4960 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4961 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4962 && SSE_REG_P (operands[0])"
4963 [(const_int 0)]
4964 {
4965 rtx dest;
4966 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4967 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4968 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4969 DONE;
4970 })
4971
4972 (define_expand "floathidf2"
4973 [(set (match_operand:DF 0 "register_operand" "")
4974 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4975 "TARGET_SSE2 || TARGET_80387"
4976 {
4977 if (TARGET_SSE && TARGET_SSE_MATH)
4978 {
4979 emit_insn (gen_floatsidf2 (operands[0],
4980 convert_to_mode (SImode, operands[1], 0)));
4981 DONE;
4982 }
4983 })
4984
4985 (define_insn "*floathidf2_1"
4986 [(set (match_operand:DF 0 "register_operand" "=f,f")
4987 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4988 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4989 "@
4990 fild%z1\t%1
4991 #"
4992 [(set_attr "type" "fmov,multi")
4993 (set_attr "mode" "DF")
4994 (set_attr "fp_int_src" "true")])
4995
4996 (define_expand "floatsidf2"
4997 [(set (match_operand:DF 0 "register_operand" "")
4998 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4999 "TARGET_80387 || TARGET_SSE2"
5000 "")
5001
5002 (define_insn "*floatsidf2_i387"
5003 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5004 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
5005 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5006 "@
5007 fild%z1\t%1
5008 #
5009 cvtsi2sd\t{%1, %0|%0, %1}
5010 cvtsi2sd\t{%1, %0|%0, %1}"
5011 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5012 (set_attr "mode" "DF")
5013 (set_attr "athlon_decode" "*,*,double,direct")
5014 (set_attr "fp_int_src" "true")])
5015
5016 (define_insn "*floatsidf2_sse"
5017 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5018 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
5019 "TARGET_SSE2"
5020 "cvtsi2sd\t{%1, %0|%0, %1}"
5021 [(set_attr "type" "sseicvt")
5022 (set_attr "mode" "DF")
5023 (set_attr "athlon_decode" "double,direct")
5024 (set_attr "fp_int_src" "true")])
5025
5026 (define_expand "floatdidf2"
5027 [(set (match_operand:DF 0 "register_operand" "")
5028 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5029 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5030 "")
5031
5032 (define_insn "*floatdidf2_i387_only"
5033 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5034 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5035 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5036 "@
5037 fild%z1\t%1
5038 #"
5039 [(set_attr "type" "fmov,multi")
5040 (set_attr "mode" "DF")
5041 (set_attr "fp_int_src" "true")])
5042
5043 (define_insn "*floatdidf2_i387"
5044 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5045 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
5046 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5047 "@
5048 fild%z1\t%1
5049 #
5050 cvtsi2sd{q}\t{%1, %0|%0, %1}
5051 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5052 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5053 (set_attr "mode" "DF")
5054 (set_attr "athlon_decode" "*,*,double,direct")
5055 (set_attr "fp_int_src" "true")])
5056
5057 (define_insn "*floatdidf2_sse"
5058 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5059 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
5060 "TARGET_SSE2"
5061 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5062 [(set_attr "type" "sseicvt")
5063 (set_attr "mode" "DF")
5064 (set_attr "athlon_decode" "double,direct")
5065 (set_attr "fp_int_src" "true")])
5066
5067 (define_insn "floathixf2"
5068 [(set (match_operand:XF 0 "register_operand" "=f,f")
5069 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5070 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5071 "@
5072 fild%z1\t%1
5073 #"
5074 [(set_attr "type" "fmov,multi")
5075 (set_attr "mode" "XF")
5076 (set_attr "fp_int_src" "true")])
5077
5078 (define_insn "floathitf2"
5079 [(set (match_operand:TF 0 "register_operand" "=f,f")
5080 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5081 "TARGET_80387"
5082 "@
5083 fild%z1\t%1
5084 #"
5085 [(set_attr "type" "fmov,multi")
5086 (set_attr "mode" "XF")
5087 (set_attr "fp_int_src" "true")])
5088
5089 (define_insn "floatsixf2"
5090 [(set (match_operand:XF 0 "register_operand" "=f,f")
5091 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5092 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5093 "@
5094 fild%z1\t%1
5095 #"
5096 [(set_attr "type" "fmov,multi")
5097 (set_attr "mode" "XF")
5098 (set_attr "fp_int_src" "true")])
5099
5100 (define_insn "floatsitf2"
5101 [(set (match_operand:TF 0 "register_operand" "=f,f")
5102 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5103 "TARGET_80387"
5104 "@
5105 fild%z1\t%1
5106 #"
5107 [(set_attr "type" "fmov,multi")
5108 (set_attr "mode" "XF")
5109 (set_attr "fp_int_src" "true")])
5110
5111 (define_insn "floatdixf2"
5112 [(set (match_operand:XF 0 "register_operand" "=f,f")
5113 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5114 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5115 "@
5116 fild%z1\t%1
5117 #"
5118 [(set_attr "type" "fmov,multi")
5119 (set_attr "mode" "XF")
5120 (set_attr "fp_int_src" "true")])
5121
5122 (define_insn "floatditf2"
5123 [(set (match_operand:TF 0 "register_operand" "=f,f")
5124 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5125 "TARGET_80387"
5126 "@
5127 fild%z1\t%1
5128 #"
5129 [(set_attr "type" "fmov,multi")
5130 (set_attr "mode" "XF")
5131 (set_attr "fp_int_src" "true")])
5132
5133 ;; %%% Kill these when reload knows how to do it.
5134 (define_split
5135 [(set (match_operand 0 "fp_register_operand" "")
5136 (float (match_operand 1 "register_operand" "")))]
5137 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5138 [(const_int 0)]
5139 {
5140 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5141 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5142 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5143 ix86_free_from_memory (GET_MODE (operands[1]));
5144 DONE;
5145 })
5146
5147 (define_expand "floatunssisf2"
5148 [(use (match_operand:SF 0 "register_operand" ""))
5149 (use (match_operand:SI 1 "register_operand" ""))]
5150 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
5151 "x86_emit_floatuns (operands); DONE;")
5152
5153 (define_expand "floatunsdisf2"
5154 [(use (match_operand:SF 0 "register_operand" ""))
5155 (use (match_operand:DI 1 "register_operand" ""))]
5156 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
5157 "x86_emit_floatuns (operands); DONE;")
5158
5159 (define_expand "floatunsdidf2"
5160 [(use (match_operand:DF 0 "register_operand" ""))
5161 (use (match_operand:DI 1 "register_operand" ""))]
5162 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
5163 "x86_emit_floatuns (operands); DONE;")
5164 \f
5165 ;; Add instructions
5166
5167 ;; %%% splits for addsidi3
5168 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5169 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5170 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5171
5172 (define_expand "adddi3"
5173 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5174 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5175 (match_operand:DI 2 "x86_64_general_operand" "")))
5176 (clobber (reg:CC 17))]
5177 ""
5178 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5179
5180 (define_insn "*adddi3_1"
5181 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5182 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5183 (match_operand:DI 2 "general_operand" "roiF,riF")))
5184 (clobber (reg:CC 17))]
5185 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5186 "#")
5187
5188 (define_split
5189 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5190 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5191 (match_operand:DI 2 "general_operand" "")))
5192 (clobber (reg:CC 17))]
5193 "!TARGET_64BIT && reload_completed"
5194 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
5195 UNSPEC_ADD_CARRY))
5196 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5197 (parallel [(set (match_dup 3)
5198 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5199 (match_dup 4))
5200 (match_dup 5)))
5201 (clobber (reg:CC 17))])]
5202 "split_di (operands+0, 1, operands+0, operands+3);
5203 split_di (operands+1, 1, operands+1, operands+4);
5204 split_di (operands+2, 1, operands+2, operands+5);")
5205
5206 (define_insn "adddi3_carry_rex64"
5207 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5208 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5209 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5210 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5211 (clobber (reg:CC 17))]
5212 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5213 "adc{q}\t{%2, %0|%0, %2}"
5214 [(set_attr "type" "alu")
5215 (set_attr "pent_pair" "pu")
5216 (set_attr "mode" "DI")
5217 (set_attr "ppro_uops" "few")])
5218
5219 (define_insn "*adddi3_cc_rex64"
5220 [(set (reg:CC 17)
5221 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5222 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5223 UNSPEC_ADD_CARRY))
5224 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5225 (plus:DI (match_dup 1) (match_dup 2)))]
5226 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5227 "add{q}\t{%2, %0|%0, %2}"
5228 [(set_attr "type" "alu")
5229 (set_attr "mode" "DI")])
5230
5231 (define_insn "addqi3_carry"
5232 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
5233 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5234 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5235 (match_operand:QI 2 "general_operand" "ri,rm")))
5236 (clobber (reg:CC 17))]
5237 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5238 "adc{b}\t{%2, %0|%0, %2}"
5239 [(set_attr "type" "alu")
5240 (set_attr "pent_pair" "pu")
5241 (set_attr "mode" "QI")
5242 (set_attr "ppro_uops" "few")])
5243
5244 (define_insn "addhi3_carry"
5245 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5246 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5247 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5248 (match_operand:HI 2 "general_operand" "ri,rm")))
5249 (clobber (reg:CC 17))]
5250 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5251 "adc{w}\t{%2, %0|%0, %2}"
5252 [(set_attr "type" "alu")
5253 (set_attr "pent_pair" "pu")
5254 (set_attr "mode" "HI")
5255 (set_attr "ppro_uops" "few")])
5256
5257 (define_insn "addsi3_carry"
5258 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5259 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5260 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5261 (match_operand:SI 2 "general_operand" "ri,rm")))
5262 (clobber (reg:CC 17))]
5263 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5264 "adc{l}\t{%2, %0|%0, %2}"
5265 [(set_attr "type" "alu")
5266 (set_attr "pent_pair" "pu")
5267 (set_attr "mode" "SI")
5268 (set_attr "ppro_uops" "few")])
5269
5270 (define_insn "*addsi3_carry_zext"
5271 [(set (match_operand:DI 0 "register_operand" "=r")
5272 (zero_extend:DI
5273 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5274 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5275 (match_operand:SI 2 "general_operand" "rim"))))
5276 (clobber (reg:CC 17))]
5277 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5278 "adc{l}\t{%2, %k0|%k0, %2}"
5279 [(set_attr "type" "alu")
5280 (set_attr "pent_pair" "pu")
5281 (set_attr "mode" "SI")
5282 (set_attr "ppro_uops" "few")])
5283
5284 (define_insn "*addsi3_cc"
5285 [(set (reg:CC 17)
5286 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5287 (match_operand:SI 2 "general_operand" "ri,rm")]
5288 UNSPEC_ADD_CARRY))
5289 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5290 (plus:SI (match_dup 1) (match_dup 2)))]
5291 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5292 "add{l}\t{%2, %0|%0, %2}"
5293 [(set_attr "type" "alu")
5294 (set_attr "mode" "SI")])
5295
5296 (define_insn "addqi3_cc"
5297 [(set (reg:CC 17)
5298 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5299 (match_operand:QI 2 "general_operand" "qi,qm")]
5300 UNSPEC_ADD_CARRY))
5301 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5302 (plus:QI (match_dup 1) (match_dup 2)))]
5303 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5304 "add{b}\t{%2, %0|%0, %2}"
5305 [(set_attr "type" "alu")
5306 (set_attr "mode" "QI")])
5307
5308 (define_expand "addsi3"
5309 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5310 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5311 (match_operand:SI 2 "general_operand" "")))
5312 (clobber (reg:CC 17))])]
5313 ""
5314 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5315
5316 (define_insn "*lea_1"
5317 [(set (match_operand:SI 0 "register_operand" "=r")
5318 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5319 "!TARGET_64BIT"
5320 "lea{l}\t{%a1, %0|%0, %a1}"
5321 [(set_attr "type" "lea")
5322 (set_attr "mode" "SI")])
5323
5324 (define_insn "*lea_1_rex64"
5325 [(set (match_operand:SI 0 "register_operand" "=r")
5326 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5327 "TARGET_64BIT"
5328 "lea{l}\t{%a1, %0|%0, %a1}"
5329 [(set_attr "type" "lea")
5330 (set_attr "mode" "SI")])
5331
5332 (define_insn "*lea_1_zext"
5333 [(set (match_operand:DI 0 "register_operand" "=r")
5334 (zero_extend:DI
5335 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5336 "TARGET_64BIT"
5337 "lea{l}\t{%a1, %k0|%k0, %a1}"
5338 [(set_attr "type" "lea")
5339 (set_attr "mode" "SI")])
5340
5341 (define_insn "*lea_2_rex64"
5342 [(set (match_operand:DI 0 "register_operand" "=r")
5343 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5344 "TARGET_64BIT"
5345 "lea{q}\t{%a1, %0|%0, %a1}"
5346 [(set_attr "type" "lea")
5347 (set_attr "mode" "DI")])
5348
5349 ;; The lea patterns for non-Pmodes needs to be matched by several
5350 ;; insns converted to real lea by splitters.
5351
5352 (define_insn_and_split "*lea_general_1"
5353 [(set (match_operand 0 "register_operand" "=r")
5354 (plus (plus (match_operand 1 "index_register_operand" "r")
5355 (match_operand 2 "register_operand" "r"))
5356 (match_operand 3 "immediate_operand" "i")))]
5357 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5358 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5359 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5360 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5361 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5362 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5363 || GET_MODE (operands[3]) == VOIDmode)"
5364 "#"
5365 "&& reload_completed"
5366 [(const_int 0)]
5367 {
5368 rtx pat;
5369 operands[0] = gen_lowpart (SImode, operands[0]);
5370 operands[1] = gen_lowpart (Pmode, operands[1]);
5371 operands[2] = gen_lowpart (Pmode, operands[2]);
5372 operands[3] = gen_lowpart (Pmode, operands[3]);
5373 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5374 operands[3]);
5375 if (Pmode != SImode)
5376 pat = gen_rtx_SUBREG (SImode, pat, 0);
5377 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5378 DONE;
5379 }
5380 [(set_attr "type" "lea")
5381 (set_attr "mode" "SI")])
5382
5383 (define_insn_and_split "*lea_general_1_zext"
5384 [(set (match_operand:DI 0 "register_operand" "=r")
5385 (zero_extend:DI
5386 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5387 (match_operand:SI 2 "register_operand" "r"))
5388 (match_operand:SI 3 "immediate_operand" "i"))))]
5389 "TARGET_64BIT"
5390 "#"
5391 "&& reload_completed"
5392 [(set (match_dup 0)
5393 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5394 (match_dup 2))
5395 (match_dup 3)) 0)))]
5396 {
5397 operands[1] = gen_lowpart (Pmode, operands[1]);
5398 operands[2] = gen_lowpart (Pmode, operands[2]);
5399 operands[3] = gen_lowpart (Pmode, operands[3]);
5400 }
5401 [(set_attr "type" "lea")
5402 (set_attr "mode" "SI")])
5403
5404 (define_insn_and_split "*lea_general_2"
5405 [(set (match_operand 0 "register_operand" "=r")
5406 (plus (mult (match_operand 1 "index_register_operand" "r")
5407 (match_operand 2 "const248_operand" "i"))
5408 (match_operand 3 "nonmemory_operand" "ri")))]
5409 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5410 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5411 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5412 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5413 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5414 || GET_MODE (operands[3]) == VOIDmode)"
5415 "#"
5416 "&& reload_completed"
5417 [(const_int 0)]
5418 {
5419 rtx pat;
5420 operands[0] = gen_lowpart (SImode, operands[0]);
5421 operands[1] = gen_lowpart (Pmode, operands[1]);
5422 operands[3] = gen_lowpart (Pmode, operands[3]);
5423 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5424 operands[3]);
5425 if (Pmode != SImode)
5426 pat = gen_rtx_SUBREG (SImode, pat, 0);
5427 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5428 DONE;
5429 }
5430 [(set_attr "type" "lea")
5431 (set_attr "mode" "SI")])
5432
5433 (define_insn_and_split "*lea_general_2_zext"
5434 [(set (match_operand:DI 0 "register_operand" "=r")
5435 (zero_extend:DI
5436 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5437 (match_operand:SI 2 "const248_operand" "n"))
5438 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5439 "TARGET_64BIT"
5440 "#"
5441 "&& reload_completed"
5442 [(set (match_dup 0)
5443 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5444 (match_dup 2))
5445 (match_dup 3)) 0)))]
5446 {
5447 operands[1] = gen_lowpart (Pmode, operands[1]);
5448 operands[3] = gen_lowpart (Pmode, operands[3]);
5449 }
5450 [(set_attr "type" "lea")
5451 (set_attr "mode" "SI")])
5452
5453 (define_insn_and_split "*lea_general_3"
5454 [(set (match_operand 0 "register_operand" "=r")
5455 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5456 (match_operand 2 "const248_operand" "i"))
5457 (match_operand 3 "register_operand" "r"))
5458 (match_operand 4 "immediate_operand" "i")))]
5459 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5460 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5461 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5462 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5463 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5464 "#"
5465 "&& reload_completed"
5466 [(const_int 0)]
5467 {
5468 rtx pat;
5469 operands[0] = gen_lowpart (SImode, operands[0]);
5470 operands[1] = gen_lowpart (Pmode, operands[1]);
5471 operands[3] = gen_lowpart (Pmode, operands[3]);
5472 operands[4] = gen_lowpart (Pmode, operands[4]);
5473 pat = gen_rtx_PLUS (Pmode,
5474 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5475 operands[2]),
5476 operands[3]),
5477 operands[4]);
5478 if (Pmode != SImode)
5479 pat = gen_rtx_SUBREG (SImode, pat, 0);
5480 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5481 DONE;
5482 }
5483 [(set_attr "type" "lea")
5484 (set_attr "mode" "SI")])
5485
5486 (define_insn_and_split "*lea_general_3_zext"
5487 [(set (match_operand:DI 0 "register_operand" "=r")
5488 (zero_extend:DI
5489 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5490 (match_operand:SI 2 "const248_operand" "n"))
5491 (match_operand:SI 3 "register_operand" "r"))
5492 (match_operand:SI 4 "immediate_operand" "i"))))]
5493 "TARGET_64BIT"
5494 "#"
5495 "&& reload_completed"
5496 [(set (match_dup 0)
5497 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5498 (match_dup 2))
5499 (match_dup 3))
5500 (match_dup 4)) 0)))]
5501 {
5502 operands[1] = gen_lowpart (Pmode, operands[1]);
5503 operands[3] = gen_lowpart (Pmode, operands[3]);
5504 operands[4] = gen_lowpart (Pmode, operands[4]);
5505 }
5506 [(set_attr "type" "lea")
5507 (set_attr "mode" "SI")])
5508
5509 (define_insn "*adddi_1_rex64"
5510 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5511 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5512 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5513 (clobber (reg:CC 17))]
5514 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5515 {
5516 switch (get_attr_type (insn))
5517 {
5518 case TYPE_LEA:
5519 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5520 return "lea{q}\t{%a2, %0|%0, %a2}";
5521
5522 case TYPE_INCDEC:
5523 if (! rtx_equal_p (operands[0], operands[1]))
5524 abort ();
5525 if (operands[2] == const1_rtx)
5526 return "inc{q}\t%0";
5527 else if (operands[2] == constm1_rtx)
5528 return "dec{q}\t%0";
5529 else
5530 abort ();
5531
5532 default:
5533 if (! rtx_equal_p (operands[0], operands[1]))
5534 abort ();
5535
5536 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5537 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5538 if (GET_CODE (operands[2]) == CONST_INT
5539 /* Avoid overflows. */
5540 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5541 && (INTVAL (operands[2]) == 128
5542 || (INTVAL (operands[2]) < 0
5543 && INTVAL (operands[2]) != -128)))
5544 {
5545 operands[2] = GEN_INT (-INTVAL (operands[2]));
5546 return "sub{q}\t{%2, %0|%0, %2}";
5547 }
5548 return "add{q}\t{%2, %0|%0, %2}";
5549 }
5550 }
5551 [(set (attr "type")
5552 (cond [(eq_attr "alternative" "2")
5553 (const_string "lea")
5554 ; Current assemblers are broken and do not allow @GOTOFF in
5555 ; ought but a memory context.
5556 (match_operand:DI 2 "pic_symbolic_operand" "")
5557 (const_string "lea")
5558 (match_operand:DI 2 "incdec_operand" "")
5559 (const_string "incdec")
5560 ]
5561 (const_string "alu")))
5562 (set_attr "mode" "DI")])
5563
5564 ;; Convert lea to the lea pattern to avoid flags dependency.
5565 (define_split
5566 [(set (match_operand:DI 0 "register_operand" "")
5567 (plus:DI (match_operand:DI 1 "register_operand" "")
5568 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5569 (clobber (reg:CC 17))]
5570 "TARGET_64BIT && reload_completed
5571 && true_regnum (operands[0]) != true_regnum (operands[1])"
5572 [(set (match_dup 0)
5573 (plus:DI (match_dup 1)
5574 (match_dup 2)))]
5575 "")
5576
5577 (define_insn "*adddi_2_rex64"
5578 [(set (reg 17)
5579 (compare
5580 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5581 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5582 (const_int 0)))
5583 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5584 (plus:DI (match_dup 1) (match_dup 2)))]
5585 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5586 && ix86_binary_operator_ok (PLUS, DImode, operands)
5587 /* Current assemblers are broken and do not allow @GOTOFF in
5588 ought but a memory context. */
5589 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5590 {
5591 switch (get_attr_type (insn))
5592 {
5593 case TYPE_INCDEC:
5594 if (! rtx_equal_p (operands[0], operands[1]))
5595 abort ();
5596 if (operands[2] == const1_rtx)
5597 return "inc{q}\t%0";
5598 else if (operands[2] == constm1_rtx)
5599 return "dec{q}\t%0";
5600 else
5601 abort ();
5602
5603 default:
5604 if (! rtx_equal_p (operands[0], operands[1]))
5605 abort ();
5606 /* ???? We ought to handle there the 32bit case too
5607 - do we need new constraint? */
5608 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5609 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5610 if (GET_CODE (operands[2]) == CONST_INT
5611 /* Avoid overflows. */
5612 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5613 && (INTVAL (operands[2]) == 128
5614 || (INTVAL (operands[2]) < 0
5615 && INTVAL (operands[2]) != -128)))
5616 {
5617 operands[2] = GEN_INT (-INTVAL (operands[2]));
5618 return "sub{q}\t{%2, %0|%0, %2}";
5619 }
5620 return "add{q}\t{%2, %0|%0, %2}";
5621 }
5622 }
5623 [(set (attr "type")
5624 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5625 (const_string "incdec")
5626 (const_string "alu")))
5627 (set_attr "mode" "DI")])
5628
5629 (define_insn "*adddi_3_rex64"
5630 [(set (reg 17)
5631 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5632 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5633 (clobber (match_scratch:DI 0 "=r"))]
5634 "TARGET_64BIT
5635 && ix86_match_ccmode (insn, CCZmode)
5636 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5637 /* Current assemblers are broken and do not allow @GOTOFF in
5638 ought but a memory context. */
5639 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5640 {
5641 switch (get_attr_type (insn))
5642 {
5643 case TYPE_INCDEC:
5644 if (! rtx_equal_p (operands[0], operands[1]))
5645 abort ();
5646 if (operands[2] == const1_rtx)
5647 return "inc{q}\t%0";
5648 else if (operands[2] == constm1_rtx)
5649 return "dec{q}\t%0";
5650 else
5651 abort ();
5652
5653 default:
5654 if (! rtx_equal_p (operands[0], operands[1]))
5655 abort ();
5656 /* ???? We ought to handle there the 32bit case too
5657 - do we need new constraint? */
5658 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5659 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5660 if (GET_CODE (operands[2]) == CONST_INT
5661 /* Avoid overflows. */
5662 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5663 && (INTVAL (operands[2]) == 128
5664 || (INTVAL (operands[2]) < 0
5665 && INTVAL (operands[2]) != -128)))
5666 {
5667 operands[2] = GEN_INT (-INTVAL (operands[2]));
5668 return "sub{q}\t{%2, %0|%0, %2}";
5669 }
5670 return "add{q}\t{%2, %0|%0, %2}";
5671 }
5672 }
5673 [(set (attr "type")
5674 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5675 (const_string "incdec")
5676 (const_string "alu")))
5677 (set_attr "mode" "DI")])
5678
5679 ; For comparisons against 1, -1 and 128, we may generate better code
5680 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5681 ; is matched then. We can't accept general immediate, because for
5682 ; case of overflows, the result is messed up.
5683 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5684 ; when negated.
5685 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5686 ; only for comparisons not depending on it.
5687 (define_insn "*adddi_4_rex64"
5688 [(set (reg 17)
5689 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5690 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5691 (clobber (match_scratch:DI 0 "=rm"))]
5692 "TARGET_64BIT
5693 && ix86_match_ccmode (insn, CCGCmode)"
5694 {
5695 switch (get_attr_type (insn))
5696 {
5697 case TYPE_INCDEC:
5698 if (operands[2] == constm1_rtx)
5699 return "inc{q}\t%0";
5700 else if (operands[2] == const1_rtx)
5701 return "dec{q}\t%0";
5702 else
5703 abort();
5704
5705 default:
5706 if (! rtx_equal_p (operands[0], operands[1]))
5707 abort ();
5708 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5709 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5710 if ((INTVAL (operands[2]) == -128
5711 || (INTVAL (operands[2]) > 0
5712 && INTVAL (operands[2]) != 128))
5713 /* Avoid overflows. */
5714 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5715 return "sub{q}\t{%2, %0|%0, %2}";
5716 operands[2] = GEN_INT (-INTVAL (operands[2]));
5717 return "add{q}\t{%2, %0|%0, %2}";
5718 }
5719 }
5720 [(set (attr "type")
5721 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5722 (const_string "incdec")
5723 (const_string "alu")))
5724 (set_attr "mode" "DI")])
5725
5726 (define_insn "*adddi_5_rex64"
5727 [(set (reg 17)
5728 (compare
5729 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5730 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5731 (const_int 0)))
5732 (clobber (match_scratch:DI 0 "=r"))]
5733 "TARGET_64BIT
5734 && ix86_match_ccmode (insn, CCGOCmode)
5735 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5736 /* Current assemblers are broken and do not allow @GOTOFF in
5737 ought but a memory context. */
5738 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5739 {
5740 switch (get_attr_type (insn))
5741 {
5742 case TYPE_INCDEC:
5743 if (! rtx_equal_p (operands[0], operands[1]))
5744 abort ();
5745 if (operands[2] == const1_rtx)
5746 return "inc{q}\t%0";
5747 else if (operands[2] == constm1_rtx)
5748 return "dec{q}\t%0";
5749 else
5750 abort();
5751
5752 default:
5753 if (! rtx_equal_p (operands[0], operands[1]))
5754 abort ();
5755 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5756 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5757 if (GET_CODE (operands[2]) == CONST_INT
5758 /* Avoid overflows. */
5759 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5760 && (INTVAL (operands[2]) == 128
5761 || (INTVAL (operands[2]) < 0
5762 && INTVAL (operands[2]) != -128)))
5763 {
5764 operands[2] = GEN_INT (-INTVAL (operands[2]));
5765 return "sub{q}\t{%2, %0|%0, %2}";
5766 }
5767 return "add{q}\t{%2, %0|%0, %2}";
5768 }
5769 }
5770 [(set (attr "type")
5771 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5772 (const_string "incdec")
5773 (const_string "alu")))
5774 (set_attr "mode" "DI")])
5775
5776
5777 (define_insn "*addsi_1"
5778 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5779 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5780 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5781 (clobber (reg:CC 17))]
5782 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5783 {
5784 switch (get_attr_type (insn))
5785 {
5786 case TYPE_LEA:
5787 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5788 return "lea{l}\t{%a2, %0|%0, %a2}";
5789
5790 case TYPE_INCDEC:
5791 if (! rtx_equal_p (operands[0], operands[1]))
5792 abort ();
5793 if (operands[2] == const1_rtx)
5794 return "inc{l}\t%0";
5795 else if (operands[2] == constm1_rtx)
5796 return "dec{l}\t%0";
5797 else
5798 abort();
5799
5800 default:
5801 if (! rtx_equal_p (operands[0], operands[1]))
5802 abort ();
5803
5804 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5805 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5806 if (GET_CODE (operands[2]) == CONST_INT
5807 && (INTVAL (operands[2]) == 128
5808 || (INTVAL (operands[2]) < 0
5809 && INTVAL (operands[2]) != -128)))
5810 {
5811 operands[2] = GEN_INT (-INTVAL (operands[2]));
5812 return "sub{l}\t{%2, %0|%0, %2}";
5813 }
5814 return "add{l}\t{%2, %0|%0, %2}";
5815 }
5816 }
5817 [(set (attr "type")
5818 (cond [(eq_attr "alternative" "2")
5819 (const_string "lea")
5820 ; Current assemblers are broken and do not allow @GOTOFF in
5821 ; ought but a memory context.
5822 (match_operand:SI 2 "pic_symbolic_operand" "")
5823 (const_string "lea")
5824 (match_operand:SI 2 "incdec_operand" "")
5825 (const_string "incdec")
5826 ]
5827 (const_string "alu")))
5828 (set_attr "mode" "SI")])
5829
5830 ;; Convert lea to the lea pattern to avoid flags dependency.
5831 (define_split
5832 [(set (match_operand 0 "register_operand" "")
5833 (plus (match_operand 1 "register_operand" "")
5834 (match_operand 2 "nonmemory_operand" "")))
5835 (clobber (reg:CC 17))]
5836 "reload_completed
5837 && true_regnum (operands[0]) != true_regnum (operands[1])"
5838 [(const_int 0)]
5839 {
5840 rtx pat;
5841 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5842 may confuse gen_lowpart. */
5843 if (GET_MODE (operands[0]) != Pmode)
5844 {
5845 operands[1] = gen_lowpart (Pmode, operands[1]);
5846 operands[2] = gen_lowpart (Pmode, operands[2]);
5847 }
5848 operands[0] = gen_lowpart (SImode, operands[0]);
5849 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5850 if (Pmode != SImode)
5851 pat = gen_rtx_SUBREG (SImode, pat, 0);
5852 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5853 DONE;
5854 })
5855
5856 ;; It may seem that nonimmediate operand is proper one for operand 1.
5857 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5858 ;; we take care in ix86_binary_operator_ok to not allow two memory
5859 ;; operands so proper swapping will be done in reload. This allow
5860 ;; patterns constructed from addsi_1 to match.
5861 (define_insn "addsi_1_zext"
5862 [(set (match_operand:DI 0 "register_operand" "=r,r")
5863 (zero_extend:DI
5864 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5865 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5866 (clobber (reg:CC 17))]
5867 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5868 {
5869 switch (get_attr_type (insn))
5870 {
5871 case TYPE_LEA:
5872 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5873 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5874
5875 case TYPE_INCDEC:
5876 if (operands[2] == const1_rtx)
5877 return "inc{l}\t%k0";
5878 else if (operands[2] == constm1_rtx)
5879 return "dec{l}\t%k0";
5880 else
5881 abort();
5882
5883 default:
5884 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5885 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5886 if (GET_CODE (operands[2]) == CONST_INT
5887 && (INTVAL (operands[2]) == 128
5888 || (INTVAL (operands[2]) < 0
5889 && INTVAL (operands[2]) != -128)))
5890 {
5891 operands[2] = GEN_INT (-INTVAL (operands[2]));
5892 return "sub{l}\t{%2, %k0|%k0, %2}";
5893 }
5894 return "add{l}\t{%2, %k0|%k0, %2}";
5895 }
5896 }
5897 [(set (attr "type")
5898 (cond [(eq_attr "alternative" "1")
5899 (const_string "lea")
5900 ; Current assemblers are broken and do not allow @GOTOFF in
5901 ; ought but a memory context.
5902 (match_operand:SI 2 "pic_symbolic_operand" "")
5903 (const_string "lea")
5904 (match_operand:SI 2 "incdec_operand" "")
5905 (const_string "incdec")
5906 ]
5907 (const_string "alu")))
5908 (set_attr "mode" "SI")])
5909
5910 ;; Convert lea to the lea pattern to avoid flags dependency.
5911 (define_split
5912 [(set (match_operand:DI 0 "register_operand" "")
5913 (zero_extend:DI
5914 (plus:SI (match_operand:SI 1 "register_operand" "")
5915 (match_operand:SI 2 "nonmemory_operand" ""))))
5916 (clobber (reg:CC 17))]
5917 "TARGET_64BIT && reload_completed
5918 && true_regnum (operands[0]) != true_regnum (operands[1])"
5919 [(set (match_dup 0)
5920 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5921 {
5922 operands[1] = gen_lowpart (Pmode, operands[1]);
5923 operands[2] = gen_lowpart (Pmode, operands[2]);
5924 })
5925
5926 (define_insn "*addsi_2"
5927 [(set (reg 17)
5928 (compare
5929 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5930 (match_operand:SI 2 "general_operand" "rmni,rni"))
5931 (const_int 0)))
5932 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5933 (plus:SI (match_dup 1) (match_dup 2)))]
5934 "ix86_match_ccmode (insn, CCGOCmode)
5935 && ix86_binary_operator_ok (PLUS, SImode, operands)
5936 /* Current assemblers are broken and do not allow @GOTOFF in
5937 ought but a memory context. */
5938 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5939 {
5940 switch (get_attr_type (insn))
5941 {
5942 case TYPE_INCDEC:
5943 if (! rtx_equal_p (operands[0], operands[1]))
5944 abort ();
5945 if (operands[2] == const1_rtx)
5946 return "inc{l}\t%0";
5947 else if (operands[2] == constm1_rtx)
5948 return "dec{l}\t%0";
5949 else
5950 abort();
5951
5952 default:
5953 if (! rtx_equal_p (operands[0], operands[1]))
5954 abort ();
5955 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5957 if (GET_CODE (operands[2]) == CONST_INT
5958 && (INTVAL (operands[2]) == 128
5959 || (INTVAL (operands[2]) < 0
5960 && INTVAL (operands[2]) != -128)))
5961 {
5962 operands[2] = GEN_INT (-INTVAL (operands[2]));
5963 return "sub{l}\t{%2, %0|%0, %2}";
5964 }
5965 return "add{l}\t{%2, %0|%0, %2}";
5966 }
5967 }
5968 [(set (attr "type")
5969 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5970 (const_string "incdec")
5971 (const_string "alu")))
5972 (set_attr "mode" "SI")])
5973
5974 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5975 (define_insn "*addsi_2_zext"
5976 [(set (reg 17)
5977 (compare
5978 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5979 (match_operand:SI 2 "general_operand" "rmni"))
5980 (const_int 0)))
5981 (set (match_operand:DI 0 "register_operand" "=r")
5982 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5983 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5984 && ix86_binary_operator_ok (PLUS, SImode, operands)
5985 /* Current assemblers are broken and do not allow @GOTOFF in
5986 ought but a memory context. */
5987 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5988 {
5989 switch (get_attr_type (insn))
5990 {
5991 case TYPE_INCDEC:
5992 if (operands[2] == const1_rtx)
5993 return "inc{l}\t%k0";
5994 else if (operands[2] == constm1_rtx)
5995 return "dec{l}\t%k0";
5996 else
5997 abort();
5998
5999 default:
6000 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6001 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6002 if (GET_CODE (operands[2]) == CONST_INT
6003 && (INTVAL (operands[2]) == 128
6004 || (INTVAL (operands[2]) < 0
6005 && INTVAL (operands[2]) != -128)))
6006 {
6007 operands[2] = GEN_INT (-INTVAL (operands[2]));
6008 return "sub{l}\t{%2, %k0|%k0, %2}";
6009 }
6010 return "add{l}\t{%2, %k0|%k0, %2}";
6011 }
6012 }
6013 [(set (attr "type")
6014 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6015 (const_string "incdec")
6016 (const_string "alu")))
6017 (set_attr "mode" "SI")])
6018
6019 (define_insn "*addsi_3"
6020 [(set (reg 17)
6021 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6022 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6023 (clobber (match_scratch:SI 0 "=r"))]
6024 "ix86_match_ccmode (insn, CCZmode)
6025 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6026 /* Current assemblers are broken and do not allow @GOTOFF in
6027 ought but a memory context. */
6028 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6029 {
6030 switch (get_attr_type (insn))
6031 {
6032 case TYPE_INCDEC:
6033 if (! rtx_equal_p (operands[0], operands[1]))
6034 abort ();
6035 if (operands[2] == const1_rtx)
6036 return "inc{l}\t%0";
6037 else if (operands[2] == constm1_rtx)
6038 return "dec{l}\t%0";
6039 else
6040 abort();
6041
6042 default:
6043 if (! rtx_equal_p (operands[0], operands[1]))
6044 abort ();
6045 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6046 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6047 if (GET_CODE (operands[2]) == CONST_INT
6048 && (INTVAL (operands[2]) == 128
6049 || (INTVAL (operands[2]) < 0
6050 && INTVAL (operands[2]) != -128)))
6051 {
6052 operands[2] = GEN_INT (-INTVAL (operands[2]));
6053 return "sub{l}\t{%2, %0|%0, %2}";
6054 }
6055 return "add{l}\t{%2, %0|%0, %2}";
6056 }
6057 }
6058 [(set (attr "type")
6059 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6060 (const_string "incdec")
6061 (const_string "alu")))
6062 (set_attr "mode" "SI")])
6063
6064 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6065 (define_insn "*addsi_3_zext"
6066 [(set (reg 17)
6067 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6068 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6069 (set (match_operand:DI 0 "register_operand" "=r")
6070 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6071 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6072 && ix86_binary_operator_ok (PLUS, SImode, operands)
6073 /* Current assemblers are broken and do not allow @GOTOFF in
6074 ought but a memory context. */
6075 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6076 {
6077 switch (get_attr_type (insn))
6078 {
6079 case TYPE_INCDEC:
6080 if (operands[2] == const1_rtx)
6081 return "inc{l}\t%k0";
6082 else if (operands[2] == constm1_rtx)
6083 return "dec{l}\t%k0";
6084 else
6085 abort();
6086
6087 default:
6088 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6089 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6090 if (GET_CODE (operands[2]) == CONST_INT
6091 && (INTVAL (operands[2]) == 128
6092 || (INTVAL (operands[2]) < 0
6093 && INTVAL (operands[2]) != -128)))
6094 {
6095 operands[2] = GEN_INT (-INTVAL (operands[2]));
6096 return "sub{l}\t{%2, %k0|%k0, %2}";
6097 }
6098 return "add{l}\t{%2, %k0|%k0, %2}";
6099 }
6100 }
6101 [(set (attr "type")
6102 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6103 (const_string "incdec")
6104 (const_string "alu")))
6105 (set_attr "mode" "SI")])
6106
6107 ; For comparisons against 1, -1 and 128, we may generate better code
6108 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6109 ; is matched then. We can't accept general immediate, because for
6110 ; case of overflows, the result is messed up.
6111 ; This pattern also don't hold of 0x80000000, since the value overflows
6112 ; when negated.
6113 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6114 ; only for comparisons not depending on it.
6115 (define_insn "*addsi_4"
6116 [(set (reg 17)
6117 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6118 (match_operand:SI 2 "const_int_operand" "n")))
6119 (clobber (match_scratch:SI 0 "=rm"))]
6120 "ix86_match_ccmode (insn, CCGCmode)
6121 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6122 {
6123 switch (get_attr_type (insn))
6124 {
6125 case TYPE_INCDEC:
6126 if (operands[2] == constm1_rtx)
6127 return "inc{l}\t%0";
6128 else if (operands[2] == const1_rtx)
6129 return "dec{l}\t%0";
6130 else
6131 abort();
6132
6133 default:
6134 if (! rtx_equal_p (operands[0], operands[1]))
6135 abort ();
6136 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6137 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6138 if ((INTVAL (operands[2]) == -128
6139 || (INTVAL (operands[2]) > 0
6140 && INTVAL (operands[2]) != 128)))
6141 return "sub{l}\t{%2, %0|%0, %2}";
6142 operands[2] = GEN_INT (-INTVAL (operands[2]));
6143 return "add{l}\t{%2, %0|%0, %2}";
6144 }
6145 }
6146 [(set (attr "type")
6147 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6148 (const_string "incdec")
6149 (const_string "alu")))
6150 (set_attr "mode" "SI")])
6151
6152 (define_insn "*addsi_5"
6153 [(set (reg 17)
6154 (compare
6155 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6156 (match_operand:SI 2 "general_operand" "rmni"))
6157 (const_int 0)))
6158 (clobber (match_scratch:SI 0 "=r"))]
6159 "ix86_match_ccmode (insn, CCGOCmode)
6160 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6161 /* Current assemblers are broken and do not allow @GOTOFF in
6162 ought but a memory context. */
6163 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6164 {
6165 switch (get_attr_type (insn))
6166 {
6167 case TYPE_INCDEC:
6168 if (! rtx_equal_p (operands[0], operands[1]))
6169 abort ();
6170 if (operands[2] == const1_rtx)
6171 return "inc{l}\t%0";
6172 else if (operands[2] == constm1_rtx)
6173 return "dec{l}\t%0";
6174 else
6175 abort();
6176
6177 default:
6178 if (! rtx_equal_p (operands[0], operands[1]))
6179 abort ();
6180 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6181 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6182 if (GET_CODE (operands[2]) == CONST_INT
6183 && (INTVAL (operands[2]) == 128
6184 || (INTVAL (operands[2]) < 0
6185 && INTVAL (operands[2]) != -128)))
6186 {
6187 operands[2] = GEN_INT (-INTVAL (operands[2]));
6188 return "sub{l}\t{%2, %0|%0, %2}";
6189 }
6190 return "add{l}\t{%2, %0|%0, %2}";
6191 }
6192 }
6193 [(set (attr "type")
6194 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6195 (const_string "incdec")
6196 (const_string "alu")))
6197 (set_attr "mode" "SI")])
6198
6199 (define_expand "addhi3"
6200 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6201 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6202 (match_operand:HI 2 "general_operand" "")))
6203 (clobber (reg:CC 17))])]
6204 "TARGET_HIMODE_MATH"
6205 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6206
6207 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6208 ;; type optimizations enabled by define-splits. This is not important
6209 ;; for PII, and in fact harmful because of partial register stalls.
6210
6211 (define_insn "*addhi_1_lea"
6212 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6213 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6214 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6215 (clobber (reg:CC 17))]
6216 "!TARGET_PARTIAL_REG_STALL
6217 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6218 {
6219 switch (get_attr_type (insn))
6220 {
6221 case TYPE_LEA:
6222 return "#";
6223 case TYPE_INCDEC:
6224 if (operands[2] == const1_rtx)
6225 return "inc{w}\t%0";
6226 else if (operands[2] == constm1_rtx)
6227 return "dec{w}\t%0";
6228 abort();
6229
6230 default:
6231 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6232 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6233 if (GET_CODE (operands[2]) == CONST_INT
6234 && (INTVAL (operands[2]) == 128
6235 || (INTVAL (operands[2]) < 0
6236 && INTVAL (operands[2]) != -128)))
6237 {
6238 operands[2] = GEN_INT (-INTVAL (operands[2]));
6239 return "sub{w}\t{%2, %0|%0, %2}";
6240 }
6241 return "add{w}\t{%2, %0|%0, %2}";
6242 }
6243 }
6244 [(set (attr "type")
6245 (if_then_else (eq_attr "alternative" "2")
6246 (const_string "lea")
6247 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6248 (const_string "incdec")
6249 (const_string "alu"))))
6250 (set_attr "mode" "HI,HI,SI")])
6251
6252 (define_insn "*addhi_1"
6253 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6254 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6255 (match_operand:HI 2 "general_operand" "ri,rm")))
6256 (clobber (reg:CC 17))]
6257 "TARGET_PARTIAL_REG_STALL
6258 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6259 {
6260 switch (get_attr_type (insn))
6261 {
6262 case TYPE_INCDEC:
6263 if (operands[2] == const1_rtx)
6264 return "inc{w}\t%0";
6265 else if (operands[2] == constm1_rtx)
6266 return "dec{w}\t%0";
6267 abort();
6268
6269 default:
6270 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6271 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6272 if (GET_CODE (operands[2]) == CONST_INT
6273 && (INTVAL (operands[2]) == 128
6274 || (INTVAL (operands[2]) < 0
6275 && INTVAL (operands[2]) != -128)))
6276 {
6277 operands[2] = GEN_INT (-INTVAL (operands[2]));
6278 return "sub{w}\t{%2, %0|%0, %2}";
6279 }
6280 return "add{w}\t{%2, %0|%0, %2}";
6281 }
6282 }
6283 [(set (attr "type")
6284 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6285 (const_string "incdec")
6286 (const_string "alu")))
6287 (set_attr "mode" "HI")])
6288
6289 (define_insn "*addhi_2"
6290 [(set (reg 17)
6291 (compare
6292 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6293 (match_operand:HI 2 "general_operand" "rmni,rni"))
6294 (const_int 0)))
6295 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6296 (plus:HI (match_dup 1) (match_dup 2)))]
6297 "ix86_match_ccmode (insn, CCGOCmode)
6298 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6299 {
6300 switch (get_attr_type (insn))
6301 {
6302 case TYPE_INCDEC:
6303 if (operands[2] == const1_rtx)
6304 return "inc{w}\t%0";
6305 else if (operands[2] == constm1_rtx)
6306 return "dec{w}\t%0";
6307 abort();
6308
6309 default:
6310 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6311 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6312 if (GET_CODE (operands[2]) == CONST_INT
6313 && (INTVAL (operands[2]) == 128
6314 || (INTVAL (operands[2]) < 0
6315 && INTVAL (operands[2]) != -128)))
6316 {
6317 operands[2] = GEN_INT (-INTVAL (operands[2]));
6318 return "sub{w}\t{%2, %0|%0, %2}";
6319 }
6320 return "add{w}\t{%2, %0|%0, %2}";
6321 }
6322 }
6323 [(set (attr "type")
6324 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6325 (const_string "incdec")
6326 (const_string "alu")))
6327 (set_attr "mode" "HI")])
6328
6329 (define_insn "*addhi_3"
6330 [(set (reg 17)
6331 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6332 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6333 (clobber (match_scratch:HI 0 "=r"))]
6334 "ix86_match_ccmode (insn, CCZmode)
6335 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6336 {
6337 switch (get_attr_type (insn))
6338 {
6339 case TYPE_INCDEC:
6340 if (operands[2] == const1_rtx)
6341 return "inc{w}\t%0";
6342 else if (operands[2] == constm1_rtx)
6343 return "dec{w}\t%0";
6344 abort();
6345
6346 default:
6347 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6348 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6349 if (GET_CODE (operands[2]) == CONST_INT
6350 && (INTVAL (operands[2]) == 128
6351 || (INTVAL (operands[2]) < 0
6352 && INTVAL (operands[2]) != -128)))
6353 {
6354 operands[2] = GEN_INT (-INTVAL (operands[2]));
6355 return "sub{w}\t{%2, %0|%0, %2}";
6356 }
6357 return "add{w}\t{%2, %0|%0, %2}";
6358 }
6359 }
6360 [(set (attr "type")
6361 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6362 (const_string "incdec")
6363 (const_string "alu")))
6364 (set_attr "mode" "HI")])
6365
6366 ; See comments above addsi_3_imm for details.
6367 (define_insn "*addhi_4"
6368 [(set (reg 17)
6369 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6370 (match_operand:HI 2 "const_int_operand" "n")))
6371 (clobber (match_scratch:HI 0 "=rm"))]
6372 "ix86_match_ccmode (insn, CCGCmode)
6373 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6374 {
6375 switch (get_attr_type (insn))
6376 {
6377 case TYPE_INCDEC:
6378 if (operands[2] == constm1_rtx)
6379 return "inc{w}\t%0";
6380 else if (operands[2] == const1_rtx)
6381 return "dec{w}\t%0";
6382 else
6383 abort();
6384
6385 default:
6386 if (! rtx_equal_p (operands[0], operands[1]))
6387 abort ();
6388 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6389 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6390 if ((INTVAL (operands[2]) == -128
6391 || (INTVAL (operands[2]) > 0
6392 && INTVAL (operands[2]) != 128)))
6393 return "sub{w}\t{%2, %0|%0, %2}";
6394 operands[2] = GEN_INT (-INTVAL (operands[2]));
6395 return "add{w}\t{%2, %0|%0, %2}";
6396 }
6397 }
6398 [(set (attr "type")
6399 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6400 (const_string "incdec")
6401 (const_string "alu")))
6402 (set_attr "mode" "SI")])
6403
6404
6405 (define_insn "*addhi_5"
6406 [(set (reg 17)
6407 (compare
6408 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6409 (match_operand:HI 2 "general_operand" "rmni"))
6410 (const_int 0)))
6411 (clobber (match_scratch:HI 0 "=r"))]
6412 "ix86_match_ccmode (insn, CCGOCmode)
6413 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6414 {
6415 switch (get_attr_type (insn))
6416 {
6417 case TYPE_INCDEC:
6418 if (operands[2] == const1_rtx)
6419 return "inc{w}\t%0";
6420 else if (operands[2] == constm1_rtx)
6421 return "dec{w}\t%0";
6422 abort();
6423
6424 default:
6425 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6426 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6427 if (GET_CODE (operands[2]) == CONST_INT
6428 && (INTVAL (operands[2]) == 128
6429 || (INTVAL (operands[2]) < 0
6430 && INTVAL (operands[2]) != -128)))
6431 {
6432 operands[2] = GEN_INT (-INTVAL (operands[2]));
6433 return "sub{w}\t{%2, %0|%0, %2}";
6434 }
6435 return "add{w}\t{%2, %0|%0, %2}";
6436 }
6437 }
6438 [(set (attr "type")
6439 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6440 (const_string "incdec")
6441 (const_string "alu")))
6442 (set_attr "mode" "HI")])
6443
6444 (define_expand "addqi3"
6445 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6446 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6447 (match_operand:QI 2 "general_operand" "")))
6448 (clobber (reg:CC 17))])]
6449 "TARGET_QIMODE_MATH"
6450 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6451
6452 ;; %%% Potential partial reg stall on alternative 2. What to do?
6453 (define_insn "*addqi_1_lea"
6454 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6455 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6456 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6457 (clobber (reg:CC 17))]
6458 "!TARGET_PARTIAL_REG_STALL
6459 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6460 {
6461 int widen = (which_alternative == 2);
6462 switch (get_attr_type (insn))
6463 {
6464 case TYPE_LEA:
6465 return "#";
6466 case TYPE_INCDEC:
6467 if (operands[2] == const1_rtx)
6468 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6469 else if (operands[2] == constm1_rtx)
6470 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6471 abort();
6472
6473 default:
6474 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6475 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6476 if (GET_CODE (operands[2]) == CONST_INT
6477 && (INTVAL (operands[2]) == 128
6478 || (INTVAL (operands[2]) < 0
6479 && INTVAL (operands[2]) != -128)))
6480 {
6481 operands[2] = GEN_INT (-INTVAL (operands[2]));
6482 if (widen)
6483 return "sub{l}\t{%2, %k0|%k0, %2}";
6484 else
6485 return "sub{b}\t{%2, %0|%0, %2}";
6486 }
6487 if (widen)
6488 return "add{l}\t{%k2, %k0|%k0, %k2}";
6489 else
6490 return "add{b}\t{%2, %0|%0, %2}";
6491 }
6492 }
6493 [(set (attr "type")
6494 (if_then_else (eq_attr "alternative" "3")
6495 (const_string "lea")
6496 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6497 (const_string "incdec")
6498 (const_string "alu"))))
6499 (set_attr "mode" "QI,QI,SI,SI")])
6500
6501 (define_insn "*addqi_1"
6502 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6503 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6504 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6505 (clobber (reg:CC 17))]
6506 "TARGET_PARTIAL_REG_STALL
6507 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6508 {
6509 int widen = (which_alternative == 2);
6510 switch (get_attr_type (insn))
6511 {
6512 case TYPE_INCDEC:
6513 if (operands[2] == const1_rtx)
6514 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6515 else if (operands[2] == constm1_rtx)
6516 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6517 abort();
6518
6519 default:
6520 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6521 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6522 if (GET_CODE (operands[2]) == CONST_INT
6523 && (INTVAL (operands[2]) == 128
6524 || (INTVAL (operands[2]) < 0
6525 && INTVAL (operands[2]) != -128)))
6526 {
6527 operands[2] = GEN_INT (-INTVAL (operands[2]));
6528 if (widen)
6529 return "sub{l}\t{%2, %k0|%k0, %2}";
6530 else
6531 return "sub{b}\t{%2, %0|%0, %2}";
6532 }
6533 if (widen)
6534 return "add{l}\t{%k2, %k0|%k0, %k2}";
6535 else
6536 return "add{b}\t{%2, %0|%0, %2}";
6537 }
6538 }
6539 [(set (attr "type")
6540 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6541 (const_string "incdec")
6542 (const_string "alu")))
6543 (set_attr "mode" "QI,QI,SI")])
6544
6545 (define_insn "*addqi_1_slp"
6546 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6547 (plus:QI (match_dup 0)
6548 (match_operand:QI 1 "general_operand" "qn,qnm")))
6549 (clobber (reg:CC 17))]
6550 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6551 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6552 {
6553 switch (get_attr_type (insn))
6554 {
6555 case TYPE_INCDEC:
6556 if (operands[1] == const1_rtx)
6557 return "inc{b}\t%0";
6558 else if (operands[1] == constm1_rtx)
6559 return "dec{b}\t%0";
6560 abort();
6561
6562 default:
6563 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6564 if (GET_CODE (operands[1]) == CONST_INT
6565 && INTVAL (operands[1]) < 0)
6566 {
6567 operands[2] = GEN_INT (-INTVAL (operands[2]));
6568 return "sub{b}\t{%1, %0|%0, %1}";
6569 }
6570 return "add{b}\t{%1, %0|%0, %1}";
6571 }
6572 }
6573 [(set (attr "type")
6574 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6575 (const_string "incdec")
6576 (const_string "alu1")))
6577 (set_attr "mode" "QI")])
6578
6579 (define_insn "*addqi_2"
6580 [(set (reg 17)
6581 (compare
6582 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6583 (match_operand:QI 2 "general_operand" "qmni,qni"))
6584 (const_int 0)))
6585 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6586 (plus:QI (match_dup 1) (match_dup 2)))]
6587 "ix86_match_ccmode (insn, CCGOCmode)
6588 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6589 {
6590 switch (get_attr_type (insn))
6591 {
6592 case TYPE_INCDEC:
6593 if (operands[2] == const1_rtx)
6594 return "inc{b}\t%0";
6595 else if (operands[2] == constm1_rtx
6596 || (GET_CODE (operands[2]) == CONST_INT
6597 && INTVAL (operands[2]) == 255))
6598 return "dec{b}\t%0";
6599 abort();
6600
6601 default:
6602 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6603 if (GET_CODE (operands[2]) == CONST_INT
6604 && INTVAL (operands[2]) < 0)
6605 {
6606 operands[2] = GEN_INT (-INTVAL (operands[2]));
6607 return "sub{b}\t{%2, %0|%0, %2}";
6608 }
6609 return "add{b}\t{%2, %0|%0, %2}";
6610 }
6611 }
6612 [(set (attr "type")
6613 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6614 (const_string "incdec")
6615 (const_string "alu")))
6616 (set_attr "mode" "QI")])
6617
6618 (define_insn "*addqi_3"
6619 [(set (reg 17)
6620 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6621 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6622 (clobber (match_scratch:QI 0 "=q"))]
6623 "ix86_match_ccmode (insn, CCZmode)
6624 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
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 ; See comments above addsi_3_imm for details.
6655 (define_insn "*addqi_4"
6656 [(set (reg 17)
6657 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6658 (match_operand:QI 2 "const_int_operand" "n")))
6659 (clobber (match_scratch:QI 0 "=qm"))]
6660 "ix86_match_ccmode (insn, CCGCmode)
6661 && (INTVAL (operands[2]) & 0xff) != 0x80"
6662 {
6663 switch (get_attr_type (insn))
6664 {
6665 case TYPE_INCDEC:
6666 if (operands[2] == constm1_rtx
6667 || (GET_CODE (operands[2]) == CONST_INT
6668 && INTVAL (operands[2]) == 255))
6669 return "inc{b}\t%0";
6670 else if (operands[2] == const1_rtx)
6671 return "dec{b}\t%0";
6672 else
6673 abort();
6674
6675 default:
6676 if (! rtx_equal_p (operands[0], operands[1]))
6677 abort ();
6678 if (INTVAL (operands[2]) < 0)
6679 {
6680 operands[2] = GEN_INT (-INTVAL (operands[2]));
6681 return "add{b}\t{%2, %0|%0, %2}";
6682 }
6683 return "sub{b}\t{%2, %0|%0, %2}";
6684 }
6685 }
6686 [(set (attr "type")
6687 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6688 (const_string "incdec")
6689 (const_string "alu")))
6690 (set_attr "mode" "QI")])
6691
6692
6693 (define_insn "*addqi_5"
6694 [(set (reg 17)
6695 (compare
6696 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6697 (match_operand:QI 2 "general_operand" "qmni"))
6698 (const_int 0)))
6699 (clobber (match_scratch:QI 0 "=q"))]
6700 "ix86_match_ccmode (insn, CCGOCmode)
6701 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6702 {
6703 switch (get_attr_type (insn))
6704 {
6705 case TYPE_INCDEC:
6706 if (operands[2] == const1_rtx)
6707 return "inc{b}\t%0";
6708 else if (operands[2] == constm1_rtx
6709 || (GET_CODE (operands[2]) == CONST_INT
6710 && INTVAL (operands[2]) == 255))
6711 return "dec{b}\t%0";
6712 abort();
6713
6714 default:
6715 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6716 if (GET_CODE (operands[2]) == CONST_INT
6717 && INTVAL (operands[2]) < 0)
6718 {
6719 operands[2] = GEN_INT (-INTVAL (operands[2]));
6720 return "sub{b}\t{%2, %0|%0, %2}";
6721 }
6722 return "add{b}\t{%2, %0|%0, %2}";
6723 }
6724 }
6725 [(set (attr "type")
6726 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6727 (const_string "incdec")
6728 (const_string "alu")))
6729 (set_attr "mode" "QI")])
6730
6731
6732 (define_insn "addqi_ext_1"
6733 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6734 (const_int 8)
6735 (const_int 8))
6736 (plus:SI
6737 (zero_extract:SI
6738 (match_operand 1 "ext_register_operand" "0")
6739 (const_int 8)
6740 (const_int 8))
6741 (match_operand:QI 2 "general_operand" "Qmn")))
6742 (clobber (reg:CC 17))]
6743 "!TARGET_64BIT"
6744 {
6745 switch (get_attr_type (insn))
6746 {
6747 case TYPE_INCDEC:
6748 if (operands[2] == const1_rtx)
6749 return "inc{b}\t%h0";
6750 else if (operands[2] == constm1_rtx
6751 || (GET_CODE (operands[2]) == CONST_INT
6752 && INTVAL (operands[2]) == 255))
6753 return "dec{b}\t%h0";
6754 abort();
6755
6756 default:
6757 return "add{b}\t{%2, %h0|%h0, %2}";
6758 }
6759 }
6760 [(set (attr "type")
6761 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6762 (const_string "incdec")
6763 (const_string "alu")))
6764 (set_attr "mode" "QI")])
6765
6766 (define_insn "*addqi_ext_1_rex64"
6767 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6768 (const_int 8)
6769 (const_int 8))
6770 (plus:SI
6771 (zero_extract:SI
6772 (match_operand 1 "ext_register_operand" "0")
6773 (const_int 8)
6774 (const_int 8))
6775 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6776 (clobber (reg:CC 17))]
6777 "TARGET_64BIT"
6778 {
6779 switch (get_attr_type (insn))
6780 {
6781 case TYPE_INCDEC:
6782 if (operands[2] == const1_rtx)
6783 return "inc{b}\t%h0";
6784 else if (operands[2] == constm1_rtx
6785 || (GET_CODE (operands[2]) == CONST_INT
6786 && INTVAL (operands[2]) == 255))
6787 return "dec{b}\t%h0";
6788 abort();
6789
6790 default:
6791 return "add{b}\t{%2, %h0|%h0, %2}";
6792 }
6793 }
6794 [(set (attr "type")
6795 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6796 (const_string "incdec")
6797 (const_string "alu")))
6798 (set_attr "mode" "QI")])
6799
6800 (define_insn "*addqi_ext_2"
6801 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6802 (const_int 8)
6803 (const_int 8))
6804 (plus:SI
6805 (zero_extract:SI
6806 (match_operand 1 "ext_register_operand" "%0")
6807 (const_int 8)
6808 (const_int 8))
6809 (zero_extract:SI
6810 (match_operand 2 "ext_register_operand" "Q")
6811 (const_int 8)
6812 (const_int 8))))
6813 (clobber (reg:CC 17))]
6814 ""
6815 "add{b}\t{%h2, %h0|%h0, %h2}"
6816 [(set_attr "type" "alu")
6817 (set_attr "mode" "QI")])
6818
6819 ;; The patterns that match these are at the end of this file.
6820
6821 (define_expand "addxf3"
6822 [(set (match_operand:XF 0 "register_operand" "")
6823 (plus:XF (match_operand:XF 1 "register_operand" "")
6824 (match_operand:XF 2 "register_operand" "")))]
6825 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
6826 "")
6827
6828 (define_expand "addtf3"
6829 [(set (match_operand:TF 0 "register_operand" "")
6830 (plus:TF (match_operand:TF 1 "register_operand" "")
6831 (match_operand:TF 2 "register_operand" "")))]
6832 "TARGET_80387"
6833 "")
6834
6835 (define_expand "adddf3"
6836 [(set (match_operand:DF 0 "register_operand" "")
6837 (plus:DF (match_operand:DF 1 "register_operand" "")
6838 (match_operand:DF 2 "nonimmediate_operand" "")))]
6839 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6840 "")
6841
6842 (define_expand "addsf3"
6843 [(set (match_operand:SF 0 "register_operand" "")
6844 (plus:SF (match_operand:SF 1 "register_operand" "")
6845 (match_operand:SF 2 "nonimmediate_operand" "")))]
6846 "TARGET_80387 || TARGET_SSE_MATH"
6847 "")
6848 \f
6849 ;; Subtract instructions
6850
6851 ;; %%% splits for subsidi3
6852
6853 (define_expand "subdi3"
6854 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6855 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6856 (match_operand:DI 2 "x86_64_general_operand" "")))
6857 (clobber (reg:CC 17))])]
6858 ""
6859 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6860
6861 (define_insn "*subdi3_1"
6862 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6863 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6864 (match_operand:DI 2 "general_operand" "roiF,riF")))
6865 (clobber (reg:CC 17))]
6866 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6867 "#")
6868
6869 (define_split
6870 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6871 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6872 (match_operand:DI 2 "general_operand" "")))
6873 (clobber (reg:CC 17))]
6874 "!TARGET_64BIT && reload_completed"
6875 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6876 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6877 (parallel [(set (match_dup 3)
6878 (minus:SI (match_dup 4)
6879 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6880 (match_dup 5))))
6881 (clobber (reg:CC 17))])]
6882 "split_di (operands+0, 1, operands+0, operands+3);
6883 split_di (operands+1, 1, operands+1, operands+4);
6884 split_di (operands+2, 1, operands+2, operands+5);")
6885
6886 (define_insn "subdi3_carry_rex64"
6887 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6888 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6889 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6890 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6891 (clobber (reg:CC 17))]
6892 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6893 "sbb{q}\t{%2, %0|%0, %2}"
6894 [(set_attr "type" "alu")
6895 (set_attr "pent_pair" "pu")
6896 (set_attr "ppro_uops" "few")
6897 (set_attr "mode" "DI")])
6898
6899 (define_insn "*subdi_1_rex64"
6900 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6901 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6902 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6903 (clobber (reg:CC 17))]
6904 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6905 "sub{q}\t{%2, %0|%0, %2}"
6906 [(set_attr "type" "alu")
6907 (set_attr "mode" "DI")])
6908
6909 (define_insn "*subdi_2_rex64"
6910 [(set (reg 17)
6911 (compare
6912 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6913 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6914 (const_int 0)))
6915 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6916 (minus:DI (match_dup 1) (match_dup 2)))]
6917 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6918 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6919 "sub{q}\t{%2, %0|%0, %2}"
6920 [(set_attr "type" "alu")
6921 (set_attr "mode" "DI")])
6922
6923 (define_insn "*subdi_3_rex63"
6924 [(set (reg 17)
6925 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6926 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6927 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6928 (minus:DI (match_dup 1) (match_dup 2)))]
6929 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6930 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6931 "sub{q}\t{%2, %0|%0, %2}"
6932 [(set_attr "type" "alu")
6933 (set_attr "mode" "DI")])
6934
6935 (define_insn "subqi3_carry"
6936 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
6937 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6938 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6939 (match_operand:QI 2 "general_operand" "ri,rm"))))
6940 (clobber (reg:CC 17))]
6941 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6942 "sbb{b}\t{%2, %0|%0, %2}"
6943 [(set_attr "type" "alu")
6944 (set_attr "pent_pair" "pu")
6945 (set_attr "ppro_uops" "few")
6946 (set_attr "mode" "QI")])
6947
6948 (define_insn "subhi3_carry"
6949 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6950 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6951 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6952 (match_operand:HI 2 "general_operand" "ri,rm"))))
6953 (clobber (reg:CC 17))]
6954 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6955 "sbb{w}\t{%2, %0|%0, %2}"
6956 [(set_attr "type" "alu")
6957 (set_attr "pent_pair" "pu")
6958 (set_attr "ppro_uops" "few")
6959 (set_attr "mode" "HI")])
6960
6961 (define_insn "subsi3_carry"
6962 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6963 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6964 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6965 (match_operand:SI 2 "general_operand" "ri,rm"))))
6966 (clobber (reg:CC 17))]
6967 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6968 "sbb{l}\t{%2, %0|%0, %2}"
6969 [(set_attr "type" "alu")
6970 (set_attr "pent_pair" "pu")
6971 (set_attr "ppro_uops" "few")
6972 (set_attr "mode" "SI")])
6973
6974 (define_insn "subsi3_carry_zext"
6975 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6976 (zero_extend:DI
6977 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6978 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6979 (match_operand:SI 2 "general_operand" "ri,rm")))))
6980 (clobber (reg:CC 17))]
6981 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6982 "sbb{l}\t{%2, %k0|%k0, %2}"
6983 [(set_attr "type" "alu")
6984 (set_attr "pent_pair" "pu")
6985 (set_attr "ppro_uops" "few")
6986 (set_attr "mode" "SI")])
6987
6988 (define_expand "subsi3"
6989 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6990 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6991 (match_operand:SI 2 "general_operand" "")))
6992 (clobber (reg:CC 17))])]
6993 ""
6994 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6995
6996 (define_insn "*subsi_1"
6997 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6998 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6999 (match_operand:SI 2 "general_operand" "ri,rm")))
7000 (clobber (reg:CC 17))]
7001 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7002 "sub{l}\t{%2, %0|%0, %2}"
7003 [(set_attr "type" "alu")
7004 (set_attr "mode" "SI")])
7005
7006 (define_insn "*subsi_1_zext"
7007 [(set (match_operand:DI 0 "register_operand" "=r")
7008 (zero_extend:DI
7009 (minus:SI (match_operand:SI 1 "register_operand" "0")
7010 (match_operand:SI 2 "general_operand" "rim"))))
7011 (clobber (reg:CC 17))]
7012 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7013 "sub{l}\t{%2, %k0|%k0, %2}"
7014 [(set_attr "type" "alu")
7015 (set_attr "mode" "SI")])
7016
7017 (define_insn "*subsi_2"
7018 [(set (reg 17)
7019 (compare
7020 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7021 (match_operand:SI 2 "general_operand" "ri,rm"))
7022 (const_int 0)))
7023 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7024 (minus:SI (match_dup 1) (match_dup 2)))]
7025 "ix86_match_ccmode (insn, CCGOCmode)
7026 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7027 "sub{l}\t{%2, %0|%0, %2}"
7028 [(set_attr "type" "alu")
7029 (set_attr "mode" "SI")])
7030
7031 (define_insn "*subsi_2_zext"
7032 [(set (reg 17)
7033 (compare
7034 (minus:SI (match_operand:SI 1 "register_operand" "0")
7035 (match_operand:SI 2 "general_operand" "rim"))
7036 (const_int 0)))
7037 (set (match_operand:DI 0 "register_operand" "=r")
7038 (zero_extend:DI
7039 (minus:SI (match_dup 1)
7040 (match_dup 2))))]
7041 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7042 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7043 "sub{l}\t{%2, %k0|%k0, %2}"
7044 [(set_attr "type" "alu")
7045 (set_attr "mode" "SI")])
7046
7047 (define_insn "*subsi_3"
7048 [(set (reg 17)
7049 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7050 (match_operand:SI 2 "general_operand" "ri,rm")))
7051 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7052 (minus:SI (match_dup 1) (match_dup 2)))]
7053 "ix86_match_ccmode (insn, CCmode)
7054 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7055 "sub{l}\t{%2, %0|%0, %2}"
7056 [(set_attr "type" "alu")
7057 (set_attr "mode" "SI")])
7058
7059 (define_insn "*subsi_3_zext"
7060 [(set (reg 17)
7061 (compare (match_operand:SI 1 "register_operand" "0")
7062 (match_operand:SI 2 "general_operand" "rim")))
7063 (set (match_operand:DI 0 "register_operand" "=r")
7064 (zero_extend:DI
7065 (minus:SI (match_dup 1)
7066 (match_dup 2))))]
7067 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7068 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7069 "sub{q}\t{%2, %0|%0, %2}"
7070 [(set_attr "type" "alu")
7071 (set_attr "mode" "DI")])
7072
7073 (define_expand "subhi3"
7074 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7075 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7076 (match_operand:HI 2 "general_operand" "")))
7077 (clobber (reg:CC 17))])]
7078 "TARGET_HIMODE_MATH"
7079 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7080
7081 (define_insn "*subhi_1"
7082 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7083 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7084 (match_operand:HI 2 "general_operand" "ri,rm")))
7085 (clobber (reg:CC 17))]
7086 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7087 "sub{w}\t{%2, %0|%0, %2}"
7088 [(set_attr "type" "alu")
7089 (set_attr "mode" "HI")])
7090
7091 (define_insn "*subhi_2"
7092 [(set (reg 17)
7093 (compare
7094 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7095 (match_operand:HI 2 "general_operand" "ri,rm"))
7096 (const_int 0)))
7097 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7098 (minus:HI (match_dup 1) (match_dup 2)))]
7099 "ix86_match_ccmode (insn, CCGOCmode)
7100 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7101 "sub{w}\t{%2, %0|%0, %2}"
7102 [(set_attr "type" "alu")
7103 (set_attr "mode" "HI")])
7104
7105 (define_insn "*subhi_3"
7106 [(set (reg 17)
7107 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7108 (match_operand:HI 2 "general_operand" "ri,rm")))
7109 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7110 (minus:HI (match_dup 1) (match_dup 2)))]
7111 "ix86_match_ccmode (insn, CCmode)
7112 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7113 "sub{w}\t{%2, %0|%0, %2}"
7114 [(set_attr "type" "alu")
7115 (set_attr "mode" "HI")])
7116
7117 (define_expand "subqi3"
7118 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7119 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7120 (match_operand:QI 2 "general_operand" "")))
7121 (clobber (reg:CC 17))])]
7122 "TARGET_QIMODE_MATH"
7123 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7124
7125 (define_insn "*subqi_1"
7126 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7127 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7128 (match_operand:QI 2 "general_operand" "qn,qmn")))
7129 (clobber (reg:CC 17))]
7130 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7131 "sub{b}\t{%2, %0|%0, %2}"
7132 [(set_attr "type" "alu")
7133 (set_attr "mode" "QI")])
7134
7135 (define_insn "*subqi_1_slp"
7136 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7137 (minus:QI (match_dup 0)
7138 (match_operand:QI 1 "general_operand" "qn,qmn")))
7139 (clobber (reg:CC 17))]
7140 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7141 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7142 "sub{b}\t{%1, %0|%0, %1}"
7143 [(set_attr "type" "alu1")
7144 (set_attr "mode" "QI")])
7145
7146 (define_insn "*subqi_2"
7147 [(set (reg 17)
7148 (compare
7149 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7150 (match_operand:QI 2 "general_operand" "qi,qm"))
7151 (const_int 0)))
7152 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7153 (minus:HI (match_dup 1) (match_dup 2)))]
7154 "ix86_match_ccmode (insn, CCGOCmode)
7155 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7156 "sub{b}\t{%2, %0|%0, %2}"
7157 [(set_attr "type" "alu")
7158 (set_attr "mode" "QI")])
7159
7160 (define_insn "*subqi_3"
7161 [(set (reg 17)
7162 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7163 (match_operand:QI 2 "general_operand" "qi,qm")))
7164 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7165 (minus:HI (match_dup 1) (match_dup 2)))]
7166 "ix86_match_ccmode (insn, CCmode)
7167 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7168 "sub{b}\t{%2, %0|%0, %2}"
7169 [(set_attr "type" "alu")
7170 (set_attr "mode" "QI")])
7171
7172 ;; The patterns that match these are at the end of this file.
7173
7174 (define_expand "subxf3"
7175 [(set (match_operand:XF 0 "register_operand" "")
7176 (minus:XF (match_operand:XF 1 "register_operand" "")
7177 (match_operand:XF 2 "register_operand" "")))]
7178 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7179 "")
7180
7181 (define_expand "subtf3"
7182 [(set (match_operand:TF 0 "register_operand" "")
7183 (minus:TF (match_operand:TF 1 "register_operand" "")
7184 (match_operand:TF 2 "register_operand" "")))]
7185 "TARGET_80387"
7186 "")
7187
7188 (define_expand "subdf3"
7189 [(set (match_operand:DF 0 "register_operand" "")
7190 (minus:DF (match_operand:DF 1 "register_operand" "")
7191 (match_operand:DF 2 "nonimmediate_operand" "")))]
7192 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7193 "")
7194
7195 (define_expand "subsf3"
7196 [(set (match_operand:SF 0 "register_operand" "")
7197 (minus:SF (match_operand:SF 1 "register_operand" "")
7198 (match_operand:SF 2 "nonimmediate_operand" "")))]
7199 "TARGET_80387 || TARGET_SSE_MATH"
7200 "")
7201 \f
7202 ;; Multiply instructions
7203
7204 (define_expand "muldi3"
7205 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7206 (mult:DI (match_operand:DI 1 "register_operand" "")
7207 (match_operand:DI 2 "x86_64_general_operand" "")))
7208 (clobber (reg:CC 17))])]
7209 "TARGET_64BIT"
7210 "")
7211
7212 (define_insn "*muldi3_1_rex64"
7213 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7214 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7215 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7216 (clobber (reg:CC 17))]
7217 "TARGET_64BIT
7218 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7219 "@
7220 imul{q}\t{%2, %1, %0|%0, %1, %2}
7221 imul{q}\t{%2, %1, %0|%0, %1, %2}
7222 imul{q}\t{%2, %0|%0, %2}"
7223 [(set_attr "type" "imul")
7224 (set_attr "prefix_0f" "0,0,1")
7225 (set (attr "athlon_decode")
7226 (cond [(eq_attr "cpu" "athlon")
7227 (const_string "vector")
7228 (eq_attr "alternative" "1")
7229 (const_string "vector")
7230 (and (eq_attr "alternative" "2")
7231 (match_operand 1 "memory_operand" ""))
7232 (const_string "vector")]
7233 (const_string "direct")))
7234 (set_attr "mode" "DI")])
7235
7236 (define_expand "mulsi3"
7237 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7238 (mult:SI (match_operand:SI 1 "register_operand" "")
7239 (match_operand:SI 2 "general_operand" "")))
7240 (clobber (reg:CC 17))])]
7241 ""
7242 "")
7243
7244 (define_insn "*mulsi3_1"
7245 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7246 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7247 (match_operand:SI 2 "general_operand" "K,i,mr")))
7248 (clobber (reg:CC 17))]
7249 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7250 "@
7251 imul{l}\t{%2, %1, %0|%0, %1, %2}
7252 imul{l}\t{%2, %1, %0|%0, %1, %2}
7253 imul{l}\t{%2, %0|%0, %2}"
7254 [(set_attr "type" "imul")
7255 (set_attr "prefix_0f" "0,0,1")
7256 (set (attr "athlon_decode")
7257 (cond [(eq_attr "cpu" "athlon")
7258 (const_string "vector")
7259 (eq_attr "alternative" "1")
7260 (const_string "vector")
7261 (and (eq_attr "alternative" "2")
7262 (match_operand 1 "memory_operand" ""))
7263 (const_string "vector")]
7264 (const_string "direct")))
7265 (set_attr "mode" "SI")])
7266
7267 (define_insn "*mulsi3_1_zext"
7268 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7269 (zero_extend:DI
7270 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7271 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7272 (clobber (reg:CC 17))]
7273 "TARGET_64BIT
7274 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7275 "@
7276 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7277 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7278 imul{l}\t{%2, %k0|%k0, %2}"
7279 [(set_attr "type" "imul")
7280 (set_attr "prefix_0f" "0,0,1")
7281 (set (attr "athlon_decode")
7282 (cond [(eq_attr "cpu" "athlon")
7283 (const_string "vector")
7284 (eq_attr "alternative" "1")
7285 (const_string "vector")
7286 (and (eq_attr "alternative" "2")
7287 (match_operand 1 "memory_operand" ""))
7288 (const_string "vector")]
7289 (const_string "direct")))
7290 (set_attr "mode" "SI")])
7291
7292 (define_expand "mulhi3"
7293 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7294 (mult:HI (match_operand:HI 1 "register_operand" "")
7295 (match_operand:HI 2 "general_operand" "")))
7296 (clobber (reg:CC 17))])]
7297 "TARGET_HIMODE_MATH"
7298 "")
7299
7300 (define_insn "*mulhi3_1"
7301 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7302 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7303 (match_operand:HI 2 "general_operand" "K,i,mr")))
7304 (clobber (reg:CC 17))]
7305 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7306 "@
7307 imul{w}\t{%2, %1, %0|%0, %1, %2}
7308 imul{w}\t{%2, %1, %0|%0, %1, %2}
7309 imul{w}\t{%2, %0|%0, %2}"
7310 [(set_attr "type" "imul")
7311 (set_attr "prefix_0f" "0,0,1")
7312 (set (attr "athlon_decode")
7313 (cond [(eq_attr "cpu" "athlon")
7314 (const_string "vector")
7315 (eq_attr "alternative" "1,2")
7316 (const_string "vector")]
7317 (const_string "direct")))
7318 (set_attr "mode" "HI")])
7319
7320 (define_expand "mulqi3"
7321 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7322 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7323 (match_operand:QI 2 "register_operand" "")))
7324 (clobber (reg:CC 17))])]
7325 "TARGET_QIMODE_MATH"
7326 "")
7327
7328 (define_insn "*mulqi3_1"
7329 [(set (match_operand:QI 0 "register_operand" "=a")
7330 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7331 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7332 (clobber (reg:CC 17))]
7333 "TARGET_QIMODE_MATH
7334 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7335 "mul{b}\t%2"
7336 [(set_attr "type" "imul")
7337 (set_attr "length_immediate" "0")
7338 (set (attr "athlon_decode")
7339 (if_then_else (eq_attr "cpu" "athlon")
7340 (const_string "vector")
7341 (const_string "direct")))
7342 (set_attr "mode" "QI")])
7343
7344 (define_expand "umulqihi3"
7345 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7346 (mult:HI (zero_extend:HI
7347 (match_operand:QI 1 "nonimmediate_operand" ""))
7348 (zero_extend:HI
7349 (match_operand:QI 2 "register_operand" ""))))
7350 (clobber (reg:CC 17))])]
7351 "TARGET_QIMODE_MATH"
7352 "")
7353
7354 (define_insn "*umulqihi3_1"
7355 [(set (match_operand:HI 0 "register_operand" "=a")
7356 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7357 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7358 (clobber (reg:CC 17))]
7359 "TARGET_QIMODE_MATH
7360 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7361 "mul{b}\t%2"
7362 [(set_attr "type" "imul")
7363 (set_attr "length_immediate" "0")
7364 (set (attr "athlon_decode")
7365 (if_then_else (eq_attr "cpu" "athlon")
7366 (const_string "vector")
7367 (const_string "direct")))
7368 (set_attr "mode" "QI")])
7369
7370 (define_expand "mulqihi3"
7371 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7372 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7373 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7374 (clobber (reg:CC 17))])]
7375 "TARGET_QIMODE_MATH"
7376 "")
7377
7378 (define_insn "*mulqihi3_insn"
7379 [(set (match_operand:HI 0 "register_operand" "=a")
7380 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7381 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7382 (clobber (reg:CC 17))]
7383 "TARGET_QIMODE_MATH
7384 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7385 "imul{b}\t%2"
7386 [(set_attr "type" "imul")
7387 (set_attr "length_immediate" "0")
7388 (set (attr "athlon_decode")
7389 (if_then_else (eq_attr "cpu" "athlon")
7390 (const_string "vector")
7391 (const_string "direct")))
7392 (set_attr "mode" "QI")])
7393
7394 (define_expand "umulditi3"
7395 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7396 (mult:TI (zero_extend:TI
7397 (match_operand:DI 1 "nonimmediate_operand" ""))
7398 (zero_extend:TI
7399 (match_operand:DI 2 "register_operand" ""))))
7400 (clobber (reg:CC 17))])]
7401 "TARGET_64BIT"
7402 "")
7403
7404 (define_insn "*umulditi3_insn"
7405 [(set (match_operand:TI 0 "register_operand" "=A")
7406 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7407 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7408 (clobber (reg:CC 17))]
7409 "TARGET_64BIT
7410 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7411 "mul{q}\t%2"
7412 [(set_attr "type" "imul")
7413 (set_attr "ppro_uops" "few")
7414 (set_attr "length_immediate" "0")
7415 (set (attr "athlon_decode")
7416 (if_then_else (eq_attr "cpu" "athlon")
7417 (const_string "vector")
7418 (const_string "double")))
7419 (set_attr "mode" "DI")])
7420
7421 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7422 (define_expand "umulsidi3"
7423 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7424 (mult:DI (zero_extend:DI
7425 (match_operand:SI 1 "nonimmediate_operand" ""))
7426 (zero_extend:DI
7427 (match_operand:SI 2 "register_operand" ""))))
7428 (clobber (reg:CC 17))])]
7429 "!TARGET_64BIT"
7430 "")
7431
7432 (define_insn "*umulsidi3_insn"
7433 [(set (match_operand:DI 0 "register_operand" "=A")
7434 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7435 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7436 (clobber (reg:CC 17))]
7437 "!TARGET_64BIT
7438 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7439 "mul{l}\t%2"
7440 [(set_attr "type" "imul")
7441 (set_attr "ppro_uops" "few")
7442 (set_attr "length_immediate" "0")
7443 (set (attr "athlon_decode")
7444 (if_then_else (eq_attr "cpu" "athlon")
7445 (const_string "vector")
7446 (const_string "double")))
7447 (set_attr "mode" "SI")])
7448
7449 (define_expand "mulditi3"
7450 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7451 (mult:TI (sign_extend:TI
7452 (match_operand:DI 1 "nonimmediate_operand" ""))
7453 (sign_extend:TI
7454 (match_operand:DI 2 "register_operand" ""))))
7455 (clobber (reg:CC 17))])]
7456 "TARGET_64BIT"
7457 "")
7458
7459 (define_insn "*mulditi3_insn"
7460 [(set (match_operand:TI 0 "register_operand" "=A")
7461 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7462 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7463 (clobber (reg:CC 17))]
7464 "TARGET_64BIT
7465 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7466 "imul{q}\t%2"
7467 [(set_attr "type" "imul")
7468 (set_attr "length_immediate" "0")
7469 (set (attr "athlon_decode")
7470 (if_then_else (eq_attr "cpu" "athlon")
7471 (const_string "vector")
7472 (const_string "double")))
7473 (set_attr "mode" "DI")])
7474
7475 (define_expand "mulsidi3"
7476 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7477 (mult:DI (sign_extend:DI
7478 (match_operand:SI 1 "nonimmediate_operand" ""))
7479 (sign_extend:DI
7480 (match_operand:SI 2 "register_operand" ""))))
7481 (clobber (reg:CC 17))])]
7482 "!TARGET_64BIT"
7483 "")
7484
7485 (define_insn "*mulsidi3_insn"
7486 [(set (match_operand:DI 0 "register_operand" "=A")
7487 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7488 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7489 (clobber (reg:CC 17))]
7490 "!TARGET_64BIT
7491 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7492 "imul{l}\t%2"
7493 [(set_attr "type" "imul")
7494 (set_attr "length_immediate" "0")
7495 (set (attr "athlon_decode")
7496 (if_then_else (eq_attr "cpu" "athlon")
7497 (const_string "vector")
7498 (const_string "double")))
7499 (set_attr "mode" "SI")])
7500
7501 (define_expand "umuldi3_highpart"
7502 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7503 (truncate:DI
7504 (lshiftrt:TI
7505 (mult:TI (zero_extend:TI
7506 (match_operand:DI 1 "nonimmediate_operand" ""))
7507 (zero_extend:TI
7508 (match_operand:DI 2 "register_operand" "")))
7509 (const_int 64))))
7510 (clobber (match_scratch:DI 3 ""))
7511 (clobber (reg:CC 17))])]
7512 "TARGET_64BIT"
7513 "")
7514
7515 (define_insn "*umuldi3_highpart_rex64"
7516 [(set (match_operand:DI 0 "register_operand" "=d")
7517 (truncate:DI
7518 (lshiftrt:TI
7519 (mult:TI (zero_extend:TI
7520 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7521 (zero_extend:TI
7522 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7523 (const_int 64))))
7524 (clobber (match_scratch:DI 3 "=1"))
7525 (clobber (reg:CC 17))]
7526 "TARGET_64BIT
7527 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7528 "mul{q}\t%2"
7529 [(set_attr "type" "imul")
7530 (set_attr "ppro_uops" "few")
7531 (set_attr "length_immediate" "0")
7532 (set (attr "athlon_decode")
7533 (if_then_else (eq_attr "cpu" "athlon")
7534 (const_string "vector")
7535 (const_string "double")))
7536 (set_attr "mode" "DI")])
7537
7538 (define_expand "umulsi3_highpart"
7539 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7540 (truncate:SI
7541 (lshiftrt:DI
7542 (mult:DI (zero_extend:DI
7543 (match_operand:SI 1 "nonimmediate_operand" ""))
7544 (zero_extend:DI
7545 (match_operand:SI 2 "register_operand" "")))
7546 (const_int 32))))
7547 (clobber (match_scratch:SI 3 ""))
7548 (clobber (reg:CC 17))])]
7549 ""
7550 "")
7551
7552 (define_insn "*umulsi3_highpart_insn"
7553 [(set (match_operand:SI 0 "register_operand" "=d")
7554 (truncate:SI
7555 (lshiftrt:DI
7556 (mult:DI (zero_extend:DI
7557 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7558 (zero_extend:DI
7559 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7560 (const_int 32))))
7561 (clobber (match_scratch:SI 3 "=1"))
7562 (clobber (reg:CC 17))]
7563 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7564 "mul{l}\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" "SI")])
7573
7574 (define_insn "*umulsi3_highpart_zext"
7575 [(set (match_operand:DI 0 "register_operand" "=d")
7576 (zero_extend:DI (truncate:SI
7577 (lshiftrt:DI
7578 (mult:DI (zero_extend:DI
7579 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7580 (zero_extend:DI
7581 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7582 (const_int 32)))))
7583 (clobber (match_scratch:SI 3 "=1"))
7584 (clobber (reg:CC 17))]
7585 "TARGET_64BIT
7586 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7587 "mul{l}\t%2"
7588 [(set_attr "type" "imul")
7589 (set_attr "ppro_uops" "few")
7590 (set_attr "length_immediate" "0")
7591 (set (attr "athlon_decode")
7592 (if_then_else (eq_attr "cpu" "athlon")
7593 (const_string "vector")
7594 (const_string "double")))
7595 (set_attr "mode" "SI")])
7596
7597 (define_expand "smuldi3_highpart"
7598 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7599 (truncate:DI
7600 (lshiftrt:TI
7601 (mult:TI (sign_extend:TI
7602 (match_operand:DI 1 "nonimmediate_operand" ""))
7603 (sign_extend:TI
7604 (match_operand:DI 2 "register_operand" "")))
7605 (const_int 64))))
7606 (clobber (match_scratch:DI 3 ""))
7607 (clobber (reg:CC 17))])]
7608 "TARGET_64BIT"
7609 "")
7610
7611 (define_insn "*smuldi3_highpart_rex64"
7612 [(set (match_operand:DI 0 "register_operand" "=d")
7613 (truncate:DI
7614 (lshiftrt:TI
7615 (mult:TI (sign_extend:TI
7616 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7617 (sign_extend:TI
7618 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7619 (const_int 64))))
7620 (clobber (match_scratch:DI 3 "=1"))
7621 (clobber (reg:CC 17))]
7622 "TARGET_64BIT
7623 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7624 "imul{q}\t%2"
7625 [(set_attr "type" "imul")
7626 (set_attr "ppro_uops" "few")
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" "DI")])
7632
7633 (define_expand "smulsi3_highpart"
7634 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7635 (truncate:SI
7636 (lshiftrt:DI
7637 (mult:DI (sign_extend:DI
7638 (match_operand:SI 1 "nonimmediate_operand" ""))
7639 (sign_extend:DI
7640 (match_operand:SI 2 "register_operand" "")))
7641 (const_int 32))))
7642 (clobber (match_scratch:SI 3 ""))
7643 (clobber (reg:CC 17))])]
7644 ""
7645 "")
7646
7647 (define_insn "*smulsi3_highpart_insn"
7648 [(set (match_operand:SI 0 "register_operand" "=d")
7649 (truncate:SI
7650 (lshiftrt:DI
7651 (mult:DI (sign_extend:DI
7652 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7653 (sign_extend:DI
7654 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7655 (const_int 32))))
7656 (clobber (match_scratch:SI 3 "=1"))
7657 (clobber (reg:CC 17))]
7658 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7659 "imul{l}\t%2"
7660 [(set_attr "type" "imul")
7661 (set_attr "ppro_uops" "few")
7662 (set (attr "athlon_decode")
7663 (if_then_else (eq_attr "cpu" "athlon")
7664 (const_string "vector")
7665 (const_string "double")))
7666 (set_attr "mode" "SI")])
7667
7668 (define_insn "*smulsi3_highpart_zext"
7669 [(set (match_operand:DI 0 "register_operand" "=d")
7670 (zero_extend:DI (truncate:SI
7671 (lshiftrt:DI
7672 (mult:DI (sign_extend:DI
7673 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7674 (sign_extend:DI
7675 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7676 (const_int 32)))))
7677 (clobber (match_scratch:SI 3 "=1"))
7678 (clobber (reg:CC 17))]
7679 "TARGET_64BIT
7680 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7681 "imul{l}\t%2"
7682 [(set_attr "type" "imul")
7683 (set_attr "ppro_uops" "few")
7684 (set (attr "athlon_decode")
7685 (if_then_else (eq_attr "cpu" "athlon")
7686 (const_string "vector")
7687 (const_string "double")))
7688 (set_attr "mode" "SI")])
7689
7690 ;; The patterns that match these are at the end of this file.
7691
7692 (define_expand "mulxf3"
7693 [(set (match_operand:XF 0 "register_operand" "")
7694 (mult:XF (match_operand:XF 1 "register_operand" "")
7695 (match_operand:XF 2 "register_operand" "")))]
7696 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7697 "")
7698
7699 (define_expand "multf3"
7700 [(set (match_operand:TF 0 "register_operand" "")
7701 (mult:TF (match_operand:TF 1 "register_operand" "")
7702 (match_operand:TF 2 "register_operand" "")))]
7703 "TARGET_80387"
7704 "")
7705
7706 (define_expand "muldf3"
7707 [(set (match_operand:DF 0 "register_operand" "")
7708 (mult:DF (match_operand:DF 1 "register_operand" "")
7709 (match_operand:DF 2 "nonimmediate_operand" "")))]
7710 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7711 "")
7712
7713 (define_expand "mulsf3"
7714 [(set (match_operand:SF 0 "register_operand" "")
7715 (mult:SF (match_operand:SF 1 "register_operand" "")
7716 (match_operand:SF 2 "nonimmediate_operand" "")))]
7717 "TARGET_80387 || TARGET_SSE_MATH"
7718 "")
7719 \f
7720 ;; Divide instructions
7721
7722 (define_insn "divqi3"
7723 [(set (match_operand:QI 0 "register_operand" "=a")
7724 (div:QI (match_operand:HI 1 "register_operand" "0")
7725 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7726 (clobber (reg:CC 17))]
7727 "TARGET_QIMODE_MATH"
7728 "idiv{b}\t%2"
7729 [(set_attr "type" "idiv")
7730 (set_attr "mode" "QI")
7731 (set_attr "ppro_uops" "few")])
7732
7733 (define_insn "udivqi3"
7734 [(set (match_operand:QI 0 "register_operand" "=a")
7735 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7736 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7737 (clobber (reg:CC 17))]
7738 "TARGET_QIMODE_MATH"
7739 "div{b}\t%2"
7740 [(set_attr "type" "idiv")
7741 (set_attr "mode" "QI")
7742 (set_attr "ppro_uops" "few")])
7743
7744 ;; The patterns that match these are at the end of this file.
7745
7746 (define_expand "divxf3"
7747 [(set (match_operand:XF 0 "register_operand" "")
7748 (div:XF (match_operand:XF 1 "register_operand" "")
7749 (match_operand:XF 2 "register_operand" "")))]
7750 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7751 "")
7752
7753 (define_expand "divtf3"
7754 [(set (match_operand:TF 0 "register_operand" "")
7755 (div:TF (match_operand:TF 1 "register_operand" "")
7756 (match_operand:TF 2 "register_operand" "")))]
7757 "TARGET_80387"
7758 "")
7759
7760 (define_expand "divdf3"
7761 [(set (match_operand:DF 0 "register_operand" "")
7762 (div:DF (match_operand:DF 1 "register_operand" "")
7763 (match_operand:DF 2 "nonimmediate_operand" "")))]
7764 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7765 "")
7766
7767 (define_expand "divsf3"
7768 [(set (match_operand:SF 0 "register_operand" "")
7769 (div:SF (match_operand:SF 1 "register_operand" "")
7770 (match_operand:SF 2 "nonimmediate_operand" "")))]
7771 "TARGET_80387 || TARGET_SSE_MATH"
7772 "")
7773 \f
7774 ;; Remainder instructions.
7775
7776 (define_expand "divmoddi4"
7777 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7778 (div:DI (match_operand:DI 1 "register_operand" "")
7779 (match_operand:DI 2 "nonimmediate_operand" "")))
7780 (set (match_operand:DI 3 "register_operand" "")
7781 (mod:DI (match_dup 1) (match_dup 2)))
7782 (clobber (reg:CC 17))])]
7783 "TARGET_64BIT"
7784 "")
7785
7786 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7787 ;; Penalize eax case slightly because it results in worse scheduling
7788 ;; of code.
7789 (define_insn "*divmoddi4_nocltd_rex64"
7790 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7791 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7792 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7793 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7794 (mod:DI (match_dup 2) (match_dup 3)))
7795 (clobber (reg:CC 17))]
7796 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7797 "#"
7798 [(set_attr "type" "multi")])
7799
7800 (define_insn "*divmoddi4_cltd_rex64"
7801 [(set (match_operand:DI 0 "register_operand" "=a")
7802 (div:DI (match_operand:DI 2 "register_operand" "a")
7803 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7804 (set (match_operand:DI 1 "register_operand" "=&d")
7805 (mod:DI (match_dup 2) (match_dup 3)))
7806 (clobber (reg:CC 17))]
7807 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7808 "#"
7809 [(set_attr "type" "multi")])
7810
7811 (define_insn "*divmoddi_noext_rex64"
7812 [(set (match_operand:DI 0 "register_operand" "=a")
7813 (div:DI (match_operand:DI 1 "register_operand" "0")
7814 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7815 (set (match_operand:DI 3 "register_operand" "=d")
7816 (mod:DI (match_dup 1) (match_dup 2)))
7817 (use (match_operand:DI 4 "register_operand" "3"))
7818 (clobber (reg:CC 17))]
7819 "TARGET_64BIT"
7820 "idiv{q}\t%2"
7821 [(set_attr "type" "idiv")
7822 (set_attr "mode" "DI")
7823 (set_attr "ppro_uops" "few")])
7824
7825 (define_split
7826 [(set (match_operand:DI 0 "register_operand" "")
7827 (div:DI (match_operand:DI 1 "register_operand" "")
7828 (match_operand:DI 2 "nonimmediate_operand" "")))
7829 (set (match_operand:DI 3 "register_operand" "")
7830 (mod:DI (match_dup 1) (match_dup 2)))
7831 (clobber (reg:CC 17))]
7832 "TARGET_64BIT && reload_completed"
7833 [(parallel [(set (match_dup 3)
7834 (ashiftrt:DI (match_dup 4) (const_int 63)))
7835 (clobber (reg:CC 17))])
7836 (parallel [(set (match_dup 0)
7837 (div:DI (reg:DI 0) (match_dup 2)))
7838 (set (match_dup 3)
7839 (mod:DI (reg:DI 0) (match_dup 2)))
7840 (use (match_dup 3))
7841 (clobber (reg:CC 17))])]
7842 {
7843 /* Avoid use of cltd in favor of a mov+shift. */
7844 if (!TARGET_USE_CLTD && !optimize_size)
7845 {
7846 if (true_regnum (operands[1]))
7847 emit_move_insn (operands[0], operands[1]);
7848 else
7849 emit_move_insn (operands[3], operands[1]);
7850 operands[4] = operands[3];
7851 }
7852 else
7853 {
7854 if (true_regnum (operands[1]))
7855 abort();
7856 operands[4] = operands[1];
7857 }
7858 })
7859
7860
7861 (define_expand "divmodsi4"
7862 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7863 (div:SI (match_operand:SI 1 "register_operand" "")
7864 (match_operand:SI 2 "nonimmediate_operand" "")))
7865 (set (match_operand:SI 3 "register_operand" "")
7866 (mod:SI (match_dup 1) (match_dup 2)))
7867 (clobber (reg:CC 17))])]
7868 ""
7869 "")
7870
7871 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7872 ;; Penalize eax case slightly because it results in worse scheduling
7873 ;; of code.
7874 (define_insn "*divmodsi4_nocltd"
7875 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7876 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7877 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7878 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7879 (mod:SI (match_dup 2) (match_dup 3)))
7880 (clobber (reg:CC 17))]
7881 "!optimize_size && !TARGET_USE_CLTD"
7882 "#"
7883 [(set_attr "type" "multi")])
7884
7885 (define_insn "*divmodsi4_cltd"
7886 [(set (match_operand:SI 0 "register_operand" "=a")
7887 (div:SI (match_operand:SI 2 "register_operand" "a")
7888 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7889 (set (match_operand:SI 1 "register_operand" "=&d")
7890 (mod:SI (match_dup 2) (match_dup 3)))
7891 (clobber (reg:CC 17))]
7892 "optimize_size || TARGET_USE_CLTD"
7893 "#"
7894 [(set_attr "type" "multi")])
7895
7896 (define_insn "*divmodsi_noext"
7897 [(set (match_operand:SI 0 "register_operand" "=a")
7898 (div:SI (match_operand:SI 1 "register_operand" "0")
7899 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7900 (set (match_operand:SI 3 "register_operand" "=d")
7901 (mod:SI (match_dup 1) (match_dup 2)))
7902 (use (match_operand:SI 4 "register_operand" "3"))
7903 (clobber (reg:CC 17))]
7904 ""
7905 "idiv{l}\t%2"
7906 [(set_attr "type" "idiv")
7907 (set_attr "mode" "SI")
7908 (set_attr "ppro_uops" "few")])
7909
7910 (define_split
7911 [(set (match_operand:SI 0 "register_operand" "")
7912 (div:SI (match_operand:SI 1 "register_operand" "")
7913 (match_operand:SI 2 "nonimmediate_operand" "")))
7914 (set (match_operand:SI 3 "register_operand" "")
7915 (mod:SI (match_dup 1) (match_dup 2)))
7916 (clobber (reg:CC 17))]
7917 "reload_completed"
7918 [(parallel [(set (match_dup 3)
7919 (ashiftrt:SI (match_dup 4) (const_int 31)))
7920 (clobber (reg:CC 17))])
7921 (parallel [(set (match_dup 0)
7922 (div:SI (reg:SI 0) (match_dup 2)))
7923 (set (match_dup 3)
7924 (mod:SI (reg:SI 0) (match_dup 2)))
7925 (use (match_dup 3))
7926 (clobber (reg:CC 17))])]
7927 {
7928 /* Avoid use of cltd in favor of a mov+shift. */
7929 if (!TARGET_USE_CLTD && !optimize_size)
7930 {
7931 if (true_regnum (operands[1]))
7932 emit_move_insn (operands[0], operands[1]);
7933 else
7934 emit_move_insn (operands[3], operands[1]);
7935 operands[4] = operands[3];
7936 }
7937 else
7938 {
7939 if (true_regnum (operands[1]))
7940 abort();
7941 operands[4] = operands[1];
7942 }
7943 })
7944 ;; %%% Split me.
7945 (define_insn "divmodhi4"
7946 [(set (match_operand:HI 0 "register_operand" "=a")
7947 (div:HI (match_operand:HI 1 "register_operand" "0")
7948 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7949 (set (match_operand:HI 3 "register_operand" "=&d")
7950 (mod:HI (match_dup 1) (match_dup 2)))
7951 (clobber (reg:CC 17))]
7952 "TARGET_HIMODE_MATH"
7953 "cwtd\;idiv{w}\t%2"
7954 [(set_attr "type" "multi")
7955 (set_attr "length_immediate" "0")
7956 (set_attr "mode" "SI")])
7957
7958 (define_insn "udivmoddi4"
7959 [(set (match_operand:DI 0 "register_operand" "=a")
7960 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7961 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7962 (set (match_operand:DI 3 "register_operand" "=&d")
7963 (umod:DI (match_dup 1) (match_dup 2)))
7964 (clobber (reg:CC 17))]
7965 "TARGET_64BIT"
7966 "xor{q}\t%3, %3\;div{q}\t%2"
7967 [(set_attr "type" "multi")
7968 (set_attr "length_immediate" "0")
7969 (set_attr "mode" "DI")])
7970
7971 (define_insn "*udivmoddi4_noext"
7972 [(set (match_operand:DI 0 "register_operand" "=a")
7973 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7974 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7975 (set (match_operand:DI 3 "register_operand" "=d")
7976 (umod:DI (match_dup 1) (match_dup 2)))
7977 (use (match_dup 3))
7978 (clobber (reg:CC 17))]
7979 "TARGET_64BIT"
7980 "div{q}\t%2"
7981 [(set_attr "type" "idiv")
7982 (set_attr "ppro_uops" "few")
7983 (set_attr "mode" "DI")])
7984
7985 (define_split
7986 [(set (match_operand:DI 0 "register_operand" "")
7987 (udiv:DI (match_operand:DI 1 "register_operand" "")
7988 (match_operand:DI 2 "nonimmediate_operand" "")))
7989 (set (match_operand:DI 3 "register_operand" "")
7990 (umod:DI (match_dup 1) (match_dup 2)))
7991 (clobber (reg:CC 17))]
7992 "TARGET_64BIT && reload_completed"
7993 [(set (match_dup 3) (const_int 0))
7994 (parallel [(set (match_dup 0)
7995 (udiv:DI (match_dup 1) (match_dup 2)))
7996 (set (match_dup 3)
7997 (umod:DI (match_dup 1) (match_dup 2)))
7998 (use (match_dup 3))
7999 (clobber (reg:CC 17))])]
8000 "")
8001
8002 (define_insn "udivmodsi4"
8003 [(set (match_operand:SI 0 "register_operand" "=a")
8004 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8005 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8006 (set (match_operand:SI 3 "register_operand" "=&d")
8007 (umod:SI (match_dup 1) (match_dup 2)))
8008 (clobber (reg:CC 17))]
8009 ""
8010 "xor{l}\t%3, %3\;div{l}\t%2"
8011 [(set_attr "type" "multi")
8012 (set_attr "length_immediate" "0")
8013 (set_attr "mode" "SI")])
8014
8015 (define_insn "*udivmodsi4_noext"
8016 [(set (match_operand:SI 0 "register_operand" "=a")
8017 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8018 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8019 (set (match_operand:SI 3 "register_operand" "=d")
8020 (umod:SI (match_dup 1) (match_dup 2)))
8021 (use (match_dup 3))
8022 (clobber (reg:CC 17))]
8023 ""
8024 "div{l}\t%2"
8025 [(set_attr "type" "idiv")
8026 (set_attr "ppro_uops" "few")
8027 (set_attr "mode" "SI")])
8028
8029 (define_split
8030 [(set (match_operand:SI 0 "register_operand" "")
8031 (udiv:SI (match_operand:SI 1 "register_operand" "")
8032 (match_operand:SI 2 "nonimmediate_operand" "")))
8033 (set (match_operand:SI 3 "register_operand" "")
8034 (umod:SI (match_dup 1) (match_dup 2)))
8035 (clobber (reg:CC 17))]
8036 "reload_completed"
8037 [(set (match_dup 3) (const_int 0))
8038 (parallel [(set (match_dup 0)
8039 (udiv:SI (match_dup 1) (match_dup 2)))
8040 (set (match_dup 3)
8041 (umod:SI (match_dup 1) (match_dup 2)))
8042 (use (match_dup 3))
8043 (clobber (reg:CC 17))])]
8044 "")
8045
8046 (define_expand "udivmodhi4"
8047 [(set (match_dup 4) (const_int 0))
8048 (parallel [(set (match_operand:HI 0 "register_operand" "")
8049 (udiv:HI (match_operand:HI 1 "register_operand" "")
8050 (match_operand:HI 2 "nonimmediate_operand" "")))
8051 (set (match_operand:HI 3 "register_operand" "")
8052 (umod:HI (match_dup 1) (match_dup 2)))
8053 (use (match_dup 4))
8054 (clobber (reg:CC 17))])]
8055 "TARGET_HIMODE_MATH"
8056 "operands[4] = gen_reg_rtx (HImode);")
8057
8058 (define_insn "*udivmodhi_noext"
8059 [(set (match_operand:HI 0 "register_operand" "=a")
8060 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8061 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8062 (set (match_operand:HI 3 "register_operand" "=d")
8063 (umod:HI (match_dup 1) (match_dup 2)))
8064 (use (match_operand:HI 4 "register_operand" "3"))
8065 (clobber (reg:CC 17))]
8066 ""
8067 "div{w}\t%2"
8068 [(set_attr "type" "idiv")
8069 (set_attr "mode" "HI")
8070 (set_attr "ppro_uops" "few")])
8071
8072 ;; We can not use div/idiv for double division, because it causes
8073 ;; "division by zero" on the overflow and that's not what we expect
8074 ;; from truncate. Because true (non truncating) double division is
8075 ;; never generated, we can't create this insn anyway.
8076 ;
8077 ;(define_insn ""
8078 ; [(set (match_operand:SI 0 "register_operand" "=a")
8079 ; (truncate:SI
8080 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8081 ; (zero_extend:DI
8082 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8083 ; (set (match_operand:SI 3 "register_operand" "=d")
8084 ; (truncate:SI
8085 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8086 ; (clobber (reg:CC 17))]
8087 ; ""
8088 ; "div{l}\t{%2, %0|%0, %2}"
8089 ; [(set_attr "type" "idiv")
8090 ; (set_attr "ppro_uops" "few")])
8091 \f
8092 ;;- Logical AND instructions
8093
8094 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8095 ;; Note that this excludes ah.
8096
8097 (define_insn "*testdi_1_rex64"
8098 [(set (reg 17)
8099 (compare
8100 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8101 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8102 (const_int 0)))]
8103 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8104 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8105 "@
8106 test{l}\t{%k1, %k0|%k0, %k1}
8107 test{l}\t{%k1, %k0|%k0, %k1}
8108 test{q}\t{%1, %0|%0, %1}
8109 test{q}\t{%1, %0|%0, %1}
8110 test{q}\t{%1, %0|%0, %1}"
8111 [(set_attr "type" "test")
8112 (set_attr "modrm" "0,1,0,1,1")
8113 (set_attr "mode" "SI,SI,DI,DI,DI")
8114 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8115
8116 (define_insn "testsi_1"
8117 [(set (reg 17)
8118 (compare
8119 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8120 (match_operand:SI 1 "general_operand" "in,in,rin"))
8121 (const_int 0)))]
8122 "ix86_match_ccmode (insn, CCNOmode)
8123 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8124 "test{l}\t{%1, %0|%0, %1}"
8125 [(set_attr "type" "test")
8126 (set_attr "modrm" "0,1,1")
8127 (set_attr "mode" "SI")
8128 (set_attr "pent_pair" "uv,np,uv")])
8129
8130 (define_expand "testsi_ccno_1"
8131 [(set (reg:CCNO 17)
8132 (compare:CCNO
8133 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8134 (match_operand:SI 1 "nonmemory_operand" ""))
8135 (const_int 0)))]
8136 ""
8137 "")
8138
8139 (define_insn "*testhi_1"
8140 [(set (reg 17)
8141 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8142 (match_operand:HI 1 "general_operand" "n,n,rn"))
8143 (const_int 0)))]
8144 "ix86_match_ccmode (insn, CCNOmode)
8145 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8146 "test{w}\t{%1, %0|%0, %1}"
8147 [(set_attr "type" "test")
8148 (set_attr "modrm" "0,1,1")
8149 (set_attr "mode" "HI")
8150 (set_attr "pent_pair" "uv,np,uv")])
8151
8152 (define_expand "testqi_ccz_1"
8153 [(set (reg:CCZ 17)
8154 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8155 (match_operand:QI 1 "nonmemory_operand" ""))
8156 (const_int 0)))]
8157 ""
8158 "")
8159
8160 (define_insn "*testqi_1"
8161 [(set (reg 17)
8162 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8163 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8164 (const_int 0)))]
8165 "ix86_match_ccmode (insn, CCNOmode)
8166 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8167 {
8168 if (which_alternative == 3)
8169 {
8170 if (GET_CODE (operands[1]) == CONST_INT
8171 && (INTVAL (operands[1]) & 0xffffff00))
8172 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8173 return "test{l}\t{%1, %k0|%k0, %1}";
8174 }
8175 return "test{b}\t{%1, %0|%0, %1}";
8176 }
8177 [(set_attr "type" "test")
8178 (set_attr "modrm" "0,1,1,1")
8179 (set_attr "mode" "QI,QI,QI,SI")
8180 (set_attr "pent_pair" "uv,np,uv,np")])
8181
8182 (define_expand "testqi_ext_ccno_0"
8183 [(set (reg:CCNO 17)
8184 (compare:CCNO
8185 (and:SI
8186 (zero_extract:SI
8187 (match_operand 0 "ext_register_operand" "")
8188 (const_int 8)
8189 (const_int 8))
8190 (match_operand 1 "const_int_operand" ""))
8191 (const_int 0)))]
8192 ""
8193 "")
8194
8195 (define_insn "*testqi_ext_0"
8196 [(set (reg 17)
8197 (compare
8198 (and:SI
8199 (zero_extract:SI
8200 (match_operand 0 "ext_register_operand" "Q")
8201 (const_int 8)
8202 (const_int 8))
8203 (match_operand 1 "const_int_operand" "n"))
8204 (const_int 0)))]
8205 "ix86_match_ccmode (insn, CCNOmode)"
8206 "test{b}\t{%1, %h0|%h0, %1}"
8207 [(set_attr "type" "test")
8208 (set_attr "mode" "QI")
8209 (set_attr "length_immediate" "1")
8210 (set_attr "pent_pair" "np")])
8211
8212 (define_insn "*testqi_ext_1"
8213 [(set (reg 17)
8214 (compare
8215 (and:SI
8216 (zero_extract:SI
8217 (match_operand 0 "ext_register_operand" "Q")
8218 (const_int 8)
8219 (const_int 8))
8220 (zero_extend:SI
8221 (match_operand:QI 1 "general_operand" "Qm")))
8222 (const_int 0)))]
8223 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8224 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8225 "test{b}\t{%1, %h0|%h0, %1}"
8226 [(set_attr "type" "test")
8227 (set_attr "mode" "QI")])
8228
8229 (define_insn "*testqi_ext_1_rex64"
8230 [(set (reg 17)
8231 (compare
8232 (and:SI
8233 (zero_extract:SI
8234 (match_operand 0 "ext_register_operand" "Q")
8235 (const_int 8)
8236 (const_int 8))
8237 (zero_extend:SI
8238 (match_operand:QI 1 "register_operand" "Q")))
8239 (const_int 0)))]
8240 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8241 "test{b}\t{%1, %h0|%h0, %1}"
8242 [(set_attr "type" "test")
8243 (set_attr "mode" "QI")])
8244
8245 (define_insn "*testqi_ext_2"
8246 [(set (reg 17)
8247 (compare
8248 (and:SI
8249 (zero_extract:SI
8250 (match_operand 0 "ext_register_operand" "Q")
8251 (const_int 8)
8252 (const_int 8))
8253 (zero_extract:SI
8254 (match_operand 1 "ext_register_operand" "Q")
8255 (const_int 8)
8256 (const_int 8)))
8257 (const_int 0)))]
8258 "ix86_match_ccmode (insn, CCNOmode)"
8259 "test{b}\t{%h1, %h0|%h0, %h1}"
8260 [(set_attr "type" "test")
8261 (set_attr "mode" "QI")])
8262
8263 ;; Combine likes to form bit extractions for some tests. Humor it.
8264 (define_insn "*testqi_ext_3"
8265 [(set (reg 17)
8266 (compare (zero_extract:SI
8267 (match_operand 0 "nonimmediate_operand" "rm")
8268 (match_operand:SI 1 "const_int_operand" "")
8269 (match_operand:SI 2 "const_int_operand" ""))
8270 (const_int 0)))]
8271 "ix86_match_ccmode (insn, CCNOmode)
8272 && (GET_MODE (operands[0]) == SImode
8273 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8274 || GET_MODE (operands[0]) == HImode
8275 || GET_MODE (operands[0]) == QImode)"
8276 "#")
8277
8278 (define_insn "*testqi_ext_3_rex64"
8279 [(set (reg 17)
8280 (compare (zero_extract:DI
8281 (match_operand 0 "nonimmediate_operand" "rm")
8282 (match_operand:DI 1 "const_int_operand" "")
8283 (match_operand:DI 2 "const_int_operand" ""))
8284 (const_int 0)))]
8285 "TARGET_64BIT
8286 && ix86_match_ccmode (insn, CCNOmode)
8287 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8288 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8289 /* Ensure that resulting mask is zero or sign extended operand. */
8290 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8291 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8292 && INTVAL (operands[1]) > 32))
8293 && (GET_MODE (operands[0]) == SImode
8294 || GET_MODE (operands[0]) == DImode
8295 || GET_MODE (operands[0]) == HImode
8296 || GET_MODE (operands[0]) == QImode)"
8297 "#")
8298
8299 (define_split
8300 [(set (reg 17)
8301 (compare (zero_extract
8302 (match_operand 0 "nonimmediate_operand" "")
8303 (match_operand 1 "const_int_operand" "")
8304 (match_operand 2 "const_int_operand" ""))
8305 (const_int 0)))]
8306 "ix86_match_ccmode (insn, CCNOmode)"
8307 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8308 {
8309 HOST_WIDE_INT len = INTVAL (operands[1]);
8310 HOST_WIDE_INT pos = INTVAL (operands[2]);
8311 HOST_WIDE_INT mask;
8312 enum machine_mode mode, submode;
8313
8314 mode = GET_MODE (operands[0]);
8315 if (GET_CODE (operands[0]) == MEM)
8316 {
8317 /* ??? Combine likes to put non-volatile mem extractions in QImode
8318 no matter the size of the test. So find a mode that works. */
8319 if (! MEM_VOLATILE_P (operands[0]))
8320 {
8321 mode = smallest_mode_for_size (pos + len, MODE_INT);
8322 operands[0] = adjust_address (operands[0], mode, 0);
8323 }
8324 }
8325 else if (GET_CODE (operands[0]) == SUBREG
8326 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8327 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8328 && pos + len <= GET_MODE_BITSIZE (submode))
8329 {
8330 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8331 mode = submode;
8332 operands[0] = SUBREG_REG (operands[0]);
8333 }
8334 else if (mode == HImode && pos + len <= 8)
8335 {
8336 /* Small HImode tests can be converted to QImode. */
8337 mode = QImode;
8338 operands[0] = gen_lowpart (QImode, operands[0]);
8339 }
8340
8341 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8342 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8343
8344 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8345 })
8346
8347 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8348 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8349 ;; this is relatively important trick.
8350 ;; Do the conversion only post-reload to avoid limiting of the register class
8351 ;; to QI regs.
8352 (define_split
8353 [(set (reg 17)
8354 (compare
8355 (and (match_operand 0 "register_operand" "")
8356 (match_operand 1 "const_int_operand" ""))
8357 (const_int 0)))]
8358 "reload_completed
8359 && QI_REG_P (operands[0])
8360 && ((ix86_match_ccmode (insn, CCZmode)
8361 && !(INTVAL (operands[1]) & ~(255 << 8)))
8362 || (ix86_match_ccmode (insn, CCNOmode)
8363 && !(INTVAL (operands[1]) & ~(127 << 8))))
8364 && GET_MODE (operands[0]) != QImode"
8365 [(set (reg:CCNO 17)
8366 (compare:CCNO
8367 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8368 (match_dup 1))
8369 (const_int 0)))]
8370 "operands[0] = gen_lowpart (SImode, operands[0]);
8371 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8372
8373 (define_split
8374 [(set (reg 17)
8375 (compare
8376 (and (match_operand 0 "nonimmediate_operand" "")
8377 (match_operand 1 "const_int_operand" ""))
8378 (const_int 0)))]
8379 "reload_completed
8380 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8381 && ((ix86_match_ccmode (insn, CCZmode)
8382 && !(INTVAL (operands[1]) & ~255))
8383 || (ix86_match_ccmode (insn, CCNOmode)
8384 && !(INTVAL (operands[1]) & ~127)))
8385 && GET_MODE (operands[0]) != QImode"
8386 [(set (reg:CCNO 17)
8387 (compare:CCNO
8388 (and:QI (match_dup 0)
8389 (match_dup 1))
8390 (const_int 0)))]
8391 "operands[0] = gen_lowpart (QImode, operands[0]);
8392 operands[1] = gen_lowpart (QImode, operands[1]);")
8393
8394
8395 ;; %%% This used to optimize known byte-wide and operations to memory,
8396 ;; and sometimes to QImode registers. If this is considered useful,
8397 ;; it should be done with splitters.
8398
8399 (define_expand "anddi3"
8400 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8401 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8402 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8403 (clobber (reg:CC 17))]
8404 "TARGET_64BIT"
8405 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8406
8407 (define_insn "*anddi_1_rex64"
8408 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8409 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8410 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8411 (clobber (reg:CC 17))]
8412 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8413 {
8414 switch (get_attr_type (insn))
8415 {
8416 case TYPE_IMOVX:
8417 {
8418 enum machine_mode mode;
8419
8420 if (GET_CODE (operands[2]) != CONST_INT)
8421 abort ();
8422 if (INTVAL (operands[2]) == 0xff)
8423 mode = QImode;
8424 else if (INTVAL (operands[2]) == 0xffff)
8425 mode = HImode;
8426 else
8427 abort ();
8428
8429 operands[1] = gen_lowpart (mode, operands[1]);
8430 if (mode == QImode)
8431 return "movz{bq|x}\t{%1,%0|%0, %1}";
8432 else
8433 return "movz{wq|x}\t{%1,%0|%0, %1}";
8434 }
8435
8436 default:
8437 if (! rtx_equal_p (operands[0], operands[1]))
8438 abort ();
8439 if (get_attr_mode (insn) == MODE_SI)
8440 return "and{l}\t{%k2, %k0|%k0, %k2}";
8441 else
8442 return "and{q}\t{%2, %0|%0, %2}";
8443 }
8444 }
8445 [(set_attr "type" "alu,alu,alu,imovx")
8446 (set_attr "length_immediate" "*,*,*,0")
8447 (set_attr "mode" "SI,DI,DI,DI")])
8448
8449 (define_insn "*anddi_2"
8450 [(set (reg 17)
8451 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8452 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8453 (const_int 0)))
8454 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8455 (and:DI (match_dup 1) (match_dup 2)))]
8456 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8457 && ix86_binary_operator_ok (AND, DImode, operands)"
8458 "@
8459 and{l}\t{%k2, %k0|%k0, %k2}
8460 and{q}\t{%2, %0|%0, %2}
8461 and{q}\t{%2, %0|%0, %2}"
8462 [(set_attr "type" "alu")
8463 (set_attr "mode" "SI,DI,DI")])
8464
8465 (define_expand "andsi3"
8466 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8467 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8468 (match_operand:SI 2 "general_operand" "")))
8469 (clobber (reg:CC 17))]
8470 ""
8471 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8472
8473 (define_insn "*andsi_1"
8474 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8475 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8476 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8477 (clobber (reg:CC 17))]
8478 "ix86_binary_operator_ok (AND, SImode, operands)"
8479 {
8480 switch (get_attr_type (insn))
8481 {
8482 case TYPE_IMOVX:
8483 {
8484 enum machine_mode mode;
8485
8486 if (GET_CODE (operands[2]) != CONST_INT)
8487 abort ();
8488 if (INTVAL (operands[2]) == 0xff)
8489 mode = QImode;
8490 else if (INTVAL (operands[2]) == 0xffff)
8491 mode = HImode;
8492 else
8493 abort ();
8494
8495 operands[1] = gen_lowpart (mode, operands[1]);
8496 if (mode == QImode)
8497 return "movz{bl|x}\t{%1,%0|%0, %1}";
8498 else
8499 return "movz{wl|x}\t{%1,%0|%0, %1}";
8500 }
8501
8502 default:
8503 if (! rtx_equal_p (operands[0], operands[1]))
8504 abort ();
8505 return "and{l}\t{%2, %0|%0, %2}";
8506 }
8507 }
8508 [(set_attr "type" "alu,alu,imovx")
8509 (set_attr "length_immediate" "*,*,0")
8510 (set_attr "mode" "SI")])
8511
8512 (define_split
8513 [(set (match_operand 0 "register_operand" "")
8514 (and (match_dup 0)
8515 (const_int -65536)))
8516 (clobber (reg:CC 17))]
8517 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8518 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8519 "operands[1] = gen_lowpart (HImode, operands[0]);")
8520
8521 (define_split
8522 [(set (match_operand 0 "ext_register_operand" "")
8523 (and (match_dup 0)
8524 (const_int -256)))
8525 (clobber (reg:CC 17))]
8526 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8527 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8528 "operands[1] = gen_lowpart (QImode, operands[0]);")
8529
8530 (define_split
8531 [(set (match_operand 0 "ext_register_operand" "")
8532 (and (match_dup 0)
8533 (const_int -65281)))
8534 (clobber (reg:CC 17))]
8535 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8536 [(parallel [(set (zero_extract:SI (match_dup 0)
8537 (const_int 8)
8538 (const_int 8))
8539 (xor:SI
8540 (zero_extract:SI (match_dup 0)
8541 (const_int 8)
8542 (const_int 8))
8543 (zero_extract:SI (match_dup 0)
8544 (const_int 8)
8545 (const_int 8))))
8546 (clobber (reg:CC 17))])]
8547 "operands[0] = gen_lowpart (SImode, operands[0]);")
8548
8549 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8550 (define_insn "*andsi_1_zext"
8551 [(set (match_operand:DI 0 "register_operand" "=r")
8552 (zero_extend:DI
8553 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8554 (match_operand:SI 2 "general_operand" "rim"))))
8555 (clobber (reg:CC 17))]
8556 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8557 "and{l}\t{%2, %k0|%k0, %2}"
8558 [(set_attr "type" "alu")
8559 (set_attr "mode" "SI")])
8560
8561 (define_insn "*andsi_2"
8562 [(set (reg 17)
8563 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8564 (match_operand:SI 2 "general_operand" "rim,ri"))
8565 (const_int 0)))
8566 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8567 (and:SI (match_dup 1) (match_dup 2)))]
8568 "ix86_match_ccmode (insn, CCNOmode)
8569 && ix86_binary_operator_ok (AND, SImode, operands)"
8570 "and{l}\t{%2, %0|%0, %2}"
8571 [(set_attr "type" "alu")
8572 (set_attr "mode" "SI")])
8573
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 (define_insn "*andsi_2_zext"
8576 [(set (reg 17)
8577 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8578 (match_operand:SI 2 "general_operand" "rim"))
8579 (const_int 0)))
8580 (set (match_operand:DI 0 "register_operand" "=r")
8581 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8582 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8583 && ix86_binary_operator_ok (AND, SImode, operands)"
8584 "and{l}\t{%2, %k0|%k0, %2}"
8585 [(set_attr "type" "alu")
8586 (set_attr "mode" "SI")])
8587
8588 (define_expand "andhi3"
8589 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8590 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8591 (match_operand:HI 2 "general_operand" "")))
8592 (clobber (reg:CC 17))]
8593 "TARGET_HIMODE_MATH"
8594 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8595
8596 (define_insn "*andhi_1"
8597 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8598 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8599 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8600 (clobber (reg:CC 17))]
8601 "ix86_binary_operator_ok (AND, HImode, operands)"
8602 {
8603 switch (get_attr_type (insn))
8604 {
8605 case TYPE_IMOVX:
8606 if (GET_CODE (operands[2]) != CONST_INT)
8607 abort ();
8608 if (INTVAL (operands[2]) == 0xff)
8609 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8610 abort ();
8611
8612 default:
8613 if (! rtx_equal_p (operands[0], operands[1]))
8614 abort ();
8615
8616 return "and{w}\t{%2, %0|%0, %2}";
8617 }
8618 }
8619 [(set_attr "type" "alu,alu,imovx")
8620 (set_attr "length_immediate" "*,*,0")
8621 (set_attr "mode" "HI,HI,SI")])
8622
8623 (define_insn "*andhi_2"
8624 [(set (reg 17)
8625 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8626 (match_operand:HI 2 "general_operand" "rim,ri"))
8627 (const_int 0)))
8628 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8629 (and:HI (match_dup 1) (match_dup 2)))]
8630 "ix86_match_ccmode (insn, CCNOmode)
8631 && ix86_binary_operator_ok (AND, HImode, operands)"
8632 "and{w}\t{%2, %0|%0, %2}"
8633 [(set_attr "type" "alu")
8634 (set_attr "mode" "HI")])
8635
8636 (define_expand "andqi3"
8637 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8638 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8639 (match_operand:QI 2 "general_operand" "")))
8640 (clobber (reg:CC 17))]
8641 "TARGET_QIMODE_MATH"
8642 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8643
8644 ;; %%% Potential partial reg stall on alternative 2. What to do?
8645 (define_insn "*andqi_1"
8646 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8647 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8648 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8649 (clobber (reg:CC 17))]
8650 "ix86_binary_operator_ok (AND, QImode, operands)"
8651 "@
8652 and{b}\t{%2, %0|%0, %2}
8653 and{b}\t{%2, %0|%0, %2}
8654 and{l}\t{%k2, %k0|%k0, %k2}"
8655 [(set_attr "type" "alu")
8656 (set_attr "mode" "QI,QI,SI")])
8657
8658 (define_insn "*andqi_1_slp"
8659 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8660 (and:QI (match_dup 0)
8661 (match_operand:QI 1 "general_operand" "qi,qmi")))
8662 (clobber (reg:CC 17))]
8663 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8664 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8665 "and{b}\t{%1, %0|%0, %1}"
8666 [(set_attr "type" "alu1")
8667 (set_attr "mode" "QI")])
8668
8669 (define_insn "*andqi_2"
8670 [(set (reg 17)
8671 (compare (and:QI
8672 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8673 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8674 (const_int 0)))
8675 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8676 (and:QI (match_dup 1) (match_dup 2)))]
8677 "ix86_match_ccmode (insn, CCNOmode)
8678 && ix86_binary_operator_ok (AND, QImode, operands)"
8679 {
8680 if (which_alternative == 2)
8681 {
8682 if (GET_CODE (operands[2]) == CONST_INT
8683 && (INTVAL (operands[2]) & 0xffffff00))
8684 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8685 return "and{l}\t{%2, %k0|%k0, %2}";
8686 }
8687 return "and{b}\t{%2, %0|%0, %2}";
8688 }
8689 [(set_attr "type" "alu")
8690 (set_attr "mode" "QI,QI,SI")])
8691
8692 (define_insn "*andqi_2_slp"
8693 [(set (reg 17)
8694 (compare (and:QI
8695 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8696 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8697 (const_int 0)))
8698 (set (strict_low_part (match_dup 0))
8699 (and:QI (match_dup 0) (match_dup 1)))]
8700 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8701 && ix86_match_ccmode (insn, CCNOmode)
8702 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8703 "and{b}\t{%1, %0|%0, %1}"
8704 [(set_attr "type" "alu1")
8705 (set_attr "mode" "QI")])
8706
8707 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8708 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8709 ;; for a QImode operand, which of course failed.
8710
8711 (define_insn "andqi_ext_0"
8712 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8713 (const_int 8)
8714 (const_int 8))
8715 (and:SI
8716 (zero_extract:SI
8717 (match_operand 1 "ext_register_operand" "0")
8718 (const_int 8)
8719 (const_int 8))
8720 (match_operand 2 "const_int_operand" "n")))
8721 (clobber (reg:CC 17))]
8722 ""
8723 "and{b}\t{%2, %h0|%h0, %2}"
8724 [(set_attr "type" "alu")
8725 (set_attr "length_immediate" "1")
8726 (set_attr "mode" "QI")])
8727
8728 ;; Generated by peephole translating test to and. This shows up
8729 ;; often in fp comparisons.
8730
8731 (define_insn "*andqi_ext_0_cc"
8732 [(set (reg 17)
8733 (compare
8734 (and:SI
8735 (zero_extract:SI
8736 (match_operand 1 "ext_register_operand" "0")
8737 (const_int 8)
8738 (const_int 8))
8739 (match_operand 2 "const_int_operand" "n"))
8740 (const_int 0)))
8741 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8742 (const_int 8)
8743 (const_int 8))
8744 (and:SI
8745 (zero_extract:SI
8746 (match_dup 1)
8747 (const_int 8)
8748 (const_int 8))
8749 (match_dup 2)))]
8750 "ix86_match_ccmode (insn, CCNOmode)"
8751 "and{b}\t{%2, %h0|%h0, %2}"
8752 [(set_attr "type" "alu")
8753 (set_attr "length_immediate" "1")
8754 (set_attr "mode" "QI")])
8755
8756 (define_insn "*andqi_ext_1"
8757 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8758 (const_int 8)
8759 (const_int 8))
8760 (and:SI
8761 (zero_extract:SI
8762 (match_operand 1 "ext_register_operand" "0")
8763 (const_int 8)
8764 (const_int 8))
8765 (zero_extend:SI
8766 (match_operand:QI 2 "general_operand" "Qm"))))
8767 (clobber (reg:CC 17))]
8768 "!TARGET_64BIT"
8769 "and{b}\t{%2, %h0|%h0, %2}"
8770 [(set_attr "type" "alu")
8771 (set_attr "length_immediate" "0")
8772 (set_attr "mode" "QI")])
8773
8774 (define_insn "*andqi_ext_1_rex64"
8775 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8776 (const_int 8)
8777 (const_int 8))
8778 (and:SI
8779 (zero_extract:SI
8780 (match_operand 1 "ext_register_operand" "0")
8781 (const_int 8)
8782 (const_int 8))
8783 (zero_extend:SI
8784 (match_operand 2 "ext_register_operand" "Q"))))
8785 (clobber (reg:CC 17))]
8786 "TARGET_64BIT"
8787 "and{b}\t{%2, %h0|%h0, %2}"
8788 [(set_attr "type" "alu")
8789 (set_attr "length_immediate" "0")
8790 (set_attr "mode" "QI")])
8791
8792 (define_insn "*andqi_ext_2"
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_extract:SI
8802 (match_operand 2 "ext_register_operand" "Q")
8803 (const_int 8)
8804 (const_int 8))))
8805 (clobber (reg:CC 17))]
8806 ""
8807 "and{b}\t{%h2, %h0|%h0, %h2}"
8808 [(set_attr "type" "alu")
8809 (set_attr "length_immediate" "0")
8810 (set_attr "mode" "QI")])
8811
8812 ;; Convert wide AND instructions with immediate operand to shorter QImode
8813 ;; equivalents when possible.
8814 ;; Don't do the splitting with memory operands, since it introduces risk
8815 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8816 ;; for size, but that can (should?) be handled by generic code instead.
8817 (define_split
8818 [(set (match_operand 0 "register_operand" "")
8819 (and (match_operand 1 "register_operand" "")
8820 (match_operand 2 "const_int_operand" "")))
8821 (clobber (reg:CC 17))]
8822 "reload_completed
8823 && QI_REG_P (operands[0])
8824 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8825 && !(~INTVAL (operands[2]) & ~(255 << 8))
8826 && GET_MODE (operands[0]) != QImode"
8827 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8828 (and:SI (zero_extract:SI (match_dup 1)
8829 (const_int 8) (const_int 8))
8830 (match_dup 2)))
8831 (clobber (reg:CC 17))])]
8832 "operands[0] = gen_lowpart (SImode, operands[0]);
8833 operands[1] = gen_lowpart (SImode, operands[1]);
8834 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8835
8836 ;; Since AND can be encoded with sign extended immediate, this is only
8837 ;; profitable when 7th bit is not set.
8838 (define_split
8839 [(set (match_operand 0 "register_operand" "")
8840 (and (match_operand 1 "general_operand" "")
8841 (match_operand 2 "const_int_operand" "")))
8842 (clobber (reg:CC 17))]
8843 "reload_completed
8844 && ANY_QI_REG_P (operands[0])
8845 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8846 && !(~INTVAL (operands[2]) & ~255)
8847 && !(INTVAL (operands[2]) & 128)
8848 && GET_MODE (operands[0]) != QImode"
8849 [(parallel [(set (strict_low_part (match_dup 0))
8850 (and:QI (match_dup 1)
8851 (match_dup 2)))
8852 (clobber (reg:CC 17))])]
8853 "operands[0] = gen_lowpart (QImode, operands[0]);
8854 operands[1] = gen_lowpart (QImode, operands[1]);
8855 operands[2] = gen_lowpart (QImode, operands[2]);")
8856 \f
8857 ;; Logical inclusive OR instructions
8858
8859 ;; %%% This used to optimize known byte-wide and operations to memory.
8860 ;; If this is considered useful, it should be done with splitters.
8861
8862 (define_expand "iordi3"
8863 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8864 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8865 (match_operand:DI 2 "x86_64_general_operand" "")))
8866 (clobber (reg:CC 17))]
8867 "TARGET_64BIT"
8868 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8869
8870 (define_insn "*iordi_1_rex64"
8871 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8872 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8873 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8874 (clobber (reg:CC 17))]
8875 "TARGET_64BIT
8876 && ix86_binary_operator_ok (IOR, DImode, operands)"
8877 "or{q}\t{%2, %0|%0, %2}"
8878 [(set_attr "type" "alu")
8879 (set_attr "mode" "DI")])
8880
8881 (define_insn "*iordi_2_rex64"
8882 [(set (reg 17)
8883 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8884 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8885 (const_int 0)))
8886 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8887 (ior:DI (match_dup 1) (match_dup 2)))]
8888 "TARGET_64BIT
8889 && ix86_match_ccmode (insn, CCNOmode)
8890 && ix86_binary_operator_ok (IOR, DImode, operands)"
8891 "or{q}\t{%2, %0|%0, %2}"
8892 [(set_attr "type" "alu")
8893 (set_attr "mode" "DI")])
8894
8895 (define_insn "*iordi_3_rex64"
8896 [(set (reg 17)
8897 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8898 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8899 (const_int 0)))
8900 (clobber (match_scratch:DI 0 "=r"))]
8901 "TARGET_64BIT
8902 && ix86_match_ccmode (insn, CCNOmode)
8903 && ix86_binary_operator_ok (IOR, DImode, operands)"
8904 "or{q}\t{%2, %0|%0, %2}"
8905 [(set_attr "type" "alu")
8906 (set_attr "mode" "DI")])
8907
8908
8909 (define_expand "iorsi3"
8910 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8911 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8912 (match_operand:SI 2 "general_operand" "")))
8913 (clobber (reg:CC 17))]
8914 ""
8915 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8916
8917 (define_insn "*iorsi_1"
8918 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8919 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8920 (match_operand:SI 2 "general_operand" "ri,rmi")))
8921 (clobber (reg:CC 17))]
8922 "ix86_binary_operator_ok (IOR, SImode, operands)"
8923 "or{l}\t{%2, %0|%0, %2}"
8924 [(set_attr "type" "alu")
8925 (set_attr "mode" "SI")])
8926
8927 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8928 (define_insn "*iorsi_1_zext"
8929 [(set (match_operand:DI 0 "register_operand" "=rm")
8930 (zero_extend:DI
8931 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8932 (match_operand:SI 2 "general_operand" "rim"))))
8933 (clobber (reg:CC 17))]
8934 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8935 "or{l}\t{%2, %k0|%k0, %2}"
8936 [(set_attr "type" "alu")
8937 (set_attr "mode" "SI")])
8938
8939 (define_insn "*iorsi_1_zext_imm"
8940 [(set (match_operand:DI 0 "register_operand" "=rm")
8941 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8942 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8943 (clobber (reg:CC 17))]
8944 "TARGET_64BIT"
8945 "or{l}\t{%2, %k0|%k0, %2}"
8946 [(set_attr "type" "alu")
8947 (set_attr "mode" "SI")])
8948
8949 (define_insn "*iorsi_2"
8950 [(set (reg 17)
8951 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8952 (match_operand:SI 2 "general_operand" "rim,ri"))
8953 (const_int 0)))
8954 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8955 (ior:SI (match_dup 1) (match_dup 2)))]
8956 "ix86_match_ccmode (insn, CCNOmode)
8957 && ix86_binary_operator_ok (IOR, SImode, operands)"
8958 "or{l}\t{%2, %0|%0, %2}"
8959 [(set_attr "type" "alu")
8960 (set_attr "mode" "SI")])
8961
8962 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8963 ;; ??? Special case for immediate operand is missing - it is tricky.
8964 (define_insn "*iorsi_2_zext"
8965 [(set (reg 17)
8966 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8967 (match_operand:SI 2 "general_operand" "rim"))
8968 (const_int 0)))
8969 (set (match_operand:DI 0 "register_operand" "=r")
8970 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8971 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8972 && ix86_binary_operator_ok (IOR, SImode, operands)"
8973 "or{l}\t{%2, %k0|%k0, %2}"
8974 [(set_attr "type" "alu")
8975 (set_attr "mode" "SI")])
8976
8977 (define_insn "*iorsi_2_zext_imm"
8978 [(set (reg 17)
8979 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8980 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8981 (const_int 0)))
8982 (set (match_operand:DI 0 "register_operand" "=r")
8983 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8984 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8985 && ix86_binary_operator_ok (IOR, SImode, operands)"
8986 "or{l}\t{%2, %k0|%k0, %2}"
8987 [(set_attr "type" "alu")
8988 (set_attr "mode" "SI")])
8989
8990 (define_insn "*iorsi_3"
8991 [(set (reg 17)
8992 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8993 (match_operand:SI 2 "general_operand" "rim"))
8994 (const_int 0)))
8995 (clobber (match_scratch:SI 0 "=r"))]
8996 "ix86_match_ccmode (insn, CCNOmode)
8997 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8998 "or{l}\t{%2, %0|%0, %2}"
8999 [(set_attr "type" "alu")
9000 (set_attr "mode" "SI")])
9001
9002 (define_expand "iorhi3"
9003 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9004 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9005 (match_operand:HI 2 "general_operand" "")))
9006 (clobber (reg:CC 17))]
9007 "TARGET_HIMODE_MATH"
9008 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9009
9010 (define_insn "*iorhi_1"
9011 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9012 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9013 (match_operand:HI 2 "general_operand" "rmi,ri")))
9014 (clobber (reg:CC 17))]
9015 "ix86_binary_operator_ok (IOR, HImode, operands)"
9016 "or{w}\t{%2, %0|%0, %2}"
9017 [(set_attr "type" "alu")
9018 (set_attr "mode" "HI")])
9019
9020 (define_insn "*iorhi_2"
9021 [(set (reg 17)
9022 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9023 (match_operand:HI 2 "general_operand" "rim,ri"))
9024 (const_int 0)))
9025 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9026 (ior:HI (match_dup 1) (match_dup 2)))]
9027 "ix86_match_ccmode (insn, CCNOmode)
9028 && ix86_binary_operator_ok (IOR, HImode, operands)"
9029 "or{w}\t{%2, %0|%0, %2}"
9030 [(set_attr "type" "alu")
9031 (set_attr "mode" "HI")])
9032
9033 (define_insn "*iorhi_3"
9034 [(set (reg 17)
9035 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9036 (match_operand:HI 2 "general_operand" "rim"))
9037 (const_int 0)))
9038 (clobber (match_scratch:HI 0 "=r"))]
9039 "ix86_match_ccmode (insn, CCNOmode)
9040 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9041 "or{w}\t{%2, %0|%0, %2}"
9042 [(set_attr "type" "alu")
9043 (set_attr "mode" "HI")])
9044
9045 (define_expand "iorqi3"
9046 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9047 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9048 (match_operand:QI 2 "general_operand" "")))
9049 (clobber (reg:CC 17))]
9050 "TARGET_QIMODE_MATH"
9051 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9052
9053 ;; %%% Potential partial reg stall on alternative 2. What to do?
9054 (define_insn "*iorqi_1"
9055 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9056 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9057 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9058 (clobber (reg:CC 17))]
9059 "ix86_binary_operator_ok (IOR, QImode, operands)"
9060 "@
9061 or{b}\t{%2, %0|%0, %2}
9062 or{b}\t{%2, %0|%0, %2}
9063 or{l}\t{%k2, %k0|%k0, %k2}"
9064 [(set_attr "type" "alu")
9065 (set_attr "mode" "QI,QI,SI")])
9066
9067 (define_insn "*iorqi_1_slp"
9068 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9069 (ior:QI (match_dup 0)
9070 (match_operand:QI 1 "general_operand" "qmi,qi")))
9071 (clobber (reg:CC 17))]
9072 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9073 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9074 "or{b}\t{%1, %0|%0, %1}"
9075 [(set_attr "type" "alu1")
9076 (set_attr "mode" "QI")])
9077
9078 (define_insn "*iorqi_2"
9079 [(set (reg 17)
9080 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9081 (match_operand:QI 2 "general_operand" "qim,qi"))
9082 (const_int 0)))
9083 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9084 (ior:QI (match_dup 1) (match_dup 2)))]
9085 "ix86_match_ccmode (insn, CCNOmode)
9086 && ix86_binary_operator_ok (IOR, QImode, operands)"
9087 "or{b}\t{%2, %0|%0, %2}"
9088 [(set_attr "type" "alu")
9089 (set_attr "mode" "QI")])
9090
9091 (define_insn "*iorqi_2_slp"
9092 [(set (reg 17)
9093 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9094 (match_operand:QI 1 "general_operand" "qim,qi"))
9095 (const_int 0)))
9096 (set (strict_low_part (match_dup 0))
9097 (ior:QI (match_dup 0) (match_dup 1)))]
9098 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9099 && ix86_match_ccmode (insn, CCNOmode)
9100 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9101 "or{b}\t{%1, %0|%0, %1}"
9102 [(set_attr "type" "alu1")
9103 (set_attr "mode" "QI")])
9104
9105 (define_insn "*iorqi_3"
9106 [(set (reg 17)
9107 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9108 (match_operand:QI 2 "general_operand" "qim"))
9109 (const_int 0)))
9110 (clobber (match_scratch:QI 0 "=q"))]
9111 "ix86_match_ccmode (insn, CCNOmode)
9112 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9113 "or{b}\t{%2, %0|%0, %2}"
9114 [(set_attr "type" "alu")
9115 (set_attr "mode" "QI")])
9116
9117 (define_insn "iorqi_ext_0"
9118 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9119 (const_int 8)
9120 (const_int 8))
9121 (ior:SI
9122 (zero_extract:SI
9123 (match_operand 1 "ext_register_operand" "0")
9124 (const_int 8)
9125 (const_int 8))
9126 (match_operand 2 "const_int_operand" "n")))
9127 (clobber (reg:CC 17))]
9128 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9129 "or{b}\t{%2, %h0|%h0, %2}"
9130 [(set_attr "type" "alu")
9131 (set_attr "length_immediate" "1")
9132 (set_attr "mode" "QI")])
9133
9134 (define_insn "*iorqi_ext_1"
9135 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9136 (const_int 8)
9137 (const_int 8))
9138 (ior:SI
9139 (zero_extract:SI
9140 (match_operand 1 "ext_register_operand" "0")
9141 (const_int 8)
9142 (const_int 8))
9143 (zero_extend:SI
9144 (match_operand:QI 2 "general_operand" "Qm"))))
9145 (clobber (reg:CC 17))]
9146 "!TARGET_64BIT
9147 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9148 "or{b}\t{%2, %h0|%h0, %2}"
9149 [(set_attr "type" "alu")
9150 (set_attr "length_immediate" "0")
9151 (set_attr "mode" "QI")])
9152
9153 (define_insn "*iorqi_ext_1_rex64"
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 (zero_extend:SI
9163 (match_operand 2 "ext_register_operand" "Q"))))
9164 (clobber (reg:CC 17))]
9165 "TARGET_64BIT
9166 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167 "or{b}\t{%2, %h0|%h0, %2}"
9168 [(set_attr "type" "alu")
9169 (set_attr "length_immediate" "0")
9170 (set_attr "mode" "QI")])
9171
9172 (define_insn "*iorqi_ext_2"
9173 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9174 (const_int 8)
9175 (const_int 8))
9176 (ior:SI
9177 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9178 (const_int 8)
9179 (const_int 8))
9180 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9181 (const_int 8)
9182 (const_int 8))))
9183 (clobber (reg:CC 17))]
9184 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9185 "ior{b}\t{%h2, %h0|%h0, %h2}"
9186 [(set_attr "type" "alu")
9187 (set_attr "length_immediate" "0")
9188 (set_attr "mode" "QI")])
9189
9190 (define_split
9191 [(set (match_operand 0 "register_operand" "")
9192 (ior (match_operand 1 "register_operand" "")
9193 (match_operand 2 "const_int_operand" "")))
9194 (clobber (reg:CC 17))]
9195 "reload_completed
9196 && QI_REG_P (operands[0])
9197 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9198 && !(INTVAL (operands[2]) & ~(255 << 8))
9199 && GET_MODE (operands[0]) != QImode"
9200 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9201 (ior:SI (zero_extract:SI (match_dup 1)
9202 (const_int 8) (const_int 8))
9203 (match_dup 2)))
9204 (clobber (reg:CC 17))])]
9205 "operands[0] = gen_lowpart (SImode, operands[0]);
9206 operands[1] = gen_lowpart (SImode, operands[1]);
9207 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9208
9209 ;; Since OR can be encoded with sign extended immediate, this is only
9210 ;; profitable when 7th bit is set.
9211 (define_split
9212 [(set (match_operand 0 "register_operand" "")
9213 (ior (match_operand 1 "general_operand" "")
9214 (match_operand 2 "const_int_operand" "")))
9215 (clobber (reg:CC 17))]
9216 "reload_completed
9217 && ANY_QI_REG_P (operands[0])
9218 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9219 && !(INTVAL (operands[2]) & ~255)
9220 && (INTVAL (operands[2]) & 128)
9221 && GET_MODE (operands[0]) != QImode"
9222 [(parallel [(set (strict_low_part (match_dup 0))
9223 (ior:QI (match_dup 1)
9224 (match_dup 2)))
9225 (clobber (reg:CC 17))])]
9226 "operands[0] = gen_lowpart (QImode, operands[0]);
9227 operands[1] = gen_lowpart (QImode, operands[1]);
9228 operands[2] = gen_lowpart (QImode, operands[2]);")
9229 \f
9230 ;; Logical XOR instructions
9231
9232 ;; %%% This used to optimize known byte-wide and operations to memory.
9233 ;; If this is considered useful, it should be done with splitters.
9234
9235 (define_expand "xordi3"
9236 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9237 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9238 (match_operand:DI 2 "x86_64_general_operand" "")))
9239 (clobber (reg:CC 17))]
9240 "TARGET_64BIT"
9241 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9242
9243 (define_insn "*xordi_1_rex64"
9244 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9245 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9246 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9247 (clobber (reg:CC 17))]
9248 "TARGET_64BIT
9249 && ix86_binary_operator_ok (XOR, DImode, operands)"
9250 "@
9251 xor{q}\t{%2, %0|%0, %2}
9252 xor{q}\t{%2, %0|%0, %2}"
9253 [(set_attr "type" "alu")
9254 (set_attr "mode" "DI,DI")])
9255
9256 (define_insn "*xordi_2_rex64"
9257 [(set (reg 17)
9258 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9259 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9260 (const_int 0)))
9261 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9262 (xor:DI (match_dup 1) (match_dup 2)))]
9263 "TARGET_64BIT
9264 && ix86_match_ccmode (insn, CCNOmode)
9265 && ix86_binary_operator_ok (XOR, DImode, operands)"
9266 "@
9267 xor{q}\t{%2, %0|%0, %2}
9268 xor{q}\t{%2, %0|%0, %2}"
9269 [(set_attr "type" "alu")
9270 (set_attr "mode" "DI,DI")])
9271
9272 (define_insn "*xordi_3_rex64"
9273 [(set (reg 17)
9274 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9275 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9276 (const_int 0)))
9277 (clobber (match_scratch:DI 0 "=r"))]
9278 "TARGET_64BIT
9279 && ix86_match_ccmode (insn, CCNOmode)
9280 && ix86_binary_operator_ok (XOR, DImode, operands)"
9281 "xor{q}\t{%2, %0|%0, %2}"
9282 [(set_attr "type" "alu")
9283 (set_attr "mode" "DI")])
9284
9285 (define_expand "xorsi3"
9286 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9287 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9288 (match_operand:SI 2 "general_operand" "")))
9289 (clobber (reg:CC 17))]
9290 ""
9291 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9292
9293 (define_insn "*xorsi_1"
9294 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9295 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9296 (match_operand:SI 2 "general_operand" "ri,rm")))
9297 (clobber (reg:CC 17))]
9298 "ix86_binary_operator_ok (XOR, SImode, operands)"
9299 "xor{l}\t{%2, %0|%0, %2}"
9300 [(set_attr "type" "alu")
9301 (set_attr "mode" "SI")])
9302
9303 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9304 ;; Add speccase for immediates
9305 (define_insn "*xorsi_1_zext"
9306 [(set (match_operand:DI 0 "register_operand" "=r")
9307 (zero_extend:DI
9308 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9309 (match_operand:SI 2 "general_operand" "rim"))))
9310 (clobber (reg:CC 17))]
9311 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9312 "xor{l}\t{%2, %k0|%k0, %2}"
9313 [(set_attr "type" "alu")
9314 (set_attr "mode" "SI")])
9315
9316 (define_insn "*xorsi_1_zext_imm"
9317 [(set (match_operand:DI 0 "register_operand" "=r")
9318 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9319 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9320 (clobber (reg:CC 17))]
9321 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9322 "xor{l}\t{%2, %k0|%k0, %2}"
9323 [(set_attr "type" "alu")
9324 (set_attr "mode" "SI")])
9325
9326 (define_insn "*xorsi_2"
9327 [(set (reg 17)
9328 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9329 (match_operand:SI 2 "general_operand" "rim,ri"))
9330 (const_int 0)))
9331 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9332 (xor:SI (match_dup 1) (match_dup 2)))]
9333 "ix86_match_ccmode (insn, CCNOmode)
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 ;; ??? Special case for immediate operand is missing - it is tricky.
9341 (define_insn "*xorsi_2_zext"
9342 [(set (reg 17)
9343 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9344 (match_operand:SI 2 "general_operand" "rim"))
9345 (const_int 0)))
9346 (set (match_operand:DI 0 "register_operand" "=r")
9347 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9348 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9349 && ix86_binary_operator_ok (XOR, SImode, operands)"
9350 "xor{l}\t{%2, %k0|%k0, %2}"
9351 [(set_attr "type" "alu")
9352 (set_attr "mode" "SI")])
9353
9354 (define_insn "*xorsi_2_zext_imm"
9355 [(set (reg 17)
9356 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9357 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9358 (const_int 0)))
9359 (set (match_operand:DI 0 "register_operand" "=r")
9360 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9361 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9362 && ix86_binary_operator_ok (XOR, SImode, operands)"
9363 "xor{l}\t{%2, %k0|%k0, %2}"
9364 [(set_attr "type" "alu")
9365 (set_attr "mode" "SI")])
9366
9367 (define_insn "*xorsi_3"
9368 [(set (reg 17)
9369 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9370 (match_operand:SI 2 "general_operand" "rim"))
9371 (const_int 0)))
9372 (clobber (match_scratch:SI 0 "=r"))]
9373 "ix86_match_ccmode (insn, CCNOmode)
9374 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9375 "xor{l}\t{%2, %0|%0, %2}"
9376 [(set_attr "type" "alu")
9377 (set_attr "mode" "SI")])
9378
9379 (define_expand "xorhi3"
9380 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9381 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9382 (match_operand:HI 2 "general_operand" "")))
9383 (clobber (reg:CC 17))]
9384 "TARGET_HIMODE_MATH"
9385 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9386
9387 (define_insn "*xorhi_1"
9388 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9389 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9390 (match_operand:HI 2 "general_operand" "rmi,ri")))
9391 (clobber (reg:CC 17))]
9392 "ix86_binary_operator_ok (XOR, HImode, operands)"
9393 "xor{w}\t{%2, %0|%0, %2}"
9394 [(set_attr "type" "alu")
9395 (set_attr "mode" "HI")])
9396
9397 (define_insn "*xorhi_2"
9398 [(set (reg 17)
9399 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9400 (match_operand:HI 2 "general_operand" "rim,ri"))
9401 (const_int 0)))
9402 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9403 (xor:HI (match_dup 1) (match_dup 2)))]
9404 "ix86_match_ccmode (insn, CCNOmode)
9405 && ix86_binary_operator_ok (XOR, HImode, operands)"
9406 "xor{w}\t{%2, %0|%0, %2}"
9407 [(set_attr "type" "alu")
9408 (set_attr "mode" "HI")])
9409
9410 (define_insn "*xorhi_3"
9411 [(set (reg 17)
9412 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9413 (match_operand:HI 2 "general_operand" "rim"))
9414 (const_int 0)))
9415 (clobber (match_scratch:HI 0 "=r"))]
9416 "ix86_match_ccmode (insn, CCNOmode)
9417 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9418 "xor{w}\t{%2, %0|%0, %2}"
9419 [(set_attr "type" "alu")
9420 (set_attr "mode" "HI")])
9421
9422 (define_expand "xorqi3"
9423 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9424 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9425 (match_operand:QI 2 "general_operand" "")))
9426 (clobber (reg:CC 17))]
9427 "TARGET_QIMODE_MATH"
9428 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9429
9430 ;; %%% Potential partial reg stall on alternative 2. What to do?
9431 (define_insn "*xorqi_1"
9432 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9433 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9434 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9435 (clobber (reg:CC 17))]
9436 "ix86_binary_operator_ok (XOR, QImode, operands)"
9437 "@
9438 xor{b}\t{%2, %0|%0, %2}
9439 xor{b}\t{%2, %0|%0, %2}
9440 xor{l}\t{%k2, %k0|%k0, %k2}"
9441 [(set_attr "type" "alu")
9442 (set_attr "mode" "QI,QI,SI")])
9443
9444 (define_insn "*xorqi_1_slp"
9445 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9446 (xor:QI (match_dup 0)
9447 (match_operand:QI 1 "general_operand" "qi,qmi")))
9448 (clobber (reg:CC 17))]
9449 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9450 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9451 "xor{b}\t{%1, %0|%0, %1}"
9452 [(set_attr "type" "alu1")
9453 (set_attr "mode" "QI")])
9454
9455 (define_insn "xorqi_ext_0"
9456 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9457 (const_int 8)
9458 (const_int 8))
9459 (xor:SI
9460 (zero_extract:SI
9461 (match_operand 1 "ext_register_operand" "0")
9462 (const_int 8)
9463 (const_int 8))
9464 (match_operand 2 "const_int_operand" "n")))
9465 (clobber (reg:CC 17))]
9466 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9467 "xor{b}\t{%2, %h0|%h0, %2}"
9468 [(set_attr "type" "alu")
9469 (set_attr "length_immediate" "1")
9470 (set_attr "mode" "QI")])
9471
9472 (define_insn "*xorqi_ext_1"
9473 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9474 (const_int 8)
9475 (const_int 8))
9476 (xor:SI
9477 (zero_extract:SI
9478 (match_operand 1 "ext_register_operand" "0")
9479 (const_int 8)
9480 (const_int 8))
9481 (zero_extend:SI
9482 (match_operand:QI 2 "general_operand" "Qm"))))
9483 (clobber (reg:CC 17))]
9484 "!TARGET_64BIT
9485 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9486 "xor{b}\t{%2, %h0|%h0, %2}"
9487 [(set_attr "type" "alu")
9488 (set_attr "length_immediate" "0")
9489 (set_attr "mode" "QI")])
9490
9491 (define_insn "*xorqi_ext_1_rex64"
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 (zero_extend:SI
9501 (match_operand 2 "ext_register_operand" "Q"))))
9502 (clobber (reg:CC 17))]
9503 "TARGET_64BIT
9504 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9505 "xor{b}\t{%2, %h0|%h0, %2}"
9506 [(set_attr "type" "alu")
9507 (set_attr "length_immediate" "0")
9508 (set_attr "mode" "QI")])
9509
9510 (define_insn "*xorqi_ext_2"
9511 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9512 (const_int 8)
9513 (const_int 8))
9514 (xor:SI
9515 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9516 (const_int 8)
9517 (const_int 8))
9518 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9519 (const_int 8)
9520 (const_int 8))))
9521 (clobber (reg:CC 17))]
9522 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9523 "xor{b}\t{%h2, %h0|%h0, %h2}"
9524 [(set_attr "type" "alu")
9525 (set_attr "length_immediate" "0")
9526 (set_attr "mode" "QI")])
9527
9528 (define_insn "*xorqi_cc_1"
9529 [(set (reg 17)
9530 (compare
9531 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9532 (match_operand:QI 2 "general_operand" "qim,qi"))
9533 (const_int 0)))
9534 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9535 (xor:QI (match_dup 1) (match_dup 2)))]
9536 "ix86_match_ccmode (insn, CCNOmode)
9537 && ix86_binary_operator_ok (XOR, QImode, operands)"
9538 "xor{b}\t{%2, %0|%0, %2}"
9539 [(set_attr "type" "alu")
9540 (set_attr "mode" "QI")])
9541
9542 (define_insn "*xorqi_2_slp"
9543 [(set (reg 17)
9544 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9545 (match_operand:QI 1 "general_operand" "qim,qi"))
9546 (const_int 0)))
9547 (set (strict_low_part (match_dup 0))
9548 (xor:QI (match_dup 0) (match_dup 1)))]
9549 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9550 && ix86_match_ccmode (insn, CCNOmode)
9551 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9552 "xor{b}\t{%1, %0|%0, %1}"
9553 [(set_attr "type" "alu1")
9554 (set_attr "mode" "QI")])
9555
9556 (define_insn "*xorqi_cc_2"
9557 [(set (reg 17)
9558 (compare
9559 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9560 (match_operand:QI 2 "general_operand" "qim"))
9561 (const_int 0)))
9562 (clobber (match_scratch:QI 0 "=q"))]
9563 "ix86_match_ccmode (insn, CCNOmode)
9564 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9565 "xor{b}\t{%2, %0|%0, %2}"
9566 [(set_attr "type" "alu")
9567 (set_attr "mode" "QI")])
9568
9569 (define_insn "*xorqi_cc_ext_1"
9570 [(set (reg 17)
9571 (compare
9572 (xor:SI
9573 (zero_extract:SI
9574 (match_operand 1 "ext_register_operand" "0")
9575 (const_int 8)
9576 (const_int 8))
9577 (match_operand:QI 2 "general_operand" "qmn"))
9578 (const_int 0)))
9579 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9580 (const_int 8)
9581 (const_int 8))
9582 (xor:SI
9583 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9584 (match_dup 2)))]
9585 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9586 "xor{b}\t{%2, %h0|%h0, %2}"
9587 [(set_attr "type" "alu")
9588 (set_attr "mode" "QI")])
9589
9590 (define_insn "*xorqi_cc_ext_1_rex64"
9591 [(set (reg 17)
9592 (compare
9593 (xor:SI
9594 (zero_extract:SI
9595 (match_operand 1 "ext_register_operand" "0")
9596 (const_int 8)
9597 (const_int 8))
9598 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9599 (const_int 0)))
9600 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9601 (const_int 8)
9602 (const_int 8))
9603 (xor:SI
9604 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9605 (match_dup 2)))]
9606 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9607 "xor{b}\t{%2, %h0|%h0, %2}"
9608 [(set_attr "type" "alu")
9609 (set_attr "mode" "QI")])
9610
9611 (define_expand "xorqi_cc_ext_1"
9612 [(parallel [
9613 (set (reg:CCNO 17)
9614 (compare:CCNO
9615 (xor:SI
9616 (zero_extract:SI
9617 (match_operand 1 "ext_register_operand" "")
9618 (const_int 8)
9619 (const_int 8))
9620 (match_operand:QI 2 "general_operand" ""))
9621 (const_int 0)))
9622 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9623 (const_int 8)
9624 (const_int 8))
9625 (xor:SI
9626 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9627 (match_dup 2)))])]
9628 ""
9629 "")
9630
9631 (define_split
9632 [(set (match_operand 0 "register_operand" "")
9633 (xor (match_operand 1 "register_operand" "")
9634 (match_operand 2 "const_int_operand" "")))
9635 (clobber (reg:CC 17))]
9636 "reload_completed
9637 && QI_REG_P (operands[0])
9638 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9639 && !(INTVAL (operands[2]) & ~(255 << 8))
9640 && GET_MODE (operands[0]) != QImode"
9641 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9642 (xor:SI (zero_extract:SI (match_dup 1)
9643 (const_int 8) (const_int 8))
9644 (match_dup 2)))
9645 (clobber (reg:CC 17))])]
9646 "operands[0] = gen_lowpart (SImode, operands[0]);
9647 operands[1] = gen_lowpart (SImode, operands[1]);
9648 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9649
9650 ;; Since XOR can be encoded with sign extended immediate, this is only
9651 ;; profitable when 7th bit is set.
9652 (define_split
9653 [(set (match_operand 0 "register_operand" "")
9654 (xor (match_operand 1 "general_operand" "")
9655 (match_operand 2 "const_int_operand" "")))
9656 (clobber (reg:CC 17))]
9657 "reload_completed
9658 && ANY_QI_REG_P (operands[0])
9659 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9660 && !(INTVAL (operands[2]) & ~255)
9661 && (INTVAL (operands[2]) & 128)
9662 && GET_MODE (operands[0]) != QImode"
9663 [(parallel [(set (strict_low_part (match_dup 0))
9664 (xor:QI (match_dup 1)
9665 (match_dup 2)))
9666 (clobber (reg:CC 17))])]
9667 "operands[0] = gen_lowpart (QImode, operands[0]);
9668 operands[1] = gen_lowpart (QImode, operands[1]);
9669 operands[2] = gen_lowpart (QImode, operands[2]);")
9670 \f
9671 ;; Negation instructions
9672
9673 (define_expand "negdi2"
9674 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9675 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9676 (clobber (reg:CC 17))])]
9677 ""
9678 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9679
9680 (define_insn "*negdi2_1"
9681 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9682 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9683 (clobber (reg:CC 17))]
9684 "!TARGET_64BIT
9685 && ix86_unary_operator_ok (NEG, DImode, operands)"
9686 "#")
9687
9688 (define_split
9689 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9690 (neg:DI (match_operand:DI 1 "general_operand" "")))
9691 (clobber (reg:CC 17))]
9692 "!TARGET_64BIT && reload_completed"
9693 [(parallel
9694 [(set (reg:CCZ 17)
9695 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9696 (set (match_dup 0) (neg:SI (match_dup 2)))])
9697 (parallel
9698 [(set (match_dup 1)
9699 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9700 (match_dup 3))
9701 (const_int 0)))
9702 (clobber (reg:CC 17))])
9703 (parallel
9704 [(set (match_dup 1)
9705 (neg:SI (match_dup 1)))
9706 (clobber (reg:CC 17))])]
9707 "split_di (operands+1, 1, operands+2, operands+3);
9708 split_di (operands+0, 1, operands+0, operands+1);")
9709
9710 (define_insn "*negdi2_1_rex64"
9711 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9712 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9713 (clobber (reg:CC 17))]
9714 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9715 "neg{q}\t%0"
9716 [(set_attr "type" "negnot")
9717 (set_attr "mode" "DI")])
9718
9719 ;; The problem with neg is that it does not perform (compare x 0),
9720 ;; it really performs (compare 0 x), which leaves us with the zero
9721 ;; flag being the only useful item.
9722
9723 (define_insn "*negdi2_cmpz_rex64"
9724 [(set (reg:CCZ 17)
9725 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9726 (const_int 0)))
9727 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9728 (neg:DI (match_dup 1)))]
9729 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9730 "neg{q}\t%0"
9731 [(set_attr "type" "negnot")
9732 (set_attr "mode" "DI")])
9733
9734
9735 (define_expand "negsi2"
9736 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9737 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9738 (clobber (reg:CC 17))])]
9739 ""
9740 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9741
9742 (define_insn "*negsi2_1"
9743 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9744 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9745 (clobber (reg:CC 17))]
9746 "ix86_unary_operator_ok (NEG, SImode, operands)"
9747 "neg{l}\t%0"
9748 [(set_attr "type" "negnot")
9749 (set_attr "mode" "SI")])
9750
9751 ;; Combine is quite creative about this pattern.
9752 (define_insn "*negsi2_1_zext"
9753 [(set (match_operand:DI 0 "register_operand" "=r")
9754 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9755 (const_int 32)))
9756 (const_int 32)))
9757 (clobber (reg:CC 17))]
9758 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9759 "neg{l}\t%k0"
9760 [(set_attr "type" "negnot")
9761 (set_attr "mode" "SI")])
9762
9763 ;; The problem with neg is that it does not perform (compare x 0),
9764 ;; it really performs (compare 0 x), which leaves us with the zero
9765 ;; flag being the only useful item.
9766
9767 (define_insn "*negsi2_cmpz"
9768 [(set (reg:CCZ 17)
9769 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9770 (const_int 0)))
9771 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9772 (neg:SI (match_dup 1)))]
9773 "ix86_unary_operator_ok (NEG, SImode, operands)"
9774 "neg{l}\t%0"
9775 [(set_attr "type" "negnot")
9776 (set_attr "mode" "SI")])
9777
9778 (define_insn "*negsi2_cmpz_zext"
9779 [(set (reg:CCZ 17)
9780 (compare:CCZ (lshiftrt:DI
9781 (neg:DI (ashift:DI
9782 (match_operand:DI 1 "register_operand" "0")
9783 (const_int 32)))
9784 (const_int 32))
9785 (const_int 0)))
9786 (set (match_operand:DI 0 "register_operand" "=r")
9787 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9788 (const_int 32)))
9789 (const_int 32)))]
9790 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9791 "neg{l}\t%k0"
9792 [(set_attr "type" "negnot")
9793 (set_attr "mode" "SI")])
9794
9795 (define_expand "neghi2"
9796 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9797 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9798 (clobber (reg:CC 17))])]
9799 "TARGET_HIMODE_MATH"
9800 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9801
9802 (define_insn "*neghi2_1"
9803 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9804 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9805 (clobber (reg:CC 17))]
9806 "ix86_unary_operator_ok (NEG, HImode, operands)"
9807 "neg{w}\t%0"
9808 [(set_attr "type" "negnot")
9809 (set_attr "mode" "HI")])
9810
9811 (define_insn "*neghi2_cmpz"
9812 [(set (reg:CCZ 17)
9813 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9814 (const_int 0)))
9815 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9816 (neg:HI (match_dup 1)))]
9817 "ix86_unary_operator_ok (NEG, HImode, operands)"
9818 "neg{w}\t%0"
9819 [(set_attr "type" "negnot")
9820 (set_attr "mode" "HI")])
9821
9822 (define_expand "negqi2"
9823 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9824 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9825 (clobber (reg:CC 17))])]
9826 "TARGET_QIMODE_MATH"
9827 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9828
9829 (define_insn "*negqi2_1"
9830 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9831 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9832 (clobber (reg:CC 17))]
9833 "ix86_unary_operator_ok (NEG, QImode, operands)"
9834 "neg{b}\t%0"
9835 [(set_attr "type" "negnot")
9836 (set_attr "mode" "QI")])
9837
9838 (define_insn "*negqi2_cmpz"
9839 [(set (reg:CCZ 17)
9840 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9841 (const_int 0)))
9842 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9843 (neg:QI (match_dup 1)))]
9844 "ix86_unary_operator_ok (NEG, QImode, operands)"
9845 "neg{b}\t%0"
9846 [(set_attr "type" "negnot")
9847 (set_attr "mode" "QI")])
9848
9849 ;; Changing of sign for FP values is doable using integer unit too.
9850
9851 (define_expand "negsf2"
9852 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9853 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9854 (clobber (reg:CC 17))])]
9855 "TARGET_80387"
9856 "if (TARGET_SSE)
9857 {
9858 /* In case operand is in memory, we will not use SSE. */
9859 if (memory_operand (operands[0], VOIDmode)
9860 && rtx_equal_p (operands[0], operands[1]))
9861 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9862 else
9863 {
9864 /* Using SSE is tricky, since we need bitwise negation of -0
9865 in register. */
9866 rtx reg = gen_reg_rtx (SFmode);
9867 rtx dest = operands[0];
9868 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9869
9870 operands[1] = force_reg (SFmode, operands[1]);
9871 operands[0] = force_reg (SFmode, operands[0]);
9872 reg = force_reg (V4SFmode,
9873 gen_rtx_CONST_VECTOR (V4SFmode,
9874 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9875 CONST0_RTX (SFmode),
9876 CONST0_RTX (SFmode))));
9877 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9878 if (dest != operands[0])
9879 emit_move_insn (dest, operands[0]);
9880 }
9881 DONE;
9882 }
9883 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9884
9885 (define_insn "negsf2_memory"
9886 [(set (match_operand:SF 0 "memory_operand" "=m")
9887 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9888 (clobber (reg:CC 17))]
9889 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9890 "#")
9891
9892 (define_insn "negsf2_ifs"
9893 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9894 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9895 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9896 (clobber (reg:CC 17))]
9897 "TARGET_SSE
9898 && (reload_in_progress || reload_completed
9899 || (register_operand (operands[0], VOIDmode)
9900 && register_operand (operands[1], VOIDmode)))"
9901 "#")
9902
9903 (define_split
9904 [(set (match_operand:SF 0 "memory_operand" "")
9905 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9906 (use (match_operand:SF 2 "" ""))
9907 (clobber (reg:CC 17))]
9908 ""
9909 [(parallel [(set (match_dup 0)
9910 (neg:SF (match_dup 1)))
9911 (clobber (reg:CC 17))])])
9912
9913 (define_split
9914 [(set (match_operand:SF 0 "register_operand" "")
9915 (neg:SF (match_operand:SF 1 "register_operand" "")))
9916 (use (match_operand:V4SF 2 "" ""))
9917 (clobber (reg:CC 17))]
9918 "reload_completed && !SSE_REG_P (operands[0])"
9919 [(parallel [(set (match_dup 0)
9920 (neg:SF (match_dup 1)))
9921 (clobber (reg:CC 17))])])
9922
9923 (define_split
9924 [(set (match_operand:SF 0 "register_operand" "")
9925 (neg:SF (match_operand:SF 1 "register_operand" "")))
9926 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9927 (clobber (reg:CC 17))]
9928 "reload_completed && SSE_REG_P (operands[0])"
9929 [(set (subreg:TI (match_dup 0) 0)
9930 (xor:TI (match_dup 1)
9931 (match_dup 2)))]
9932 {
9933 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9934 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9935 if (operands_match_p (operands[0], operands[2]))
9936 {
9937 rtx tmp;
9938 tmp = operands[1];
9939 operands[1] = operands[2];
9940 operands[2] = tmp;
9941 }
9942 })
9943
9944
9945 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9946 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9947 ;; to itself.
9948 (define_insn "*negsf2_if"
9949 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9950 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9951 (clobber (reg:CC 17))]
9952 "TARGET_80387 && !TARGET_SSE
9953 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9954 "#")
9955
9956 (define_split
9957 [(set (match_operand:SF 0 "fp_register_operand" "")
9958 (neg:SF (match_operand:SF 1 "register_operand" "")))
9959 (clobber (reg:CC 17))]
9960 "TARGET_80387 && reload_completed"
9961 [(set (match_dup 0)
9962 (neg:SF (match_dup 1)))]
9963 "")
9964
9965 (define_split
9966 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9967 (neg:SF (match_operand:SF 1 "register_operand" "")))
9968 (clobber (reg:CC 17))]
9969 "TARGET_80387 && reload_completed"
9970 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9971 (clobber (reg:CC 17))])]
9972 "operands[1] = gen_int_mode (0x80000000, SImode);
9973 operands[0] = gen_lowpart (SImode, operands[0]);")
9974
9975 (define_split
9976 [(set (match_operand 0 "memory_operand" "")
9977 (neg (match_operand 1 "memory_operand" "")))
9978 (clobber (reg:CC 17))]
9979 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9980 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9981 (clobber (reg:CC 17))])]
9982 {
9983 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9984
9985 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9986 if (size >= 12)
9987 size = 10;
9988 operands[0] = adjust_address (operands[0], QImode, size - 1);
9989 operands[1] = gen_int_mode (0x80, QImode);
9990 })
9991
9992 (define_expand "negdf2"
9993 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9994 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9995 (clobber (reg:CC 17))])]
9996 "TARGET_80387"
9997 "if (TARGET_SSE2)
9998 {
9999 /* In case operand is in memory, we will not use SSE. */
10000 if (memory_operand (operands[0], VOIDmode)
10001 && rtx_equal_p (operands[0], operands[1]))
10002 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
10003 else
10004 {
10005 /* Using SSE is tricky, since we need bitwise negation of -0
10006 in register. */
10007 rtx reg;
10008 #if HOST_BITS_PER_WIDE_INT >= 64
10009 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
10010 #else
10011 rtx imm = immed_double_const (0, 0x80000000, DImode);
10012 #endif
10013 rtx dest = operands[0];
10014
10015 operands[1] = force_reg (DFmode, operands[1]);
10016 operands[0] = force_reg (DFmode, operands[0]);
10017 imm = gen_lowpart (DFmode, imm);
10018 reg = force_reg (V2DFmode,
10019 gen_rtx_CONST_VECTOR (V2DFmode,
10020 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10021 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
10022 if (dest != operands[0])
10023 emit_move_insn (dest, operands[0]);
10024 }
10025 DONE;
10026 }
10027 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
10028
10029 (define_insn "negdf2_memory"
10030 [(set (match_operand:DF 0 "memory_operand" "=m")
10031 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
10032 (clobber (reg:CC 17))]
10033 "ix86_unary_operator_ok (NEG, DFmode, operands)"
10034 "#")
10035
10036 (define_insn "negdf2_ifs"
10037 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
10038 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10039 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10040 (clobber (reg:CC 17))]
10041 "!TARGET_64BIT && TARGET_SSE2
10042 && (reload_in_progress || reload_completed
10043 || (register_operand (operands[0], VOIDmode)
10044 && register_operand (operands[1], VOIDmode)))"
10045 "#")
10046
10047 (define_insn "*negdf2_ifs_rex64"
10048 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
10049 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10050 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10051 (clobber (reg:CC 17))]
10052 "TARGET_64BIT && TARGET_SSE2
10053 && (reload_in_progress || reload_completed
10054 || (register_operand (operands[0], VOIDmode)
10055 && register_operand (operands[1], VOIDmode)))"
10056 "#")
10057
10058 (define_split
10059 [(set (match_operand:DF 0 "memory_operand" "")
10060 (neg:DF (match_operand:DF 1 "memory_operand" "")))
10061 (use (match_operand:V2DF 2 "" ""))
10062 (clobber (reg:CC 17))]
10063 ""
10064 [(parallel [(set (match_dup 0)
10065 (neg:DF (match_dup 1)))
10066 (clobber (reg:CC 17))])])
10067
10068 (define_split
10069 [(set (match_operand:DF 0 "register_operand" "")
10070 (neg:DF (match_operand:DF 1 "register_operand" "")))
10071 (use (match_operand:V2DF 2 "" ""))
10072 (clobber (reg:CC 17))]
10073 "reload_completed && !SSE_REG_P (operands[0])
10074 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
10075 [(parallel [(set (match_dup 0)
10076 (neg:DF (match_dup 1)))
10077 (clobber (reg:CC 17))])])
10078
10079 (define_split
10080 [(set (match_operand:DF 0 "register_operand" "")
10081 (neg:DF (match_operand:DF 1 "register_operand" "")))
10082 (use (match_operand:V2DF 2 "" ""))
10083 (clobber (reg:CC 17))]
10084 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
10085 [(parallel [(set (match_dup 0)
10086 (xor:DI (match_dup 1) (match_dup 2)))
10087 (clobber (reg:CC 17))])]
10088 "operands[0] = gen_lowpart (DImode, operands[0]);
10089 operands[1] = gen_lowpart (DImode, operands[1]);
10090 operands[2] = gen_lowpart (DImode, operands[2]);")
10091
10092 (define_split
10093 [(set (match_operand:DF 0 "register_operand" "")
10094 (neg:DF (match_operand:DF 1 "register_operand" "")))
10095 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10096 (clobber (reg:CC 17))]
10097 "reload_completed && SSE_REG_P (operands[0])"
10098 [(set (subreg:TI (match_dup 0) 0)
10099 (xor:TI (match_dup 1)
10100 (match_dup 2)))]
10101 {
10102 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10103 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10104 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10105 /* Avoid possible reformatting on the operands. */
10106 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10107 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10108 if (operands_match_p (operands[0], operands[2]))
10109 {
10110 rtx tmp;
10111 tmp = operands[1];
10112 operands[1] = operands[2];
10113 operands[2] = tmp;
10114 }
10115 })
10116
10117 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10118 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10119 ;; to itself.
10120 (define_insn "*negdf2_if"
10121 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10122 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10123 (clobber (reg:CC 17))]
10124 "!TARGET_64BIT && TARGET_80387
10125 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10126 "#")
10127
10128 ;; FIXME: We should to allow integer registers here. Problem is that
10129 ;; we need another scratch register to get constant from.
10130 ;; Forcing constant to mem if no register available in peep2 should be
10131 ;; safe even for PIC mode, because of RIP relative addressing.
10132 (define_insn "*negdf2_if_rex64"
10133 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10134 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10135 (clobber (reg:CC 17))]
10136 "TARGET_64BIT && TARGET_80387
10137 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10138 "#")
10139
10140 (define_split
10141 [(set (match_operand:DF 0 "fp_register_operand" "")
10142 (neg:DF (match_operand:DF 1 "register_operand" "")))
10143 (clobber (reg:CC 17))]
10144 "TARGET_80387 && reload_completed"
10145 [(set (match_dup 0)
10146 (neg:DF (match_dup 1)))]
10147 "")
10148
10149 (define_split
10150 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10151 (neg:DF (match_operand:DF 1 "register_operand" "")))
10152 (clobber (reg:CC 17))]
10153 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10154 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
10155 (clobber (reg:CC 17))])]
10156 "operands[4] = gen_int_mode (0x80000000, SImode);
10157 split_di (operands+0, 1, operands+2, operands+3);")
10158
10159 (define_expand "negxf2"
10160 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10161 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10162 (clobber (reg:CC 17))])]
10163 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10164 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
10165
10166 (define_expand "negtf2"
10167 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10168 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10169 (clobber (reg:CC 17))])]
10170 "TARGET_80387"
10171 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
10172
10173 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10174 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10175 ;; to itself.
10176 (define_insn "*negxf2_if"
10177 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10178 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10179 (clobber (reg:CC 17))]
10180 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10181 && ix86_unary_operator_ok (NEG, XFmode, operands)"
10182 "#")
10183
10184 (define_split
10185 [(set (match_operand:XF 0 "fp_register_operand" "")
10186 (neg:XF (match_operand:XF 1 "register_operand" "")))
10187 (clobber (reg:CC 17))]
10188 "TARGET_80387 && reload_completed"
10189 [(set (match_dup 0)
10190 (neg:XF (match_dup 1)))]
10191 "")
10192
10193 (define_split
10194 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10195 (neg:XF (match_operand:XF 1 "register_operand" "")))
10196 (clobber (reg:CC 17))]
10197 "TARGET_80387 && reload_completed"
10198 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10199 (clobber (reg:CC 17))])]
10200 "operands[1] = GEN_INT (0x8000);
10201 operands[0] = gen_rtx_REG (SImode,
10202 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10203
10204 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10205 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10206 ;; to itself.
10207 (define_insn "*negtf2_if"
10208 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10209 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10210 (clobber (reg:CC 17))]
10211 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
10212 "#")
10213
10214 (define_split
10215 [(set (match_operand:TF 0 "fp_register_operand" "")
10216 (neg:TF (match_operand:TF 1 "register_operand" "")))
10217 (clobber (reg:CC 17))]
10218 "TARGET_80387 && reload_completed"
10219 [(set (match_dup 0)
10220 (neg:TF (match_dup 1)))]
10221 "")
10222
10223 (define_split
10224 [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
10225 (neg:TF (match_operand:TF 1 "register_operand" "")))
10226 (clobber (reg:CC 17))]
10227 "TARGET_80387 && reload_completed"
10228 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10229 (clobber (reg:CC 17))])]
10230 "operands[1] = GEN_INT (0x8000);
10231 operands[0] = gen_rtx_REG (SImode,
10232 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10233
10234 ;; Conditionalize these after reload. If they matches before reload, we
10235 ;; lose the clobber and ability to use integer instructions.
10236
10237 (define_insn "*negsf2_1"
10238 [(set (match_operand:SF 0 "register_operand" "=f")
10239 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10240 "TARGET_80387 && reload_completed"
10241 "fchs"
10242 [(set_attr "type" "fsgn")
10243 (set_attr "mode" "SF")
10244 (set_attr "ppro_uops" "few")])
10245
10246 (define_insn "*negdf2_1"
10247 [(set (match_operand:DF 0 "register_operand" "=f")
10248 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10249 "TARGET_80387 && reload_completed"
10250 "fchs"
10251 [(set_attr "type" "fsgn")
10252 (set_attr "mode" "DF")
10253 (set_attr "ppro_uops" "few")])
10254
10255 (define_insn "*negextendsfdf2"
10256 [(set (match_operand:DF 0 "register_operand" "=f")
10257 (neg:DF (float_extend:DF
10258 (match_operand:SF 1 "register_operand" "0"))))]
10259 "TARGET_80387"
10260 "fchs"
10261 [(set_attr "type" "fsgn")
10262 (set_attr "mode" "DF")
10263 (set_attr "ppro_uops" "few")])
10264
10265 (define_insn "*negxf2_1"
10266 [(set (match_operand:XF 0 "register_operand" "=f")
10267 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10268 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10269 "fchs"
10270 [(set_attr "type" "fsgn")
10271 (set_attr "mode" "XF")
10272 (set_attr "ppro_uops" "few")])
10273
10274 (define_insn "*negextenddfxf2"
10275 [(set (match_operand:XF 0 "register_operand" "=f")
10276 (neg:XF (float_extend:XF
10277 (match_operand:DF 1 "register_operand" "0"))))]
10278 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10279 "fchs"
10280 [(set_attr "type" "fsgn")
10281 (set_attr "mode" "XF")
10282 (set_attr "ppro_uops" "few")])
10283
10284 (define_insn "*negextendsfxf2"
10285 [(set (match_operand:XF 0 "register_operand" "=f")
10286 (neg:XF (float_extend:XF
10287 (match_operand:SF 1 "register_operand" "0"))))]
10288 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10289 "fchs"
10290 [(set_attr "type" "fsgn")
10291 (set_attr "mode" "XF")
10292 (set_attr "ppro_uops" "few")])
10293
10294 (define_insn "*negtf2_1"
10295 [(set (match_operand:TF 0 "register_operand" "=f")
10296 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
10297 "TARGET_80387 && reload_completed"
10298 "fchs"
10299 [(set_attr "type" "fsgn")
10300 (set_attr "mode" "XF")
10301 (set_attr "ppro_uops" "few")])
10302
10303 (define_insn "*negextenddftf2"
10304 [(set (match_operand:TF 0 "register_operand" "=f")
10305 (neg:TF (float_extend:TF
10306 (match_operand:DF 1 "register_operand" "0"))))]
10307 "TARGET_80387"
10308 "fchs"
10309 [(set_attr "type" "fsgn")
10310 (set_attr "mode" "XF")
10311 (set_attr "ppro_uops" "few")])
10312
10313 (define_insn "*negextendsftf2"
10314 [(set (match_operand:TF 0 "register_operand" "=f")
10315 (neg:TF (float_extend:TF
10316 (match_operand:SF 1 "register_operand" "0"))))]
10317 "TARGET_80387"
10318 "fchs"
10319 [(set_attr "type" "fsgn")
10320 (set_attr "mode" "XF")
10321 (set_attr "ppro_uops" "few")])
10322 \f
10323 ;; Absolute value instructions
10324
10325 (define_expand "abssf2"
10326 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10327 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10328 (clobber (reg:CC 17))])]
10329 "TARGET_80387"
10330 "if (TARGET_SSE)
10331 {
10332 /* In case operand is in memory, we will not use SSE. */
10333 if (memory_operand (operands[0], VOIDmode)
10334 && rtx_equal_p (operands[0], operands[1]))
10335 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10336 else
10337 {
10338 /* Using SSE is tricky, since we need bitwise negation of -0
10339 in register. */
10340 rtx reg = gen_reg_rtx (V4SFmode);
10341 rtx dest = operands[0];
10342 rtx imm;
10343
10344 operands[1] = force_reg (SFmode, operands[1]);
10345 operands[0] = force_reg (SFmode, operands[0]);
10346 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10347 reg = force_reg (V4SFmode,
10348 gen_rtx_CONST_VECTOR (V4SFmode,
10349 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10350 CONST0_RTX (SFmode),
10351 CONST0_RTX (SFmode))));
10352 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10353 if (dest != operands[0])
10354 emit_move_insn (dest, operands[0]);
10355 }
10356 DONE;
10357 }
10358 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10359
10360 (define_insn "abssf2_memory"
10361 [(set (match_operand:SF 0 "memory_operand" "=m")
10362 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10363 (clobber (reg:CC 17))]
10364 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10365 "#")
10366
10367 (define_insn "abssf2_ifs"
10368 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10369 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10370 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10371 (clobber (reg:CC 17))]
10372 "TARGET_SSE
10373 && (reload_in_progress || reload_completed
10374 || (register_operand (operands[0], VOIDmode)
10375 && register_operand (operands[1], VOIDmode)))"
10376 "#")
10377
10378 (define_split
10379 [(set (match_operand:SF 0 "memory_operand" "")
10380 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10381 (use (match_operand:V4SF 2 "" ""))
10382 (clobber (reg:CC 17))]
10383 ""
10384 [(parallel [(set (match_dup 0)
10385 (abs:SF (match_dup 1)))
10386 (clobber (reg:CC 17))])])
10387
10388 (define_split
10389 [(set (match_operand:SF 0 "register_operand" "")
10390 (abs:SF (match_operand:SF 1 "register_operand" "")))
10391 (use (match_operand:V4SF 2 "" ""))
10392 (clobber (reg:CC 17))]
10393 "reload_completed && !SSE_REG_P (operands[0])"
10394 [(parallel [(set (match_dup 0)
10395 (abs:SF (match_dup 1)))
10396 (clobber (reg:CC 17))])])
10397
10398 (define_split
10399 [(set (match_operand:SF 0 "register_operand" "")
10400 (abs:SF (match_operand:SF 1 "register_operand" "")))
10401 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10402 (clobber (reg:CC 17))]
10403 "reload_completed && SSE_REG_P (operands[0])"
10404 [(set (subreg:TI (match_dup 0) 0)
10405 (and:TI (match_dup 1)
10406 (match_dup 2)))]
10407 {
10408 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10409 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10410 if (operands_match_p (operands[0], operands[2]))
10411 {
10412 rtx tmp;
10413 tmp = operands[1];
10414 operands[1] = operands[2];
10415 operands[2] = tmp;
10416 }
10417 })
10418
10419 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10420 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10421 ;; to itself.
10422 (define_insn "*abssf2_if"
10423 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10424 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10425 (clobber (reg:CC 17))]
10426 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10427 "#")
10428
10429 (define_split
10430 [(set (match_operand:SF 0 "fp_register_operand" "")
10431 (abs:SF (match_operand:SF 1 "register_operand" "")))
10432 (clobber (reg:CC 17))]
10433 "TARGET_80387 && reload_completed"
10434 [(set (match_dup 0)
10435 (abs:SF (match_dup 1)))]
10436 "")
10437
10438 (define_split
10439 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10440 (abs:SF (match_operand:SF 1 "register_operand" "")))
10441 (clobber (reg:CC 17))]
10442 "TARGET_80387 && reload_completed"
10443 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10444 (clobber (reg:CC 17))])]
10445 "operands[1] = gen_int_mode (~0x80000000, SImode);
10446 operands[0] = gen_lowpart (SImode, operands[0]);")
10447
10448 (define_split
10449 [(set (match_operand 0 "memory_operand" "")
10450 (abs (match_operand 1 "memory_operand" "")))
10451 (clobber (reg:CC 17))]
10452 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10453 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10454 (clobber (reg:CC 17))])]
10455 {
10456 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10457
10458 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10459 if (size >= 12)
10460 size = 10;
10461 operands[0] = adjust_address (operands[0], QImode, size - 1);
10462 operands[1] = gen_int_mode (~0x80, QImode);
10463 })
10464
10465 (define_expand "absdf2"
10466 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10467 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10468 (clobber (reg:CC 17))])]
10469 "TARGET_80387"
10470 "if (TARGET_SSE2)
10471 {
10472 /* In case operand is in memory, we will not use SSE. */
10473 if (memory_operand (operands[0], VOIDmode)
10474 && rtx_equal_p (operands[0], operands[1]))
10475 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10476 else
10477 {
10478 /* Using SSE is tricky, since we need bitwise negation of -0
10479 in register. */
10480 rtx reg = gen_reg_rtx (V2DFmode);
10481 #if HOST_BITS_PER_WIDE_INT >= 64
10482 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10483 #else
10484 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10485 #endif
10486 rtx dest = operands[0];
10487
10488 operands[1] = force_reg (DFmode, operands[1]);
10489 operands[0] = force_reg (DFmode, operands[0]);
10490
10491 /* Produce LONG_DOUBLE with the proper immediate argument. */
10492 imm = gen_lowpart (DFmode, imm);
10493 reg = force_reg (V2DFmode,
10494 gen_rtx_CONST_VECTOR (V2DFmode,
10495 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10496 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10497 if (dest != operands[0])
10498 emit_move_insn (dest, operands[0]);
10499 }
10500 DONE;
10501 }
10502 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10503
10504 (define_insn "absdf2_memory"
10505 [(set (match_operand:DF 0 "memory_operand" "=m")
10506 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10507 (clobber (reg:CC 17))]
10508 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10509 "#")
10510
10511 (define_insn "absdf2_ifs"
10512 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10513 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10514 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10515 (clobber (reg:CC 17))]
10516 "!TARGET_64BIT && TARGET_SSE2
10517 && (reload_in_progress || reload_completed
10518 || (register_operand (operands[0], VOIDmode)
10519 && register_operand (operands[1], VOIDmode)))"
10520 "#")
10521
10522 (define_insn "*absdf2_ifs_rex64"
10523 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10524 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10525 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10526 (clobber (reg:CC 17))]
10527 "TARGET_64BIT && TARGET_SSE2
10528 && (reload_in_progress || reload_completed
10529 || (register_operand (operands[0], VOIDmode)
10530 && register_operand (operands[1], VOIDmode)))"
10531 "#")
10532
10533 (define_split
10534 [(set (match_operand:DF 0 "memory_operand" "")
10535 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10536 (use (match_operand:V2DF 2 "" ""))
10537 (clobber (reg:CC 17))]
10538 ""
10539 [(parallel [(set (match_dup 0)
10540 (abs:DF (match_dup 1)))
10541 (clobber (reg:CC 17))])])
10542
10543 (define_split
10544 [(set (match_operand:DF 0 "register_operand" "")
10545 (abs:DF (match_operand:DF 1 "register_operand" "")))
10546 (use (match_operand:V2DF 2 "" ""))
10547 (clobber (reg:CC 17))]
10548 "reload_completed && !SSE_REG_P (operands[0])"
10549 [(parallel [(set (match_dup 0)
10550 (abs:DF (match_dup 1)))
10551 (clobber (reg:CC 17))])])
10552
10553 (define_split
10554 [(set (match_operand:DF 0 "register_operand" "")
10555 (abs:DF (match_operand:DF 1 "register_operand" "")))
10556 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10557 (clobber (reg:CC 17))]
10558 "reload_completed && SSE_REG_P (operands[0])"
10559 [(set (subreg:TI (match_dup 0) 0)
10560 (and:TI (match_dup 1)
10561 (match_dup 2)))]
10562 {
10563 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10564 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10565 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10566 /* Avoid possible reformatting on the operands. */
10567 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10568 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10569 if (operands_match_p (operands[0], operands[2]))
10570 {
10571 rtx tmp;
10572 tmp = operands[1];
10573 operands[1] = operands[2];
10574 operands[2] = tmp;
10575 }
10576 })
10577
10578
10579 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10580 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10581 ;; to itself.
10582 (define_insn "*absdf2_if"
10583 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10584 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10585 (clobber (reg:CC 17))]
10586 "!TARGET_64BIT && TARGET_80387
10587 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10588 "#")
10589
10590 ;; FIXME: We should to allow integer registers here. Problem is that
10591 ;; we need another scratch register to get constant from.
10592 ;; Forcing constant to mem if no register available in peep2 should be
10593 ;; safe even for PIC mode, because of RIP relative addressing.
10594 (define_insn "*absdf2_if_rex64"
10595 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10596 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10597 (clobber (reg:CC 17))]
10598 "TARGET_64BIT && TARGET_80387
10599 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10600 "#")
10601
10602 (define_split
10603 [(set (match_operand:DF 0 "fp_register_operand" "")
10604 (abs:DF (match_operand:DF 1 "register_operand" "")))
10605 (clobber (reg:CC 17))]
10606 "TARGET_80387 && reload_completed"
10607 [(set (match_dup 0)
10608 (abs:DF (match_dup 1)))]
10609 "")
10610
10611 (define_split
10612 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10613 (abs:DF (match_operand:DF 1 "register_operand" "")))
10614 (clobber (reg:CC 17))]
10615 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10616 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10617 (clobber (reg:CC 17))])]
10618 "operands[4] = gen_int_mode (~0x80000000, SImode);
10619 split_di (operands+0, 1, operands+2, operands+3);")
10620
10621 (define_expand "absxf2"
10622 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10623 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10624 (clobber (reg:CC 17))])]
10625 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10626 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10627
10628 (define_expand "abstf2"
10629 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10630 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10631 (clobber (reg:CC 17))])]
10632 "TARGET_80387"
10633 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10634
10635 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10636 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10637 ;; to itself.
10638 (define_insn "*absxf2_if"
10639 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10640 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10641 (clobber (reg:CC 17))]
10642 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10643 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10644 "#")
10645
10646 (define_split
10647 [(set (match_operand:XF 0 "fp_register_operand" "")
10648 (abs:XF (match_operand:XF 1 "register_operand" "")))
10649 (clobber (reg:CC 17))]
10650 "TARGET_80387 && reload_completed"
10651 [(set (match_dup 0)
10652 (abs:XF (match_dup 1)))]
10653 "")
10654
10655 (define_split
10656 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10657 (abs:XF (match_operand:XF 1 "register_operand" "")))
10658 (clobber (reg:CC 17))]
10659 "TARGET_80387 && reload_completed"
10660 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10661 (clobber (reg:CC 17))])]
10662 "operands[1] = GEN_INT (~0x8000);
10663 operands[0] = gen_rtx_REG (SImode,
10664 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10665
10666 (define_insn "*abstf2_if"
10667 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10668 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10669 (clobber (reg:CC 17))]
10670 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10671 "#")
10672
10673 (define_split
10674 [(set (match_operand:TF 0 "fp_register_operand" "")
10675 (abs:TF (match_operand:TF 1 "register_operand" "")))
10676 (clobber (reg:CC 17))]
10677 "TARGET_80387 && reload_completed"
10678 [(set (match_dup 0)
10679 (abs:TF (match_dup 1)))]
10680 "")
10681
10682 (define_split
10683 [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
10684 (abs:TF (match_operand:TF 1 "register_operand" "")))
10685 (clobber (reg:CC 17))]
10686 "TARGET_80387 && reload_completed"
10687 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10688 (clobber (reg:CC 17))])]
10689 "operands[1] = GEN_INT (~0x8000);
10690 operands[0] = gen_rtx_REG (SImode,
10691 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10692
10693 (define_insn "*abssf2_1"
10694 [(set (match_operand:SF 0 "register_operand" "=f")
10695 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10696 "TARGET_80387 && reload_completed"
10697 "fabs"
10698 [(set_attr "type" "fsgn")
10699 (set_attr "mode" "SF")])
10700
10701 (define_insn "*absdf2_1"
10702 [(set (match_operand:DF 0 "register_operand" "=f")
10703 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10704 "TARGET_80387 && reload_completed"
10705 "fabs"
10706 [(set_attr "type" "fsgn")
10707 (set_attr "mode" "DF")])
10708
10709 (define_insn "*absextendsfdf2"
10710 [(set (match_operand:DF 0 "register_operand" "=f")
10711 (abs:DF (float_extend:DF
10712 (match_operand:SF 1 "register_operand" "0"))))]
10713 "TARGET_80387"
10714 "fabs"
10715 [(set_attr "type" "fsgn")
10716 (set_attr "mode" "DF")])
10717
10718 (define_insn "*absxf2_1"
10719 [(set (match_operand:XF 0 "register_operand" "=f")
10720 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10721 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10722 "fabs"
10723 [(set_attr "type" "fsgn")
10724 (set_attr "mode" "DF")])
10725
10726 (define_insn "*absextenddfxf2"
10727 [(set (match_operand:XF 0 "register_operand" "=f")
10728 (abs:XF (float_extend:XF
10729 (match_operand:DF 1 "register_operand" "0"))))]
10730 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10731 "fabs"
10732 [(set_attr "type" "fsgn")
10733 (set_attr "mode" "XF")])
10734
10735 (define_insn "*absextendsfxf2"
10736 [(set (match_operand:XF 0 "register_operand" "=f")
10737 (abs:XF (float_extend:XF
10738 (match_operand:SF 1 "register_operand" "0"))))]
10739 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10740 "fabs"
10741 [(set_attr "type" "fsgn")
10742 (set_attr "mode" "XF")])
10743
10744 (define_insn "*abstf2_1"
10745 [(set (match_operand:TF 0 "register_operand" "=f")
10746 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10747 "TARGET_80387 && reload_completed"
10748 "fabs"
10749 [(set_attr "type" "fsgn")
10750 (set_attr "mode" "DF")])
10751
10752 (define_insn "*absextenddftf2"
10753 [(set (match_operand:TF 0 "register_operand" "=f")
10754 (abs:TF (float_extend:TF
10755 (match_operand:DF 1 "register_operand" "0"))))]
10756 "TARGET_80387"
10757 "fabs"
10758 [(set_attr "type" "fsgn")
10759 (set_attr "mode" "XF")])
10760
10761 (define_insn "*absextendsftf2"
10762 [(set (match_operand:TF 0 "register_operand" "=f")
10763 (abs:TF (float_extend:TF
10764 (match_operand:SF 1 "register_operand" "0"))))]
10765 "TARGET_80387"
10766 "fabs"
10767 [(set_attr "type" "fsgn")
10768 (set_attr "mode" "XF")])
10769 \f
10770 ;; One complement instructions
10771
10772 (define_expand "one_cmpldi2"
10773 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10774 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10775 "TARGET_64BIT"
10776 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10777
10778 (define_insn "*one_cmpldi2_1_rex64"
10779 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10780 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10781 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10782 "not{q}\t%0"
10783 [(set_attr "type" "negnot")
10784 (set_attr "mode" "DI")])
10785
10786 (define_insn "*one_cmpldi2_2_rex64"
10787 [(set (reg 17)
10788 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10789 (const_int 0)))
10790 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10791 (not:DI (match_dup 1)))]
10792 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10793 && ix86_unary_operator_ok (NOT, DImode, operands)"
10794 "#"
10795 [(set_attr "type" "alu1")
10796 (set_attr "mode" "DI")])
10797
10798 (define_split
10799 [(set (reg 17)
10800 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10801 (const_int 0)))
10802 (set (match_operand:DI 0 "nonimmediate_operand" "")
10803 (not:DI (match_dup 1)))]
10804 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10805 [(parallel [(set (reg:CCNO 17)
10806 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10807 (const_int 0)))
10808 (set (match_dup 0)
10809 (xor:DI (match_dup 1) (const_int -1)))])]
10810 "")
10811
10812 (define_expand "one_cmplsi2"
10813 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10814 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10815 ""
10816 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10817
10818 (define_insn "*one_cmplsi2_1"
10819 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10820 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10821 "ix86_unary_operator_ok (NOT, SImode, operands)"
10822 "not{l}\t%0"
10823 [(set_attr "type" "negnot")
10824 (set_attr "mode" "SI")])
10825
10826 ;; ??? Currently never generated - xor is used instead.
10827 (define_insn "*one_cmplsi2_1_zext"
10828 [(set (match_operand:DI 0 "register_operand" "=r")
10829 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10830 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10831 "not{l}\t%k0"
10832 [(set_attr "type" "negnot")
10833 (set_attr "mode" "SI")])
10834
10835 (define_insn "*one_cmplsi2_2"
10836 [(set (reg 17)
10837 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10838 (const_int 0)))
10839 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10840 (not:SI (match_dup 1)))]
10841 "ix86_match_ccmode (insn, CCNOmode)
10842 && ix86_unary_operator_ok (NOT, SImode, operands)"
10843 "#"
10844 [(set_attr "type" "alu1")
10845 (set_attr "mode" "SI")])
10846
10847 (define_split
10848 [(set (reg 17)
10849 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10850 (const_int 0)))
10851 (set (match_operand:SI 0 "nonimmediate_operand" "")
10852 (not:SI (match_dup 1)))]
10853 "ix86_match_ccmode (insn, CCNOmode)"
10854 [(parallel [(set (reg:CCNO 17)
10855 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10856 (const_int 0)))
10857 (set (match_dup 0)
10858 (xor:SI (match_dup 1) (const_int -1)))])]
10859 "")
10860
10861 ;; ??? Currently never generated - xor is used instead.
10862 (define_insn "*one_cmplsi2_2_zext"
10863 [(set (reg 17)
10864 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10865 (const_int 0)))
10866 (set (match_operand:DI 0 "register_operand" "=r")
10867 (zero_extend:DI (not:SI (match_dup 1))))]
10868 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10869 && ix86_unary_operator_ok (NOT, SImode, operands)"
10870 "#"
10871 [(set_attr "type" "alu1")
10872 (set_attr "mode" "SI")])
10873
10874 (define_split
10875 [(set (reg 17)
10876 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10877 (const_int 0)))
10878 (set (match_operand:DI 0 "register_operand" "")
10879 (zero_extend:DI (not:SI (match_dup 1))))]
10880 "ix86_match_ccmode (insn, CCNOmode)"
10881 [(parallel [(set (reg:CCNO 17)
10882 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10883 (const_int 0)))
10884 (set (match_dup 0)
10885 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10886 "")
10887
10888 (define_expand "one_cmplhi2"
10889 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10890 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10891 "TARGET_HIMODE_MATH"
10892 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10893
10894 (define_insn "*one_cmplhi2_1"
10895 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10896 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10897 "ix86_unary_operator_ok (NOT, HImode, operands)"
10898 "not{w}\t%0"
10899 [(set_attr "type" "negnot")
10900 (set_attr "mode" "HI")])
10901
10902 (define_insn "*one_cmplhi2_2"
10903 [(set (reg 17)
10904 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10905 (const_int 0)))
10906 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10907 (not:HI (match_dup 1)))]
10908 "ix86_match_ccmode (insn, CCNOmode)
10909 && ix86_unary_operator_ok (NEG, HImode, operands)"
10910 "#"
10911 [(set_attr "type" "alu1")
10912 (set_attr "mode" "HI")])
10913
10914 (define_split
10915 [(set (reg 17)
10916 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10917 (const_int 0)))
10918 (set (match_operand:HI 0 "nonimmediate_operand" "")
10919 (not:HI (match_dup 1)))]
10920 "ix86_match_ccmode (insn, CCNOmode)"
10921 [(parallel [(set (reg:CCNO 17)
10922 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10923 (const_int 0)))
10924 (set (match_dup 0)
10925 (xor:HI (match_dup 1) (const_int -1)))])]
10926 "")
10927
10928 ;; %%% Potential partial reg stall on alternative 1. What to do?
10929 (define_expand "one_cmplqi2"
10930 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10931 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10932 "TARGET_QIMODE_MATH"
10933 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10934
10935 (define_insn "*one_cmplqi2_1"
10936 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10937 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10938 "ix86_unary_operator_ok (NOT, QImode, operands)"
10939 "@
10940 not{b}\t%0
10941 not{l}\t%k0"
10942 [(set_attr "type" "negnot")
10943 (set_attr "mode" "QI,SI")])
10944
10945 (define_insn "*one_cmplqi2_2"
10946 [(set (reg 17)
10947 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10948 (const_int 0)))
10949 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10950 (not:QI (match_dup 1)))]
10951 "ix86_match_ccmode (insn, CCNOmode)
10952 && ix86_unary_operator_ok (NOT, QImode, operands)"
10953 "#"
10954 [(set_attr "type" "alu1")
10955 (set_attr "mode" "QI")])
10956
10957 (define_split
10958 [(set (reg 17)
10959 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10960 (const_int 0)))
10961 (set (match_operand:QI 0 "nonimmediate_operand" "")
10962 (not:QI (match_dup 1)))]
10963 "ix86_match_ccmode (insn, CCNOmode)"
10964 [(parallel [(set (reg:CCNO 17)
10965 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10966 (const_int 0)))
10967 (set (match_dup 0)
10968 (xor:QI (match_dup 1) (const_int -1)))])]
10969 "")
10970 \f
10971 ;; Arithmetic shift instructions
10972
10973 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10974 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10975 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10976 ;; from the assembler input.
10977 ;;
10978 ;; This instruction shifts the target reg/mem as usual, but instead of
10979 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10980 ;; is a left shift double, bits are taken from the high order bits of
10981 ;; reg, else if the insn is a shift right double, bits are taken from the
10982 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10983 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10984 ;;
10985 ;; Since sh[lr]d does not change the `reg' operand, that is done
10986 ;; separately, making all shifts emit pairs of shift double and normal
10987 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10988 ;; support a 63 bit shift, each shift where the count is in a reg expands
10989 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10990 ;;
10991 ;; If the shift count is a constant, we need never emit more than one
10992 ;; shift pair, instead using moves and sign extension for counts greater
10993 ;; than 31.
10994
10995 (define_expand "ashldi3"
10996 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10997 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10998 (match_operand:QI 2 "nonmemory_operand" "")))
10999 (clobber (reg:CC 17))])]
11000 ""
11001 {
11002 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11003 {
11004 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
11005 DONE;
11006 }
11007 ix86_expand_binary_operator (ASHIFT, DImode, operands);
11008 DONE;
11009 })
11010
11011 (define_insn "*ashldi3_1_rex64"
11012 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11013 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
11014 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11015 (clobber (reg:CC 17))]
11016 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11017 {
11018 switch (get_attr_type (insn))
11019 {
11020 case TYPE_ALU:
11021 if (operands[2] != const1_rtx)
11022 abort ();
11023 if (!rtx_equal_p (operands[0], operands[1]))
11024 abort ();
11025 return "add{q}\t{%0, %0|%0, %0}";
11026
11027 case TYPE_LEA:
11028 if (GET_CODE (operands[2]) != CONST_INT
11029 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
11030 abort ();
11031 operands[1] = gen_rtx_MULT (DImode, operands[1],
11032 GEN_INT (1 << INTVAL (operands[2])));
11033 return "lea{q}\t{%a1, %0|%0, %a1}";
11034
11035 default:
11036 if (REG_P (operands[2]))
11037 return "sal{q}\t{%b2, %0|%0, %b2}";
11038 else if (GET_CODE (operands[2]) == CONST_INT
11039 && INTVAL (operands[2]) == 1
11040 && (TARGET_SHIFT1 || optimize_size))
11041 return "sal{q}\t%0";
11042 else
11043 return "sal{q}\t{%2, %0|%0, %2}";
11044 }
11045 }
11046 [(set (attr "type")
11047 (cond [(eq_attr "alternative" "1")
11048 (const_string "lea")
11049 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11050 (const_int 0))
11051 (match_operand 0 "register_operand" ""))
11052 (match_operand 2 "const1_operand" ""))
11053 (const_string "alu")
11054 ]
11055 (const_string "ishift")))
11056 (set_attr "mode" "DI")])
11057
11058 ;; Convert lea to the lea pattern to avoid flags dependency.
11059 (define_split
11060 [(set (match_operand:DI 0 "register_operand" "")
11061 (ashift:DI (match_operand:DI 1 "register_operand" "")
11062 (match_operand:QI 2 "immediate_operand" "")))
11063 (clobber (reg:CC 17))]
11064 "TARGET_64BIT && reload_completed
11065 && true_regnum (operands[0]) != true_regnum (operands[1])"
11066 [(set (match_dup 0)
11067 (mult:DI (match_dup 1)
11068 (match_dup 2)))]
11069 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11070
11071 ;; This pattern can't accept a variable shift count, since shifts by
11072 ;; zero don't affect the flags. We assume that shifts by constant
11073 ;; zero are optimized away.
11074 (define_insn "*ashldi3_cmp_rex64"
11075 [(set (reg 17)
11076 (compare
11077 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11078 (match_operand:QI 2 "immediate_operand" "e"))
11079 (const_int 0)))
11080 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11081 (ashift:DI (match_dup 1) (match_dup 2)))]
11082 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11083 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11084 {
11085 switch (get_attr_type (insn))
11086 {
11087 case TYPE_ALU:
11088 if (operands[2] != const1_rtx)
11089 abort ();
11090 return "add{q}\t{%0, %0|%0, %0}";
11091
11092 default:
11093 if (REG_P (operands[2]))
11094 return "sal{q}\t{%b2, %0|%0, %b2}";
11095 else if (GET_CODE (operands[2]) == CONST_INT
11096 && INTVAL (operands[2]) == 1
11097 && (TARGET_SHIFT1 || optimize_size))
11098 return "sal{q}\t%0";
11099 else
11100 return "sal{q}\t{%2, %0|%0, %2}";
11101 }
11102 }
11103 [(set (attr "type")
11104 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11105 (const_int 0))
11106 (match_operand 0 "register_operand" ""))
11107 (match_operand 2 "const1_operand" ""))
11108 (const_string "alu")
11109 ]
11110 (const_string "ishift")))
11111 (set_attr "mode" "DI")])
11112
11113 (define_insn "ashldi3_1"
11114 [(set (match_operand:DI 0 "register_operand" "=r")
11115 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11116 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11117 (clobber (match_scratch:SI 3 "=&r"))
11118 (clobber (reg:CC 17))]
11119 "!TARGET_64BIT && TARGET_CMOVE"
11120 "#"
11121 [(set_attr "type" "multi")])
11122
11123 (define_insn "*ashldi3_2"
11124 [(set (match_operand:DI 0 "register_operand" "=r")
11125 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11126 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11127 (clobber (reg:CC 17))]
11128 "!TARGET_64BIT"
11129 "#"
11130 [(set_attr "type" "multi")])
11131
11132 (define_split
11133 [(set (match_operand:DI 0 "register_operand" "")
11134 (ashift:DI (match_operand:DI 1 "register_operand" "")
11135 (match_operand:QI 2 "nonmemory_operand" "")))
11136 (clobber (match_scratch:SI 3 ""))
11137 (clobber (reg:CC 17))]
11138 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11139 [(const_int 0)]
11140 "ix86_split_ashldi (operands, operands[3]); DONE;")
11141
11142 (define_split
11143 [(set (match_operand:DI 0 "register_operand" "")
11144 (ashift:DI (match_operand:DI 1 "register_operand" "")
11145 (match_operand:QI 2 "nonmemory_operand" "")))
11146 (clobber (reg:CC 17))]
11147 "!TARGET_64BIT && reload_completed"
11148 [(const_int 0)]
11149 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
11150
11151 (define_insn "x86_shld_1"
11152 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11153 (ior:SI (ashift:SI (match_dup 0)
11154 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11155 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11156 (minus:QI (const_int 32) (match_dup 2)))))
11157 (clobber (reg:CC 17))]
11158 ""
11159 "@
11160 shld{l}\t{%2, %1, %0|%0, %1, %2}
11161 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11162 [(set_attr "type" "ishift")
11163 (set_attr "prefix_0f" "1")
11164 (set_attr "mode" "SI")
11165 (set_attr "pent_pair" "np")
11166 (set_attr "athlon_decode" "vector")
11167 (set_attr "ppro_uops" "few")])
11168
11169 (define_expand "x86_shift_adj_1"
11170 [(set (reg:CCZ 17)
11171 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11172 (const_int 32))
11173 (const_int 0)))
11174 (set (match_operand:SI 0 "register_operand" "")
11175 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11176 (match_operand:SI 1 "register_operand" "")
11177 (match_dup 0)))
11178 (set (match_dup 1)
11179 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11180 (match_operand:SI 3 "register_operand" "r")
11181 (match_dup 1)))]
11182 "TARGET_CMOVE"
11183 "")
11184
11185 (define_expand "x86_shift_adj_2"
11186 [(use (match_operand:SI 0 "register_operand" ""))
11187 (use (match_operand:SI 1 "register_operand" ""))
11188 (use (match_operand:QI 2 "register_operand" ""))]
11189 ""
11190 {
11191 rtx label = gen_label_rtx ();
11192 rtx tmp;
11193
11194 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11195
11196 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11197 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11198 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11199 gen_rtx_LABEL_REF (VOIDmode, label),
11200 pc_rtx);
11201 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11202 JUMP_LABEL (tmp) = label;
11203
11204 emit_move_insn (operands[0], operands[1]);
11205 emit_move_insn (operands[1], const0_rtx);
11206
11207 emit_label (label);
11208 LABEL_NUSES (label) = 1;
11209
11210 DONE;
11211 })
11212
11213 (define_expand "ashlsi3"
11214 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11215 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11216 (match_operand:QI 2 "nonmemory_operand" "")))
11217 (clobber (reg:CC 17))]
11218 ""
11219 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11220
11221 (define_insn "*ashlsi3_1"
11222 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11223 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
11224 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11225 (clobber (reg:CC 17))]
11226 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11227 {
11228 switch (get_attr_type (insn))
11229 {
11230 case TYPE_ALU:
11231 if (operands[2] != const1_rtx)
11232 abort ();
11233 if (!rtx_equal_p (operands[0], operands[1]))
11234 abort ();
11235 return "add{l}\t{%0, %0|%0, %0}";
11236
11237 case TYPE_LEA:
11238 return "#";
11239
11240 default:
11241 if (REG_P (operands[2]))
11242 return "sal{l}\t{%b2, %0|%0, %b2}";
11243 else if (GET_CODE (operands[2]) == CONST_INT
11244 && INTVAL (operands[2]) == 1
11245 && (TARGET_SHIFT1 || optimize_size))
11246 return "sal{l}\t%0";
11247 else
11248 return "sal{l}\t{%2, %0|%0, %2}";
11249 }
11250 }
11251 [(set (attr "type")
11252 (cond [(eq_attr "alternative" "1")
11253 (const_string "lea")
11254 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11255 (const_int 0))
11256 (match_operand 0 "register_operand" ""))
11257 (match_operand 2 "const1_operand" ""))
11258 (const_string "alu")
11259 ]
11260 (const_string "ishift")))
11261 (set_attr "mode" "SI")])
11262
11263 ;; Convert lea to the lea pattern to avoid flags dependency.
11264 (define_split
11265 [(set (match_operand 0 "register_operand" "")
11266 (ashift (match_operand 1 "index_register_operand" "")
11267 (match_operand:QI 2 "const_int_operand" "")))
11268 (clobber (reg:CC 17))]
11269 "reload_completed
11270 && true_regnum (operands[0]) != true_regnum (operands[1])"
11271 [(const_int 0)]
11272 {
11273 rtx pat;
11274 operands[0] = gen_lowpart (SImode, operands[0]);
11275 operands[1] = gen_lowpart (Pmode, operands[1]);
11276 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11277 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11278 if (Pmode != SImode)
11279 pat = gen_rtx_SUBREG (SImode, pat, 0);
11280 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11281 DONE;
11282 })
11283
11284 ;; Rare case of shifting RSP is handled by generating move and shift
11285 (define_split
11286 [(set (match_operand 0 "register_operand" "")
11287 (ashift (match_operand 1 "register_operand" "")
11288 (match_operand:QI 2 "const_int_operand" "")))
11289 (clobber (reg:CC 17))]
11290 "reload_completed
11291 && true_regnum (operands[0]) != true_regnum (operands[1])"
11292 [(const_int 0)]
11293 {
11294 rtx pat, clob;
11295 emit_move_insn (operands[1], operands[0]);
11296 pat = gen_rtx_SET (VOIDmode, operands[0],
11297 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11298 operands[0], operands[2]));
11299 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11300 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11301 DONE;
11302 })
11303
11304 (define_insn "*ashlsi3_1_zext"
11305 [(set (match_operand:DI 0 "register_operand" "=r,r")
11306 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
11307 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11308 (clobber (reg:CC 17))]
11309 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11310 {
11311 switch (get_attr_type (insn))
11312 {
11313 case TYPE_ALU:
11314 if (operands[2] != const1_rtx)
11315 abort ();
11316 return "add{l}\t{%k0, %k0|%k0, %k0}";
11317
11318 case TYPE_LEA:
11319 return "#";
11320
11321 default:
11322 if (REG_P (operands[2]))
11323 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11324 else if (GET_CODE (operands[2]) == CONST_INT
11325 && INTVAL (operands[2]) == 1
11326 && (TARGET_SHIFT1 || optimize_size))
11327 return "sal{l}\t%k0";
11328 else
11329 return "sal{l}\t{%2, %k0|%k0, %2}";
11330 }
11331 }
11332 [(set (attr "type")
11333 (cond [(eq_attr "alternative" "1")
11334 (const_string "lea")
11335 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11336 (const_int 0))
11337 (match_operand 2 "const1_operand" ""))
11338 (const_string "alu")
11339 ]
11340 (const_string "ishift")))
11341 (set_attr "mode" "SI")])
11342
11343 ;; Convert lea to the lea pattern to avoid flags dependency.
11344 (define_split
11345 [(set (match_operand:DI 0 "register_operand" "")
11346 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11347 (match_operand:QI 2 "const_int_operand" ""))))
11348 (clobber (reg:CC 17))]
11349 "TARGET_64BIT && reload_completed
11350 && true_regnum (operands[0]) != true_regnum (operands[1])"
11351 [(set (match_dup 0) (zero_extend:DI
11352 (subreg:SI (mult:SI (match_dup 1)
11353 (match_dup 2)) 0)))]
11354 {
11355 operands[1] = gen_lowpart (Pmode, operands[1]);
11356 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11357 })
11358
11359 ;; This pattern can't accept a variable shift count, since shifts by
11360 ;; zero don't affect the flags. We assume that shifts by constant
11361 ;; zero are optimized away.
11362 (define_insn "*ashlsi3_cmp"
11363 [(set (reg 17)
11364 (compare
11365 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11366 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11367 (const_int 0)))
11368 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11369 (ashift:SI (match_dup 1) (match_dup 2)))]
11370 "ix86_match_ccmode (insn, CCGOCmode)
11371 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11372 {
11373 switch (get_attr_type (insn))
11374 {
11375 case TYPE_ALU:
11376 if (operands[2] != const1_rtx)
11377 abort ();
11378 return "add{l}\t{%0, %0|%0, %0}";
11379
11380 default:
11381 if (REG_P (operands[2]))
11382 return "sal{l}\t{%b2, %0|%0, %b2}";
11383 else if (GET_CODE (operands[2]) == CONST_INT
11384 && INTVAL (operands[2]) == 1
11385 && (TARGET_SHIFT1 || optimize_size))
11386 return "sal{l}\t%0";
11387 else
11388 return "sal{l}\t{%2, %0|%0, %2}";
11389 }
11390 }
11391 [(set (attr "type")
11392 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11393 (const_int 0))
11394 (match_operand 0 "register_operand" ""))
11395 (match_operand 2 "const1_operand" ""))
11396 (const_string "alu")
11397 ]
11398 (const_string "ishift")))
11399 (set_attr "mode" "SI")])
11400
11401 (define_insn "*ashlsi3_cmp_zext"
11402 [(set (reg 17)
11403 (compare
11404 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11405 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11406 (const_int 0)))
11407 (set (match_operand:DI 0 "register_operand" "=r")
11408 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11409 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11410 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11411 {
11412 switch (get_attr_type (insn))
11413 {
11414 case TYPE_ALU:
11415 if (operands[2] != const1_rtx)
11416 abort ();
11417 return "add{l}\t{%k0, %k0|%k0, %k0}";
11418
11419 default:
11420 if (REG_P (operands[2]))
11421 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11422 else if (GET_CODE (operands[2]) == CONST_INT
11423 && INTVAL (operands[2]) == 1
11424 && (TARGET_SHIFT1 || optimize_size))
11425 return "sal{l}\t%k0";
11426 else
11427 return "sal{l}\t{%2, %k0|%k0, %2}";
11428 }
11429 }
11430 [(set (attr "type")
11431 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11432 (const_int 0))
11433 (match_operand 2 "const1_operand" ""))
11434 (const_string "alu")
11435 ]
11436 (const_string "ishift")))
11437 (set_attr "mode" "SI")])
11438
11439 (define_expand "ashlhi3"
11440 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11441 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11442 (match_operand:QI 2 "nonmemory_operand" "")))
11443 (clobber (reg:CC 17))]
11444 "TARGET_HIMODE_MATH"
11445 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11446
11447 (define_insn "*ashlhi3_1_lea"
11448 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11449 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11450 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11451 (clobber (reg:CC 17))]
11452 "!TARGET_PARTIAL_REG_STALL
11453 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11454 {
11455 switch (get_attr_type (insn))
11456 {
11457 case TYPE_LEA:
11458 return "#";
11459 case TYPE_ALU:
11460 if (operands[2] != const1_rtx)
11461 abort ();
11462 return "add{w}\t{%0, %0|%0, %0}";
11463
11464 default:
11465 if (REG_P (operands[2]))
11466 return "sal{w}\t{%b2, %0|%0, %b2}";
11467 else if (GET_CODE (operands[2]) == CONST_INT
11468 && INTVAL (operands[2]) == 1
11469 && (TARGET_SHIFT1 || optimize_size))
11470 return "sal{w}\t%0";
11471 else
11472 return "sal{w}\t{%2, %0|%0, %2}";
11473 }
11474 }
11475 [(set (attr "type")
11476 (cond [(eq_attr "alternative" "1")
11477 (const_string "lea")
11478 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11479 (const_int 0))
11480 (match_operand 0 "register_operand" ""))
11481 (match_operand 2 "const1_operand" ""))
11482 (const_string "alu")
11483 ]
11484 (const_string "ishift")))
11485 (set_attr "mode" "HI,SI")])
11486
11487 (define_insn "*ashlhi3_1"
11488 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11489 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11490 (match_operand:QI 2 "nonmemory_operand" "cI")))
11491 (clobber (reg:CC 17))]
11492 "TARGET_PARTIAL_REG_STALL
11493 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11494 {
11495 switch (get_attr_type (insn))
11496 {
11497 case TYPE_ALU:
11498 if (operands[2] != const1_rtx)
11499 abort ();
11500 return "add{w}\t{%0, %0|%0, %0}";
11501
11502 default:
11503 if (REG_P (operands[2]))
11504 return "sal{w}\t{%b2, %0|%0, %b2}";
11505 else if (GET_CODE (operands[2]) == CONST_INT
11506 && INTVAL (operands[2]) == 1
11507 && (TARGET_SHIFT1 || optimize_size))
11508 return "sal{w}\t%0";
11509 else
11510 return "sal{w}\t{%2, %0|%0, %2}";
11511 }
11512 }
11513 [(set (attr "type")
11514 (cond [(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")])
11522
11523 ;; This pattern can't accept a variable shift count, since shifts by
11524 ;; zero don't affect the flags. We assume that shifts by constant
11525 ;; zero are optimized away.
11526 (define_insn "*ashlhi3_cmp"
11527 [(set (reg 17)
11528 (compare
11529 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11530 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11531 (const_int 0)))
11532 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11533 (ashift:HI (match_dup 1) (match_dup 2)))]
11534 "ix86_match_ccmode (insn, CCGOCmode)
11535 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11536 {
11537 switch (get_attr_type (insn))
11538 {
11539 case TYPE_ALU:
11540 if (operands[2] != const1_rtx)
11541 abort ();
11542 return "add{w}\t{%0, %0|%0, %0}";
11543
11544 default:
11545 if (REG_P (operands[2]))
11546 return "sal{w}\t{%b2, %0|%0, %b2}";
11547 else if (GET_CODE (operands[2]) == CONST_INT
11548 && INTVAL (operands[2]) == 1
11549 && (TARGET_SHIFT1 || optimize_size))
11550 return "sal{w}\t%0";
11551 else
11552 return "sal{w}\t{%2, %0|%0, %2}";
11553 }
11554 }
11555 [(set (attr "type")
11556 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11557 (const_int 0))
11558 (match_operand 0 "register_operand" ""))
11559 (match_operand 2 "const1_operand" ""))
11560 (const_string "alu")
11561 ]
11562 (const_string "ishift")))
11563 (set_attr "mode" "HI")])
11564
11565 (define_expand "ashlqi3"
11566 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11567 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11568 (match_operand:QI 2 "nonmemory_operand" "")))
11569 (clobber (reg:CC 17))]
11570 "TARGET_QIMODE_MATH"
11571 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11572
11573 ;; %%% Potential partial reg stall on alternative 2. What to do?
11574
11575 (define_insn "*ashlqi3_1_lea"
11576 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11577 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11578 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11579 (clobber (reg:CC 17))]
11580 "!TARGET_PARTIAL_REG_STALL
11581 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11582 {
11583 switch (get_attr_type (insn))
11584 {
11585 case TYPE_LEA:
11586 return "#";
11587 case TYPE_ALU:
11588 if (operands[2] != const1_rtx)
11589 abort ();
11590 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11591 return "add{l}\t{%k0, %k0|%k0, %k0}";
11592 else
11593 return "add{b}\t{%0, %0|%0, %0}";
11594
11595 default:
11596 if (REG_P (operands[2]))
11597 {
11598 if (get_attr_mode (insn) == MODE_SI)
11599 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11600 else
11601 return "sal{b}\t{%b2, %0|%0, %b2}";
11602 }
11603 else if (GET_CODE (operands[2]) == CONST_INT
11604 && INTVAL (operands[2]) == 1
11605 && (TARGET_SHIFT1 || optimize_size))
11606 {
11607 if (get_attr_mode (insn) == MODE_SI)
11608 return "sal{l}\t%0";
11609 else
11610 return "sal{b}\t%0";
11611 }
11612 else
11613 {
11614 if (get_attr_mode (insn) == MODE_SI)
11615 return "sal{l}\t{%2, %k0|%k0, %2}";
11616 else
11617 return "sal{b}\t{%2, %0|%0, %2}";
11618 }
11619 }
11620 }
11621 [(set (attr "type")
11622 (cond [(eq_attr "alternative" "2")
11623 (const_string "lea")
11624 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11625 (const_int 0))
11626 (match_operand 0 "register_operand" ""))
11627 (match_operand 2 "const1_operand" ""))
11628 (const_string "alu")
11629 ]
11630 (const_string "ishift")))
11631 (set_attr "mode" "QI,SI,SI")])
11632
11633 (define_insn "*ashlqi3_1"
11634 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11635 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11636 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11637 (clobber (reg:CC 17))]
11638 "TARGET_PARTIAL_REG_STALL
11639 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11640 {
11641 switch (get_attr_type (insn))
11642 {
11643 case TYPE_ALU:
11644 if (operands[2] != const1_rtx)
11645 abort ();
11646 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11647 return "add{l}\t{%k0, %k0|%k0, %k0}";
11648 else
11649 return "add{b}\t{%0, %0|%0, %0}";
11650
11651 default:
11652 if (REG_P (operands[2]))
11653 {
11654 if (get_attr_mode (insn) == MODE_SI)
11655 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11656 else
11657 return "sal{b}\t{%b2, %0|%0, %b2}";
11658 }
11659 else if (GET_CODE (operands[2]) == CONST_INT
11660 && INTVAL (operands[2]) == 1
11661 && (TARGET_SHIFT1 || optimize_size))
11662 {
11663 if (get_attr_mode (insn) == MODE_SI)
11664 return "sal{l}\t%0";
11665 else
11666 return "sal{b}\t%0";
11667 }
11668 else
11669 {
11670 if (get_attr_mode (insn) == MODE_SI)
11671 return "sal{l}\t{%2, %k0|%k0, %2}";
11672 else
11673 return "sal{b}\t{%2, %0|%0, %2}";
11674 }
11675 }
11676 }
11677 [(set (attr "type")
11678 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11679 (const_int 0))
11680 (match_operand 0 "register_operand" ""))
11681 (match_operand 2 "const1_operand" ""))
11682 (const_string "alu")
11683 ]
11684 (const_string "ishift")))
11685 (set_attr "mode" "QI,SI")])
11686
11687 ;; This pattern can't accept a variable shift count, since shifts by
11688 ;; zero don't affect the flags. We assume that shifts by constant
11689 ;; zero are optimized away.
11690 (define_insn "*ashlqi3_cmp"
11691 [(set (reg 17)
11692 (compare
11693 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11694 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11695 (const_int 0)))
11696 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11697 (ashift:QI (match_dup 1) (match_dup 2)))]
11698 "ix86_match_ccmode (insn, CCGOCmode)
11699 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11700 {
11701 switch (get_attr_type (insn))
11702 {
11703 case TYPE_ALU:
11704 if (operands[2] != const1_rtx)
11705 abort ();
11706 return "add{b}\t{%0, %0|%0, %0}";
11707
11708 default:
11709 if (REG_P (operands[2]))
11710 return "sal{b}\t{%b2, %0|%0, %b2}";
11711 else if (GET_CODE (operands[2]) == CONST_INT
11712 && INTVAL (operands[2]) == 1
11713 && (TARGET_SHIFT1 || optimize_size))
11714 return "sal{b}\t%0";
11715 else
11716 return "sal{b}\t{%2, %0|%0, %2}";
11717 }
11718 }
11719 [(set (attr "type")
11720 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11721 (const_int 0))
11722 (match_operand 0 "register_operand" ""))
11723 (match_operand 2 "const1_operand" ""))
11724 (const_string "alu")
11725 ]
11726 (const_string "ishift")))
11727 (set_attr "mode" "QI")])
11728
11729 ;; See comment above `ashldi3' about how this works.
11730
11731 (define_expand "ashrdi3"
11732 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11733 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11734 (match_operand:QI 2 "nonmemory_operand" "")))
11735 (clobber (reg:CC 17))])]
11736 ""
11737 {
11738 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11739 {
11740 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11741 DONE;
11742 }
11743 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11744 DONE;
11745 })
11746
11747 (define_insn "ashrdi3_63_rex64"
11748 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11749 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11750 (match_operand:DI 2 "const_int_operand" "i,i")))
11751 (clobber (reg:CC 17))]
11752 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11753 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11754 "@
11755 {cqto|cqo}
11756 sar{q}\t{%2, %0|%0, %2}"
11757 [(set_attr "type" "imovx,ishift")
11758 (set_attr "prefix_0f" "0,*")
11759 (set_attr "length_immediate" "0,*")
11760 (set_attr "modrm" "0,1")
11761 (set_attr "mode" "DI")])
11762
11763 (define_insn "*ashrdi3_1_one_bit_rex64"
11764 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11765 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11766 (match_operand:QI 2 "const_int_1_operand" "")))
11767 (clobber (reg:CC 17))]
11768 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11769 && (TARGET_SHIFT1 || optimize_size)"
11770 "sar{q}\t%0"
11771 [(set_attr "type" "ishift")
11772 (set (attr "length")
11773 (if_then_else (match_operand:DI 0 "register_operand" "")
11774 (const_string "2")
11775 (const_string "*")))])
11776
11777 (define_insn "*ashrdi3_1_rex64"
11778 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11779 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11780 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11781 (clobber (reg:CC 17))]
11782 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11783 "@
11784 sar{q}\t{%2, %0|%0, %2}
11785 sar{q}\t{%b2, %0|%0, %b2}"
11786 [(set_attr "type" "ishift")
11787 (set_attr "mode" "DI")])
11788
11789 ;; This pattern can't accept a variable shift count, since shifts by
11790 ;; zero don't affect the flags. We assume that shifts by constant
11791 ;; zero are optimized away.
11792 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11793 [(set (reg 17)
11794 (compare
11795 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11796 (match_operand:QI 2 "const_int_1_operand" ""))
11797 (const_int 0)))
11798 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11799 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11800 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11801 && (TARGET_SHIFT1 || optimize_size)
11802 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11803 "sar{q}\t%0"
11804 [(set_attr "type" "ishift")
11805 (set (attr "length")
11806 (if_then_else (match_operand:DI 0 "register_operand" "")
11807 (const_string "2")
11808 (const_string "*")))])
11809
11810 ;; This pattern can't accept a variable shift count, since shifts by
11811 ;; zero don't affect the flags. We assume that shifts by constant
11812 ;; zero are optimized away.
11813 (define_insn "*ashrdi3_cmp_rex64"
11814 [(set (reg 17)
11815 (compare
11816 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11817 (match_operand:QI 2 "const_int_operand" "n"))
11818 (const_int 0)))
11819 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11820 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11821 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11822 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11823 "sar{q}\t{%2, %0|%0, %2}"
11824 [(set_attr "type" "ishift")
11825 (set_attr "mode" "DI")])
11826
11827
11828 (define_insn "ashrdi3_1"
11829 [(set (match_operand:DI 0 "register_operand" "=r")
11830 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11831 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11832 (clobber (match_scratch:SI 3 "=&r"))
11833 (clobber (reg:CC 17))]
11834 "!TARGET_64BIT && TARGET_CMOVE"
11835 "#"
11836 [(set_attr "type" "multi")])
11837
11838 (define_insn "*ashrdi3_2"
11839 [(set (match_operand:DI 0 "register_operand" "=r")
11840 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11841 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11842 (clobber (reg:CC 17))]
11843 "!TARGET_64BIT"
11844 "#"
11845 [(set_attr "type" "multi")])
11846
11847 (define_split
11848 [(set (match_operand:DI 0 "register_operand" "")
11849 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11850 (match_operand:QI 2 "nonmemory_operand" "")))
11851 (clobber (match_scratch:SI 3 ""))
11852 (clobber (reg:CC 17))]
11853 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11854 [(const_int 0)]
11855 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11856
11857 (define_split
11858 [(set (match_operand:DI 0 "register_operand" "")
11859 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11860 (match_operand:QI 2 "nonmemory_operand" "")))
11861 (clobber (reg:CC 17))]
11862 "!TARGET_64BIT && reload_completed"
11863 [(const_int 0)]
11864 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11865
11866 (define_insn "x86_shrd_1"
11867 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11868 (ior:SI (ashiftrt:SI (match_dup 0)
11869 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11870 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11871 (minus:QI (const_int 32) (match_dup 2)))))
11872 (clobber (reg:CC 17))]
11873 ""
11874 "@
11875 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11876 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11877 [(set_attr "type" "ishift")
11878 (set_attr "prefix_0f" "1")
11879 (set_attr "pent_pair" "np")
11880 (set_attr "ppro_uops" "few")
11881 (set_attr "mode" "SI")])
11882
11883 (define_expand "x86_shift_adj_3"
11884 [(use (match_operand:SI 0 "register_operand" ""))
11885 (use (match_operand:SI 1 "register_operand" ""))
11886 (use (match_operand:QI 2 "register_operand" ""))]
11887 ""
11888 {
11889 rtx label = gen_label_rtx ();
11890 rtx tmp;
11891
11892 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11893
11894 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11895 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11896 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11897 gen_rtx_LABEL_REF (VOIDmode, label),
11898 pc_rtx);
11899 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11900 JUMP_LABEL (tmp) = label;
11901
11902 emit_move_insn (operands[0], operands[1]);
11903 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11904
11905 emit_label (label);
11906 LABEL_NUSES (label) = 1;
11907
11908 DONE;
11909 })
11910
11911 (define_insn "ashrsi3_31"
11912 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11913 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11914 (match_operand:SI 2 "const_int_operand" "i,i")))
11915 (clobber (reg:CC 17))]
11916 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11917 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11918 "@
11919 {cltd|cdq}
11920 sar{l}\t{%2, %0|%0, %2}"
11921 [(set_attr "type" "imovx,ishift")
11922 (set_attr "prefix_0f" "0,*")
11923 (set_attr "length_immediate" "0,*")
11924 (set_attr "modrm" "0,1")
11925 (set_attr "mode" "SI")])
11926
11927 (define_insn "*ashrsi3_31_zext"
11928 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11929 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11930 (match_operand:SI 2 "const_int_operand" "i,i"))))
11931 (clobber (reg:CC 17))]
11932 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11933 && INTVAL (operands[2]) == 31
11934 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11935 "@
11936 {cltd|cdq}
11937 sar{l}\t{%2, %k0|%k0, %2}"
11938 [(set_attr "type" "imovx,ishift")
11939 (set_attr "prefix_0f" "0,*")
11940 (set_attr "length_immediate" "0,*")
11941 (set_attr "modrm" "0,1")
11942 (set_attr "mode" "SI")])
11943
11944 (define_expand "ashrsi3"
11945 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11946 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11947 (match_operand:QI 2 "nonmemory_operand" "")))
11948 (clobber (reg:CC 17))]
11949 ""
11950 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11951
11952 (define_insn "*ashrsi3_1_one_bit"
11953 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11954 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11955 (match_operand:QI 2 "const_int_1_operand" "")))
11956 (clobber (reg:CC 17))]
11957 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11958 && (TARGET_SHIFT1 || optimize_size)"
11959 "sar{l}\t%0"
11960 [(set_attr "type" "ishift")
11961 (set (attr "length")
11962 (if_then_else (match_operand:SI 0 "register_operand" "")
11963 (const_string "2")
11964 (const_string "*")))])
11965
11966 (define_insn "*ashrsi3_1_one_bit_zext"
11967 [(set (match_operand:DI 0 "register_operand" "=r")
11968 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11969 (match_operand:QI 2 "const_int_1_operand" ""))))
11970 (clobber (reg:CC 17))]
11971 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11972 && (TARGET_SHIFT1 || optimize_size)"
11973 "sar{l}\t%k0"
11974 [(set_attr "type" "ishift")
11975 (set_attr "length" "2")])
11976
11977 (define_insn "*ashrsi3_1"
11978 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11979 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11980 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11981 (clobber (reg:CC 17))]
11982 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11983 "@
11984 sar{l}\t{%2, %0|%0, %2}
11985 sar{l}\t{%b2, %0|%0, %b2}"
11986 [(set_attr "type" "ishift")
11987 (set_attr "mode" "SI")])
11988
11989 (define_insn "*ashrsi3_1_zext"
11990 [(set (match_operand:DI 0 "register_operand" "=r,r")
11991 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11992 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11993 (clobber (reg:CC 17))]
11994 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11995 "@
11996 sar{l}\t{%2, %k0|%k0, %2}
11997 sar{l}\t{%b2, %k0|%k0, %b2}"
11998 [(set_attr "type" "ishift")
11999 (set_attr "mode" "SI")])
12000
12001 ;; This pattern can't accept a variable shift count, since shifts by
12002 ;; zero don't affect the flags. We assume that shifts by constant
12003 ;; zero are optimized away.
12004 (define_insn "*ashrsi3_one_bit_cmp"
12005 [(set (reg 17)
12006 (compare
12007 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12008 (match_operand:QI 2 "const_int_1_operand" ""))
12009 (const_int 0)))
12010 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12011 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12012 "ix86_match_ccmode (insn, CCGOCmode)
12013 && (TARGET_SHIFT1 || optimize_size)
12014 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12015 "sar{l}\t%0"
12016 [(set_attr "type" "ishift")
12017 (set (attr "length")
12018 (if_then_else (match_operand:SI 0 "register_operand" "")
12019 (const_string "2")
12020 (const_string "*")))])
12021
12022 (define_insn "*ashrsi3_one_bit_cmp_zext"
12023 [(set (reg 17)
12024 (compare
12025 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12026 (match_operand:QI 2 "const_int_1_operand" ""))
12027 (const_int 0)))
12028 (set (match_operand:DI 0 "register_operand" "=r")
12029 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12030 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
12031 && (TARGET_SHIFT1 || optimize_size)
12032 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12033 "sar{l}\t%k0"
12034 [(set_attr "type" "ishift")
12035 (set_attr "length" "2")])
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_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_31_operand" "I"))
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 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12050 "sar{l}\t{%2, %0|%0, %2}"
12051 [(set_attr "type" "ishift")
12052 (set_attr "mode" "SI")])
12053
12054 (define_insn "*ashrsi3_cmp_zext"
12055 [(set (reg 17)
12056 (compare
12057 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12058 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12059 (const_int 0)))
12060 (set (match_operand:DI 0 "register_operand" "=r")
12061 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12062 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12063 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12064 "sar{l}\t{%2, %k0|%k0, %2}"
12065 [(set_attr "type" "ishift")
12066 (set_attr "mode" "SI")])
12067
12068 (define_expand "ashrhi3"
12069 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12070 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12071 (match_operand:QI 2 "nonmemory_operand" "")))
12072 (clobber (reg:CC 17))]
12073 "TARGET_HIMODE_MATH"
12074 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12075
12076 (define_insn "*ashrhi3_1_one_bit"
12077 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12078 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12079 (match_operand:QI 2 "const_int_1_operand" "")))
12080 (clobber (reg:CC 17))]
12081 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12082 && (TARGET_SHIFT1 || optimize_size)"
12083 "sar{w}\t%0"
12084 [(set_attr "type" "ishift")
12085 (set (attr "length")
12086 (if_then_else (match_operand 0 "register_operand" "")
12087 (const_string "2")
12088 (const_string "*")))])
12089
12090 (define_insn "*ashrhi3_1"
12091 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12092 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12093 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12094 (clobber (reg:CC 17))]
12095 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12096 "@
12097 sar{w}\t{%2, %0|%0, %2}
12098 sar{w}\t{%b2, %0|%0, %b2}"
12099 [(set_attr "type" "ishift")
12100 (set_attr "mode" "HI")])
12101
12102 ;; This pattern can't accept a variable shift count, since shifts by
12103 ;; zero don't affect the flags. We assume that shifts by constant
12104 ;; zero are optimized away.
12105 (define_insn "*ashrhi3_one_bit_cmp"
12106 [(set (reg 17)
12107 (compare
12108 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12109 (match_operand:QI 2 "const_int_1_operand" ""))
12110 (const_int 0)))
12111 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12112 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12113 "ix86_match_ccmode (insn, CCGOCmode)
12114 && (TARGET_SHIFT1 || optimize_size)
12115 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12116 "sar{w}\t%0"
12117 [(set_attr "type" "ishift")
12118 (set (attr "length")
12119 (if_then_else (match_operand 0 "register_operand" "")
12120 (const_string "2")
12121 (const_string "*")))])
12122
12123 ;; This pattern can't accept a variable shift count, since shifts by
12124 ;; zero don't affect the flags. We assume that shifts by constant
12125 ;; zero are optimized away.
12126 (define_insn "*ashrhi3_cmp"
12127 [(set (reg 17)
12128 (compare
12129 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12130 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12131 (const_int 0)))
12132 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12133 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12134 "ix86_match_ccmode (insn, CCGOCmode)
12135 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12136 "sar{w}\t{%2, %0|%0, %2}"
12137 [(set_attr "type" "ishift")
12138 (set_attr "mode" "HI")])
12139
12140 (define_expand "ashrqi3"
12141 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12142 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12143 (match_operand:QI 2 "nonmemory_operand" "")))
12144 (clobber (reg:CC 17))]
12145 "TARGET_QIMODE_MATH"
12146 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12147
12148 (define_insn "*ashrqi3_1_one_bit"
12149 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12150 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12151 (match_operand:QI 2 "const_int_1_operand" "")))
12152 (clobber (reg:CC 17))]
12153 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12154 && (TARGET_SHIFT1 || optimize_size)"
12155 "sar{b}\t%0"
12156 [(set_attr "type" "ishift")
12157 (set (attr "length")
12158 (if_then_else (match_operand 0 "register_operand" "")
12159 (const_string "2")
12160 (const_string "*")))])
12161
12162 (define_insn "*ashrqi3_1_one_bit_slp"
12163 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12164 (ashiftrt:QI (match_dup 0)
12165 (match_operand:QI 1 "const_int_1_operand" "")))
12166 (clobber (reg:CC 17))]
12167 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12168 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12169 && (TARGET_SHIFT1 || optimize_size)"
12170 "sar{b}\t%0"
12171 [(set_attr "type" "ishift1")
12172 (set (attr "length")
12173 (if_then_else (match_operand 0 "register_operand" "")
12174 (const_string "2")
12175 (const_string "*")))])
12176
12177 (define_insn "*ashrqi3_1"
12178 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12179 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12180 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12181 (clobber (reg:CC 17))]
12182 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12183 "@
12184 sar{b}\t{%2, %0|%0, %2}
12185 sar{b}\t{%b2, %0|%0, %b2}"
12186 [(set_attr "type" "ishift")
12187 (set_attr "mode" "QI")])
12188
12189 (define_insn "*ashrqi3_1_slp"
12190 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12191 (ashiftrt:QI (match_dup 0)
12192 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12193 (clobber (reg:CC 17))]
12194 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12195 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12196 "@
12197 sar{b}\t{%1, %0|%0, %1}
12198 sar{b}\t{%b1, %0|%0, %b1}"
12199 [(set_attr "type" "ishift1")
12200 (set_attr "mode" "QI")])
12201
12202 ;; This pattern can't accept a variable shift count, since shifts by
12203 ;; zero don't affect the flags. We assume that shifts by constant
12204 ;; zero are optimized away.
12205 (define_insn "*ashrqi3_one_bit_cmp"
12206 [(set (reg 17)
12207 (compare
12208 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12209 (match_operand:QI 2 "const_int_1_operand" "I"))
12210 (const_int 0)))
12211 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12212 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12213 "ix86_match_ccmode (insn, CCGOCmode)
12214 && (TARGET_SHIFT1 || optimize_size)
12215 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12216 "sar{b}\t%0"
12217 [(set_attr "type" "ishift")
12218 (set (attr "length")
12219 (if_then_else (match_operand 0 "register_operand" "")
12220 (const_string "2")
12221 (const_string "*")))])
12222
12223 ;; This pattern can't accept a variable shift count, since shifts by
12224 ;; zero don't affect the flags. We assume that shifts by constant
12225 ;; zero are optimized away.
12226 (define_insn "*ashrqi3_cmp"
12227 [(set (reg 17)
12228 (compare
12229 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12230 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12231 (const_int 0)))
12232 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12233 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12234 "ix86_match_ccmode (insn, CCGOCmode)
12235 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12236 "sar{b}\t{%2, %0|%0, %2}"
12237 [(set_attr "type" "ishift")
12238 (set_attr "mode" "QI")])
12239 \f
12240 ;; Logical shift instructions
12241
12242 ;; See comment above `ashldi3' about how this works.
12243
12244 (define_expand "lshrdi3"
12245 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
12246 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12247 (match_operand:QI 2 "nonmemory_operand" "")))
12248 (clobber (reg:CC 17))])]
12249 ""
12250 {
12251 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
12252 {
12253 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
12254 DONE;
12255 }
12256 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
12257 DONE;
12258 })
12259
12260 (define_insn "*lshrdi3_1_one_bit_rex64"
12261 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12262 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12263 (match_operand:QI 2 "const_int_1_operand" "")))
12264 (clobber (reg:CC 17))]
12265 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12266 && (TARGET_SHIFT1 || optimize_size)"
12267 "shr{q}\t%0"
12268 [(set_attr "type" "ishift")
12269 (set (attr "length")
12270 (if_then_else (match_operand:DI 0 "register_operand" "")
12271 (const_string "2")
12272 (const_string "*")))])
12273
12274 (define_insn "*lshrdi3_1_rex64"
12275 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12276 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12277 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12278 (clobber (reg:CC 17))]
12279 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12280 "@
12281 shr{q}\t{%2, %0|%0, %2}
12282 shr{q}\t{%b2, %0|%0, %b2}"
12283 [(set_attr "type" "ishift")
12284 (set_attr "mode" "DI")])
12285
12286 ;; This pattern can't accept a variable shift count, since shifts by
12287 ;; zero don't affect the flags. We assume that shifts by constant
12288 ;; zero are optimized away.
12289 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12290 [(set (reg 17)
12291 (compare
12292 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12293 (match_operand:QI 2 "const_int_1_operand" ""))
12294 (const_int 0)))
12295 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12296 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12297 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12298 && (TARGET_SHIFT1 || optimize_size)
12299 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12300 "shr{q}\t%0"
12301 [(set_attr "type" "ishift")
12302 (set (attr "length")
12303 (if_then_else (match_operand:DI 0 "register_operand" "")
12304 (const_string "2")
12305 (const_string "*")))])
12306
12307 ;; This pattern can't accept a variable shift count, since shifts by
12308 ;; zero don't affect the flags. We assume that shifts by constant
12309 ;; zero are optimized away.
12310 (define_insn "*lshrdi3_cmp_rex64"
12311 [(set (reg 17)
12312 (compare
12313 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12314 (match_operand:QI 2 "const_int_operand" "e"))
12315 (const_int 0)))
12316 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12317 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12318 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12319 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12320 "shr{q}\t{%2, %0|%0, %2}"
12321 [(set_attr "type" "ishift")
12322 (set_attr "mode" "DI")])
12323
12324 (define_insn "lshrdi3_1"
12325 [(set (match_operand:DI 0 "register_operand" "=r")
12326 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12327 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12328 (clobber (match_scratch:SI 3 "=&r"))
12329 (clobber (reg:CC 17))]
12330 "!TARGET_64BIT && TARGET_CMOVE"
12331 "#"
12332 [(set_attr "type" "multi")])
12333
12334 (define_insn "*lshrdi3_2"
12335 [(set (match_operand:DI 0 "register_operand" "=r")
12336 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12337 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12338 (clobber (reg:CC 17))]
12339 "!TARGET_64BIT"
12340 "#"
12341 [(set_attr "type" "multi")])
12342
12343 (define_split
12344 [(set (match_operand:DI 0 "register_operand" "")
12345 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12346 (match_operand:QI 2 "nonmemory_operand" "")))
12347 (clobber (match_scratch:SI 3 ""))
12348 (clobber (reg:CC 17))]
12349 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
12350 [(const_int 0)]
12351 "ix86_split_lshrdi (operands, operands[3]); DONE;")
12352
12353 (define_split
12354 [(set (match_operand:DI 0 "register_operand" "")
12355 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12356 (match_operand:QI 2 "nonmemory_operand" "")))
12357 (clobber (reg:CC 17))]
12358 "!TARGET_64BIT && reload_completed"
12359 [(const_int 0)]
12360 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
12361
12362 (define_expand "lshrsi3"
12363 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12364 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12365 (match_operand:QI 2 "nonmemory_operand" "")))
12366 (clobber (reg:CC 17))]
12367 ""
12368 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12369
12370 (define_insn "*lshrsi3_1_one_bit"
12371 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12372 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12373 (match_operand:QI 2 "const_int_1_operand" "")))
12374 (clobber (reg:CC 17))]
12375 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12376 && (TARGET_SHIFT1 || optimize_size)"
12377 "shr{l}\t%0"
12378 [(set_attr "type" "ishift")
12379 (set (attr "length")
12380 (if_then_else (match_operand:SI 0 "register_operand" "")
12381 (const_string "2")
12382 (const_string "*")))])
12383
12384 (define_insn "*lshrsi3_1_one_bit_zext"
12385 [(set (match_operand:DI 0 "register_operand" "=r")
12386 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12387 (match_operand:QI 2 "const_int_1_operand" "")))
12388 (clobber (reg:CC 17))]
12389 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12390 && (TARGET_SHIFT1 || optimize_size)"
12391 "shr{l}\t%k0"
12392 [(set_attr "type" "ishift")
12393 (set_attr "length" "2")])
12394
12395 (define_insn "*lshrsi3_1"
12396 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12397 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12398 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12399 (clobber (reg:CC 17))]
12400 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12401 "@
12402 shr{l}\t{%2, %0|%0, %2}
12403 shr{l}\t{%b2, %0|%0, %b2}"
12404 [(set_attr "type" "ishift")
12405 (set_attr "mode" "SI")])
12406
12407 (define_insn "*lshrsi3_1_zext"
12408 [(set (match_operand:DI 0 "register_operand" "=r,r")
12409 (zero_extend:DI
12410 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12411 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12412 (clobber (reg:CC 17))]
12413 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12414 "@
12415 shr{l}\t{%2, %k0|%k0, %2}
12416 shr{l}\t{%b2, %k0|%k0, %b2}"
12417 [(set_attr "type" "ishift")
12418 (set_attr "mode" "SI")])
12419
12420 ;; This pattern can't accept a variable shift count, since shifts by
12421 ;; zero don't affect the flags. We assume that shifts by constant
12422 ;; zero are optimized away.
12423 (define_insn "*lshrsi3_one_bit_cmp"
12424 [(set (reg 17)
12425 (compare
12426 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12427 (match_operand:QI 2 "const_int_1_operand" ""))
12428 (const_int 0)))
12429 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12430 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12431 "ix86_match_ccmode (insn, CCGOCmode)
12432 && (TARGET_SHIFT1 || optimize_size)
12433 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12434 "shr{l}\t%0"
12435 [(set_attr "type" "ishift")
12436 (set (attr "length")
12437 (if_then_else (match_operand:SI 0 "register_operand" "")
12438 (const_string "2")
12439 (const_string "*")))])
12440
12441 (define_insn "*lshrsi3_cmp_one_bit_zext"
12442 [(set (reg 17)
12443 (compare
12444 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12445 (match_operand:QI 2 "const_int_1_operand" ""))
12446 (const_int 0)))
12447 (set (match_operand:DI 0 "register_operand" "=r")
12448 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12449 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12450 && (TARGET_SHIFT1 || optimize_size)
12451 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12452 "shr{l}\t%k0"
12453 [(set_attr "type" "ishift")
12454 (set_attr "length" "2")])
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_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_31_operand" "I"))
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 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12469 "shr{l}\t{%2, %0|%0, %2}"
12470 [(set_attr "type" "ishift")
12471 (set_attr "mode" "SI")])
12472
12473 (define_insn "*lshrsi3_cmp_zext"
12474 [(set (reg 17)
12475 (compare
12476 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12477 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12478 (const_int 0)))
12479 (set (match_operand:DI 0 "register_operand" "=r")
12480 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12481 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12482 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12483 "shr{l}\t{%2, %k0|%k0, %2}"
12484 [(set_attr "type" "ishift")
12485 (set_attr "mode" "SI")])
12486
12487 (define_expand "lshrhi3"
12488 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12489 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12490 (match_operand:QI 2 "nonmemory_operand" "")))
12491 (clobber (reg:CC 17))]
12492 "TARGET_HIMODE_MATH"
12493 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12494
12495 (define_insn "*lshrhi3_1_one_bit"
12496 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12497 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12498 (match_operand:QI 2 "const_int_1_operand" "")))
12499 (clobber (reg:CC 17))]
12500 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12501 && (TARGET_SHIFT1 || optimize_size)"
12502 "shr{w}\t%0"
12503 [(set_attr "type" "ishift")
12504 (set (attr "length")
12505 (if_then_else (match_operand 0 "register_operand" "")
12506 (const_string "2")
12507 (const_string "*")))])
12508
12509 (define_insn "*lshrhi3_1"
12510 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12511 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12512 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12513 (clobber (reg:CC 17))]
12514 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12515 "@
12516 shr{w}\t{%2, %0|%0, %2}
12517 shr{w}\t{%b2, %0|%0, %b2}"
12518 [(set_attr "type" "ishift")
12519 (set_attr "mode" "HI")])
12520
12521 ;; This pattern can't accept a variable shift count, since shifts by
12522 ;; zero don't affect the flags. We assume that shifts by constant
12523 ;; zero are optimized away.
12524 (define_insn "*lshrhi3_one_bit_cmp"
12525 [(set (reg 17)
12526 (compare
12527 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12528 (match_operand:QI 2 "const_int_1_operand" ""))
12529 (const_int 0)))
12530 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12531 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12532 "ix86_match_ccmode (insn, CCGOCmode)
12533 && (TARGET_SHIFT1 || optimize_size)
12534 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12535 "shr{w}\t%0"
12536 [(set_attr "type" "ishift")
12537 (set (attr "length")
12538 (if_then_else (match_operand:SI 0 "register_operand" "")
12539 (const_string "2")
12540 (const_string "*")))])
12541
12542 ;; This pattern can't accept a variable shift count, since shifts by
12543 ;; zero don't affect the flags. We assume that shifts by constant
12544 ;; zero are optimized away.
12545 (define_insn "*lshrhi3_cmp"
12546 [(set (reg 17)
12547 (compare
12548 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12549 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12550 (const_int 0)))
12551 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12552 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12553 "ix86_match_ccmode (insn, CCGOCmode)
12554 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12555 "shr{w}\t{%2, %0|%0, %2}"
12556 [(set_attr "type" "ishift")
12557 (set_attr "mode" "HI")])
12558
12559 (define_expand "lshrqi3"
12560 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12561 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12562 (match_operand:QI 2 "nonmemory_operand" "")))
12563 (clobber (reg:CC 17))]
12564 "TARGET_QIMODE_MATH"
12565 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12566
12567 (define_insn "*lshrqi3_1_one_bit"
12568 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12569 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12570 (match_operand:QI 2 "const_int_1_operand" "")))
12571 (clobber (reg:CC 17))]
12572 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12573 && (TARGET_SHIFT1 || optimize_size)"
12574 "shr{b}\t%0"
12575 [(set_attr "type" "ishift")
12576 (set (attr "length")
12577 (if_then_else (match_operand 0 "register_operand" "")
12578 (const_string "2")
12579 (const_string "*")))])
12580
12581 (define_insn "*lshrqi3_1_one_bit_slp"
12582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12583 (lshiftrt:QI (match_dup 0)
12584 (match_operand:QI 1 "const_int_1_operand" "")))
12585 (clobber (reg:CC 17))]
12586 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12587 && (TARGET_SHIFT1 || optimize_size)"
12588 "shr{b}\t%0"
12589 [(set_attr "type" "ishift1")
12590 (set (attr "length")
12591 (if_then_else (match_operand 0 "register_operand" "")
12592 (const_string "2")
12593 (const_string "*")))])
12594
12595 (define_insn "*lshrqi3_1"
12596 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12597 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12598 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12599 (clobber (reg:CC 17))]
12600 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12601 "@
12602 shr{b}\t{%2, %0|%0, %2}
12603 shr{b}\t{%b2, %0|%0, %b2}"
12604 [(set_attr "type" "ishift")
12605 (set_attr "mode" "QI")])
12606
12607 (define_insn "*lshrqi3_1_slp"
12608 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12609 (lshiftrt:QI (match_dup 0)
12610 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12611 (clobber (reg:CC 17))]
12612 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12613 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12614 "@
12615 shr{b}\t{%1, %0|%0, %1}
12616 shr{b}\t{%b1, %0|%0, %b1}"
12617 [(set_attr "type" "ishift1")
12618 (set_attr "mode" "QI")])
12619
12620 ;; This pattern can't accept a variable shift count, since shifts by
12621 ;; zero don't affect the flags. We assume that shifts by constant
12622 ;; zero are optimized away.
12623 (define_insn "*lshrqi2_one_bit_cmp"
12624 [(set (reg 17)
12625 (compare
12626 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12627 (match_operand:QI 2 "const_int_1_operand" ""))
12628 (const_int 0)))
12629 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12630 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12631 "ix86_match_ccmode (insn, CCGOCmode)
12632 && (TARGET_SHIFT1 || optimize_size)
12633 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12634 "shr{b}\t%0"
12635 [(set_attr "type" "ishift")
12636 (set (attr "length")
12637 (if_then_else (match_operand:SI 0 "register_operand" "")
12638 (const_string "2")
12639 (const_string "*")))])
12640
12641 ;; This pattern can't accept a variable shift count, since shifts by
12642 ;; zero don't affect the flags. We assume that shifts by constant
12643 ;; zero are optimized away.
12644 (define_insn "*lshrqi2_cmp"
12645 [(set (reg 17)
12646 (compare
12647 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12648 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12649 (const_int 0)))
12650 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12651 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12652 "ix86_match_ccmode (insn, CCGOCmode)
12653 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12654 "shr{b}\t{%2, %0|%0, %2}"
12655 [(set_attr "type" "ishift")
12656 (set_attr "mode" "QI")])
12657 \f
12658 ;; Rotate instructions
12659
12660 (define_expand "rotldi3"
12661 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12662 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12663 (match_operand:QI 2 "nonmemory_operand" "")))
12664 (clobber (reg:CC 17))]
12665 "TARGET_64BIT"
12666 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12667
12668 (define_insn "*rotlsi3_1_one_bit_rex64"
12669 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12670 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12671 (match_operand:QI 2 "const_int_1_operand" "")))
12672 (clobber (reg:CC 17))]
12673 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12674 && (TARGET_SHIFT1 || optimize_size)"
12675 "rol{q}\t%0"
12676 [(set_attr "type" "rotate")
12677 (set (attr "length")
12678 (if_then_else (match_operand:DI 0 "register_operand" "")
12679 (const_string "2")
12680 (const_string "*")))])
12681
12682 (define_insn "*rotldi3_1_rex64"
12683 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12684 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12685 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12686 (clobber (reg:CC 17))]
12687 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12688 "@
12689 rol{q}\t{%2, %0|%0, %2}
12690 rol{q}\t{%b2, %0|%0, %b2}"
12691 [(set_attr "type" "rotate")
12692 (set_attr "mode" "DI")])
12693
12694 (define_expand "rotlsi3"
12695 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12696 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12697 (match_operand:QI 2 "nonmemory_operand" "")))
12698 (clobber (reg:CC 17))]
12699 ""
12700 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12701
12702 (define_insn "*rotlsi3_1_one_bit"
12703 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12704 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12705 (match_operand:QI 2 "const_int_1_operand" "")))
12706 (clobber (reg:CC 17))]
12707 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12708 && (TARGET_SHIFT1 || optimize_size)"
12709 "rol{l}\t%0"
12710 [(set_attr "type" "rotate")
12711 (set (attr "length")
12712 (if_then_else (match_operand:SI 0 "register_operand" "")
12713 (const_string "2")
12714 (const_string "*")))])
12715
12716 (define_insn "*rotlsi3_1_one_bit_zext"
12717 [(set (match_operand:DI 0 "register_operand" "=r")
12718 (zero_extend:DI
12719 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12720 (match_operand:QI 2 "const_int_1_operand" ""))))
12721 (clobber (reg:CC 17))]
12722 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12723 && (TARGET_SHIFT1 || optimize_size)"
12724 "rol{l}\t%k0"
12725 [(set_attr "type" "rotate")
12726 (set_attr "length" "2")])
12727
12728 (define_insn "*rotlsi3_1"
12729 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12730 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12731 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12732 (clobber (reg:CC 17))]
12733 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12734 "@
12735 rol{l}\t{%2, %0|%0, %2}
12736 rol{l}\t{%b2, %0|%0, %b2}"
12737 [(set_attr "type" "rotate")
12738 (set_attr "mode" "SI")])
12739
12740 (define_insn "*rotlsi3_1_zext"
12741 [(set (match_operand:DI 0 "register_operand" "=r,r")
12742 (zero_extend:DI
12743 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12744 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12745 (clobber (reg:CC 17))]
12746 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12747 "@
12748 rol{l}\t{%2, %k0|%k0, %2}
12749 rol{l}\t{%b2, %k0|%k0, %b2}"
12750 [(set_attr "type" "rotate")
12751 (set_attr "mode" "SI")])
12752
12753 (define_expand "rotlhi3"
12754 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12755 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12756 (match_operand:QI 2 "nonmemory_operand" "")))
12757 (clobber (reg:CC 17))]
12758 "TARGET_HIMODE_MATH"
12759 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12760
12761 (define_insn "*rotlhi3_1_one_bit"
12762 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12763 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12764 (match_operand:QI 2 "const_int_1_operand" "")))
12765 (clobber (reg:CC 17))]
12766 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12767 && (TARGET_SHIFT1 || optimize_size)"
12768 "rol{w}\t%0"
12769 [(set_attr "type" "rotate")
12770 (set (attr "length")
12771 (if_then_else (match_operand 0 "register_operand" "")
12772 (const_string "2")
12773 (const_string "*")))])
12774
12775 (define_insn "*rotlhi3_1"
12776 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12777 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12778 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12779 (clobber (reg:CC 17))]
12780 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12781 "@
12782 rol{w}\t{%2, %0|%0, %2}
12783 rol{w}\t{%b2, %0|%0, %b2}"
12784 [(set_attr "type" "rotate")
12785 (set_attr "mode" "HI")])
12786
12787 (define_expand "rotlqi3"
12788 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12789 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12790 (match_operand:QI 2 "nonmemory_operand" "")))
12791 (clobber (reg:CC 17))]
12792 "TARGET_QIMODE_MATH"
12793 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12794
12795 (define_insn "*rotlqi3_1_one_bit_slp"
12796 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12797 (rotate:QI (match_dup 0)
12798 (match_operand:QI 1 "const_int_1_operand" "")))
12799 (clobber (reg:CC 17))]
12800 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12801 && (TARGET_SHIFT1 || optimize_size)"
12802 "rol{b}\t%0"
12803 [(set_attr "type" "rotate1")
12804 (set (attr "length")
12805 (if_then_else (match_operand 0 "register_operand" "")
12806 (const_string "2")
12807 (const_string "*")))])
12808
12809 (define_insn "*rotlqi3_1_one_bit"
12810 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12811 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12812 (match_operand:QI 2 "const_int_1_operand" "")))
12813 (clobber (reg:CC 17))]
12814 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12815 && (TARGET_SHIFT1 || optimize_size)"
12816 "rol{b}\t%0"
12817 [(set_attr "type" "rotate")
12818 (set (attr "length")
12819 (if_then_else (match_operand 0 "register_operand" "")
12820 (const_string "2")
12821 (const_string "*")))])
12822
12823 (define_insn "*rotlqi3_1_slp"
12824 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12825 (rotate:QI (match_dup 0)
12826 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12827 (clobber (reg:CC 17))]
12828 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12829 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12830 "@
12831 rol{b}\t{%1, %0|%0, %1}
12832 rol{b}\t{%b1, %0|%0, %b1}"
12833 [(set_attr "type" "rotate1")
12834 (set_attr "mode" "QI")])
12835
12836 (define_insn "*rotlqi3_1"
12837 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12838 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12839 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12840 (clobber (reg:CC 17))]
12841 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12842 "@
12843 rol{b}\t{%2, %0|%0, %2}
12844 rol{b}\t{%b2, %0|%0, %b2}"
12845 [(set_attr "type" "rotate")
12846 (set_attr "mode" "QI")])
12847
12848 (define_expand "rotrdi3"
12849 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12850 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12851 (match_operand:QI 2 "nonmemory_operand" "")))
12852 (clobber (reg:CC 17))]
12853 "TARGET_64BIT"
12854 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12855
12856 (define_insn "*rotrdi3_1_one_bit_rex64"
12857 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12858 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12859 (match_operand:QI 2 "const_int_1_operand" "")))
12860 (clobber (reg:CC 17))]
12861 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12862 && (TARGET_SHIFT1 || optimize_size)"
12863 "ror{q}\t%0"
12864 [(set_attr "type" "rotate")
12865 (set (attr "length")
12866 (if_then_else (match_operand:DI 0 "register_operand" "")
12867 (const_string "2")
12868 (const_string "*")))])
12869
12870 (define_insn "*rotrdi3_1_rex64"
12871 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12872 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12873 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12874 (clobber (reg:CC 17))]
12875 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12876 "@
12877 ror{q}\t{%2, %0|%0, %2}
12878 ror{q}\t{%b2, %0|%0, %b2}"
12879 [(set_attr "type" "rotate")
12880 (set_attr "mode" "DI")])
12881
12882 (define_expand "rotrsi3"
12883 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12884 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12885 (match_operand:QI 2 "nonmemory_operand" "")))
12886 (clobber (reg:CC 17))]
12887 ""
12888 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12889
12890 (define_insn "*rotrsi3_1_one_bit"
12891 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12892 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12893 (match_operand:QI 2 "const_int_1_operand" "")))
12894 (clobber (reg:CC 17))]
12895 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12896 && (TARGET_SHIFT1 || optimize_size)"
12897 "ror{l}\t%0"
12898 [(set_attr "type" "rotate")
12899 (set (attr "length")
12900 (if_then_else (match_operand:SI 0 "register_operand" "")
12901 (const_string "2")
12902 (const_string "*")))])
12903
12904 (define_insn "*rotrsi3_1_one_bit_zext"
12905 [(set (match_operand:DI 0 "register_operand" "=r")
12906 (zero_extend:DI
12907 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12908 (match_operand:QI 2 "const_int_1_operand" ""))))
12909 (clobber (reg:CC 17))]
12910 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12911 && (TARGET_SHIFT1 || optimize_size)"
12912 "ror{l}\t%k0"
12913 [(set_attr "type" "rotate")
12914 (set (attr "length")
12915 (if_then_else (match_operand:SI 0 "register_operand" "")
12916 (const_string "2")
12917 (const_string "*")))])
12918
12919 (define_insn "*rotrsi3_1"
12920 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12921 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12922 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12923 (clobber (reg:CC 17))]
12924 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12925 "@
12926 ror{l}\t{%2, %0|%0, %2}
12927 ror{l}\t{%b2, %0|%0, %b2}"
12928 [(set_attr "type" "rotate")
12929 (set_attr "mode" "SI")])
12930
12931 (define_insn "*rotrsi3_1_zext"
12932 [(set (match_operand:DI 0 "register_operand" "=r,r")
12933 (zero_extend:DI
12934 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12935 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12936 (clobber (reg:CC 17))]
12937 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12938 "@
12939 ror{l}\t{%2, %k0|%k0, %2}
12940 ror{l}\t{%b2, %k0|%k0, %b2}"
12941 [(set_attr "type" "rotate")
12942 (set_attr "mode" "SI")])
12943
12944 (define_expand "rotrhi3"
12945 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12946 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12947 (match_operand:QI 2 "nonmemory_operand" "")))
12948 (clobber (reg:CC 17))]
12949 "TARGET_HIMODE_MATH"
12950 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12951
12952 (define_insn "*rotrhi3_one_bit"
12953 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12954 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12955 (match_operand:QI 2 "const_int_1_operand" "")))
12956 (clobber (reg:CC 17))]
12957 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12958 && (TARGET_SHIFT1 || optimize_size)"
12959 "ror{w}\t%0"
12960 [(set_attr "type" "rotate")
12961 (set (attr "length")
12962 (if_then_else (match_operand 0 "register_operand" "")
12963 (const_string "2")
12964 (const_string "*")))])
12965
12966 (define_insn "*rotrhi3"
12967 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12968 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12969 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12970 (clobber (reg:CC 17))]
12971 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12972 "@
12973 ror{w}\t{%2, %0|%0, %2}
12974 ror{w}\t{%b2, %0|%0, %b2}"
12975 [(set_attr "type" "rotate")
12976 (set_attr "mode" "HI")])
12977
12978 (define_expand "rotrqi3"
12979 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12980 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12981 (match_operand:QI 2 "nonmemory_operand" "")))
12982 (clobber (reg:CC 17))]
12983 "TARGET_QIMODE_MATH"
12984 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12985
12986 (define_insn "*rotrqi3_1_one_bit"
12987 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12988 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12989 (match_operand:QI 2 "const_int_1_operand" "")))
12990 (clobber (reg:CC 17))]
12991 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12992 && (TARGET_SHIFT1 || optimize_size)"
12993 "ror{b}\t%0"
12994 [(set_attr "type" "rotate")
12995 (set (attr "length")
12996 (if_then_else (match_operand 0 "register_operand" "")
12997 (const_string "2")
12998 (const_string "*")))])
12999
13000 (define_insn "*rotrqi3_1_one_bit_slp"
13001 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13002 (rotatert:QI (match_dup 0)
13003 (match_operand:QI 1 "const_int_1_operand" "")))
13004 (clobber (reg:CC 17))]
13005 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13006 && (TARGET_SHIFT1 || optimize_size)"
13007 "ror{b}\t%0"
13008 [(set_attr "type" "rotate1")
13009 (set (attr "length")
13010 (if_then_else (match_operand 0 "register_operand" "")
13011 (const_string "2")
13012 (const_string "*")))])
13013
13014 (define_insn "*rotrqi3_1"
13015 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13016 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13017 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13018 (clobber (reg:CC 17))]
13019 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13020 "@
13021 ror{b}\t{%2, %0|%0, %2}
13022 ror{b}\t{%b2, %0|%0, %b2}"
13023 [(set_attr "type" "rotate")
13024 (set_attr "mode" "QI")])
13025
13026 (define_insn "*rotrqi3_1_slp"
13027 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13028 (rotatert:QI (match_dup 0)
13029 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13030 (clobber (reg:CC 17))]
13031 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13032 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13033 "@
13034 ror{b}\t{%1, %0|%0, %1}
13035 ror{b}\t{%b1, %0|%0, %b1}"
13036 [(set_attr "type" "rotate1")
13037 (set_attr "mode" "QI")])
13038 \f
13039 ;; Bit set / bit test instructions
13040
13041 (define_expand "extv"
13042 [(set (match_operand:SI 0 "register_operand" "")
13043 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13044 (match_operand:SI 2 "immediate_operand" "")
13045 (match_operand:SI 3 "immediate_operand" "")))]
13046 ""
13047 {
13048 /* Handle extractions from %ah et al. */
13049 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13050 FAIL;
13051
13052 /* From mips.md: extract_bit_field doesn't verify that our source
13053 matches the predicate, so check it again here. */
13054 if (! register_operand (operands[1], VOIDmode))
13055 FAIL;
13056 })
13057
13058 (define_expand "extzv"
13059 [(set (match_operand:SI 0 "register_operand" "")
13060 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13061 (match_operand:SI 2 "immediate_operand" "")
13062 (match_operand:SI 3 "immediate_operand" "")))]
13063 ""
13064 {
13065 /* Handle extractions from %ah et al. */
13066 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13067 FAIL;
13068
13069 /* From mips.md: extract_bit_field doesn't verify that our source
13070 matches the predicate, so check it again here. */
13071 if (! register_operand (operands[1], VOIDmode))
13072 FAIL;
13073 })
13074
13075 (define_expand "insv"
13076 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
13077 (match_operand:SI 1 "immediate_operand" "")
13078 (match_operand:SI 2 "immediate_operand" ""))
13079 (match_operand:SI 3 "register_operand" ""))]
13080 ""
13081 {
13082 /* Handle extractions from %ah et al. */
13083 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13084 FAIL;
13085
13086 /* From mips.md: insert_bit_field doesn't verify that our source
13087 matches the predicate, so check it again here. */
13088 if (! register_operand (operands[0], VOIDmode))
13089 FAIL;
13090 })
13091
13092 ;; %%% bts, btr, btc, bt.
13093 \f
13094 ;; Store-flag instructions.
13095
13096 ;; For all sCOND expanders, also expand the compare or test insn that
13097 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13098
13099 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13100 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13101 ;; way, which can later delete the movzx if only QImode is needed.
13102
13103 (define_expand "seq"
13104 [(set (match_operand:QI 0 "register_operand" "")
13105 (eq:QI (reg:CC 17) (const_int 0)))]
13106 ""
13107 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13108
13109 (define_expand "sne"
13110 [(set (match_operand:QI 0 "register_operand" "")
13111 (ne:QI (reg:CC 17) (const_int 0)))]
13112 ""
13113 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13114
13115 (define_expand "sgt"
13116 [(set (match_operand:QI 0 "register_operand" "")
13117 (gt:QI (reg:CC 17) (const_int 0)))]
13118 ""
13119 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13120
13121 (define_expand "sgtu"
13122 [(set (match_operand:QI 0 "register_operand" "")
13123 (gtu:QI (reg:CC 17) (const_int 0)))]
13124 ""
13125 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13126
13127 (define_expand "slt"
13128 [(set (match_operand:QI 0 "register_operand" "")
13129 (lt:QI (reg:CC 17) (const_int 0)))]
13130 ""
13131 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13132
13133 (define_expand "sltu"
13134 [(set (match_operand:QI 0 "register_operand" "")
13135 (ltu:QI (reg:CC 17) (const_int 0)))]
13136 ""
13137 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13138
13139 (define_expand "sge"
13140 [(set (match_operand:QI 0 "register_operand" "")
13141 (ge:QI (reg:CC 17) (const_int 0)))]
13142 ""
13143 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13144
13145 (define_expand "sgeu"
13146 [(set (match_operand:QI 0 "register_operand" "")
13147 (geu:QI (reg:CC 17) (const_int 0)))]
13148 ""
13149 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13150
13151 (define_expand "sle"
13152 [(set (match_operand:QI 0 "register_operand" "")
13153 (le:QI (reg:CC 17) (const_int 0)))]
13154 ""
13155 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13156
13157 (define_expand "sleu"
13158 [(set (match_operand:QI 0 "register_operand" "")
13159 (leu:QI (reg:CC 17) (const_int 0)))]
13160 ""
13161 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13162
13163 (define_expand "sunordered"
13164 [(set (match_operand:QI 0 "register_operand" "")
13165 (unordered:QI (reg:CC 17) (const_int 0)))]
13166 "TARGET_80387 || TARGET_SSE"
13167 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13168
13169 (define_expand "sordered"
13170 [(set (match_operand:QI 0 "register_operand" "")
13171 (ordered:QI (reg:CC 17) (const_int 0)))]
13172 "TARGET_80387"
13173 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13174
13175 (define_expand "suneq"
13176 [(set (match_operand:QI 0 "register_operand" "")
13177 (uneq:QI (reg:CC 17) (const_int 0)))]
13178 "TARGET_80387 || TARGET_SSE"
13179 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13180
13181 (define_expand "sunge"
13182 [(set (match_operand:QI 0 "register_operand" "")
13183 (unge:QI (reg:CC 17) (const_int 0)))]
13184 "TARGET_80387 || TARGET_SSE"
13185 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13186
13187 (define_expand "sungt"
13188 [(set (match_operand:QI 0 "register_operand" "")
13189 (ungt:QI (reg:CC 17) (const_int 0)))]
13190 "TARGET_80387 || TARGET_SSE"
13191 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13192
13193 (define_expand "sunle"
13194 [(set (match_operand:QI 0 "register_operand" "")
13195 (unle:QI (reg:CC 17) (const_int 0)))]
13196 "TARGET_80387 || TARGET_SSE"
13197 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13198
13199 (define_expand "sunlt"
13200 [(set (match_operand:QI 0 "register_operand" "")
13201 (unlt:QI (reg:CC 17) (const_int 0)))]
13202 "TARGET_80387 || TARGET_SSE"
13203 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13204
13205 (define_expand "sltgt"
13206 [(set (match_operand:QI 0 "register_operand" "")
13207 (ltgt:QI (reg:CC 17) (const_int 0)))]
13208 "TARGET_80387 || TARGET_SSE"
13209 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13210
13211 (define_insn "*setcc_1"
13212 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13213 (match_operator:QI 1 "ix86_comparison_operator"
13214 [(reg 17) (const_int 0)]))]
13215 ""
13216 "set%C1\t%0"
13217 [(set_attr "type" "setcc")
13218 (set_attr "mode" "QI")])
13219
13220 (define_insn "setcc_2"
13221 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13222 (match_operator:QI 1 "ix86_comparison_operator"
13223 [(reg 17) (const_int 0)]))]
13224 ""
13225 "set%C1\t%0"
13226 [(set_attr "type" "setcc")
13227 (set_attr "mode" "QI")])
13228
13229 ;; In general it is not safe to assume too much about CCmode registers,
13230 ;; so simplify-rtx stops when it sees a second one. Under certain
13231 ;; conditions this is safe on x86, so help combine not create
13232 ;;
13233 ;; seta %al
13234 ;; testb %al, %al
13235 ;; sete %al
13236
13237 (define_split
13238 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13239 (ne:QI (match_operator 1 "ix86_comparison_operator"
13240 [(reg 17) (const_int 0)])
13241 (const_int 0)))]
13242 ""
13243 [(set (match_dup 0) (match_dup 1))]
13244 {
13245 PUT_MODE (operands[1], QImode);
13246 })
13247
13248 (define_split
13249 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13250 (ne:QI (match_operator 1 "ix86_comparison_operator"
13251 [(reg 17) (const_int 0)])
13252 (const_int 0)))]
13253 ""
13254 [(set (match_dup 0) (match_dup 1))]
13255 {
13256 PUT_MODE (operands[1], QImode);
13257 })
13258
13259 (define_split
13260 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13261 (eq:QI (match_operator 1 "ix86_comparison_operator"
13262 [(reg 17) (const_int 0)])
13263 (const_int 0)))]
13264 ""
13265 [(set (match_dup 0) (match_dup 1))]
13266 {
13267 rtx new_op1 = copy_rtx (operands[1]);
13268 operands[1] = new_op1;
13269 PUT_MODE (new_op1, QImode);
13270 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13271 GET_MODE (XEXP (new_op1, 0))));
13272
13273 /* Make sure that (a) the CCmode we have for the flags is strong
13274 enough for the reversed compare or (b) we have a valid FP compare. */
13275 if (! ix86_comparison_operator (new_op1, VOIDmode))
13276 FAIL;
13277 })
13278
13279 (define_split
13280 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13281 (eq:QI (match_operator 1 "ix86_comparison_operator"
13282 [(reg 17) (const_int 0)])
13283 (const_int 0)))]
13284 ""
13285 [(set (match_dup 0) (match_dup 1))]
13286 {
13287 rtx new_op1 = copy_rtx (operands[1]);
13288 operands[1] = new_op1;
13289 PUT_MODE (new_op1, QImode);
13290 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13291 GET_MODE (XEXP (new_op1, 0))));
13292
13293 /* Make sure that (a) the CCmode we have for the flags is strong
13294 enough for the reversed compare or (b) we have a valid FP compare. */
13295 if (! ix86_comparison_operator (new_op1, VOIDmode))
13296 FAIL;
13297 })
13298
13299 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13300 ;; subsequent logical operations are used to imitate conditional moves.
13301 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13302 ;; it directly. Further holding this value in pseudo register might bring
13303 ;; problem in implicit normalization in spill code.
13304 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
13305 ;; instructions after reload by splitting the conditional move patterns.
13306
13307 (define_insn "*sse_setccsf"
13308 [(set (match_operand:SF 0 "register_operand" "=x")
13309 (match_operator:SF 1 "sse_comparison_operator"
13310 [(match_operand:SF 2 "register_operand" "0")
13311 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13312 "TARGET_SSE && reload_completed"
13313 "cmp%D1ss\t{%3, %0|%0, %3}"
13314 [(set_attr "type" "ssecmp")
13315 (set_attr "mode" "SF")])
13316
13317 (define_insn "*sse_setccdf"
13318 [(set (match_operand:DF 0 "register_operand" "=Y")
13319 (match_operator:DF 1 "sse_comparison_operator"
13320 [(match_operand:DF 2 "register_operand" "0")
13321 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13322 "TARGET_SSE2 && reload_completed"
13323 "cmp%D1sd\t{%3, %0|%0, %3}"
13324 [(set_attr "type" "ssecmp")
13325 (set_attr "mode" "DF")])
13326 \f
13327 ;; Basic conditional jump instructions.
13328 ;; We ignore the overflow flag for signed branch instructions.
13329
13330 ;; For all bCOND expanders, also expand the compare or test insn that
13331 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
13332
13333 (define_expand "beq"
13334 [(set (pc)
13335 (if_then_else (match_dup 1)
13336 (label_ref (match_operand 0 "" ""))
13337 (pc)))]
13338 ""
13339 "ix86_expand_branch (EQ, operands[0]); DONE;")
13340
13341 (define_expand "bne"
13342 [(set (pc)
13343 (if_then_else (match_dup 1)
13344 (label_ref (match_operand 0 "" ""))
13345 (pc)))]
13346 ""
13347 "ix86_expand_branch (NE, operands[0]); DONE;")
13348
13349 (define_expand "bgt"
13350 [(set (pc)
13351 (if_then_else (match_dup 1)
13352 (label_ref (match_operand 0 "" ""))
13353 (pc)))]
13354 ""
13355 "ix86_expand_branch (GT, operands[0]); DONE;")
13356
13357 (define_expand "bgtu"
13358 [(set (pc)
13359 (if_then_else (match_dup 1)
13360 (label_ref (match_operand 0 "" ""))
13361 (pc)))]
13362 ""
13363 "ix86_expand_branch (GTU, operands[0]); DONE;")
13364
13365 (define_expand "blt"
13366 [(set (pc)
13367 (if_then_else (match_dup 1)
13368 (label_ref (match_operand 0 "" ""))
13369 (pc)))]
13370 ""
13371 "ix86_expand_branch (LT, operands[0]); DONE;")
13372
13373 (define_expand "bltu"
13374 [(set (pc)
13375 (if_then_else (match_dup 1)
13376 (label_ref (match_operand 0 "" ""))
13377 (pc)))]
13378 ""
13379 "ix86_expand_branch (LTU, operands[0]); DONE;")
13380
13381 (define_expand "bge"
13382 [(set (pc)
13383 (if_then_else (match_dup 1)
13384 (label_ref (match_operand 0 "" ""))
13385 (pc)))]
13386 ""
13387 "ix86_expand_branch (GE, operands[0]); DONE;")
13388
13389 (define_expand "bgeu"
13390 [(set (pc)
13391 (if_then_else (match_dup 1)
13392 (label_ref (match_operand 0 "" ""))
13393 (pc)))]
13394 ""
13395 "ix86_expand_branch (GEU, operands[0]); DONE;")
13396
13397 (define_expand "ble"
13398 [(set (pc)
13399 (if_then_else (match_dup 1)
13400 (label_ref (match_operand 0 "" ""))
13401 (pc)))]
13402 ""
13403 "ix86_expand_branch (LE, operands[0]); DONE;")
13404
13405 (define_expand "bleu"
13406 [(set (pc)
13407 (if_then_else (match_dup 1)
13408 (label_ref (match_operand 0 "" ""))
13409 (pc)))]
13410 ""
13411 "ix86_expand_branch (LEU, operands[0]); DONE;")
13412
13413 (define_expand "bunordered"
13414 [(set (pc)
13415 (if_then_else (match_dup 1)
13416 (label_ref (match_operand 0 "" ""))
13417 (pc)))]
13418 "TARGET_80387 || TARGET_SSE"
13419 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13420
13421 (define_expand "bordered"
13422 [(set (pc)
13423 (if_then_else (match_dup 1)
13424 (label_ref (match_operand 0 "" ""))
13425 (pc)))]
13426 "TARGET_80387 || TARGET_SSE"
13427 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13428
13429 (define_expand "buneq"
13430 [(set (pc)
13431 (if_then_else (match_dup 1)
13432 (label_ref (match_operand 0 "" ""))
13433 (pc)))]
13434 "TARGET_80387 || TARGET_SSE"
13435 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13436
13437 (define_expand "bunge"
13438 [(set (pc)
13439 (if_then_else (match_dup 1)
13440 (label_ref (match_operand 0 "" ""))
13441 (pc)))]
13442 "TARGET_80387 || TARGET_SSE"
13443 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13444
13445 (define_expand "bungt"
13446 [(set (pc)
13447 (if_then_else (match_dup 1)
13448 (label_ref (match_operand 0 "" ""))
13449 (pc)))]
13450 "TARGET_80387 || TARGET_SSE"
13451 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13452
13453 (define_expand "bunle"
13454 [(set (pc)
13455 (if_then_else (match_dup 1)
13456 (label_ref (match_operand 0 "" ""))
13457 (pc)))]
13458 "TARGET_80387 || TARGET_SSE"
13459 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13460
13461 (define_expand "bunlt"
13462 [(set (pc)
13463 (if_then_else (match_dup 1)
13464 (label_ref (match_operand 0 "" ""))
13465 (pc)))]
13466 "TARGET_80387 || TARGET_SSE"
13467 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13468
13469 (define_expand "bltgt"
13470 [(set (pc)
13471 (if_then_else (match_dup 1)
13472 (label_ref (match_operand 0 "" ""))
13473 (pc)))]
13474 "TARGET_80387 || TARGET_SSE"
13475 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13476
13477 (define_insn "*jcc_1"
13478 [(set (pc)
13479 (if_then_else (match_operator 1 "ix86_comparison_operator"
13480 [(reg 17) (const_int 0)])
13481 (label_ref (match_operand 0 "" ""))
13482 (pc)))]
13483 ""
13484 "%+j%C1\t%l0"
13485 [(set_attr "type" "ibr")
13486 (set_attr "modrm" "0")
13487 (set (attr "length")
13488 (if_then_else (and (ge (minus (match_dup 0) (pc))
13489 (const_int -126))
13490 (lt (minus (match_dup 0) (pc))
13491 (const_int 128)))
13492 (const_int 2)
13493 (const_int 6)))])
13494
13495 (define_insn "*jcc_2"
13496 [(set (pc)
13497 (if_then_else (match_operator 1 "ix86_comparison_operator"
13498 [(reg 17) (const_int 0)])
13499 (pc)
13500 (label_ref (match_operand 0 "" ""))))]
13501 ""
13502 "%+j%c1\t%l0"
13503 [(set_attr "type" "ibr")
13504 (set_attr "modrm" "0")
13505 (set (attr "length")
13506 (if_then_else (and (ge (minus (match_dup 0) (pc))
13507 (const_int -126))
13508 (lt (minus (match_dup 0) (pc))
13509 (const_int 128)))
13510 (const_int 2)
13511 (const_int 6)))])
13512
13513 ;; In general it is not safe to assume too much about CCmode registers,
13514 ;; so simplify-rtx stops when it sees a second one. Under certain
13515 ;; conditions this is safe on x86, so help combine not create
13516 ;;
13517 ;; seta %al
13518 ;; testb %al, %al
13519 ;; je Lfoo
13520
13521 (define_split
13522 [(set (pc)
13523 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13524 [(reg 17) (const_int 0)])
13525 (const_int 0))
13526 (label_ref (match_operand 1 "" ""))
13527 (pc)))]
13528 ""
13529 [(set (pc)
13530 (if_then_else (match_dup 0)
13531 (label_ref (match_dup 1))
13532 (pc)))]
13533 {
13534 PUT_MODE (operands[0], VOIDmode);
13535 })
13536
13537 (define_split
13538 [(set (pc)
13539 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13540 [(reg 17) (const_int 0)])
13541 (const_int 0))
13542 (label_ref (match_operand 1 "" ""))
13543 (pc)))]
13544 ""
13545 [(set (pc)
13546 (if_then_else (match_dup 0)
13547 (label_ref (match_dup 1))
13548 (pc)))]
13549 {
13550 rtx new_op0 = copy_rtx (operands[0]);
13551 operands[0] = new_op0;
13552 PUT_MODE (new_op0, VOIDmode);
13553 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13554 GET_MODE (XEXP (new_op0, 0))));
13555
13556 /* Make sure that (a) the CCmode we have for the flags is strong
13557 enough for the reversed compare or (b) we have a valid FP compare. */
13558 if (! ix86_comparison_operator (new_op0, VOIDmode))
13559 FAIL;
13560 })
13561
13562 ;; Define combination compare-and-branch fp compare instructions to use
13563 ;; during early optimization. Splitting the operation apart early makes
13564 ;; for bad code when we want to reverse the operation.
13565
13566 (define_insn "*fp_jcc_1"
13567 [(set (pc)
13568 (if_then_else (match_operator 0 "comparison_operator"
13569 [(match_operand 1 "register_operand" "f")
13570 (match_operand 2 "register_operand" "f")])
13571 (label_ref (match_operand 3 "" ""))
13572 (pc)))
13573 (clobber (reg:CCFP 18))
13574 (clobber (reg:CCFP 17))]
13575 "TARGET_CMOVE && TARGET_80387
13576 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13577 && FLOAT_MODE_P (GET_MODE (operands[1]))
13578 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13579 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13580 "#")
13581
13582 (define_insn "*fp_jcc_1_sse"
13583 [(set (pc)
13584 (if_then_else (match_operator 0 "comparison_operator"
13585 [(match_operand 1 "register_operand" "f#x,x#f")
13586 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13587 (label_ref (match_operand 3 "" ""))
13588 (pc)))
13589 (clobber (reg:CCFP 18))
13590 (clobber (reg:CCFP 17))]
13591 "TARGET_80387
13592 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13593 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13594 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13595 "#")
13596
13597 (define_insn "*fp_jcc_1_sse_only"
13598 [(set (pc)
13599 (if_then_else (match_operator 0 "comparison_operator"
13600 [(match_operand 1 "register_operand" "x")
13601 (match_operand 2 "nonimmediate_operand" "xm")])
13602 (label_ref (match_operand 3 "" ""))
13603 (pc)))
13604 (clobber (reg:CCFP 18))
13605 (clobber (reg:CCFP 17))]
13606 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13607 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13608 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13609 "#")
13610
13611 (define_insn "*fp_jcc_2"
13612 [(set (pc)
13613 (if_then_else (match_operator 0 "comparison_operator"
13614 [(match_operand 1 "register_operand" "f")
13615 (match_operand 2 "register_operand" "f")])
13616 (pc)
13617 (label_ref (match_operand 3 "" ""))))
13618 (clobber (reg:CCFP 18))
13619 (clobber (reg:CCFP 17))]
13620 "TARGET_CMOVE && TARGET_80387
13621 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13622 && FLOAT_MODE_P (GET_MODE (operands[1]))
13623 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13624 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13625 "#")
13626
13627 (define_insn "*fp_jcc_2_sse"
13628 [(set (pc)
13629 (if_then_else (match_operator 0 "comparison_operator"
13630 [(match_operand 1 "register_operand" "f#x,x#f")
13631 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13632 (pc)
13633 (label_ref (match_operand 3 "" ""))))
13634 (clobber (reg:CCFP 18))
13635 (clobber (reg:CCFP 17))]
13636 "TARGET_80387
13637 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13638 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13639 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13640 "#")
13641
13642 (define_insn "*fp_jcc_2_sse_only"
13643 [(set (pc)
13644 (if_then_else (match_operator 0 "comparison_operator"
13645 [(match_operand 1 "register_operand" "x")
13646 (match_operand 2 "nonimmediate_operand" "xm")])
13647 (pc)
13648 (label_ref (match_operand 3 "" ""))))
13649 (clobber (reg:CCFP 18))
13650 (clobber (reg:CCFP 17))]
13651 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13652 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13653 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13654 "#")
13655
13656 (define_insn "*fp_jcc_3"
13657 [(set (pc)
13658 (if_then_else (match_operator 0 "comparison_operator"
13659 [(match_operand 1 "register_operand" "f")
13660 (match_operand 2 "nonimmediate_operand" "fm")])
13661 (label_ref (match_operand 3 "" ""))
13662 (pc)))
13663 (clobber (reg:CCFP 18))
13664 (clobber (reg:CCFP 17))
13665 (clobber (match_scratch:HI 4 "=a"))]
13666 "TARGET_80387
13667 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13668 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13669 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13670 && SELECT_CC_MODE (GET_CODE (operands[0]),
13671 operands[1], operands[2]) == CCFPmode
13672 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13673 "#")
13674
13675 (define_insn "*fp_jcc_4"
13676 [(set (pc)
13677 (if_then_else (match_operator 0 "comparison_operator"
13678 [(match_operand 1 "register_operand" "f")
13679 (match_operand 2 "nonimmediate_operand" "fm")])
13680 (pc)
13681 (label_ref (match_operand 3 "" ""))))
13682 (clobber (reg:CCFP 18))
13683 (clobber (reg:CCFP 17))
13684 (clobber (match_scratch:HI 4 "=a"))]
13685 "TARGET_80387
13686 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13687 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13688 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13689 && SELECT_CC_MODE (GET_CODE (operands[0]),
13690 operands[1], operands[2]) == CCFPmode
13691 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13692 "#")
13693
13694 (define_insn "*fp_jcc_5"
13695 [(set (pc)
13696 (if_then_else (match_operator 0 "comparison_operator"
13697 [(match_operand 1 "register_operand" "f")
13698 (match_operand 2 "register_operand" "f")])
13699 (label_ref (match_operand 3 "" ""))
13700 (pc)))
13701 (clobber (reg:CCFP 18))
13702 (clobber (reg:CCFP 17))
13703 (clobber (match_scratch:HI 4 "=a"))]
13704 "TARGET_80387
13705 && FLOAT_MODE_P (GET_MODE (operands[1]))
13706 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13707 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13708 "#")
13709
13710 (define_insn "*fp_jcc_6"
13711 [(set (pc)
13712 (if_then_else (match_operator 0 "comparison_operator"
13713 [(match_operand 1 "register_operand" "f")
13714 (match_operand 2 "register_operand" "f")])
13715 (pc)
13716 (label_ref (match_operand 3 "" ""))))
13717 (clobber (reg:CCFP 18))
13718 (clobber (reg:CCFP 17))
13719 (clobber (match_scratch:HI 4 "=a"))]
13720 "TARGET_80387
13721 && FLOAT_MODE_P (GET_MODE (operands[1]))
13722 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13723 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13724 "#")
13725
13726 (define_split
13727 [(set (pc)
13728 (if_then_else (match_operator 0 "comparison_operator"
13729 [(match_operand 1 "register_operand" "")
13730 (match_operand 2 "nonimmediate_operand" "")])
13731 (match_operand 3 "" "")
13732 (match_operand 4 "" "")))
13733 (clobber (reg:CCFP 18))
13734 (clobber (reg:CCFP 17))]
13735 "reload_completed"
13736 [(const_int 0)]
13737 {
13738 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13739 operands[3], operands[4], NULL_RTX);
13740 DONE;
13741 })
13742
13743 (define_split
13744 [(set (pc)
13745 (if_then_else (match_operator 0 "comparison_operator"
13746 [(match_operand 1 "register_operand" "")
13747 (match_operand 2 "nonimmediate_operand" "")])
13748 (match_operand 3 "" "")
13749 (match_operand 4 "" "")))
13750 (clobber (reg:CCFP 18))
13751 (clobber (reg:CCFP 17))
13752 (clobber (match_scratch:HI 5 "=a"))]
13753 "reload_completed"
13754 [(set (pc)
13755 (if_then_else (match_dup 6)
13756 (match_dup 3)
13757 (match_dup 4)))]
13758 {
13759 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13760 operands[3], operands[4], operands[5]);
13761 DONE;
13762 })
13763 \f
13764 ;; Unconditional and other jump instructions
13765
13766 (define_insn "jump"
13767 [(set (pc)
13768 (label_ref (match_operand 0 "" "")))]
13769 ""
13770 "jmp\t%l0"
13771 [(set_attr "type" "ibr")
13772 (set (attr "length")
13773 (if_then_else (and (ge (minus (match_dup 0) (pc))
13774 (const_int -126))
13775 (lt (minus (match_dup 0) (pc))
13776 (const_int 128)))
13777 (const_int 2)
13778 (const_int 5)))
13779 (set_attr "modrm" "0")])
13780
13781 (define_expand "indirect_jump"
13782 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13783 ""
13784 "")
13785
13786 (define_insn "*indirect_jump"
13787 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13788 "!TARGET_64BIT"
13789 "jmp\t%A0"
13790 [(set_attr "type" "ibr")
13791 (set_attr "length_immediate" "0")])
13792
13793 (define_insn "*indirect_jump_rtx64"
13794 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13795 "TARGET_64BIT"
13796 "jmp\t%A0"
13797 [(set_attr "type" "ibr")
13798 (set_attr "length_immediate" "0")])
13799
13800 (define_expand "tablejump"
13801 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13802 (use (label_ref (match_operand 1 "" "")))])]
13803 ""
13804 {
13805 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13806 relative. Convert the relative address to an absolute address. */
13807 if (flag_pic)
13808 {
13809 rtx op0, op1;
13810 enum rtx_code code;
13811
13812 if (TARGET_64BIT)
13813 {
13814 code = PLUS;
13815 op0 = operands[0];
13816 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13817 }
13818 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13819 {
13820 code = PLUS;
13821 op0 = operands[0];
13822 op1 = pic_offset_table_rtx;
13823 }
13824 else
13825 {
13826 code = MINUS;
13827 op0 = pic_offset_table_rtx;
13828 op1 = operands[0];
13829 }
13830
13831 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13832 OPTAB_DIRECT);
13833 }
13834 })
13835
13836 (define_insn "*tablejump_1"
13837 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13838 (use (label_ref (match_operand 1 "" "")))]
13839 "!TARGET_64BIT"
13840 "jmp\t%A0"
13841 [(set_attr "type" "ibr")
13842 (set_attr "length_immediate" "0")])
13843
13844 (define_insn "*tablejump_1_rtx64"
13845 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13846 (use (label_ref (match_operand 1 "" "")))]
13847 "TARGET_64BIT"
13848 "jmp\t%A0"
13849 [(set_attr "type" "ibr")
13850 (set_attr "length_immediate" "0")])
13851 \f
13852 ;; Loop instruction
13853 ;;
13854 ;; This is all complicated by the fact that since this is a jump insn
13855 ;; we must handle our own reloads.
13856
13857 (define_expand "doloop_end"
13858 [(use (match_operand 0 "" "")) ; loop pseudo
13859 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13860 (use (match_operand 2 "" "")) ; max iterations
13861 (use (match_operand 3 "" "")) ; loop level
13862 (use (match_operand 4 "" ""))] ; label
13863 "!TARGET_64BIT && TARGET_USE_LOOP"
13864 "
13865 {
13866 /* Only use cloop on innermost loops. */
13867 if (INTVAL (operands[3]) > 1)
13868 FAIL;
13869 if (GET_MODE (operands[0]) != SImode)
13870 FAIL;
13871 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13872 operands[0]));
13873 DONE;
13874 }")
13875
13876 (define_insn "doloop_end_internal"
13877 [(set (pc)
13878 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13879 (const_int 1))
13880 (label_ref (match_operand 0 "" ""))
13881 (pc)))
13882 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13883 (plus:SI (match_dup 1)
13884 (const_int -1)))
13885 (clobber (match_scratch:SI 3 "=X,X,r"))
13886 (clobber (reg:CC 17))]
13887 "!TARGET_64BIT && TARGET_USE_LOOP"
13888 {
13889 if (which_alternative != 0)
13890 return "#";
13891 if (get_attr_length (insn) == 2)
13892 return "%+loop\t%l0";
13893 else
13894 return "dec{l}\t%1\;%+jne\t%l0";
13895 }
13896 [(set_attr "ppro_uops" "many")
13897 (set (attr "length")
13898 (if_then_else (and (eq_attr "alternative" "0")
13899 (and (ge (minus (match_dup 0) (pc))
13900 (const_int -126))
13901 (lt (minus (match_dup 0) (pc))
13902 (const_int 128))))
13903 (const_int 2)
13904 (const_int 16)))
13905 ;; We don't know the type before shorten branches. Optimistically expect
13906 ;; the loop instruction to match.
13907 (set (attr "type") (const_string "ibr"))])
13908
13909 (define_split
13910 [(set (pc)
13911 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13912 (const_int 1))
13913 (match_operand 0 "" "")
13914 (pc)))
13915 (set (match_dup 1)
13916 (plus:SI (match_dup 1)
13917 (const_int -1)))
13918 (clobber (match_scratch:SI 2 ""))
13919 (clobber (reg:CC 17))]
13920 "!TARGET_64BIT && TARGET_USE_LOOP
13921 && reload_completed
13922 && REGNO (operands[1]) != 2"
13923 [(parallel [(set (reg:CCZ 17)
13924 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13925 (const_int 0)))
13926 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13927 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13928 (match_dup 0)
13929 (pc)))]
13930 "")
13931
13932 (define_split
13933 [(set (pc)
13934 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13935 (const_int 1))
13936 (match_operand 0 "" "")
13937 (pc)))
13938 (set (match_operand:SI 2 "nonimmediate_operand" "")
13939 (plus:SI (match_dup 1)
13940 (const_int -1)))
13941 (clobber (match_scratch:SI 3 ""))
13942 (clobber (reg:CC 17))]
13943 "!TARGET_64BIT && TARGET_USE_LOOP
13944 && reload_completed
13945 && (! REG_P (operands[2])
13946 || ! rtx_equal_p (operands[1], operands[2]))"
13947 [(set (match_dup 3) (match_dup 1))
13948 (parallel [(set (reg:CCZ 17)
13949 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13950 (const_int 0)))
13951 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13952 (set (match_dup 2) (match_dup 3))
13953 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13954 (match_dup 0)
13955 (pc)))]
13956 "")
13957
13958 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13959
13960 (define_peephole2
13961 [(set (reg 17) (match_operand 0 "" ""))
13962 (set (match_operand:QI 1 "register_operand" "")
13963 (match_operator:QI 2 "ix86_comparison_operator"
13964 [(reg 17) (const_int 0)]))
13965 (set (match_operand 3 "q_regs_operand" "")
13966 (zero_extend (match_dup 1)))]
13967 "(peep2_reg_dead_p (3, operands[1])
13968 || operands_match_p (operands[1], operands[3]))
13969 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13970 [(set (match_dup 4) (match_dup 0))
13971 (set (strict_low_part (match_dup 5))
13972 (match_dup 2))]
13973 {
13974 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13975 operands[5] = gen_lowpart (QImode, operands[3]);
13976 ix86_expand_clear (operands[3]);
13977 })
13978
13979 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13980
13981 (define_peephole2
13982 [(set (reg 17) (match_operand 0 "" ""))
13983 (set (match_operand:QI 1 "register_operand" "")
13984 (match_operator:QI 2 "ix86_comparison_operator"
13985 [(reg 17) (const_int 0)]))
13986 (parallel [(set (match_operand 3 "q_regs_operand" "")
13987 (zero_extend (match_dup 1)))
13988 (clobber (reg:CC 17))])]
13989 "(peep2_reg_dead_p (3, operands[1])
13990 || operands_match_p (operands[1], operands[3]))
13991 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13992 [(set (match_dup 4) (match_dup 0))
13993 (set (strict_low_part (match_dup 5))
13994 (match_dup 2))]
13995 {
13996 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13997 operands[5] = gen_lowpart (QImode, operands[3]);
13998 ix86_expand_clear (operands[3]);
13999 })
14000 \f
14001 ;; Call instructions.
14002
14003 ;; The predicates normally associated with named expanders are not properly
14004 ;; checked for calls. This is a bug in the generic code, but it isn't that
14005 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14006
14007 ;; Call subroutine returning no value.
14008
14009 (define_expand "call_pop"
14010 [(parallel [(call (match_operand:QI 0 "" "")
14011 (match_operand:SI 1 "" ""))
14012 (set (reg:SI 7)
14013 (plus:SI (reg:SI 7)
14014 (match_operand:SI 3 "" "")))])]
14015 "!TARGET_64BIT"
14016 {
14017 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14018 DONE;
14019 })
14020
14021 (define_insn "*call_pop_0"
14022 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14023 (match_operand:SI 1 "" ""))
14024 (set (reg:SI 7) (plus:SI (reg:SI 7)
14025 (match_operand:SI 2 "immediate_operand" "")))]
14026 "!TARGET_64BIT"
14027 {
14028 if (SIBLING_CALL_P (insn))
14029 return "jmp\t%P0";
14030 else
14031 return "call\t%P0";
14032 }
14033 [(set_attr "type" "call")])
14034
14035 (define_insn "*call_pop_1"
14036 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14037 (match_operand:SI 1 "" ""))
14038 (set (reg:SI 7) (plus:SI (reg:SI 7)
14039 (match_operand:SI 2 "immediate_operand" "i")))]
14040 "!TARGET_64BIT"
14041 {
14042 if (constant_call_address_operand (operands[0], Pmode))
14043 {
14044 if (SIBLING_CALL_P (insn))
14045 return "jmp\t%P0";
14046 else
14047 return "call\t%P0";
14048 }
14049 if (SIBLING_CALL_P (insn))
14050 return "jmp\t%A0";
14051 else
14052 return "call\t%A0";
14053 }
14054 [(set_attr "type" "call")])
14055
14056 (define_expand "call"
14057 [(call (match_operand:QI 0 "" "")
14058 (match_operand 1 "" ""))
14059 (use (match_operand 2 "" ""))]
14060 ""
14061 {
14062 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14063 DONE;
14064 })
14065
14066 (define_expand "sibcall"
14067 [(call (match_operand:QI 0 "" "")
14068 (match_operand 1 "" ""))
14069 (use (match_operand 2 "" ""))]
14070 ""
14071 {
14072 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14073 DONE;
14074 })
14075
14076 (define_insn "*call_0"
14077 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14078 (match_operand 1 "" ""))]
14079 ""
14080 {
14081 if (SIBLING_CALL_P (insn))
14082 return "jmp\t%P0";
14083 else
14084 return "call\t%P0";
14085 }
14086 [(set_attr "type" "call")])
14087
14088 (define_insn "*call_1"
14089 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14090 (match_operand 1 "" ""))]
14091 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14092 {
14093 if (constant_call_address_operand (operands[0], QImode))
14094 return "call\t%P0";
14095 return "call\t%A0";
14096 }
14097 [(set_attr "type" "call")])
14098
14099 (define_insn "*sibcall_1"
14100 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14101 (match_operand 1 "" ""))]
14102 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14103 {
14104 if (constant_call_address_operand (operands[0], QImode))
14105 return "jmp\t%P0";
14106 return "jmp\t%A0";
14107 }
14108 [(set_attr "type" "call")])
14109
14110 (define_insn "*call_1_rex64"
14111 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14112 (match_operand 1 "" ""))]
14113 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14114 {
14115 if (constant_call_address_operand (operands[0], QImode))
14116 return "call\t%P0";
14117 return "call\t%A0";
14118 }
14119 [(set_attr "type" "call")])
14120
14121 (define_insn "*sibcall_1_rex64"
14122 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14123 (match_operand 1 "" ""))]
14124 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14125 "jmp\t%P0"
14126 [(set_attr "type" "call")])
14127
14128 (define_insn "*sibcall_1_rex64_v"
14129 [(call (mem:QI (reg:DI 40))
14130 (match_operand 0 "" ""))]
14131 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14132 "jmp\t*%%r11"
14133 [(set_attr "type" "call")])
14134
14135
14136 ;; Call subroutine, returning value in operand 0
14137
14138 (define_expand "call_value_pop"
14139 [(parallel [(set (match_operand 0 "" "")
14140 (call (match_operand:QI 1 "" "")
14141 (match_operand:SI 2 "" "")))
14142 (set (reg:SI 7)
14143 (plus:SI (reg:SI 7)
14144 (match_operand:SI 4 "" "")))])]
14145 "!TARGET_64BIT"
14146 {
14147 ix86_expand_call (operands[0], operands[1], operands[2],
14148 operands[3], operands[4], 0);
14149 DONE;
14150 })
14151
14152 (define_expand "call_value"
14153 [(set (match_operand 0 "" "")
14154 (call (match_operand:QI 1 "" "")
14155 (match_operand:SI 2 "" "")))
14156 (use (match_operand:SI 3 "" ""))]
14157 ;; Operand 2 not used on the i386.
14158 ""
14159 {
14160 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14161 DONE;
14162 })
14163
14164 (define_expand "sibcall_value"
14165 [(set (match_operand 0 "" "")
14166 (call (match_operand:QI 1 "" "")
14167 (match_operand:SI 2 "" "")))
14168 (use (match_operand:SI 3 "" ""))]
14169 ;; Operand 2 not used on the i386.
14170 ""
14171 {
14172 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14173 DONE;
14174 })
14175
14176 ;; Call subroutine returning any type.
14177
14178 (define_expand "untyped_call"
14179 [(parallel [(call (match_operand 0 "" "")
14180 (const_int 0))
14181 (match_operand 1 "" "")
14182 (match_operand 2 "" "")])]
14183 ""
14184 {
14185 int i;
14186
14187 /* In order to give reg-stack an easier job in validating two
14188 coprocessor registers as containing a possible return value,
14189 simply pretend the untyped call returns a complex long double
14190 value. */
14191
14192 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14193 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14194 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14195 NULL, 0);
14196
14197 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14198 {
14199 rtx set = XVECEXP (operands[2], 0, i);
14200 emit_move_insn (SET_DEST (set), SET_SRC (set));
14201 }
14202
14203 /* The optimizer does not know that the call sets the function value
14204 registers we stored in the result block. We avoid problems by
14205 claiming that all hard registers are used and clobbered at this
14206 point. */
14207 emit_insn (gen_blockage (const0_rtx));
14208
14209 DONE;
14210 })
14211 \f
14212 ;; Prologue and epilogue instructions
14213
14214 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14215 ;; all of memory. This blocks insns from being moved across this point.
14216
14217 (define_insn "blockage"
14218 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14219 ""
14220 ""
14221 [(set_attr "length" "0")])
14222
14223 ;; Insn emitted into the body of a function to return from a function.
14224 ;; This is only done if the function's epilogue is known to be simple.
14225 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14226
14227 (define_expand "return"
14228 [(return)]
14229 "ix86_can_use_return_insn_p ()"
14230 {
14231 if (current_function_pops_args)
14232 {
14233 rtx popc = GEN_INT (current_function_pops_args);
14234 emit_jump_insn (gen_return_pop_internal (popc));
14235 DONE;
14236 }
14237 })
14238
14239 (define_insn "return_internal"
14240 [(return)]
14241 "reload_completed"
14242 "ret"
14243 [(set_attr "length" "1")
14244 (set_attr "length_immediate" "0")
14245 (set_attr "modrm" "0")])
14246
14247 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14248 ;; instruction Athlon and K8 have.
14249
14250 (define_insn "return_internal_long"
14251 [(return)
14252 (unspec [(const_int 0)] UNSPEC_REP)]
14253 "reload_completed"
14254 "rep {;} ret"
14255 [(set_attr "length" "1")
14256 (set_attr "length_immediate" "0")
14257 (set_attr "prefix_rep" "1")
14258 (set_attr "modrm" "0")])
14259
14260 (define_insn "return_pop_internal"
14261 [(return)
14262 (use (match_operand:SI 0 "const_int_operand" ""))]
14263 "reload_completed"
14264 "ret\t%0"
14265 [(set_attr "length" "3")
14266 (set_attr "length_immediate" "2")
14267 (set_attr "modrm" "0")])
14268
14269 (define_insn "return_indirect_internal"
14270 [(return)
14271 (use (match_operand:SI 0 "register_operand" "r"))]
14272 "reload_completed"
14273 "jmp\t%A0"
14274 [(set_attr "type" "ibr")
14275 (set_attr "length_immediate" "0")])
14276
14277 (define_insn "nop"
14278 [(const_int 0)]
14279 ""
14280 "nop"
14281 [(set_attr "length" "1")
14282 (set_attr "length_immediate" "0")
14283 (set_attr "modrm" "0")
14284 (set_attr "ppro_uops" "one")])
14285
14286 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14287 ;; branch prediction penalty for the third jump in a 16-byte
14288 ;; block on K8.
14289
14290 (define_insn "align"
14291 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14292 ""
14293 {
14294 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14295 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14296 #else
14297 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14298 The align insn is used to avoid 3 jump instructions in the row to improve
14299 branch prediction and the benefits hardly outweight the cost of extra 8
14300 nops on the average inserted by full alignment pseudo operation. */
14301 #endif
14302 return "";
14303 }
14304 [(set_attr "length" "16")])
14305
14306 (define_expand "prologue"
14307 [(const_int 1)]
14308 ""
14309 "ix86_expand_prologue (); DONE;")
14310
14311 (define_insn "set_got"
14312 [(set (match_operand:SI 0 "register_operand" "=r")
14313 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14314 (clobber (reg:CC 17))]
14315 "!TARGET_64BIT"
14316 { return output_set_got (operands[0]); }
14317 [(set_attr "type" "multi")
14318 (set_attr "length" "12")])
14319
14320 (define_expand "epilogue"
14321 [(const_int 1)]
14322 ""
14323 "ix86_expand_epilogue (1); DONE;")
14324
14325 (define_expand "sibcall_epilogue"
14326 [(const_int 1)]
14327 ""
14328 "ix86_expand_epilogue (0); DONE;")
14329
14330 (define_expand "eh_return"
14331 [(use (match_operand 0 "register_operand" ""))]
14332 ""
14333 {
14334 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14335
14336 /* Tricky bit: we write the address of the handler to which we will
14337 be returning into someone else's stack frame, one word below the
14338 stack address we wish to restore. */
14339 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14340 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14341 tmp = gen_rtx_MEM (Pmode, tmp);
14342 emit_move_insn (tmp, ra);
14343
14344 if (Pmode == SImode)
14345 emit_insn (gen_eh_return_si (sa));
14346 else
14347 emit_insn (gen_eh_return_di (sa));
14348 emit_barrier ();
14349 DONE;
14350 })
14351
14352 (define_insn_and_split "eh_return_si"
14353 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
14354 UNSPECV_EH_RETURN)]
14355 "!TARGET_64BIT"
14356 "#"
14357 "reload_completed"
14358 [(const_int 1)]
14359 "ix86_expand_epilogue (2); DONE;")
14360
14361 (define_insn_and_split "eh_return_di"
14362 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14363 UNSPECV_EH_RETURN)]
14364 "TARGET_64BIT"
14365 "#"
14366 "reload_completed"
14367 [(const_int 1)]
14368 "ix86_expand_epilogue (2); DONE;")
14369
14370 (define_insn "leave"
14371 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14372 (set (reg:SI 6) (mem:SI (reg:SI 6)))
14373 (clobber (mem:BLK (scratch)))]
14374 "!TARGET_64BIT"
14375 "leave"
14376 [(set_attr "type" "leave")])
14377
14378 (define_insn "leave_rex64"
14379 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14380 (set (reg:DI 6) (mem:DI (reg:DI 6)))
14381 (clobber (mem:BLK (scratch)))]
14382 "TARGET_64BIT"
14383 "leave"
14384 [(set_attr "type" "leave")])
14385 \f
14386 (define_expand "ffssi2"
14387 [(parallel
14388 [(set (match_operand:SI 0 "register_operand" "")
14389 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14390 (clobber (match_scratch:SI 2 ""))
14391 (clobber (reg:CC 17))])]
14392 ""
14393 "")
14394
14395 (define_insn_and_split "*ffs_cmove"
14396 [(set (match_operand:SI 0 "register_operand" "=r")
14397 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14398 (clobber (match_scratch:SI 2 "=&r"))
14399 (clobber (reg:CC 17))]
14400 "TARGET_CMOVE"
14401 "#"
14402 "&& reload_completed"
14403 [(set (match_dup 2) (const_int -1))
14404 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14405 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14406 (set (match_dup 0) (if_then_else:SI
14407 (eq (reg:CCZ 17) (const_int 0))
14408 (match_dup 2)
14409 (match_dup 0)))
14410 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14411 (clobber (reg:CC 17))])]
14412 "")
14413
14414 (define_insn_and_split "*ffs_no_cmove"
14415 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14416 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14417 (clobber (match_scratch:SI 2 "=&r"))
14418 (clobber (reg:CC 17))]
14419 ""
14420 "#"
14421 "reload_completed"
14422 [(parallel [(set (match_dup 2) (const_int 0))
14423 (clobber (reg:CC 17))])
14424 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14425 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14426 (set (strict_low_part (match_dup 3))
14427 (eq:QI (reg:CCZ 17) (const_int 0)))
14428 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14429 (clobber (reg:CC 17))])
14430 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14431 (clobber (reg:CC 17))])
14432 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14433 (clobber (reg:CC 17))])]
14434 {
14435 operands[3] = gen_lowpart (QImode, operands[2]);
14436 })
14437
14438 (define_insn "*ffssi_1"
14439 [(set (reg:CCZ 17)
14440 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14441 (const_int 0)))
14442 (set (match_operand:SI 0 "register_operand" "=r")
14443 (ctz:SI (match_dup 1)))]
14444 ""
14445 "bsf{l}\t{%1, %0|%0, %1}"
14446 [(set_attr "prefix_0f" "1")
14447 (set_attr "ppro_uops" "few")])
14448
14449 (define_insn "ctzsi2"
14450 [(set (match_operand:SI 0 "register_operand" "=r")
14451 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14452 (clobber (reg:CC 17))]
14453 ""
14454 "bsf{l}\t{%1, %0|%0, %1}"
14455 [(set_attr "prefix_0f" "1")
14456 (set_attr "ppro_uops" "few")])
14457
14458 (define_expand "clzsi2"
14459 [(parallel
14460 [(set (match_operand:SI 0 "register_operand" "")
14461 (minus:SI (const_int 31)
14462 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14463 (clobber (reg:CC 17))])
14464 (parallel
14465 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14466 (clobber (reg:CC 17))])]
14467 ""
14468 "")
14469
14470 (define_insn "*bsr"
14471 [(set (match_operand:SI 0 "register_operand" "=r")
14472 (minus:SI (const_int 31)
14473 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14474 (clobber (reg:CC 17))]
14475 ""
14476 "bsr{l}\t{%1, %0|%0, %1}"
14477 [(set_attr "prefix_0f" "1")
14478 (set_attr "ppro_uops" "few")])
14479 \f
14480 ;; Thread-local storage patterns for ELF.
14481 ;;
14482 ;; Note that these code sequences must appear exactly as shown
14483 ;; in order to allow linker relaxation.
14484
14485 (define_insn "*tls_global_dynamic_32_gnu"
14486 [(set (match_operand:SI 0 "register_operand" "=a")
14487 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14488 (match_operand:SI 2 "tls_symbolic_operand" "")
14489 (match_operand:SI 3 "call_insn_operand" "")]
14490 UNSPEC_TLS_GD))
14491 (clobber (match_scratch:SI 4 "=d"))
14492 (clobber (match_scratch:SI 5 "=c"))
14493 (clobber (reg:CC 17))]
14494 "!TARGET_64BIT && TARGET_GNU_TLS"
14495 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14496 [(set_attr "type" "multi")
14497 (set_attr "length" "12")])
14498
14499 (define_insn "*tls_global_dynamic_32_sun"
14500 [(set (match_operand:SI 0 "register_operand" "=a")
14501 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14502 (match_operand:SI 2 "tls_symbolic_operand" "")
14503 (match_operand:SI 3 "call_insn_operand" "")]
14504 UNSPEC_TLS_GD))
14505 (clobber (match_scratch:SI 4 "=d"))
14506 (clobber (match_scratch:SI 5 "=c"))
14507 (clobber (reg:CC 17))]
14508 "!TARGET_64BIT && TARGET_SUN_TLS"
14509 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14510 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14511 [(set_attr "type" "multi")
14512 (set_attr "length" "14")])
14513
14514 (define_expand "tls_global_dynamic_32"
14515 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14516 (unspec:SI
14517 [(match_dup 2)
14518 (match_operand:SI 1 "tls_symbolic_operand" "")
14519 (match_dup 3)]
14520 UNSPEC_TLS_GD))
14521 (clobber (match_scratch:SI 4 ""))
14522 (clobber (match_scratch:SI 5 ""))
14523 (clobber (reg:CC 17))])]
14524 ""
14525 {
14526 if (flag_pic)
14527 operands[2] = pic_offset_table_rtx;
14528 else
14529 {
14530 operands[2] = gen_reg_rtx (Pmode);
14531 emit_insn (gen_set_got (operands[2]));
14532 }
14533 operands[3] = ix86_tls_get_addr ();
14534 })
14535
14536 (define_insn "*tls_global_dynamic_64"
14537 [(set (match_operand:DI 0 "register_operand" "=a")
14538 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14539 (match_operand:DI 3 "" "")))
14540 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14541 UNSPEC_TLS_GD)]
14542 "TARGET_64BIT"
14543 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14544 [(set_attr "type" "multi")
14545 (set_attr "length" "16")])
14546
14547 (define_expand "tls_global_dynamic_64"
14548 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14549 (call (mem:QI (match_dup 2)) (const_int 0)))
14550 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14551 UNSPEC_TLS_GD)])]
14552 ""
14553 {
14554 operands[2] = ix86_tls_get_addr ();
14555 })
14556
14557 (define_insn "*tls_local_dynamic_base_32_gnu"
14558 [(set (match_operand:SI 0 "register_operand" "=a")
14559 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14560 (match_operand:SI 2 "call_insn_operand" "")]
14561 UNSPEC_TLS_LD_BASE))
14562 (clobber (match_scratch:SI 3 "=d"))
14563 (clobber (match_scratch:SI 4 "=c"))
14564 (clobber (reg:CC 17))]
14565 "!TARGET_64BIT && TARGET_GNU_TLS"
14566 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14567 [(set_attr "type" "multi")
14568 (set_attr "length" "11")])
14569
14570 (define_insn "*tls_local_dynamic_base_32_sun"
14571 [(set (match_operand:SI 0 "register_operand" "=a")
14572 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14573 (match_operand:SI 2 "call_insn_operand" "")]
14574 UNSPEC_TLS_LD_BASE))
14575 (clobber (match_scratch:SI 3 "=d"))
14576 (clobber (match_scratch:SI 4 "=c"))
14577 (clobber (reg:CC 17))]
14578 "!TARGET_64BIT && TARGET_SUN_TLS"
14579 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14580 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14581 [(set_attr "type" "multi")
14582 (set_attr "length" "13")])
14583
14584 (define_expand "tls_local_dynamic_base_32"
14585 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14586 (unspec:SI [(match_dup 1) (match_dup 2)]
14587 UNSPEC_TLS_LD_BASE))
14588 (clobber (match_scratch:SI 3 ""))
14589 (clobber (match_scratch:SI 4 ""))
14590 (clobber (reg:CC 17))])]
14591 ""
14592 {
14593 if (flag_pic)
14594 operands[1] = pic_offset_table_rtx;
14595 else
14596 {
14597 operands[1] = gen_reg_rtx (Pmode);
14598 emit_insn (gen_set_got (operands[1]));
14599 }
14600 operands[2] = ix86_tls_get_addr ();
14601 })
14602
14603 (define_insn "*tls_local_dynamic_base_64"
14604 [(set (match_operand:DI 0 "register_operand" "=a")
14605 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14606 (match_operand:DI 2 "" "")))
14607 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14608 "TARGET_64BIT"
14609 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14610 [(set_attr "type" "multi")
14611 (set_attr "length" "12")])
14612
14613 (define_expand "tls_local_dynamic_base_64"
14614 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14615 (call (mem:QI (match_dup 1)) (const_int 0)))
14616 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14617 ""
14618 {
14619 operands[1] = ix86_tls_get_addr ();
14620 })
14621
14622 ;; Local dynamic of a single variable is a lose. Show combine how
14623 ;; to convert that back to global dynamic.
14624
14625 (define_insn_and_split "*tls_local_dynamic_32_once"
14626 [(set (match_operand:SI 0 "register_operand" "=a")
14627 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14628 (match_operand:SI 2 "call_insn_operand" "")]
14629 UNSPEC_TLS_LD_BASE)
14630 (const:SI (unspec:SI
14631 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14632 UNSPEC_DTPOFF))))
14633 (clobber (match_scratch:SI 4 "=d"))
14634 (clobber (match_scratch:SI 5 "=c"))
14635 (clobber (reg:CC 17))]
14636 ""
14637 "#"
14638 ""
14639 [(parallel [(set (match_dup 0)
14640 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14641 UNSPEC_TLS_GD))
14642 (clobber (match_dup 4))
14643 (clobber (match_dup 5))
14644 (clobber (reg:CC 17))])]
14645 "")
14646
14647 ;; Load and add the thread base pointer from %gs:0.
14648
14649 (define_insn "*load_tp_si"
14650 [(set (match_operand:SI 0 "register_operand" "=r")
14651 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14652 "!TARGET_64BIT"
14653 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14654 [(set_attr "type" "imov")
14655 (set_attr "modrm" "0")
14656 (set_attr "length" "7")
14657 (set_attr "memory" "load")
14658 (set_attr "imm_disp" "false")])
14659
14660 (define_insn "*add_tp_si"
14661 [(set (match_operand:SI 0 "register_operand" "=r")
14662 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14663 (match_operand:SI 1 "register_operand" "0")))
14664 (clobber (reg:CC 17))]
14665 "!TARGET_64BIT"
14666 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14667 [(set_attr "type" "alu")
14668 (set_attr "modrm" "0")
14669 (set_attr "length" "7")
14670 (set_attr "memory" "load")
14671 (set_attr "imm_disp" "false")])
14672
14673 (define_insn "*load_tp_di"
14674 [(set (match_operand:DI 0 "register_operand" "=r")
14675 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14676 "TARGET_64BIT"
14677 "mov{l}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14678 [(set_attr "type" "imov")
14679 (set_attr "modrm" "0")
14680 (set_attr "length" "7")
14681 (set_attr "memory" "load")
14682 (set_attr "imm_disp" "false")])
14683
14684 (define_insn "*add_tp_di"
14685 [(set (match_operand:DI 0 "register_operand" "=r")
14686 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14687 (match_operand:DI 1 "register_operand" "0")))
14688 (clobber (reg:CC 17))]
14689 "TARGET_64BIT"
14690 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14691 [(set_attr "type" "alu")
14692 (set_attr "modrm" "0")
14693 (set_attr "length" "7")
14694 (set_attr "memory" "load")
14695 (set_attr "imm_disp" "false")])
14696 \f
14697 ;; These patterns match the binary 387 instructions for addM3, subM3,
14698 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14699 ;; SFmode. The first is the normal insn, the second the same insn but
14700 ;; with one operand a conversion, and the third the same insn but with
14701 ;; the other operand a conversion. The conversion may be SFmode or
14702 ;; SImode if the target mode DFmode, but only SImode if the target mode
14703 ;; is SFmode.
14704
14705 ;; Gcc is slightly more smart about handling normal two address instructions
14706 ;; so use special patterns for add and mull.
14707 (define_insn "*fop_sf_comm_nosse"
14708 [(set (match_operand:SF 0 "register_operand" "=f")
14709 (match_operator:SF 3 "binary_fp_operator"
14710 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14711 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14712 "TARGET_80387 && !TARGET_SSE_MATH
14713 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14714 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14715 "* return output_387_binary_op (insn, operands);"
14716 [(set (attr "type")
14717 (if_then_else (match_operand:SF 3 "mult_operator" "")
14718 (const_string "fmul")
14719 (const_string "fop")))
14720 (set_attr "mode" "SF")])
14721
14722 (define_insn "*fop_sf_comm"
14723 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14724 (match_operator:SF 3 "binary_fp_operator"
14725 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14726 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14727 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14728 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14729 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14730 "* return output_387_binary_op (insn, operands);"
14731 [(set (attr "type")
14732 (if_then_else (eq_attr "alternative" "1")
14733 (if_then_else (match_operand:SF 3 "mult_operator" "")
14734 (const_string "ssemul")
14735 (const_string "sseadd"))
14736 (if_then_else (match_operand:SF 3 "mult_operator" "")
14737 (const_string "fmul")
14738 (const_string "fop"))))
14739 (set_attr "mode" "SF")])
14740
14741 (define_insn "*fop_sf_comm_sse"
14742 [(set (match_operand:SF 0 "register_operand" "=x")
14743 (match_operator:SF 3 "binary_fp_operator"
14744 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14745 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14746 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14747 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14748 "* return output_387_binary_op (insn, operands);"
14749 [(set (attr "type")
14750 (if_then_else (match_operand:SF 3 "mult_operator" "")
14751 (const_string "ssemul")
14752 (const_string "sseadd")))
14753 (set_attr "mode" "SF")])
14754
14755 (define_insn "*fop_df_comm_nosse"
14756 [(set (match_operand:DF 0 "register_operand" "=f")
14757 (match_operator:DF 3 "binary_fp_operator"
14758 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14759 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14760 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14761 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14762 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14763 "* return output_387_binary_op (insn, operands);"
14764 [(set (attr "type")
14765 (if_then_else (match_operand:SF 3 "mult_operator" "")
14766 (const_string "fmul")
14767 (const_string "fop")))
14768 (set_attr "mode" "DF")])
14769
14770 (define_insn "*fop_df_comm"
14771 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14772 (match_operator:DF 3 "binary_fp_operator"
14773 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14774 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14775 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14776 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14777 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14778 "* return output_387_binary_op (insn, operands);"
14779 [(set (attr "type")
14780 (if_then_else (eq_attr "alternative" "1")
14781 (if_then_else (match_operand:SF 3 "mult_operator" "")
14782 (const_string "ssemul")
14783 (const_string "sseadd"))
14784 (if_then_else (match_operand:SF 3 "mult_operator" "")
14785 (const_string "fmul")
14786 (const_string "fop"))))
14787 (set_attr "mode" "DF")])
14788
14789 (define_insn "*fop_df_comm_sse"
14790 [(set (match_operand:DF 0 "register_operand" "=Y")
14791 (match_operator:DF 3 "binary_fp_operator"
14792 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14793 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14794 "TARGET_SSE2 && TARGET_SSE_MATH
14795 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14796 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14797 "* return output_387_binary_op (insn, operands);"
14798 [(set (attr "type")
14799 (if_then_else (match_operand:SF 3 "mult_operator" "")
14800 (const_string "ssemul")
14801 (const_string "sseadd")))
14802 (set_attr "mode" "DF")])
14803
14804 (define_insn "*fop_xf_comm"
14805 [(set (match_operand:XF 0 "register_operand" "=f")
14806 (match_operator:XF 3 "binary_fp_operator"
14807 [(match_operand:XF 1 "register_operand" "%0")
14808 (match_operand:XF 2 "register_operand" "f")]))]
14809 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
14810 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14811 "* return output_387_binary_op (insn, operands);"
14812 [(set (attr "type")
14813 (if_then_else (match_operand:XF 3 "mult_operator" "")
14814 (const_string "fmul")
14815 (const_string "fop")))
14816 (set_attr "mode" "XF")])
14817
14818 (define_insn "*fop_tf_comm"
14819 [(set (match_operand:TF 0 "register_operand" "=f")
14820 (match_operator:TF 3 "binary_fp_operator"
14821 [(match_operand:TF 1 "register_operand" "%0")
14822 (match_operand:TF 2 "register_operand" "f")]))]
14823 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14824 "* return output_387_binary_op (insn, operands);"
14825 [(set (attr "type")
14826 (if_then_else (match_operand:TF 3 "mult_operator" "")
14827 (const_string "fmul")
14828 (const_string "fop")))
14829 (set_attr "mode" "XF")])
14830
14831 (define_insn "*fop_sf_1_nosse"
14832 [(set (match_operand:SF 0 "register_operand" "=f,f")
14833 (match_operator:SF 3 "binary_fp_operator"
14834 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14835 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14836 "TARGET_80387 && !TARGET_SSE_MATH
14837 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14838 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14839 "* return output_387_binary_op (insn, operands);"
14840 [(set (attr "type")
14841 (cond [(match_operand:SF 3 "mult_operator" "")
14842 (const_string "fmul")
14843 (match_operand:SF 3 "div_operator" "")
14844 (const_string "fdiv")
14845 ]
14846 (const_string "fop")))
14847 (set_attr "mode" "SF")])
14848
14849 (define_insn "*fop_sf_1"
14850 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14851 (match_operator:SF 3 "binary_fp_operator"
14852 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14853 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14854 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14855 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14856 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14857 "* return output_387_binary_op (insn, operands);"
14858 [(set (attr "type")
14859 (cond [(and (eq_attr "alternative" "2")
14860 (match_operand:SF 3 "mult_operator" ""))
14861 (const_string "ssemul")
14862 (and (eq_attr "alternative" "2")
14863 (match_operand:SF 3 "div_operator" ""))
14864 (const_string "ssediv")
14865 (eq_attr "alternative" "2")
14866 (const_string "sseadd")
14867 (match_operand:SF 3 "mult_operator" "")
14868 (const_string "fmul")
14869 (match_operand:SF 3 "div_operator" "")
14870 (const_string "fdiv")
14871 ]
14872 (const_string "fop")))
14873 (set_attr "mode" "SF")])
14874
14875 (define_insn "*fop_sf_1_sse"
14876 [(set (match_operand:SF 0 "register_operand" "=x")
14877 (match_operator:SF 3 "binary_fp_operator"
14878 [(match_operand:SF 1 "register_operand" "0")
14879 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14880 "TARGET_SSE_MATH
14881 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14882 "* return output_387_binary_op (insn, operands);"
14883 [(set (attr "type")
14884 (cond [(match_operand:SF 3 "mult_operator" "")
14885 (const_string "ssemul")
14886 (match_operand:SF 3 "div_operator" "")
14887 (const_string "ssediv")
14888 ]
14889 (const_string "sseadd")))
14890 (set_attr "mode" "SF")])
14891
14892 ;; ??? Add SSE splitters for these!
14893 (define_insn "*fop_sf_2"
14894 [(set (match_operand:SF 0 "register_operand" "=f,f")
14895 (match_operator:SF 3 "binary_fp_operator"
14896 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14897 (match_operand:SF 2 "register_operand" "0,0")]))]
14898 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14899 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14900 [(set (attr "type")
14901 (cond [(match_operand:SF 3 "mult_operator" "")
14902 (const_string "fmul")
14903 (match_operand:SF 3 "div_operator" "")
14904 (const_string "fdiv")
14905 ]
14906 (const_string "fop")))
14907 (set_attr "fp_int_src" "true")
14908 (set_attr "ppro_uops" "many")
14909 (set_attr "mode" "SI")])
14910
14911 (define_insn "*fop_sf_3"
14912 [(set (match_operand:SF 0 "register_operand" "=f,f")
14913 (match_operator:SF 3 "binary_fp_operator"
14914 [(match_operand:SF 1 "register_operand" "0,0")
14915 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14916 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14917 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14918 [(set (attr "type")
14919 (cond [(match_operand:SF 3 "mult_operator" "")
14920 (const_string "fmul")
14921 (match_operand:SF 3 "div_operator" "")
14922 (const_string "fdiv")
14923 ]
14924 (const_string "fop")))
14925 (set_attr "fp_int_src" "true")
14926 (set_attr "ppro_uops" "many")
14927 (set_attr "mode" "SI")])
14928
14929 (define_insn "*fop_df_1_nosse"
14930 [(set (match_operand:DF 0 "register_operand" "=f,f")
14931 (match_operator:DF 3 "binary_fp_operator"
14932 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14933 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14934 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14935 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14936 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14937 "* return output_387_binary_op (insn, operands);"
14938 [(set (attr "type")
14939 (cond [(match_operand:DF 3 "mult_operator" "")
14940 (const_string "fmul")
14941 (match_operand:DF 3 "div_operator" "")
14942 (const_string "fdiv")
14943 ]
14944 (const_string "fop")))
14945 (set_attr "mode" "DF")])
14946
14947
14948 (define_insn "*fop_df_1"
14949 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14950 (match_operator:DF 3 "binary_fp_operator"
14951 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14952 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14953 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14954 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14955 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14956 "* return output_387_binary_op (insn, operands);"
14957 [(set (attr "type")
14958 (cond [(and (eq_attr "alternative" "2")
14959 (match_operand:SF 3 "mult_operator" ""))
14960 (const_string "ssemul")
14961 (and (eq_attr "alternative" "2")
14962 (match_operand:SF 3 "div_operator" ""))
14963 (const_string "ssediv")
14964 (eq_attr "alternative" "2")
14965 (const_string "sseadd")
14966 (match_operand:DF 3 "mult_operator" "")
14967 (const_string "fmul")
14968 (match_operand:DF 3 "div_operator" "")
14969 (const_string "fdiv")
14970 ]
14971 (const_string "fop")))
14972 (set_attr "mode" "DF")])
14973
14974 (define_insn "*fop_df_1_sse"
14975 [(set (match_operand:DF 0 "register_operand" "=Y")
14976 (match_operator:DF 3 "binary_fp_operator"
14977 [(match_operand:DF 1 "register_operand" "0")
14978 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14979 "TARGET_SSE2 && TARGET_SSE_MATH
14980 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14981 "* return output_387_binary_op (insn, operands);"
14982 [(set_attr "mode" "DF")
14983 (set (attr "type")
14984 (cond [(match_operand:SF 3 "mult_operator" "")
14985 (const_string "ssemul")
14986 (match_operand:SF 3 "div_operator" "")
14987 (const_string "ssediv")
14988 ]
14989 (const_string "sseadd")))])
14990
14991 ;; ??? Add SSE splitters for these!
14992 (define_insn "*fop_df_2"
14993 [(set (match_operand:DF 0 "register_operand" "=f,f")
14994 (match_operator:DF 3 "binary_fp_operator"
14995 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14996 (match_operand:DF 2 "register_operand" "0,0")]))]
14997 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14998 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14999 [(set (attr "type")
15000 (cond [(match_operand:DF 3 "mult_operator" "")
15001 (const_string "fmul")
15002 (match_operand:DF 3 "div_operator" "")
15003 (const_string "fdiv")
15004 ]
15005 (const_string "fop")))
15006 (set_attr "fp_int_src" "true")
15007 (set_attr "ppro_uops" "many")
15008 (set_attr "mode" "SI")])
15009
15010 (define_insn "*fop_df_3"
15011 [(set (match_operand:DF 0 "register_operand" "=f,f")
15012 (match_operator:DF 3 "binary_fp_operator"
15013 [(match_operand:DF 1 "register_operand" "0,0")
15014 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15015 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15016 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15017 [(set (attr "type")
15018 (cond [(match_operand:DF 3 "mult_operator" "")
15019 (const_string "fmul")
15020 (match_operand:DF 3 "div_operator" "")
15021 (const_string "fdiv")
15022 ]
15023 (const_string "fop")))
15024 (set_attr "fp_int_src" "true")
15025 (set_attr "ppro_uops" "many")
15026 (set_attr "mode" "SI")])
15027
15028 (define_insn "*fop_df_4"
15029 [(set (match_operand:DF 0 "register_operand" "=f,f")
15030 (match_operator:DF 3 "binary_fp_operator"
15031 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15032 (match_operand:DF 2 "register_operand" "0,f")]))]
15033 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
15034 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15035 "* return output_387_binary_op (insn, operands);"
15036 [(set (attr "type")
15037 (cond [(match_operand:DF 3 "mult_operator" "")
15038 (const_string "fmul")
15039 (match_operand:DF 3 "div_operator" "")
15040 (const_string "fdiv")
15041 ]
15042 (const_string "fop")))
15043 (set_attr "mode" "SF")])
15044
15045 (define_insn "*fop_df_5"
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,f")
15049 (float_extend:DF
15050 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15051 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15052 "* return output_387_binary_op (insn, operands);"
15053 [(set (attr "type")
15054 (cond [(match_operand:DF 3 "mult_operator" "")
15055 (const_string "fmul")
15056 (match_operand:DF 3 "div_operator" "")
15057 (const_string "fdiv")
15058 ]
15059 (const_string "fop")))
15060 (set_attr "mode" "SF")])
15061
15062 (define_insn "*fop_df_6"
15063 [(set (match_operand:DF 0 "register_operand" "=f,f")
15064 (match_operator:DF 3 "binary_fp_operator"
15065 [(float_extend:DF
15066 (match_operand:SF 1 "register_operand" "0,f"))
15067 (float_extend:DF
15068 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15069 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
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_xf_1"
15081 [(set (match_operand:XF 0 "register_operand" "=f,f")
15082 (match_operator:XF 3 "binary_fp_operator"
15083 [(match_operand:XF 1 "register_operand" "0,f")
15084 (match_operand:XF 2 "register_operand" "f,0")]))]
15085 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
15086 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15087 "* return output_387_binary_op (insn, operands);"
15088 [(set (attr "type")
15089 (cond [(match_operand:XF 3 "mult_operator" "")
15090 (const_string "fmul")
15091 (match_operand:XF 3 "div_operator" "")
15092 (const_string "fdiv")
15093 ]
15094 (const_string "fop")))
15095 (set_attr "mode" "XF")])
15096
15097 (define_insn "*fop_tf_1"
15098 [(set (match_operand:TF 0 "register_operand" "=f,f")
15099 (match_operator:TF 3 "binary_fp_operator"
15100 [(match_operand:TF 1 "register_operand" "0,f")
15101 (match_operand:TF 2 "register_operand" "f,0")]))]
15102 "TARGET_80387
15103 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15104 "* return output_387_binary_op (insn, operands);"
15105 [(set (attr "type")
15106 (cond [(match_operand:TF 3 "mult_operator" "")
15107 (const_string "fmul")
15108 (match_operand:TF 3 "div_operator" "")
15109 (const_string "fdiv")
15110 ]
15111 (const_string "fop")))
15112 (set_attr "mode" "XF")])
15113
15114 (define_insn "*fop_xf_2"
15115 [(set (match_operand:XF 0 "register_operand" "=f,f")
15116 (match_operator:XF 3 "binary_fp_operator"
15117 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15118 (match_operand:XF 2 "register_operand" "0,0")]))]
15119 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15120 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15121 [(set (attr "type")
15122 (cond [(match_operand:XF 3 "mult_operator" "")
15123 (const_string "fmul")
15124 (match_operand:XF 3 "div_operator" "")
15125 (const_string "fdiv")
15126 ]
15127 (const_string "fop")))
15128 (set_attr "fp_int_src" "true")
15129 (set_attr "mode" "SI")
15130 (set_attr "ppro_uops" "many")])
15131
15132 (define_insn "*fop_tf_2"
15133 [(set (match_operand:TF 0 "register_operand" "=f,f")
15134 (match_operator:TF 3 "binary_fp_operator"
15135 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15136 (match_operand:TF 2 "register_operand" "0,0")]))]
15137 "TARGET_80387 && TARGET_USE_FIOP"
15138 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15139 [(set (attr "type")
15140 (cond [(match_operand:TF 3 "mult_operator" "")
15141 (const_string "fmul")
15142 (match_operand:TF 3 "div_operator" "")
15143 (const_string "fdiv")
15144 ]
15145 (const_string "fop")))
15146 (set_attr "fp_int_src" "true")
15147 (set_attr "mode" "SI")
15148 (set_attr "ppro_uops" "many")])
15149
15150 (define_insn "*fop_xf_3"
15151 [(set (match_operand:XF 0 "register_operand" "=f,f")
15152 (match_operator:XF 3 "binary_fp_operator"
15153 [(match_operand:XF 1 "register_operand" "0,0")
15154 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15155 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15156 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15157 [(set (attr "type")
15158 (cond [(match_operand:XF 3 "mult_operator" "")
15159 (const_string "fmul")
15160 (match_operand:XF 3 "div_operator" "")
15161 (const_string "fdiv")
15162 ]
15163 (const_string "fop")))
15164 (set_attr "fp_int_src" "true")
15165 (set_attr "mode" "SI")
15166 (set_attr "ppro_uops" "many")])
15167
15168 (define_insn "*fop_tf_3"
15169 [(set (match_operand:TF 0 "register_operand" "=f,f")
15170 (match_operator:TF 3 "binary_fp_operator"
15171 [(match_operand:TF 1 "register_operand" "0,0")
15172 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15173 "TARGET_80387 && TARGET_USE_FIOP"
15174 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15175 [(set (attr "type")
15176 (cond [(match_operand:TF 3 "mult_operator" "")
15177 (const_string "fmul")
15178 (match_operand:TF 3 "div_operator" "")
15179 (const_string "fdiv")
15180 ]
15181 (const_string "fop")))
15182 (set_attr "fp_int_src" "true")
15183 (set_attr "mode" "SI")
15184 (set_attr "ppro_uops" "many")])
15185
15186 (define_insn "*fop_xf_4"
15187 [(set (match_operand:XF 0 "register_operand" "=f,f")
15188 (match_operator:XF 3 "binary_fp_operator"
15189 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15190 (match_operand:XF 2 "register_operand" "0,f")]))]
15191 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15192 "* return output_387_binary_op (insn, operands);"
15193 [(set (attr "type")
15194 (cond [(match_operand:XF 3 "mult_operator" "")
15195 (const_string "fmul")
15196 (match_operand:XF 3 "div_operator" "")
15197 (const_string "fdiv")
15198 ]
15199 (const_string "fop")))
15200 (set_attr "mode" "SF")])
15201
15202 (define_insn "*fop_tf_4"
15203 [(set (match_operand:TF 0 "register_operand" "=f,f")
15204 (match_operator:TF 3 "binary_fp_operator"
15205 [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
15206 (match_operand:TF 2 "register_operand" "0,f")]))]
15207 "TARGET_80387"
15208 "* return output_387_binary_op (insn, operands);"
15209 [(set (attr "type")
15210 (cond [(match_operand:TF 3 "mult_operator" "")
15211 (const_string "fmul")
15212 (match_operand:TF 3 "div_operator" "")
15213 (const_string "fdiv")
15214 ]
15215 (const_string "fop")))
15216 (set_attr "mode" "SF")])
15217
15218 (define_insn "*fop_xf_5"
15219 [(set (match_operand:XF 0 "register_operand" "=f,f")
15220 (match_operator:XF 3 "binary_fp_operator"
15221 [(match_operand:XF 1 "register_operand" "0,f")
15222 (float_extend:XF
15223 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15224 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15225 "* return output_387_binary_op (insn, operands);"
15226 [(set (attr "type")
15227 (cond [(match_operand:XF 3 "mult_operator" "")
15228 (const_string "fmul")
15229 (match_operand:XF 3 "div_operator" "")
15230 (const_string "fdiv")
15231 ]
15232 (const_string "fop")))
15233 (set_attr "mode" "SF")])
15234
15235 (define_insn "*fop_tf_5"
15236 [(set (match_operand:TF 0 "register_operand" "=f,f")
15237 (match_operator:TF 3 "binary_fp_operator"
15238 [(match_operand:TF 1 "register_operand" "0,f")
15239 (float_extend:TF
15240 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15241 "TARGET_80387"
15242 "* return output_387_binary_op (insn, operands);"
15243 [(set (attr "type")
15244 (cond [(match_operand:TF 3 "mult_operator" "")
15245 (const_string "fmul")
15246 (match_operand:TF 3 "div_operator" "")
15247 (const_string "fdiv")
15248 ]
15249 (const_string "fop")))
15250 (set_attr "mode" "SF")])
15251
15252 (define_insn "*fop_xf_6"
15253 [(set (match_operand:XF 0 "register_operand" "=f,f")
15254 (match_operator:XF 3 "binary_fp_operator"
15255 [(float_extend:XF
15256 (match_operand 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_6"
15271 [(set (match_operand:TF 0 "register_operand" "=f,f")
15272 (match_operator:TF 3 "binary_fp_operator"
15273 [(float_extend:TF
15274 (match_operand 1 "register_operand" "0,f"))
15275 (float_extend:TF
15276 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15277 "TARGET_80387"
15278 "* return output_387_binary_op (insn, operands);"
15279 [(set (attr "type")
15280 (cond [(match_operand:TF 3 "mult_operator" "")
15281 (const_string "fmul")
15282 (match_operand:TF 3 "div_operator" "")
15283 (const_string "fdiv")
15284 ]
15285 (const_string "fop")))
15286 (set_attr "mode" "SF")])
15287
15288 (define_split
15289 [(set (match_operand 0 "register_operand" "")
15290 (match_operator 3 "binary_fp_operator"
15291 [(float (match_operand:SI 1 "register_operand" ""))
15292 (match_operand 2 "register_operand" "")]))]
15293 "TARGET_80387 && reload_completed
15294 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15295 [(const_int 0)]
15296 {
15297 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15298 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15299 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15300 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15301 GET_MODE (operands[3]),
15302 operands[4],
15303 operands[2])));
15304 ix86_free_from_memory (GET_MODE (operands[1]));
15305 DONE;
15306 })
15307
15308 (define_split
15309 [(set (match_operand 0 "register_operand" "")
15310 (match_operator 3 "binary_fp_operator"
15311 [(match_operand 1 "register_operand" "")
15312 (float (match_operand:SI 2 "register_operand" ""))]))]
15313 "TARGET_80387 && reload_completed
15314 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15315 [(const_int 0)]
15316 {
15317 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15318 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15319 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15320 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15321 GET_MODE (operands[3]),
15322 operands[1],
15323 operands[4])));
15324 ix86_free_from_memory (GET_MODE (operands[2]));
15325 DONE;
15326 })
15327 \f
15328 ;; FPU special functions.
15329
15330 (define_expand "sqrtsf2"
15331 [(set (match_operand:SF 0 "register_operand" "")
15332 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15333 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
15334 {
15335 if (!TARGET_SSE_MATH)
15336 operands[1] = force_reg (SFmode, operands[1]);
15337 })
15338
15339 (define_insn "sqrtsf2_1"
15340 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15341 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15342 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15343 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15344 "@
15345 fsqrt
15346 sqrtss\t{%1, %0|%0, %1}"
15347 [(set_attr "type" "fpspc,sse")
15348 (set_attr "mode" "SF,SF")
15349 (set_attr "athlon_decode" "direct,*")])
15350
15351 (define_insn "sqrtsf2_1_sse_only"
15352 [(set (match_operand:SF 0 "register_operand" "=x")
15353 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15354 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15355 "sqrtss\t{%1, %0|%0, %1}"
15356 [(set_attr "type" "sse")
15357 (set_attr "mode" "SF")
15358 (set_attr "athlon_decode" "*")])
15359
15360 (define_insn "sqrtsf2_i387"
15361 [(set (match_operand:SF 0 "register_operand" "=f")
15362 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15363 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15364 && !TARGET_SSE_MATH"
15365 "fsqrt"
15366 [(set_attr "type" "fpspc")
15367 (set_attr "mode" "SF")
15368 (set_attr "athlon_decode" "direct")])
15369
15370 (define_expand "sqrtdf2"
15371 [(set (match_operand:DF 0 "register_operand" "")
15372 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15373 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
15374 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15375 {
15376 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
15377 operands[1] = force_reg (DFmode, operands[1]);
15378 })
15379
15380 (define_insn "sqrtdf2_1"
15381 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15382 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15383 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15384 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15385 "@
15386 fsqrt
15387 sqrtsd\t{%1, %0|%0, %1}"
15388 [(set_attr "type" "fpspc,sse")
15389 (set_attr "mode" "DF,DF")
15390 (set_attr "athlon_decode" "direct,*")])
15391
15392 (define_insn "sqrtdf2_1_sse_only"
15393 [(set (match_operand:DF 0 "register_operand" "=Y")
15394 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15395 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15396 "sqrtsd\t{%1, %0|%0, %1}"
15397 [(set_attr "type" "sse")
15398 (set_attr "mode" "DF")
15399 (set_attr "athlon_decode" "*")])
15400
15401 (define_insn "sqrtdf2_i387"
15402 [(set (match_operand:DF 0 "register_operand" "=f")
15403 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15404 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15405 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
15406 "fsqrt"
15407 [(set_attr "type" "fpspc")
15408 (set_attr "mode" "DF")
15409 (set_attr "athlon_decode" "direct")])
15410
15411 (define_insn "*sqrtextendsfdf2"
15412 [(set (match_operand:DF 0 "register_operand" "=f")
15413 (sqrt:DF (float_extend:DF
15414 (match_operand:SF 1 "register_operand" "0"))))]
15415 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15416 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15417 "fsqrt"
15418 [(set_attr "type" "fpspc")
15419 (set_attr "mode" "DF")
15420 (set_attr "athlon_decode" "direct")])
15421
15422 (define_insn "sqrtxf2"
15423 [(set (match_operand:XF 0 "register_operand" "=f")
15424 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15425 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15426 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15427 "fsqrt"
15428 [(set_attr "type" "fpspc")
15429 (set_attr "mode" "XF")
15430 (set_attr "athlon_decode" "direct")])
15431
15432 (define_insn "sqrttf2"
15433 [(set (match_operand:TF 0 "register_operand" "=f")
15434 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
15435 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15436 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15437 "fsqrt"
15438 [(set_attr "type" "fpspc")
15439 (set_attr "mode" "XF")
15440 (set_attr "athlon_decode" "direct")])
15441
15442 (define_insn "*sqrtextenddfxf2"
15443 [(set (match_operand:XF 0 "register_operand" "=f")
15444 (sqrt:XF (float_extend:XF
15445 (match_operand:DF 1 "register_operand" "0"))))]
15446 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15447 "fsqrt"
15448 [(set_attr "type" "fpspc")
15449 (set_attr "mode" "XF")
15450 (set_attr "athlon_decode" "direct")])
15451
15452 (define_insn "*sqrtextenddftf2"
15453 [(set (match_operand:TF 0 "register_operand" "=f")
15454 (sqrt:TF (float_extend:TF
15455 (match_operand:DF 1 "register_operand" "0"))))]
15456 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15457 "fsqrt"
15458 [(set_attr "type" "fpspc")
15459 (set_attr "mode" "XF")
15460 (set_attr "athlon_decode" "direct")])
15461
15462 (define_insn "*sqrtextendsfxf2"
15463 [(set (match_operand:XF 0 "register_operand" "=f")
15464 (sqrt:XF (float_extend:XF
15465 (match_operand:SF 1 "register_operand" "0"))))]
15466 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15467 "fsqrt"
15468 [(set_attr "type" "fpspc")
15469 (set_attr "mode" "XF")
15470 (set_attr "athlon_decode" "direct")])
15471
15472 (define_insn "*sqrtextendsftf2"
15473 [(set (match_operand:TF 0 "register_operand" "=f")
15474 (sqrt:TF (float_extend:TF
15475 (match_operand:SF 1 "register_operand" "0"))))]
15476 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15477 "fsqrt"
15478 [(set_attr "type" "fpspc")
15479 (set_attr "mode" "XF")
15480 (set_attr "athlon_decode" "direct")])
15481
15482 (define_insn "sindf2"
15483 [(set (match_operand:DF 0 "register_operand" "=f")
15484 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15485 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15486 && flag_unsafe_math_optimizations"
15487 "fsin"
15488 [(set_attr "type" "fpspc")
15489 (set_attr "mode" "DF")])
15490
15491 (define_insn "sinsf2"
15492 [(set (match_operand:SF 0 "register_operand" "=f")
15493 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15494 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15495 && flag_unsafe_math_optimizations"
15496 "fsin"
15497 [(set_attr "type" "fpspc")
15498 (set_attr "mode" "SF")])
15499
15500 (define_insn "*sinextendsfdf2"
15501 [(set (match_operand:DF 0 "register_operand" "=f")
15502 (unspec:DF [(float_extend:DF
15503 (match_operand:SF 1 "register_operand" "0"))]
15504 UNSPEC_SIN))]
15505 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15506 && flag_unsafe_math_optimizations"
15507 "fsin"
15508 [(set_attr "type" "fpspc")
15509 (set_attr "mode" "DF")])
15510
15511 (define_insn "sinxf2"
15512 [(set (match_operand:XF 0 "register_operand" "=f")
15513 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15514 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15515 && flag_unsafe_math_optimizations"
15516 "fsin"
15517 [(set_attr "type" "fpspc")
15518 (set_attr "mode" "XF")])
15519
15520 (define_insn "sintf2"
15521 [(set (match_operand:TF 0 "register_operand" "=f")
15522 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15523 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15524 && flag_unsafe_math_optimizations"
15525 "fsin"
15526 [(set_attr "type" "fpspc")
15527 (set_attr "mode" "XF")])
15528
15529 (define_insn "cosdf2"
15530 [(set (match_operand:DF 0 "register_operand" "=f")
15531 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15532 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15533 && flag_unsafe_math_optimizations"
15534 "fcos"
15535 [(set_attr "type" "fpspc")
15536 (set_attr "mode" "DF")])
15537
15538 (define_insn "cossf2"
15539 [(set (match_operand:SF 0 "register_operand" "=f")
15540 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15541 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15542 && flag_unsafe_math_optimizations"
15543 "fcos"
15544 [(set_attr "type" "fpspc")
15545 (set_attr "mode" "SF")])
15546
15547 (define_insn "*cosextendsfdf2"
15548 [(set (match_operand:DF 0 "register_operand" "=f")
15549 (unspec:DF [(float_extend:DF
15550 (match_operand:SF 1 "register_operand" "0"))]
15551 UNSPEC_COS))]
15552 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15553 && flag_unsafe_math_optimizations"
15554 "fcos"
15555 [(set_attr "type" "fpspc")
15556 (set_attr "mode" "DF")])
15557
15558 (define_insn "cosxf2"
15559 [(set (match_operand:XF 0 "register_operand" "=f")
15560 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15561 "!TARGET_128BIT_LONG_DOUBLE && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15562 && flag_unsafe_math_optimizations"
15563 "fcos"
15564 [(set_attr "type" "fpspc")
15565 (set_attr "mode" "XF")])
15566
15567 (define_insn "costf2"
15568 [(set (match_operand:TF 0 "register_operand" "=f")
15569 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15570 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15571 && flag_unsafe_math_optimizations"
15572 "fcos"
15573 [(set_attr "type" "fpspc")
15574 (set_attr "mode" "XF")])
15575
15576 (define_insn "atan2df3"
15577 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15578 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15579 (match_operand:DF 1 "register_operand" "u")]
15580 UNSPEC_FPATAN))
15581 (clobber (match_dup 1))])]
15582 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15583 && flag_unsafe_math_optimizations"
15584 "fpatan"
15585 [(set_attr "type" "fpspc")
15586 (set_attr "mode" "DF")])
15587
15588 (define_insn "atan2sf3"
15589 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15590 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15591 (match_operand:SF 1 "register_operand" "u")]
15592 UNSPEC_FPATAN))
15593 (clobber (match_dup 1))])]
15594 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15595 && flag_unsafe_math_optimizations"
15596 "fpatan"
15597 [(set_attr "type" "fpspc")
15598 (set_attr "mode" "SF")])
15599
15600 (define_insn "atan2xf3"
15601 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15602 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15603 (match_operand:XF 1 "register_operand" "u")]
15604 UNSPEC_FPATAN))
15605 (clobber (match_dup 1))])]
15606 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15607 && flag_unsafe_math_optimizations"
15608 "fpatan"
15609 [(set_attr "type" "fpspc")
15610 (set_attr "mode" "XF")])
15611
15612 (define_insn "atan2tf3"
15613 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15614 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15615 (match_operand:TF 1 "register_operand" "u")]
15616 UNSPEC_FPATAN))
15617 (clobber (match_dup 1))])]
15618 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15619 && flag_unsafe_math_optimizations"
15620 "fpatan"
15621 [(set_attr "type" "fpspc")
15622 (set_attr "mode" "XF")])
15623
15624 (define_insn "*fyl2x_sfxf3"
15625 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15626 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15627 (match_operand:XF 1 "register_operand" "u")]
15628 UNSPEC_FYL2X))
15629 (clobber (match_dup 1))])]
15630 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15631 && flag_unsafe_math_optimizations"
15632 "fyl2x"
15633 [(set_attr "type" "fpspc")
15634 (set_attr "mode" "SF")])
15635
15636 (define_insn "*fyl2x_dfxf3"
15637 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15638 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15639 (match_operand:XF 1 "register_operand" "u")]
15640 UNSPEC_FYL2X))
15641 (clobber (match_dup 1))])]
15642 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15643 && flag_unsafe_math_optimizations"
15644 "fyl2x"
15645 [(set_attr "type" "fpspc")
15646 (set_attr "mode" "DF")])
15647
15648 (define_insn "*fyl2x_xf3"
15649 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15650 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15651 (match_operand:XF 1 "register_operand" "u")]
15652 UNSPEC_FYL2X))
15653 (clobber (match_dup 1))])]
15654 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15655 && flag_unsafe_math_optimizations"
15656 "fyl2x"
15657 [(set_attr "type" "fpspc")
15658 (set_attr "mode" "XF")])
15659
15660 (define_insn "*fyl2x_tfxf3"
15661 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15662 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15663 (match_operand:XF 1 "register_operand" "u")]
15664 UNSPEC_FYL2X))
15665 (clobber (match_dup 1))])]
15666 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15667 && flag_unsafe_math_optimizations"
15668 "fyl2x"
15669 [(set_attr "type" "fpspc")
15670 (set_attr "mode" "XF")])
15671
15672 (define_expand "logsf2"
15673 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15674 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15675 (match_dup 2)] UNSPEC_FYL2X))
15676 (clobber (match_dup 2))])]
15677 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15678 && flag_unsafe_math_optimizations"
15679 {
15680 rtx temp;
15681
15682 operands[2] = gen_reg_rtx (XFmode);
15683 temp = standard_80387_constant_rtx (4); /* fldln2 */
15684 emit_move_insn (operands[2], temp);
15685 })
15686
15687 (define_expand "logdf2"
15688 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15689 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15690 (match_dup 2)] UNSPEC_FYL2X))
15691 (clobber (match_dup 2))])]
15692 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15693 && flag_unsafe_math_optimizations"
15694 {
15695 rtx temp;
15696
15697 operands[2] = gen_reg_rtx (XFmode);
15698 temp = standard_80387_constant_rtx (4); /* fldln2 */
15699 emit_move_insn (operands[2], temp);
15700 })
15701
15702 (define_expand "logxf2"
15703 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15704 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15705 (match_dup 2)] UNSPEC_FYL2X))
15706 (clobber (match_dup 2))])]
15707 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15708 && flag_unsafe_math_optimizations"
15709 {
15710 rtx temp;
15711
15712 operands[2] = gen_reg_rtx (XFmode);
15713 temp = standard_80387_constant_rtx (4); /* fldln2 */
15714 emit_move_insn (operands[2], temp);
15715 })
15716
15717 (define_expand "logtf2"
15718 [(parallel [(set (match_operand:TF 0 "register_operand" "")
15719 (unspec:TF [(match_operand:TF 1 "register_operand" "")
15720 (match_dup 2)] UNSPEC_FYL2X))
15721 (clobber (match_dup 2))])]
15722 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15723 && flag_unsafe_math_optimizations"
15724 {
15725 rtx temp;
15726
15727 operands[2] = gen_reg_rtx (XFmode);
15728 temp = standard_80387_constant_rtx (4); /* fldln2 */
15729 emit_move_insn (operands[2], temp);
15730 })
15731
15732 (define_insn "*fscale_sfxf3"
15733 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15734 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15735 (match_operand:XF 1 "register_operand" "u")]
15736 UNSPEC_FSCALE))
15737 (clobber (match_dup 1))])]
15738 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15739 && flag_unsafe_math_optimizations"
15740 "fscale\;fstp\t%y1"
15741 [(set_attr "type" "fpspc")
15742 (set_attr "mode" "SF")])
15743
15744 (define_insn "*fscale_dfxf3"
15745 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15746 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15747 (match_operand:XF 1 "register_operand" "u")]
15748 UNSPEC_FSCALE))
15749 (clobber (match_dup 1))])]
15750 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15751 && flag_unsafe_math_optimizations"
15752 "fscale\;fstp\t%y1"
15753 [(set_attr "type" "fpspc")
15754 (set_attr "mode" "DF")])
15755
15756 (define_insn "*fscale_xf3"
15757 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15758 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15759 (match_operand:XF 1 "register_operand" "u")]
15760 UNSPEC_FSCALE))
15761 (clobber (match_dup 1))])]
15762 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15763 && flag_unsafe_math_optimizations"
15764 "fscale\;fstp\t%y1"
15765 [(set_attr "type" "fpspc")
15766 (set_attr "mode" "XF")])
15767
15768 (define_insn "*frndintxf2"
15769 [(set (match_operand:XF 0 "register_operand" "=f")
15770 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15771 UNSPEC_FRNDINT))]
15772 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15773 && flag_unsafe_math_optimizations"
15774 "frndint"
15775 [(set_attr "type" "fpspc")
15776 (set_attr "mode" "XF")])
15777
15778 (define_insn "*f2xm1xf2"
15779 [(set (match_operand:XF 0 "register_operand" "=f")
15780 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15781 UNSPEC_F2XM1))]
15782 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15783 && flag_unsafe_math_optimizations"
15784 "f2xm1"
15785 [(set_attr "type" "fpspc")
15786 (set_attr "mode" "XF")])
15787
15788 (define_expand "expsf2"
15789 [(set (match_dup 2)
15790 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15791 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15792 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15793 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15794 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15795 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15796 (parallel [(set (match_operand:SF 0 "register_operand" "")
15797 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15798 (clobber (match_dup 5))])]
15799 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15800 && flag_unsafe_math_optimizations"
15801 {
15802 rtx temp;
15803 int i;
15804
15805 for (i=2; i<10; i++)
15806 operands[i] = gen_reg_rtx (XFmode);
15807 temp = standard_80387_constant_rtx (5); /* fldl2e */
15808 emit_move_insn (operands[3], temp);
15809 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15810 })
15811
15812 (define_expand "expdf2"
15813 [(set (match_dup 2)
15814 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15815 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15816 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15817 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15818 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15819 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15820 (parallel [(set (match_operand:DF 0 "register_operand" "")
15821 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15822 (clobber (match_dup 5))])]
15823 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15824 && flag_unsafe_math_optimizations"
15825 {
15826 rtx temp;
15827 int i;
15828
15829 for (i=2; i<10; i++)
15830 operands[i] = gen_reg_rtx (XFmode);
15831 temp = standard_80387_constant_rtx (5); /* fldl2e */
15832 emit_move_insn (operands[3], temp);
15833 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15834 })
15835
15836 (define_expand "expxf2"
15837 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15838 (match_dup 2)))
15839 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15840 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15841 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15842 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15843 (parallel [(set (match_operand:XF 0 "register_operand" "")
15844 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15845 (clobber (match_dup 4))])]
15846 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15847 && flag_unsafe_math_optimizations"
15848 {
15849 rtx temp;
15850 int i;
15851
15852 for (i=2; i<9; i++)
15853 operands[i] = gen_reg_rtx (XFmode);
15854 temp = standard_80387_constant_rtx (5); /* fldl2e */
15855 emit_move_insn (operands[2], temp);
15856 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15857 })
15858
15859 (define_expand "atansf2"
15860 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15861 (unspec:SF [(match_dup 2)
15862 (match_operand:SF 1 "register_operand" "")]
15863 UNSPEC_FPATAN))
15864 (clobber (match_dup 1))])]
15865 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15866 && flag_unsafe_math_optimizations"
15867 {
15868 operands[2] = gen_reg_rtx (SFmode);
15869 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15870 })
15871
15872 (define_expand "atandf2"
15873 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15874 (unspec:DF [(match_dup 2)
15875 (match_operand:DF 1 "register_operand" "")]
15876 UNSPEC_FPATAN))
15877 (clobber (match_dup 1))])]
15878 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15879 && flag_unsafe_math_optimizations"
15880 {
15881 operands[2] = gen_reg_rtx (DFmode);
15882 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15883 })
15884
15885 (define_expand "atanxf2"
15886 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15887 (unspec:XF [(match_dup 2)
15888 (match_operand:XF 1 "register_operand" "")]
15889 UNSPEC_FPATAN))
15890 (clobber (match_dup 1))])]
15891 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15892 && flag_unsafe_math_optimizations"
15893 {
15894 operands[2] = gen_reg_rtx (XFmode);
15895 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15896 })
15897
15898 (define_expand "atantf2"
15899 [(parallel [(set (match_operand:TF 0 "register_operand" "")
15900 (unspec:TF [(match_dup 2)
15901 (match_operand:TF 1 "register_operand" "")]
15902 UNSPEC_FPATAN))
15903 (clobber (match_dup 1))])]
15904 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15905 && flag_unsafe_math_optimizations"
15906 {
15907 operands[2] = gen_reg_rtx (TFmode);
15908 emit_move_insn (operands[2], CONST1_RTX (TFmode)); /* fld1 */
15909 })
15910 \f
15911 ;; Block operation instructions
15912
15913 (define_insn "cld"
15914 [(set (reg:SI 19) (const_int 0))]
15915 ""
15916 "cld"
15917 [(set_attr "type" "cld")])
15918
15919 (define_expand "movstrsi"
15920 [(use (match_operand:BLK 0 "memory_operand" ""))
15921 (use (match_operand:BLK 1 "memory_operand" ""))
15922 (use (match_operand:SI 2 "nonmemory_operand" ""))
15923 (use (match_operand:SI 3 "const_int_operand" ""))]
15924 ""
15925 {
15926 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15927 DONE;
15928 else
15929 FAIL;
15930 })
15931
15932 (define_expand "movstrdi"
15933 [(use (match_operand:BLK 0 "memory_operand" ""))
15934 (use (match_operand:BLK 1 "memory_operand" ""))
15935 (use (match_operand:DI 2 "nonmemory_operand" ""))
15936 (use (match_operand:DI 3 "const_int_operand" ""))]
15937 "TARGET_64BIT"
15938 {
15939 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15940 DONE;
15941 else
15942 FAIL;
15943 })
15944
15945 ;; Most CPUs don't like single string operations
15946 ;; Handle this case here to simplify previous expander.
15947
15948 (define_expand "strmovdi_rex64"
15949 [(set (match_dup 2)
15950 (mem:DI (match_operand:DI 1 "register_operand" "")))
15951 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
15952 (match_dup 2))
15953 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15954 (clobber (reg:CC 17))])
15955 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
15956 (clobber (reg:CC 17))])]
15957 "TARGET_64BIT"
15958 {
15959 if (TARGET_SINGLE_STRINGOP || optimize_size)
15960 {
15961 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
15962 operands[1]));
15963 DONE;
15964 }
15965 else
15966 operands[2] = gen_reg_rtx (DImode);
15967 })
15968
15969
15970 (define_expand "strmovsi"
15971 [(set (match_dup 2)
15972 (mem:SI (match_operand:SI 1 "register_operand" "")))
15973 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
15974 (match_dup 2))
15975 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15976 (clobber (reg:CC 17))])
15977 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
15978 (clobber (reg:CC 17))])]
15979 ""
15980 {
15981 if (TARGET_64BIT)
15982 {
15983 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
15984 DONE;
15985 }
15986 if (TARGET_SINGLE_STRINGOP || optimize_size)
15987 {
15988 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
15989 operands[1]));
15990 DONE;
15991 }
15992 else
15993 operands[2] = gen_reg_rtx (SImode);
15994 })
15995
15996 (define_expand "strmovsi_rex64"
15997 [(set (match_dup 2)
15998 (mem:SI (match_operand:DI 1 "register_operand" "")))
15999 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
16000 (match_dup 2))
16001 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16002 (clobber (reg:CC 17))])
16003 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
16004 (clobber (reg:CC 17))])]
16005 "TARGET_64BIT"
16006 {
16007 if (TARGET_SINGLE_STRINGOP || optimize_size)
16008 {
16009 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
16010 operands[1]));
16011 DONE;
16012 }
16013 else
16014 operands[2] = gen_reg_rtx (SImode);
16015 })
16016
16017 (define_expand "strmovhi"
16018 [(set (match_dup 2)
16019 (mem:HI (match_operand:SI 1 "register_operand" "")))
16020 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
16021 (match_dup 2))
16022 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16023 (clobber (reg:CC 17))])
16024 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
16025 (clobber (reg:CC 17))])]
16026 ""
16027 {
16028 if (TARGET_64BIT)
16029 {
16030 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
16031 DONE;
16032 }
16033 if (TARGET_SINGLE_STRINGOP || optimize_size)
16034 {
16035 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
16036 operands[1]));
16037 DONE;
16038 }
16039 else
16040 operands[2] = gen_reg_rtx (HImode);
16041 })
16042
16043 (define_expand "strmovhi_rex64"
16044 [(set (match_dup 2)
16045 (mem:HI (match_operand:DI 1 "register_operand" "")))
16046 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
16047 (match_dup 2))
16048 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16049 (clobber (reg:CC 17))])
16050 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
16051 (clobber (reg:CC 17))])]
16052 "TARGET_64BIT"
16053 {
16054 if (TARGET_SINGLE_STRINGOP || optimize_size)
16055 {
16056 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
16057 operands[1]));
16058 DONE;
16059 }
16060 else
16061 operands[2] = gen_reg_rtx (HImode);
16062 })
16063
16064 (define_expand "strmovqi"
16065 [(set (match_dup 2)
16066 (mem:QI (match_operand:SI 1 "register_operand" "")))
16067 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
16068 (match_dup 2))
16069 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16070 (clobber (reg:CC 17))])
16071 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
16072 (clobber (reg:CC 17))])]
16073 ""
16074 {
16075 if (TARGET_64BIT)
16076 {
16077 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
16078 DONE;
16079 }
16080 if (TARGET_SINGLE_STRINGOP || optimize_size)
16081 {
16082 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
16083 operands[1]));
16084 DONE;
16085 }
16086 else
16087 operands[2] = gen_reg_rtx (QImode);
16088 })
16089
16090 (define_expand "strmovqi_rex64"
16091 [(set (match_dup 2)
16092 (mem:QI (match_operand:DI 1 "register_operand" "")))
16093 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
16094 (match_dup 2))
16095 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16096 (clobber (reg:CC 17))])
16097 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
16098 (clobber (reg:CC 17))])]
16099 "TARGET_64BIT"
16100 {
16101 if (TARGET_SINGLE_STRINGOP || optimize_size)
16102 {
16103 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
16104 operands[1]));
16105 DONE;
16106 }
16107 else
16108 operands[2] = gen_reg_rtx (QImode);
16109 })
16110
16111 (define_insn "strmovdi_rex_1"
16112 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16113 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16114 (set (match_operand:DI 0 "register_operand" "=D")
16115 (plus:DI (match_dup 2)
16116 (const_int 8)))
16117 (set (match_operand:DI 1 "register_operand" "=S")
16118 (plus:DI (match_dup 3)
16119 (const_int 8)))
16120 (use (reg:SI 19))]
16121 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16122 "movsq"
16123 [(set_attr "type" "str")
16124 (set_attr "mode" "DI")
16125 (set_attr "memory" "both")])
16126
16127 (define_insn "strmovsi_1"
16128 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16129 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16130 (set (match_operand:SI 0 "register_operand" "=D")
16131 (plus:SI (match_dup 2)
16132 (const_int 4)))
16133 (set (match_operand:SI 1 "register_operand" "=S")
16134 (plus:SI (match_dup 3)
16135 (const_int 4)))
16136 (use (reg:SI 19))]
16137 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16138 "{movsl|movsd}"
16139 [(set_attr "type" "str")
16140 (set_attr "mode" "SI")
16141 (set_attr "memory" "both")])
16142
16143 (define_insn "strmovsi_rex_1"
16144 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16145 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16146 (set (match_operand:DI 0 "register_operand" "=D")
16147 (plus:DI (match_dup 2)
16148 (const_int 4)))
16149 (set (match_operand:DI 1 "register_operand" "=S")
16150 (plus:DI (match_dup 3)
16151 (const_int 4)))
16152 (use (reg:SI 19))]
16153 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16154 "{movsl|movsd}"
16155 [(set_attr "type" "str")
16156 (set_attr "mode" "SI")
16157 (set_attr "memory" "both")])
16158
16159 (define_insn "strmovhi_1"
16160 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16161 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16162 (set (match_operand:SI 0 "register_operand" "=D")
16163 (plus:SI (match_dup 2)
16164 (const_int 2)))
16165 (set (match_operand:SI 1 "register_operand" "=S")
16166 (plus:SI (match_dup 3)
16167 (const_int 2)))
16168 (use (reg:SI 19))]
16169 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16170 "movsw"
16171 [(set_attr "type" "str")
16172 (set_attr "memory" "both")
16173 (set_attr "mode" "HI")])
16174
16175 (define_insn "strmovhi_rex_1"
16176 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16177 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16178 (set (match_operand:DI 0 "register_operand" "=D")
16179 (plus:DI (match_dup 2)
16180 (const_int 2)))
16181 (set (match_operand:DI 1 "register_operand" "=S")
16182 (plus:DI (match_dup 3)
16183 (const_int 2)))
16184 (use (reg:SI 19))]
16185 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16186 "movsw"
16187 [(set_attr "type" "str")
16188 (set_attr "memory" "both")
16189 (set_attr "mode" "HI")])
16190
16191 (define_insn "strmovqi_1"
16192 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16193 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16194 (set (match_operand:SI 0 "register_operand" "=D")
16195 (plus:SI (match_dup 2)
16196 (const_int 1)))
16197 (set (match_operand:SI 1 "register_operand" "=S")
16198 (plus:SI (match_dup 3)
16199 (const_int 1)))
16200 (use (reg:SI 19))]
16201 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16202 "movsb"
16203 [(set_attr "type" "str")
16204 (set_attr "memory" "both")
16205 (set_attr "mode" "QI")])
16206
16207 (define_insn "strmovqi_rex_1"
16208 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16209 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16210 (set (match_operand:DI 0 "register_operand" "=D")
16211 (plus:DI (match_dup 2)
16212 (const_int 1)))
16213 (set (match_operand:DI 1 "register_operand" "=S")
16214 (plus:DI (match_dup 3)
16215 (const_int 1)))
16216 (use (reg:SI 19))]
16217 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16218 "movsb"
16219 [(set_attr "type" "str")
16220 (set_attr "memory" "both")
16221 (set_attr "mode" "QI")])
16222
16223 (define_insn "rep_movdi_rex64"
16224 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16225 (set (match_operand:DI 0 "register_operand" "=D")
16226 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16227 (const_int 3))
16228 (match_operand:DI 3 "register_operand" "0")))
16229 (set (match_operand:DI 1 "register_operand" "=S")
16230 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16231 (match_operand:DI 4 "register_operand" "1")))
16232 (set (mem:BLK (match_dup 3))
16233 (mem:BLK (match_dup 4)))
16234 (use (match_dup 5))
16235 (use (reg:SI 19))]
16236 "TARGET_64BIT"
16237 "{rep\;movsq|rep movsq}"
16238 [(set_attr "type" "str")
16239 (set_attr "prefix_rep" "1")
16240 (set_attr "memory" "both")
16241 (set_attr "mode" "DI")])
16242
16243 (define_insn "rep_movsi"
16244 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16245 (set (match_operand:SI 0 "register_operand" "=D")
16246 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16247 (const_int 2))
16248 (match_operand:SI 3 "register_operand" "0")))
16249 (set (match_operand:SI 1 "register_operand" "=S")
16250 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16251 (match_operand:SI 4 "register_operand" "1")))
16252 (set (mem:BLK (match_dup 3))
16253 (mem:BLK (match_dup 4)))
16254 (use (match_dup 5))
16255 (use (reg:SI 19))]
16256 "!TARGET_64BIT"
16257 "{rep\;movsl|rep movsd}"
16258 [(set_attr "type" "str")
16259 (set_attr "prefix_rep" "1")
16260 (set_attr "memory" "both")
16261 (set_attr "mode" "SI")])
16262
16263 (define_insn "rep_movsi_rex64"
16264 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16265 (set (match_operand:DI 0 "register_operand" "=D")
16266 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16267 (const_int 2))
16268 (match_operand:DI 3 "register_operand" "0")))
16269 (set (match_operand:DI 1 "register_operand" "=S")
16270 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16271 (match_operand:DI 4 "register_operand" "1")))
16272 (set (mem:BLK (match_dup 3))
16273 (mem:BLK (match_dup 4)))
16274 (use (match_dup 5))
16275 (use (reg:SI 19))]
16276 "TARGET_64BIT"
16277 "{rep\;movsl|rep movsd}"
16278 [(set_attr "type" "str")
16279 (set_attr "prefix_rep" "1")
16280 (set_attr "memory" "both")
16281 (set_attr "mode" "SI")])
16282
16283 (define_insn "rep_movqi"
16284 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16285 (set (match_operand:SI 0 "register_operand" "=D")
16286 (plus:SI (match_operand:SI 3 "register_operand" "0")
16287 (match_operand:SI 5 "register_operand" "2")))
16288 (set (match_operand:SI 1 "register_operand" "=S")
16289 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16290 (set (mem:BLK (match_dup 3))
16291 (mem:BLK (match_dup 4)))
16292 (use (match_dup 5))
16293 (use (reg:SI 19))]
16294 "!TARGET_64BIT"
16295 "{rep\;movsb|rep movsb}"
16296 [(set_attr "type" "str")
16297 (set_attr "prefix_rep" "1")
16298 (set_attr "memory" "both")
16299 (set_attr "mode" "SI")])
16300
16301 (define_insn "rep_movqi_rex64"
16302 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16303 (set (match_operand:DI 0 "register_operand" "=D")
16304 (plus:DI (match_operand:DI 3 "register_operand" "0")
16305 (match_operand:DI 5 "register_operand" "2")))
16306 (set (match_operand:DI 1 "register_operand" "=S")
16307 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16308 (set (mem:BLK (match_dup 3))
16309 (mem:BLK (match_dup 4)))
16310 (use (match_dup 5))
16311 (use (reg:SI 19))]
16312 "TARGET_64BIT"
16313 "{rep\;movsb|rep movsb}"
16314 [(set_attr "type" "str")
16315 (set_attr "prefix_rep" "1")
16316 (set_attr "memory" "both")
16317 (set_attr "mode" "SI")])
16318
16319 (define_expand "clrstrsi"
16320 [(use (match_operand:BLK 0 "memory_operand" ""))
16321 (use (match_operand:SI 1 "nonmemory_operand" ""))
16322 (use (match_operand 2 "const_int_operand" ""))]
16323 ""
16324 {
16325 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16326 DONE;
16327 else
16328 FAIL;
16329 })
16330
16331 (define_expand "clrstrdi"
16332 [(use (match_operand:BLK 0 "memory_operand" ""))
16333 (use (match_operand:DI 1 "nonmemory_operand" ""))
16334 (use (match_operand 2 "const_int_operand" ""))]
16335 "TARGET_64BIT"
16336 {
16337 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16338 DONE;
16339 else
16340 FAIL;
16341 })
16342
16343 ;; Most CPUs don't like single string operations
16344 ;; Handle this case here to simplify previous expander.
16345
16346 (define_expand "strsetdi_rex64"
16347 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
16348 (match_operand:DI 1 "register_operand" ""))
16349 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16350 (clobber (reg:CC 17))])]
16351 "TARGET_64BIT"
16352 {
16353 if (TARGET_SINGLE_STRINGOP || optimize_size)
16354 {
16355 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
16356 DONE;
16357 }
16358 })
16359
16360 (define_expand "strsetsi"
16361 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
16362 (match_operand:SI 1 "register_operand" ""))
16363 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16364 (clobber (reg:CC 17))])]
16365 ""
16366 {
16367 if (TARGET_64BIT)
16368 {
16369 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
16370 DONE;
16371 }
16372 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16373 {
16374 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
16375 DONE;
16376 }
16377 })
16378
16379 (define_expand "strsetsi_rex64"
16380 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
16381 (match_operand:SI 1 "register_operand" ""))
16382 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16383 (clobber (reg:CC 17))])]
16384 "TARGET_64BIT"
16385 {
16386 if (TARGET_SINGLE_STRINGOP || optimize_size)
16387 {
16388 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
16389 DONE;
16390 }
16391 })
16392
16393 (define_expand "strsethi"
16394 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
16395 (match_operand:HI 1 "register_operand" ""))
16396 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16397 (clobber (reg:CC 17))])]
16398 ""
16399 {
16400 if (TARGET_64BIT)
16401 {
16402 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
16403 DONE;
16404 }
16405 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16406 {
16407 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
16408 DONE;
16409 }
16410 })
16411
16412 (define_expand "strsethi_rex64"
16413 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
16414 (match_operand:HI 1 "register_operand" ""))
16415 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16416 (clobber (reg:CC 17))])]
16417 "TARGET_64BIT"
16418 {
16419 if (TARGET_SINGLE_STRINGOP || optimize_size)
16420 {
16421 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
16422 DONE;
16423 }
16424 })
16425
16426 (define_expand "strsetqi"
16427 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
16428 (match_operand:QI 1 "register_operand" ""))
16429 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16430 (clobber (reg:CC 17))])]
16431 ""
16432 {
16433 if (TARGET_64BIT)
16434 {
16435 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
16436 DONE;
16437 }
16438 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16439 {
16440 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
16441 DONE;
16442 }
16443 })
16444
16445 (define_expand "strsetqi_rex64"
16446 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
16447 (match_operand:QI 1 "register_operand" ""))
16448 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16449 (clobber (reg:CC 17))])]
16450 "TARGET_64BIT"
16451 {
16452 if (TARGET_SINGLE_STRINGOP || optimize_size)
16453 {
16454 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
16455 DONE;
16456 }
16457 })
16458
16459 (define_insn "strsetdi_rex_1"
16460 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16461 (match_operand:SI 2 "register_operand" "a"))
16462 (set (match_operand:DI 0 "register_operand" "=D")
16463 (plus:DI (match_dup 1)
16464 (const_int 8)))
16465 (use (reg:SI 19))]
16466 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16467 "stosq"
16468 [(set_attr "type" "str")
16469 (set_attr "memory" "store")
16470 (set_attr "mode" "DI")])
16471
16472 (define_insn "strsetsi_1"
16473 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16474 (match_operand:SI 2 "register_operand" "a"))
16475 (set (match_operand:SI 0 "register_operand" "=D")
16476 (plus:SI (match_dup 1)
16477 (const_int 4)))
16478 (use (reg:SI 19))]
16479 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16480 "{stosl|stosd}"
16481 [(set_attr "type" "str")
16482 (set_attr "memory" "store")
16483 (set_attr "mode" "SI")])
16484
16485 (define_insn "strsetsi_rex_1"
16486 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16487 (match_operand:SI 2 "register_operand" "a"))
16488 (set (match_operand:DI 0 "register_operand" "=D")
16489 (plus:DI (match_dup 1)
16490 (const_int 4)))
16491 (use (reg:SI 19))]
16492 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16493 "{stosl|stosd}"
16494 [(set_attr "type" "str")
16495 (set_attr "memory" "store")
16496 (set_attr "mode" "SI")])
16497
16498 (define_insn "strsethi_1"
16499 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16500 (match_operand:HI 2 "register_operand" "a"))
16501 (set (match_operand:SI 0 "register_operand" "=D")
16502 (plus:SI (match_dup 1)
16503 (const_int 2)))
16504 (use (reg:SI 19))]
16505 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16506 "stosw"
16507 [(set_attr "type" "str")
16508 (set_attr "memory" "store")
16509 (set_attr "mode" "HI")])
16510
16511 (define_insn "strsethi_rex_1"
16512 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16513 (match_operand:HI 2 "register_operand" "a"))
16514 (set (match_operand:DI 0 "register_operand" "=D")
16515 (plus:DI (match_dup 1)
16516 (const_int 2)))
16517 (use (reg:SI 19))]
16518 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16519 "stosw"
16520 [(set_attr "type" "str")
16521 (set_attr "memory" "store")
16522 (set_attr "mode" "HI")])
16523
16524 (define_insn "strsetqi_1"
16525 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16526 (match_operand:QI 2 "register_operand" "a"))
16527 (set (match_operand:SI 0 "register_operand" "=D")
16528 (plus:SI (match_dup 1)
16529 (const_int 1)))
16530 (use (reg:SI 19))]
16531 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16532 "stosb"
16533 [(set_attr "type" "str")
16534 (set_attr "memory" "store")
16535 (set_attr "mode" "QI")])
16536
16537 (define_insn "strsetqi_rex_1"
16538 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16539 (match_operand:QI 2 "register_operand" "a"))
16540 (set (match_operand:DI 0 "register_operand" "=D")
16541 (plus:DI (match_dup 1)
16542 (const_int 1)))
16543 (use (reg:SI 19))]
16544 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16545 "stosb"
16546 [(set_attr "type" "str")
16547 (set_attr "memory" "store")
16548 (set_attr "mode" "QI")])
16549
16550 (define_insn "rep_stosdi_rex64"
16551 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16552 (set (match_operand:DI 0 "register_operand" "=D")
16553 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16554 (const_int 3))
16555 (match_operand:DI 3 "register_operand" "0")))
16556 (set (mem:BLK (match_dup 3))
16557 (const_int 0))
16558 (use (match_operand:DI 2 "register_operand" "a"))
16559 (use (match_dup 4))
16560 (use (reg:SI 19))]
16561 "TARGET_64BIT"
16562 "{rep\;stosq|rep stosq}"
16563 [(set_attr "type" "str")
16564 (set_attr "prefix_rep" "1")
16565 (set_attr "memory" "store")
16566 (set_attr "mode" "DI")])
16567
16568 (define_insn "rep_stossi"
16569 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16570 (set (match_operand:SI 0 "register_operand" "=D")
16571 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16572 (const_int 2))
16573 (match_operand:SI 3 "register_operand" "0")))
16574 (set (mem:BLK (match_dup 3))
16575 (const_int 0))
16576 (use (match_operand:SI 2 "register_operand" "a"))
16577 (use (match_dup 4))
16578 (use (reg:SI 19))]
16579 "!TARGET_64BIT"
16580 "{rep\;stosl|rep stosd}"
16581 [(set_attr "type" "str")
16582 (set_attr "prefix_rep" "1")
16583 (set_attr "memory" "store")
16584 (set_attr "mode" "SI")])
16585
16586 (define_insn "rep_stossi_rex64"
16587 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16588 (set (match_operand:DI 0 "register_operand" "=D")
16589 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16590 (const_int 2))
16591 (match_operand:DI 3 "register_operand" "0")))
16592 (set (mem:BLK (match_dup 3))
16593 (const_int 0))
16594 (use (match_operand:SI 2 "register_operand" "a"))
16595 (use (match_dup 4))
16596 (use (reg:SI 19))]
16597 "TARGET_64BIT"
16598 "{rep\;stosl|rep stosd}"
16599 [(set_attr "type" "str")
16600 (set_attr "prefix_rep" "1")
16601 (set_attr "memory" "store")
16602 (set_attr "mode" "SI")])
16603
16604 (define_insn "rep_stosqi"
16605 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16606 (set (match_operand:SI 0 "register_operand" "=D")
16607 (plus:SI (match_operand:SI 3 "register_operand" "0")
16608 (match_operand:SI 4 "register_operand" "1")))
16609 (set (mem:BLK (match_dup 3))
16610 (const_int 0))
16611 (use (match_operand:QI 2 "register_operand" "a"))
16612 (use (match_dup 4))
16613 (use (reg:SI 19))]
16614 "!TARGET_64BIT"
16615 "{rep\;stosb|rep stosb}"
16616 [(set_attr "type" "str")
16617 (set_attr "prefix_rep" "1")
16618 (set_attr "memory" "store")
16619 (set_attr "mode" "QI")])
16620
16621 (define_insn "rep_stosqi_rex64"
16622 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16623 (set (match_operand:DI 0 "register_operand" "=D")
16624 (plus:DI (match_operand:DI 3 "register_operand" "0")
16625 (match_operand:DI 4 "register_operand" "1")))
16626 (set (mem:BLK (match_dup 3))
16627 (const_int 0))
16628 (use (match_operand:QI 2 "register_operand" "a"))
16629 (use (match_dup 4))
16630 (use (reg:DI 19))]
16631 "TARGET_64BIT"
16632 "{rep\;stosb|rep stosb}"
16633 [(set_attr "type" "str")
16634 (set_attr "prefix_rep" "1")
16635 (set_attr "memory" "store")
16636 (set_attr "mode" "QI")])
16637
16638 (define_expand "cmpstrsi"
16639 [(set (match_operand:SI 0 "register_operand" "")
16640 (compare:SI (match_operand:BLK 1 "general_operand" "")
16641 (match_operand:BLK 2 "general_operand" "")))
16642 (use (match_operand 3 "general_operand" ""))
16643 (use (match_operand 4 "immediate_operand" ""))]
16644 ""
16645 {
16646 rtx addr1, addr2, out, outlow, count, countreg, align;
16647
16648 /* Can't use this if the user has appropriated esi or edi. */
16649 if (global_regs[4] || global_regs[5])
16650 FAIL;
16651
16652 out = operands[0];
16653 if (GET_CODE (out) != REG)
16654 out = gen_reg_rtx (SImode);
16655
16656 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16657 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16658
16659 count = operands[3];
16660 countreg = ix86_zero_extend_to_Pmode (count);
16661
16662 /* %%% Iff we are testing strict equality, we can use known alignment
16663 to good advantage. This may be possible with combine, particularly
16664 once cc0 is dead. */
16665 align = operands[4];
16666
16667 emit_insn (gen_cld ());
16668 if (GET_CODE (count) == CONST_INT)
16669 {
16670 if (INTVAL (count) == 0)
16671 {
16672 emit_move_insn (operands[0], const0_rtx);
16673 DONE;
16674 }
16675 if (TARGET_64BIT)
16676 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16677 addr1, addr2, countreg));
16678 else
16679 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16680 addr1, addr2, countreg));
16681 }
16682 else
16683 {
16684 if (TARGET_64BIT)
16685 {
16686 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16687 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16688 addr1, addr2, countreg));
16689 }
16690 else
16691 {
16692 emit_insn (gen_cmpsi_1 (countreg, countreg));
16693 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16694 addr1, addr2, countreg));
16695 }
16696 }
16697
16698 outlow = gen_lowpart (QImode, out);
16699 emit_insn (gen_cmpintqi (outlow));
16700 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16701
16702 if (operands[0] != out)
16703 emit_move_insn (operands[0], out);
16704
16705 DONE;
16706 })
16707
16708 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16709
16710 (define_expand "cmpintqi"
16711 [(set (match_dup 1)
16712 (gtu:QI (reg:CC 17) (const_int 0)))
16713 (set (match_dup 2)
16714 (ltu:QI (reg:CC 17) (const_int 0)))
16715 (parallel [(set (match_operand:QI 0 "register_operand" "")
16716 (minus:QI (match_dup 1)
16717 (match_dup 2)))
16718 (clobber (reg:CC 17))])]
16719 ""
16720 "operands[1] = gen_reg_rtx (QImode);
16721 operands[2] = gen_reg_rtx (QImode);")
16722
16723 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16724 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16725
16726 (define_insn "cmpstrqi_nz_1"
16727 [(set (reg:CC 17)
16728 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16729 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16730 (use (match_operand:SI 6 "register_operand" "2"))
16731 (use (match_operand:SI 3 "immediate_operand" "i"))
16732 (use (reg:SI 19))
16733 (clobber (match_operand:SI 0 "register_operand" "=S"))
16734 (clobber (match_operand:SI 1 "register_operand" "=D"))
16735 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16736 "!TARGET_64BIT"
16737 "repz{\;| }cmpsb"
16738 [(set_attr "type" "str")
16739 (set_attr "mode" "QI")
16740 (set_attr "prefix_rep" "1")])
16741
16742 (define_insn "cmpstrqi_nz_rex_1"
16743 [(set (reg:CC 17)
16744 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16745 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16746 (use (match_operand:DI 6 "register_operand" "2"))
16747 (use (match_operand:SI 3 "immediate_operand" "i"))
16748 (use (reg:SI 19))
16749 (clobber (match_operand:DI 0 "register_operand" "=S"))
16750 (clobber (match_operand:DI 1 "register_operand" "=D"))
16751 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16752 "TARGET_64BIT"
16753 "repz{\;| }cmpsb"
16754 [(set_attr "type" "str")
16755 (set_attr "mode" "QI")
16756 (set_attr "prefix_rep" "1")])
16757
16758 ;; The same, but the count is not known to not be zero.
16759
16760 (define_insn "cmpstrqi_1"
16761 [(set (reg:CC 17)
16762 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16763 (const_int 0))
16764 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16765 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16766 (const_int 0)))
16767 (use (match_operand:SI 3 "immediate_operand" "i"))
16768 (use (reg:CC 17))
16769 (use (reg:SI 19))
16770 (clobber (match_operand:SI 0 "register_operand" "=S"))
16771 (clobber (match_operand:SI 1 "register_operand" "=D"))
16772 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16773 "!TARGET_64BIT"
16774 "repz{\;| }cmpsb"
16775 [(set_attr "type" "str")
16776 (set_attr "mode" "QI")
16777 (set_attr "prefix_rep" "1")])
16778
16779 (define_insn "cmpstrqi_rex_1"
16780 [(set (reg:CC 17)
16781 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16782 (const_int 0))
16783 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16784 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16785 (const_int 0)))
16786 (use (match_operand:SI 3 "immediate_operand" "i"))
16787 (use (reg:CC 17))
16788 (use (reg:SI 19))
16789 (clobber (match_operand:DI 0 "register_operand" "=S"))
16790 (clobber (match_operand:DI 1 "register_operand" "=D"))
16791 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16792 "TARGET_64BIT"
16793 "repz{\;| }cmpsb"
16794 [(set_attr "type" "str")
16795 (set_attr "mode" "QI")
16796 (set_attr "prefix_rep" "1")])
16797
16798 (define_expand "strlensi"
16799 [(set (match_operand:SI 0 "register_operand" "")
16800 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16801 (match_operand:QI 2 "immediate_operand" "")
16802 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16803 ""
16804 {
16805 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16806 DONE;
16807 else
16808 FAIL;
16809 })
16810
16811 (define_expand "strlendi"
16812 [(set (match_operand:DI 0 "register_operand" "")
16813 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16814 (match_operand:QI 2 "immediate_operand" "")
16815 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16816 ""
16817 {
16818 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16819 DONE;
16820 else
16821 FAIL;
16822 })
16823
16824 (define_insn "strlenqi_1"
16825 [(set (match_operand:SI 0 "register_operand" "=&c")
16826 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16827 (match_operand:QI 2 "register_operand" "a")
16828 (match_operand:SI 3 "immediate_operand" "i")
16829 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16830 (use (reg:SI 19))
16831 (clobber (match_operand:SI 1 "register_operand" "=D"))
16832 (clobber (reg:CC 17))]
16833 "!TARGET_64BIT"
16834 "repnz{\;| }scasb"
16835 [(set_attr "type" "str")
16836 (set_attr "mode" "QI")
16837 (set_attr "prefix_rep" "1")])
16838
16839 (define_insn "strlenqi_rex_1"
16840 [(set (match_operand:DI 0 "register_operand" "=&c")
16841 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16842 (match_operand:QI 2 "register_operand" "a")
16843 (match_operand:DI 3 "immediate_operand" "i")
16844 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16845 (use (reg:SI 19))
16846 (clobber (match_operand:DI 1 "register_operand" "=D"))
16847 (clobber (reg:CC 17))]
16848 "TARGET_64BIT"
16849 "repnz{\;| }scasb"
16850 [(set_attr "type" "str")
16851 (set_attr "mode" "QI")
16852 (set_attr "prefix_rep" "1")])
16853
16854 ;; Peephole optimizations to clean up after cmpstr*. This should be
16855 ;; handled in combine, but it is not currently up to the task.
16856 ;; When used for their truth value, the cmpstr* expanders generate
16857 ;; code like this:
16858 ;;
16859 ;; repz cmpsb
16860 ;; seta %al
16861 ;; setb %dl
16862 ;; cmpb %al, %dl
16863 ;; jcc label
16864 ;;
16865 ;; The intermediate three instructions are unnecessary.
16866
16867 ;; This one handles cmpstr*_nz_1...
16868 (define_peephole2
16869 [(parallel[
16870 (set (reg:CC 17)
16871 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16872 (mem:BLK (match_operand 5 "register_operand" ""))))
16873 (use (match_operand 6 "register_operand" ""))
16874 (use (match_operand:SI 3 "immediate_operand" ""))
16875 (use (reg:SI 19))
16876 (clobber (match_operand 0 "register_operand" ""))
16877 (clobber (match_operand 1 "register_operand" ""))
16878 (clobber (match_operand 2 "register_operand" ""))])
16879 (set (match_operand:QI 7 "register_operand" "")
16880 (gtu:QI (reg:CC 17) (const_int 0)))
16881 (set (match_operand:QI 8 "register_operand" "")
16882 (ltu:QI (reg:CC 17) (const_int 0)))
16883 (set (reg 17)
16884 (compare (match_dup 7) (match_dup 8)))
16885 ]
16886 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16887 [(parallel[
16888 (set (reg:CC 17)
16889 (compare:CC (mem:BLK (match_dup 4))
16890 (mem:BLK (match_dup 5))))
16891 (use (match_dup 6))
16892 (use (match_dup 3))
16893 (use (reg:SI 19))
16894 (clobber (match_dup 0))
16895 (clobber (match_dup 1))
16896 (clobber (match_dup 2))])]
16897 "")
16898
16899 ;; ...and this one handles cmpstr*_1.
16900 (define_peephole2
16901 [(parallel[
16902 (set (reg:CC 17)
16903 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16904 (const_int 0))
16905 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16906 (mem:BLK (match_operand 5 "register_operand" "")))
16907 (const_int 0)))
16908 (use (match_operand:SI 3 "immediate_operand" ""))
16909 (use (reg:CC 17))
16910 (use (reg:SI 19))
16911 (clobber (match_operand 0 "register_operand" ""))
16912 (clobber (match_operand 1 "register_operand" ""))
16913 (clobber (match_operand 2 "register_operand" ""))])
16914 (set (match_operand:QI 7 "register_operand" "")
16915 (gtu:QI (reg:CC 17) (const_int 0)))
16916 (set (match_operand:QI 8 "register_operand" "")
16917 (ltu:QI (reg:CC 17) (const_int 0)))
16918 (set (reg 17)
16919 (compare (match_dup 7) (match_dup 8)))
16920 ]
16921 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16922 [(parallel[
16923 (set (reg:CC 17)
16924 (if_then_else:CC (ne (match_dup 6)
16925 (const_int 0))
16926 (compare:CC (mem:BLK (match_dup 4))
16927 (mem:BLK (match_dup 5)))
16928 (const_int 0)))
16929 (use (match_dup 3))
16930 (use (reg:CC 17))
16931 (use (reg:SI 19))
16932 (clobber (match_dup 0))
16933 (clobber (match_dup 1))
16934 (clobber (match_dup 2))])]
16935 "")
16936
16937
16938 \f
16939 ;; Conditional move instructions.
16940
16941 (define_expand "movdicc"
16942 [(set (match_operand:DI 0 "register_operand" "")
16943 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16944 (match_operand:DI 2 "general_operand" "")
16945 (match_operand:DI 3 "general_operand" "")))]
16946 "TARGET_64BIT"
16947 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16948
16949 (define_insn "x86_movdicc_0_m1_rex64"
16950 [(set (match_operand:DI 0 "register_operand" "=r")
16951 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16952 (const_int -1)
16953 (const_int 0)))
16954 (clobber (reg:CC 17))]
16955 "TARGET_64BIT"
16956 "sbb{q}\t%0, %0"
16957 ; Since we don't have the proper number of operands for an alu insn,
16958 ; fill in all the blanks.
16959 [(set_attr "type" "alu")
16960 (set_attr "pent_pair" "pu")
16961 (set_attr "memory" "none")
16962 (set_attr "imm_disp" "false")
16963 (set_attr "mode" "DI")
16964 (set_attr "length_immediate" "0")])
16965
16966 (define_insn "movdicc_c_rex64"
16967 [(set (match_operand:DI 0 "register_operand" "=r,r")
16968 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16969 [(reg 17) (const_int 0)])
16970 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16971 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16972 "TARGET_64BIT && TARGET_CMOVE
16973 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16974 "@
16975 cmov%O2%C1\t{%2, %0|%0, %2}
16976 cmov%O2%c1\t{%3, %0|%0, %3}"
16977 [(set_attr "type" "icmov")
16978 (set_attr "mode" "DI")])
16979
16980 (define_expand "movsicc"
16981 [(set (match_operand:SI 0 "register_operand" "")
16982 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16983 (match_operand:SI 2 "general_operand" "")
16984 (match_operand:SI 3 "general_operand" "")))]
16985 ""
16986 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16987
16988 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16989 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16990 ;; So just document what we're doing explicitly.
16991
16992 (define_insn "x86_movsicc_0_m1"
16993 [(set (match_operand:SI 0 "register_operand" "=r")
16994 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16995 (const_int -1)
16996 (const_int 0)))
16997 (clobber (reg:CC 17))]
16998 ""
16999 "sbb{l}\t%0, %0"
17000 ; Since we don't have the proper number of operands for an alu insn,
17001 ; fill in all the blanks.
17002 [(set_attr "type" "alu")
17003 (set_attr "pent_pair" "pu")
17004 (set_attr "memory" "none")
17005 (set_attr "imm_disp" "false")
17006 (set_attr "mode" "SI")
17007 (set_attr "length_immediate" "0")])
17008
17009 (define_insn "*movsicc_noc"
17010 [(set (match_operand:SI 0 "register_operand" "=r,r")
17011 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17012 [(reg 17) (const_int 0)])
17013 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17014 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17015 "TARGET_CMOVE
17016 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17017 "@
17018 cmov%O2%C1\t{%2, %0|%0, %2}
17019 cmov%O2%c1\t{%3, %0|%0, %3}"
17020 [(set_attr "type" "icmov")
17021 (set_attr "mode" "SI")])
17022
17023 (define_expand "movhicc"
17024 [(set (match_operand:HI 0 "register_operand" "")
17025 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17026 (match_operand:HI 2 "general_operand" "")
17027 (match_operand:HI 3 "general_operand" "")))]
17028 "TARGET_HIMODE_MATH"
17029 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17030
17031 (define_insn "*movhicc_noc"
17032 [(set (match_operand:HI 0 "register_operand" "=r,r")
17033 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17034 [(reg 17) (const_int 0)])
17035 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17036 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17037 "TARGET_CMOVE
17038 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17039 "@
17040 cmov%O2%C1\t{%2, %0|%0, %2}
17041 cmov%O2%c1\t{%3, %0|%0, %3}"
17042 [(set_attr "type" "icmov")
17043 (set_attr "mode" "HI")])
17044
17045 (define_expand "movqicc"
17046 [(set (match_operand:QI 0 "register_operand" "")
17047 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17048 (match_operand:QI 2 "general_operand" "")
17049 (match_operand:QI 3 "general_operand" "")))]
17050 "TARGET_QIMODE_MATH"
17051 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17052
17053 (define_insn_and_split "*movqicc_noc"
17054 [(set (match_operand:QI 0 "register_operand" "=r,r")
17055 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17056 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17057 (match_operand:QI 2 "register_operand" "r,0")
17058 (match_operand:QI 3 "register_operand" "0,r")))]
17059 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17060 "#"
17061 "&& reload_completed"
17062 [(set (match_dup 0)
17063 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17064 (match_dup 2)
17065 (match_dup 3)))]
17066 "operands[0] = gen_lowpart (SImode, operands[0]);
17067 operands[2] = gen_lowpart (SImode, operands[2]);
17068 operands[3] = gen_lowpart (SImode, operands[3]);"
17069 [(set_attr "type" "icmov")
17070 (set_attr "mode" "SI")])
17071
17072 (define_expand "movsfcc"
17073 [(set (match_operand:SF 0 "register_operand" "")
17074 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17075 (match_operand:SF 2 "register_operand" "")
17076 (match_operand:SF 3 "register_operand" "")))]
17077 "TARGET_CMOVE"
17078 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17079
17080 (define_insn "*movsfcc_1"
17081 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17082 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17083 [(reg 17) (const_int 0)])
17084 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17085 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17086 "TARGET_CMOVE
17087 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17088 "@
17089 fcmov%F1\t{%2, %0|%0, %2}
17090 fcmov%f1\t{%3, %0|%0, %3}
17091 cmov%O2%C1\t{%2, %0|%0, %2}
17092 cmov%O2%c1\t{%3, %0|%0, %3}"
17093 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17094 (set_attr "mode" "SF,SF,SI,SI")])
17095
17096 (define_expand "movdfcc"
17097 [(set (match_operand:DF 0 "register_operand" "")
17098 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17099 (match_operand:DF 2 "register_operand" "")
17100 (match_operand:DF 3 "register_operand" "")))]
17101 "TARGET_CMOVE"
17102 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17103
17104 (define_insn "*movdfcc_1"
17105 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17106 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17107 [(reg 17) (const_int 0)])
17108 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17109 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17110 "!TARGET_64BIT && TARGET_CMOVE
17111 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17112 "@
17113 fcmov%F1\t{%2, %0|%0, %2}
17114 fcmov%f1\t{%3, %0|%0, %3}
17115 #
17116 #"
17117 [(set_attr "type" "fcmov,fcmov,multi,multi")
17118 (set_attr "mode" "DF")])
17119
17120 (define_insn "*movdfcc_1_rex64"
17121 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17122 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17123 [(reg 17) (const_int 0)])
17124 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17125 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17126 "TARGET_64BIT && TARGET_CMOVE
17127 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17128 "@
17129 fcmov%F1\t{%2, %0|%0, %2}
17130 fcmov%f1\t{%3, %0|%0, %3}
17131 cmov%O2%C1\t{%2, %0|%0, %2}
17132 cmov%O2%c1\t{%3, %0|%0, %3}"
17133 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17134 (set_attr "mode" "DF")])
17135
17136 (define_split
17137 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17138 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17139 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17140 (match_operand:DF 2 "nonimmediate_operand" "")
17141 (match_operand:DF 3 "nonimmediate_operand" "")))]
17142 "!TARGET_64BIT && reload_completed"
17143 [(set (match_dup 2)
17144 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17145 (match_dup 5)
17146 (match_dup 7)))
17147 (set (match_dup 3)
17148 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17149 (match_dup 6)
17150 (match_dup 8)))]
17151 "split_di (operands+2, 1, operands+5, operands+6);
17152 split_di (operands+3, 1, operands+7, operands+8);
17153 split_di (operands, 1, operands+2, operands+3);")
17154
17155 (define_expand "movxfcc"
17156 [(set (match_operand:XF 0 "register_operand" "")
17157 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17158 (match_operand:XF 2 "register_operand" "")
17159 (match_operand:XF 3 "register_operand" "")))]
17160 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17161 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17162
17163 (define_expand "movtfcc"
17164 [(set (match_operand:TF 0 "register_operand" "")
17165 (if_then_else:TF (match_operand 1 "comparison_operator" "")
17166 (match_operand:TF 2 "register_operand" "")
17167 (match_operand:TF 3 "register_operand" "")))]
17168 "TARGET_CMOVE"
17169 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17170
17171 (define_insn "*movxfcc_1"
17172 [(set (match_operand:XF 0 "register_operand" "=f,f")
17173 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17174 [(reg 17) (const_int 0)])
17175 (match_operand:XF 2 "register_operand" "f,0")
17176 (match_operand:XF 3 "register_operand" "0,f")))]
17177 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17178 "@
17179 fcmov%F1\t{%2, %0|%0, %2}
17180 fcmov%f1\t{%3, %0|%0, %3}"
17181 [(set_attr "type" "fcmov")
17182 (set_attr "mode" "XF")])
17183
17184 (define_insn "*movtfcc_1"
17185 [(set (match_operand:TF 0 "register_operand" "=f,f")
17186 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
17187 [(reg 17) (const_int 0)])
17188 (match_operand:TF 2 "register_operand" "f,0")
17189 (match_operand:TF 3 "register_operand" "0,f")))]
17190 "TARGET_CMOVE"
17191 "@
17192 fcmov%F1\t{%2, %0|%0, %2}
17193 fcmov%f1\t{%3, %0|%0, %3}"
17194 [(set_attr "type" "fcmov")
17195 (set_attr "mode" "XF")])
17196
17197 (define_expand "minsf3"
17198 [(parallel [
17199 (set (match_operand:SF 0 "register_operand" "")
17200 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17201 (match_operand:SF 2 "nonimmediate_operand" ""))
17202 (match_dup 1)
17203 (match_dup 2)))
17204 (clobber (reg:CC 17))])]
17205 "TARGET_SSE"
17206 "")
17207
17208 (define_insn "*minsf"
17209 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17210 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17211 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17212 (match_dup 1)
17213 (match_dup 2)))
17214 (clobber (reg:CC 17))]
17215 "TARGET_SSE && TARGET_IEEE_FP"
17216 "#")
17217
17218 (define_insn "*minsf_nonieee"
17219 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17220 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17221 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17222 (match_dup 1)
17223 (match_dup 2)))
17224 (clobber (reg:CC 17))]
17225 "TARGET_SSE && !TARGET_IEEE_FP
17226 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17227 "#")
17228
17229 (define_split
17230 [(set (match_operand:SF 0 "register_operand" "")
17231 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17232 (match_operand:SF 2 "nonimmediate_operand" ""))
17233 (match_operand:SF 3 "register_operand" "")
17234 (match_operand:SF 4 "nonimmediate_operand" "")))
17235 (clobber (reg:CC 17))]
17236 "SSE_REG_P (operands[0]) && reload_completed
17237 && ((operands_match_p (operands[1], operands[3])
17238 && operands_match_p (operands[2], operands[4]))
17239 || (operands_match_p (operands[1], operands[4])
17240 && operands_match_p (operands[2], operands[3])))"
17241 [(set (match_dup 0)
17242 (if_then_else:SF (lt (match_dup 1)
17243 (match_dup 2))
17244 (match_dup 1)
17245 (match_dup 2)))])
17246
17247 ;; Conditional addition patterns
17248 (define_expand "addqicc"
17249 [(match_operand:QI 0 "register_operand" "")
17250 (match_operand 1 "comparison_operator" "")
17251 (match_operand:QI 2 "register_operand" "")
17252 (match_operand:QI 3 "const_int_operand" "")]
17253 ""
17254 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17255
17256 (define_expand "addhicc"
17257 [(match_operand:HI 0 "register_operand" "")
17258 (match_operand 1 "comparison_operator" "")
17259 (match_operand:HI 2 "register_operand" "")
17260 (match_operand:HI 3 "const_int_operand" "")]
17261 ""
17262 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17263
17264 (define_expand "addsicc"
17265 [(match_operand:SI 0 "register_operand" "")
17266 (match_operand 1 "comparison_operator" "")
17267 (match_operand:SI 2 "register_operand" "")
17268 (match_operand:SI 3 "const_int_operand" "")]
17269 ""
17270 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17271
17272 (define_expand "adddicc"
17273 [(match_operand:DI 0 "register_operand" "")
17274 (match_operand 1 "comparison_operator" "")
17275 (match_operand:DI 2 "register_operand" "")
17276 (match_operand:DI 3 "const_int_operand" "")]
17277 "TARGET_64BIT"
17278 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17279
17280 ;; We can't represent the LT test directly. Do this by swapping the operands.
17281
17282 (define_split
17283 [(set (match_operand:SF 0 "fp_register_operand" "")
17284 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17285 (match_operand:SF 2 "register_operand" ""))
17286 (match_operand:SF 3 "register_operand" "")
17287 (match_operand:SF 4 "register_operand" "")))
17288 (clobber (reg:CC 17))]
17289 "reload_completed
17290 && ((operands_match_p (operands[1], operands[3])
17291 && operands_match_p (operands[2], operands[4]))
17292 || (operands_match_p (operands[1], operands[4])
17293 && operands_match_p (operands[2], operands[3])))"
17294 [(set (reg:CCFP 17)
17295 (compare:CCFP (match_dup 2)
17296 (match_dup 1)))
17297 (set (match_dup 0)
17298 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17299 (match_dup 1)
17300 (match_dup 2)))])
17301
17302 (define_insn "*minsf_sse"
17303 [(set (match_operand:SF 0 "register_operand" "=x")
17304 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17305 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17306 (match_dup 1)
17307 (match_dup 2)))]
17308 "TARGET_SSE && reload_completed"
17309 "minss\t{%2, %0|%0, %2}"
17310 [(set_attr "type" "sse")
17311 (set_attr "mode" "SF")])
17312
17313 (define_expand "mindf3"
17314 [(parallel [
17315 (set (match_operand:DF 0 "register_operand" "")
17316 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17317 (match_operand:DF 2 "nonimmediate_operand" ""))
17318 (match_dup 1)
17319 (match_dup 2)))
17320 (clobber (reg:CC 17))])]
17321 "TARGET_SSE2 && TARGET_SSE_MATH"
17322 "#")
17323
17324 (define_insn "*mindf"
17325 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17326 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17327 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17328 (match_dup 1)
17329 (match_dup 2)))
17330 (clobber (reg:CC 17))]
17331 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17332 "#")
17333
17334 (define_insn "*mindf_nonieee"
17335 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17336 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17337 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17338 (match_dup 1)
17339 (match_dup 2)))
17340 (clobber (reg:CC 17))]
17341 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17342 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17343 "#")
17344
17345 (define_split
17346 [(set (match_operand:DF 0 "register_operand" "")
17347 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17348 (match_operand:DF 2 "nonimmediate_operand" ""))
17349 (match_operand:DF 3 "register_operand" "")
17350 (match_operand:DF 4 "nonimmediate_operand" "")))
17351 (clobber (reg:CC 17))]
17352 "SSE_REG_P (operands[0]) && reload_completed
17353 && ((operands_match_p (operands[1], operands[3])
17354 && operands_match_p (operands[2], operands[4]))
17355 || (operands_match_p (operands[1], operands[4])
17356 && operands_match_p (operands[2], operands[3])))"
17357 [(set (match_dup 0)
17358 (if_then_else:DF (lt (match_dup 1)
17359 (match_dup 2))
17360 (match_dup 1)
17361 (match_dup 2)))])
17362
17363 ;; We can't represent the LT test directly. Do this by swapping the operands.
17364 (define_split
17365 [(set (match_operand:DF 0 "fp_register_operand" "")
17366 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17367 (match_operand:DF 2 "register_operand" ""))
17368 (match_operand:DF 3 "register_operand" "")
17369 (match_operand:DF 4 "register_operand" "")))
17370 (clobber (reg:CC 17))]
17371 "reload_completed
17372 && ((operands_match_p (operands[1], operands[3])
17373 && operands_match_p (operands[2], operands[4]))
17374 || (operands_match_p (operands[1], operands[4])
17375 && operands_match_p (operands[2], operands[3])))"
17376 [(set (reg:CCFP 17)
17377 (compare:CCFP (match_dup 2)
17378 (match_dup 2)))
17379 (set (match_dup 0)
17380 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17381 (match_dup 1)
17382 (match_dup 2)))])
17383
17384 (define_insn "*mindf_sse"
17385 [(set (match_operand:DF 0 "register_operand" "=Y")
17386 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17387 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17388 (match_dup 1)
17389 (match_dup 2)))]
17390 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17391 "minsd\t{%2, %0|%0, %2}"
17392 [(set_attr "type" "sse")
17393 (set_attr "mode" "DF")])
17394
17395 (define_expand "maxsf3"
17396 [(parallel [
17397 (set (match_operand:SF 0 "register_operand" "")
17398 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17399 (match_operand:SF 2 "nonimmediate_operand" ""))
17400 (match_dup 1)
17401 (match_dup 2)))
17402 (clobber (reg:CC 17))])]
17403 "TARGET_SSE"
17404 "#")
17405
17406 (define_insn "*maxsf"
17407 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17408 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17409 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17410 (match_dup 1)
17411 (match_dup 2)))
17412 (clobber (reg:CC 17))]
17413 "TARGET_SSE && TARGET_IEEE_FP"
17414 "#")
17415
17416 (define_insn "*maxsf_nonieee"
17417 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17418 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17419 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17420 (match_dup 1)
17421 (match_dup 2)))
17422 (clobber (reg:CC 17))]
17423 "TARGET_SSE && !TARGET_IEEE_FP
17424 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17425 "#")
17426
17427 (define_split
17428 [(set (match_operand:SF 0 "register_operand" "")
17429 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17430 (match_operand:SF 2 "nonimmediate_operand" ""))
17431 (match_operand:SF 3 "register_operand" "")
17432 (match_operand:SF 4 "nonimmediate_operand" "")))
17433 (clobber (reg:CC 17))]
17434 "SSE_REG_P (operands[0]) && reload_completed
17435 && ((operands_match_p (operands[1], operands[3])
17436 && operands_match_p (operands[2], operands[4]))
17437 || (operands_match_p (operands[1], operands[4])
17438 && operands_match_p (operands[2], operands[3])))"
17439 [(set (match_dup 0)
17440 (if_then_else:SF (gt (match_dup 1)
17441 (match_dup 2))
17442 (match_dup 1)
17443 (match_dup 2)))])
17444
17445 (define_split
17446 [(set (match_operand:SF 0 "fp_register_operand" "")
17447 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17448 (match_operand:SF 2 "register_operand" ""))
17449 (match_operand:SF 3 "register_operand" "")
17450 (match_operand:SF 4 "register_operand" "")))
17451 (clobber (reg:CC 17))]
17452 "reload_completed
17453 && ((operands_match_p (operands[1], operands[3])
17454 && operands_match_p (operands[2], operands[4]))
17455 || (operands_match_p (operands[1], operands[4])
17456 && operands_match_p (operands[2], operands[3])))"
17457 [(set (reg:CCFP 17)
17458 (compare:CCFP (match_dup 1)
17459 (match_dup 2)))
17460 (set (match_dup 0)
17461 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17462 (match_dup 1)
17463 (match_dup 2)))])
17464
17465 (define_insn "*maxsf_sse"
17466 [(set (match_operand:SF 0 "register_operand" "=x")
17467 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17468 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17469 (match_dup 1)
17470 (match_dup 2)))]
17471 "TARGET_SSE && reload_completed"
17472 "maxss\t{%2, %0|%0, %2}"
17473 [(set_attr "type" "sse")
17474 (set_attr "mode" "SF")])
17475
17476 (define_expand "maxdf3"
17477 [(parallel [
17478 (set (match_operand:DF 0 "register_operand" "")
17479 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17480 (match_operand:DF 2 "nonimmediate_operand" ""))
17481 (match_dup 1)
17482 (match_dup 2)))
17483 (clobber (reg:CC 17))])]
17484 "TARGET_SSE2 && TARGET_SSE_MATH"
17485 "#")
17486
17487 (define_insn "*maxdf"
17488 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17489 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17490 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17491 (match_dup 1)
17492 (match_dup 2)))
17493 (clobber (reg:CC 17))]
17494 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17495 "#")
17496
17497 (define_insn "*maxdf_nonieee"
17498 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17499 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17500 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17501 (match_dup 1)
17502 (match_dup 2)))
17503 (clobber (reg:CC 17))]
17504 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17505 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17506 "#")
17507
17508 (define_split
17509 [(set (match_operand:DF 0 "register_operand" "")
17510 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17511 (match_operand:DF 2 "nonimmediate_operand" ""))
17512 (match_operand:DF 3 "register_operand" "")
17513 (match_operand:DF 4 "nonimmediate_operand" "")))
17514 (clobber (reg:CC 17))]
17515 "SSE_REG_P (operands[0]) && reload_completed
17516 && ((operands_match_p (operands[1], operands[3])
17517 && operands_match_p (operands[2], operands[4]))
17518 || (operands_match_p (operands[1], operands[4])
17519 && operands_match_p (operands[2], operands[3])))"
17520 [(set (match_dup 0)
17521 (if_then_else:DF (gt (match_dup 1)
17522 (match_dup 2))
17523 (match_dup 1)
17524 (match_dup 2)))])
17525
17526 (define_split
17527 [(set (match_operand:DF 0 "fp_register_operand" "")
17528 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17529 (match_operand:DF 2 "register_operand" ""))
17530 (match_operand:DF 3 "register_operand" "")
17531 (match_operand:DF 4 "register_operand" "")))
17532 (clobber (reg:CC 17))]
17533 "reload_completed
17534 && ((operands_match_p (operands[1], operands[3])
17535 && operands_match_p (operands[2], operands[4]))
17536 || (operands_match_p (operands[1], operands[4])
17537 && operands_match_p (operands[2], operands[3])))"
17538 [(set (reg:CCFP 17)
17539 (compare:CCFP (match_dup 1)
17540 (match_dup 2)))
17541 (set (match_dup 0)
17542 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17543 (match_dup 1)
17544 (match_dup 2)))])
17545
17546 (define_insn "*maxdf_sse"
17547 [(set (match_operand:DF 0 "register_operand" "=Y")
17548 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17549 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17550 (match_dup 1)
17551 (match_dup 2)))]
17552 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17553 "maxsd\t{%2, %0|%0, %2}"
17554 [(set_attr "type" "sse")
17555 (set_attr "mode" "DF")])
17556 \f
17557 ;; Misc patterns (?)
17558
17559 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17560 ;; Otherwise there will be nothing to keep
17561 ;;
17562 ;; [(set (reg ebp) (reg esp))]
17563 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17564 ;; (clobber (eflags)]
17565 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17566 ;;
17567 ;; in proper program order.
17568 (define_expand "pro_epilogue_adjust_stack"
17569 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
17570 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17571 (match_operand:SI 2 "immediate_operand" "i,i")))
17572 (clobber (reg:CC 17))
17573 (clobber (mem:BLK (scratch)))])]
17574 ""
17575 {
17576 if (TARGET_64BIT)
17577 {
17578 emit_insn (gen_pro_epilogue_adjust_stack_rex64
17579 (operands[0], operands[1], operands[2]));
17580 DONE;
17581 }
17582 })
17583
17584 (define_insn "*pro_epilogue_adjust_stack_1"
17585 [(set (match_operand:SI 0 "register_operand" "=r,r")
17586 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17587 (match_operand:SI 2 "immediate_operand" "i,i")))
17588 (clobber (reg:CC 17))
17589 (clobber (mem:BLK (scratch)))]
17590 "!TARGET_64BIT"
17591 {
17592 switch (get_attr_type (insn))
17593 {
17594 case TYPE_IMOV:
17595 return "mov{l}\t{%1, %0|%0, %1}";
17596
17597 case TYPE_ALU:
17598 if (GET_CODE (operands[2]) == CONST_INT
17599 && (INTVAL (operands[2]) == 128
17600 || (INTVAL (operands[2]) < 0
17601 && INTVAL (operands[2]) != -128)))
17602 {
17603 operands[2] = GEN_INT (-INTVAL (operands[2]));
17604 return "sub{l}\t{%2, %0|%0, %2}";
17605 }
17606 return "add{l}\t{%2, %0|%0, %2}";
17607
17608 case TYPE_LEA:
17609 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17610 return "lea{l}\t{%a2, %0|%0, %a2}";
17611
17612 default:
17613 abort ();
17614 }
17615 }
17616 [(set (attr "type")
17617 (cond [(eq_attr "alternative" "0")
17618 (const_string "alu")
17619 (match_operand:SI 2 "const0_operand" "")
17620 (const_string "imov")
17621 ]
17622 (const_string "lea")))
17623 (set_attr "mode" "SI")])
17624
17625 (define_insn "pro_epilogue_adjust_stack_rex64"
17626 [(set (match_operand:DI 0 "register_operand" "=r,r")
17627 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17628 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17629 (clobber (reg:CC 17))
17630 (clobber (mem:BLK (scratch)))]
17631 "TARGET_64BIT"
17632 {
17633 switch (get_attr_type (insn))
17634 {
17635 case TYPE_IMOV:
17636 return "mov{q}\t{%1, %0|%0, %1}";
17637
17638 case TYPE_ALU:
17639 if (GET_CODE (operands[2]) == CONST_INT
17640 && (INTVAL (operands[2]) == 128
17641 || (INTVAL (operands[2]) < 0
17642 && INTVAL (operands[2]) != -128)))
17643 {
17644 operands[2] = GEN_INT (-INTVAL (operands[2]));
17645 return "sub{q}\t{%2, %0|%0, %2}";
17646 }
17647 return "add{q}\t{%2, %0|%0, %2}";
17648
17649 case TYPE_LEA:
17650 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17651 return "lea{q}\t{%a2, %0|%0, %a2}";
17652
17653 default:
17654 abort ();
17655 }
17656 }
17657 [(set (attr "type")
17658 (cond [(eq_attr "alternative" "0")
17659 (const_string "alu")
17660 (match_operand:DI 2 "const0_operand" "")
17661 (const_string "imov")
17662 ]
17663 (const_string "lea")))
17664 (set_attr "mode" "DI")])
17665
17666
17667 ;; Placeholder for the conditional moves. This one is split either to SSE
17668 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17669 ;; fact is that compares supported by the cmp??ss instructions are exactly
17670 ;; swapped of those supported by cmove sequence.
17671 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17672 ;; supported by i387 comparisons and we do need to emit two conditional moves
17673 ;; in tandem.
17674
17675 (define_insn "sse_movsfcc"
17676 [(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")
17677 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17678 [(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")
17679 (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")])
17680 (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")
17681 (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")))
17682 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17683 (clobber (reg:CC 17))]
17684 "TARGET_SSE
17685 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17686 /* Avoid combine from being smart and converting min/max
17687 instruction patterns into conditional moves. */
17688 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17689 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17690 || !rtx_equal_p (operands[4], operands[2])
17691 || !rtx_equal_p (operands[5], operands[3]))
17692 && (!TARGET_IEEE_FP
17693 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17694 "#")
17695
17696 (define_insn "sse_movsfcc_eq"
17697 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17698 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17699 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17700 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17701 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17702 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17703 (clobber (reg:CC 17))]
17704 "TARGET_SSE
17705 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17706 "#")
17707
17708 (define_insn "sse_movdfcc"
17709 [(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")
17710 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17711 [(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")
17712 (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")])
17713 (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")
17714 (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")))
17715 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17716 (clobber (reg:CC 17))]
17717 "TARGET_SSE2
17718 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17719 /* Avoid combine from being smart and converting min/max
17720 instruction patterns into conditional moves. */
17721 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17722 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17723 || !rtx_equal_p (operands[4], operands[2])
17724 || !rtx_equal_p (operands[5], operands[3]))
17725 && (!TARGET_IEEE_FP
17726 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17727 "#")
17728
17729 (define_insn "sse_movdfcc_eq"
17730 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17731 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17732 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17733 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17734 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17735 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17736 (clobber (reg:CC 17))]
17737 "TARGET_SSE
17738 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17739 "#")
17740
17741 ;; For non-sse moves just expand the usual cmove sequence.
17742 (define_split
17743 [(set (match_operand 0 "register_operand" "")
17744 (if_then_else (match_operator 1 "comparison_operator"
17745 [(match_operand 4 "nonimmediate_operand" "")
17746 (match_operand 5 "register_operand" "")])
17747 (match_operand 2 "nonimmediate_operand" "")
17748 (match_operand 3 "nonimmediate_operand" "")))
17749 (clobber (match_operand 6 "" ""))
17750 (clobber (reg:CC 17))]
17751 "!SSE_REG_P (operands[0]) && reload_completed
17752 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17753 [(const_int 0)]
17754 {
17755 ix86_compare_op0 = operands[5];
17756 ix86_compare_op1 = operands[4];
17757 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17758 VOIDmode, operands[5], operands[4]);
17759 ix86_expand_fp_movcc (operands);
17760 DONE;
17761 })
17762
17763 ;; Split SSE based conditional move into sequence:
17764 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17765 ;; and op2, op0 - zero op2 if comparison was false
17766 ;; nand op0, op3 - load op3 to op0 if comparison was false
17767 ;; or op2, op0 - get the nonzero one into the result.
17768 (define_split
17769 [(set (match_operand 0 "register_operand" "")
17770 (if_then_else (match_operator 1 "sse_comparison_operator"
17771 [(match_operand 4 "register_operand" "")
17772 (match_operand 5 "nonimmediate_operand" "")])
17773 (match_operand 2 "register_operand" "")
17774 (match_operand 3 "register_operand" "")))
17775 (clobber (match_operand 6 "" ""))
17776 (clobber (reg:CC 17))]
17777 "SSE_REG_P (operands[0]) && reload_completed"
17778 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17779 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17780 (subreg:TI (match_dup 4) 0)))
17781 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17782 (subreg:TI (match_dup 3) 0)))
17783 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17784 (subreg:TI (match_dup 7) 0)))]
17785 {
17786 if (GET_MODE (operands[2]) == DFmode
17787 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17788 {
17789 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17790 emit_insn (gen_sse2_unpcklpd (op, op, op));
17791 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17792 emit_insn (gen_sse2_unpcklpd (op, op, op));
17793 }
17794
17795 /* If op2 == op3, op3 would be clobbered before it is used. */
17796 if (operands_match_p (operands[2], operands[3]))
17797 {
17798 emit_move_insn (operands[0], operands[2]);
17799 DONE;
17800 }
17801
17802 PUT_MODE (operands[1], GET_MODE (operands[0]));
17803 if (operands_match_p (operands[0], operands[4]))
17804 operands[6] = operands[4], operands[7] = operands[2];
17805 else
17806 operands[6] = operands[2], operands[7] = operands[4];
17807 })
17808
17809 ;; Special case of conditional move we can handle effectively.
17810 ;; Do not brother with the integer/floating point case, since these are
17811 ;; bot considerably slower, unlike in the generic case.
17812 (define_insn "*sse_movsfcc_const0_1"
17813 [(set (match_operand:SF 0 "register_operand" "=&x")
17814 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17815 [(match_operand:SF 4 "register_operand" "0")
17816 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17817 (match_operand:SF 2 "register_operand" "x")
17818 (match_operand:SF 3 "const0_operand" "X")))]
17819 "TARGET_SSE"
17820 "#")
17821
17822 (define_insn "*sse_movsfcc_const0_2"
17823 [(set (match_operand:SF 0 "register_operand" "=&x")
17824 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17825 [(match_operand:SF 4 "register_operand" "0")
17826 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17827 (match_operand:SF 2 "const0_operand" "X")
17828 (match_operand:SF 3 "register_operand" "x")))]
17829 "TARGET_SSE"
17830 "#")
17831
17832 (define_insn "*sse_movsfcc_const0_3"
17833 [(set (match_operand:SF 0 "register_operand" "=&x")
17834 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17835 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17836 (match_operand:SF 5 "register_operand" "0")])
17837 (match_operand:SF 2 "register_operand" "x")
17838 (match_operand:SF 3 "const0_operand" "X")))]
17839 "TARGET_SSE"
17840 "#")
17841
17842 (define_insn "*sse_movsfcc_const0_4"
17843 [(set (match_operand:SF 0 "register_operand" "=&x")
17844 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17845 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17846 (match_operand:SF 5 "register_operand" "0")])
17847 (match_operand:SF 2 "const0_operand" "X")
17848 (match_operand:SF 3 "register_operand" "x")))]
17849 "TARGET_SSE"
17850 "#")
17851
17852 (define_insn "*sse_movdfcc_const0_1"
17853 [(set (match_operand:DF 0 "register_operand" "=&Y")
17854 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17855 [(match_operand:DF 4 "register_operand" "0")
17856 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17857 (match_operand:DF 2 "register_operand" "Y")
17858 (match_operand:DF 3 "const0_operand" "X")))]
17859 "TARGET_SSE2"
17860 "#")
17861
17862 (define_insn "*sse_movdfcc_const0_2"
17863 [(set (match_operand:DF 0 "register_operand" "=&Y")
17864 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17865 [(match_operand:DF 4 "register_operand" "0")
17866 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17867 (match_operand:DF 2 "const0_operand" "X")
17868 (match_operand:DF 3 "register_operand" "Y")))]
17869 "TARGET_SSE2"
17870 "#")
17871
17872 (define_insn "*sse_movdfcc_const0_3"
17873 [(set (match_operand:DF 0 "register_operand" "=&Y")
17874 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17875 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17876 (match_operand:DF 5 "register_operand" "0")])
17877 (match_operand:DF 2 "register_operand" "Y")
17878 (match_operand:DF 3 "const0_operand" "X")))]
17879 "TARGET_SSE2"
17880 "#")
17881
17882 (define_insn "*sse_movdfcc_const0_4"
17883 [(set (match_operand:DF 0 "register_operand" "=&Y")
17884 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17885 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17886 (match_operand:DF 5 "register_operand" "0")])
17887 (match_operand:DF 2 "const0_operand" "X")
17888 (match_operand:DF 3 "register_operand" "Y")))]
17889 "TARGET_SSE2"
17890 "#")
17891
17892 (define_split
17893 [(set (match_operand 0 "register_operand" "")
17894 (if_then_else (match_operator 1 "comparison_operator"
17895 [(match_operand 4 "nonimmediate_operand" "")
17896 (match_operand 5 "nonimmediate_operand" "")])
17897 (match_operand 2 "nonmemory_operand" "")
17898 (match_operand 3 "nonmemory_operand" "")))]
17899 "SSE_REG_P (operands[0]) && reload_completed
17900 && (const0_operand (operands[2], GET_MODE (operands[0]))
17901 || const0_operand (operands[3], GET_MODE (operands[0])))"
17902 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17903 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17904 (match_dup 7)))]
17905 {
17906 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17907 && GET_MODE (operands[2]) == DFmode)
17908 {
17909 if (REG_P (operands[2]))
17910 {
17911 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17912 emit_insn (gen_sse2_unpcklpd (op, op, op));
17913 }
17914 if (REG_P (operands[3]))
17915 {
17916 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17917 emit_insn (gen_sse2_unpcklpd (op, op, op));
17918 }
17919 }
17920 PUT_MODE (operands[1], GET_MODE (operands[0]));
17921 if (!sse_comparison_operator (operands[1], VOIDmode)
17922 || !rtx_equal_p (operands[0], operands[4]))
17923 {
17924 rtx tmp = operands[5];
17925 operands[5] = operands[4];
17926 operands[4] = tmp;
17927 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17928 }
17929 if (!rtx_equal_p (operands[0], operands[4]))
17930 abort ();
17931 if (const0_operand (operands[2], GET_MODE (operands[0])))
17932 {
17933 operands[7] = operands[3];
17934 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17935 0));
17936 }
17937 else
17938 {
17939 operands[7] = operands[2];
17940 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17941 }
17942 operands[7] = simplify_gen_subreg (TImode, operands[7],
17943 GET_MODE (operands[7]), 0);
17944 })
17945
17946 (define_expand "allocate_stack_worker"
17947 [(match_operand:SI 0 "register_operand" "")]
17948 "TARGET_STACK_PROBE"
17949 {
17950 if (TARGET_64BIT)
17951 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17952 else
17953 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17954 DONE;
17955 })
17956
17957 (define_insn "allocate_stack_worker_1"
17958 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17959 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17960 (clobber (match_dup 0))
17961 (clobber (reg:CC 17))]
17962 "!TARGET_64BIT && TARGET_STACK_PROBE"
17963 "call\t__alloca"
17964 [(set_attr "type" "multi")
17965 (set_attr "length" "5")])
17966
17967 (define_insn "allocate_stack_worker_rex64"
17968 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17969 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17970 (clobber (match_dup 0))
17971 (clobber (reg:CC 17))]
17972 "TARGET_64BIT && TARGET_STACK_PROBE"
17973 "call\t__alloca"
17974 [(set_attr "type" "multi")
17975 (set_attr "length" "5")])
17976
17977 (define_expand "allocate_stack"
17978 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17979 (minus:SI (reg:SI 7)
17980 (match_operand:SI 1 "general_operand" "")))
17981 (clobber (reg:CC 17))])
17982 (parallel [(set (reg:SI 7)
17983 (minus:SI (reg:SI 7) (match_dup 1)))
17984 (clobber (reg:CC 17))])]
17985 "TARGET_STACK_PROBE"
17986 {
17987 #ifdef CHECK_STACK_LIMIT
17988 if (GET_CODE (operands[1]) == CONST_INT
17989 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17990 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17991 operands[1]));
17992 else
17993 #endif
17994 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17995 operands[1])));
17996
17997 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17998 DONE;
17999 })
18000
18001 (define_expand "builtin_setjmp_receiver"
18002 [(label_ref (match_operand 0 "" ""))]
18003 "!TARGET_64BIT && flag_pic"
18004 {
18005 emit_insn (gen_set_got (pic_offset_table_rtx));
18006 DONE;
18007 })
18008 \f
18009 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18010
18011 (define_split
18012 [(set (match_operand 0 "register_operand" "")
18013 (match_operator 3 "promotable_binary_operator"
18014 [(match_operand 1 "register_operand" "")
18015 (match_operand 2 "aligned_operand" "")]))
18016 (clobber (reg:CC 17))]
18017 "! TARGET_PARTIAL_REG_STALL && reload_completed
18018 && ((GET_MODE (operands[0]) == HImode
18019 && ((!optimize_size && !TARGET_FAST_PREFIX)
18020 || GET_CODE (operands[2]) != CONST_INT
18021 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18022 || (GET_MODE (operands[0]) == QImode
18023 && (TARGET_PROMOTE_QImode || optimize_size)))"
18024 [(parallel [(set (match_dup 0)
18025 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18026 (clobber (reg:CC 17))])]
18027 "operands[0] = gen_lowpart (SImode, operands[0]);
18028 operands[1] = gen_lowpart (SImode, operands[1]);
18029 if (GET_CODE (operands[3]) != ASHIFT)
18030 operands[2] = gen_lowpart (SImode, operands[2]);
18031 PUT_MODE (operands[3], SImode);")
18032
18033 ; Promote the QImode tests, as i386 has encoding of the AND
18034 ; instruction with 32-bit sign-extended immediate and thus the
18035 ; instruction size is unchanged, except in the %eax case for
18036 ; which it is increased by one byte, hence the ! optimize_size.
18037 (define_split
18038 [(set (reg 17)
18039 (compare (and (match_operand 1 "aligned_operand" "")
18040 (match_operand 2 "const_int_operand" ""))
18041 (const_int 0)))
18042 (set (match_operand 0 "register_operand" "")
18043 (and (match_dup 1) (match_dup 2)))]
18044 "! TARGET_PARTIAL_REG_STALL && reload_completed
18045 /* Ensure that the operand will remain sign-extended immediate. */
18046 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18047 && ! optimize_size
18048 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18049 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18050 [(parallel [(set (reg:CCNO 17)
18051 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18052 (const_int 0)))
18053 (set (match_dup 0)
18054 (and:SI (match_dup 1) (match_dup 2)))])]
18055 "operands[2]
18056 = gen_int_mode (INTVAL (operands[2])
18057 & GET_MODE_MASK (GET_MODE (operands[0])),
18058 SImode);
18059 operands[0] = gen_lowpart (SImode, operands[0]);
18060 operands[1] = gen_lowpart (SImode, operands[1]);")
18061
18062 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18063 ; the TEST instruction with 32-bit sign-extended immediate and thus
18064 ; the instruction size would at least double, which is not what we
18065 ; want even with ! optimize_size.
18066 (define_split
18067 [(set (reg 17)
18068 (compare (and (match_operand:HI 0 "aligned_operand" "")
18069 (match_operand:HI 1 "const_int_operand" ""))
18070 (const_int 0)))]
18071 "! TARGET_PARTIAL_REG_STALL && reload_completed
18072 /* Ensure that the operand will remain sign-extended immediate. */
18073 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18074 && ! TARGET_FAST_PREFIX
18075 && ! optimize_size"
18076 [(set (reg:CCNO 17)
18077 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18078 (const_int 0)))]
18079 "operands[1]
18080 = gen_int_mode (INTVAL (operands[1])
18081 & GET_MODE_MASK (GET_MODE (operands[0])),
18082 SImode);
18083 operands[0] = gen_lowpart (SImode, operands[0]);")
18084
18085 (define_split
18086 [(set (match_operand 0 "register_operand" "")
18087 (neg (match_operand 1 "register_operand" "")))
18088 (clobber (reg:CC 17))]
18089 "! TARGET_PARTIAL_REG_STALL && reload_completed
18090 && (GET_MODE (operands[0]) == HImode
18091 || (GET_MODE (operands[0]) == QImode
18092 && (TARGET_PROMOTE_QImode || optimize_size)))"
18093 [(parallel [(set (match_dup 0)
18094 (neg:SI (match_dup 1)))
18095 (clobber (reg:CC 17))])]
18096 "operands[0] = gen_lowpart (SImode, operands[0]);
18097 operands[1] = gen_lowpart (SImode, operands[1]);")
18098
18099 (define_split
18100 [(set (match_operand 0 "register_operand" "")
18101 (not (match_operand 1 "register_operand" "")))]
18102 "! TARGET_PARTIAL_REG_STALL && reload_completed
18103 && (GET_MODE (operands[0]) == HImode
18104 || (GET_MODE (operands[0]) == QImode
18105 && (TARGET_PROMOTE_QImode || optimize_size)))"
18106 [(set (match_dup 0)
18107 (not:SI (match_dup 1)))]
18108 "operands[0] = gen_lowpart (SImode, operands[0]);
18109 operands[1] = gen_lowpart (SImode, operands[1]);")
18110
18111 (define_split
18112 [(set (match_operand 0 "register_operand" "")
18113 (if_then_else (match_operator 1 "comparison_operator"
18114 [(reg 17) (const_int 0)])
18115 (match_operand 2 "register_operand" "")
18116 (match_operand 3 "register_operand" "")))]
18117 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18118 && (GET_MODE (operands[0]) == HImode
18119 || (GET_MODE (operands[0]) == QImode
18120 && (TARGET_PROMOTE_QImode || optimize_size)))"
18121 [(set (match_dup 0)
18122 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18123 "operands[0] = gen_lowpart (SImode, operands[0]);
18124 operands[2] = gen_lowpart (SImode, operands[2]);
18125 operands[3] = gen_lowpart (SImode, operands[3]);")
18126
18127 \f
18128 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18129 ;; transform a complex memory operation into two memory to register operations.
18130
18131 ;; Don't push memory operands
18132 (define_peephole2
18133 [(set (match_operand:SI 0 "push_operand" "")
18134 (match_operand:SI 1 "memory_operand" ""))
18135 (match_scratch:SI 2 "r")]
18136 "! optimize_size && ! TARGET_PUSH_MEMORY"
18137 [(set (match_dup 2) (match_dup 1))
18138 (set (match_dup 0) (match_dup 2))]
18139 "")
18140
18141 (define_peephole2
18142 [(set (match_operand:DI 0 "push_operand" "")
18143 (match_operand:DI 1 "memory_operand" ""))
18144 (match_scratch:DI 2 "r")]
18145 "! optimize_size && ! TARGET_PUSH_MEMORY"
18146 [(set (match_dup 2) (match_dup 1))
18147 (set (match_dup 0) (match_dup 2))]
18148 "")
18149
18150 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18151 ;; SImode pushes.
18152 (define_peephole2
18153 [(set (match_operand:SF 0 "push_operand" "")
18154 (match_operand:SF 1 "memory_operand" ""))
18155 (match_scratch:SF 2 "r")]
18156 "! optimize_size && ! TARGET_PUSH_MEMORY"
18157 [(set (match_dup 2) (match_dup 1))
18158 (set (match_dup 0) (match_dup 2))]
18159 "")
18160
18161 (define_peephole2
18162 [(set (match_operand:HI 0 "push_operand" "")
18163 (match_operand:HI 1 "memory_operand" ""))
18164 (match_scratch:HI 2 "r")]
18165 "! optimize_size && ! TARGET_PUSH_MEMORY"
18166 [(set (match_dup 2) (match_dup 1))
18167 (set (match_dup 0) (match_dup 2))]
18168 "")
18169
18170 (define_peephole2
18171 [(set (match_operand:QI 0 "push_operand" "")
18172 (match_operand:QI 1 "memory_operand" ""))
18173 (match_scratch:QI 2 "q")]
18174 "! optimize_size && ! TARGET_PUSH_MEMORY"
18175 [(set (match_dup 2) (match_dup 1))
18176 (set (match_dup 0) (match_dup 2))]
18177 "")
18178
18179 ;; Don't move an immediate directly to memory when the instruction
18180 ;; gets too big.
18181 (define_peephole2
18182 [(match_scratch:SI 1 "r")
18183 (set (match_operand:SI 0 "memory_operand" "")
18184 (const_int 0))]
18185 "! optimize_size
18186 && ! TARGET_USE_MOV0
18187 && TARGET_SPLIT_LONG_MOVES
18188 && get_attr_length (insn) >= ix86_cost->large_insn
18189 && peep2_regno_dead_p (0, FLAGS_REG)"
18190 [(parallel [(set (match_dup 1) (const_int 0))
18191 (clobber (reg:CC 17))])
18192 (set (match_dup 0) (match_dup 1))]
18193 "")
18194
18195 (define_peephole2
18196 [(match_scratch:HI 1 "r")
18197 (set (match_operand:HI 0 "memory_operand" "")
18198 (const_int 0))]
18199 "! optimize_size
18200 && ! TARGET_USE_MOV0
18201 && TARGET_SPLIT_LONG_MOVES
18202 && get_attr_length (insn) >= ix86_cost->large_insn
18203 && peep2_regno_dead_p (0, FLAGS_REG)"
18204 [(parallel [(set (match_dup 2) (const_int 0))
18205 (clobber (reg:CC 17))])
18206 (set (match_dup 0) (match_dup 1))]
18207 "operands[2] = gen_lowpart (SImode, operands[1]);")
18208
18209 (define_peephole2
18210 [(match_scratch:QI 1 "q")
18211 (set (match_operand:QI 0 "memory_operand" "")
18212 (const_int 0))]
18213 "! optimize_size
18214 && ! TARGET_USE_MOV0
18215 && TARGET_SPLIT_LONG_MOVES
18216 && get_attr_length (insn) >= ix86_cost->large_insn
18217 && peep2_regno_dead_p (0, FLAGS_REG)"
18218 [(parallel [(set (match_dup 2) (const_int 0))
18219 (clobber (reg:CC 17))])
18220 (set (match_dup 0) (match_dup 1))]
18221 "operands[2] = gen_lowpart (SImode, operands[1]);")
18222
18223 (define_peephole2
18224 [(match_scratch:SI 2 "r")
18225 (set (match_operand:SI 0 "memory_operand" "")
18226 (match_operand:SI 1 "immediate_operand" ""))]
18227 "! optimize_size
18228 && get_attr_length (insn) >= ix86_cost->large_insn
18229 && TARGET_SPLIT_LONG_MOVES"
18230 [(set (match_dup 2) (match_dup 1))
18231 (set (match_dup 0) (match_dup 2))]
18232 "")
18233
18234 (define_peephole2
18235 [(match_scratch:HI 2 "r")
18236 (set (match_operand:HI 0 "memory_operand" "")
18237 (match_operand:HI 1 "immediate_operand" ""))]
18238 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18239 && TARGET_SPLIT_LONG_MOVES"
18240 [(set (match_dup 2) (match_dup 1))
18241 (set (match_dup 0) (match_dup 2))]
18242 "")
18243
18244 (define_peephole2
18245 [(match_scratch:QI 2 "q")
18246 (set (match_operand:QI 0 "memory_operand" "")
18247 (match_operand:QI 1 "immediate_operand" ""))]
18248 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18249 && TARGET_SPLIT_LONG_MOVES"
18250 [(set (match_dup 2) (match_dup 1))
18251 (set (match_dup 0) (match_dup 2))]
18252 "")
18253
18254 ;; Don't compare memory with zero, load and use a test instead.
18255 (define_peephole2
18256 [(set (reg 17)
18257 (compare (match_operand:SI 0 "memory_operand" "")
18258 (const_int 0)))
18259 (match_scratch:SI 3 "r")]
18260 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18261 [(set (match_dup 3) (match_dup 0))
18262 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18263 "")
18264
18265 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18266 ;; Don't split NOTs with a displacement operand, because resulting XOR
18267 ;; will not be pairable anyway.
18268 ;;
18269 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18270 ;; represented using a modRM byte. The XOR replacement is long decoded,
18271 ;; so this split helps here as well.
18272 ;;
18273 ;; Note: Can't do this as a regular split because we can't get proper
18274 ;; lifetime information then.
18275
18276 (define_peephole2
18277 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18278 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18279 "!optimize_size
18280 && peep2_regno_dead_p (0, FLAGS_REG)
18281 && ((TARGET_PENTIUM
18282 && (GET_CODE (operands[0]) != MEM
18283 || !memory_displacement_operand (operands[0], SImode)))
18284 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18285 [(parallel [(set (match_dup 0)
18286 (xor:SI (match_dup 1) (const_int -1)))
18287 (clobber (reg:CC 17))])]
18288 "")
18289
18290 (define_peephole2
18291 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18292 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18293 "!optimize_size
18294 && peep2_regno_dead_p (0, FLAGS_REG)
18295 && ((TARGET_PENTIUM
18296 && (GET_CODE (operands[0]) != MEM
18297 || !memory_displacement_operand (operands[0], HImode)))
18298 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18299 [(parallel [(set (match_dup 0)
18300 (xor:HI (match_dup 1) (const_int -1)))
18301 (clobber (reg:CC 17))])]
18302 "")
18303
18304 (define_peephole2
18305 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18306 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18307 "!optimize_size
18308 && peep2_regno_dead_p (0, FLAGS_REG)
18309 && ((TARGET_PENTIUM
18310 && (GET_CODE (operands[0]) != MEM
18311 || !memory_displacement_operand (operands[0], QImode)))
18312 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18313 [(parallel [(set (match_dup 0)
18314 (xor:QI (match_dup 1) (const_int -1)))
18315 (clobber (reg:CC 17))])]
18316 "")
18317
18318 ;; Non pairable "test imm, reg" instructions can be translated to
18319 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18320 ;; byte opcode instead of two, have a short form for byte operands),
18321 ;; so do it for other CPUs as well. Given that the value was dead,
18322 ;; this should not create any new dependencies. Pass on the sub-word
18323 ;; versions if we're concerned about partial register stalls.
18324
18325 (define_peephole2
18326 [(set (reg 17)
18327 (compare (and:SI (match_operand:SI 0 "register_operand" "")
18328 (match_operand:SI 1 "immediate_operand" ""))
18329 (const_int 0)))]
18330 "ix86_match_ccmode (insn, CCNOmode)
18331 && (true_regnum (operands[0]) != 0
18332 || (GET_CODE (operands[1]) == CONST_INT
18333 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18334 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18335 [(parallel
18336 [(set (reg:CCNO 17)
18337 (compare:CCNO (and:SI (match_dup 0)
18338 (match_dup 1))
18339 (const_int 0)))
18340 (set (match_dup 0)
18341 (and:SI (match_dup 0) (match_dup 1)))])]
18342 "")
18343
18344 ;; We don't need to handle HImode case, because it will be promoted to SImode
18345 ;; on ! TARGET_PARTIAL_REG_STALL
18346
18347 (define_peephole2
18348 [(set (reg 17)
18349 (compare (and:QI (match_operand:QI 0 "register_operand" "")
18350 (match_operand:QI 1 "immediate_operand" ""))
18351 (const_int 0)))]
18352 "! TARGET_PARTIAL_REG_STALL
18353 && ix86_match_ccmode (insn, CCNOmode)
18354 && true_regnum (operands[0]) != 0
18355 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18356 [(parallel
18357 [(set (reg:CCNO 17)
18358 (compare:CCNO (and:QI (match_dup 0)
18359 (match_dup 1))
18360 (const_int 0)))
18361 (set (match_dup 0)
18362 (and:QI (match_dup 0) (match_dup 1)))])]
18363 "")
18364
18365 (define_peephole2
18366 [(set (reg 17)
18367 (compare
18368 (and:SI
18369 (zero_extract:SI
18370 (match_operand 0 "ext_register_operand" "")
18371 (const_int 8)
18372 (const_int 8))
18373 (match_operand 1 "const_int_operand" ""))
18374 (const_int 0)))]
18375 "! TARGET_PARTIAL_REG_STALL
18376 && ix86_match_ccmode (insn, CCNOmode)
18377 && true_regnum (operands[0]) != 0
18378 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18379 [(parallel [(set (reg:CCNO 17)
18380 (compare:CCNO
18381 (and:SI
18382 (zero_extract:SI
18383 (match_dup 0)
18384 (const_int 8)
18385 (const_int 8))
18386 (match_dup 1))
18387 (const_int 0)))
18388 (set (zero_extract:SI (match_dup 0)
18389 (const_int 8)
18390 (const_int 8))
18391 (and:SI
18392 (zero_extract:SI
18393 (match_dup 0)
18394 (const_int 8)
18395 (const_int 8))
18396 (match_dup 1)))])]
18397 "")
18398
18399 ;; Don't do logical operations with memory inputs.
18400 (define_peephole2
18401 [(match_scratch:SI 2 "r")
18402 (parallel [(set (match_operand:SI 0 "register_operand" "")
18403 (match_operator:SI 3 "arith_or_logical_operator"
18404 [(match_dup 0)
18405 (match_operand:SI 1 "memory_operand" "")]))
18406 (clobber (reg:CC 17))])]
18407 "! optimize_size && ! TARGET_READ_MODIFY"
18408 [(set (match_dup 2) (match_dup 1))
18409 (parallel [(set (match_dup 0)
18410 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18411 (clobber (reg:CC 17))])]
18412 "")
18413
18414 (define_peephole2
18415 [(match_scratch:SI 2 "r")
18416 (parallel [(set (match_operand:SI 0 "register_operand" "")
18417 (match_operator:SI 3 "arith_or_logical_operator"
18418 [(match_operand:SI 1 "memory_operand" "")
18419 (match_dup 0)]))
18420 (clobber (reg:CC 17))])]
18421 "! optimize_size && ! TARGET_READ_MODIFY"
18422 [(set (match_dup 2) (match_dup 1))
18423 (parallel [(set (match_dup 0)
18424 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18425 (clobber (reg:CC 17))])]
18426 "")
18427
18428 ; Don't do logical operations with memory outputs
18429 ;
18430 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18431 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18432 ; the same decoder scheduling characteristics as the original.
18433
18434 (define_peephole2
18435 [(match_scratch:SI 2 "r")
18436 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18437 (match_operator:SI 3 "arith_or_logical_operator"
18438 [(match_dup 0)
18439 (match_operand:SI 1 "nonmemory_operand" "")]))
18440 (clobber (reg:CC 17))])]
18441 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18442 [(set (match_dup 2) (match_dup 0))
18443 (parallel [(set (match_dup 2)
18444 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18445 (clobber (reg:CC 17))])
18446 (set (match_dup 0) (match_dup 2))]
18447 "")
18448
18449 (define_peephole2
18450 [(match_scratch:SI 2 "r")
18451 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18452 (match_operator:SI 3 "arith_or_logical_operator"
18453 [(match_operand:SI 1 "nonmemory_operand" "")
18454 (match_dup 0)]))
18455 (clobber (reg:CC 17))])]
18456 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18457 [(set (match_dup 2) (match_dup 0))
18458 (parallel [(set (match_dup 2)
18459 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18460 (clobber (reg:CC 17))])
18461 (set (match_dup 0) (match_dup 2))]
18462 "")
18463
18464 ;; Attempt to always use XOR for zeroing registers.
18465 (define_peephole2
18466 [(set (match_operand 0 "register_operand" "")
18467 (const_int 0))]
18468 "(GET_MODE (operands[0]) == QImode
18469 || GET_MODE (operands[0]) == HImode
18470 || GET_MODE (operands[0]) == SImode
18471 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18472 && (! TARGET_USE_MOV0 || optimize_size)
18473 && peep2_regno_dead_p (0, FLAGS_REG)"
18474 [(parallel [(set (match_dup 0) (const_int 0))
18475 (clobber (reg:CC 17))])]
18476 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18477 operands[0]);")
18478
18479 (define_peephole2
18480 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18481 (const_int 0))]
18482 "(GET_MODE (operands[0]) == QImode
18483 || GET_MODE (operands[0]) == HImode)
18484 && (! TARGET_USE_MOV0 || optimize_size)
18485 && peep2_regno_dead_p (0, FLAGS_REG)"
18486 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18487 (clobber (reg:CC 17))])])
18488
18489 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18490 (define_peephole2
18491 [(set (match_operand 0 "register_operand" "")
18492 (const_int -1))]
18493 "(GET_MODE (operands[0]) == HImode
18494 || GET_MODE (operands[0]) == SImode
18495 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18496 && (optimize_size || TARGET_PENTIUM)
18497 && peep2_regno_dead_p (0, FLAGS_REG)"
18498 [(parallel [(set (match_dup 0) (const_int -1))
18499 (clobber (reg:CC 17))])]
18500 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18501 operands[0]);")
18502
18503 ;; Attempt to convert simple leas to adds. These can be created by
18504 ;; move expanders.
18505 (define_peephole2
18506 [(set (match_operand:SI 0 "register_operand" "")
18507 (plus:SI (match_dup 0)
18508 (match_operand:SI 1 "nonmemory_operand" "")))]
18509 "peep2_regno_dead_p (0, FLAGS_REG)"
18510 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18511 (clobber (reg:CC 17))])]
18512 "")
18513
18514 (define_peephole2
18515 [(set (match_operand:SI 0 "register_operand" "")
18516 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18517 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18518 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18519 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18520 (clobber (reg:CC 17))])]
18521 "operands[2] = gen_lowpart (SImode, operands[2]);")
18522
18523 (define_peephole2
18524 [(set (match_operand:DI 0 "register_operand" "")
18525 (plus:DI (match_dup 0)
18526 (match_operand:DI 1 "x86_64_general_operand" "")))]
18527 "peep2_regno_dead_p (0, FLAGS_REG)"
18528 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18529 (clobber (reg:CC 17))])]
18530 "")
18531
18532 (define_peephole2
18533 [(set (match_operand:SI 0 "register_operand" "")
18534 (mult:SI (match_dup 0)
18535 (match_operand:SI 1 "const_int_operand" "")))]
18536 "exact_log2 (INTVAL (operands[1])) >= 0
18537 && peep2_regno_dead_p (0, FLAGS_REG)"
18538 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18539 (clobber (reg:CC 17))])]
18540 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18541
18542 (define_peephole2
18543 [(set (match_operand:DI 0 "register_operand" "")
18544 (mult:DI (match_dup 0)
18545 (match_operand:DI 1 "const_int_operand" "")))]
18546 "exact_log2 (INTVAL (operands[1])) >= 0
18547 && peep2_regno_dead_p (0, FLAGS_REG)"
18548 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18549 (clobber (reg:CC 17))])]
18550 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18551
18552 (define_peephole2
18553 [(set (match_operand:SI 0 "register_operand" "")
18554 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18555 (match_operand:DI 2 "const_int_operand" "")) 0))]
18556 "exact_log2 (INTVAL (operands[2])) >= 0
18557 && REGNO (operands[0]) == REGNO (operands[1])
18558 && peep2_regno_dead_p (0, FLAGS_REG)"
18559 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18560 (clobber (reg:CC 17))])]
18561 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18562
18563 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18564 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18565 ;; many CPUs it is also faster, since special hardware to avoid esp
18566 ;; dependencies is present.
18567
18568 ;; While some of these conversions may be done using splitters, we use peepholes
18569 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18570
18571 ;; Convert prologue esp subtractions to push.
18572 ;; We need register to push. In order to keep verify_flow_info happy we have
18573 ;; two choices
18574 ;; - use scratch and clobber it in order to avoid dependencies
18575 ;; - use already live register
18576 ;; We can't use the second way right now, since there is no reliable way how to
18577 ;; verify that given register is live. First choice will also most likely in
18578 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18579 ;; call clobbered registers are dead. We may want to use base pointer as an
18580 ;; alternative when no register is available later.
18581
18582 (define_peephole2
18583 [(match_scratch:SI 0 "r")
18584 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18585 (clobber (reg:CC 17))
18586 (clobber (mem:BLK (scratch)))])]
18587 "optimize_size || !TARGET_SUB_ESP_4"
18588 [(clobber (match_dup 0))
18589 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18590 (clobber (mem:BLK (scratch)))])])
18591
18592 (define_peephole2
18593 [(match_scratch:SI 0 "r")
18594 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18595 (clobber (reg:CC 17))
18596 (clobber (mem:BLK (scratch)))])]
18597 "optimize_size || !TARGET_SUB_ESP_8"
18598 [(clobber (match_dup 0))
18599 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18600 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18601 (clobber (mem:BLK (scratch)))])])
18602
18603 ;; Convert esp subtractions to push.
18604 (define_peephole2
18605 [(match_scratch:SI 0 "r")
18606 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18607 (clobber (reg:CC 17))])]
18608 "optimize_size || !TARGET_SUB_ESP_4"
18609 [(clobber (match_dup 0))
18610 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18611
18612 (define_peephole2
18613 [(match_scratch:SI 0 "r")
18614 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18615 (clobber (reg:CC 17))])]
18616 "optimize_size || !TARGET_SUB_ESP_8"
18617 [(clobber (match_dup 0))
18618 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18619 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18620
18621 ;; Convert epilogue deallocator to pop.
18622 (define_peephole2
18623 [(match_scratch:SI 0 "r")
18624 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18625 (clobber (reg:CC 17))
18626 (clobber (mem:BLK (scratch)))])]
18627 "optimize_size || !TARGET_ADD_ESP_4"
18628 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18629 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18630 (clobber (mem:BLK (scratch)))])]
18631 "")
18632
18633 ;; Two pops case is tricky, since pop causes dependency on destination register.
18634 ;; We use two registers if available.
18635 (define_peephole2
18636 [(match_scratch:SI 0 "r")
18637 (match_scratch:SI 1 "r")
18638 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18639 (clobber (reg:CC 17))
18640 (clobber (mem:BLK (scratch)))])]
18641 "optimize_size || !TARGET_ADD_ESP_8"
18642 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18643 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18644 (clobber (mem:BLK (scratch)))])
18645 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18646 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18647 "")
18648
18649 (define_peephole2
18650 [(match_scratch:SI 0 "r")
18651 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18652 (clobber (reg:CC 17))
18653 (clobber (mem:BLK (scratch)))])]
18654 "optimize_size"
18655 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18656 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18657 (clobber (mem:BLK (scratch)))])
18658 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18659 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18660 "")
18661
18662 ;; Convert esp additions to pop.
18663 (define_peephole2
18664 [(match_scratch:SI 0 "r")
18665 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18666 (clobber (reg:CC 17))])]
18667 ""
18668 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18669 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18670 "")
18671
18672 ;; Two pops case is tricky, since pop causes dependency on destination register.
18673 ;; We use two registers if available.
18674 (define_peephole2
18675 [(match_scratch:SI 0 "r")
18676 (match_scratch:SI 1 "r")
18677 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18678 (clobber (reg:CC 17))])]
18679 ""
18680 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18681 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18682 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18683 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18684 "")
18685
18686 (define_peephole2
18687 [(match_scratch:SI 0 "r")
18688 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18689 (clobber (reg:CC 17))])]
18690 "optimize_size"
18691 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18692 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18693 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18694 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18695 "")
18696 \f
18697 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18698 ;; required and register dies.
18699 (define_peephole2
18700 [(set (reg 17)
18701 (compare (match_operand:SI 0 "register_operand" "")
18702 (match_operand:SI 1 "incdec_operand" "")))]
18703 "ix86_match_ccmode (insn, CCGCmode)
18704 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18705 [(parallel [(set (reg:CCGC 17)
18706 (compare:CCGC (match_dup 0)
18707 (match_dup 1)))
18708 (clobber (match_dup 0))])]
18709 "")
18710
18711 (define_peephole2
18712 [(set (reg 17)
18713 (compare (match_operand:HI 0 "register_operand" "")
18714 (match_operand:HI 1 "incdec_operand" "")))]
18715 "ix86_match_ccmode (insn, CCGCmode)
18716 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18717 [(parallel [(set (reg:CCGC 17)
18718 (compare:CCGC (match_dup 0)
18719 (match_dup 1)))
18720 (clobber (match_dup 0))])]
18721 "")
18722
18723 (define_peephole2
18724 [(set (reg 17)
18725 (compare (match_operand:QI 0 "register_operand" "")
18726 (match_operand:QI 1 "incdec_operand" "")))]
18727 "ix86_match_ccmode (insn, CCGCmode)
18728 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18729 [(parallel [(set (reg:CCGC 17)
18730 (compare:CCGC (match_dup 0)
18731 (match_dup 1)))
18732 (clobber (match_dup 0))])]
18733 "")
18734
18735 ;; Convert compares with 128 to shorter add -128
18736 (define_peephole2
18737 [(set (reg 17)
18738 (compare (match_operand:SI 0 "register_operand" "")
18739 (const_int 128)))]
18740 "ix86_match_ccmode (insn, CCGCmode)
18741 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18742 [(parallel [(set (reg:CCGC 17)
18743 (compare:CCGC (match_dup 0)
18744 (const_int 128)))
18745 (clobber (match_dup 0))])]
18746 "")
18747
18748 (define_peephole2
18749 [(set (reg 17)
18750 (compare (match_operand:HI 0 "register_operand" "")
18751 (const_int 128)))]
18752 "ix86_match_ccmode (insn, CCGCmode)
18753 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18754 [(parallel [(set (reg:CCGC 17)
18755 (compare:CCGC (match_dup 0)
18756 (const_int 128)))
18757 (clobber (match_dup 0))])]
18758 "")
18759 \f
18760 (define_peephole2
18761 [(match_scratch:DI 0 "r")
18762 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18763 (clobber (reg:CC 17))
18764 (clobber (mem:BLK (scratch)))])]
18765 "optimize_size || !TARGET_SUB_ESP_4"
18766 [(clobber (match_dup 0))
18767 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18768 (clobber (mem:BLK (scratch)))])])
18769
18770 (define_peephole2
18771 [(match_scratch:DI 0 "r")
18772 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18773 (clobber (reg:CC 17))
18774 (clobber (mem:BLK (scratch)))])]
18775 "optimize_size || !TARGET_SUB_ESP_8"
18776 [(clobber (match_dup 0))
18777 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18778 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18779 (clobber (mem:BLK (scratch)))])])
18780
18781 ;; Convert esp subtractions to push.
18782 (define_peephole2
18783 [(match_scratch:DI 0 "r")
18784 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18785 (clobber (reg:CC 17))])]
18786 "optimize_size || !TARGET_SUB_ESP_4"
18787 [(clobber (match_dup 0))
18788 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18789
18790 (define_peephole2
18791 [(match_scratch:DI 0 "r")
18792 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18793 (clobber (reg:CC 17))])]
18794 "optimize_size || !TARGET_SUB_ESP_8"
18795 [(clobber (match_dup 0))
18796 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18797 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18798
18799 ;; Convert epilogue deallocator to pop.
18800 (define_peephole2
18801 [(match_scratch:DI 0 "r")
18802 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18803 (clobber (reg:CC 17))
18804 (clobber (mem:BLK (scratch)))])]
18805 "optimize_size || !TARGET_ADD_ESP_4"
18806 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18807 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18808 (clobber (mem:BLK (scratch)))])]
18809 "")
18810
18811 ;; Two pops case is tricky, since pop causes dependency on destination register.
18812 ;; We use two registers if available.
18813 (define_peephole2
18814 [(match_scratch:DI 0 "r")
18815 (match_scratch:DI 1 "r")
18816 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18817 (clobber (reg:CC 17))
18818 (clobber (mem:BLK (scratch)))])]
18819 "optimize_size || !TARGET_ADD_ESP_8"
18820 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18821 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18822 (clobber (mem:BLK (scratch)))])
18823 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18824 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18825 "")
18826
18827 (define_peephole2
18828 [(match_scratch:DI 0 "r")
18829 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18830 (clobber (reg:CC 17))
18831 (clobber (mem:BLK (scratch)))])]
18832 "optimize_size"
18833 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18834 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18835 (clobber (mem:BLK (scratch)))])
18836 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18837 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18838 "")
18839
18840 ;; Convert esp additions to pop.
18841 (define_peephole2
18842 [(match_scratch:DI 0 "r")
18843 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18844 (clobber (reg:CC 17))])]
18845 ""
18846 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18847 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18848 "")
18849
18850 ;; Two pops case is tricky, since pop causes dependency on destination register.
18851 ;; We use two registers if available.
18852 (define_peephole2
18853 [(match_scratch:DI 0 "r")
18854 (match_scratch:DI 1 "r")
18855 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18856 (clobber (reg:CC 17))])]
18857 ""
18858 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18859 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18860 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18861 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18862 "")
18863
18864 (define_peephole2
18865 [(match_scratch:DI 0 "r")
18866 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18867 (clobber (reg:CC 17))])]
18868 "optimize_size"
18869 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18870 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18871 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18872 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18873 "")
18874 \f
18875 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18876 ;; imul $32bit_imm, reg, reg is direct decoded.
18877 (define_peephole2
18878 [(match_scratch:DI 3 "r")
18879 (parallel [(set (match_operand:DI 0 "register_operand" "")
18880 (mult:DI (match_operand:DI 1 "memory_operand" "")
18881 (match_operand:DI 2 "immediate_operand" "")))
18882 (clobber (reg:CC 17))])]
18883 "TARGET_K8 && !optimize_size
18884 && (GET_CODE (operands[2]) != CONST_INT
18885 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18886 [(set (match_dup 3) (match_dup 1))
18887 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18888 (clobber (reg:CC 17))])]
18889 "")
18890
18891 (define_peephole2
18892 [(match_scratch:SI 3 "r")
18893 (parallel [(set (match_operand:SI 0 "register_operand" "")
18894 (mult:SI (match_operand:SI 1 "memory_operand" "")
18895 (match_operand:SI 2 "immediate_operand" "")))
18896 (clobber (reg:CC 17))])]
18897 "TARGET_K8 && !optimize_size
18898 && (GET_CODE (operands[2]) != CONST_INT
18899 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18900 [(set (match_dup 3) (match_dup 1))
18901 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18902 (clobber (reg:CC 17))])]
18903 "")
18904
18905 (define_peephole2
18906 [(match_scratch:SI 3 "r")
18907 (parallel [(set (match_operand:DI 0 "register_operand" "")
18908 (zero_extend:DI
18909 (mult:SI (match_operand:SI 1 "memory_operand" "")
18910 (match_operand:SI 2 "immediate_operand" ""))))
18911 (clobber (reg:CC 17))])]
18912 "TARGET_K8 && !optimize_size
18913 && (GET_CODE (operands[2]) != CONST_INT
18914 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18915 [(set (match_dup 3) (match_dup 1))
18916 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18917 (clobber (reg:CC 17))])]
18918 "")
18919
18920 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18921 ;; Convert it into imul reg, reg
18922 ;; It would be better to force assembler to encode instruction using long
18923 ;; immediate, but there is apparently no way to do so.
18924 (define_peephole2
18925 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18926 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18927 (match_operand:DI 2 "const_int_operand" "")))
18928 (clobber (reg:CC 17))])
18929 (match_scratch:DI 3 "r")]
18930 "TARGET_K8 && !optimize_size
18931 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18932 [(set (match_dup 3) (match_dup 2))
18933 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18934 (clobber (reg:CC 17))])]
18935 {
18936 if (!rtx_equal_p (operands[0], operands[1]))
18937 emit_move_insn (operands[0], operands[1]);
18938 })
18939
18940 (define_peephole2
18941 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18942 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18943 (match_operand:SI 2 "const_int_operand" "")))
18944 (clobber (reg:CC 17))])
18945 (match_scratch:SI 3 "r")]
18946 "TARGET_K8 && !optimize_size
18947 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18948 [(set (match_dup 3) (match_dup 2))
18949 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18950 (clobber (reg:CC 17))])]
18951 {
18952 if (!rtx_equal_p (operands[0], operands[1]))
18953 emit_move_insn (operands[0], operands[1]);
18954 })
18955
18956 (define_peephole2
18957 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18958 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18959 (match_operand:HI 2 "immediate_operand" "")))
18960 (clobber (reg:CC 17))])
18961 (match_scratch:HI 3 "r")]
18962 "TARGET_K8 && !optimize_size"
18963 [(set (match_dup 3) (match_dup 2))
18964 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18965 (clobber (reg:CC 17))])]
18966 {
18967 if (!rtx_equal_p (operands[0], operands[1]))
18968 emit_move_insn (operands[0], operands[1]);
18969 })
18970 \f
18971 ;; Call-value patterns last so that the wildcard operand does not
18972 ;; disrupt insn-recog's switch tables.
18973
18974 (define_insn "*call_value_pop_0"
18975 [(set (match_operand 0 "" "")
18976 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18977 (match_operand:SI 2 "" "")))
18978 (set (reg:SI 7) (plus:SI (reg:SI 7)
18979 (match_operand:SI 3 "immediate_operand" "")))]
18980 "!TARGET_64BIT"
18981 {
18982 if (SIBLING_CALL_P (insn))
18983 return "jmp\t%P1";
18984 else
18985 return "call\t%P1";
18986 }
18987 [(set_attr "type" "callv")])
18988
18989 (define_insn "*call_value_pop_1"
18990 [(set (match_operand 0 "" "")
18991 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18992 (match_operand:SI 2 "" "")))
18993 (set (reg:SI 7) (plus:SI (reg:SI 7)
18994 (match_operand:SI 3 "immediate_operand" "i")))]
18995 "!TARGET_64BIT"
18996 {
18997 if (constant_call_address_operand (operands[1], QImode))
18998 {
18999 if (SIBLING_CALL_P (insn))
19000 return "jmp\t%P1";
19001 else
19002 return "call\t%P1";
19003 }
19004 if (SIBLING_CALL_P (insn))
19005 return "jmp\t%A1";
19006 else
19007 return "call\t%A1";
19008 }
19009 [(set_attr "type" "callv")])
19010
19011 (define_insn "*call_value_0"
19012 [(set (match_operand 0 "" "")
19013 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19014 (match_operand:SI 2 "" "")))]
19015 "!TARGET_64BIT"
19016 {
19017 if (SIBLING_CALL_P (insn))
19018 return "jmp\t%P1";
19019 else
19020 return "call\t%P1";
19021 }
19022 [(set_attr "type" "callv")])
19023
19024 (define_insn "*call_value_0_rex64"
19025 [(set (match_operand 0 "" "")
19026 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19027 (match_operand:DI 2 "const_int_operand" "")))]
19028 "TARGET_64BIT"
19029 {
19030 if (SIBLING_CALL_P (insn))
19031 return "jmp\t%P1";
19032 else
19033 return "call\t%P1";
19034 }
19035 [(set_attr "type" "callv")])
19036
19037 (define_insn "*call_value_1"
19038 [(set (match_operand 0 "" "")
19039 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19040 (match_operand:SI 2 "" "")))]
19041 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19042 {
19043 if (constant_call_address_operand (operands[1], QImode))
19044 return "call\t%P1";
19045 return "call\t%*%1";
19046 }
19047 [(set_attr "type" "callv")])
19048
19049 (define_insn "*sibcall_value_1"
19050 [(set (match_operand 0 "" "")
19051 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19052 (match_operand:SI 2 "" "")))]
19053 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19054 {
19055 if (constant_call_address_operand (operands[1], QImode))
19056 return "jmp\t%P1";
19057 return "jmp\t%*%1";
19058 }
19059 [(set_attr "type" "callv")])
19060
19061 (define_insn "*call_value_1_rex64"
19062 [(set (match_operand 0 "" "")
19063 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19064 (match_operand:DI 2 "" "")))]
19065 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19066 {
19067 if (constant_call_address_operand (operands[1], QImode))
19068 return "call\t%P1";
19069 return "call\t%A1";
19070 }
19071 [(set_attr "type" "callv")])
19072
19073 (define_insn "*sibcall_value_1_rex64"
19074 [(set (match_operand 0 "" "")
19075 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19076 (match_operand:DI 2 "" "")))]
19077 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19078 "jmp\t%P1"
19079 [(set_attr "type" "callv")])
19080
19081 (define_insn "*sibcall_value_1_rex64_v"
19082 [(set (match_operand 0 "" "")
19083 (call (mem:QI (reg:DI 40))
19084 (match_operand:DI 1 "" "")))]
19085 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19086 "jmp\t*%%r11"
19087 [(set_attr "type" "callv")])
19088 \f
19089 (define_insn "trap"
19090 [(trap_if (const_int 1) (const_int 5))]
19091 ""
19092 "int\t$5")
19093
19094 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19095 ;;; for the sake of bounds checking. By emitting bounds checks as
19096 ;;; conditional traps rather than as conditional jumps around
19097 ;;; unconditional traps we avoid introducing spurious basic-block
19098 ;;; boundaries and facilitate elimination of redundant checks. In
19099 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19100 ;;; interrupt 5.
19101 ;;;
19102 ;;; FIXME: Static branch prediction rules for ix86 are such that
19103 ;;; forward conditional branches predict as untaken. As implemented
19104 ;;; below, pseudo conditional traps violate that rule. We should use
19105 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19106 ;;; section loaded at the end of the text segment and branch forward
19107 ;;; there on bounds-failure, and then jump back immediately (in case
19108 ;;; the system chooses to ignore bounds violations, or to report
19109 ;;; violations and continue execution).
19110
19111 (define_expand "conditional_trap"
19112 [(trap_if (match_operator 0 "comparison_operator"
19113 [(match_dup 2) (const_int 0)])
19114 (match_operand 1 "const_int_operand" ""))]
19115 ""
19116 {
19117 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19118 ix86_expand_compare (GET_CODE (operands[0]),
19119 NULL, NULL),
19120 operands[1]));
19121 DONE;
19122 })
19123
19124 (define_insn "*conditional_trap_1"
19125 [(trap_if (match_operator 0 "comparison_operator"
19126 [(reg 17) (const_int 0)])
19127 (match_operand 1 "const_int_operand" ""))]
19128 ""
19129 {
19130 operands[2] = gen_label_rtx ();
19131 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19132 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19133 CODE_LABEL_NUMBER (operands[2]));
19134 RET;
19135 })
19136
19137 ;; Pentium III SIMD instructions.
19138
19139 ;; Moves for SSE/MMX regs.
19140
19141 (define_insn "movv4sf_internal"
19142 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19143 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19144 "TARGET_SSE"
19145 "@
19146 xorps\t%0, %0
19147 movaps\t{%1, %0|%0, %1}
19148 movaps\t{%1, %0|%0, %1}"
19149 [(set_attr "type" "ssemov")
19150 (set_attr "mode" "V4SF")])
19151
19152 (define_split
19153 [(set (match_operand:V4SF 0 "register_operand" "")
19154 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19155 "TARGET_SSE"
19156 [(set (match_dup 0)
19157 (vec_merge:V4SF
19158 (vec_duplicate:V4SF (match_dup 1))
19159 (match_dup 2)
19160 (const_int 1)))]
19161 {
19162 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19163 operands[2] = CONST0_RTX (V4SFmode);
19164 })
19165
19166 (define_insn "movv4si_internal"
19167 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19168 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19169 "TARGET_SSE"
19170 {
19171 switch (which_alternative)
19172 {
19173 case 0:
19174 if (get_attr_mode (insn) == MODE_V4SF)
19175 return "xorps\t%0, %0";
19176 else
19177 return "pxor\t%0, %0";
19178 case 1:
19179 case 2:
19180 if (get_attr_mode (insn) == MODE_V4SF)
19181 return "movaps\t{%1, %0|%0, %1}";
19182 else
19183 return "movdqa\t{%1, %0|%0, %1}";
19184 default:
19185 abort ();
19186 }
19187 }
19188 [(set_attr "type" "ssemov")
19189 (set (attr "mode")
19190 (cond [(eq_attr "alternative" "0,1")
19191 (if_then_else
19192 (ne (symbol_ref "optimize_size")
19193 (const_int 0))
19194 (const_string "V4SF")
19195 (const_string "TI"))
19196 (eq_attr "alternative" "2")
19197 (if_then_else
19198 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19199 (const_int 0))
19200 (ne (symbol_ref "optimize_size")
19201 (const_int 0)))
19202 (const_string "V4SF")
19203 (const_string "TI"))]
19204 (const_string "TI")))])
19205
19206 (define_insn "movv2di_internal"
19207 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19208 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19209 "TARGET_SSE2"
19210 {
19211 switch (which_alternative)
19212 {
19213 case 0:
19214 if (get_attr_mode (insn) == MODE_V4SF)
19215 return "xorps\t%0, %0";
19216 else
19217 return "pxor\t%0, %0";
19218 case 1:
19219 case 2:
19220 if (get_attr_mode (insn) == MODE_V4SF)
19221 return "movaps\t{%1, %0|%0, %1}";
19222 else
19223 return "movdqa\t{%1, %0|%0, %1}";
19224 default:
19225 abort ();
19226 }
19227 }
19228 [(set_attr "type" "ssemov")
19229 (set (attr "mode")
19230 (cond [(eq_attr "alternative" "0,1")
19231 (if_then_else
19232 (ne (symbol_ref "optimize_size")
19233 (const_int 0))
19234 (const_string "V4SF")
19235 (const_string "TI"))
19236 (eq_attr "alternative" "2")
19237 (if_then_else
19238 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19239 (const_int 0))
19240 (ne (symbol_ref "optimize_size")
19241 (const_int 0)))
19242 (const_string "V4SF")
19243 (const_string "TI"))]
19244 (const_string "TI")))])
19245
19246 (define_split
19247 [(set (match_operand:V2DF 0 "register_operand" "")
19248 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19249 "TARGET_SSE2"
19250 [(set (match_dup 0)
19251 (vec_merge:V2DF
19252 (vec_duplicate:V2DF (match_dup 1))
19253 (match_dup 2)
19254 (const_int 1)))]
19255 {
19256 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19257 operands[2] = CONST0_RTX (V2DFmode);
19258 })
19259
19260 (define_insn "movv8qi_internal"
19261 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19262 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19263 "TARGET_MMX
19264 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19265 "@
19266 pxor\t%0, %0
19267 movq\t{%1, %0|%0, %1}
19268 movq\t{%1, %0|%0, %1}"
19269 [(set_attr "type" "mmxmov")
19270 (set_attr "mode" "DI")])
19271
19272 (define_insn "movv4hi_internal"
19273 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19274 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19275 "TARGET_MMX
19276 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19277 "@
19278 pxor\t%0, %0
19279 movq\t{%1, %0|%0, %1}
19280 movq\t{%1, %0|%0, %1}"
19281 [(set_attr "type" "mmxmov")
19282 (set_attr "mode" "DI")])
19283
19284 (define_insn "movv2si_internal"
19285 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19286 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19287 "TARGET_MMX
19288 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19289 "@
19290 pxor\t%0, %0
19291 movq\t{%1, %0|%0, %1}
19292 movq\t{%1, %0|%0, %1}"
19293 [(set_attr "type" "mmxcvt")
19294 (set_attr "mode" "DI")])
19295
19296 (define_insn "movv2sf_internal"
19297 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19298 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19299 "TARGET_3DNOW
19300 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19301 "@
19302 pxor\t%0, %0
19303 movq\t{%1, %0|%0, %1}
19304 movq\t{%1, %0|%0, %1}"
19305 [(set_attr "type" "mmxcvt")
19306 (set_attr "mode" "DI")])
19307
19308 (define_expand "movti"
19309 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19310 (match_operand:TI 1 "nonimmediate_operand" ""))]
19311 "TARGET_SSE || TARGET_64BIT"
19312 {
19313 if (TARGET_64BIT)
19314 ix86_expand_move (TImode, operands);
19315 else
19316 ix86_expand_vector_move (TImode, operands);
19317 DONE;
19318 })
19319
19320 (define_insn "movv2df_internal"
19321 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19322 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19323 "TARGET_SSE2
19324 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19325 {
19326 switch (which_alternative)
19327 {
19328 case 0:
19329 if (get_attr_mode (insn) == MODE_V4SF)
19330 return "xorps\t%0, %0";
19331 else
19332 return "xorpd\t%0, %0";
19333 case 1:
19334 case 2:
19335 if (get_attr_mode (insn) == MODE_V4SF)
19336 return "movaps\t{%1, %0|%0, %1}";
19337 else
19338 return "movapd\t{%1, %0|%0, %1}";
19339 default:
19340 abort ();
19341 }
19342 }
19343 [(set_attr "type" "ssemov")
19344 (set (attr "mode")
19345 (cond [(eq_attr "alternative" "0,1")
19346 (if_then_else
19347 (ne (symbol_ref "optimize_size")
19348 (const_int 0))
19349 (const_string "V4SF")
19350 (const_string "V2DF"))
19351 (eq_attr "alternative" "2")
19352 (if_then_else
19353 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19354 (const_int 0))
19355 (ne (symbol_ref "optimize_size")
19356 (const_int 0)))
19357 (const_string "V4SF")
19358 (const_string "V2DF"))]
19359 (const_string "V2DF")))])
19360
19361 (define_insn "movv8hi_internal"
19362 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19363 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19364 "TARGET_SSE2
19365 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19366 {
19367 switch (which_alternative)
19368 {
19369 case 0:
19370 if (get_attr_mode (insn) == MODE_V4SF)
19371 return "xorps\t%0, %0";
19372 else
19373 return "pxor\t%0, %0";
19374 case 1:
19375 case 2:
19376 if (get_attr_mode (insn) == MODE_V4SF)
19377 return "movaps\t{%1, %0|%0, %1}";
19378 else
19379 return "movdqa\t{%1, %0|%0, %1}";
19380 default:
19381 abort ();
19382 }
19383 }
19384 [(set_attr "type" "ssemov")
19385 (set (attr "mode")
19386 (cond [(eq_attr "alternative" "0,1")
19387 (if_then_else
19388 (ne (symbol_ref "optimize_size")
19389 (const_int 0))
19390 (const_string "V4SF")
19391 (const_string "TI"))
19392 (eq_attr "alternative" "2")
19393 (if_then_else
19394 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19395 (const_int 0))
19396 (ne (symbol_ref "optimize_size")
19397 (const_int 0)))
19398 (const_string "V4SF")
19399 (const_string "TI"))]
19400 (const_string "TI")))])
19401
19402 (define_insn "movv16qi_internal"
19403 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19404 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19405 "TARGET_SSE2
19406 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19407 {
19408 switch (which_alternative)
19409 {
19410 case 0:
19411 if (get_attr_mode (insn) == MODE_V4SF)
19412 return "xorps\t%0, %0";
19413 else
19414 return "pxor\t%0, %0";
19415 case 1:
19416 case 2:
19417 if (get_attr_mode (insn) == MODE_V4SF)
19418 return "movaps\t{%1, %0|%0, %1}";
19419 else
19420 return "movdqa\t{%1, %0|%0, %1}";
19421 default:
19422 abort ();
19423 }
19424 }
19425 [(set_attr "type" "ssemov")
19426 (set (attr "mode")
19427 (cond [(eq_attr "alternative" "0,1")
19428 (if_then_else
19429 (ne (symbol_ref "optimize_size")
19430 (const_int 0))
19431 (const_string "V4SF")
19432 (const_string "TI"))
19433 (eq_attr "alternative" "2")
19434 (if_then_else
19435 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19436 (const_int 0))
19437 (ne (symbol_ref "optimize_size")
19438 (const_int 0)))
19439 (const_string "V4SF")
19440 (const_string "TI"))]
19441 (const_string "TI")))])
19442
19443 (define_expand "movv2df"
19444 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19445 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19446 "TARGET_SSE2"
19447 {
19448 ix86_expand_vector_move (V2DFmode, operands);
19449 DONE;
19450 })
19451
19452 (define_expand "movv8hi"
19453 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19454 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19455 "TARGET_SSE2"
19456 {
19457 ix86_expand_vector_move (V8HImode, operands);
19458 DONE;
19459 })
19460
19461 (define_expand "movv16qi"
19462 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19463 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19464 "TARGET_SSE2"
19465 {
19466 ix86_expand_vector_move (V16QImode, operands);
19467 DONE;
19468 })
19469
19470 (define_expand "movv4sf"
19471 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19472 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19473 "TARGET_SSE"
19474 {
19475 ix86_expand_vector_move (V4SFmode, operands);
19476 DONE;
19477 })
19478
19479 (define_expand "movv4si"
19480 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19481 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19482 "TARGET_SSE"
19483 {
19484 ix86_expand_vector_move (V4SImode, operands);
19485 DONE;
19486 })
19487
19488 (define_expand "movv2di"
19489 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19490 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19491 "TARGET_SSE"
19492 {
19493 ix86_expand_vector_move (V2DImode, operands);
19494 DONE;
19495 })
19496
19497 (define_expand "movv2si"
19498 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19499 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19500 "TARGET_MMX"
19501 {
19502 ix86_expand_vector_move (V2SImode, operands);
19503 DONE;
19504 })
19505
19506 (define_expand "movv4hi"
19507 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19508 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19509 "TARGET_MMX"
19510 {
19511 ix86_expand_vector_move (V4HImode, operands);
19512 DONE;
19513 })
19514
19515 (define_expand "movv8qi"
19516 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19517 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19518 "TARGET_MMX"
19519 {
19520 ix86_expand_vector_move (V8QImode, operands);
19521 DONE;
19522 })
19523
19524 (define_expand "movv2sf"
19525 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19526 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19527 "TARGET_3DNOW"
19528 {
19529 ix86_expand_vector_move (V2SFmode, operands);
19530 DONE;
19531 })
19532
19533 (define_insn "*pushti"
19534 [(set (match_operand:TI 0 "push_operand" "=<")
19535 (match_operand:TI 1 "register_operand" "x"))]
19536 "TARGET_SSE"
19537 "#")
19538
19539 (define_insn "*pushv2df"
19540 [(set (match_operand:V2DF 0 "push_operand" "=<")
19541 (match_operand:V2DF 1 "register_operand" "x"))]
19542 "TARGET_SSE"
19543 "#")
19544
19545 (define_insn "*pushv2di"
19546 [(set (match_operand:V2DI 0 "push_operand" "=<")
19547 (match_operand:V2DI 1 "register_operand" "x"))]
19548 "TARGET_SSE2"
19549 "#")
19550
19551 (define_insn "*pushv8hi"
19552 [(set (match_operand:V8HI 0 "push_operand" "=<")
19553 (match_operand:V8HI 1 "register_operand" "x"))]
19554 "TARGET_SSE2"
19555 "#")
19556
19557 (define_insn "*pushv16qi"
19558 [(set (match_operand:V16QI 0 "push_operand" "=<")
19559 (match_operand:V16QI 1 "register_operand" "x"))]
19560 "TARGET_SSE2"
19561 "#")
19562
19563 (define_insn "*pushv4sf"
19564 [(set (match_operand:V4SF 0 "push_operand" "=<")
19565 (match_operand:V4SF 1 "register_operand" "x"))]
19566 "TARGET_SSE"
19567 "#")
19568
19569 (define_insn "*pushv4si"
19570 [(set (match_operand:V4SI 0 "push_operand" "=<")
19571 (match_operand:V4SI 1 "register_operand" "x"))]
19572 "TARGET_SSE2"
19573 "#")
19574
19575 (define_insn "*pushv2si"
19576 [(set (match_operand:V2SI 0 "push_operand" "=<")
19577 (match_operand:V2SI 1 "register_operand" "y"))]
19578 "TARGET_MMX"
19579 "#")
19580
19581 (define_insn "*pushv4hi"
19582 [(set (match_operand:V4HI 0 "push_operand" "=<")
19583 (match_operand:V4HI 1 "register_operand" "y"))]
19584 "TARGET_MMX"
19585 "#")
19586
19587 (define_insn "*pushv8qi"
19588 [(set (match_operand:V8QI 0 "push_operand" "=<")
19589 (match_operand:V8QI 1 "register_operand" "y"))]
19590 "TARGET_MMX"
19591 "#")
19592
19593 (define_insn "*pushv2sf"
19594 [(set (match_operand:V2SF 0 "push_operand" "=<")
19595 (match_operand:V2SF 1 "register_operand" "y"))]
19596 "TARGET_3DNOW"
19597 "#")
19598
19599 (define_split
19600 [(set (match_operand 0 "push_operand" "")
19601 (match_operand 1 "register_operand" ""))]
19602 "!TARGET_64BIT && reload_completed
19603 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19604 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19605 (set (match_dup 2) (match_dup 1))]
19606 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19607 stack_pointer_rtx);
19608 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19609
19610 (define_split
19611 [(set (match_operand 0 "push_operand" "")
19612 (match_operand 1 "register_operand" ""))]
19613 "TARGET_64BIT && reload_completed
19614 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19615 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19616 (set (match_dup 2) (match_dup 1))]
19617 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19618 stack_pointer_rtx);
19619 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19620
19621
19622 (define_insn "movti_internal"
19623 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19624 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19625 "TARGET_SSE && !TARGET_64BIT
19626 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19627 {
19628 switch (which_alternative)
19629 {
19630 case 0:
19631 if (get_attr_mode (insn) == MODE_V4SF)
19632 return "xorps\t%0, %0";
19633 else
19634 return "pxor\t%0, %0";
19635 case 1:
19636 case 2:
19637 if (get_attr_mode (insn) == MODE_V4SF)
19638 return "movaps\t{%1, %0|%0, %1}";
19639 else
19640 return "movdqa\t{%1, %0|%0, %1}";
19641 default:
19642 abort ();
19643 }
19644 }
19645 [(set_attr "type" "ssemov,ssemov,ssemov")
19646 (set (attr "mode")
19647 (cond [(eq_attr "alternative" "0,1")
19648 (if_then_else
19649 (ne (symbol_ref "optimize_size")
19650 (const_int 0))
19651 (const_string "V4SF")
19652 (const_string "TI"))
19653 (eq_attr "alternative" "2")
19654 (if_then_else
19655 (ne (symbol_ref "optimize_size")
19656 (const_int 0))
19657 (const_string "V4SF")
19658 (const_string "TI"))]
19659 (const_string "TI")))])
19660
19661 (define_insn "*movti_rex64"
19662 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19663 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19664 "TARGET_64BIT
19665 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19666 {
19667 switch (which_alternative)
19668 {
19669 case 0:
19670 case 1:
19671 return "#";
19672 case 2:
19673 if (get_attr_mode (insn) == MODE_V4SF)
19674 return "xorps\t%0, %0";
19675 else
19676 return "pxor\t%0, %0";
19677 case 3:
19678 case 4:
19679 if (get_attr_mode (insn) == MODE_V4SF)
19680 return "movaps\t{%1, %0|%0, %1}";
19681 else
19682 return "movdqa\t{%1, %0|%0, %1}";
19683 default:
19684 abort ();
19685 }
19686 }
19687 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19688 (set (attr "mode")
19689 (cond [(eq_attr "alternative" "2,3")
19690 (if_then_else
19691 (ne (symbol_ref "optimize_size")
19692 (const_int 0))
19693 (const_string "V4SF")
19694 (const_string "TI"))
19695 (eq_attr "alternative" "4")
19696 (if_then_else
19697 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19698 (const_int 0))
19699 (ne (symbol_ref "optimize_size")
19700 (const_int 0)))
19701 (const_string "V4SF")
19702 (const_string "TI"))]
19703 (const_string "DI")))])
19704
19705 (define_split
19706 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19707 (match_operand:TI 1 "general_operand" ""))]
19708 "reload_completed && !SSE_REG_P (operands[0])
19709 && !SSE_REG_P (operands[1])"
19710 [(const_int 0)]
19711 "ix86_split_long_move (operands); DONE;")
19712
19713 ;; These two patterns are useful for specifying exactly whether to use
19714 ;; movaps or movups
19715 (define_expand "sse_movaps"
19716 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19717 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19718 UNSPEC_MOVA))]
19719 "TARGET_SSE"
19720 {
19721 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19722 {
19723 rtx tmp = gen_reg_rtx (V4SFmode);
19724 emit_insn (gen_sse_movaps (tmp, operands[1]));
19725 emit_move_insn (operands[0], tmp);
19726 DONE;
19727 }
19728 })
19729
19730 (define_insn "*sse_movaps_1"
19731 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19732 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19733 UNSPEC_MOVA))]
19734 "TARGET_SSE
19735 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19736 "movaps\t{%1, %0|%0, %1}"
19737 [(set_attr "type" "ssemov,ssemov")
19738 (set_attr "mode" "V4SF")])
19739
19740 (define_expand "sse_movups"
19741 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19742 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19743 UNSPEC_MOVU))]
19744 "TARGET_SSE"
19745 {
19746 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19747 {
19748 rtx tmp = gen_reg_rtx (V4SFmode);
19749 emit_insn (gen_sse_movups (tmp, operands[1]));
19750 emit_move_insn (operands[0], tmp);
19751 DONE;
19752 }
19753 })
19754
19755 (define_insn "*sse_movups_1"
19756 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19757 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19758 UNSPEC_MOVU))]
19759 "TARGET_SSE
19760 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19761 "movups\t{%1, %0|%0, %1}"
19762 [(set_attr "type" "ssecvt,ssecvt")
19763 (set_attr "mode" "V4SF")])
19764
19765 ;; SSE Strange Moves.
19766
19767 (define_insn "sse_movmskps"
19768 [(set (match_operand:SI 0 "register_operand" "=r")
19769 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19770 UNSPEC_MOVMSK))]
19771 "TARGET_SSE"
19772 "movmskps\t{%1, %0|%0, %1}"
19773 [(set_attr "type" "ssecvt")
19774 (set_attr "mode" "V4SF")])
19775
19776 (define_insn "mmx_pmovmskb"
19777 [(set (match_operand:SI 0 "register_operand" "=r")
19778 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19779 UNSPEC_MOVMSK))]
19780 "TARGET_SSE || TARGET_3DNOW_A"
19781 "pmovmskb\t{%1, %0|%0, %1}"
19782 [(set_attr "type" "ssecvt")
19783 (set_attr "mode" "V4SF")])
19784
19785
19786 (define_insn "mmx_maskmovq"
19787 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19788 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19789 (match_operand:V8QI 2 "register_operand" "y")]
19790 UNSPEC_MASKMOV))]
19791 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19792 ;; @@@ check ordering of operands in intel/nonintel syntax
19793 "maskmovq\t{%2, %1|%1, %2}"
19794 [(set_attr "type" "mmxcvt")
19795 (set_attr "mode" "DI")])
19796
19797 (define_insn "mmx_maskmovq_rex"
19798 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19799 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19800 (match_operand:V8QI 2 "register_operand" "y")]
19801 UNSPEC_MASKMOV))]
19802 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19803 ;; @@@ check ordering of operands in intel/nonintel syntax
19804 "maskmovq\t{%2, %1|%1, %2}"
19805 [(set_attr "type" "mmxcvt")
19806 (set_attr "mode" "DI")])
19807
19808 (define_insn "sse_movntv4sf"
19809 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19810 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19811 UNSPEC_MOVNT))]
19812 "TARGET_SSE"
19813 "movntps\t{%1, %0|%0, %1}"
19814 [(set_attr "type" "ssemov")
19815 (set_attr "mode" "V4SF")])
19816
19817 (define_insn "sse_movntdi"
19818 [(set (match_operand:DI 0 "memory_operand" "=m")
19819 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19820 UNSPEC_MOVNT))]
19821 "TARGET_SSE || TARGET_3DNOW_A"
19822 "movntq\t{%1, %0|%0, %1}"
19823 [(set_attr "type" "mmxmov")
19824 (set_attr "mode" "DI")])
19825
19826 (define_insn "sse_movhlps"
19827 [(set (match_operand:V4SF 0 "register_operand" "=x")
19828 (vec_merge:V4SF
19829 (match_operand:V4SF 1 "register_operand" "0")
19830 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19831 (parallel [(const_int 2)
19832 (const_int 3)
19833 (const_int 0)
19834 (const_int 1)]))
19835 (const_int 3)))]
19836 "TARGET_SSE"
19837 "movhlps\t{%2, %0|%0, %2}"
19838 [(set_attr "type" "ssecvt")
19839 (set_attr "mode" "V4SF")])
19840
19841 (define_insn "sse_movlhps"
19842 [(set (match_operand:V4SF 0 "register_operand" "=x")
19843 (vec_merge:V4SF
19844 (match_operand:V4SF 1 "register_operand" "0")
19845 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19846 (parallel [(const_int 2)
19847 (const_int 3)
19848 (const_int 0)
19849 (const_int 1)]))
19850 (const_int 12)))]
19851 "TARGET_SSE"
19852 "movlhps\t{%2, %0|%0, %2}"
19853 [(set_attr "type" "ssecvt")
19854 (set_attr "mode" "V4SF")])
19855
19856 (define_insn "sse_movhps"
19857 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19858 (vec_merge:V4SF
19859 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19860 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19861 (const_int 12)))]
19862 "TARGET_SSE
19863 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19864 "movhps\t{%2, %0|%0, %2}"
19865 [(set_attr "type" "ssecvt")
19866 (set_attr "mode" "V4SF")])
19867
19868 (define_insn "sse_movlps"
19869 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19870 (vec_merge:V4SF
19871 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19872 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19873 (const_int 3)))]
19874 "TARGET_SSE
19875 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19876 "movlps\t{%2, %0|%0, %2}"
19877 [(set_attr "type" "ssecvt")
19878 (set_attr "mode" "V4SF")])
19879
19880 (define_expand "sse_loadss"
19881 [(match_operand:V4SF 0 "register_operand" "")
19882 (match_operand:SF 1 "memory_operand" "")]
19883 "TARGET_SSE"
19884 {
19885 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19886 CONST0_RTX (V4SFmode)));
19887 DONE;
19888 })
19889
19890 (define_insn "sse_loadss_1"
19891 [(set (match_operand:V4SF 0 "register_operand" "=x")
19892 (vec_merge:V4SF
19893 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19894 (match_operand:V4SF 2 "const0_operand" "X")
19895 (const_int 1)))]
19896 "TARGET_SSE"
19897 "movss\t{%1, %0|%0, %1}"
19898 [(set_attr "type" "ssemov")
19899 (set_attr "mode" "SF")])
19900
19901 (define_insn "sse_movss"
19902 [(set (match_operand:V4SF 0 "register_operand" "=x")
19903 (vec_merge:V4SF
19904 (match_operand:V4SF 1 "register_operand" "0")
19905 (match_operand:V4SF 2 "register_operand" "x")
19906 (const_int 1)))]
19907 "TARGET_SSE"
19908 "movss\t{%2, %0|%0, %2}"
19909 [(set_attr "type" "ssemov")
19910 (set_attr "mode" "SF")])
19911
19912 (define_insn "sse_storess"
19913 [(set (match_operand:SF 0 "memory_operand" "=m")
19914 (vec_select:SF
19915 (match_operand:V4SF 1 "register_operand" "x")
19916 (parallel [(const_int 0)])))]
19917 "TARGET_SSE"
19918 "movss\t{%1, %0|%0, %1}"
19919 [(set_attr "type" "ssemov")
19920 (set_attr "mode" "SF")])
19921
19922 (define_insn "sse_shufps"
19923 [(set (match_operand:V4SF 0 "register_operand" "=x")
19924 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19925 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19926 (match_operand:SI 3 "immediate_operand" "i")]
19927 UNSPEC_SHUFFLE))]
19928 "TARGET_SSE"
19929 ;; @@@ check operand order for intel/nonintel syntax
19930 "shufps\t{%3, %2, %0|%0, %2, %3}"
19931 [(set_attr "type" "ssecvt")
19932 (set_attr "mode" "V4SF")])
19933
19934
19935 ;; SSE arithmetic
19936
19937 (define_insn "addv4sf3"
19938 [(set (match_operand:V4SF 0 "register_operand" "=x")
19939 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19940 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19941 "TARGET_SSE"
19942 "addps\t{%2, %0|%0, %2}"
19943 [(set_attr "type" "sseadd")
19944 (set_attr "mode" "V4SF")])
19945
19946 (define_insn "vmaddv4sf3"
19947 [(set (match_operand:V4SF 0 "register_operand" "=x")
19948 (vec_merge:V4SF
19949 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19950 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19951 (match_dup 1)
19952 (const_int 1)))]
19953 "TARGET_SSE"
19954 "addss\t{%2, %0|%0, %2}"
19955 [(set_attr "type" "sseadd")
19956 (set_attr "mode" "SF")])
19957
19958 (define_insn "subv4sf3"
19959 [(set (match_operand:V4SF 0 "register_operand" "=x")
19960 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19961 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19962 "TARGET_SSE"
19963 "subps\t{%2, %0|%0, %2}"
19964 [(set_attr "type" "sseadd")
19965 (set_attr "mode" "V4SF")])
19966
19967 (define_insn "vmsubv4sf3"
19968 [(set (match_operand:V4SF 0 "register_operand" "=x")
19969 (vec_merge:V4SF
19970 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19971 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19972 (match_dup 1)
19973 (const_int 1)))]
19974 "TARGET_SSE"
19975 "subss\t{%2, %0|%0, %2}"
19976 [(set_attr "type" "sseadd")
19977 (set_attr "mode" "SF")])
19978
19979 (define_insn "mulv4sf3"
19980 [(set (match_operand:V4SF 0 "register_operand" "=x")
19981 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19982 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19983 "TARGET_SSE"
19984 "mulps\t{%2, %0|%0, %2}"
19985 [(set_attr "type" "ssemul")
19986 (set_attr "mode" "V4SF")])
19987
19988 (define_insn "vmmulv4sf3"
19989 [(set (match_operand:V4SF 0 "register_operand" "=x")
19990 (vec_merge:V4SF
19991 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19992 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19993 (match_dup 1)
19994 (const_int 1)))]
19995 "TARGET_SSE"
19996 "mulss\t{%2, %0|%0, %2}"
19997 [(set_attr "type" "ssemul")
19998 (set_attr "mode" "SF")])
19999
20000 (define_insn "divv4sf3"
20001 [(set (match_operand:V4SF 0 "register_operand" "=x")
20002 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20003 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20004 "TARGET_SSE"
20005 "divps\t{%2, %0|%0, %2}"
20006 [(set_attr "type" "ssediv")
20007 (set_attr "mode" "V4SF")])
20008
20009 (define_insn "vmdivv4sf3"
20010 [(set (match_operand:V4SF 0 "register_operand" "=x")
20011 (vec_merge:V4SF
20012 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20013 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20014 (match_dup 1)
20015 (const_int 1)))]
20016 "TARGET_SSE"
20017 "divss\t{%2, %0|%0, %2}"
20018 [(set_attr "type" "ssediv")
20019 (set_attr "mode" "SF")])
20020
20021
20022 ;; SSE square root/reciprocal
20023
20024 (define_insn "rcpv4sf2"
20025 [(set (match_operand:V4SF 0 "register_operand" "=x")
20026 (unspec:V4SF
20027 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20028 "TARGET_SSE"
20029 "rcpps\t{%1, %0|%0, %1}"
20030 [(set_attr "type" "sse")
20031 (set_attr "mode" "V4SF")])
20032
20033 (define_insn "vmrcpv4sf2"
20034 [(set (match_operand:V4SF 0 "register_operand" "=x")
20035 (vec_merge:V4SF
20036 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20037 UNSPEC_RCP)
20038 (match_operand:V4SF 2 "register_operand" "0")
20039 (const_int 1)))]
20040 "TARGET_SSE"
20041 "rcpss\t{%1, %0|%0, %1}"
20042 [(set_attr "type" "sse")
20043 (set_attr "mode" "SF")])
20044
20045 (define_insn "rsqrtv4sf2"
20046 [(set (match_operand:V4SF 0 "register_operand" "=x")
20047 (unspec:V4SF
20048 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20049 "TARGET_SSE"
20050 "rsqrtps\t{%1, %0|%0, %1}"
20051 [(set_attr "type" "sse")
20052 (set_attr "mode" "V4SF")])
20053
20054 (define_insn "vmrsqrtv4sf2"
20055 [(set (match_operand:V4SF 0 "register_operand" "=x")
20056 (vec_merge:V4SF
20057 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20058 UNSPEC_RSQRT)
20059 (match_operand:V4SF 2 "register_operand" "0")
20060 (const_int 1)))]
20061 "TARGET_SSE"
20062 "rsqrtss\t{%1, %0|%0, %1}"
20063 [(set_attr "type" "sse")
20064 (set_attr "mode" "SF")])
20065
20066 (define_insn "sqrtv4sf2"
20067 [(set (match_operand:V4SF 0 "register_operand" "=x")
20068 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20069 "TARGET_SSE"
20070 "sqrtps\t{%1, %0|%0, %1}"
20071 [(set_attr "type" "sse")
20072 (set_attr "mode" "V4SF")])
20073
20074 (define_insn "vmsqrtv4sf2"
20075 [(set (match_operand:V4SF 0 "register_operand" "=x")
20076 (vec_merge:V4SF
20077 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20078 (match_operand:V4SF 2 "register_operand" "0")
20079 (const_int 1)))]
20080 "TARGET_SSE"
20081 "sqrtss\t{%1, %0|%0, %1}"
20082 [(set_attr "type" "sse")
20083 (set_attr "mode" "SF")])
20084
20085 ;; SSE logical operations.
20086
20087 ;; SSE defines logical operations on floating point values. This brings
20088 ;; interesting challenge to RTL representation where logicals are only valid
20089 ;; on integral types. We deal with this by representing the floating point
20090 ;; logical as logical on arguments casted to TImode as this is what hardware
20091 ;; really does. Unfortunately hardware requires the type information to be
20092 ;; present and thus we must avoid subregs from being simplified and eliminated
20093 ;; in later compilation phases.
20094 ;;
20095 ;; We have following variants from each instruction:
20096 ;; sse_andsf3 - the operation taking V4SF vector operands
20097 ;; and doing TImode cast on them
20098 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20099 ;; TImode, since backend insist on eliminating casts
20100 ;; on memory operands
20101 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20102 ;; We can not accept memory operand here as instruction reads
20103 ;; whole scalar. This is generated only post reload by GCC
20104 ;; scalar float operations that expands to logicals (fabs)
20105 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20106 ;; memory operand. Eventually combine can be able
20107 ;; to synthesize these using splitter.
20108 ;; sse2_anddf3, *sse2_anddf3_memory
20109 ;;
20110 ;;
20111 ;; These are not called andti3 etc. because we really really don't want
20112 ;; the compiler to widen DImode ands to TImode ands and then try to move
20113 ;; into DImode subregs of SSE registers, and them together, and move out
20114 ;; of DImode subregs again!
20115 ;; SSE1 single precision floating point logical operation
20116 (define_expand "sse_andv4sf3"
20117 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20118 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20119 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20120 "TARGET_SSE"
20121 "")
20122
20123 (define_insn "*sse_andv4sf3"
20124 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20125 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20126 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20127 "TARGET_SSE
20128 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20129 "andps\t{%2, %0|%0, %2}"
20130 [(set_attr "type" "sselog")
20131 (set_attr "mode" "V4SF")])
20132
20133 (define_insn "*sse_andsf3"
20134 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20135 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20136 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20137 "TARGET_SSE
20138 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20139 "andps\t{%2, %0|%0, %2}"
20140 [(set_attr "type" "sselog")
20141 (set_attr "mode" "V4SF")])
20142
20143 (define_expand "sse_nandv4sf3"
20144 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20145 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
20146 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20147 "TARGET_SSE"
20148 "")
20149
20150 (define_insn "*sse_nandv4sf3"
20151 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20152 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20153 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20154 "TARGET_SSE"
20155 "andnps\t{%2, %0|%0, %2}"
20156 [(set_attr "type" "sselog")
20157 (set_attr "mode" "V4SF")])
20158
20159 (define_insn "*sse_nandsf3"
20160 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20161 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20162 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20163 "TARGET_SSE"
20164 "andnps\t{%2, %0|%0, %2}"
20165 [(set_attr "type" "sselog")
20166 (set_attr "mode" "V4SF")])
20167
20168 (define_expand "sse_iorv4sf3"
20169 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20170 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20171 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20172 "TARGET_SSE"
20173 "")
20174
20175 (define_insn "*sse_iorv4sf3"
20176 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20177 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20178 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20179 "TARGET_SSE
20180 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20181 "orps\t{%2, %0|%0, %2}"
20182 [(set_attr "type" "sselog")
20183 (set_attr "mode" "V4SF")])
20184
20185 (define_insn "*sse_iorsf3"
20186 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20187 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20188 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20189 "TARGET_SSE
20190 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20191 "orps\t{%2, %0|%0, %2}"
20192 [(set_attr "type" "sselog")
20193 (set_attr "mode" "V4SF")])
20194
20195 (define_expand "sse_xorv4sf3"
20196 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20197 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20198 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20199 "TARGET_SSE
20200 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20201 "")
20202
20203 (define_insn "*sse_xorv4sf3"
20204 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20205 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20206 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20207 "TARGET_SSE
20208 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20209 "xorps\t{%2, %0|%0, %2}"
20210 [(set_attr "type" "sselog")
20211 (set_attr "mode" "V4SF")])
20212
20213 (define_insn "*sse_xorsf3"
20214 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20215 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20216 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20217 "TARGET_SSE
20218 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20219 "xorps\t{%2, %0|%0, %2}"
20220 [(set_attr "type" "sselog")
20221 (set_attr "mode" "V4SF")])
20222
20223 ;; SSE2 double precision floating point logical operation
20224
20225 (define_expand "sse2_andv2df3"
20226 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20227 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20228 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20229 "TARGET_SSE2"
20230 "")
20231
20232 (define_insn "*sse2_andv2df3"
20233 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20234 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20235 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20236 "TARGET_SSE2
20237 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20238 "andpd\t{%2, %0|%0, %2}"
20239 [(set_attr "type" "sselog")
20240 (set_attr "mode" "V2DF")])
20241
20242 (define_insn "*sse2_andv2df3"
20243 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20244 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20245 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20246 "TARGET_SSE2
20247 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20248 "andpd\t{%2, %0|%0, %2}"
20249 [(set_attr "type" "sselog")
20250 (set_attr "mode" "V2DF")])
20251
20252 (define_expand "sse2_nandv2df3"
20253 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20254 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
20255 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20256 "TARGET_SSE2"
20257 "")
20258
20259 (define_insn "*sse2_nandv2df3"
20260 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20261 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20262 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20263 "TARGET_SSE2"
20264 "andnpd\t{%2, %0|%0, %2}"
20265 [(set_attr "type" "sselog")
20266 (set_attr "mode" "V2DF")])
20267
20268 (define_insn "*sse_nandti3_df"
20269 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
20270 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20271 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
20272 "TARGET_SSE2"
20273 "andnpd\t{%2, %0|%0, %2}"
20274 [(set_attr "type" "sselog")
20275 (set_attr "mode" "V2DF")])
20276
20277 (define_expand "sse2_iorv2df3"
20278 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20279 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20280 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20281 "TARGET_SSE2"
20282 "")
20283
20284 (define_insn "*sse2_iorv2df3"
20285 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20286 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20287 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20288 "TARGET_SSE2
20289 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20290 "orpd\t{%2, %0|%0, %2}"
20291 [(set_attr "type" "sselog")
20292 (set_attr "mode" "V2DF")])
20293
20294 (define_insn "*sse2_iordf3"
20295 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20296 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20297 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20298 "TARGET_SSE2
20299 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20300 "orpd\t{%2, %0|%0, %2}"
20301 [(set_attr "type" "sselog")
20302 (set_attr "mode" "V2DF")])
20303
20304 (define_expand "sse2_xorv2df3"
20305 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20306 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
20307 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20308 "TARGET_SSE2"
20309 "")
20310
20311 (define_insn "*sse2_xorv2df3"
20312 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20313 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20314 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20315 "TARGET_SSE2
20316 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20317 "xorpd\t{%2, %0|%0, %2}"
20318 [(set_attr "type" "sselog")
20319 (set_attr "mode" "V2DF")])
20320
20321 (define_insn "*sse2_xordf3"
20322 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20323 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20324 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20325 "TARGET_SSE2
20326 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20327 "xorpd\t{%2, %0|%0, %2}"
20328 [(set_attr "type" "sselog")
20329 (set_attr "mode" "V2DF")])
20330
20331 ;; SSE2 integral logicals. These patterns must always come after floating
20332 ;; point ones since we don't want compiler to use integer opcodes on floating
20333 ;; point SSE values to avoid matching of subregs in the match_operand.
20334 (define_insn "*sse2_andti3"
20335 [(set (match_operand:TI 0 "register_operand" "=x")
20336 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20337 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20338 "TARGET_SSE2
20339 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20340 "pand\t{%2, %0|%0, %2}"
20341 [(set_attr "type" "sselog")
20342 (set_attr "mode" "TI")])
20343
20344 (define_insn "sse2_andv2di3"
20345 [(set (match_operand:V2DI 0 "register_operand" "=x")
20346 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20347 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20348 "TARGET_SSE2
20349 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20350 "pand\t{%2, %0|%0, %2}"
20351 [(set_attr "type" "sselog")
20352 (set_attr "mode" "TI")])
20353
20354 (define_insn "*sse2_nandti3"
20355 [(set (match_operand:TI 0 "register_operand" "=x")
20356 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20357 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20358 "TARGET_SSE2"
20359 "pandn\t{%2, %0|%0, %2}"
20360 [(set_attr "type" "sselog")
20361 (set_attr "mode" "TI")])
20362
20363 (define_insn "sse2_nandv2di3"
20364 [(set (match_operand:V2DI 0 "register_operand" "=x")
20365 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20366 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20367 "TARGET_SSE2
20368 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20369 "pandn\t{%2, %0|%0, %2}"
20370 [(set_attr "type" "sselog")
20371 (set_attr "mode" "TI")])
20372
20373 (define_insn "*sse2_iorti3"
20374 [(set (match_operand:TI 0 "register_operand" "=x")
20375 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20376 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20377 "TARGET_SSE2
20378 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20379 "por\t{%2, %0|%0, %2}"
20380 [(set_attr "type" "sselog")
20381 (set_attr "mode" "TI")])
20382
20383 (define_insn "sse2_iorv2di3"
20384 [(set (match_operand:V2DI 0 "register_operand" "=x")
20385 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20386 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20387 "TARGET_SSE2
20388 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20389 "por\t{%2, %0|%0, %2}"
20390 [(set_attr "type" "sselog")
20391 (set_attr "mode" "TI")])
20392
20393 (define_insn "*sse2_xorti3"
20394 [(set (match_operand:TI 0 "register_operand" "=x")
20395 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20396 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20397 "TARGET_SSE2
20398 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20399 "pxor\t{%2, %0|%0, %2}"
20400 [(set_attr "type" "sselog")
20401 (set_attr "mode" "TI")])
20402
20403 (define_insn "sse2_xorv2di3"
20404 [(set (match_operand:V2DI 0 "register_operand" "=x")
20405 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20406 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20407 "TARGET_SSE2
20408 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20409 "pxor\t{%2, %0|%0, %2}"
20410 [(set_attr "type" "sselog")
20411 (set_attr "mode" "TI")])
20412
20413 ;; Use xor, but don't show input operands so they aren't live before
20414 ;; this insn.
20415 (define_insn "sse_clrv4sf"
20416 [(set (match_operand:V4SF 0 "register_operand" "=x")
20417 (match_operand:V4SF 1 "const0_operand" "X"))]
20418 "TARGET_SSE"
20419 {
20420 if (get_attr_mode (insn) == MODE_TI)
20421 return "pxor\t{%0, %0|%0, %0}";
20422 else
20423 return "xorps\t{%0, %0|%0, %0}";
20424 }
20425 [(set_attr "type" "sselog")
20426 (set_attr "memory" "none")
20427 (set (attr "mode")
20428 (if_then_else
20429 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20430 (const_int 0))
20431 (ne (symbol_ref "TARGET_SSE2")
20432 (const_int 0)))
20433 (eq (symbol_ref "optimize_size")
20434 (const_int 0)))
20435 (const_string "TI")
20436 (const_string "V4SF")))])
20437
20438 ;; Use xor, but don't show input operands so they aren't live before
20439 ;; this insn.
20440 (define_insn "sse_clrv2df"
20441 [(set (match_operand:V2DF 0 "register_operand" "=x")
20442 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20443 "TARGET_SSE2"
20444 "xorpd\t{%0, %0|%0, %0}"
20445 [(set_attr "type" "sselog")
20446 (set_attr "memory" "none")
20447 (set_attr "mode" "V4SF")])
20448
20449 ;; SSE mask-generating compares
20450
20451 (define_insn "maskcmpv4sf3"
20452 [(set (match_operand:V4SI 0 "register_operand" "=x")
20453 (match_operator:V4SI 3 "sse_comparison_operator"
20454 [(match_operand:V4SF 1 "register_operand" "0")
20455 (match_operand:V4SF 2 "register_operand" "x")]))]
20456 "TARGET_SSE"
20457 "cmp%D3ps\t{%2, %0|%0, %2}"
20458 [(set_attr "type" "ssecmp")
20459 (set_attr "mode" "V4SF")])
20460
20461 (define_insn "maskncmpv4sf3"
20462 [(set (match_operand:V4SI 0 "register_operand" "=x")
20463 (not:V4SI
20464 (match_operator:V4SI 3 "sse_comparison_operator"
20465 [(match_operand:V4SF 1 "register_operand" "0")
20466 (match_operand:V4SF 2 "register_operand" "x")])))]
20467 "TARGET_SSE"
20468 {
20469 if (GET_CODE (operands[3]) == UNORDERED)
20470 return "cmpordps\t{%2, %0|%0, %2}";
20471 else
20472 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20473 }
20474 [(set_attr "type" "ssecmp")
20475 (set_attr "mode" "V4SF")])
20476
20477 (define_insn "vmmaskcmpv4sf3"
20478 [(set (match_operand:V4SI 0 "register_operand" "=x")
20479 (vec_merge:V4SI
20480 (match_operator:V4SI 3 "sse_comparison_operator"
20481 [(match_operand:V4SF 1 "register_operand" "0")
20482 (match_operand:V4SF 2 "register_operand" "x")])
20483 (subreg:V4SI (match_dup 1) 0)
20484 (const_int 1)))]
20485 "TARGET_SSE"
20486 "cmp%D3ss\t{%2, %0|%0, %2}"
20487 [(set_attr "type" "ssecmp")
20488 (set_attr "mode" "SF")])
20489
20490 (define_insn "vmmaskncmpv4sf3"
20491 [(set (match_operand:V4SI 0 "register_operand" "=x")
20492 (vec_merge:V4SI
20493 (not:V4SI
20494 (match_operator:V4SI 3 "sse_comparison_operator"
20495 [(match_operand:V4SF 1 "register_operand" "0")
20496 (match_operand:V4SF 2 "register_operand" "x")]))
20497 (subreg:V4SI (match_dup 1) 0)
20498 (const_int 1)))]
20499 "TARGET_SSE"
20500 {
20501 if (GET_CODE (operands[3]) == UNORDERED)
20502 return "cmpordss\t{%2, %0|%0, %2}";
20503 else
20504 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20505 }
20506 [(set_attr "type" "ssecmp")
20507 (set_attr "mode" "SF")])
20508
20509 (define_insn "sse_comi"
20510 [(set (reg:CCFP 17)
20511 (compare:CCFP (vec_select:SF
20512 (match_operand:V4SF 0 "register_operand" "x")
20513 (parallel [(const_int 0)]))
20514 (vec_select:SF
20515 (match_operand:V4SF 1 "register_operand" "x")
20516 (parallel [(const_int 0)]))))]
20517 "TARGET_SSE"
20518 "comiss\t{%1, %0|%0, %1}"
20519 [(set_attr "type" "ssecomi")
20520 (set_attr "mode" "SF")])
20521
20522 (define_insn "sse_ucomi"
20523 [(set (reg:CCFPU 17)
20524 (compare:CCFPU (vec_select:SF
20525 (match_operand:V4SF 0 "register_operand" "x")
20526 (parallel [(const_int 0)]))
20527 (vec_select:SF
20528 (match_operand:V4SF 1 "register_operand" "x")
20529 (parallel [(const_int 0)]))))]
20530 "TARGET_SSE"
20531 "ucomiss\t{%1, %0|%0, %1}"
20532 [(set_attr "type" "ssecomi")
20533 (set_attr "mode" "SF")])
20534
20535
20536 ;; SSE unpack
20537
20538 (define_insn "sse_unpckhps"
20539 [(set (match_operand:V4SF 0 "register_operand" "=x")
20540 (vec_merge:V4SF
20541 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20542 (parallel [(const_int 2)
20543 (const_int 0)
20544 (const_int 3)
20545 (const_int 1)]))
20546 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20547 (parallel [(const_int 0)
20548 (const_int 2)
20549 (const_int 1)
20550 (const_int 3)]))
20551 (const_int 5)))]
20552 "TARGET_SSE"
20553 "unpckhps\t{%2, %0|%0, %2}"
20554 [(set_attr "type" "ssecvt")
20555 (set_attr "mode" "V4SF")])
20556
20557 (define_insn "sse_unpcklps"
20558 [(set (match_operand:V4SF 0 "register_operand" "=x")
20559 (vec_merge:V4SF
20560 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20561 (parallel [(const_int 0)
20562 (const_int 2)
20563 (const_int 1)
20564 (const_int 3)]))
20565 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20566 (parallel [(const_int 2)
20567 (const_int 0)
20568 (const_int 3)
20569 (const_int 1)]))
20570 (const_int 5)))]
20571 "TARGET_SSE"
20572 "unpcklps\t{%2, %0|%0, %2}"
20573 [(set_attr "type" "ssecvt")
20574 (set_attr "mode" "V4SF")])
20575
20576
20577 ;; SSE min/max
20578
20579 (define_insn "smaxv4sf3"
20580 [(set (match_operand:V4SF 0 "register_operand" "=x")
20581 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20582 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20583 "TARGET_SSE"
20584 "maxps\t{%2, %0|%0, %2}"
20585 [(set_attr "type" "sse")
20586 (set_attr "mode" "V4SF")])
20587
20588 (define_insn "vmsmaxv4sf3"
20589 [(set (match_operand:V4SF 0 "register_operand" "=x")
20590 (vec_merge:V4SF
20591 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20592 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20593 (match_dup 1)
20594 (const_int 1)))]
20595 "TARGET_SSE"
20596 "maxss\t{%2, %0|%0, %2}"
20597 [(set_attr "type" "sse")
20598 (set_attr "mode" "SF")])
20599
20600 (define_insn "sminv4sf3"
20601 [(set (match_operand:V4SF 0 "register_operand" "=x")
20602 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20603 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20604 "TARGET_SSE"
20605 "minps\t{%2, %0|%0, %2}"
20606 [(set_attr "type" "sse")
20607 (set_attr "mode" "V4SF")])
20608
20609 (define_insn "vmsminv4sf3"
20610 [(set (match_operand:V4SF 0 "register_operand" "=x")
20611 (vec_merge:V4SF
20612 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20613 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20614 (match_dup 1)
20615 (const_int 1)))]
20616 "TARGET_SSE"
20617 "minss\t{%2, %0|%0, %2}"
20618 [(set_attr "type" "sse")
20619 (set_attr "mode" "SF")])
20620
20621 ;; SSE <-> integer/MMX conversions
20622
20623 (define_insn "cvtpi2ps"
20624 [(set (match_operand:V4SF 0 "register_operand" "=x")
20625 (vec_merge:V4SF
20626 (match_operand:V4SF 1 "register_operand" "0")
20627 (vec_duplicate:V4SF
20628 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20629 (const_int 12)))]
20630 "TARGET_SSE"
20631 "cvtpi2ps\t{%2, %0|%0, %2}"
20632 [(set_attr "type" "ssecvt")
20633 (set_attr "mode" "V4SF")])
20634
20635 (define_insn "cvtps2pi"
20636 [(set (match_operand:V2SI 0 "register_operand" "=y")
20637 (vec_select:V2SI
20638 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20639 (parallel [(const_int 0) (const_int 1)])))]
20640 "TARGET_SSE"
20641 "cvtps2pi\t{%1, %0|%0, %1}"
20642 [(set_attr "type" "ssecvt")
20643 (set_attr "mode" "V4SF")])
20644
20645 (define_insn "cvttps2pi"
20646 [(set (match_operand:V2SI 0 "register_operand" "=y")
20647 (vec_select:V2SI
20648 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20649 UNSPEC_FIX)
20650 (parallel [(const_int 0) (const_int 1)])))]
20651 "TARGET_SSE"
20652 "cvttps2pi\t{%1, %0|%0, %1}"
20653 [(set_attr "type" "ssecvt")
20654 (set_attr "mode" "SF")])
20655
20656 (define_insn "cvtsi2ss"
20657 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20658 (vec_merge:V4SF
20659 (match_operand:V4SF 1 "register_operand" "0,0")
20660 (vec_duplicate:V4SF
20661 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20662 (const_int 14)))]
20663 "TARGET_SSE"
20664 "cvtsi2ss\t{%2, %0|%0, %2}"
20665 [(set_attr "type" "sseicvt")
20666 (set_attr "athlon_decode" "vector,double")
20667 (set_attr "mode" "SF")])
20668
20669 (define_insn "cvtsi2ssq"
20670 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20671 (vec_merge:V4SF
20672 (match_operand:V4SF 1 "register_operand" "0,0")
20673 (vec_duplicate:V4SF
20674 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20675 (const_int 14)))]
20676 "TARGET_SSE && TARGET_64BIT"
20677 "cvtsi2ssq\t{%2, %0|%0, %2}"
20678 [(set_attr "type" "sseicvt")
20679 (set_attr "athlon_decode" "vector,double")
20680 (set_attr "mode" "SF")])
20681
20682 (define_insn "cvtss2si"
20683 [(set (match_operand:SI 0 "register_operand" "=r,r")
20684 (vec_select:SI
20685 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20686 (parallel [(const_int 0)])))]
20687 "TARGET_SSE"
20688 "cvtss2si\t{%1, %0|%0, %1}"
20689 [(set_attr "type" "sseicvt")
20690 (set_attr "athlon_decode" "double,vector")
20691 (set_attr "mode" "SI")])
20692
20693 (define_insn "cvtss2siq"
20694 [(set (match_operand:DI 0 "register_operand" "=r,r")
20695 (vec_select:DI
20696 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20697 (parallel [(const_int 0)])))]
20698 "TARGET_SSE"
20699 "cvtss2siq\t{%1, %0|%0, %1}"
20700 [(set_attr "type" "sseicvt")
20701 (set_attr "athlon_decode" "double,vector")
20702 (set_attr "mode" "DI")])
20703
20704 (define_insn "cvttss2si"
20705 [(set (match_operand:SI 0 "register_operand" "=r,r")
20706 (vec_select:SI
20707 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20708 UNSPEC_FIX)
20709 (parallel [(const_int 0)])))]
20710 "TARGET_SSE"
20711 "cvttss2si\t{%1, %0|%0, %1}"
20712 [(set_attr "type" "sseicvt")
20713 (set_attr "mode" "SF")
20714 (set_attr "athlon_decode" "double,vector")])
20715
20716 (define_insn "cvttss2siq"
20717 [(set (match_operand:DI 0 "register_operand" "=r,r")
20718 (vec_select:DI
20719 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20720 UNSPEC_FIX)
20721 (parallel [(const_int 0)])))]
20722 "TARGET_SSE && TARGET_64BIT"
20723 "cvttss2siq\t{%1, %0|%0, %1}"
20724 [(set_attr "type" "sseicvt")
20725 (set_attr "mode" "SF")
20726 (set_attr "athlon_decode" "double,vector")])
20727
20728
20729 ;; MMX insns
20730
20731 ;; MMX arithmetic
20732
20733 (define_insn "addv8qi3"
20734 [(set (match_operand:V8QI 0 "register_operand" "=y")
20735 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20736 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20737 "TARGET_MMX"
20738 "paddb\t{%2, %0|%0, %2}"
20739 [(set_attr "type" "mmxadd")
20740 (set_attr "mode" "DI")])
20741
20742 (define_insn "addv4hi3"
20743 [(set (match_operand:V4HI 0 "register_operand" "=y")
20744 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20745 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20746 "TARGET_MMX"
20747 "paddw\t{%2, %0|%0, %2}"
20748 [(set_attr "type" "mmxadd")
20749 (set_attr "mode" "DI")])
20750
20751 (define_insn "addv2si3"
20752 [(set (match_operand:V2SI 0 "register_operand" "=y")
20753 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20754 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20755 "TARGET_MMX"
20756 "paddd\t{%2, %0|%0, %2}"
20757 [(set_attr "type" "mmxadd")
20758 (set_attr "mode" "DI")])
20759
20760 (define_insn "mmx_adddi3"
20761 [(set (match_operand:DI 0 "register_operand" "=y")
20762 (unspec:DI
20763 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20764 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20765 UNSPEC_NOP))]
20766 "TARGET_MMX"
20767 "paddq\t{%2, %0|%0, %2}"
20768 [(set_attr "type" "mmxadd")
20769 (set_attr "mode" "DI")])
20770
20771 (define_insn "ssaddv8qi3"
20772 [(set (match_operand:V8QI 0 "register_operand" "=y")
20773 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20774 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20775 "TARGET_MMX"
20776 "paddsb\t{%2, %0|%0, %2}"
20777 [(set_attr "type" "mmxadd")
20778 (set_attr "mode" "DI")])
20779
20780 (define_insn "ssaddv4hi3"
20781 [(set (match_operand:V4HI 0 "register_operand" "=y")
20782 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20783 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20784 "TARGET_MMX"
20785 "paddsw\t{%2, %0|%0, %2}"
20786 [(set_attr "type" "mmxadd")
20787 (set_attr "mode" "DI")])
20788
20789 (define_insn "usaddv8qi3"
20790 [(set (match_operand:V8QI 0 "register_operand" "=y")
20791 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20792 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20793 "TARGET_MMX"
20794 "paddusb\t{%2, %0|%0, %2}"
20795 [(set_attr "type" "mmxadd")
20796 (set_attr "mode" "DI")])
20797
20798 (define_insn "usaddv4hi3"
20799 [(set (match_operand:V4HI 0 "register_operand" "=y")
20800 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20801 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20802 "TARGET_MMX"
20803 "paddusw\t{%2, %0|%0, %2}"
20804 [(set_attr "type" "mmxadd")
20805 (set_attr "mode" "DI")])
20806
20807 (define_insn "subv8qi3"
20808 [(set (match_operand:V8QI 0 "register_operand" "=y")
20809 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20810 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20811 "TARGET_MMX"
20812 "psubb\t{%2, %0|%0, %2}"
20813 [(set_attr "type" "mmxadd")
20814 (set_attr "mode" "DI")])
20815
20816 (define_insn "subv4hi3"
20817 [(set (match_operand:V4HI 0 "register_operand" "=y")
20818 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20819 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20820 "TARGET_MMX"
20821 "psubw\t{%2, %0|%0, %2}"
20822 [(set_attr "type" "mmxadd")
20823 (set_attr "mode" "DI")])
20824
20825 (define_insn "subv2si3"
20826 [(set (match_operand:V2SI 0 "register_operand" "=y")
20827 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20828 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20829 "TARGET_MMX"
20830 "psubd\t{%2, %0|%0, %2}"
20831 [(set_attr "type" "mmxadd")
20832 (set_attr "mode" "DI")])
20833
20834 (define_insn "mmx_subdi3"
20835 [(set (match_operand:DI 0 "register_operand" "=y")
20836 (unspec:DI
20837 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20838 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20839 UNSPEC_NOP))]
20840 "TARGET_MMX"
20841 "psubq\t{%2, %0|%0, %2}"
20842 [(set_attr "type" "mmxadd")
20843 (set_attr "mode" "DI")])
20844
20845 (define_insn "sssubv8qi3"
20846 [(set (match_operand:V8QI 0 "register_operand" "=y")
20847 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20848 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20849 "TARGET_MMX"
20850 "psubsb\t{%2, %0|%0, %2}"
20851 [(set_attr "type" "mmxadd")
20852 (set_attr "mode" "DI")])
20853
20854 (define_insn "sssubv4hi3"
20855 [(set (match_operand:V4HI 0 "register_operand" "=y")
20856 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20857 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20858 "TARGET_MMX"
20859 "psubsw\t{%2, %0|%0, %2}"
20860 [(set_attr "type" "mmxadd")
20861 (set_attr "mode" "DI")])
20862
20863 (define_insn "ussubv8qi3"
20864 [(set (match_operand:V8QI 0 "register_operand" "=y")
20865 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20866 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20867 "TARGET_MMX"
20868 "psubusb\t{%2, %0|%0, %2}"
20869 [(set_attr "type" "mmxadd")
20870 (set_attr "mode" "DI")])
20871
20872 (define_insn "ussubv4hi3"
20873 [(set (match_operand:V4HI 0 "register_operand" "=y")
20874 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20875 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20876 "TARGET_MMX"
20877 "psubusw\t{%2, %0|%0, %2}"
20878 [(set_attr "type" "mmxadd")
20879 (set_attr "mode" "DI")])
20880
20881 (define_insn "mulv4hi3"
20882 [(set (match_operand:V4HI 0 "register_operand" "=y")
20883 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20884 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20885 "TARGET_MMX"
20886 "pmullw\t{%2, %0|%0, %2}"
20887 [(set_attr "type" "mmxmul")
20888 (set_attr "mode" "DI")])
20889
20890 (define_insn "smulv4hi3_highpart"
20891 [(set (match_operand:V4HI 0 "register_operand" "=y")
20892 (truncate:V4HI
20893 (lshiftrt:V4SI
20894 (mult:V4SI (sign_extend:V4SI
20895 (match_operand:V4HI 1 "register_operand" "0"))
20896 (sign_extend:V4SI
20897 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20898 (const_int 16))))]
20899 "TARGET_MMX"
20900 "pmulhw\t{%2, %0|%0, %2}"
20901 [(set_attr "type" "mmxmul")
20902 (set_attr "mode" "DI")])
20903
20904 (define_insn "umulv4hi3_highpart"
20905 [(set (match_operand:V4HI 0 "register_operand" "=y")
20906 (truncate:V4HI
20907 (lshiftrt:V4SI
20908 (mult:V4SI (zero_extend:V4SI
20909 (match_operand:V4HI 1 "register_operand" "0"))
20910 (zero_extend:V4SI
20911 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20912 (const_int 16))))]
20913 "TARGET_SSE || TARGET_3DNOW_A"
20914 "pmulhuw\t{%2, %0|%0, %2}"
20915 [(set_attr "type" "mmxmul")
20916 (set_attr "mode" "DI")])
20917
20918 (define_insn "mmx_pmaddwd"
20919 [(set (match_operand:V2SI 0 "register_operand" "=y")
20920 (plus:V2SI
20921 (mult:V2SI
20922 (sign_extend:V2SI
20923 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20924 (parallel [(const_int 0) (const_int 2)])))
20925 (sign_extend:V2SI
20926 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20927 (parallel [(const_int 0) (const_int 2)]))))
20928 (mult:V2SI
20929 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20930 (parallel [(const_int 1)
20931 (const_int 3)])))
20932 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20933 (parallel [(const_int 1)
20934 (const_int 3)]))))))]
20935 "TARGET_MMX"
20936 "pmaddwd\t{%2, %0|%0, %2}"
20937 [(set_attr "type" "mmxmul")
20938 (set_attr "mode" "DI")])
20939
20940
20941 ;; MMX logical operations
20942 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20943 ;; normal code that also wants to use the FPU from getting broken.
20944 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20945 (define_insn "mmx_iordi3"
20946 [(set (match_operand:DI 0 "register_operand" "=y")
20947 (unspec:DI
20948 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20949 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20950 UNSPEC_NOP))]
20951 "TARGET_MMX"
20952 "por\t{%2, %0|%0, %2}"
20953 [(set_attr "type" "mmxadd")
20954 (set_attr "mode" "DI")])
20955
20956 (define_insn "mmx_xordi3"
20957 [(set (match_operand:DI 0 "register_operand" "=y")
20958 (unspec:DI
20959 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20960 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20961 UNSPEC_NOP))]
20962 "TARGET_MMX"
20963 "pxor\t{%2, %0|%0, %2}"
20964 [(set_attr "type" "mmxadd")
20965 (set_attr "mode" "DI")
20966 (set_attr "memory" "none")])
20967
20968 ;; Same as pxor, but don't show input operands so that we don't think
20969 ;; they are live.
20970 (define_insn "mmx_clrdi"
20971 [(set (match_operand:DI 0 "register_operand" "=y")
20972 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20973 "TARGET_MMX"
20974 "pxor\t{%0, %0|%0, %0}"
20975 [(set_attr "type" "mmxadd")
20976 (set_attr "mode" "DI")
20977 (set_attr "memory" "none")])
20978
20979 (define_insn "mmx_anddi3"
20980 [(set (match_operand:DI 0 "register_operand" "=y")
20981 (unspec:DI
20982 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20983 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20984 UNSPEC_NOP))]
20985 "TARGET_MMX"
20986 "pand\t{%2, %0|%0, %2}"
20987 [(set_attr "type" "mmxadd")
20988 (set_attr "mode" "DI")])
20989
20990 (define_insn "mmx_nanddi3"
20991 [(set (match_operand:DI 0 "register_operand" "=y")
20992 (unspec:DI
20993 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20994 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20995 UNSPEC_NOP))]
20996 "TARGET_MMX"
20997 "pandn\t{%2, %0|%0, %2}"
20998 [(set_attr "type" "mmxadd")
20999 (set_attr "mode" "DI")])
21000
21001
21002 ;; MMX unsigned averages/sum of absolute differences
21003
21004 (define_insn "mmx_uavgv8qi3"
21005 [(set (match_operand:V8QI 0 "register_operand" "=y")
21006 (ashiftrt:V8QI
21007 (plus:V8QI (plus:V8QI
21008 (match_operand:V8QI 1 "register_operand" "0")
21009 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21010 (const_vector:V8QI [(const_int 1)
21011 (const_int 1)
21012 (const_int 1)
21013 (const_int 1)
21014 (const_int 1)
21015 (const_int 1)
21016 (const_int 1)
21017 (const_int 1)]))
21018 (const_int 1)))]
21019 "TARGET_SSE || TARGET_3DNOW_A"
21020 "pavgb\t{%2, %0|%0, %2}"
21021 [(set_attr "type" "mmxshft")
21022 (set_attr "mode" "DI")])
21023
21024 (define_insn "mmx_uavgv4hi3"
21025 [(set (match_operand:V4HI 0 "register_operand" "=y")
21026 (ashiftrt:V4HI
21027 (plus:V4HI (plus:V4HI
21028 (match_operand:V4HI 1 "register_operand" "0")
21029 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21030 (const_vector:V4HI [(const_int 1)
21031 (const_int 1)
21032 (const_int 1)
21033 (const_int 1)]))
21034 (const_int 1)))]
21035 "TARGET_SSE || TARGET_3DNOW_A"
21036 "pavgw\t{%2, %0|%0, %2}"
21037 [(set_attr "type" "mmxshft")
21038 (set_attr "mode" "DI")])
21039
21040 (define_insn "mmx_psadbw"
21041 [(set (match_operand:DI 0 "register_operand" "=y")
21042 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21043 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21044 UNSPEC_PSADBW))]
21045 "TARGET_SSE || TARGET_3DNOW_A"
21046 "psadbw\t{%2, %0|%0, %2}"
21047 [(set_attr "type" "mmxshft")
21048 (set_attr "mode" "DI")])
21049
21050
21051 ;; MMX insert/extract/shuffle
21052
21053 (define_insn "mmx_pinsrw"
21054 [(set (match_operand:V4HI 0 "register_operand" "=y")
21055 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21056 (vec_duplicate:V4HI
21057 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21058 (match_operand:SI 3 "immediate_operand" "i")))]
21059 "TARGET_SSE || TARGET_3DNOW_A"
21060 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21061 [(set_attr "type" "mmxcvt")
21062 (set_attr "mode" "DI")])
21063
21064 (define_insn "mmx_pextrw"
21065 [(set (match_operand:SI 0 "register_operand" "=r")
21066 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21067 (parallel
21068 [(match_operand:SI 2 "immediate_operand" "i")]))))]
21069 "TARGET_SSE || TARGET_3DNOW_A"
21070 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21071 [(set_attr "type" "mmxcvt")
21072 (set_attr "mode" "DI")])
21073
21074 (define_insn "mmx_pshufw"
21075 [(set (match_operand:V4HI 0 "register_operand" "=y")
21076 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
21077 (match_operand:SI 2 "immediate_operand" "i")]
21078 UNSPEC_SHUFFLE))]
21079 "TARGET_SSE || TARGET_3DNOW_A"
21080 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21081 [(set_attr "type" "mmxcvt")
21082 (set_attr "mode" "DI")])
21083
21084
21085 ;; MMX mask-generating comparisons
21086
21087 (define_insn "eqv8qi3"
21088 [(set (match_operand:V8QI 0 "register_operand" "=y")
21089 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21090 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21091 "TARGET_MMX"
21092 "pcmpeqb\t{%2, %0|%0, %2}"
21093 [(set_attr "type" "mmxcmp")
21094 (set_attr "mode" "DI")])
21095
21096 (define_insn "eqv4hi3"
21097 [(set (match_operand:V4HI 0 "register_operand" "=y")
21098 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21099 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21100 "TARGET_MMX"
21101 "pcmpeqw\t{%2, %0|%0, %2}"
21102 [(set_attr "type" "mmxcmp")
21103 (set_attr "mode" "DI")])
21104
21105 (define_insn "eqv2si3"
21106 [(set (match_operand:V2SI 0 "register_operand" "=y")
21107 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21108 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21109 "TARGET_MMX"
21110 "pcmpeqd\t{%2, %0|%0, %2}"
21111 [(set_attr "type" "mmxcmp")
21112 (set_attr "mode" "DI")])
21113
21114 (define_insn "gtv8qi3"
21115 [(set (match_operand:V8QI 0 "register_operand" "=y")
21116 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21117 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21118 "TARGET_MMX"
21119 "pcmpgtb\t{%2, %0|%0, %2}"
21120 [(set_attr "type" "mmxcmp")
21121 (set_attr "mode" "DI")])
21122
21123 (define_insn "gtv4hi3"
21124 [(set (match_operand:V4HI 0 "register_operand" "=y")
21125 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21126 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21127 "TARGET_MMX"
21128 "pcmpgtw\t{%2, %0|%0, %2}"
21129 [(set_attr "type" "mmxcmp")
21130 (set_attr "mode" "DI")])
21131
21132 (define_insn "gtv2si3"
21133 [(set (match_operand:V2SI 0 "register_operand" "=y")
21134 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21135 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21136 "TARGET_MMX"
21137 "pcmpgtd\t{%2, %0|%0, %2}"
21138 [(set_attr "type" "mmxcmp")
21139 (set_attr "mode" "DI")])
21140
21141
21142 ;; MMX max/min insns
21143
21144 (define_insn "umaxv8qi3"
21145 [(set (match_operand:V8QI 0 "register_operand" "=y")
21146 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21147 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21148 "TARGET_SSE || TARGET_3DNOW_A"
21149 "pmaxub\t{%2, %0|%0, %2}"
21150 [(set_attr "type" "mmxadd")
21151 (set_attr "mode" "DI")])
21152
21153 (define_insn "smaxv4hi3"
21154 [(set (match_operand:V4HI 0 "register_operand" "=y")
21155 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21156 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21157 "TARGET_SSE || TARGET_3DNOW_A"
21158 "pmaxsw\t{%2, %0|%0, %2}"
21159 [(set_attr "type" "mmxadd")
21160 (set_attr "mode" "DI")])
21161
21162 (define_insn "uminv8qi3"
21163 [(set (match_operand:V8QI 0 "register_operand" "=y")
21164 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21165 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21166 "TARGET_SSE || TARGET_3DNOW_A"
21167 "pminub\t{%2, %0|%0, %2}"
21168 [(set_attr "type" "mmxadd")
21169 (set_attr "mode" "DI")])
21170
21171 (define_insn "sminv4hi3"
21172 [(set (match_operand:V4HI 0 "register_operand" "=y")
21173 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21174 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21175 "TARGET_SSE || TARGET_3DNOW_A"
21176 "pminsw\t{%2, %0|%0, %2}"
21177 [(set_attr "type" "mmxadd")
21178 (set_attr "mode" "DI")])
21179
21180
21181 ;; MMX shifts
21182
21183 (define_insn "ashrv4hi3"
21184 [(set (match_operand:V4HI 0 "register_operand" "=y")
21185 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21186 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21187 "TARGET_MMX"
21188 "psraw\t{%2, %0|%0, %2}"
21189 [(set_attr "type" "mmxshft")
21190 (set_attr "mode" "DI")])
21191
21192 (define_insn "ashrv2si3"
21193 [(set (match_operand:V2SI 0 "register_operand" "=y")
21194 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21195 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21196 "TARGET_MMX"
21197 "psrad\t{%2, %0|%0, %2}"
21198 [(set_attr "type" "mmxshft")
21199 (set_attr "mode" "DI")])
21200
21201 (define_insn "lshrv4hi3"
21202 [(set (match_operand:V4HI 0 "register_operand" "=y")
21203 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21204 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21205 "TARGET_MMX"
21206 "psrlw\t{%2, %0|%0, %2}"
21207 [(set_attr "type" "mmxshft")
21208 (set_attr "mode" "DI")])
21209
21210 (define_insn "lshrv2si3"
21211 [(set (match_operand:V2SI 0 "register_operand" "=y")
21212 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21213 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21214 "TARGET_MMX"
21215 "psrld\t{%2, %0|%0, %2}"
21216 [(set_attr "type" "mmxshft")
21217 (set_attr "mode" "DI")])
21218
21219 ;; See logical MMX insns.
21220 (define_insn "mmx_lshrdi3"
21221 [(set (match_operand:DI 0 "register_operand" "=y")
21222 (unspec:DI
21223 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21224 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21225 UNSPEC_NOP))]
21226 "TARGET_MMX"
21227 "psrlq\t{%2, %0|%0, %2}"
21228 [(set_attr "type" "mmxshft")
21229 (set_attr "mode" "DI")])
21230
21231 (define_insn "ashlv4hi3"
21232 [(set (match_operand:V4HI 0 "register_operand" "=y")
21233 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21234 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21235 "TARGET_MMX"
21236 "psllw\t{%2, %0|%0, %2}"
21237 [(set_attr "type" "mmxshft")
21238 (set_attr "mode" "DI")])
21239
21240 (define_insn "ashlv2si3"
21241 [(set (match_operand:V2SI 0 "register_operand" "=y")
21242 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21243 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21244 "TARGET_MMX"
21245 "pslld\t{%2, %0|%0, %2}"
21246 [(set_attr "type" "mmxshft")
21247 (set_attr "mode" "DI")])
21248
21249 ;; See logical MMX insns.
21250 (define_insn "mmx_ashldi3"
21251 [(set (match_operand:DI 0 "register_operand" "=y")
21252 (unspec:DI
21253 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21254 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21255 UNSPEC_NOP))]
21256 "TARGET_MMX"
21257 "psllq\t{%2, %0|%0, %2}"
21258 [(set_attr "type" "mmxshft")
21259 (set_attr "mode" "DI")])
21260
21261
21262 ;; MMX pack/unpack insns.
21263
21264 (define_insn "mmx_packsswb"
21265 [(set (match_operand:V8QI 0 "register_operand" "=y")
21266 (vec_concat:V8QI
21267 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21268 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21269 "TARGET_MMX"
21270 "packsswb\t{%2, %0|%0, %2}"
21271 [(set_attr "type" "mmxshft")
21272 (set_attr "mode" "DI")])
21273
21274 (define_insn "mmx_packssdw"
21275 [(set (match_operand:V4HI 0 "register_operand" "=y")
21276 (vec_concat:V4HI
21277 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21278 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21279 "TARGET_MMX"
21280 "packssdw\t{%2, %0|%0, %2}"
21281 [(set_attr "type" "mmxshft")
21282 (set_attr "mode" "DI")])
21283
21284 (define_insn "mmx_packuswb"
21285 [(set (match_operand:V8QI 0 "register_operand" "=y")
21286 (vec_concat:V8QI
21287 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21288 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21289 "TARGET_MMX"
21290 "packuswb\t{%2, %0|%0, %2}"
21291 [(set_attr "type" "mmxshft")
21292 (set_attr "mode" "DI")])
21293
21294 (define_insn "mmx_punpckhbw"
21295 [(set (match_operand:V8QI 0 "register_operand" "=y")
21296 (vec_merge:V8QI
21297 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21298 (parallel [(const_int 4)
21299 (const_int 0)
21300 (const_int 5)
21301 (const_int 1)
21302 (const_int 6)
21303 (const_int 2)
21304 (const_int 7)
21305 (const_int 3)]))
21306 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21307 (parallel [(const_int 0)
21308 (const_int 4)
21309 (const_int 1)
21310 (const_int 5)
21311 (const_int 2)
21312 (const_int 6)
21313 (const_int 3)
21314 (const_int 7)]))
21315 (const_int 85)))]
21316 "TARGET_MMX"
21317 "punpckhbw\t{%2, %0|%0, %2}"
21318 [(set_attr "type" "mmxcvt")
21319 (set_attr "mode" "DI")])
21320
21321 (define_insn "mmx_punpckhwd"
21322 [(set (match_operand:V4HI 0 "register_operand" "=y")
21323 (vec_merge:V4HI
21324 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21325 (parallel [(const_int 0)
21326 (const_int 2)
21327 (const_int 1)
21328 (const_int 3)]))
21329 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21330 (parallel [(const_int 2)
21331 (const_int 0)
21332 (const_int 3)
21333 (const_int 1)]))
21334 (const_int 5)))]
21335 "TARGET_MMX"
21336 "punpckhwd\t{%2, %0|%0, %2}"
21337 [(set_attr "type" "mmxcvt")
21338 (set_attr "mode" "DI")])
21339
21340 (define_insn "mmx_punpckhdq"
21341 [(set (match_operand:V2SI 0 "register_operand" "=y")
21342 (vec_merge:V2SI
21343 (match_operand:V2SI 1 "register_operand" "0")
21344 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21345 (parallel [(const_int 1)
21346 (const_int 0)]))
21347 (const_int 1)))]
21348 "TARGET_MMX"
21349 "punpckhdq\t{%2, %0|%0, %2}"
21350 [(set_attr "type" "mmxcvt")
21351 (set_attr "mode" "DI")])
21352
21353 (define_insn "mmx_punpcklbw"
21354 [(set (match_operand:V8QI 0 "register_operand" "=y")
21355 (vec_merge:V8QI
21356 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21357 (parallel [(const_int 0)
21358 (const_int 4)
21359 (const_int 1)
21360 (const_int 5)
21361 (const_int 2)
21362 (const_int 6)
21363 (const_int 3)
21364 (const_int 7)]))
21365 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21366 (parallel [(const_int 4)
21367 (const_int 0)
21368 (const_int 5)
21369 (const_int 1)
21370 (const_int 6)
21371 (const_int 2)
21372 (const_int 7)
21373 (const_int 3)]))
21374 (const_int 85)))]
21375 "TARGET_MMX"
21376 "punpcklbw\t{%2, %0|%0, %2}"
21377 [(set_attr "type" "mmxcvt")
21378 (set_attr "mode" "DI")])
21379
21380 (define_insn "mmx_punpcklwd"
21381 [(set (match_operand:V4HI 0 "register_operand" "=y")
21382 (vec_merge:V4HI
21383 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21384 (parallel [(const_int 2)
21385 (const_int 0)
21386 (const_int 3)
21387 (const_int 1)]))
21388 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21389 (parallel [(const_int 0)
21390 (const_int 2)
21391 (const_int 1)
21392 (const_int 3)]))
21393 (const_int 5)))]
21394 "TARGET_MMX"
21395 "punpcklwd\t{%2, %0|%0, %2}"
21396 [(set_attr "type" "mmxcvt")
21397 (set_attr "mode" "DI")])
21398
21399 (define_insn "mmx_punpckldq"
21400 [(set (match_operand:V2SI 0 "register_operand" "=y")
21401 (vec_merge:V2SI
21402 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21403 (parallel [(const_int 1)
21404 (const_int 0)]))
21405 (match_operand:V2SI 2 "register_operand" "y")
21406 (const_int 1)))]
21407 "TARGET_MMX"
21408 "punpckldq\t{%2, %0|%0, %2}"
21409 [(set_attr "type" "mmxcvt")
21410 (set_attr "mode" "DI")])
21411
21412
21413 ;; Miscellaneous stuff
21414
21415 (define_insn "emms"
21416 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21417 (clobber (reg:XF 8))
21418 (clobber (reg:XF 9))
21419 (clobber (reg:XF 10))
21420 (clobber (reg:XF 11))
21421 (clobber (reg:XF 12))
21422 (clobber (reg:XF 13))
21423 (clobber (reg:XF 14))
21424 (clobber (reg:XF 15))
21425 (clobber (reg:DI 29))
21426 (clobber (reg:DI 30))
21427 (clobber (reg:DI 31))
21428 (clobber (reg:DI 32))
21429 (clobber (reg:DI 33))
21430 (clobber (reg:DI 34))
21431 (clobber (reg:DI 35))
21432 (clobber (reg:DI 36))]
21433 "TARGET_MMX"
21434 "emms"
21435 [(set_attr "type" "mmx")
21436 (set_attr "memory" "unknown")])
21437
21438 (define_insn "ldmxcsr"
21439 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21440 UNSPECV_LDMXCSR)]
21441 "TARGET_SSE"
21442 "ldmxcsr\t%0"
21443 [(set_attr "type" "sse")
21444 (set_attr "memory" "load")])
21445
21446 (define_insn "stmxcsr"
21447 [(set (match_operand:SI 0 "memory_operand" "=m")
21448 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21449 "TARGET_SSE"
21450 "stmxcsr\t%0"
21451 [(set_attr "type" "sse")
21452 (set_attr "memory" "store")])
21453
21454 (define_expand "sfence"
21455 [(set (match_dup 0)
21456 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21457 "TARGET_SSE || TARGET_3DNOW_A"
21458 {
21459 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21460 MEM_VOLATILE_P (operands[0]) = 1;
21461 })
21462
21463 (define_insn "*sfence_insn"
21464 [(set (match_operand:BLK 0 "" "")
21465 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21466 "TARGET_SSE || TARGET_3DNOW_A"
21467 "sfence"
21468 [(set_attr "type" "sse")
21469 (set_attr "memory" "unknown")])
21470
21471 (define_expand "sse_prologue_save"
21472 [(parallel [(set (match_operand:BLK 0 "" "")
21473 (unspec:BLK [(reg:DI 21)
21474 (reg:DI 22)
21475 (reg:DI 23)
21476 (reg:DI 24)
21477 (reg:DI 25)
21478 (reg:DI 26)
21479 (reg:DI 27)
21480 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21481 (use (match_operand:DI 1 "register_operand" ""))
21482 (use (match_operand:DI 2 "immediate_operand" ""))
21483 (use (label_ref:DI (match_operand 3 "" "")))])]
21484 "TARGET_64BIT"
21485 "")
21486
21487 (define_insn "*sse_prologue_save_insn"
21488 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21489 (match_operand:DI 4 "const_int_operand" "n")))
21490 (unspec:BLK [(reg:DI 21)
21491 (reg:DI 22)
21492 (reg:DI 23)
21493 (reg:DI 24)
21494 (reg:DI 25)
21495 (reg:DI 26)
21496 (reg:DI 27)
21497 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21498 (use (match_operand:DI 1 "register_operand" "r"))
21499 (use (match_operand:DI 2 "const_int_operand" "i"))
21500 (use (label_ref:DI (match_operand 3 "" "X")))]
21501 "TARGET_64BIT
21502 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21503 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21504 "*
21505 {
21506 int i;
21507 operands[0] = gen_rtx_MEM (Pmode,
21508 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21509 output_asm_insn (\"jmp\\t%A1\", operands);
21510 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21511 {
21512 operands[4] = adjust_address (operands[0], DImode, i*16);
21513 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21514 PUT_MODE (operands[4], TImode);
21515 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21516 output_asm_insn (\"rex\", operands);
21517 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21518 }
21519 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21520 CODE_LABEL_NUMBER (operands[3]));
21521 RET;
21522 }
21523 "
21524 [(set_attr "type" "other")
21525 (set_attr "length_immediate" "0")
21526 (set_attr "length_address" "0")
21527 (set_attr "length" "135")
21528 (set_attr "memory" "store")
21529 (set_attr "modrm" "0")
21530 (set_attr "mode" "DI")])
21531
21532 ;; 3Dnow! instructions
21533
21534 (define_insn "addv2sf3"
21535 [(set (match_operand:V2SF 0 "register_operand" "=y")
21536 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21537 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21538 "TARGET_3DNOW"
21539 "pfadd\\t{%2, %0|%0, %2}"
21540 [(set_attr "type" "mmxadd")
21541 (set_attr "mode" "V2SF")])
21542
21543 (define_insn "subv2sf3"
21544 [(set (match_operand:V2SF 0 "register_operand" "=y")
21545 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21546 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21547 "TARGET_3DNOW"
21548 "pfsub\\t{%2, %0|%0, %2}"
21549 [(set_attr "type" "mmxadd")
21550 (set_attr "mode" "V2SF")])
21551
21552 (define_insn "subrv2sf3"
21553 [(set (match_operand:V2SF 0 "register_operand" "=y")
21554 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21555 (match_operand:V2SF 1 "register_operand" "0")))]
21556 "TARGET_3DNOW"
21557 "pfsubr\\t{%2, %0|%0, %2}"
21558 [(set_attr "type" "mmxadd")
21559 (set_attr "mode" "V2SF")])
21560
21561 (define_insn "gtv2sf3"
21562 [(set (match_operand:V2SI 0 "register_operand" "=y")
21563 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21564 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21565 "TARGET_3DNOW"
21566 "pfcmpgt\\t{%2, %0|%0, %2}"
21567 [(set_attr "type" "mmxcmp")
21568 (set_attr "mode" "V2SF")])
21569
21570 (define_insn "gev2sf3"
21571 [(set (match_operand:V2SI 0 "register_operand" "=y")
21572 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21573 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21574 "TARGET_3DNOW"
21575 "pfcmpge\\t{%2, %0|%0, %2}"
21576 [(set_attr "type" "mmxcmp")
21577 (set_attr "mode" "V2SF")])
21578
21579 (define_insn "eqv2sf3"
21580 [(set (match_operand:V2SI 0 "register_operand" "=y")
21581 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21582 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21583 "TARGET_3DNOW"
21584 "pfcmpeq\\t{%2, %0|%0, %2}"
21585 [(set_attr "type" "mmxcmp")
21586 (set_attr "mode" "V2SF")])
21587
21588 (define_insn "pfmaxv2sf3"
21589 [(set (match_operand:V2SF 0 "register_operand" "=y")
21590 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21591 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21592 "TARGET_3DNOW"
21593 "pfmax\\t{%2, %0|%0, %2}"
21594 [(set_attr "type" "mmxadd")
21595 (set_attr "mode" "V2SF")])
21596
21597 (define_insn "pfminv2sf3"
21598 [(set (match_operand:V2SF 0 "register_operand" "=y")
21599 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21600 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21601 "TARGET_3DNOW"
21602 "pfmin\\t{%2, %0|%0, %2}"
21603 [(set_attr "type" "mmxadd")
21604 (set_attr "mode" "V2SF")])
21605
21606 (define_insn "mulv2sf3"
21607 [(set (match_operand:V2SF 0 "register_operand" "=y")
21608 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21609 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21610 "TARGET_3DNOW"
21611 "pfmul\\t{%2, %0|%0, %2}"
21612 [(set_attr "type" "mmxmul")
21613 (set_attr "mode" "V2SF")])
21614
21615 (define_insn "femms"
21616 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21617 (clobber (reg:XF 8))
21618 (clobber (reg:XF 9))
21619 (clobber (reg:XF 10))
21620 (clobber (reg:XF 11))
21621 (clobber (reg:XF 12))
21622 (clobber (reg:XF 13))
21623 (clobber (reg:XF 14))
21624 (clobber (reg:XF 15))
21625 (clobber (reg:DI 29))
21626 (clobber (reg:DI 30))
21627 (clobber (reg:DI 31))
21628 (clobber (reg:DI 32))
21629 (clobber (reg:DI 33))
21630 (clobber (reg:DI 34))
21631 (clobber (reg:DI 35))
21632 (clobber (reg:DI 36))]
21633 "TARGET_3DNOW"
21634 "femms"
21635 [(set_attr "type" "mmx")
21636 (set_attr "memory" "none")])
21637
21638 (define_insn "pf2id"
21639 [(set (match_operand:V2SI 0 "register_operand" "=y")
21640 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21641 "TARGET_3DNOW"
21642 "pf2id\\t{%1, %0|%0, %1}"
21643 [(set_attr "type" "mmxcvt")
21644 (set_attr "mode" "V2SF")])
21645
21646 (define_insn "pf2iw"
21647 [(set (match_operand:V2SI 0 "register_operand" "=y")
21648 (sign_extend:V2SI
21649 (ss_truncate:V2HI
21650 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21651 "TARGET_3DNOW_A"
21652 "pf2iw\\t{%1, %0|%0, %1}"
21653 [(set_attr "type" "mmxcvt")
21654 (set_attr "mode" "V2SF")])
21655
21656 (define_insn "pfacc"
21657 [(set (match_operand:V2SF 0 "register_operand" "=y")
21658 (vec_concat:V2SF
21659 (plus:SF
21660 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21661 (parallel [(const_int 0)]))
21662 (vec_select:SF (match_dup 1)
21663 (parallel [(const_int 1)])))
21664 (plus:SF
21665 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21666 (parallel [(const_int 0)]))
21667 (vec_select:SF (match_dup 2)
21668 (parallel [(const_int 1)])))))]
21669 "TARGET_3DNOW"
21670 "pfacc\\t{%2, %0|%0, %2}"
21671 [(set_attr "type" "mmxadd")
21672 (set_attr "mode" "V2SF")])
21673
21674 (define_insn "pfnacc"
21675 [(set (match_operand:V2SF 0 "register_operand" "=y")
21676 (vec_concat:V2SF
21677 (minus:SF
21678 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21679 (parallel [(const_int 0)]))
21680 (vec_select:SF (match_dup 1)
21681 (parallel [(const_int 1)])))
21682 (minus:SF
21683 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21684 (parallel [(const_int 0)]))
21685 (vec_select:SF (match_dup 2)
21686 (parallel [(const_int 1)])))))]
21687 "TARGET_3DNOW_A"
21688 "pfnacc\\t{%2, %0|%0, %2}"
21689 [(set_attr "type" "mmxadd")
21690 (set_attr "mode" "V2SF")])
21691
21692 (define_insn "pfpnacc"
21693 [(set (match_operand:V2SF 0 "register_operand" "=y")
21694 (vec_concat:V2SF
21695 (minus:SF
21696 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21697 (parallel [(const_int 0)]))
21698 (vec_select:SF (match_dup 1)
21699 (parallel [(const_int 1)])))
21700 (plus:SF
21701 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21702 (parallel [(const_int 0)]))
21703 (vec_select:SF (match_dup 2)
21704 (parallel [(const_int 1)])))))]
21705 "TARGET_3DNOW_A"
21706 "pfpnacc\\t{%2, %0|%0, %2}"
21707 [(set_attr "type" "mmxadd")
21708 (set_attr "mode" "V2SF")])
21709
21710 (define_insn "pi2fw"
21711 [(set (match_operand:V2SF 0 "register_operand" "=y")
21712 (float:V2SF
21713 (vec_concat:V2SI
21714 (sign_extend:SI
21715 (truncate:HI
21716 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21717 (parallel [(const_int 0)]))))
21718 (sign_extend:SI
21719 (truncate:HI
21720 (vec_select:SI (match_dup 1)
21721 (parallel [(const_int 1)])))))))]
21722 "TARGET_3DNOW_A"
21723 "pi2fw\\t{%1, %0|%0, %1}"
21724 [(set_attr "type" "mmxcvt")
21725 (set_attr "mode" "V2SF")])
21726
21727 (define_insn "floatv2si2"
21728 [(set (match_operand:V2SF 0 "register_operand" "=y")
21729 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21730 "TARGET_3DNOW"
21731 "pi2fd\\t{%1, %0|%0, %1}"
21732 [(set_attr "type" "mmxcvt")
21733 (set_attr "mode" "V2SF")])
21734
21735 ;; This insn is identical to pavgb in operation, but the opcode is
21736 ;; different. To avoid accidentally matching pavgb, use an unspec.
21737
21738 (define_insn "pavgusb"
21739 [(set (match_operand:V8QI 0 "register_operand" "=y")
21740 (unspec:V8QI
21741 [(match_operand:V8QI 1 "register_operand" "0")
21742 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21743 UNSPEC_PAVGUSB))]
21744 "TARGET_3DNOW"
21745 "pavgusb\\t{%2, %0|%0, %2}"
21746 [(set_attr "type" "mmxshft")
21747 (set_attr "mode" "TI")])
21748
21749 ;; 3DNow reciprocal and sqrt
21750
21751 (define_insn "pfrcpv2sf2"
21752 [(set (match_operand:V2SF 0 "register_operand" "=y")
21753 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21754 UNSPEC_PFRCP))]
21755 "TARGET_3DNOW"
21756 "pfrcp\\t{%1, %0|%0, %1}"
21757 [(set_attr "type" "mmx")
21758 (set_attr "mode" "TI")])
21759
21760 (define_insn "pfrcpit1v2sf3"
21761 [(set (match_operand:V2SF 0 "register_operand" "=y")
21762 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21763 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21764 UNSPEC_PFRCPIT1))]
21765 "TARGET_3DNOW"
21766 "pfrcpit1\\t{%2, %0|%0, %2}"
21767 [(set_attr "type" "mmx")
21768 (set_attr "mode" "TI")])
21769
21770 (define_insn "pfrcpit2v2sf3"
21771 [(set (match_operand:V2SF 0 "register_operand" "=y")
21772 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21773 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21774 UNSPEC_PFRCPIT2))]
21775 "TARGET_3DNOW"
21776 "pfrcpit2\\t{%2, %0|%0, %2}"
21777 [(set_attr "type" "mmx")
21778 (set_attr "mode" "TI")])
21779
21780 (define_insn "pfrsqrtv2sf2"
21781 [(set (match_operand:V2SF 0 "register_operand" "=y")
21782 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21783 UNSPEC_PFRSQRT))]
21784 "TARGET_3DNOW"
21785 "pfrsqrt\\t{%1, %0|%0, %1}"
21786 [(set_attr "type" "mmx")
21787 (set_attr "mode" "TI")])
21788
21789 (define_insn "pfrsqit1v2sf3"
21790 [(set (match_operand:V2SF 0 "register_operand" "=y")
21791 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21792 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21793 UNSPEC_PFRSQIT1))]
21794 "TARGET_3DNOW"
21795 "pfrsqit1\\t{%2, %0|%0, %2}"
21796 [(set_attr "type" "mmx")
21797 (set_attr "mode" "TI")])
21798
21799 (define_insn "pmulhrwv4hi3"
21800 [(set (match_operand:V4HI 0 "register_operand" "=y")
21801 (truncate:V4HI
21802 (lshiftrt:V4SI
21803 (plus:V4SI
21804 (mult:V4SI
21805 (sign_extend:V4SI
21806 (match_operand:V4HI 1 "register_operand" "0"))
21807 (sign_extend:V4SI
21808 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21809 (const_vector:V4SI [(const_int 32768)
21810 (const_int 32768)
21811 (const_int 32768)
21812 (const_int 32768)]))
21813 (const_int 16))))]
21814 "TARGET_3DNOW"
21815 "pmulhrw\\t{%2, %0|%0, %2}"
21816 [(set_attr "type" "mmxmul")
21817 (set_attr "mode" "TI")])
21818
21819 (define_insn "pswapdv2si2"
21820 [(set (match_operand:V2SI 0 "register_operand" "=y")
21821 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21822 (parallel [(const_int 1) (const_int 0)])))]
21823 "TARGET_3DNOW_A"
21824 "pswapd\\t{%1, %0|%0, %1}"
21825 [(set_attr "type" "mmxcvt")
21826 (set_attr "mode" "TI")])
21827
21828 (define_insn "pswapdv2sf2"
21829 [(set (match_operand:V2SF 0 "register_operand" "=y")
21830 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21831 (parallel [(const_int 1) (const_int 0)])))]
21832 "TARGET_3DNOW_A"
21833 "pswapd\\t{%1, %0|%0, %1}"
21834 [(set_attr "type" "mmxcvt")
21835 (set_attr "mode" "TI")])
21836
21837 (define_expand "prefetch"
21838 [(prefetch (match_operand 0 "address_operand" "")
21839 (match_operand:SI 1 "const_int_operand" "")
21840 (match_operand:SI 2 "const_int_operand" ""))]
21841 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21842 {
21843 int rw = INTVAL (operands[1]);
21844 int locality = INTVAL (operands[2]);
21845
21846 if (rw != 0 && rw != 1)
21847 abort ();
21848 if (locality < 0 || locality > 3)
21849 abort ();
21850 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21851 abort ();
21852
21853 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21854 suported by SSE counterpart or the SSE prefetch is not available
21855 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21856 of locality. */
21857 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21858 operands[2] = GEN_INT (3);
21859 else
21860 operands[1] = const0_rtx;
21861 })
21862
21863 (define_insn "*prefetch_sse"
21864 [(prefetch (match_operand:SI 0 "address_operand" "p")
21865 (const_int 0)
21866 (match_operand:SI 1 "const_int_operand" ""))]
21867 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21868 {
21869 static const char * const patterns[4] = {
21870 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21871 };
21872
21873 int locality = INTVAL (operands[1]);
21874 if (locality < 0 || locality > 3)
21875 abort ();
21876
21877 return patterns[locality];
21878 }
21879 [(set_attr "type" "sse")
21880 (set_attr "memory" "none")])
21881
21882 (define_insn "*prefetch_sse_rex"
21883 [(prefetch (match_operand:DI 0 "address_operand" "p")
21884 (const_int 0)
21885 (match_operand:SI 1 "const_int_operand" ""))]
21886 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21887 {
21888 static const char * const patterns[4] = {
21889 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21890 };
21891
21892 int locality = INTVAL (operands[1]);
21893 if (locality < 0 || locality > 3)
21894 abort ();
21895
21896 return patterns[locality];
21897 }
21898 [(set_attr "type" "sse")
21899 (set_attr "memory" "none")])
21900
21901 (define_insn "*prefetch_3dnow"
21902 [(prefetch (match_operand:SI 0 "address_operand" "p")
21903 (match_operand:SI 1 "const_int_operand" "n")
21904 (const_int 3))]
21905 "TARGET_3DNOW && !TARGET_64BIT"
21906 {
21907 if (INTVAL (operands[1]) == 0)
21908 return "prefetch\t%a0";
21909 else
21910 return "prefetchw\t%a0";
21911 }
21912 [(set_attr "type" "mmx")
21913 (set_attr "memory" "none")])
21914
21915 (define_insn "*prefetch_3dnow_rex"
21916 [(prefetch (match_operand:DI 0 "address_operand" "p")
21917 (match_operand:SI 1 "const_int_operand" "n")
21918 (const_int 3))]
21919 "TARGET_3DNOW && TARGET_64BIT"
21920 {
21921 if (INTVAL (operands[1]) == 0)
21922 return "prefetch\t%a0";
21923 else
21924 return "prefetchw\t%a0";
21925 }
21926 [(set_attr "type" "mmx")
21927 (set_attr "memory" "none")])
21928
21929 ;; SSE2 support
21930
21931 (define_insn "addv2df3"
21932 [(set (match_operand:V2DF 0 "register_operand" "=x")
21933 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21934 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21935 "TARGET_SSE2"
21936 "addpd\t{%2, %0|%0, %2}"
21937 [(set_attr "type" "sseadd")
21938 (set_attr "mode" "V2DF")])
21939
21940 (define_insn "vmaddv2df3"
21941 [(set (match_operand:V2DF 0 "register_operand" "=x")
21942 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21943 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21944 (match_dup 1)
21945 (const_int 1)))]
21946 "TARGET_SSE2"
21947 "addsd\t{%2, %0|%0, %2}"
21948 [(set_attr "type" "sseadd")
21949 (set_attr "mode" "DF")])
21950
21951 (define_insn "subv2df3"
21952 [(set (match_operand:V2DF 0 "register_operand" "=x")
21953 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21954 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21955 "TARGET_SSE2"
21956 "subpd\t{%2, %0|%0, %2}"
21957 [(set_attr "type" "sseadd")
21958 (set_attr "mode" "V2DF")])
21959
21960 (define_insn "vmsubv2df3"
21961 [(set (match_operand:V2DF 0 "register_operand" "=x")
21962 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21963 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21964 (match_dup 1)
21965 (const_int 1)))]
21966 "TARGET_SSE2"
21967 "subsd\t{%2, %0|%0, %2}"
21968 [(set_attr "type" "sseadd")
21969 (set_attr "mode" "DF")])
21970
21971 (define_insn "mulv2df3"
21972 [(set (match_operand:V2DF 0 "register_operand" "=x")
21973 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21974 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21975 "TARGET_SSE2"
21976 "mulpd\t{%2, %0|%0, %2}"
21977 [(set_attr "type" "ssemul")
21978 (set_attr "mode" "V2DF")])
21979
21980 (define_insn "vmmulv2df3"
21981 [(set (match_operand:V2DF 0 "register_operand" "=x")
21982 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21983 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21984 (match_dup 1)
21985 (const_int 1)))]
21986 "TARGET_SSE2"
21987 "mulsd\t{%2, %0|%0, %2}"
21988 [(set_attr "type" "ssemul")
21989 (set_attr "mode" "DF")])
21990
21991 (define_insn "divv2df3"
21992 [(set (match_operand:V2DF 0 "register_operand" "=x")
21993 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21994 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21995 "TARGET_SSE2"
21996 "divpd\t{%2, %0|%0, %2}"
21997 [(set_attr "type" "ssediv")
21998 (set_attr "mode" "V2DF")])
21999
22000 (define_insn "vmdivv2df3"
22001 [(set (match_operand:V2DF 0 "register_operand" "=x")
22002 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22003 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22004 (match_dup 1)
22005 (const_int 1)))]
22006 "TARGET_SSE2"
22007 "divsd\t{%2, %0|%0, %2}"
22008 [(set_attr "type" "ssediv")
22009 (set_attr "mode" "DF")])
22010
22011 ;; SSE min/max
22012
22013 (define_insn "smaxv2df3"
22014 [(set (match_operand:V2DF 0 "register_operand" "=x")
22015 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22016 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22017 "TARGET_SSE2"
22018 "maxpd\t{%2, %0|%0, %2}"
22019 [(set_attr "type" "sseadd")
22020 (set_attr "mode" "V2DF")])
22021
22022 (define_insn "vmsmaxv2df3"
22023 [(set (match_operand:V2DF 0 "register_operand" "=x")
22024 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22025 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22026 (match_dup 1)
22027 (const_int 1)))]
22028 "TARGET_SSE2"
22029 "maxsd\t{%2, %0|%0, %2}"
22030 [(set_attr "type" "sseadd")
22031 (set_attr "mode" "DF")])
22032
22033 (define_insn "sminv2df3"
22034 [(set (match_operand:V2DF 0 "register_operand" "=x")
22035 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22036 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22037 "TARGET_SSE2"
22038 "minpd\t{%2, %0|%0, %2}"
22039 [(set_attr "type" "sseadd")
22040 (set_attr "mode" "V2DF")])
22041
22042 (define_insn "vmsminv2df3"
22043 [(set (match_operand:V2DF 0 "register_operand" "=x")
22044 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22045 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22046 (match_dup 1)
22047 (const_int 1)))]
22048 "TARGET_SSE2"
22049 "minsd\t{%2, %0|%0, %2}"
22050 [(set_attr "type" "sseadd")
22051 (set_attr "mode" "DF")])
22052 ;; SSE2 square root. There doesn't appear to be an extension for the
22053 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22054
22055 (define_insn "sqrtv2df2"
22056 [(set (match_operand:V2DF 0 "register_operand" "=x")
22057 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22058 "TARGET_SSE2"
22059 "sqrtpd\t{%1, %0|%0, %1}"
22060 [(set_attr "type" "sse")
22061 (set_attr "mode" "V2DF")])
22062
22063 (define_insn "vmsqrtv2df2"
22064 [(set (match_operand:V2DF 0 "register_operand" "=x")
22065 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22066 (match_operand:V2DF 2 "register_operand" "0")
22067 (const_int 1)))]
22068 "TARGET_SSE2"
22069 "sqrtsd\t{%1, %0|%0, %1}"
22070 [(set_attr "type" "sse")
22071 (set_attr "mode" "SF")])
22072
22073 ;; SSE mask-generating compares
22074
22075 (define_insn "maskcmpv2df3"
22076 [(set (match_operand:V2DI 0 "register_operand" "=x")
22077 (match_operator:V2DI 3 "sse_comparison_operator"
22078 [(match_operand:V2DF 1 "register_operand" "0")
22079 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22080 "TARGET_SSE2"
22081 "cmp%D3pd\t{%2, %0|%0, %2}"
22082 [(set_attr "type" "ssecmp")
22083 (set_attr "mode" "V2DF")])
22084
22085 (define_insn "maskncmpv2df3"
22086 [(set (match_operand:V2DI 0 "register_operand" "=x")
22087 (not:V2DI
22088 (match_operator:V2DI 3 "sse_comparison_operator"
22089 [(match_operand:V2DF 1 "register_operand" "0")
22090 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22091 "TARGET_SSE2"
22092 {
22093 if (GET_CODE (operands[3]) == UNORDERED)
22094 return "cmpordps\t{%2, %0|%0, %2}";
22095 else
22096 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22097 }
22098 [(set_attr "type" "ssecmp")
22099 (set_attr "mode" "V2DF")])
22100
22101 (define_insn "vmmaskcmpv2df3"
22102 [(set (match_operand:V2DI 0 "register_operand" "=x")
22103 (vec_merge:V2DI
22104 (match_operator:V2DI 3 "sse_comparison_operator"
22105 [(match_operand:V2DF 1 "register_operand" "0")
22106 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22107 (subreg:V2DI (match_dup 1) 0)
22108 (const_int 1)))]
22109 "TARGET_SSE2"
22110 "cmp%D3sd\t{%2, %0|%0, %2}"
22111 [(set_attr "type" "ssecmp")
22112 (set_attr "mode" "DF")])
22113
22114 (define_insn "vmmaskncmpv2df3"
22115 [(set (match_operand:V2DI 0 "register_operand" "=x")
22116 (vec_merge:V2DI
22117 (not:V2DI
22118 (match_operator:V2DI 3 "sse_comparison_operator"
22119 [(match_operand:V2DF 1 "register_operand" "0")
22120 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22121 (subreg:V2DI (match_dup 1) 0)
22122 (const_int 1)))]
22123 "TARGET_SSE2"
22124 {
22125 if (GET_CODE (operands[3]) == UNORDERED)
22126 return "cmpordsd\t{%2, %0|%0, %2}";
22127 else
22128 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22129 }
22130 [(set_attr "type" "ssecmp")
22131 (set_attr "mode" "DF")])
22132
22133 (define_insn "sse2_comi"
22134 [(set (reg:CCFP 17)
22135 (compare:CCFP (vec_select:DF
22136 (match_operand:V2DF 0 "register_operand" "x")
22137 (parallel [(const_int 0)]))
22138 (vec_select:DF
22139 (match_operand:V2DF 1 "register_operand" "x")
22140 (parallel [(const_int 0)]))))]
22141 "TARGET_SSE2"
22142 "comisd\t{%1, %0|%0, %1}"
22143 [(set_attr "type" "ssecomi")
22144 (set_attr "mode" "DF")])
22145
22146 (define_insn "sse2_ucomi"
22147 [(set (reg:CCFPU 17)
22148 (compare:CCFPU (vec_select:DF
22149 (match_operand:V2DF 0 "register_operand" "x")
22150 (parallel [(const_int 0)]))
22151 (vec_select:DF
22152 (match_operand:V2DF 1 "register_operand" "x")
22153 (parallel [(const_int 0)]))))]
22154 "TARGET_SSE2"
22155 "ucomisd\t{%1, %0|%0, %1}"
22156 [(set_attr "type" "ssecomi")
22157 (set_attr "mode" "DF")])
22158
22159 ;; SSE Strange Moves.
22160
22161 (define_insn "sse2_movmskpd"
22162 [(set (match_operand:SI 0 "register_operand" "=r")
22163 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22164 UNSPEC_MOVMSK))]
22165 "TARGET_SSE2"
22166 "movmskpd\t{%1, %0|%0, %1}"
22167 [(set_attr "type" "ssecvt")
22168 (set_attr "mode" "V2DF")])
22169
22170 (define_insn "sse2_pmovmskb"
22171 [(set (match_operand:SI 0 "register_operand" "=r")
22172 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22173 UNSPEC_MOVMSK))]
22174 "TARGET_SSE2"
22175 "pmovmskb\t{%1, %0|%0, %1}"
22176 [(set_attr "type" "ssecvt")
22177 (set_attr "mode" "V2DF")])
22178
22179 (define_insn "sse2_maskmovdqu"
22180 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22181 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22182 (match_operand:V16QI 2 "register_operand" "x")]
22183 UNSPEC_MASKMOV))]
22184 "TARGET_SSE2"
22185 ;; @@@ check ordering of operands in intel/nonintel syntax
22186 "maskmovdqu\t{%2, %1|%1, %2}"
22187 [(set_attr "type" "ssecvt")
22188 (set_attr "mode" "TI")])
22189
22190 (define_insn "sse2_maskmovdqu_rex64"
22191 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22192 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22193 (match_operand:V16QI 2 "register_operand" "x")]
22194 UNSPEC_MASKMOV))]
22195 "TARGET_SSE2"
22196 ;; @@@ check ordering of operands in intel/nonintel syntax
22197 "maskmovdqu\t{%2, %1|%1, %2}"
22198 [(set_attr "type" "ssecvt")
22199 (set_attr "mode" "TI")])
22200
22201 (define_insn "sse2_movntv2df"
22202 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22203 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22204 UNSPEC_MOVNT))]
22205 "TARGET_SSE2"
22206 "movntpd\t{%1, %0|%0, %1}"
22207 [(set_attr "type" "ssecvt")
22208 (set_attr "mode" "V2DF")])
22209
22210 (define_insn "sse2_movntv2di"
22211 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22212 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22213 UNSPEC_MOVNT))]
22214 "TARGET_SSE2"
22215 "movntdq\t{%1, %0|%0, %1}"
22216 [(set_attr "type" "ssecvt")
22217 (set_attr "mode" "TI")])
22218
22219 (define_insn "sse2_movntsi"
22220 [(set (match_operand:SI 0 "memory_operand" "=m")
22221 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22222 UNSPEC_MOVNT))]
22223 "TARGET_SSE2"
22224 "movnti\t{%1, %0|%0, %1}"
22225 [(set_attr "type" "ssecvt")
22226 (set_attr "mode" "V2DF")])
22227
22228 ;; SSE <-> integer/MMX conversions
22229
22230 ;; Conversions between SI and SF
22231
22232 (define_insn "cvtdq2ps"
22233 [(set (match_operand:V4SF 0 "register_operand" "=x")
22234 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22235 "TARGET_SSE2"
22236 "cvtdq2ps\t{%1, %0|%0, %1}"
22237 [(set_attr "type" "ssecvt")
22238 (set_attr "mode" "V2DF")])
22239
22240 (define_insn "cvtps2dq"
22241 [(set (match_operand:V4SI 0 "register_operand" "=x")
22242 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22243 "TARGET_SSE2"
22244 "cvtps2dq\t{%1, %0|%0, %1}"
22245 [(set_attr "type" "ssecvt")
22246 (set_attr "mode" "TI")])
22247
22248 (define_insn "cvttps2dq"
22249 [(set (match_operand:V4SI 0 "register_operand" "=x")
22250 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22251 UNSPEC_FIX))]
22252 "TARGET_SSE2"
22253 "cvttps2dq\t{%1, %0|%0, %1}"
22254 [(set_attr "type" "ssecvt")
22255 (set_attr "mode" "TI")])
22256
22257 ;; Conversions between SI and DF
22258
22259 (define_insn "cvtdq2pd"
22260 [(set (match_operand:V2DF 0 "register_operand" "=x")
22261 (float:V2DF (vec_select:V2SI
22262 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22263 (parallel
22264 [(const_int 0)
22265 (const_int 1)]))))]
22266 "TARGET_SSE2"
22267 "cvtdq2pd\t{%1, %0|%0, %1}"
22268 [(set_attr "type" "ssecvt")
22269 (set_attr "mode" "V2DF")])
22270
22271 (define_insn "cvtpd2dq"
22272 [(set (match_operand:V4SI 0 "register_operand" "=x")
22273 (vec_concat:V4SI
22274 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22275 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22276 "TARGET_SSE2"
22277 "cvtpd2dq\t{%1, %0|%0, %1}"
22278 [(set_attr "type" "ssecvt")
22279 (set_attr "mode" "TI")])
22280
22281 (define_insn "cvttpd2dq"
22282 [(set (match_operand:V4SI 0 "register_operand" "=x")
22283 (vec_concat:V4SI
22284 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22285 UNSPEC_FIX)
22286 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22287 "TARGET_SSE2"
22288 "cvttpd2dq\t{%1, %0|%0, %1}"
22289 [(set_attr "type" "ssecvt")
22290 (set_attr "mode" "TI")])
22291
22292 (define_insn "cvtpd2pi"
22293 [(set (match_operand:V2SI 0 "register_operand" "=y")
22294 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22295 "TARGET_SSE2"
22296 "cvtpd2pi\t{%1, %0|%0, %1}"
22297 [(set_attr "type" "ssecvt")
22298 (set_attr "mode" "TI")])
22299
22300 (define_insn "cvttpd2pi"
22301 [(set (match_operand:V2SI 0 "register_operand" "=y")
22302 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22303 UNSPEC_FIX))]
22304 "TARGET_SSE2"
22305 "cvttpd2pi\t{%1, %0|%0, %1}"
22306 [(set_attr "type" "ssecvt")
22307 (set_attr "mode" "TI")])
22308
22309 (define_insn "cvtpi2pd"
22310 [(set (match_operand:V2DF 0 "register_operand" "=x")
22311 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22312 "TARGET_SSE2"
22313 "cvtpi2pd\t{%1, %0|%0, %1}"
22314 [(set_attr "type" "ssecvt")
22315 (set_attr "mode" "TI")])
22316
22317 ;; Conversions between SI and DF
22318
22319 (define_insn "cvtsd2si"
22320 [(set (match_operand:SI 0 "register_operand" "=r,r")
22321 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22322 (parallel [(const_int 0)]))))]
22323 "TARGET_SSE2"
22324 "cvtsd2si\t{%1, %0|%0, %1}"
22325 [(set_attr "type" "sseicvt")
22326 (set_attr "athlon_decode" "double,vector")
22327 (set_attr "mode" "SI")])
22328
22329 (define_insn "cvtsd2siq"
22330 [(set (match_operand:DI 0 "register_operand" "=r,r")
22331 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22332 (parallel [(const_int 0)]))))]
22333 "TARGET_SSE2 && TARGET_64BIT"
22334 "cvtsd2siq\t{%1, %0|%0, %1}"
22335 [(set_attr "type" "sseicvt")
22336 (set_attr "athlon_decode" "double,vector")
22337 (set_attr "mode" "DI")])
22338
22339 (define_insn "cvttsd2si"
22340 [(set (match_operand:SI 0 "register_operand" "=r,r")
22341 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22342 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22343 "TARGET_SSE2"
22344 "cvttsd2si\t{%1, %0|%0, %1}"
22345 [(set_attr "type" "sseicvt")
22346 (set_attr "mode" "SI")
22347 (set_attr "athlon_decode" "double,vector")])
22348
22349 (define_insn "cvttsd2siq"
22350 [(set (match_operand:DI 0 "register_operand" "=r,r")
22351 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22352 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22353 "TARGET_SSE2 && TARGET_64BIT"
22354 "cvttsd2siq\t{%1, %0|%0, %1}"
22355 [(set_attr "type" "sseicvt")
22356 (set_attr "mode" "DI")
22357 (set_attr "athlon_decode" "double,vector")])
22358
22359 (define_insn "cvtsi2sd"
22360 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22361 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22362 (vec_duplicate:V2DF
22363 (float:DF
22364 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22365 (const_int 2)))]
22366 "TARGET_SSE2"
22367 "cvtsi2sd\t{%2, %0|%0, %2}"
22368 [(set_attr "type" "sseicvt")
22369 (set_attr "mode" "DF")
22370 (set_attr "athlon_decode" "double,direct")])
22371
22372 (define_insn "cvtsi2sdq"
22373 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22374 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22375 (vec_duplicate:V2DF
22376 (float:DF
22377 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22378 (const_int 2)))]
22379 "TARGET_SSE2 && TARGET_64BIT"
22380 "cvtsi2sdq\t{%2, %0|%0, %2}"
22381 [(set_attr "type" "sseicvt")
22382 (set_attr "mode" "DF")
22383 (set_attr "athlon_decode" "double,direct")])
22384
22385 ;; Conversions between SF and DF
22386
22387 (define_insn "cvtsd2ss"
22388 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22389 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22390 (vec_duplicate:V4SF
22391 (float_truncate:V2SF
22392 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22393 (const_int 14)))]
22394 "TARGET_SSE2"
22395 "cvtsd2ss\t{%2, %0|%0, %2}"
22396 [(set_attr "type" "ssecvt")
22397 (set_attr "athlon_decode" "vector,double")
22398 (set_attr "mode" "SF")])
22399
22400 (define_insn "cvtss2sd"
22401 [(set (match_operand:V2DF 0 "register_operand" "=x")
22402 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22403 (float_extend:V2DF
22404 (vec_select:V2SF
22405 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22406 (parallel [(const_int 0)
22407 (const_int 1)])))
22408 (const_int 2)))]
22409 "TARGET_SSE2"
22410 "cvtss2sd\t{%2, %0|%0, %2}"
22411 [(set_attr "type" "ssecvt")
22412 (set_attr "mode" "DF")])
22413
22414 (define_insn "cvtpd2ps"
22415 [(set (match_operand:V4SF 0 "register_operand" "=x")
22416 (subreg:V4SF
22417 (vec_concat:V4SI
22418 (subreg:V2SI (float_truncate:V2SF
22419 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22420 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22421 "TARGET_SSE2"
22422 "cvtpd2ps\t{%1, %0|%0, %1}"
22423 [(set_attr "type" "ssecvt")
22424 (set_attr "mode" "V4SF")])
22425
22426 (define_insn "cvtps2pd"
22427 [(set (match_operand:V2DF 0 "register_operand" "=x")
22428 (float_extend:V2DF
22429 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22430 (parallel [(const_int 0)
22431 (const_int 1)]))))]
22432 "TARGET_SSE2"
22433 "cvtps2pd\t{%1, %0|%0, %1}"
22434 [(set_attr "type" "ssecvt")
22435 (set_attr "mode" "V2DF")])
22436
22437 ;; SSE2 variants of MMX insns
22438
22439 ;; MMX arithmetic
22440
22441 (define_insn "addv16qi3"
22442 [(set (match_operand:V16QI 0 "register_operand" "=x")
22443 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22444 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22445 "TARGET_SSE2"
22446 "paddb\t{%2, %0|%0, %2}"
22447 [(set_attr "type" "sseiadd")
22448 (set_attr "mode" "TI")])
22449
22450 (define_insn "addv8hi3"
22451 [(set (match_operand:V8HI 0 "register_operand" "=x")
22452 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22453 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22454 "TARGET_SSE2"
22455 "paddw\t{%2, %0|%0, %2}"
22456 [(set_attr "type" "sseiadd")
22457 (set_attr "mode" "TI")])
22458
22459 (define_insn "addv4si3"
22460 [(set (match_operand:V4SI 0 "register_operand" "=x")
22461 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22462 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22463 "TARGET_SSE2"
22464 "paddd\t{%2, %0|%0, %2}"
22465 [(set_attr "type" "sseiadd")
22466 (set_attr "mode" "TI")])
22467
22468 (define_insn "addv2di3"
22469 [(set (match_operand:V2DI 0 "register_operand" "=x")
22470 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22471 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22472 "TARGET_SSE2"
22473 "paddq\t{%2, %0|%0, %2}"
22474 [(set_attr "type" "sseiadd")
22475 (set_attr "mode" "TI")])
22476
22477 (define_insn "ssaddv16qi3"
22478 [(set (match_operand:V16QI 0 "register_operand" "=x")
22479 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22480 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22481 "TARGET_SSE2"
22482 "paddsb\t{%2, %0|%0, %2}"
22483 [(set_attr "type" "sseiadd")
22484 (set_attr "mode" "TI")])
22485
22486 (define_insn "ssaddv8hi3"
22487 [(set (match_operand:V8HI 0 "register_operand" "=x")
22488 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22489 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22490 "TARGET_SSE2"
22491 "paddsw\t{%2, %0|%0, %2}"
22492 [(set_attr "type" "sseiadd")
22493 (set_attr "mode" "TI")])
22494
22495 (define_insn "usaddv16qi3"
22496 [(set (match_operand:V16QI 0 "register_operand" "=x")
22497 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22498 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22499 "TARGET_SSE2"
22500 "paddusb\t{%2, %0|%0, %2}"
22501 [(set_attr "type" "sseiadd")
22502 (set_attr "mode" "TI")])
22503
22504 (define_insn "usaddv8hi3"
22505 [(set (match_operand:V8HI 0 "register_operand" "=x")
22506 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22507 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22508 "TARGET_SSE2"
22509 "paddusw\t{%2, %0|%0, %2}"
22510 [(set_attr "type" "sseiadd")
22511 (set_attr "mode" "TI")])
22512
22513 (define_insn "subv16qi3"
22514 [(set (match_operand:V16QI 0 "register_operand" "=x")
22515 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22516 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22517 "TARGET_SSE2"
22518 "psubb\t{%2, %0|%0, %2}"
22519 [(set_attr "type" "sseiadd")
22520 (set_attr "mode" "TI")])
22521
22522 (define_insn "subv8hi3"
22523 [(set (match_operand:V8HI 0 "register_operand" "=x")
22524 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22525 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22526 "TARGET_SSE2"
22527 "psubw\t{%2, %0|%0, %2}"
22528 [(set_attr "type" "sseiadd")
22529 (set_attr "mode" "TI")])
22530
22531 (define_insn "subv4si3"
22532 [(set (match_operand:V4SI 0 "register_operand" "=x")
22533 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22534 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22535 "TARGET_SSE2"
22536 "psubd\t{%2, %0|%0, %2}"
22537 [(set_attr "type" "sseiadd")
22538 (set_attr "mode" "TI")])
22539
22540 (define_insn "subv2di3"
22541 [(set (match_operand:V2DI 0 "register_operand" "=x")
22542 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22543 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22544 "TARGET_SSE2"
22545 "psubq\t{%2, %0|%0, %2}"
22546 [(set_attr "type" "sseiadd")
22547 (set_attr "mode" "TI")])
22548
22549 (define_insn "sssubv16qi3"
22550 [(set (match_operand:V16QI 0 "register_operand" "=x")
22551 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22552 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22553 "TARGET_SSE2"
22554 "psubsb\t{%2, %0|%0, %2}"
22555 [(set_attr "type" "sseiadd")
22556 (set_attr "mode" "TI")])
22557
22558 (define_insn "sssubv8hi3"
22559 [(set (match_operand:V8HI 0 "register_operand" "=x")
22560 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22561 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22562 "TARGET_SSE2"
22563 "psubsw\t{%2, %0|%0, %2}"
22564 [(set_attr "type" "sseiadd")
22565 (set_attr "mode" "TI")])
22566
22567 (define_insn "ussubv16qi3"
22568 [(set (match_operand:V16QI 0 "register_operand" "=x")
22569 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22570 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22571 "TARGET_SSE2"
22572 "psubusb\t{%2, %0|%0, %2}"
22573 [(set_attr "type" "sseiadd")
22574 (set_attr "mode" "TI")])
22575
22576 (define_insn "ussubv8hi3"
22577 [(set (match_operand:V8HI 0 "register_operand" "=x")
22578 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22579 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22580 "TARGET_SSE2"
22581 "psubusw\t{%2, %0|%0, %2}"
22582 [(set_attr "type" "sseiadd")
22583 (set_attr "mode" "TI")])
22584
22585 (define_insn "mulv8hi3"
22586 [(set (match_operand:V8HI 0 "register_operand" "=x")
22587 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22588 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22589 "TARGET_SSE2"
22590 "pmullw\t{%2, %0|%0, %2}"
22591 [(set_attr "type" "sseimul")
22592 (set_attr "mode" "TI")])
22593
22594 (define_insn "smulv8hi3_highpart"
22595 [(set (match_operand:V8HI 0 "register_operand" "=x")
22596 (truncate:V8HI
22597 (lshiftrt:V8SI
22598 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22599 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22600 (const_int 16))))]
22601 "TARGET_SSE2"
22602 "pmulhw\t{%2, %0|%0, %2}"
22603 [(set_attr "type" "sseimul")
22604 (set_attr "mode" "TI")])
22605
22606 (define_insn "umulv8hi3_highpart"
22607 [(set (match_operand:V8HI 0 "register_operand" "=x")
22608 (truncate:V8HI
22609 (lshiftrt:V8SI
22610 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22611 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22612 (const_int 16))))]
22613 "TARGET_SSE2"
22614 "pmulhuw\t{%2, %0|%0, %2}"
22615 [(set_attr "type" "sseimul")
22616 (set_attr "mode" "TI")])
22617
22618 (define_insn "sse2_umulsidi3"
22619 [(set (match_operand:DI 0 "register_operand" "=y")
22620 (mult:DI (zero_extend:DI (vec_select:SI
22621 (match_operand:V2SI 1 "register_operand" "0")
22622 (parallel [(const_int 0)])))
22623 (zero_extend:DI (vec_select:SI
22624 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22625 (parallel [(const_int 0)])))))]
22626 "TARGET_SSE2"
22627 "pmuludq\t{%2, %0|%0, %2}"
22628 [(set_attr "type" "sseimul")
22629 (set_attr "mode" "TI")])
22630
22631 (define_insn "sse2_umulv2siv2di3"
22632 [(set (match_operand:V2DI 0 "register_operand" "=x")
22633 (mult:V2DI (zero_extend:V2DI
22634 (vec_select:V2SI
22635 (match_operand:V4SI 1 "register_operand" "0")
22636 (parallel [(const_int 0) (const_int 2)])))
22637 (zero_extend:V2DI
22638 (vec_select:V2SI
22639 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22640 (parallel [(const_int 0) (const_int 2)])))))]
22641 "TARGET_SSE2"
22642 "pmuludq\t{%2, %0|%0, %2}"
22643 [(set_attr "type" "sseimul")
22644 (set_attr "mode" "TI")])
22645
22646 (define_insn "sse2_pmaddwd"
22647 [(set (match_operand:V4SI 0 "register_operand" "=x")
22648 (plus:V4SI
22649 (mult:V4SI
22650 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22651 (parallel [(const_int 0)
22652 (const_int 2)
22653 (const_int 4)
22654 (const_int 6)])))
22655 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22656 (parallel [(const_int 0)
22657 (const_int 2)
22658 (const_int 4)
22659 (const_int 6)]))))
22660 (mult:V4SI
22661 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22662 (parallel [(const_int 1)
22663 (const_int 3)
22664 (const_int 5)
22665 (const_int 7)])))
22666 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22667 (parallel [(const_int 1)
22668 (const_int 3)
22669 (const_int 5)
22670 (const_int 7)]))))))]
22671 "TARGET_SSE2"
22672 "pmaddwd\t{%2, %0|%0, %2}"
22673 [(set_attr "type" "sseiadd")
22674 (set_attr "mode" "TI")])
22675
22676 ;; Same as pxor, but don't show input operands so that we don't think
22677 ;; they are live.
22678 (define_insn "sse2_clrti"
22679 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22680 "TARGET_SSE2"
22681 {
22682 if (get_attr_mode (insn) == MODE_TI)
22683 return "pxor\t%0, %0";
22684 else
22685 return "xorps\t%0, %0";
22686 }
22687 [(set_attr "type" "ssemov")
22688 (set_attr "memory" "none")
22689 (set (attr "mode")
22690 (if_then_else
22691 (ne (symbol_ref "optimize_size")
22692 (const_int 0))
22693 (const_string "V4SF")
22694 (const_string "TI")))])
22695
22696 ;; MMX unsigned averages/sum of absolute differences
22697
22698 (define_insn "sse2_uavgv16qi3"
22699 [(set (match_operand:V16QI 0 "register_operand" "=x")
22700 (ashiftrt:V16QI
22701 (plus:V16QI (plus:V16QI
22702 (match_operand:V16QI 1 "register_operand" "0")
22703 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22704 (const_vector:V16QI [(const_int 1) (const_int 1)
22705 (const_int 1) (const_int 1)
22706 (const_int 1) (const_int 1)
22707 (const_int 1) (const_int 1)
22708 (const_int 1) (const_int 1)
22709 (const_int 1) (const_int 1)
22710 (const_int 1) (const_int 1)
22711 (const_int 1) (const_int 1)]))
22712 (const_int 1)))]
22713 "TARGET_SSE2"
22714 "pavgb\t{%2, %0|%0, %2}"
22715 [(set_attr "type" "sseiadd")
22716 (set_attr "mode" "TI")])
22717
22718 (define_insn "sse2_uavgv8hi3"
22719 [(set (match_operand:V8HI 0 "register_operand" "=x")
22720 (ashiftrt:V8HI
22721 (plus:V8HI (plus:V8HI
22722 (match_operand:V8HI 1 "register_operand" "0")
22723 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22724 (const_vector:V8HI [(const_int 1) (const_int 1)
22725 (const_int 1) (const_int 1)
22726 (const_int 1) (const_int 1)
22727 (const_int 1) (const_int 1)]))
22728 (const_int 1)))]
22729 "TARGET_SSE2"
22730 "pavgw\t{%2, %0|%0, %2}"
22731 [(set_attr "type" "sseiadd")
22732 (set_attr "mode" "TI")])
22733
22734 ;; @@@ this isn't the right representation.
22735 (define_insn "sse2_psadbw"
22736 [(set (match_operand:V2DI 0 "register_operand" "=x")
22737 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22738 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22739 UNSPEC_PSADBW))]
22740 "TARGET_SSE2"
22741 "psadbw\t{%2, %0|%0, %2}"
22742 [(set_attr "type" "sseiadd")
22743 (set_attr "mode" "TI")])
22744
22745
22746 ;; MMX insert/extract/shuffle
22747
22748 (define_insn "sse2_pinsrw"
22749 [(set (match_operand:V8HI 0 "register_operand" "=x")
22750 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22751 (vec_duplicate:V8HI
22752 (truncate:HI
22753 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22754 (match_operand:SI 3 "immediate_operand" "i")))]
22755 "TARGET_SSE2"
22756 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22757 [(set_attr "type" "ssecvt")
22758 (set_attr "mode" "TI")])
22759
22760 (define_insn "sse2_pextrw"
22761 [(set (match_operand:SI 0 "register_operand" "=r")
22762 (zero_extend:SI
22763 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22764 (parallel
22765 [(match_operand:SI 2 "immediate_operand" "i")]))))]
22766 "TARGET_SSE2"
22767 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22768 [(set_attr "type" "ssecvt")
22769 (set_attr "mode" "TI")])
22770
22771 (define_insn "sse2_pshufd"
22772 [(set (match_operand:V4SI 0 "register_operand" "=x")
22773 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22774 (match_operand:SI 2 "immediate_operand" "i")]
22775 UNSPEC_SHUFFLE))]
22776 "TARGET_SSE2"
22777 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22778 [(set_attr "type" "ssecvt")
22779 (set_attr "mode" "TI")])
22780
22781 (define_insn "sse2_pshuflw"
22782 [(set (match_operand:V8HI 0 "register_operand" "=x")
22783 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22784 (match_operand:SI 2 "immediate_operand" "i")]
22785 UNSPEC_PSHUFLW))]
22786 "TARGET_SSE2"
22787 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22788 [(set_attr "type" "ssecvt")
22789 (set_attr "mode" "TI")])
22790
22791 (define_insn "sse2_pshufhw"
22792 [(set (match_operand:V8HI 0 "register_operand" "=x")
22793 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22794 (match_operand:SI 2 "immediate_operand" "i")]
22795 UNSPEC_PSHUFHW))]
22796 "TARGET_SSE2"
22797 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22798 [(set_attr "type" "ssecvt")
22799 (set_attr "mode" "TI")])
22800
22801 ;; MMX mask-generating comparisons
22802
22803 (define_insn "eqv16qi3"
22804 [(set (match_operand:V16QI 0 "register_operand" "=x")
22805 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22806 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22807 "TARGET_SSE2"
22808 "pcmpeqb\t{%2, %0|%0, %2}"
22809 [(set_attr "type" "ssecmp")
22810 (set_attr "mode" "TI")])
22811
22812 (define_insn "eqv8hi3"
22813 [(set (match_operand:V8HI 0 "register_operand" "=x")
22814 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22815 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22816 "TARGET_SSE2"
22817 "pcmpeqw\t{%2, %0|%0, %2}"
22818 [(set_attr "type" "ssecmp")
22819 (set_attr "mode" "TI")])
22820
22821 (define_insn "eqv4si3"
22822 [(set (match_operand:V4SI 0 "register_operand" "=x")
22823 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22824 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22825 "TARGET_SSE2"
22826 "pcmpeqd\t{%2, %0|%0, %2}"
22827 [(set_attr "type" "ssecmp")
22828 (set_attr "mode" "TI")])
22829
22830 (define_insn "gtv16qi3"
22831 [(set (match_operand:V16QI 0 "register_operand" "=x")
22832 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22833 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22834 "TARGET_SSE2"
22835 "pcmpgtb\t{%2, %0|%0, %2}"
22836 [(set_attr "type" "ssecmp")
22837 (set_attr "mode" "TI")])
22838
22839 (define_insn "gtv8hi3"
22840 [(set (match_operand:V8HI 0 "register_operand" "=x")
22841 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22842 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22843 "TARGET_SSE2"
22844 "pcmpgtw\t{%2, %0|%0, %2}"
22845 [(set_attr "type" "ssecmp")
22846 (set_attr "mode" "TI")])
22847
22848 (define_insn "gtv4si3"
22849 [(set (match_operand:V4SI 0 "register_operand" "=x")
22850 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22851 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22852 "TARGET_SSE2"
22853 "pcmpgtd\t{%2, %0|%0, %2}"
22854 [(set_attr "type" "ssecmp")
22855 (set_attr "mode" "TI")])
22856
22857
22858 ;; MMX max/min insns
22859
22860 (define_insn "umaxv16qi3"
22861 [(set (match_operand:V16QI 0 "register_operand" "=x")
22862 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22863 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22864 "TARGET_SSE2"
22865 "pmaxub\t{%2, %0|%0, %2}"
22866 [(set_attr "type" "sseiadd")
22867 (set_attr "mode" "TI")])
22868
22869 (define_insn "smaxv8hi3"
22870 [(set (match_operand:V8HI 0 "register_operand" "=x")
22871 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22872 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22873 "TARGET_SSE2"
22874 "pmaxsw\t{%2, %0|%0, %2}"
22875 [(set_attr "type" "sseiadd")
22876 (set_attr "mode" "TI")])
22877
22878 (define_insn "uminv16qi3"
22879 [(set (match_operand:V16QI 0 "register_operand" "=x")
22880 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22881 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22882 "TARGET_SSE2"
22883 "pminub\t{%2, %0|%0, %2}"
22884 [(set_attr "type" "sseiadd")
22885 (set_attr "mode" "TI")])
22886
22887 (define_insn "sminv8hi3"
22888 [(set (match_operand:V8HI 0 "register_operand" "=x")
22889 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22890 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22891 "TARGET_SSE2"
22892 "pminsw\t{%2, %0|%0, %2}"
22893 [(set_attr "type" "sseiadd")
22894 (set_attr "mode" "TI")])
22895
22896
22897 ;; MMX shifts
22898
22899 (define_insn "ashrv8hi3"
22900 [(set (match_operand:V8HI 0 "register_operand" "=x")
22901 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22902 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22903 "TARGET_SSE2"
22904 "psraw\t{%2, %0|%0, %2}"
22905 [(set_attr "type" "sseishft")
22906 (set_attr "mode" "TI")])
22907
22908 (define_insn "ashrv4si3"
22909 [(set (match_operand:V4SI 0 "register_operand" "=x")
22910 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22911 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22912 "TARGET_SSE2"
22913 "psrad\t{%2, %0|%0, %2}"
22914 [(set_attr "type" "sseishft")
22915 (set_attr "mode" "TI")])
22916
22917 (define_insn "lshrv8hi3"
22918 [(set (match_operand:V8HI 0 "register_operand" "=x")
22919 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22920 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22921 "TARGET_SSE2"
22922 "psrlw\t{%2, %0|%0, %2}"
22923 [(set_attr "type" "sseishft")
22924 (set_attr "mode" "TI")])
22925
22926 (define_insn "lshrv4si3"
22927 [(set (match_operand:V4SI 0 "register_operand" "=x")
22928 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22929 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22930 "TARGET_SSE2"
22931 "psrld\t{%2, %0|%0, %2}"
22932 [(set_attr "type" "sseishft")
22933 (set_attr "mode" "TI")])
22934
22935 (define_insn "lshrv2di3"
22936 [(set (match_operand:V2DI 0 "register_operand" "=x")
22937 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22938 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22939 "TARGET_SSE2"
22940 "psrlq\t{%2, %0|%0, %2}"
22941 [(set_attr "type" "sseishft")
22942 (set_attr "mode" "TI")])
22943
22944 (define_insn "ashlv8hi3"
22945 [(set (match_operand:V8HI 0 "register_operand" "=x")
22946 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22947 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22948 "TARGET_SSE2"
22949 "psllw\t{%2, %0|%0, %2}"
22950 [(set_attr "type" "sseishft")
22951 (set_attr "mode" "TI")])
22952
22953 (define_insn "ashlv4si3"
22954 [(set (match_operand:V4SI 0 "register_operand" "=x")
22955 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22956 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22957 "TARGET_SSE2"
22958 "pslld\t{%2, %0|%0, %2}"
22959 [(set_attr "type" "sseishft")
22960 (set_attr "mode" "TI")])
22961
22962 (define_insn "ashlv2di3"
22963 [(set (match_operand:V2DI 0 "register_operand" "=x")
22964 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22965 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22966 "TARGET_SSE2"
22967 "psllq\t{%2, %0|%0, %2}"
22968 [(set_attr "type" "sseishft")
22969 (set_attr "mode" "TI")])
22970
22971 (define_insn "ashrv8hi3_ti"
22972 [(set (match_operand:V8HI 0 "register_operand" "=x")
22973 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22974 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22975 "TARGET_SSE2"
22976 "psraw\t{%2, %0|%0, %2}"
22977 [(set_attr "type" "sseishft")
22978 (set_attr "mode" "TI")])
22979
22980 (define_insn "ashrv4si3_ti"
22981 [(set (match_operand:V4SI 0 "register_operand" "=x")
22982 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22983 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22984 "TARGET_SSE2"
22985 "psrad\t{%2, %0|%0, %2}"
22986 [(set_attr "type" "sseishft")
22987 (set_attr "mode" "TI")])
22988
22989 (define_insn "lshrv8hi3_ti"
22990 [(set (match_operand:V8HI 0 "register_operand" "=x")
22991 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22992 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22993 "TARGET_SSE2"
22994 "psrlw\t{%2, %0|%0, %2}"
22995 [(set_attr "type" "sseishft")
22996 (set_attr "mode" "TI")])
22997
22998 (define_insn "lshrv4si3_ti"
22999 [(set (match_operand:V4SI 0 "register_operand" "=x")
23000 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23001 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23002 "TARGET_SSE2"
23003 "psrld\t{%2, %0|%0, %2}"
23004 [(set_attr "type" "sseishft")
23005 (set_attr "mode" "TI")])
23006
23007 (define_insn "lshrv2di3_ti"
23008 [(set (match_operand:V2DI 0 "register_operand" "=x")
23009 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23010 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23011 "TARGET_SSE2"
23012 "psrlq\t{%2, %0|%0, %2}"
23013 [(set_attr "type" "sseishft")
23014 (set_attr "mode" "TI")])
23015
23016 (define_insn "ashlv8hi3_ti"
23017 [(set (match_operand:V8HI 0 "register_operand" "=x")
23018 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23019 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23020 "TARGET_SSE2"
23021 "psllw\t{%2, %0|%0, %2}"
23022 [(set_attr "type" "sseishft")
23023 (set_attr "mode" "TI")])
23024
23025 (define_insn "ashlv4si3_ti"
23026 [(set (match_operand:V4SI 0 "register_operand" "=x")
23027 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23028 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23029 "TARGET_SSE2"
23030 "pslld\t{%2, %0|%0, %2}"
23031 [(set_attr "type" "sseishft")
23032 (set_attr "mode" "TI")])
23033
23034 (define_insn "ashlv2di3_ti"
23035 [(set (match_operand:V2DI 0 "register_operand" "=x")
23036 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23037 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23038 "TARGET_SSE2"
23039 "psllq\t{%2, %0|%0, %2}"
23040 [(set_attr "type" "sseishft")
23041 (set_attr "mode" "TI")])
23042
23043 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23044 ;; we wouldn't need here it since we never generate TImode arithmetic.
23045
23046 ;; There has to be some kind of prize for the weirdest new instruction...
23047 (define_insn "sse2_ashlti3"
23048 [(set (match_operand:TI 0 "register_operand" "=x")
23049 (unspec:TI
23050 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23051 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23052 (const_int 8)))] UNSPEC_NOP))]
23053 "TARGET_SSE2"
23054 "pslldq\t{%2, %0|%0, %2}"
23055 [(set_attr "type" "sseishft")
23056 (set_attr "mode" "TI")])
23057
23058 (define_insn "sse2_lshrti3"
23059 [(set (match_operand:TI 0 "register_operand" "=x")
23060 (unspec:TI
23061 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23062 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23063 (const_int 8)))] UNSPEC_NOP))]
23064 "TARGET_SSE2"
23065 "psrldq\t{%2, %0|%0, %2}"
23066 [(set_attr "type" "sseishft")
23067 (set_attr "mode" "TI")])
23068
23069 ;; SSE unpack
23070
23071 (define_insn "sse2_unpckhpd"
23072 [(set (match_operand:V2DF 0 "register_operand" "=x")
23073 (vec_concat:V2DF
23074 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23075 (parallel [(const_int 1)]))
23076 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23077 (parallel [(const_int 0)]))))]
23078 "TARGET_SSE2"
23079 "unpckhpd\t{%2, %0|%0, %2}"
23080 [(set_attr "type" "ssecvt")
23081 (set_attr "mode" "TI")])
23082
23083 (define_insn "sse2_unpcklpd"
23084 [(set (match_operand:V2DF 0 "register_operand" "=x")
23085 (vec_concat:V2DF
23086 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23087 (parallel [(const_int 0)]))
23088 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23089 (parallel [(const_int 1)]))))]
23090 "TARGET_SSE2"
23091 "unpcklpd\t{%2, %0|%0, %2}"
23092 [(set_attr "type" "ssecvt")
23093 (set_attr "mode" "TI")])
23094
23095 ;; MMX pack/unpack insns.
23096
23097 (define_insn "sse2_packsswb"
23098 [(set (match_operand:V16QI 0 "register_operand" "=x")
23099 (vec_concat:V16QI
23100 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23101 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23102 "TARGET_SSE2"
23103 "packsswb\t{%2, %0|%0, %2}"
23104 [(set_attr "type" "ssecvt")
23105 (set_attr "mode" "TI")])
23106
23107 (define_insn "sse2_packssdw"
23108 [(set (match_operand:V8HI 0 "register_operand" "=x")
23109 (vec_concat:V8HI
23110 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23111 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23112 "TARGET_SSE2"
23113 "packssdw\t{%2, %0|%0, %2}"
23114 [(set_attr "type" "ssecvt")
23115 (set_attr "mode" "TI")])
23116
23117 (define_insn "sse2_packuswb"
23118 [(set (match_operand:V16QI 0 "register_operand" "=x")
23119 (vec_concat:V16QI
23120 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23121 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23122 "TARGET_SSE2"
23123 "packuswb\t{%2, %0|%0, %2}"
23124 [(set_attr "type" "ssecvt")
23125 (set_attr "mode" "TI")])
23126
23127 (define_insn "sse2_punpckhbw"
23128 [(set (match_operand:V16QI 0 "register_operand" "=x")
23129 (vec_merge:V16QI
23130 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23131 (parallel [(const_int 8) (const_int 0)
23132 (const_int 9) (const_int 1)
23133 (const_int 10) (const_int 2)
23134 (const_int 11) (const_int 3)
23135 (const_int 12) (const_int 4)
23136 (const_int 13) (const_int 5)
23137 (const_int 14) (const_int 6)
23138 (const_int 15) (const_int 7)]))
23139 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23140 (parallel [(const_int 0) (const_int 8)
23141 (const_int 1) (const_int 9)
23142 (const_int 2) (const_int 10)
23143 (const_int 3) (const_int 11)
23144 (const_int 4) (const_int 12)
23145 (const_int 5) (const_int 13)
23146 (const_int 6) (const_int 14)
23147 (const_int 7) (const_int 15)]))
23148 (const_int 21845)))]
23149 "TARGET_SSE2"
23150 "punpckhbw\t{%2, %0|%0, %2}"
23151 [(set_attr "type" "ssecvt")
23152 (set_attr "mode" "TI")])
23153
23154 (define_insn "sse2_punpckhwd"
23155 [(set (match_operand:V8HI 0 "register_operand" "=x")
23156 (vec_merge:V8HI
23157 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23158 (parallel [(const_int 4) (const_int 0)
23159 (const_int 5) (const_int 1)
23160 (const_int 6) (const_int 2)
23161 (const_int 7) (const_int 3)]))
23162 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23163 (parallel [(const_int 0) (const_int 4)
23164 (const_int 1) (const_int 5)
23165 (const_int 2) (const_int 6)
23166 (const_int 3) (const_int 7)]))
23167 (const_int 85)))]
23168 "TARGET_SSE2"
23169 "punpckhwd\t{%2, %0|%0, %2}"
23170 [(set_attr "type" "ssecvt")
23171 (set_attr "mode" "TI")])
23172
23173 (define_insn "sse2_punpckhdq"
23174 [(set (match_operand:V4SI 0 "register_operand" "=x")
23175 (vec_merge:V4SI
23176 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23177 (parallel [(const_int 2) (const_int 0)
23178 (const_int 3) (const_int 1)]))
23179 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23180 (parallel [(const_int 0) (const_int 2)
23181 (const_int 1) (const_int 3)]))
23182 (const_int 5)))]
23183 "TARGET_SSE2"
23184 "punpckhdq\t{%2, %0|%0, %2}"
23185 [(set_attr "type" "ssecvt")
23186 (set_attr "mode" "TI")])
23187
23188 (define_insn "sse2_punpcklbw"
23189 [(set (match_operand:V16QI 0 "register_operand" "=x")
23190 (vec_merge:V16QI
23191 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23192 (parallel [(const_int 0) (const_int 8)
23193 (const_int 1) (const_int 9)
23194 (const_int 2) (const_int 10)
23195 (const_int 3) (const_int 11)
23196 (const_int 4) (const_int 12)
23197 (const_int 5) (const_int 13)
23198 (const_int 6) (const_int 14)
23199 (const_int 7) (const_int 15)]))
23200 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23201 (parallel [(const_int 8) (const_int 0)
23202 (const_int 9) (const_int 1)
23203 (const_int 10) (const_int 2)
23204 (const_int 11) (const_int 3)
23205 (const_int 12) (const_int 4)
23206 (const_int 13) (const_int 5)
23207 (const_int 14) (const_int 6)
23208 (const_int 15) (const_int 7)]))
23209 (const_int 21845)))]
23210 "TARGET_SSE2"
23211 "punpcklbw\t{%2, %0|%0, %2}"
23212 [(set_attr "type" "ssecvt")
23213 (set_attr "mode" "TI")])
23214
23215 (define_insn "sse2_punpcklwd"
23216 [(set (match_operand:V8HI 0 "register_operand" "=x")
23217 (vec_merge:V8HI
23218 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23219 (parallel [(const_int 0) (const_int 4)
23220 (const_int 1) (const_int 5)
23221 (const_int 2) (const_int 6)
23222 (const_int 3) (const_int 7)]))
23223 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23224 (parallel [(const_int 4) (const_int 0)
23225 (const_int 5) (const_int 1)
23226 (const_int 6) (const_int 2)
23227 (const_int 7) (const_int 3)]))
23228 (const_int 85)))]
23229 "TARGET_SSE2"
23230 "punpcklwd\t{%2, %0|%0, %2}"
23231 [(set_attr "type" "ssecvt")
23232 (set_attr "mode" "TI")])
23233
23234 (define_insn "sse2_punpckldq"
23235 [(set (match_operand:V4SI 0 "register_operand" "=x")
23236 (vec_merge:V4SI
23237 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23238 (parallel [(const_int 0) (const_int 2)
23239 (const_int 1) (const_int 3)]))
23240 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23241 (parallel [(const_int 2) (const_int 0)
23242 (const_int 3) (const_int 1)]))
23243 (const_int 5)))]
23244 "TARGET_SSE2"
23245 "punpckldq\t{%2, %0|%0, %2}"
23246 [(set_attr "type" "ssecvt")
23247 (set_attr "mode" "TI")])
23248
23249 (define_insn "sse2_punpcklqdq"
23250 [(set (match_operand:V2DI 0 "register_operand" "=x")
23251 (vec_merge:V2DI
23252 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23253 (parallel [(const_int 1)
23254 (const_int 0)]))
23255 (match_operand:V2DI 1 "register_operand" "0")
23256 (const_int 1)))]
23257 "TARGET_SSE2"
23258 "punpcklqdq\t{%2, %0|%0, %2}"
23259 [(set_attr "type" "ssecvt")
23260 (set_attr "mode" "TI")])
23261
23262 (define_insn "sse2_punpckhqdq"
23263 [(set (match_operand:V2DI 0 "register_operand" "=x")
23264 (vec_merge:V2DI
23265 (match_operand:V2DI 1 "register_operand" "0")
23266 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23267 (parallel [(const_int 1)
23268 (const_int 0)]))
23269 (const_int 1)))]
23270 "TARGET_SSE2"
23271 "punpckhqdq\t{%2, %0|%0, %2}"
23272 [(set_attr "type" "ssecvt")
23273 (set_attr "mode" "TI")])
23274
23275 ;; SSE2 moves
23276
23277 (define_insn "sse2_movapd"
23278 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23279 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23280 UNSPEC_MOVA))]
23281 "TARGET_SSE2
23282 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23283 "movapd\t{%1, %0|%0, %1}"
23284 [(set_attr "type" "ssemov")
23285 (set_attr "mode" "V2DF")])
23286
23287 (define_insn "sse2_movupd"
23288 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23289 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23290 UNSPEC_MOVU))]
23291 "TARGET_SSE2
23292 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23293 "movupd\t{%1, %0|%0, %1}"
23294 [(set_attr "type" "ssecvt")
23295 (set_attr "mode" "V2DF")])
23296
23297 (define_insn "sse2_movdqa"
23298 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23299 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23300 UNSPEC_MOVA))]
23301 "TARGET_SSE2
23302 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23303 "movdqa\t{%1, %0|%0, %1}"
23304 [(set_attr "type" "ssemov")
23305 (set_attr "mode" "TI")])
23306
23307 (define_insn "sse2_movdqu"
23308 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23309 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23310 UNSPEC_MOVU))]
23311 "TARGET_SSE2
23312 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23313 "movdqu\t{%1, %0|%0, %1}"
23314 [(set_attr "type" "ssecvt")
23315 (set_attr "mode" "TI")])
23316
23317 (define_insn "sse2_movdq2q"
23318 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23319 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23320 (parallel [(const_int 0)])))]
23321 "TARGET_SSE2 && !TARGET_64BIT"
23322 "@
23323 movq\t{%1, %0|%0, %1}
23324 movdq2q\t{%1, %0|%0, %1}"
23325 [(set_attr "type" "ssecvt")
23326 (set_attr "mode" "TI")])
23327
23328 (define_insn "sse2_movdq2q_rex64"
23329 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23330 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23331 (parallel [(const_int 0)])))]
23332 "TARGET_SSE2 && TARGET_64BIT"
23333 "@
23334 movq\t{%1, %0|%0, %1}
23335 movdq2q\t{%1, %0|%0, %1}
23336 movd\t{%1, %0|%0, %1}"
23337 [(set_attr "type" "ssecvt")
23338 (set_attr "mode" "TI")])
23339
23340 (define_insn "sse2_movq2dq"
23341 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23342 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23343 (const_int 0)))]
23344 "TARGET_SSE2 && !TARGET_64BIT"
23345 "@
23346 movq\t{%1, %0|%0, %1}
23347 movq2dq\t{%1, %0|%0, %1}"
23348 [(set_attr "type" "ssecvt,ssemov")
23349 (set_attr "mode" "TI")])
23350
23351 (define_insn "sse2_movq2dq_rex64"
23352 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23353 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23354 (const_int 0)))]
23355 "TARGET_SSE2 && TARGET_64BIT"
23356 "@
23357 movq\t{%1, %0|%0, %1}
23358 movq2dq\t{%1, %0|%0, %1}
23359 movd\t{%1, %0|%0, %1}"
23360 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23361 (set_attr "mode" "TI")])
23362
23363 (define_insn "sse2_movq"
23364 [(set (match_operand:V2DI 0 "register_operand" "=x")
23365 (vec_concat:V2DI (vec_select:DI
23366 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23367 (parallel [(const_int 0)]))
23368 (const_int 0)))]
23369 "TARGET_SSE2"
23370 "movq\t{%1, %0|%0, %1}"
23371 [(set_attr "type" "ssemov")
23372 (set_attr "mode" "TI")])
23373
23374 (define_insn "sse2_loadd"
23375 [(set (match_operand:V4SI 0 "register_operand" "=x")
23376 (vec_merge:V4SI
23377 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23378 (const_vector:V4SI [(const_int 0)
23379 (const_int 0)
23380 (const_int 0)
23381 (const_int 0)])
23382 (const_int 1)))]
23383 "TARGET_SSE2"
23384 "movd\t{%1, %0|%0, %1}"
23385 [(set_attr "type" "ssemov")
23386 (set_attr "mode" "TI")])
23387
23388 (define_insn "sse2_stored"
23389 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23390 (vec_select:SI
23391 (match_operand:V4SI 1 "register_operand" "x")
23392 (parallel [(const_int 0)])))]
23393 "TARGET_SSE2"
23394 "movd\t{%1, %0|%0, %1}"
23395 [(set_attr "type" "ssemov")
23396 (set_attr "mode" "TI")])
23397
23398 (define_insn "sse2_movhpd"
23399 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23400 (vec_merge:V2DF
23401 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23402 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23403 (const_int 2)))]
23404 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23405 "movhpd\t{%2, %0|%0, %2}"
23406 [(set_attr "type" "ssecvt")
23407 (set_attr "mode" "V2DF")])
23408
23409 (define_insn "sse2_movlpd"
23410 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23411 (vec_merge:V2DF
23412 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23413 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23414 (const_int 1)))]
23415 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23416 "movlpd\t{%2, %0|%0, %2}"
23417 [(set_attr "type" "ssecvt")
23418 (set_attr "mode" "V2DF")])
23419
23420 (define_expand "sse2_loadsd"
23421 [(match_operand:V2DF 0 "register_operand" "")
23422 (match_operand:DF 1 "memory_operand" "")]
23423 "TARGET_SSE2"
23424 {
23425 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23426 CONST0_RTX (V2DFmode)));
23427 DONE;
23428 })
23429
23430 (define_insn "sse2_loadsd_1"
23431 [(set (match_operand:V2DF 0 "register_operand" "=x")
23432 (vec_merge:V2DF
23433 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23434 (match_operand:V2DF 2 "const0_operand" "X")
23435 (const_int 1)))]
23436 "TARGET_SSE2"
23437 "movsd\t{%1, %0|%0, %1}"
23438 [(set_attr "type" "ssecvt")
23439 (set_attr "mode" "DF")])
23440
23441 (define_insn "sse2_movsd"
23442 [(set (match_operand:V2DF 0 "register_operand" "=x")
23443 (vec_merge:V2DF
23444 (match_operand:V2DF 1 "register_operand" "0")
23445 (match_operand:V2DF 2 "register_operand" "x")
23446 (const_int 1)))]
23447 "TARGET_SSE2"
23448 "movsd\t{%2, %0|%0, %2}"
23449 [(set_attr "type" "ssecvt")
23450 (set_attr "mode" "DF")])
23451
23452 (define_insn "sse2_storesd"
23453 [(set (match_operand:DF 0 "memory_operand" "=m")
23454 (vec_select:DF
23455 (match_operand:V2DF 1 "register_operand" "x")
23456 (parallel [(const_int 0)])))]
23457 "TARGET_SSE2"
23458 "movsd\t{%1, %0|%0, %1}"
23459 [(set_attr "type" "ssecvt")
23460 (set_attr "mode" "DF")])
23461
23462 (define_insn "sse2_shufpd"
23463 [(set (match_operand:V2DF 0 "register_operand" "=x")
23464 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23465 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23466 (match_operand:SI 3 "immediate_operand" "i")]
23467 UNSPEC_SHUFFLE))]
23468 "TARGET_SSE2"
23469 ;; @@@ check operand order for intel/nonintel syntax
23470 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23471 [(set_attr "type" "ssecvt")
23472 (set_attr "mode" "V2DF")])
23473
23474 (define_insn "sse2_clflush"
23475 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23476 UNSPECV_CLFLUSH)]
23477 "TARGET_SSE2"
23478 "clflush %0"
23479 [(set_attr "type" "sse")
23480 (set_attr "memory" "unknown")])
23481
23482 (define_expand "sse2_mfence"
23483 [(set (match_dup 0)
23484 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23485 "TARGET_SSE2"
23486 {
23487 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23488 MEM_VOLATILE_P (operands[0]) = 1;
23489 })
23490
23491 (define_insn "*mfence_insn"
23492 [(set (match_operand:BLK 0 "" "")
23493 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23494 "TARGET_SSE2"
23495 "mfence"
23496 [(set_attr "type" "sse")
23497 (set_attr "memory" "unknown")])
23498
23499 (define_expand "sse2_lfence"
23500 [(set (match_dup 0)
23501 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23502 "TARGET_SSE2"
23503 {
23504 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23505 MEM_VOLATILE_P (operands[0]) = 1;
23506 })
23507
23508 (define_insn "*lfence_insn"
23509 [(set (match_operand:BLK 0 "" "")
23510 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23511 "TARGET_SSE2"
23512 "lfence"
23513 [(set_attr "type" "sse")
23514 (set_attr "memory" "unknown")])