]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.md
bf938be76c6ed006995ced2e45f6dbfadce9bc9e
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_ALLOC 11)
67 (UNSPEC_SET_GOT 12)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69
70 ; TLS support
71 (UNSPEC_TP 15)
72 (UNSPEC_TLS_GD 16)
73 (UNSPEC_TLS_LD_BASE 17)
74
75 ; Other random patterns
76 (UNSPEC_SCAS 20)
77 (UNSPEC_SIN 21)
78 (UNSPEC_COS 22)
79 (UNSPEC_FNSTSW 24)
80 (UNSPEC_SAHF 25)
81 (UNSPEC_FSTCW 26)
82 (UNSPEC_ADD_CARRY 27)
83 (UNSPEC_FLDCW 28)
84
85 ; For SSE/MMX support:
86 (UNSPEC_FIX 30)
87 (UNSPEC_MASKMOV 32)
88 (UNSPEC_MOVMSK 33)
89 (UNSPEC_MOVNT 34)
90 (UNSPEC_MOVA 38)
91 (UNSPEC_MOVU 39)
92 (UNSPEC_SHUFFLE 41)
93 (UNSPEC_RCP 42)
94 (UNSPEC_RSQRT 43)
95 (UNSPEC_SFENCE 44)
96 (UNSPEC_NOP 45) ; prevents combiner cleverness
97 (UNSPEC_PAVGUSB 49)
98 (UNSPEC_PFRCP 50)
99 (UNSPEC_PFRCPIT1 51)
100 (UNSPEC_PFRCPIT2 52)
101 (UNSPEC_PFRSQRT 53)
102 (UNSPEC_PFRSQIT1 54)
103 (UNSPEC_PSHUFLW 55)
104 (UNSPEC_PSHUFHW 56)
105 (UNSPEC_MFENCE 59)
106 (UNSPEC_LFENCE 60)
107 (UNSPEC_PSADBW 61)
108 (UNSPEC_ADDSUB 71)
109 (UNSPEC_HADD 72)
110 (UNSPEC_HSUB 73)
111 (UNSPEC_MOVSHDUP 74)
112 (UNSPEC_MOVSLDUP 75)
113 (UNSPEC_LDQQU 76)
114 (UNSPEC_MOVDDUP 77)
115
116 ; x87 Floating point
117 (UNSPEC_FPATAN 65)
118 (UNSPEC_FYL2X 66)
119 (UNSPEC_FYL2XP1 67)
120 (UNSPEC_FRNDINT 68)
121 (UNSPEC_F2XM1 69)
122
123 ; x87 Double output FP
124 (UNSPEC_SINCOS_COS 80)
125 (UNSPEC_SINCOS_SIN 81)
126 (UNSPEC_TAN_ONE 82)
127 (UNSPEC_TAN_TAN 83)
128 (UNSPEC_XTRACT_FRACT 84)
129 (UNSPEC_XTRACT_EXP 85)
130 (UNSPEC_FSCALE_FRACT 86)
131 (UNSPEC_FSCALE_EXP 87)
132 (UNSPEC_FPREM_F 88)
133 (UNSPEC_FPREM_U 89)
134 (UNSPEC_FPREM1_F 90)
135 (UNSPEC_FPREM1_U 91)
136
137 ; x87 Rounding
138 (UNSPEC_FRNDINT_FLOOR 96)
139 (UNSPEC_FRNDINT_CEIL 97)
140 (UNSPEC_FRNDINT_TRUNC 98)
141 (UNSPEC_FRNDINT_MASK_PM 99)
142
143 ; REP instruction
144 (UNSPEC_REP 75)
145
146 (UNSPEC_EH_RETURN 76)
147 ])
148
149 (define_constants
150 [(UNSPECV_BLOCKAGE 0)
151 (UNSPECV_STACK_PROBE 10)
152 (UNSPECV_EMMS 31)
153 (UNSPECV_LDMXCSR 37)
154 (UNSPECV_STMXCSR 40)
155 (UNSPECV_FEMMS 46)
156 (UNSPECV_CLFLUSH 57)
157 (UNSPECV_ALIGN 68)
158 (UNSPECV_MONITOR 69)
159 (UNSPECV_MWAIT 70)
160 ])
161
162 ;; Registers by name.
163 (define_constants
164 [(BP_REG 6)
165 (SP_REG 7)
166 (FLAGS_REG 17)
167 (FPSR_REG 18)
168 (DIRFLAG_REG 19)
169 ])
170
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
172 ;; from i386.c.
173
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first. This allows for better optimization. For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
178
179 \f
180 ;; Processor type. This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183 (const (symbol_ref "ix86_tune")))
184
185 ;; A basic instruction type. Refinements due to arguments to be
186 ;; provided in other attributes.
187 (define_attr "type"
188 "other,multi,
189 alu,alu1,negnot,imov,imovx,lea,
190 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191 icmp,test,ibr,setcc,icmov,
192 push,pop,call,callv,leave,
193 str,cld,
194 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195 sselog,sseiadd,sseishft,sseimul,
196 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198 (const_string "other"))
199
200 ;; Main data type used by the insn
201 (define_attr "mode"
202 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
203 (const_string "unknown"))
204
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208 (const_string "i387")
209 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
211 (const_string "sse")
212 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
213 (const_string "mmx")
214 (eq_attr "type" "other")
215 (const_string "unknown")]
216 (const_string "integer")))
217
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
221 (const_int 0)
222 (eq_attr "unit" "i387,sse,mmx")
223 (const_int 0)
224 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
225 imul,icmp,push,pop")
226 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227 (eq_attr "type" "imov,test")
228 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229 (eq_attr "type" "call")
230 (if_then_else (match_operand 0 "constant_call_address_operand" "")
231 (const_int 4)
232 (const_int 0))
233 (eq_attr "type" "callv")
234 (if_then_else (match_operand 1 "constant_call_address_operand" "")
235 (const_int 4)
236 (const_int 0))
237 ;; We don't know the size before shorten_branches. Expect
238 ;; the instruction to fit for better scheduling.
239 (eq_attr "type" "ibr")
240 (const_int 1)
241 ]
242 (symbol_ref "/* Update immediate_length and other attributes! */
243 abort(),1")))
244
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
248 (const_int 0)
249 (and (eq_attr "type" "call")
250 (match_operand 0 "constant_call_address_operand" ""))
251 (const_int 0)
252 (and (eq_attr "type" "callv")
253 (match_operand 1 "constant_call_address_operand" ""))
254 (const_int 0)
255 ]
256 (symbol_ref "ix86_attr_length_address_default (insn)")))
257
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260 (if_then_else (ior (eq_attr "mode" "HI")
261 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
262 (const_int 1)
263 (const_int 0)))
264
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" ""
267 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
268 (const_int 1)
269 (const_int 0)))
270
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
273 (if_then_else
274 (ior (eq_attr "type" "imovx,setcc,icmov")
275 (eq_attr "unit" "sse,mmx"))
276 (const_int 1)
277 (const_int 0)))
278
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281 (cond [(and (eq_attr "mode" "DI")
282 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
283 (const_int 1)
284 (and (eq_attr "mode" "QI")
285 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
286 (const_int 0)))
287 (const_int 1)
288 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
289 (const_int 0))
290 (const_int 1)
291 ]
292 (const_int 0)))
293
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296 (cond [(eq_attr "type" "str,cld,leave")
297 (const_int 0)
298 (eq_attr "unit" "i387")
299 (const_int 0)
300 (and (eq_attr "type" "incdec")
301 (ior (match_operand:SI 1 "register_operand" "")
302 (match_operand:HI 1 "register_operand" "")))
303 (const_int 0)
304 (and (eq_attr "type" "push")
305 (not (match_operand 1 "memory_operand" "")))
306 (const_int 0)
307 (and (eq_attr "type" "pop")
308 (not (match_operand 0 "memory_operand" "")))
309 (const_int 0)
310 (and (eq_attr "type" "imov")
311 (and (match_operand 0 "register_operand" "")
312 (match_operand 1 "immediate_operand" "")))
313 (const_int 0)
314 (and (eq_attr "type" "call")
315 (match_operand 0 "constant_call_address_operand" ""))
316 (const_int 0)
317 (and (eq_attr "type" "callv")
318 (match_operand 1 "constant_call_address_operand" ""))
319 (const_int 0)
320 ]
321 (const_int 1)))
322
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
326 ;; other insns.
327 (define_attr "length" ""
328 (cond [(eq_attr "type" "other,multi,fistp,frndint")
329 (const_int 16)
330 (eq_attr "type" "fcmp")
331 (const_int 4)
332 (eq_attr "unit" "i387")
333 (plus (const_int 2)
334 (plus (attr "prefix_data16")
335 (attr "length_address")))]
336 (plus (plus (attr "modrm")
337 (plus (attr "prefix_0f")
338 (plus (attr "prefix_rex")
339 (const_int 1))))
340 (plus (attr "prefix_rep")
341 (plus (attr "prefix_data16")
342 (plus (attr "length_immediate")
343 (attr "length_address")))))))
344
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
348
349 (define_attr "memory" "none,load,store,both,unknown"
350 (cond [(eq_attr "type" "other,multi,str")
351 (const_string "unknown")
352 (eq_attr "type" "lea,fcmov,fpspc,cld")
353 (const_string "none")
354 (eq_attr "type" "fistp,leave")
355 (const_string "both")
356 (eq_attr "type" "frndint")
357 (const_string "load")
358 (eq_attr "type" "push")
359 (if_then_else (match_operand 1 "memory_operand" "")
360 (const_string "both")
361 (const_string "store"))
362 (eq_attr "type" "pop")
363 (if_then_else (match_operand 0 "memory_operand" "")
364 (const_string "both")
365 (const_string "load"))
366 (eq_attr "type" "setcc")
367 (if_then_else (match_operand 0 "memory_operand" "")
368 (const_string "store")
369 (const_string "none"))
370 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371 (if_then_else (ior (match_operand 0 "memory_operand" "")
372 (match_operand 1 "memory_operand" ""))
373 (const_string "load")
374 (const_string "none"))
375 (eq_attr "type" "ibr")
376 (if_then_else (match_operand 0 "memory_operand" "")
377 (const_string "load")
378 (const_string "none"))
379 (eq_attr "type" "call")
380 (if_then_else (match_operand 0 "constant_call_address_operand" "")
381 (const_string "none")
382 (const_string "load"))
383 (eq_attr "type" "callv")
384 (if_then_else (match_operand 1 "constant_call_address_operand" "")
385 (const_string "none")
386 (const_string "load"))
387 (and (eq_attr "type" "alu1,negnot,ishift1")
388 (match_operand 1 "memory_operand" ""))
389 (const_string "both")
390 (and (match_operand 0 "memory_operand" "")
391 (match_operand 1 "memory_operand" ""))
392 (const_string "both")
393 (match_operand 0 "memory_operand" "")
394 (const_string "store")
395 (match_operand 1 "memory_operand" "")
396 (const_string "load")
397 (and (eq_attr "type"
398 "!alu1,negnot,ishift1,
399 imov,imovx,icmp,test,
400 fmov,fcmp,fsgn,
401 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402 mmx,mmxmov,mmxcmp,mmxcvt")
403 (match_operand 2 "memory_operand" ""))
404 (const_string "load")
405 (and (eq_attr "type" "icmov")
406 (match_operand 3 "memory_operand" ""))
407 (const_string "load")
408 ]
409 (const_string "none")))
410
411 ;; Indicates if an instruction has both an immediate and a displacement.
412
413 (define_attr "imm_disp" "false,true,unknown"
414 (cond [(eq_attr "type" "other,multi")
415 (const_string "unknown")
416 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417 (and (match_operand 0 "memory_displacement_operand" "")
418 (match_operand 1 "immediate_operand" "")))
419 (const_string "true")
420 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421 (and (match_operand 0 "memory_displacement_operand" "")
422 (match_operand 2 "immediate_operand" "")))
423 (const_string "true")
424 ]
425 (const_string "false")))
426
427 ;; Indicates if an FP operation has an integer source.
428
429 (define_attr "fp_int_src" "false,true"
430 (const_string "false"))
431
432 ;; Defines rounding mode of an FP operation.
433
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435 (const_string "any"))
436
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439 [(set_attr "length" "128")
440 (set_attr "type" "multi")])
441 \f
442 ;; Scheduling descriptions
443
444 (include "pentium.md")
445 (include "ppro.md")
446 (include "k6.md")
447 (include "athlon.md")
448
449 \f
450 ;; Operand and operator predicates
451
452 (include "predicates.md")
453
454 \f
455 ;; Compare instructions.
456
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
460
461 (define_expand "cmpdi"
462 [(set (reg:CC FLAGS_REG)
463 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464 (match_operand:DI 1 "x86_64_general_operand" "")))]
465 ""
466 {
467 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468 operands[0] = force_reg (DImode, operands[0]);
469 ix86_compare_op0 = operands[0];
470 ix86_compare_op1 = operands[1];
471 DONE;
472 })
473
474 (define_expand "cmpsi"
475 [(set (reg:CC FLAGS_REG)
476 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477 (match_operand:SI 1 "general_operand" "")))]
478 ""
479 {
480 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481 operands[0] = force_reg (SImode, operands[0]);
482 ix86_compare_op0 = operands[0];
483 ix86_compare_op1 = operands[1];
484 DONE;
485 })
486
487 (define_expand "cmphi"
488 [(set (reg:CC FLAGS_REG)
489 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490 (match_operand:HI 1 "general_operand" "")))]
491 ""
492 {
493 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494 operands[0] = force_reg (HImode, operands[0]);
495 ix86_compare_op0 = operands[0];
496 ix86_compare_op1 = operands[1];
497 DONE;
498 })
499
500 (define_expand "cmpqi"
501 [(set (reg:CC FLAGS_REG)
502 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503 (match_operand:QI 1 "general_operand" "")))]
504 "TARGET_QIMODE_MATH"
505 {
506 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507 operands[0] = force_reg (QImode, operands[0]);
508 ix86_compare_op0 = operands[0];
509 ix86_compare_op1 = operands[1];
510 DONE;
511 })
512
513 (define_insn "cmpdi_ccno_1_rex64"
514 [(set (reg FLAGS_REG)
515 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516 (match_operand:DI 1 "const0_operand" "n,n")))]
517 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
518 "@
519 test{q}\t{%0, %0|%0, %0}
520 cmp{q}\t{%1, %0|%0, %1}"
521 [(set_attr "type" "test,icmp")
522 (set_attr "length_immediate" "0,1")
523 (set_attr "mode" "DI")])
524
525 (define_insn "*cmpdi_minus_1_rex64"
526 [(set (reg FLAGS_REG)
527 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
529 (const_int 0)))]
530 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531 "cmp{q}\t{%1, %0|%0, %1}"
532 [(set_attr "type" "icmp")
533 (set_attr "mode" "DI")])
534
535 (define_expand "cmpdi_1_rex64"
536 [(set (reg:CC FLAGS_REG)
537 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538 (match_operand:DI 1 "general_operand" "")))]
539 "TARGET_64BIT"
540 "")
541
542 (define_insn "cmpdi_1_insn_rex64"
543 [(set (reg FLAGS_REG)
544 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547 "cmp{q}\t{%1, %0|%0, %1}"
548 [(set_attr "type" "icmp")
549 (set_attr "mode" "DI")])
550
551
552 (define_insn "*cmpsi_ccno_1"
553 [(set (reg FLAGS_REG)
554 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555 (match_operand:SI 1 "const0_operand" "n,n")))]
556 "ix86_match_ccmode (insn, CCNOmode)"
557 "@
558 test{l}\t{%0, %0|%0, %0}
559 cmp{l}\t{%1, %0|%0, %1}"
560 [(set_attr "type" "test,icmp")
561 (set_attr "length_immediate" "0,1")
562 (set_attr "mode" "SI")])
563
564 (define_insn "*cmpsi_minus_1"
565 [(set (reg FLAGS_REG)
566 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567 (match_operand:SI 1 "general_operand" "ri,mr"))
568 (const_int 0)))]
569 "ix86_match_ccmode (insn, CCGOCmode)"
570 "cmp{l}\t{%1, %0|%0, %1}"
571 [(set_attr "type" "icmp")
572 (set_attr "mode" "SI")])
573
574 (define_expand "cmpsi_1"
575 [(set (reg:CC FLAGS_REG)
576 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577 (match_operand:SI 1 "general_operand" "ri,mr")))]
578 ""
579 "")
580
581 (define_insn "*cmpsi_1_insn"
582 [(set (reg FLAGS_REG)
583 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584 (match_operand:SI 1 "general_operand" "ri,mr")))]
585 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586 && ix86_match_ccmode (insn, CCmode)"
587 "cmp{l}\t{%1, %0|%0, %1}"
588 [(set_attr "type" "icmp")
589 (set_attr "mode" "SI")])
590
591 (define_insn "*cmphi_ccno_1"
592 [(set (reg FLAGS_REG)
593 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594 (match_operand:HI 1 "const0_operand" "n,n")))]
595 "ix86_match_ccmode (insn, CCNOmode)"
596 "@
597 test{w}\t{%0, %0|%0, %0}
598 cmp{w}\t{%1, %0|%0, %1}"
599 [(set_attr "type" "test,icmp")
600 (set_attr "length_immediate" "0,1")
601 (set_attr "mode" "HI")])
602
603 (define_insn "*cmphi_minus_1"
604 [(set (reg FLAGS_REG)
605 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606 (match_operand:HI 1 "general_operand" "ri,mr"))
607 (const_int 0)))]
608 "ix86_match_ccmode (insn, CCGOCmode)"
609 "cmp{w}\t{%1, %0|%0, %1}"
610 [(set_attr "type" "icmp")
611 (set_attr "mode" "HI")])
612
613 (define_insn "*cmphi_1"
614 [(set (reg FLAGS_REG)
615 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616 (match_operand:HI 1 "general_operand" "ri,mr")))]
617 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618 && ix86_match_ccmode (insn, CCmode)"
619 "cmp{w}\t{%1, %0|%0, %1}"
620 [(set_attr "type" "icmp")
621 (set_attr "mode" "HI")])
622
623 (define_insn "*cmpqi_ccno_1"
624 [(set (reg FLAGS_REG)
625 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626 (match_operand:QI 1 "const0_operand" "n,n")))]
627 "ix86_match_ccmode (insn, CCNOmode)"
628 "@
629 test{b}\t{%0, %0|%0, %0}
630 cmp{b}\t{$0, %0|%0, 0}"
631 [(set_attr "type" "test,icmp")
632 (set_attr "length_immediate" "0,1")
633 (set_attr "mode" "QI")])
634
635 (define_insn "*cmpqi_1"
636 [(set (reg FLAGS_REG)
637 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638 (match_operand:QI 1 "general_operand" "qi,mq")))]
639 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640 && ix86_match_ccmode (insn, CCmode)"
641 "cmp{b}\t{%1, %0|%0, %1}"
642 [(set_attr "type" "icmp")
643 (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_minus_1"
646 [(set (reg FLAGS_REG)
647 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648 (match_operand:QI 1 "general_operand" "qi,mq"))
649 (const_int 0)))]
650 "ix86_match_ccmode (insn, CCGOCmode)"
651 "cmp{b}\t{%1, %0|%0, %1}"
652 [(set_attr "type" "icmp")
653 (set_attr "mode" "QI")])
654
655 (define_insn "*cmpqi_ext_1"
656 [(set (reg FLAGS_REG)
657 (compare
658 (match_operand:QI 0 "general_operand" "Qm")
659 (subreg:QI
660 (zero_extract:SI
661 (match_operand 1 "ext_register_operand" "Q")
662 (const_int 8)
663 (const_int 8)) 0)))]
664 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665 "cmp{b}\t{%h1, %0|%0, %h1}"
666 [(set_attr "type" "icmp")
667 (set_attr "mode" "QI")])
668
669 (define_insn "*cmpqi_ext_1_rex64"
670 [(set (reg FLAGS_REG)
671 (compare
672 (match_operand:QI 0 "register_operand" "Q")
673 (subreg:QI
674 (zero_extract:SI
675 (match_operand 1 "ext_register_operand" "Q")
676 (const_int 8)
677 (const_int 8)) 0)))]
678 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679 "cmp{b}\t{%h1, %0|%0, %h1}"
680 [(set_attr "type" "icmp")
681 (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_2"
684 [(set (reg FLAGS_REG)
685 (compare
686 (subreg:QI
687 (zero_extract:SI
688 (match_operand 0 "ext_register_operand" "Q")
689 (const_int 8)
690 (const_int 8)) 0)
691 (match_operand:QI 1 "const0_operand" "n")))]
692 "ix86_match_ccmode (insn, CCNOmode)"
693 "test{b}\t%h0, %h0"
694 [(set_attr "type" "test")
695 (set_attr "length_immediate" "0")
696 (set_attr "mode" "QI")])
697
698 (define_expand "cmpqi_ext_3"
699 [(set (reg:CC FLAGS_REG)
700 (compare:CC
701 (subreg:QI
702 (zero_extract:SI
703 (match_operand 0 "ext_register_operand" "")
704 (const_int 8)
705 (const_int 8)) 0)
706 (match_operand:QI 1 "general_operand" "")))]
707 ""
708 "")
709
710 (define_insn "cmpqi_ext_3_insn"
711 [(set (reg FLAGS_REG)
712 (compare
713 (subreg:QI
714 (zero_extract:SI
715 (match_operand 0 "ext_register_operand" "Q")
716 (const_int 8)
717 (const_int 8)) 0)
718 (match_operand:QI 1 "general_operand" "Qmn")))]
719 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720 "cmp{b}\t{%1, %h0|%h0, %1}"
721 [(set_attr "type" "icmp")
722 (set_attr "mode" "QI")])
723
724 (define_insn "cmpqi_ext_3_insn_rex64"
725 [(set (reg FLAGS_REG)
726 (compare
727 (subreg:QI
728 (zero_extract:SI
729 (match_operand 0 "ext_register_operand" "Q")
730 (const_int 8)
731 (const_int 8)) 0)
732 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734 "cmp{b}\t{%1, %h0|%h0, %1}"
735 [(set_attr "type" "icmp")
736 (set_attr "mode" "QI")])
737
738 (define_insn "*cmpqi_ext_4"
739 [(set (reg FLAGS_REG)
740 (compare
741 (subreg:QI
742 (zero_extract:SI
743 (match_operand 0 "ext_register_operand" "Q")
744 (const_int 8)
745 (const_int 8)) 0)
746 (subreg:QI
747 (zero_extract:SI
748 (match_operand 1 "ext_register_operand" "Q")
749 (const_int 8)
750 (const_int 8)) 0)))]
751 "ix86_match_ccmode (insn, CCmode)"
752 "cmp{b}\t{%h1, %h0|%h0, %h1}"
753 [(set_attr "type" "icmp")
754 (set_attr "mode" "QI")])
755
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares. Which is what
759 ;; the old patterns did, but with many more of them.
760
761 (define_expand "cmpxf"
762 [(set (reg:CC FLAGS_REG)
763 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
765 "TARGET_80387"
766 {
767 ix86_compare_op0 = operands[0];
768 ix86_compare_op1 = operands[1];
769 DONE;
770 })
771
772 (define_expand "cmpdf"
773 [(set (reg:CC FLAGS_REG)
774 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776 "TARGET_80387 || TARGET_SSE2"
777 {
778 ix86_compare_op0 = operands[0];
779 ix86_compare_op1 = operands[1];
780 DONE;
781 })
782
783 (define_expand "cmpsf"
784 [(set (reg:CC FLAGS_REG)
785 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787 "TARGET_80387 || TARGET_SSE"
788 {
789 ix86_compare_op0 = operands[0];
790 ix86_compare_op1 = operands[1];
791 DONE;
792 })
793
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
796 ;;
797 ;; CCFPmode compare with exceptions
798 ;; CCFPUmode compare with no exceptions
799
800 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
801 ;; used to manage the reg stack popping would not be preserved.
802
803 (define_insn "*cmpfp_0_sf"
804 [(set (match_operand:HI 0 "register_operand" "=a")
805 (unspec:HI
806 [(compare:CCFP
807 (match_operand:SF 1 "register_operand" "f")
808 (match_operand:SF 2 "const0_operand" "X"))]
809 UNSPEC_FNSTSW))]
810 "TARGET_80387"
811 "* return output_fp_compare (insn, operands, 0, 0);"
812 [(set_attr "type" "multi")
813 (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_0_df"
816 [(set (match_operand:HI 0 "register_operand" "=a")
817 (unspec:HI
818 [(compare:CCFP
819 (match_operand:DF 1 "register_operand" "f")
820 (match_operand:DF 2 "const0_operand" "X"))]
821 UNSPEC_FNSTSW))]
822 "TARGET_80387"
823 "* return output_fp_compare (insn, operands, 0, 0);"
824 [(set_attr "type" "multi")
825 (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_0_xf"
828 [(set (match_operand:HI 0 "register_operand" "=a")
829 (unspec:HI
830 [(compare:CCFP
831 (match_operand:XF 1 "register_operand" "f")
832 (match_operand:XF 2 "const0_operand" "X"))]
833 UNSPEC_FNSTSW))]
834 "TARGET_80387"
835 "* return output_fp_compare (insn, operands, 0, 0);"
836 [(set_attr "type" "multi")
837 (set_attr "mode" "XF")])
838
839 (define_insn "*cmpfp_sf"
840 [(set (match_operand:HI 0 "register_operand" "=a")
841 (unspec:HI
842 [(compare:CCFP
843 (match_operand:SF 1 "register_operand" "f")
844 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
845 UNSPEC_FNSTSW))]
846 "TARGET_80387"
847 "* return output_fp_compare (insn, operands, 0, 0);"
848 [(set_attr "type" "multi")
849 (set_attr "mode" "SF")])
850
851 (define_insn "*cmpfp_df"
852 [(set (match_operand:HI 0 "register_operand" "=a")
853 (unspec:HI
854 [(compare:CCFP
855 (match_operand:DF 1 "register_operand" "f")
856 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
857 UNSPEC_FNSTSW))]
858 "TARGET_80387"
859 "* return output_fp_compare (insn, operands, 0, 0);"
860 [(set_attr "type" "multi")
861 (set_attr "mode" "DF")])
862
863 (define_insn "*cmpfp_xf"
864 [(set (match_operand:HI 0 "register_operand" "=a")
865 (unspec:HI
866 [(compare:CCFP
867 (match_operand:XF 1 "register_operand" "f")
868 (match_operand:XF 2 "register_operand" "f"))]
869 UNSPEC_FNSTSW))]
870 "TARGET_80387"
871 "* return output_fp_compare (insn, operands, 0, 0);"
872 [(set_attr "type" "multi")
873 (set_attr "mode" "XF")])
874
875 (define_insn "*cmpfp_u"
876 [(set (match_operand:HI 0 "register_operand" "=a")
877 (unspec:HI
878 [(compare:CCFPU
879 (match_operand 1 "register_operand" "f")
880 (match_operand 2 "register_operand" "f"))]
881 UNSPEC_FNSTSW))]
882 "TARGET_80387
883 && FLOAT_MODE_P (GET_MODE (operands[1]))
884 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
885 "* return output_fp_compare (insn, operands, 0, 1);"
886 [(set_attr "type" "multi")
887 (set (attr "mode")
888 (cond [(match_operand:SF 1 "" "")
889 (const_string "SF")
890 (match_operand:DF 1 "" "")
891 (const_string "DF")
892 ]
893 (const_string "XF")))])
894
895 (define_insn "*cmpfp_si"
896 [(set (match_operand:HI 0 "register_operand" "=a")
897 (unspec:HI
898 [(compare:CCFP
899 (match_operand 1 "register_operand" "f")
900 (match_operator 3 "float_operator"
901 [(match_operand:SI 2 "memory_operand" "m")]))]
902 UNSPEC_FNSTSW))]
903 "TARGET_80387 && TARGET_USE_FIOP
904 && FLOAT_MODE_P (GET_MODE (operands[1]))
905 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
906 "* return output_fp_compare (insn, operands, 0, 0);"
907 [(set_attr "type" "multi")
908 (set_attr "fp_int_src" "true")
909 (set_attr "mode" "SI")])
910
911 ;; FP compares, step 2
912 ;; Move the fpsw to ax.
913
914 (define_insn "x86_fnstsw_1"
915 [(set (match_operand:HI 0 "register_operand" "=a")
916 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
917 "TARGET_80387"
918 "fnstsw\t%0"
919 [(set_attr "length" "2")
920 (set_attr "mode" "SI")
921 (set_attr "unit" "i387")])
922
923 ;; FP compares, step 3
924 ;; Get ax into flags, general case.
925
926 (define_insn "x86_sahf_1"
927 [(set (reg:CC FLAGS_REG)
928 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
929 "!TARGET_64BIT"
930 "sahf"
931 [(set_attr "length" "1")
932 (set_attr "athlon_decode" "vector")
933 (set_attr "mode" "SI")])
934
935 ;; Pentium Pro can do steps 1 through 3 in one go.
936
937 (define_insn "*cmpfp_i"
938 [(set (reg:CCFP FLAGS_REG)
939 (compare:CCFP (match_operand 0 "register_operand" "f")
940 (match_operand 1 "register_operand" "f")))]
941 "TARGET_80387 && TARGET_CMOVE
942 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
943 && FLOAT_MODE_P (GET_MODE (operands[0]))
944 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
945 "* return output_fp_compare (insn, operands, 1, 0);"
946 [(set_attr "type" "fcmp")
947 (set (attr "mode")
948 (cond [(match_operand:SF 1 "" "")
949 (const_string "SF")
950 (match_operand:DF 1 "" "")
951 (const_string "DF")
952 ]
953 (const_string "XF")))
954 (set_attr "athlon_decode" "vector")])
955
956 (define_insn "*cmpfp_i_sse"
957 [(set (reg:CCFP FLAGS_REG)
958 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
959 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
960 "TARGET_80387
961 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
963 "* return output_fp_compare (insn, operands, 1, 0);"
964 [(set_attr "type" "fcmp,ssecomi")
965 (set (attr "mode")
966 (if_then_else (match_operand:SF 1 "" "")
967 (const_string "SF")
968 (const_string "DF")))
969 (set_attr "athlon_decode" "vector")])
970
971 (define_insn "*cmpfp_i_sse_only"
972 [(set (reg:CCFP FLAGS_REG)
973 (compare:CCFP (match_operand 0 "register_operand" "x")
974 (match_operand 1 "nonimmediate_operand" "xm")))]
975 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
976 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
977 "* return output_fp_compare (insn, operands, 1, 0);"
978 [(set_attr "type" "ssecomi")
979 (set (attr "mode")
980 (if_then_else (match_operand:SF 1 "" "")
981 (const_string "SF")
982 (const_string "DF")))
983 (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_iu"
986 [(set (reg:CCFPU FLAGS_REG)
987 (compare:CCFPU (match_operand 0 "register_operand" "f")
988 (match_operand 1 "register_operand" "f")))]
989 "TARGET_80387 && TARGET_CMOVE
990 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991 && FLOAT_MODE_P (GET_MODE (operands[0]))
992 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
993 "* return output_fp_compare (insn, operands, 1, 1);"
994 [(set_attr "type" "fcmp")
995 (set (attr "mode")
996 (cond [(match_operand:SF 1 "" "")
997 (const_string "SF")
998 (match_operand:DF 1 "" "")
999 (const_string "DF")
1000 ]
1001 (const_string "XF")))
1002 (set_attr "athlon_decode" "vector")])
1003
1004 (define_insn "*cmpfp_iu_sse"
1005 [(set (reg:CCFPU FLAGS_REG)
1006 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1007 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1008 "TARGET_80387
1009 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1010 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1011 "* return output_fp_compare (insn, operands, 1, 1);"
1012 [(set_attr "type" "fcmp,ssecomi")
1013 (set (attr "mode")
1014 (if_then_else (match_operand:SF 1 "" "")
1015 (const_string "SF")
1016 (const_string "DF")))
1017 (set_attr "athlon_decode" "vector")])
1018
1019 (define_insn "*cmpfp_iu_sse_only"
1020 [(set (reg:CCFPU FLAGS_REG)
1021 (compare:CCFPU (match_operand 0 "register_operand" "x")
1022 (match_operand 1 "nonimmediate_operand" "xm")))]
1023 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025 "* return output_fp_compare (insn, operands, 1, 1);"
1026 [(set_attr "type" "ssecomi")
1027 (set (attr "mode")
1028 (if_then_else (match_operand:SF 1 "" "")
1029 (const_string "SF")
1030 (const_string "DF")))
1031 (set_attr "athlon_decode" "vector")])
1032 \f
1033 ;; Move instructions.
1034
1035 ;; General case of fullword move.
1036
1037 (define_expand "movsi"
1038 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1039 (match_operand:SI 1 "general_operand" ""))]
1040 ""
1041 "ix86_expand_move (SImode, operands); DONE;")
1042
1043 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1044 ;; general_operand.
1045 ;;
1046 ;; %%% We don't use a post-inc memory reference because x86 is not a
1047 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1048 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1049 ;; targets without our curiosities, and it is just as easy to represent
1050 ;; this differently.
1051
1052 (define_insn "*pushsi2"
1053 [(set (match_operand:SI 0 "push_operand" "=<")
1054 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1055 "!TARGET_64BIT"
1056 "push{l}\t%1"
1057 [(set_attr "type" "push")
1058 (set_attr "mode" "SI")])
1059
1060 ;; For 64BIT abi we always round up to 8 bytes.
1061 (define_insn "*pushsi2_rex64"
1062 [(set (match_operand:SI 0 "push_operand" "=X")
1063 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1064 "TARGET_64BIT"
1065 "push{q}\t%q1"
1066 [(set_attr "type" "push")
1067 (set_attr "mode" "SI")])
1068
1069 (define_insn "*pushsi2_prologue"
1070 [(set (match_operand:SI 0 "push_operand" "=<")
1071 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1072 (clobber (mem:BLK (scratch)))]
1073 "!TARGET_64BIT"
1074 "push{l}\t%1"
1075 [(set_attr "type" "push")
1076 (set_attr "mode" "SI")])
1077
1078 (define_insn "*popsi1_epilogue"
1079 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1080 (mem:SI (reg:SI SP_REG)))
1081 (set (reg:SI SP_REG)
1082 (plus:SI (reg:SI SP_REG) (const_int 4)))
1083 (clobber (mem:BLK (scratch)))]
1084 "!TARGET_64BIT"
1085 "pop{l}\t%0"
1086 [(set_attr "type" "pop")
1087 (set_attr "mode" "SI")])
1088
1089 (define_insn "popsi1"
1090 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1091 (mem:SI (reg:SI SP_REG)))
1092 (set (reg:SI SP_REG)
1093 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1094 "!TARGET_64BIT"
1095 "pop{l}\t%0"
1096 [(set_attr "type" "pop")
1097 (set_attr "mode" "SI")])
1098
1099 (define_insn "*movsi_xor"
1100 [(set (match_operand:SI 0 "register_operand" "=r")
1101 (match_operand:SI 1 "const0_operand" "i"))
1102 (clobber (reg:CC FLAGS_REG))]
1103 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1104 "xor{l}\t{%0, %0|%0, %0}"
1105 [(set_attr "type" "alu1")
1106 (set_attr "mode" "SI")
1107 (set_attr "length_immediate" "0")])
1108
1109 (define_insn "*movsi_or"
1110 [(set (match_operand:SI 0 "register_operand" "=r")
1111 (match_operand:SI 1 "immediate_operand" "i"))
1112 (clobber (reg:CC FLAGS_REG))]
1113 "reload_completed
1114 && operands[1] == constm1_rtx
1115 && (TARGET_PENTIUM || optimize_size)"
1116 {
1117 operands[1] = constm1_rtx;
1118 return "or{l}\t{%1, %0|%0, %1}";
1119 }
1120 [(set_attr "type" "alu1")
1121 (set_attr "mode" "SI")
1122 (set_attr "length_immediate" "1")])
1123
1124 (define_insn "*movsi_1"
1125 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1126 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1127 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1128 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1129 {
1130 switch (get_attr_type (insn))
1131 {
1132 case TYPE_SSEMOV:
1133 if (get_attr_mode (insn) == MODE_TI)
1134 return "movdqa\t{%1, %0|%0, %1}";
1135 return "movd\t{%1, %0|%0, %1}";
1136
1137 case TYPE_MMXMOV:
1138 if (get_attr_mode (insn) == MODE_DI)
1139 return "movq\t{%1, %0|%0, %1}";
1140 return "movd\t{%1, %0|%0, %1}";
1141
1142 case TYPE_LEA:
1143 return "lea{l}\t{%1, %0|%0, %1}";
1144
1145 default:
1146 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1147 abort();
1148 return "mov{l}\t{%1, %0|%0, %1}";
1149 }
1150 }
1151 [(set (attr "type")
1152 (cond [(eq_attr "alternative" "2,3,4")
1153 (const_string "mmxmov")
1154 (eq_attr "alternative" "5,6,7")
1155 (const_string "ssemov")
1156 (and (ne (symbol_ref "flag_pic") (const_int 0))
1157 (match_operand:SI 1 "symbolic_operand" ""))
1158 (const_string "lea")
1159 ]
1160 (const_string "imov")))
1161 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1162
1163 (define_insn "*movsi_1_nointernunit"
1164 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1165 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1166 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1167 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1168 {
1169 switch (get_attr_type (insn))
1170 {
1171 case TYPE_SSEMOV:
1172 if (get_attr_mode (insn) == MODE_TI)
1173 return "movdqa\t{%1, %0|%0, %1}";
1174 return "movd\t{%1, %0|%0, %1}";
1175
1176 case TYPE_MMXMOV:
1177 if (get_attr_mode (insn) == MODE_DI)
1178 return "movq\t{%1, %0|%0, %1}";
1179 return "movd\t{%1, %0|%0, %1}";
1180
1181 case TYPE_LEA:
1182 return "lea{l}\t{%1, %0|%0, %1}";
1183
1184 default:
1185 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1186 abort();
1187 return "mov{l}\t{%1, %0|%0, %1}";
1188 }
1189 }
1190 [(set (attr "type")
1191 (cond [(eq_attr "alternative" "2,3,4")
1192 (const_string "mmxmov")
1193 (eq_attr "alternative" "5,6,7")
1194 (const_string "ssemov")
1195 (and (ne (symbol_ref "flag_pic") (const_int 0))
1196 (match_operand:SI 1 "symbolic_operand" ""))
1197 (const_string "lea")
1198 ]
1199 (const_string "imov")))
1200 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1201
1202 ;; Stores and loads of ax to arbitrary constant address.
1203 ;; We fake an second form of instruction to force reload to load address
1204 ;; into register when rax is not available
1205 (define_insn "*movabssi_1_rex64"
1206 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1207 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1208 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1209 "@
1210 movabs{l}\t{%1, %P0|%P0, %1}
1211 mov{l}\t{%1, %a0|%a0, %1}"
1212 [(set_attr "type" "imov")
1213 (set_attr "modrm" "0,*")
1214 (set_attr "length_address" "8,0")
1215 (set_attr "length_immediate" "0,*")
1216 (set_attr "memory" "store")
1217 (set_attr "mode" "SI")])
1218
1219 (define_insn "*movabssi_2_rex64"
1220 [(set (match_operand:SI 0 "register_operand" "=a,r")
1221 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1222 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1223 "@
1224 movabs{l}\t{%P1, %0|%0, %P1}
1225 mov{l}\t{%a1, %0|%0, %a1}"
1226 [(set_attr "type" "imov")
1227 (set_attr "modrm" "0,*")
1228 (set_attr "length_address" "8,0")
1229 (set_attr "length_immediate" "0")
1230 (set_attr "memory" "load")
1231 (set_attr "mode" "SI")])
1232
1233 (define_insn "*swapsi"
1234 [(set (match_operand:SI 0 "register_operand" "+r")
1235 (match_operand:SI 1 "register_operand" "+r"))
1236 (set (match_dup 1)
1237 (match_dup 0))]
1238 ""
1239 "xchg{l}\t%1, %0"
1240 [(set_attr "type" "imov")
1241 (set_attr "pent_pair" "np")
1242 (set_attr "athlon_decode" "vector")
1243 (set_attr "mode" "SI")
1244 (set_attr "modrm" "0")])
1245
1246 (define_expand "movhi"
1247 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1248 (match_operand:HI 1 "general_operand" ""))]
1249 ""
1250 "ix86_expand_move (HImode, operands); DONE;")
1251
1252 (define_insn "*pushhi2"
1253 [(set (match_operand:HI 0 "push_operand" "=<,<")
1254 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1255 "!TARGET_64BIT"
1256 "@
1257 push{w}\t{|WORD PTR }%1
1258 push{w}\t%1"
1259 [(set_attr "type" "push")
1260 (set_attr "mode" "HI")])
1261
1262 ;; For 64BIT abi we always round up to 8 bytes.
1263 (define_insn "*pushhi2_rex64"
1264 [(set (match_operand:HI 0 "push_operand" "=X")
1265 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1266 "TARGET_64BIT"
1267 "push{q}\t%q1"
1268 [(set_attr "type" "push")
1269 (set_attr "mode" "QI")])
1270
1271 (define_insn "*movhi_1"
1272 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1273 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1274 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1275 {
1276 switch (get_attr_type (insn))
1277 {
1278 case TYPE_IMOVX:
1279 /* movzwl is faster than movw on p2 due to partial word stalls,
1280 though not as fast as an aligned movl. */
1281 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1282 default:
1283 if (get_attr_mode (insn) == MODE_SI)
1284 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1285 else
1286 return "mov{w}\t{%1, %0|%0, %1}";
1287 }
1288 }
1289 [(set (attr "type")
1290 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1291 (const_string "imov")
1292 (and (eq_attr "alternative" "0")
1293 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1294 (const_int 0))
1295 (eq (symbol_ref "TARGET_HIMODE_MATH")
1296 (const_int 0))))
1297 (const_string "imov")
1298 (and (eq_attr "alternative" "1,2")
1299 (match_operand:HI 1 "aligned_operand" ""))
1300 (const_string "imov")
1301 (and (ne (symbol_ref "TARGET_MOVX")
1302 (const_int 0))
1303 (eq_attr "alternative" "0,2"))
1304 (const_string "imovx")
1305 ]
1306 (const_string "imov")))
1307 (set (attr "mode")
1308 (cond [(eq_attr "type" "imovx")
1309 (const_string "SI")
1310 (and (eq_attr "alternative" "1,2")
1311 (match_operand:HI 1 "aligned_operand" ""))
1312 (const_string "SI")
1313 (and (eq_attr "alternative" "0")
1314 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315 (const_int 0))
1316 (eq (symbol_ref "TARGET_HIMODE_MATH")
1317 (const_int 0))))
1318 (const_string "SI")
1319 ]
1320 (const_string "HI")))])
1321
1322 ;; Stores and loads of ax to arbitrary constant address.
1323 ;; We fake an second form of instruction to force reload to load address
1324 ;; into register when rax is not available
1325 (define_insn "*movabshi_1_rex64"
1326 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1327 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1328 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1329 "@
1330 movabs{w}\t{%1, %P0|%P0, %1}
1331 mov{w}\t{%1, %a0|%a0, %1}"
1332 [(set_attr "type" "imov")
1333 (set_attr "modrm" "0,*")
1334 (set_attr "length_address" "8,0")
1335 (set_attr "length_immediate" "0,*")
1336 (set_attr "memory" "store")
1337 (set_attr "mode" "HI")])
1338
1339 (define_insn "*movabshi_2_rex64"
1340 [(set (match_operand:HI 0 "register_operand" "=a,r")
1341 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1342 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1343 "@
1344 movabs{w}\t{%P1, %0|%0, %P1}
1345 mov{w}\t{%a1, %0|%0, %a1}"
1346 [(set_attr "type" "imov")
1347 (set_attr "modrm" "0,*")
1348 (set_attr "length_address" "8,0")
1349 (set_attr "length_immediate" "0")
1350 (set_attr "memory" "load")
1351 (set_attr "mode" "HI")])
1352
1353 (define_insn "*swaphi_1"
1354 [(set (match_operand:HI 0 "register_operand" "+r")
1355 (match_operand:HI 1 "register_operand" "+r"))
1356 (set (match_dup 1)
1357 (match_dup 0))]
1358 "TARGET_PARTIAL_REG_STALL"
1359 "xchg{w}\t%1, %0"
1360 [(set_attr "type" "imov")
1361 (set_attr "pent_pair" "np")
1362 (set_attr "mode" "HI")
1363 (set_attr "modrm" "0")])
1364
1365 (define_insn "*swaphi_2"
1366 [(set (match_operand:HI 0 "register_operand" "+r")
1367 (match_operand:HI 1 "register_operand" "+r"))
1368 (set (match_dup 1)
1369 (match_dup 0))]
1370 "! TARGET_PARTIAL_REG_STALL"
1371 "xchg{l}\t%k1, %k0"
1372 [(set_attr "type" "imov")
1373 (set_attr "pent_pair" "np")
1374 (set_attr "mode" "SI")
1375 (set_attr "modrm" "0")])
1376
1377 (define_expand "movstricthi"
1378 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1379 (match_operand:HI 1 "general_operand" ""))]
1380 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1381 {
1382 /* Don't generate memory->memory moves, go through a register */
1383 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1384 operands[1] = force_reg (HImode, operands[1]);
1385 })
1386
1387 (define_insn "*movstricthi_1"
1388 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1389 (match_operand:HI 1 "general_operand" "rn,m"))]
1390 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1391 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1392 "mov{w}\t{%1, %0|%0, %1}"
1393 [(set_attr "type" "imov")
1394 (set_attr "mode" "HI")])
1395
1396 (define_insn "*movstricthi_xor"
1397 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1398 (match_operand:HI 1 "const0_operand" "i"))
1399 (clobber (reg:CC FLAGS_REG))]
1400 "reload_completed
1401 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1402 "xor{w}\t{%0, %0|%0, %0}"
1403 [(set_attr "type" "alu1")
1404 (set_attr "mode" "HI")
1405 (set_attr "length_immediate" "0")])
1406
1407 (define_expand "movqi"
1408 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1409 (match_operand:QI 1 "general_operand" ""))]
1410 ""
1411 "ix86_expand_move (QImode, operands); DONE;")
1412
1413 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1414 ;; "push a byte". But actually we use pushw, which has the effect
1415 ;; of rounding the amount pushed up to a halfword.
1416
1417 (define_insn "*pushqi2"
1418 [(set (match_operand:QI 0 "push_operand" "=X,X")
1419 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1420 "!TARGET_64BIT"
1421 "@
1422 push{w}\t{|word ptr }%1
1423 push{w}\t%w1"
1424 [(set_attr "type" "push")
1425 (set_attr "mode" "HI")])
1426
1427 ;; For 64BIT abi we always round up to 8 bytes.
1428 (define_insn "*pushqi2_rex64"
1429 [(set (match_operand:QI 0 "push_operand" "=X")
1430 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1431 "TARGET_64BIT"
1432 "push{q}\t%q1"
1433 [(set_attr "type" "push")
1434 (set_attr "mode" "QI")])
1435
1436 ;; Situation is quite tricky about when to choose full sized (SImode) move
1437 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1438 ;; partial register dependency machines (such as AMD Athlon), where QImode
1439 ;; moves issue extra dependency and for partial register stalls machines
1440 ;; that don't use QImode patterns (and QImode move cause stall on the next
1441 ;; instruction).
1442 ;;
1443 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1444 ;; register stall machines with, where we use QImode instructions, since
1445 ;; partial register stall can be caused there. Then we use movzx.
1446 (define_insn "*movqi_1"
1447 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1448 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1449 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1450 {
1451 switch (get_attr_type (insn))
1452 {
1453 case TYPE_IMOVX:
1454 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1455 abort ();
1456 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1457 default:
1458 if (get_attr_mode (insn) == MODE_SI)
1459 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1460 else
1461 return "mov{b}\t{%1, %0|%0, %1}";
1462 }
1463 }
1464 [(set (attr "type")
1465 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1466 (const_string "imov")
1467 (and (eq_attr "alternative" "3")
1468 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1469 (const_int 0))
1470 (eq (symbol_ref "TARGET_QIMODE_MATH")
1471 (const_int 0))))
1472 (const_string "imov")
1473 (eq_attr "alternative" "3,5")
1474 (const_string "imovx")
1475 (and (ne (symbol_ref "TARGET_MOVX")
1476 (const_int 0))
1477 (eq_attr "alternative" "2"))
1478 (const_string "imovx")
1479 ]
1480 (const_string "imov")))
1481 (set (attr "mode")
1482 (cond [(eq_attr "alternative" "3,4,5")
1483 (const_string "SI")
1484 (eq_attr "alternative" "6")
1485 (const_string "QI")
1486 (eq_attr "type" "imovx")
1487 (const_string "SI")
1488 (and (eq_attr "type" "imov")
1489 (and (eq_attr "alternative" "0,1,2")
1490 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1491 (const_int 0))))
1492 (const_string "SI")
1493 ;; Avoid partial register stalls when not using QImode arithmetic
1494 (and (eq_attr "type" "imov")
1495 (and (eq_attr "alternative" "0,1,2")
1496 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1497 (const_int 0))
1498 (eq (symbol_ref "TARGET_QIMODE_MATH")
1499 (const_int 0)))))
1500 (const_string "SI")
1501 ]
1502 (const_string "QI")))])
1503
1504 (define_expand "reload_outqi"
1505 [(parallel [(match_operand:QI 0 "" "=m")
1506 (match_operand:QI 1 "register_operand" "r")
1507 (match_operand:QI 2 "register_operand" "=&q")])]
1508 ""
1509 {
1510 rtx op0, op1, op2;
1511 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1512
1513 if (reg_overlap_mentioned_p (op2, op0))
1514 abort ();
1515 if (! q_regs_operand (op1, QImode))
1516 {
1517 emit_insn (gen_movqi (op2, op1));
1518 op1 = op2;
1519 }
1520 emit_insn (gen_movqi (op0, op1));
1521 DONE;
1522 })
1523
1524 (define_insn "*swapqi"
1525 [(set (match_operand:QI 0 "register_operand" "+r")
1526 (match_operand:QI 1 "register_operand" "+r"))
1527 (set (match_dup 1)
1528 (match_dup 0))]
1529 ""
1530 "xchg{b}\t%1, %0"
1531 [(set_attr "type" "imov")
1532 (set_attr "pent_pair" "np")
1533 (set_attr "mode" "QI")
1534 (set_attr "modrm" "0")])
1535
1536 (define_expand "movstrictqi"
1537 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1538 (match_operand:QI 1 "general_operand" ""))]
1539 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1540 {
1541 /* Don't generate memory->memory moves, go through a register. */
1542 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1543 operands[1] = force_reg (QImode, operands[1]);
1544 })
1545
1546 (define_insn "*movstrictqi_1"
1547 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1548 (match_operand:QI 1 "general_operand" "*qn,m"))]
1549 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1550 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1551 "mov{b}\t{%1, %0|%0, %1}"
1552 [(set_attr "type" "imov")
1553 (set_attr "mode" "QI")])
1554
1555 (define_insn "*movstrictqi_xor"
1556 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1557 (match_operand:QI 1 "const0_operand" "i"))
1558 (clobber (reg:CC FLAGS_REG))]
1559 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1560 "xor{b}\t{%0, %0|%0, %0}"
1561 [(set_attr "type" "alu1")
1562 (set_attr "mode" "QI")
1563 (set_attr "length_immediate" "0")])
1564
1565 (define_insn "*movsi_extv_1"
1566 [(set (match_operand:SI 0 "register_operand" "=R")
1567 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1568 (const_int 8)
1569 (const_int 8)))]
1570 ""
1571 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1572 [(set_attr "type" "imovx")
1573 (set_attr "mode" "SI")])
1574
1575 (define_insn "*movhi_extv_1"
1576 [(set (match_operand:HI 0 "register_operand" "=R")
1577 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1578 (const_int 8)
1579 (const_int 8)))]
1580 ""
1581 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1582 [(set_attr "type" "imovx")
1583 (set_attr "mode" "SI")])
1584
1585 (define_insn "*movqi_extv_1"
1586 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1587 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1588 (const_int 8)
1589 (const_int 8)))]
1590 "!TARGET_64BIT"
1591 {
1592 switch (get_attr_type (insn))
1593 {
1594 case TYPE_IMOVX:
1595 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1596 default:
1597 return "mov{b}\t{%h1, %0|%0, %h1}";
1598 }
1599 }
1600 [(set (attr "type")
1601 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1602 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1603 (ne (symbol_ref "TARGET_MOVX")
1604 (const_int 0))))
1605 (const_string "imovx")
1606 (const_string "imov")))
1607 (set (attr "mode")
1608 (if_then_else (eq_attr "type" "imovx")
1609 (const_string "SI")
1610 (const_string "QI")))])
1611
1612 (define_insn "*movqi_extv_1_rex64"
1613 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1614 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1615 (const_int 8)
1616 (const_int 8)))]
1617 "TARGET_64BIT"
1618 {
1619 switch (get_attr_type (insn))
1620 {
1621 case TYPE_IMOVX:
1622 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1623 default:
1624 return "mov{b}\t{%h1, %0|%0, %h1}";
1625 }
1626 }
1627 [(set (attr "type")
1628 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1629 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1630 (ne (symbol_ref "TARGET_MOVX")
1631 (const_int 0))))
1632 (const_string "imovx")
1633 (const_string "imov")))
1634 (set (attr "mode")
1635 (if_then_else (eq_attr "type" "imovx")
1636 (const_string "SI")
1637 (const_string "QI")))])
1638
1639 ;; Stores and loads of ax to arbitrary constant address.
1640 ;; We fake an second form of instruction to force reload to load address
1641 ;; into register when rax is not available
1642 (define_insn "*movabsqi_1_rex64"
1643 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1644 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1645 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1646 "@
1647 movabs{b}\t{%1, %P0|%P0, %1}
1648 mov{b}\t{%1, %a0|%a0, %1}"
1649 [(set_attr "type" "imov")
1650 (set_attr "modrm" "0,*")
1651 (set_attr "length_address" "8,0")
1652 (set_attr "length_immediate" "0,*")
1653 (set_attr "memory" "store")
1654 (set_attr "mode" "QI")])
1655
1656 (define_insn "*movabsqi_2_rex64"
1657 [(set (match_operand:QI 0 "register_operand" "=a,r")
1658 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1659 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1660 "@
1661 movabs{b}\t{%P1, %0|%0, %P1}
1662 mov{b}\t{%a1, %0|%0, %a1}"
1663 [(set_attr "type" "imov")
1664 (set_attr "modrm" "0,*")
1665 (set_attr "length_address" "8,0")
1666 (set_attr "length_immediate" "0")
1667 (set_attr "memory" "load")
1668 (set_attr "mode" "QI")])
1669
1670 (define_insn "*movsi_extzv_1"
1671 [(set (match_operand:SI 0 "register_operand" "=R")
1672 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1673 (const_int 8)
1674 (const_int 8)))]
1675 ""
1676 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1677 [(set_attr "type" "imovx")
1678 (set_attr "mode" "SI")])
1679
1680 (define_insn "*movqi_extzv_2"
1681 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1682 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1683 (const_int 8)
1684 (const_int 8)) 0))]
1685 "!TARGET_64BIT"
1686 {
1687 switch (get_attr_type (insn))
1688 {
1689 case TYPE_IMOVX:
1690 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1691 default:
1692 return "mov{b}\t{%h1, %0|%0, %h1}";
1693 }
1694 }
1695 [(set (attr "type")
1696 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1697 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1698 (ne (symbol_ref "TARGET_MOVX")
1699 (const_int 0))))
1700 (const_string "imovx")
1701 (const_string "imov")))
1702 (set (attr "mode")
1703 (if_then_else (eq_attr "type" "imovx")
1704 (const_string "SI")
1705 (const_string "QI")))])
1706
1707 (define_insn "*movqi_extzv_2_rex64"
1708 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1709 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1710 (const_int 8)
1711 (const_int 8)) 0))]
1712 "TARGET_64BIT"
1713 {
1714 switch (get_attr_type (insn))
1715 {
1716 case TYPE_IMOVX:
1717 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1718 default:
1719 return "mov{b}\t{%h1, %0|%0, %h1}";
1720 }
1721 }
1722 [(set (attr "type")
1723 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1724 (ne (symbol_ref "TARGET_MOVX")
1725 (const_int 0)))
1726 (const_string "imovx")
1727 (const_string "imov")))
1728 (set (attr "mode")
1729 (if_then_else (eq_attr "type" "imovx")
1730 (const_string "SI")
1731 (const_string "QI")))])
1732
1733 (define_insn "movsi_insv_1"
1734 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1735 (const_int 8)
1736 (const_int 8))
1737 (match_operand:SI 1 "general_operand" "Qmn"))]
1738 "!TARGET_64BIT"
1739 "mov{b}\t{%b1, %h0|%h0, %b1}"
1740 [(set_attr "type" "imov")
1741 (set_attr "mode" "QI")])
1742
1743 (define_insn "movdi_insv_1_rex64"
1744 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1745 (const_int 8)
1746 (const_int 8))
1747 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1748 "TARGET_64BIT"
1749 "mov{b}\t{%b1, %h0|%h0, %b1}"
1750 [(set_attr "type" "imov")
1751 (set_attr "mode" "QI")])
1752
1753 (define_insn "*movqi_insv_2"
1754 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1755 (const_int 8)
1756 (const_int 8))
1757 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1758 (const_int 8)))]
1759 ""
1760 "mov{b}\t{%h1, %h0|%h0, %h1}"
1761 [(set_attr "type" "imov")
1762 (set_attr "mode" "QI")])
1763
1764 (define_expand "movdi"
1765 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1766 (match_operand:DI 1 "general_operand" ""))]
1767 ""
1768 "ix86_expand_move (DImode, operands); DONE;")
1769
1770 (define_insn "*pushdi"
1771 [(set (match_operand:DI 0 "push_operand" "=<")
1772 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1773 "!TARGET_64BIT"
1774 "#")
1775
1776 (define_insn "pushdi2_rex64"
1777 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1778 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1779 "TARGET_64BIT"
1780 "@
1781 push{q}\t%1
1782 #"
1783 [(set_attr "type" "push,multi")
1784 (set_attr "mode" "DI")])
1785
1786 ;; Convert impossible pushes of immediate to existing instructions.
1787 ;; First try to get scratch register and go through it. In case this
1788 ;; fails, push sign extended lower part first and then overwrite
1789 ;; upper part by 32bit move.
1790 (define_peephole2
1791 [(match_scratch:DI 2 "r")
1792 (set (match_operand:DI 0 "push_operand" "")
1793 (match_operand:DI 1 "immediate_operand" ""))]
1794 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1795 && !x86_64_immediate_operand (operands[1], DImode)"
1796 [(set (match_dup 2) (match_dup 1))
1797 (set (match_dup 0) (match_dup 2))]
1798 "")
1799
1800 ;; We need to define this as both peepholer and splitter for case
1801 ;; peephole2 pass is not run.
1802 ;; "&& 1" is needed to keep it from matching the previous pattern.
1803 (define_peephole2
1804 [(set (match_operand:DI 0 "push_operand" "")
1805 (match_operand:DI 1 "immediate_operand" ""))]
1806 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1807 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1808 [(set (match_dup 0) (match_dup 1))
1809 (set (match_dup 2) (match_dup 3))]
1810 "split_di (operands + 1, 1, operands + 2, operands + 3);
1811 operands[1] = gen_lowpart (DImode, operands[2]);
1812 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1813 GEN_INT (4)));
1814 ")
1815
1816 (define_split
1817 [(set (match_operand:DI 0 "push_operand" "")
1818 (match_operand:DI 1 "immediate_operand" ""))]
1819 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1820 && !symbolic_operand (operands[1], DImode)
1821 && !x86_64_immediate_operand (operands[1], DImode)"
1822 [(set (match_dup 0) (match_dup 1))
1823 (set (match_dup 2) (match_dup 3))]
1824 "split_di (operands + 1, 1, operands + 2, operands + 3);
1825 operands[1] = gen_lowpart (DImode, operands[2]);
1826 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1827 GEN_INT (4)));
1828 ")
1829
1830 (define_insn "*pushdi2_prologue_rex64"
1831 [(set (match_operand:DI 0 "push_operand" "=<")
1832 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1833 (clobber (mem:BLK (scratch)))]
1834 "TARGET_64BIT"
1835 "push{q}\t%1"
1836 [(set_attr "type" "push")
1837 (set_attr "mode" "DI")])
1838
1839 (define_insn "*popdi1_epilogue_rex64"
1840 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1841 (mem:DI (reg:DI SP_REG)))
1842 (set (reg:DI SP_REG)
1843 (plus:DI (reg:DI SP_REG) (const_int 8)))
1844 (clobber (mem:BLK (scratch)))]
1845 "TARGET_64BIT"
1846 "pop{q}\t%0"
1847 [(set_attr "type" "pop")
1848 (set_attr "mode" "DI")])
1849
1850 (define_insn "popdi1"
1851 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1852 (mem:DI (reg:DI SP_REG)))
1853 (set (reg:DI SP_REG)
1854 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1855 "TARGET_64BIT"
1856 "pop{q}\t%0"
1857 [(set_attr "type" "pop")
1858 (set_attr "mode" "DI")])
1859
1860 (define_insn "*movdi_xor_rex64"
1861 [(set (match_operand:DI 0 "register_operand" "=r")
1862 (match_operand:DI 1 "const0_operand" "i"))
1863 (clobber (reg:CC FLAGS_REG))]
1864 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1865 && reload_completed"
1866 "xor{l}\t{%k0, %k0|%k0, %k0}"
1867 [(set_attr "type" "alu1")
1868 (set_attr "mode" "SI")
1869 (set_attr "length_immediate" "0")])
1870
1871 (define_insn "*movdi_or_rex64"
1872 [(set (match_operand:DI 0 "register_operand" "=r")
1873 (match_operand:DI 1 "const_int_operand" "i"))
1874 (clobber (reg:CC FLAGS_REG))]
1875 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1876 && reload_completed
1877 && operands[1] == constm1_rtx"
1878 {
1879 operands[1] = constm1_rtx;
1880 return "or{q}\t{%1, %0|%0, %1}";
1881 }
1882 [(set_attr "type" "alu1")
1883 (set_attr "mode" "DI")
1884 (set_attr "length_immediate" "1")])
1885
1886 (define_insn "*movdi_2"
1887 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1888 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1889 "!TARGET_64BIT
1890 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1891 "@
1892 #
1893 #
1894 movq\t{%1, %0|%0, %1}
1895 movq\t{%1, %0|%0, %1}
1896 movq\t{%1, %0|%0, %1}
1897 movdqa\t{%1, %0|%0, %1}
1898 movq\t{%1, %0|%0, %1}"
1899 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1900 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1901
1902 (define_split
1903 [(set (match_operand:DI 0 "push_operand" "")
1904 (match_operand:DI 1 "general_operand" ""))]
1905 "!TARGET_64BIT && reload_completed
1906 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1907 [(const_int 0)]
1908 "ix86_split_long_move (operands); DONE;")
1909
1910 ;; %%% This multiword shite has got to go.
1911 (define_split
1912 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1913 (match_operand:DI 1 "general_operand" ""))]
1914 "!TARGET_64BIT && reload_completed
1915 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1916 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1917 [(const_int 0)]
1918 "ix86_split_long_move (operands); DONE;")
1919
1920 (define_insn "*movdi_1_rex64"
1921 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
1922 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
1923 "TARGET_64BIT
1924 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1925 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1926 {
1927 switch (get_attr_type (insn))
1928 {
1929 case TYPE_SSECVT:
1930 if (which_alternative == 11)
1931 return "movq2dq\t{%1, %0|%0, %1}";
1932 else
1933 return "movdq2q\t{%1, %0|%0, %1}";
1934 case TYPE_SSEMOV:
1935 if (get_attr_mode (insn) == MODE_TI)
1936 return "movdqa\t{%1, %0|%0, %1}";
1937 /* FALLTHRU */
1938 case TYPE_MMXMOV:
1939 /* Moves from and into integer register is done using movd opcode with
1940 REX prefix. */
1941 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1942 return "movd\t{%1, %0|%0, %1}";
1943 return "movq\t{%1, %0|%0, %1}";
1944 case TYPE_MULTI:
1945 return "#";
1946 case TYPE_LEA:
1947 return "lea{q}\t{%a1, %0|%0, %a1}";
1948 default:
1949 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1950 abort ();
1951 if (get_attr_mode (insn) == MODE_SI)
1952 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1953 else if (which_alternative == 2)
1954 return "movabs{q}\t{%1, %0|%0, %1}";
1955 else
1956 return "mov{q}\t{%1, %0|%0, %1}";
1957 }
1958 }
1959 [(set (attr "type")
1960 (cond [(eq_attr "alternative" "5,6,7")
1961 (const_string "mmxmov")
1962 (eq_attr "alternative" "8,9,10")
1963 (const_string "ssemov")
1964 (eq_attr "alternative" "11,12")
1965 (const_string "ssecvt")
1966 (eq_attr "alternative" "4")
1967 (const_string "multi")
1968 (and (ne (symbol_ref "flag_pic") (const_int 0))
1969 (match_operand:DI 1 "symbolic_operand" ""))
1970 (const_string "lea")
1971 ]
1972 (const_string "imov")))
1973 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
1974 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
1975 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
1976
1977 (define_insn "*movdi_1_rex64_nointerunit"
1978 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1979 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1980 "TARGET_64BIT
1981 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1982 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1983 {
1984 switch (get_attr_type (insn))
1985 {
1986 case TYPE_SSEMOV:
1987 if (get_attr_mode (insn) == MODE_TI)
1988 return "movdqa\t{%1, %0|%0, %1}";
1989 /* FALLTHRU */
1990 case TYPE_MMXMOV:
1991 return "movq\t{%1, %0|%0, %1}";
1992 case TYPE_MULTI:
1993 return "#";
1994 case TYPE_LEA:
1995 return "lea{q}\t{%a1, %0|%0, %a1}";
1996 default:
1997 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1998 abort ();
1999 if (get_attr_mode (insn) == MODE_SI)
2000 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2001 else if (which_alternative == 2)
2002 return "movabs{q}\t{%1, %0|%0, %1}";
2003 else
2004 return "mov{q}\t{%1, %0|%0, %1}";
2005 }
2006 }
2007 [(set (attr "type")
2008 (cond [(eq_attr "alternative" "5,6,7")
2009 (const_string "mmxmov")
2010 (eq_attr "alternative" "8,9,10")
2011 (const_string "ssemov")
2012 (eq_attr "alternative" "4")
2013 (const_string "multi")
2014 (and (ne (symbol_ref "flag_pic") (const_int 0))
2015 (match_operand:DI 1 "symbolic_operand" ""))
2016 (const_string "lea")
2017 ]
2018 (const_string "imov")))
2019 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2020 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2021 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2022
2023 ;; Stores and loads of ax to arbitrary constant address.
2024 ;; We fake an second form of instruction to force reload to load address
2025 ;; into register when rax is not available
2026 (define_insn "*movabsdi_1_rex64"
2027 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2028 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2029 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2030 "@
2031 movabs{q}\t{%1, %P0|%P0, %1}
2032 mov{q}\t{%1, %a0|%a0, %1}"
2033 [(set_attr "type" "imov")
2034 (set_attr "modrm" "0,*")
2035 (set_attr "length_address" "8,0")
2036 (set_attr "length_immediate" "0,*")
2037 (set_attr "memory" "store")
2038 (set_attr "mode" "DI")])
2039
2040 (define_insn "*movabsdi_2_rex64"
2041 [(set (match_operand:DI 0 "register_operand" "=a,r")
2042 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2043 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2044 "@
2045 movabs{q}\t{%P1, %0|%0, %P1}
2046 mov{q}\t{%a1, %0|%0, %a1}"
2047 [(set_attr "type" "imov")
2048 (set_attr "modrm" "0,*")
2049 (set_attr "length_address" "8,0")
2050 (set_attr "length_immediate" "0")
2051 (set_attr "memory" "load")
2052 (set_attr "mode" "DI")])
2053
2054 ;; Convert impossible stores of immediate to existing instructions.
2055 ;; First try to get scratch register and go through it. In case this
2056 ;; fails, move by 32bit parts.
2057 (define_peephole2
2058 [(match_scratch:DI 2 "r")
2059 (set (match_operand:DI 0 "memory_operand" "")
2060 (match_operand:DI 1 "immediate_operand" ""))]
2061 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2062 && !x86_64_immediate_operand (operands[1], DImode)"
2063 [(set (match_dup 2) (match_dup 1))
2064 (set (match_dup 0) (match_dup 2))]
2065 "")
2066
2067 ;; We need to define this as both peepholer and splitter for case
2068 ;; peephole2 pass is not run.
2069 ;; "&& 1" is needed to keep it from matching the previous pattern.
2070 (define_peephole2
2071 [(set (match_operand:DI 0 "memory_operand" "")
2072 (match_operand:DI 1 "immediate_operand" ""))]
2073 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2074 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2075 [(set (match_dup 2) (match_dup 3))
2076 (set (match_dup 4) (match_dup 5))]
2077 "split_di (operands, 2, operands + 2, operands + 4);")
2078
2079 (define_split
2080 [(set (match_operand:DI 0 "memory_operand" "")
2081 (match_operand:DI 1 "immediate_operand" ""))]
2082 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2083 && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode)"
2085 [(set (match_dup 2) (match_dup 3))
2086 (set (match_dup 4) (match_dup 5))]
2087 "split_di (operands, 2, operands + 2, operands + 4);")
2088
2089 (define_insn "*swapdi_rex64"
2090 [(set (match_operand:DI 0 "register_operand" "+r")
2091 (match_operand:DI 1 "register_operand" "+r"))
2092 (set (match_dup 1)
2093 (match_dup 0))]
2094 "TARGET_64BIT"
2095 "xchg{q}\t%1, %0"
2096 [(set_attr "type" "imov")
2097 (set_attr "pent_pair" "np")
2098 (set_attr "athlon_decode" "vector")
2099 (set_attr "mode" "DI")
2100 (set_attr "modrm" "0")])
2101
2102
2103 (define_expand "movsf"
2104 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2105 (match_operand:SF 1 "general_operand" ""))]
2106 ""
2107 "ix86_expand_move (SFmode, operands); DONE;")
2108
2109 (define_insn "*pushsf"
2110 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2111 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2112 "!TARGET_64BIT"
2113 {
2114 switch (which_alternative)
2115 {
2116 case 1:
2117 return "push{l}\t%1";
2118
2119 default:
2120 /* This insn should be already split before reg-stack. */
2121 abort ();
2122 }
2123 }
2124 [(set_attr "type" "multi,push,multi")
2125 (set_attr "mode" "SF,SI,SF")])
2126
2127 (define_insn "*pushsf_rex64"
2128 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2129 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2130 "TARGET_64BIT"
2131 {
2132 switch (which_alternative)
2133 {
2134 case 1:
2135 return "push{q}\t%q1";
2136
2137 default:
2138 /* This insn should be already split before reg-stack. */
2139 abort ();
2140 }
2141 }
2142 [(set_attr "type" "multi,push,multi")
2143 (set_attr "mode" "SF,DI,SF")])
2144
2145 (define_split
2146 [(set (match_operand:SF 0 "push_operand" "")
2147 (match_operand:SF 1 "memory_operand" ""))]
2148 "reload_completed
2149 && GET_CODE (operands[1]) == MEM
2150 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2151 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2152 [(set (match_dup 0)
2153 (match_dup 1))]
2154 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2155
2156
2157 ;; %%% Kill this when call knows how to work this out.
2158 (define_split
2159 [(set (match_operand:SF 0 "push_operand" "")
2160 (match_operand:SF 1 "any_fp_register_operand" ""))]
2161 "!TARGET_64BIT"
2162 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2163 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2164
2165 (define_split
2166 [(set (match_operand:SF 0 "push_operand" "")
2167 (match_operand:SF 1 "any_fp_register_operand" ""))]
2168 "TARGET_64BIT"
2169 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2170 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2171
2172 (define_insn "*movsf_1"
2173 [(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")
2174 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2175 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2176 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2177 && (reload_in_progress || reload_completed
2178 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2179 || GET_CODE (operands[1]) != CONST_DOUBLE
2180 || memory_operand (operands[0], SFmode))"
2181 {
2182 switch (which_alternative)
2183 {
2184 case 0:
2185 return output_387_reg_move (insn, operands);
2186
2187 case 1:
2188 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2189 return "fstp%z0\t%y0";
2190 else
2191 return "fst%z0\t%y0";
2192
2193 case 2:
2194 return standard_80387_constant_opcode (operands[1]);
2195
2196 case 3:
2197 case 4:
2198 return "mov{l}\t{%1, %0|%0, %1}";
2199 case 5:
2200 if (get_attr_mode (insn) == MODE_TI)
2201 return "pxor\t%0, %0";
2202 else
2203 return "xorps\t%0, %0";
2204 case 6:
2205 if (get_attr_mode (insn) == MODE_V4SF)
2206 return "movaps\t{%1, %0|%0, %1}";
2207 else
2208 return "movss\t{%1, %0|%0, %1}";
2209 case 7:
2210 case 8:
2211 return "movss\t{%1, %0|%0, %1}";
2212
2213 case 9:
2214 case 10:
2215 return "movd\t{%1, %0|%0, %1}";
2216
2217 case 11:
2218 return "movq\t{%1, %0|%0, %1}";
2219
2220 default:
2221 abort();
2222 }
2223 }
2224 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2225 (set (attr "mode")
2226 (cond [(eq_attr "alternative" "3,4,9,10")
2227 (const_string "SI")
2228 (eq_attr "alternative" "5")
2229 (if_then_else
2230 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2231 (const_int 0))
2232 (ne (symbol_ref "TARGET_SSE2")
2233 (const_int 0)))
2234 (eq (symbol_ref "optimize_size")
2235 (const_int 0)))
2236 (const_string "TI")
2237 (const_string "V4SF"))
2238 /* For architectures resolving dependencies on
2239 whole SSE registers use APS move to break dependency
2240 chains, otherwise use short move to avoid extra work.
2241
2242 Do the same for architectures resolving dependencies on
2243 the parts. While in DF mode it is better to always handle
2244 just register parts, the SF mode is different due to lack
2245 of instructions to load just part of the register. It is
2246 better to maintain the whole registers in single format
2247 to avoid problems on using packed logical operations. */
2248 (eq_attr "alternative" "6")
2249 (if_then_else
2250 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2251 (const_int 0))
2252 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2253 (const_int 0)))
2254 (const_string "V4SF")
2255 (const_string "SF"))
2256 (eq_attr "alternative" "11")
2257 (const_string "DI")]
2258 (const_string "SF")))])
2259
2260 (define_insn "*movsf_1_nointerunit"
2261 [(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")
2262 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2263 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2264 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2265 && (reload_in_progress || reload_completed
2266 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2267 || GET_CODE (operands[1]) != CONST_DOUBLE
2268 || memory_operand (operands[0], SFmode))"
2269 {
2270 switch (which_alternative)
2271 {
2272 case 0:
2273 return output_387_reg_move (insn, operands);
2274
2275 case 1:
2276 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2277 return "fstp%z0\t%y0";
2278 else
2279 return "fst%z0\t%y0";
2280
2281 case 2:
2282 return standard_80387_constant_opcode (operands[1]);
2283
2284 case 3:
2285 case 4:
2286 return "mov{l}\t{%1, %0|%0, %1}";
2287 case 5:
2288 if (get_attr_mode (insn) == MODE_TI)
2289 return "pxor\t%0, %0";
2290 else
2291 return "xorps\t%0, %0";
2292 case 6:
2293 if (get_attr_mode (insn) == MODE_V4SF)
2294 return "movaps\t{%1, %0|%0, %1}";
2295 else
2296 return "movss\t{%1, %0|%0, %1}";
2297 case 7:
2298 case 8:
2299 return "movss\t{%1, %0|%0, %1}";
2300
2301 case 9:
2302 case 10:
2303 return "movd\t{%1, %0|%0, %1}";
2304
2305 case 11:
2306 return "movq\t{%1, %0|%0, %1}";
2307
2308 default:
2309 abort();
2310 }
2311 }
2312 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2313 (set (attr "mode")
2314 (cond [(eq_attr "alternative" "3,4,9,10")
2315 (const_string "SI")
2316 (eq_attr "alternative" "5")
2317 (if_then_else
2318 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2319 (const_int 0))
2320 (ne (symbol_ref "TARGET_SSE2")
2321 (const_int 0)))
2322 (eq (symbol_ref "optimize_size")
2323 (const_int 0)))
2324 (const_string "TI")
2325 (const_string "V4SF"))
2326 /* For architectures resolving dependencies on
2327 whole SSE registers use APS move to break dependency
2328 chains, otherwise use short move to avoid extra work.
2329
2330 Do the same for architectures resolving dependencies on
2331 the parts. While in DF mode it is better to always handle
2332 just register parts, the SF mode is different due to lack
2333 of instructions to load just part of the register. It is
2334 better to maintain the whole registers in single format
2335 to avoid problems on using packed logical operations. */
2336 (eq_attr "alternative" "6")
2337 (if_then_else
2338 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2339 (const_int 0))
2340 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2341 (const_int 0)))
2342 (const_string "V4SF")
2343 (const_string "SF"))
2344 (eq_attr "alternative" "11")
2345 (const_string "DI")]
2346 (const_string "SF")))])
2347
2348 (define_insn "*swapsf"
2349 [(set (match_operand:SF 0 "register_operand" "+f")
2350 (match_operand:SF 1 "register_operand" "+f"))
2351 (set (match_dup 1)
2352 (match_dup 0))]
2353 "reload_completed || !TARGET_SSE"
2354 {
2355 if (STACK_TOP_P (operands[0]))
2356 return "fxch\t%1";
2357 else
2358 return "fxch\t%0";
2359 }
2360 [(set_attr "type" "fxch")
2361 (set_attr "mode" "SF")])
2362
2363 (define_expand "movdf"
2364 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2365 (match_operand:DF 1 "general_operand" ""))]
2366 ""
2367 "ix86_expand_move (DFmode, operands); DONE;")
2368
2369 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2370 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2371 ;; On the average, pushdf using integers can be still shorter. Allow this
2372 ;; pattern for optimize_size too.
2373
2374 (define_insn "*pushdf_nointeger"
2375 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2376 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2377 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2378 {
2379 /* This insn should be already split before reg-stack. */
2380 abort ();
2381 }
2382 [(set_attr "type" "multi")
2383 (set_attr "mode" "DF,SI,SI,DF")])
2384
2385 (define_insn "*pushdf_integer"
2386 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2387 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2388 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2389 {
2390 /* This insn should be already split before reg-stack. */
2391 abort ();
2392 }
2393 [(set_attr "type" "multi")
2394 (set_attr "mode" "DF,SI,DF")])
2395
2396 ;; %%% Kill this when call knows how to work this out.
2397 (define_split
2398 [(set (match_operand:DF 0 "push_operand" "")
2399 (match_operand:DF 1 "any_fp_register_operand" ""))]
2400 "!TARGET_64BIT && reload_completed"
2401 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2402 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2403 "")
2404
2405 (define_split
2406 [(set (match_operand:DF 0 "push_operand" "")
2407 (match_operand:DF 1 "any_fp_register_operand" ""))]
2408 "TARGET_64BIT && reload_completed"
2409 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2410 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2411 "")
2412
2413 (define_split
2414 [(set (match_operand:DF 0 "push_operand" "")
2415 (match_operand:DF 1 "general_operand" ""))]
2416 "reload_completed"
2417 [(const_int 0)]
2418 "ix86_split_long_move (operands); DONE;")
2419
2420 ;; Moving is usually shorter when only FP registers are used. This separate
2421 ;; movdf pattern avoids the use of integer registers for FP operations
2422 ;; when optimizing for size.
2423
2424 (define_insn "*movdf_nointeger"
2425 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2426 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2427 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2428 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2429 && (reload_in_progress || reload_completed
2430 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2431 || GET_CODE (operands[1]) != CONST_DOUBLE
2432 || memory_operand (operands[0], DFmode))"
2433 {
2434 switch (which_alternative)
2435 {
2436 case 0:
2437 return output_387_reg_move (insn, operands);
2438
2439 case 1:
2440 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2441 return "fstp%z0\t%y0";
2442 else
2443 return "fst%z0\t%y0";
2444
2445 case 2:
2446 return standard_80387_constant_opcode (operands[1]);
2447
2448 case 3:
2449 case 4:
2450 return "#";
2451 case 5:
2452 switch (get_attr_mode (insn))
2453 {
2454 case MODE_V4SF:
2455 return "xorps\t%0, %0";
2456 case MODE_V2DF:
2457 return "xorpd\t%0, %0";
2458 case MODE_TI:
2459 return "pxor\t%0, %0";
2460 default:
2461 abort ();
2462 }
2463 case 6:
2464 switch (get_attr_mode (insn))
2465 {
2466 case MODE_V4SF:
2467 return "movaps\t{%1, %0|%0, %1}";
2468 case MODE_V2DF:
2469 return "movapd\t{%1, %0|%0, %1}";
2470 case MODE_DF:
2471 return "movsd\t{%1, %0|%0, %1}";
2472 default:
2473 abort ();
2474 }
2475 case 7:
2476 if (get_attr_mode (insn) == MODE_V2DF)
2477 return "movlpd\t{%1, %0|%0, %1}";
2478 else
2479 return "movsd\t{%1, %0|%0, %1}";
2480 case 8:
2481 return "movsd\t{%1, %0|%0, %1}";
2482
2483 default:
2484 abort();
2485 }
2486 }
2487 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2488 (set (attr "mode")
2489 (cond [(eq_attr "alternative" "3,4")
2490 (const_string "SI")
2491 /* xorps is one byte shorter. */
2492 (eq_attr "alternative" "5")
2493 (cond [(ne (symbol_ref "optimize_size")
2494 (const_int 0))
2495 (const_string "V4SF")
2496 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2497 (const_int 0))
2498 (const_string "TI")]
2499 (const_string "V2DF"))
2500 /* For architectures resolving dependencies on
2501 whole SSE registers use APD move to break dependency
2502 chains, otherwise use short move to avoid extra work.
2503
2504 movaps encodes one byte shorter. */
2505 (eq_attr "alternative" "6")
2506 (cond
2507 [(ne (symbol_ref "optimize_size")
2508 (const_int 0))
2509 (const_string "V4SF")
2510 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2511 (const_int 0))
2512 (const_string "V2DF")]
2513 (const_string "DF"))
2514 /* For architectures resolving dependencies on register
2515 parts we may avoid extra work to zero out upper part
2516 of register. */
2517 (eq_attr "alternative" "7")
2518 (if_then_else
2519 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2520 (const_int 0))
2521 (const_string "V2DF")
2522 (const_string "DF"))]
2523 (const_string "DF")))])
2524
2525 (define_insn "*movdf_integer"
2526 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2527 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2528 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2529 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2530 && (reload_in_progress || reload_completed
2531 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2532 || GET_CODE (operands[1]) != CONST_DOUBLE
2533 || memory_operand (operands[0], DFmode))"
2534 {
2535 switch (which_alternative)
2536 {
2537 case 0:
2538 return output_387_reg_move (insn, operands);
2539
2540 case 1:
2541 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2542 return "fstp%z0\t%y0";
2543 else
2544 return "fst%z0\t%y0";
2545
2546 case 2:
2547 return standard_80387_constant_opcode (operands[1]);
2548
2549 case 3:
2550 case 4:
2551 return "#";
2552
2553 case 5:
2554 switch (get_attr_mode (insn))
2555 {
2556 case MODE_V4SF:
2557 return "xorps\t%0, %0";
2558 case MODE_V2DF:
2559 return "xorpd\t%0, %0";
2560 case MODE_TI:
2561 return "pxor\t%0, %0";
2562 default:
2563 abort ();
2564 }
2565 case 6:
2566 switch (get_attr_mode (insn))
2567 {
2568 case MODE_V4SF:
2569 return "movaps\t{%1, %0|%0, %1}";
2570 case MODE_V2DF:
2571 return "movapd\t{%1, %0|%0, %1}";
2572 case MODE_DF:
2573 return "movsd\t{%1, %0|%0, %1}";
2574 default:
2575 abort ();
2576 }
2577 case 7:
2578 if (get_attr_mode (insn) == MODE_V2DF)
2579 return "movlpd\t{%1, %0|%0, %1}";
2580 else
2581 return "movsd\t{%1, %0|%0, %1}";
2582 case 8:
2583 return "movsd\t{%1, %0|%0, %1}";
2584
2585 default:
2586 abort();
2587 }
2588 }
2589 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2590 (set (attr "mode")
2591 (cond [(eq_attr "alternative" "3,4")
2592 (const_string "SI")
2593 /* xorps is one byte shorter. */
2594 (eq_attr "alternative" "5")
2595 (cond [(ne (symbol_ref "optimize_size")
2596 (const_int 0))
2597 (const_string "V4SF")
2598 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2599 (const_int 0))
2600 (const_string "TI")]
2601 (const_string "V2DF"))
2602 /* For architectures resolving dependencies on
2603 whole SSE registers use APD move to break dependency
2604 chains, otherwise use short move to avoid extra work.
2605
2606 movaps encodes one byte shorter. */
2607 (eq_attr "alternative" "6")
2608 (cond
2609 [(ne (symbol_ref "optimize_size")
2610 (const_int 0))
2611 (const_string "V4SF")
2612 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2613 (const_int 0))
2614 (const_string "V2DF")]
2615 (const_string "DF"))
2616 /* For architectures resolving dependencies on register
2617 parts we may avoid extra work to zero out upper part
2618 of register. */
2619 (eq_attr "alternative" "7")
2620 (if_then_else
2621 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2622 (const_int 0))
2623 (const_string "V2DF")
2624 (const_string "DF"))]
2625 (const_string "DF")))])
2626
2627 (define_split
2628 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2629 (match_operand:DF 1 "general_operand" ""))]
2630 "reload_completed
2631 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2632 && ! (ANY_FP_REG_P (operands[0]) ||
2633 (GET_CODE (operands[0]) == SUBREG
2634 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2635 && ! (ANY_FP_REG_P (operands[1]) ||
2636 (GET_CODE (operands[1]) == SUBREG
2637 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2638 [(const_int 0)]
2639 "ix86_split_long_move (operands); DONE;")
2640
2641 (define_insn "*swapdf"
2642 [(set (match_operand:DF 0 "register_operand" "+f")
2643 (match_operand:DF 1 "register_operand" "+f"))
2644 (set (match_dup 1)
2645 (match_dup 0))]
2646 "reload_completed || !TARGET_SSE2"
2647 {
2648 if (STACK_TOP_P (operands[0]))
2649 return "fxch\t%1";
2650 else
2651 return "fxch\t%0";
2652 }
2653 [(set_attr "type" "fxch")
2654 (set_attr "mode" "DF")])
2655
2656 (define_expand "movxf"
2657 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2658 (match_operand:XF 1 "general_operand" ""))]
2659 ""
2660 "ix86_expand_move (XFmode, operands); DONE;")
2661
2662 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references.
2666 ;; (assuming that any given constant is pushed only once, but this ought to be
2667 ;; handled elsewhere).
2668
2669 (define_insn "*pushxf_nointeger"
2670 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2671 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2672 "optimize_size"
2673 {
2674 /* This insn should be already split before reg-stack. */
2675 abort ();
2676 }
2677 [(set_attr "type" "multi")
2678 (set_attr "mode" "XF,SI,SI")])
2679
2680 (define_insn "*pushxf_integer"
2681 [(set (match_operand:XF 0 "push_operand" "=<,<")
2682 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2683 "!optimize_size"
2684 {
2685 /* This insn should be already split before reg-stack. */
2686 abort ();
2687 }
2688 [(set_attr "type" "multi")
2689 (set_attr "mode" "XF,SI")])
2690
2691 (define_split
2692 [(set (match_operand 0 "push_operand" "")
2693 (match_operand 1 "general_operand" ""))]
2694 "reload_completed
2695 && (GET_MODE (operands[0]) == XFmode
2696 || GET_MODE (operands[0]) == DFmode)
2697 && !ANY_FP_REG_P (operands[1])"
2698 [(const_int 0)]
2699 "ix86_split_long_move (operands); DONE;")
2700
2701 (define_split
2702 [(set (match_operand:XF 0 "push_operand" "")
2703 (match_operand:XF 1 "any_fp_register_operand" ""))]
2704 "!TARGET_64BIT"
2705 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2706 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2707 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2708
2709 (define_split
2710 [(set (match_operand:XF 0 "push_operand" "")
2711 (match_operand:XF 1 "any_fp_register_operand" ""))]
2712 "TARGET_64BIT"
2713 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2714 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2715 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2716
2717 ;; Do not use integer registers when optimizing for size
2718 (define_insn "*movxf_nointeger"
2719 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2720 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2721 "optimize_size
2722 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2723 && (reload_in_progress || reload_completed
2724 || GET_CODE (operands[1]) != CONST_DOUBLE
2725 || memory_operand (operands[0], XFmode))"
2726 {
2727 switch (which_alternative)
2728 {
2729 case 0:
2730 return output_387_reg_move (insn, operands);
2731
2732 case 1:
2733 /* There is no non-popping store to memory for XFmode. So if
2734 we need one, follow the store with a load. */
2735 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2736 return "fstp%z0\t%y0\;fld%z0\t%y0";
2737 else
2738 return "fstp%z0\t%y0";
2739
2740 case 2:
2741 return standard_80387_constant_opcode (operands[1]);
2742
2743 case 3: case 4:
2744 return "#";
2745 }
2746 abort();
2747 }
2748 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2749 (set_attr "mode" "XF,XF,XF,SI,SI")])
2750
2751 (define_insn "*movxf_integer"
2752 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2753 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2754 "!optimize_size
2755 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2756 && (reload_in_progress || reload_completed
2757 || GET_CODE (operands[1]) != CONST_DOUBLE
2758 || memory_operand (operands[0], XFmode))"
2759 {
2760 switch (which_alternative)
2761 {
2762 case 0:
2763 return output_387_reg_move (insn, operands);
2764
2765 case 1:
2766 /* There is no non-popping store to memory for XFmode. So if
2767 we need one, follow the store with a load. */
2768 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2769 return "fstp%z0\t%y0\;fld%z0\t%y0";
2770 else
2771 return "fstp%z0\t%y0";
2772
2773 case 2:
2774 return standard_80387_constant_opcode (operands[1]);
2775
2776 case 3: case 4:
2777 return "#";
2778 }
2779 abort();
2780 }
2781 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2782 (set_attr "mode" "XF,XF,XF,SI,SI")])
2783
2784 (define_split
2785 [(set (match_operand 0 "nonimmediate_operand" "")
2786 (match_operand 1 "general_operand" ""))]
2787 "reload_completed
2788 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789 && GET_MODE (operands[0]) == XFmode
2790 && ! (ANY_FP_REG_P (operands[0]) ||
2791 (GET_CODE (operands[0]) == SUBREG
2792 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2793 && ! (ANY_FP_REG_P (operands[1]) ||
2794 (GET_CODE (operands[1]) == SUBREG
2795 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2796 [(const_int 0)]
2797 "ix86_split_long_move (operands); DONE;")
2798
2799 (define_split
2800 [(set (match_operand 0 "register_operand" "")
2801 (match_operand 1 "memory_operand" ""))]
2802 "reload_completed
2803 && GET_CODE (operands[1]) == MEM
2804 && (GET_MODE (operands[0]) == XFmode
2805 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2806 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2807 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2808 [(set (match_dup 0) (match_dup 1))]
2809 {
2810 rtx c = get_pool_constant (XEXP (operands[1], 0));
2811 rtx r = operands[0];
2812
2813 if (GET_CODE (r) == SUBREG)
2814 r = SUBREG_REG (r);
2815
2816 if (SSE_REG_P (r))
2817 {
2818 if (!standard_sse_constant_p (c))
2819 FAIL;
2820 }
2821 else if (FP_REG_P (r))
2822 {
2823 if (!standard_80387_constant_p (c))
2824 FAIL;
2825 }
2826 else if (MMX_REG_P (r))
2827 FAIL;
2828
2829 operands[1] = c;
2830 })
2831
2832 (define_insn "swapxf"
2833 [(set (match_operand:XF 0 "register_operand" "+f")
2834 (match_operand:XF 1 "register_operand" "+f"))
2835 (set (match_dup 1)
2836 (match_dup 0))]
2837 ""
2838 {
2839 if (STACK_TOP_P (operands[0]))
2840 return "fxch\t%1";
2841 else
2842 return "fxch\t%0";
2843 }
2844 [(set_attr "type" "fxch")
2845 (set_attr "mode" "XF")])
2846 \f
2847 ;; Zero extension instructions
2848
2849 (define_expand "zero_extendhisi2"
2850 [(set (match_operand:SI 0 "register_operand" "")
2851 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2852 ""
2853 {
2854 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2855 {
2856 operands[1] = force_reg (HImode, operands[1]);
2857 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2858 DONE;
2859 }
2860 })
2861
2862 (define_insn "zero_extendhisi2_and"
2863 [(set (match_operand:SI 0 "register_operand" "=r")
2864 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2865 (clobber (reg:CC FLAGS_REG))]
2866 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2867 "#"
2868 [(set_attr "type" "alu1")
2869 (set_attr "mode" "SI")])
2870
2871 (define_split
2872 [(set (match_operand:SI 0 "register_operand" "")
2873 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2874 (clobber (reg:CC FLAGS_REG))]
2875 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2876 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2877 (clobber (reg:CC FLAGS_REG))])]
2878 "")
2879
2880 (define_insn "*zero_extendhisi2_movzwl"
2881 [(set (match_operand:SI 0 "register_operand" "=r")
2882 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2883 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2884 "movz{wl|x}\t{%1, %0|%0, %1}"
2885 [(set_attr "type" "imovx")
2886 (set_attr "mode" "SI")])
2887
2888 (define_expand "zero_extendqihi2"
2889 [(parallel
2890 [(set (match_operand:HI 0 "register_operand" "")
2891 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2892 (clobber (reg:CC FLAGS_REG))])]
2893 ""
2894 "")
2895
2896 (define_insn "*zero_extendqihi2_and"
2897 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2898 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2899 (clobber (reg:CC FLAGS_REG))]
2900 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2901 "#"
2902 [(set_attr "type" "alu1")
2903 (set_attr "mode" "HI")])
2904
2905 (define_insn "*zero_extendqihi2_movzbw_and"
2906 [(set (match_operand:HI 0 "register_operand" "=r,r")
2907 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2908 (clobber (reg:CC FLAGS_REG))]
2909 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2910 "#"
2911 [(set_attr "type" "imovx,alu1")
2912 (set_attr "mode" "HI")])
2913
2914 (define_insn "*zero_extendqihi2_movzbw"
2915 [(set (match_operand:HI 0 "register_operand" "=r")
2916 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2917 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2918 "movz{bw|x}\t{%1, %0|%0, %1}"
2919 [(set_attr "type" "imovx")
2920 (set_attr "mode" "HI")])
2921
2922 ;; For the movzbw case strip only the clobber
2923 (define_split
2924 [(set (match_operand:HI 0 "register_operand" "")
2925 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2926 (clobber (reg:CC FLAGS_REG))]
2927 "reload_completed
2928 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2929 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2930 [(set (match_operand:HI 0 "register_operand" "")
2931 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2932
2933 ;; When source and destination does not overlap, clear destination
2934 ;; first and then do the movb
2935 (define_split
2936 [(set (match_operand:HI 0 "register_operand" "")
2937 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2938 (clobber (reg:CC FLAGS_REG))]
2939 "reload_completed
2940 && ANY_QI_REG_P (operands[0])
2941 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2942 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2943 [(set (match_dup 0) (const_int 0))
2944 (set (strict_low_part (match_dup 2)) (match_dup 1))]
2945 "operands[2] = gen_lowpart (QImode, operands[0]);")
2946
2947 ;; Rest is handled by single and.
2948 (define_split
2949 [(set (match_operand:HI 0 "register_operand" "")
2950 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2951 (clobber (reg:CC FLAGS_REG))]
2952 "reload_completed
2953 && true_regnum (operands[0]) == true_regnum (operands[1])"
2954 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2955 (clobber (reg:CC FLAGS_REG))])]
2956 "")
2957
2958 (define_expand "zero_extendqisi2"
2959 [(parallel
2960 [(set (match_operand:SI 0 "register_operand" "")
2961 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2962 (clobber (reg:CC FLAGS_REG))])]
2963 ""
2964 "")
2965
2966 (define_insn "*zero_extendqisi2_and"
2967 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2968 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2969 (clobber (reg:CC FLAGS_REG))]
2970 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2971 "#"
2972 [(set_attr "type" "alu1")
2973 (set_attr "mode" "SI")])
2974
2975 (define_insn "*zero_extendqisi2_movzbw_and"
2976 [(set (match_operand:SI 0 "register_operand" "=r,r")
2977 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2978 (clobber (reg:CC FLAGS_REG))]
2979 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2980 "#"
2981 [(set_attr "type" "imovx,alu1")
2982 (set_attr "mode" "SI")])
2983
2984 (define_insn "*zero_extendqisi2_movzbw"
2985 [(set (match_operand:SI 0 "register_operand" "=r")
2986 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2987 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2988 "movz{bl|x}\t{%1, %0|%0, %1}"
2989 [(set_attr "type" "imovx")
2990 (set_attr "mode" "SI")])
2991
2992 ;; For the movzbl case strip only the clobber
2993 (define_split
2994 [(set (match_operand:SI 0 "register_operand" "")
2995 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2996 (clobber (reg:CC FLAGS_REG))]
2997 "reload_completed
2998 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2999 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3000 [(set (match_dup 0)
3001 (zero_extend:SI (match_dup 1)))])
3002
3003 ;; When source and destination does not overlap, clear destination
3004 ;; first and then do the movb
3005 (define_split
3006 [(set (match_operand:SI 0 "register_operand" "")
3007 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3008 (clobber (reg:CC FLAGS_REG))]
3009 "reload_completed
3010 && ANY_QI_REG_P (operands[0])
3011 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3012 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3013 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3014 [(set (match_dup 0) (const_int 0))
3015 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3016 "operands[2] = gen_lowpart (QImode, operands[0]);")
3017
3018 ;; Rest is handled by single and.
3019 (define_split
3020 [(set (match_operand:SI 0 "register_operand" "")
3021 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3022 (clobber (reg:CC FLAGS_REG))]
3023 "reload_completed
3024 && true_regnum (operands[0]) == true_regnum (operands[1])"
3025 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3026 (clobber (reg:CC FLAGS_REG))])]
3027 "")
3028
3029 ;; %%% Kill me once multi-word ops are sane.
3030 (define_expand "zero_extendsidi2"
3031 [(set (match_operand:DI 0 "register_operand" "=r")
3032 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3033 ""
3034 "if (!TARGET_64BIT)
3035 {
3036 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3037 DONE;
3038 }
3039 ")
3040
3041 (define_insn "zero_extendsidi2_32"
3042 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3043 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3044 (clobber (reg:CC FLAGS_REG))]
3045 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3046 "@
3047 #
3048 #
3049 #
3050 movd\t{%1, %0|%0, %1}
3051 movd\t{%1, %0|%0, %1}"
3052 [(set_attr "mode" "SI,SI,SI,DI,TI")
3053 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3054
3055 (define_insn "*zero_extendsidi2_32_1"
3056 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3057 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3058 (clobber (reg:CC FLAGS_REG))]
3059 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3060 "@
3061 #
3062 #
3063 #
3064 movd\t{%1, %0|%0, %1}
3065 movd\t{%1, %0|%0, %1}"
3066 [(set_attr "mode" "SI,SI,SI,DI,TI")
3067 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3068
3069 (define_insn "zero_extendsidi2_rex64"
3070 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3071 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3072 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3073 "@
3074 mov\t{%k1, %k0|%k0, %k1}
3075 #
3076 movd\t{%1, %0|%0, %1}
3077 movd\t{%1, %0|%0, %1}"
3078 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3079 (set_attr "mode" "SI,DI,DI,TI")])
3080
3081 (define_insn "*zero_extendsidi2_rex64_1"
3082 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3083 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3084 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3085 "@
3086 mov\t{%k1, %k0|%k0, %k1}
3087 #
3088 movd\t{%1, %0|%0, %1}
3089 movd\t{%1, %0|%0, %1}"
3090 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3091 (set_attr "mode" "SI,DI,SI,SI")])
3092
3093 (define_split
3094 [(set (match_operand:DI 0 "memory_operand" "")
3095 (zero_extend:DI (match_dup 0)))]
3096 "TARGET_64BIT"
3097 [(set (match_dup 4) (const_int 0))]
3098 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3099
3100 (define_split
3101 [(set (match_operand:DI 0 "register_operand" "")
3102 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3103 (clobber (reg:CC FLAGS_REG))]
3104 "!TARGET_64BIT && reload_completed
3105 && true_regnum (operands[0]) == true_regnum (operands[1])"
3106 [(set (match_dup 4) (const_int 0))]
3107 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3108
3109 (define_split
3110 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3111 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3112 (clobber (reg:CC FLAGS_REG))]
3113 "!TARGET_64BIT && reload_completed
3114 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3115 [(set (match_dup 3) (match_dup 1))
3116 (set (match_dup 4) (const_int 0))]
3117 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3118
3119 (define_insn "zero_extendhidi2"
3120 [(set (match_operand:DI 0 "register_operand" "=r,r")
3121 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3122 "TARGET_64BIT"
3123 "@
3124 movz{wl|x}\t{%1, %k0|%k0, %1}
3125 movz{wq|x}\t{%1, %0|%0, %1}"
3126 [(set_attr "type" "imovx")
3127 (set_attr "mode" "SI,DI")])
3128
3129 (define_insn "zero_extendqidi2"
3130 [(set (match_operand:DI 0 "register_operand" "=r,r")
3131 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3132 "TARGET_64BIT"
3133 "@
3134 movz{bl|x}\t{%1, %k0|%k0, %1}
3135 movz{bq|x}\t{%1, %0|%0, %1}"
3136 [(set_attr "type" "imovx")
3137 (set_attr "mode" "SI,DI")])
3138 \f
3139 ;; Sign extension instructions
3140
3141 (define_expand "extendsidi2"
3142 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3143 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3144 (clobber (reg:CC FLAGS_REG))
3145 (clobber (match_scratch:SI 2 ""))])]
3146 ""
3147 {
3148 if (TARGET_64BIT)
3149 {
3150 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3151 DONE;
3152 }
3153 })
3154
3155 (define_insn "*extendsidi2_1"
3156 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3157 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3158 (clobber (reg:CC FLAGS_REG))
3159 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3160 "!TARGET_64BIT"
3161 "#")
3162
3163 (define_insn "extendsidi2_rex64"
3164 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3165 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3166 "TARGET_64BIT"
3167 "@
3168 {cltq|cdqe}
3169 movs{lq|x}\t{%1,%0|%0, %1}"
3170 [(set_attr "type" "imovx")
3171 (set_attr "mode" "DI")
3172 (set_attr "prefix_0f" "0")
3173 (set_attr "modrm" "0,1")])
3174
3175 (define_insn "extendhidi2"
3176 [(set (match_operand:DI 0 "register_operand" "=r")
3177 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3178 "TARGET_64BIT"
3179 "movs{wq|x}\t{%1,%0|%0, %1}"
3180 [(set_attr "type" "imovx")
3181 (set_attr "mode" "DI")])
3182
3183 (define_insn "extendqidi2"
3184 [(set (match_operand:DI 0 "register_operand" "=r")
3185 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3186 "TARGET_64BIT"
3187 "movs{bq|x}\t{%1,%0|%0, %1}"
3188 [(set_attr "type" "imovx")
3189 (set_attr "mode" "DI")])
3190
3191 ;; Extend to memory case when source register does die.
3192 (define_split
3193 [(set (match_operand:DI 0 "memory_operand" "")
3194 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3195 (clobber (reg:CC FLAGS_REG))
3196 (clobber (match_operand:SI 2 "register_operand" ""))]
3197 "(reload_completed
3198 && dead_or_set_p (insn, operands[1])
3199 && !reg_mentioned_p (operands[1], operands[0]))"
3200 [(set (match_dup 3) (match_dup 1))
3201 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3202 (clobber (reg:CC FLAGS_REG))])
3203 (set (match_dup 4) (match_dup 1))]
3204 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205
3206 ;; Extend to memory case when source register does not die.
3207 (define_split
3208 [(set (match_operand:DI 0 "memory_operand" "")
3209 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3210 (clobber (reg:CC FLAGS_REG))
3211 (clobber (match_operand:SI 2 "register_operand" ""))]
3212 "reload_completed"
3213 [(const_int 0)]
3214 {
3215 split_di (&operands[0], 1, &operands[3], &operands[4]);
3216
3217 emit_move_insn (operands[3], operands[1]);
3218
3219 /* Generate a cltd if possible and doing so it profitable. */
3220 if (true_regnum (operands[1]) == 0
3221 && true_regnum (operands[2]) == 1
3222 && (optimize_size || TARGET_USE_CLTD))
3223 {
3224 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3225 }
3226 else
3227 {
3228 emit_move_insn (operands[2], operands[1]);
3229 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3230 }
3231 emit_move_insn (operands[4], operands[2]);
3232 DONE;
3233 })
3234
3235 ;; Extend to register case. Optimize case where source and destination
3236 ;; registers match and cases where we can use cltd.
3237 (define_split
3238 [(set (match_operand:DI 0 "register_operand" "")
3239 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3240 (clobber (reg:CC FLAGS_REG))
3241 (clobber (match_scratch:SI 2 ""))]
3242 "reload_completed"
3243 [(const_int 0)]
3244 {
3245 split_di (&operands[0], 1, &operands[3], &operands[4]);
3246
3247 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3248 emit_move_insn (operands[3], operands[1]);
3249
3250 /* Generate a cltd if possible and doing so it profitable. */
3251 if (true_regnum (operands[3]) == 0
3252 && (optimize_size || TARGET_USE_CLTD))
3253 {
3254 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3255 DONE;
3256 }
3257
3258 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3259 emit_move_insn (operands[4], operands[1]);
3260
3261 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3262 DONE;
3263 })
3264
3265 (define_insn "extendhisi2"
3266 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3267 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3268 ""
3269 {
3270 switch (get_attr_prefix_0f (insn))
3271 {
3272 case 0:
3273 return "{cwtl|cwde}";
3274 default:
3275 return "movs{wl|x}\t{%1,%0|%0, %1}";
3276 }
3277 }
3278 [(set_attr "type" "imovx")
3279 (set_attr "mode" "SI")
3280 (set (attr "prefix_0f")
3281 ;; movsx is short decodable while cwtl is vector decoded.
3282 (if_then_else (and (eq_attr "cpu" "!k6")
3283 (eq_attr "alternative" "0"))
3284 (const_string "0")
3285 (const_string "1")))
3286 (set (attr "modrm")
3287 (if_then_else (eq_attr "prefix_0f" "0")
3288 (const_string "0")
3289 (const_string "1")))])
3290
3291 (define_insn "*extendhisi2_zext"
3292 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3293 (zero_extend:DI
3294 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3295 "TARGET_64BIT"
3296 {
3297 switch (get_attr_prefix_0f (insn))
3298 {
3299 case 0:
3300 return "{cwtl|cwde}";
3301 default:
3302 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3303 }
3304 }
3305 [(set_attr "type" "imovx")
3306 (set_attr "mode" "SI")
3307 (set (attr "prefix_0f")
3308 ;; movsx is short decodable while cwtl is vector decoded.
3309 (if_then_else (and (eq_attr "cpu" "!k6")
3310 (eq_attr "alternative" "0"))
3311 (const_string "0")
3312 (const_string "1")))
3313 (set (attr "modrm")
3314 (if_then_else (eq_attr "prefix_0f" "0")
3315 (const_string "0")
3316 (const_string "1")))])
3317
3318 (define_insn "extendqihi2"
3319 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3320 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3321 ""
3322 {
3323 switch (get_attr_prefix_0f (insn))
3324 {
3325 case 0:
3326 return "{cbtw|cbw}";
3327 default:
3328 return "movs{bw|x}\t{%1,%0|%0, %1}";
3329 }
3330 }
3331 [(set_attr "type" "imovx")
3332 (set_attr "mode" "HI")
3333 (set (attr "prefix_0f")
3334 ;; movsx is short decodable while cwtl is vector decoded.
3335 (if_then_else (and (eq_attr "cpu" "!k6")
3336 (eq_attr "alternative" "0"))
3337 (const_string "0")
3338 (const_string "1")))
3339 (set (attr "modrm")
3340 (if_then_else (eq_attr "prefix_0f" "0")
3341 (const_string "0")
3342 (const_string "1")))])
3343
3344 (define_insn "extendqisi2"
3345 [(set (match_operand:SI 0 "register_operand" "=r")
3346 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3347 ""
3348 "movs{bl|x}\t{%1,%0|%0, %1}"
3349 [(set_attr "type" "imovx")
3350 (set_attr "mode" "SI")])
3351
3352 (define_insn "*extendqisi2_zext"
3353 [(set (match_operand:DI 0 "register_operand" "=r")
3354 (zero_extend:DI
3355 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3356 "TARGET_64BIT"
3357 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3358 [(set_attr "type" "imovx")
3359 (set_attr "mode" "SI")])
3360 \f
3361 ;; Conversions between float and double.
3362
3363 ;; These are all no-ops in the model used for the 80387. So just
3364 ;; emit moves.
3365
3366 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3367 (define_insn "*dummy_extendsfdf2"
3368 [(set (match_operand:DF 0 "push_operand" "=<")
3369 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3370 "0"
3371 "#")
3372
3373 (define_split
3374 [(set (match_operand:DF 0 "push_operand" "")
3375 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3376 "!TARGET_64BIT"
3377 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3378 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3379
3380 (define_split
3381 [(set (match_operand:DF 0 "push_operand" "")
3382 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3383 "TARGET_64BIT"
3384 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3385 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3386
3387 (define_insn "*dummy_extendsfxf2"
3388 [(set (match_operand:XF 0 "push_operand" "=<")
3389 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3390 "0"
3391 "#")
3392
3393 (define_split
3394 [(set (match_operand:XF 0 "push_operand" "")
3395 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3396 ""
3397 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3398 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3399 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3400
3401 (define_split
3402 [(set (match_operand:XF 0 "push_operand" "")
3403 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3404 "TARGET_64BIT"
3405 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3406 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3407 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3408
3409 (define_split
3410 [(set (match_operand:XF 0 "push_operand" "")
3411 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3412 ""
3413 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3414 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3415 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3416
3417 (define_split
3418 [(set (match_operand:XF 0 "push_operand" "")
3419 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3420 "TARGET_64BIT"
3421 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3422 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3423 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3424
3425 (define_expand "extendsfdf2"
3426 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3427 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3428 "TARGET_80387 || TARGET_SSE2"
3429 {
3430 /* ??? Needed for compress_float_constant since all fp constants
3431 are LEGITIMATE_CONSTANT_P. */
3432 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3433 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3434 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3435 operands[1] = force_reg (SFmode, operands[1]);
3436 })
3437
3438 (define_insn "*extendsfdf2_1"
3439 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3440 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3441 "(TARGET_80387 || TARGET_SSE2)
3442 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3443 {
3444 switch (which_alternative)
3445 {
3446 case 0:
3447 return output_387_reg_move (insn, operands);
3448
3449 case 1:
3450 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3451 return "fstp%z0\t%y0";
3452 else
3453 return "fst%z0\t%y0";
3454
3455 case 2:
3456 return "cvtss2sd\t{%1, %0|%0, %1}";
3457
3458 default:
3459 abort ();
3460 }
3461 }
3462 [(set_attr "type" "fmov,fmov,ssecvt")
3463 (set_attr "mode" "SF,XF,DF")])
3464
3465 (define_insn "*extendsfdf2_1_sse_only"
3466 [(set (match_operand:DF 0 "register_operand" "=Y")
3467 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3468 "!TARGET_80387 && TARGET_SSE2
3469 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3470 "cvtss2sd\t{%1, %0|%0, %1}"
3471 [(set_attr "type" "ssecvt")
3472 (set_attr "mode" "DF")])
3473
3474 (define_expand "extendsfxf2"
3475 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3476 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3477 "TARGET_80387"
3478 {
3479 /* ??? Needed for compress_float_constant since all fp constants
3480 are LEGITIMATE_CONSTANT_P. */
3481 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3482 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3483 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3484 operands[1] = force_reg (SFmode, operands[1]);
3485 })
3486
3487 (define_insn "*extendsfxf2_1"
3488 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3489 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3490 "TARGET_80387
3491 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3492 {
3493 switch (which_alternative)
3494 {
3495 case 0:
3496 return output_387_reg_move (insn, operands);
3497
3498 case 1:
3499 /* There is no non-popping store to memory for XFmode. So if
3500 we need one, follow the store with a load. */
3501 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3502 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3503 else
3504 return "fstp%z0\t%y0";
3505
3506 default:
3507 abort ();
3508 }
3509 }
3510 [(set_attr "type" "fmov")
3511 (set_attr "mode" "SF,XF")])
3512
3513 (define_expand "extenddfxf2"
3514 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3515 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3516 "TARGET_80387"
3517 {
3518 /* ??? Needed for compress_float_constant since all fp constants
3519 are LEGITIMATE_CONSTANT_P. */
3520 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3521 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3522 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3523 operands[1] = force_reg (DFmode, operands[1]);
3524 })
3525
3526 (define_insn "*extenddfxf2_1"
3527 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3528 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3529 "TARGET_80387
3530 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3531 {
3532 switch (which_alternative)
3533 {
3534 case 0:
3535 return output_387_reg_move (insn, operands);
3536
3537 case 1:
3538 /* There is no non-popping store to memory for XFmode. So if
3539 we need one, follow the store with a load. */
3540 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3541 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3542 else
3543 return "fstp%z0\t%y0";
3544
3545 default:
3546 abort ();
3547 }
3548 }
3549 [(set_attr "type" "fmov")
3550 (set_attr "mode" "DF,XF")])
3551
3552 ;; %%% This seems bad bad news.
3553 ;; This cannot output into an f-reg because there is no way to be sure
3554 ;; of truncating in that case. Otherwise this is just like a simple move
3555 ;; insn. So we pretend we can output to a reg in order to get better
3556 ;; register preferencing, but we really use a stack slot.
3557
3558 (define_expand "truncdfsf2"
3559 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3560 (float_truncate:SF
3561 (match_operand:DF 1 "register_operand" "")))
3562 (clobber (match_dup 2))])]
3563 "TARGET_80387 || TARGET_SSE2"
3564 "
3565 if (!TARGET_80387)
3566 {
3567 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3568 DONE;
3569 }
3570 else if (flag_unsafe_math_optimizations)
3571 {
3572 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3573 emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3574 if (reg != operands[0])
3575 emit_move_insn (operands[0], reg);
3576 DONE;
3577 }
3578 else
3579 operands[2] = assign_386_stack_local (SFmode, 0);
3580 ")
3581
3582 (define_insn "truncdfsf2_noop"
3583 [(set (match_operand:SF 0 "register_operand" "=f")
3584 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3585 "TARGET_80387 && flag_unsafe_math_optimizations"
3586 {
3587 return output_387_reg_move (insn, operands);
3588 }
3589 [(set_attr "type" "fmov")
3590 (set_attr "mode" "SF")])
3591
3592 (define_insn "*truncdfsf2_1"
3593 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3594 (float_truncate:SF
3595 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3596 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3597 "TARGET_80387 && !TARGET_SSE2"
3598 {
3599 switch (which_alternative)
3600 {
3601 case 0:
3602 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3603 return "fstp%z0\t%y0";
3604 else
3605 return "fst%z0\t%y0";
3606 default:
3607 abort ();
3608 }
3609 }
3610 [(set_attr "type" "fmov,multi,multi,multi")
3611 (set_attr "mode" "SF,SF,SF,SF")])
3612
3613 (define_insn "*truncdfsf2_1_sse"
3614 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3615 (float_truncate:SF
3616 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3617 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3618 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3619 {
3620 switch (which_alternative)
3621 {
3622 case 0:
3623 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624 return "fstp%z0\t%y0";
3625 else
3626 return "fst%z0\t%y0";
3627 case 4:
3628 return "#";
3629 default:
3630 abort ();
3631 }
3632 }
3633 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3634 (set_attr "mode" "SF,SF,SF,SF,DF")])
3635
3636 (define_insn "*truncdfsf2_1_sse_nooverlap"
3637 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3638 (float_truncate:SF
3639 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3640 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3641 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3642 {
3643 switch (which_alternative)
3644 {
3645 case 0:
3646 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3647 return "fstp%z0\t%y0";
3648 else
3649 return "fst%z0\t%y0";
3650 case 4:
3651 return "#";
3652 default:
3653 abort ();
3654 }
3655 }
3656 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3657 (set_attr "mode" "SF,SF,SF,SF,DF")])
3658
3659 (define_insn "*truncdfsf2_2"
3660 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3661 (float_truncate:SF
3662 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3663 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3664 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3665 {
3666 switch (which_alternative)
3667 {
3668 case 0:
3669 case 1:
3670 return "cvtsd2ss\t{%1, %0|%0, %1}";
3671 case 2:
3672 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3673 return "fstp%z0\t%y0";
3674 else
3675 return "fst%z0\t%y0";
3676 default:
3677 abort ();
3678 }
3679 }
3680 [(set_attr "type" "ssecvt,ssecvt,fmov")
3681 (set_attr "athlon_decode" "vector,double,*")
3682 (set_attr "mode" "SF,SF,SF")])
3683
3684 (define_insn "*truncdfsf2_2_nooverlap"
3685 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3686 (float_truncate:SF
3687 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3688 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3689 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3690 {
3691 switch (which_alternative)
3692 {
3693 case 0:
3694 return "#";
3695 case 1:
3696 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697 return "fstp%z0\t%y0";
3698 else
3699 return "fst%z0\t%y0";
3700 default:
3701 abort ();
3702 }
3703 }
3704 [(set_attr "type" "ssecvt,fmov")
3705 (set_attr "mode" "DF,SF")])
3706
3707 (define_insn "*truncdfsf2_3"
3708 [(set (match_operand:SF 0 "memory_operand" "=m")
3709 (float_truncate:SF
3710 (match_operand:DF 1 "register_operand" "f")))]
3711 "TARGET_80387"
3712 {
3713 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3714 return "fstp%z0\t%y0";
3715 else
3716 return "fst%z0\t%y0";
3717 }
3718 [(set_attr "type" "fmov")
3719 (set_attr "mode" "SF")])
3720
3721 (define_insn "truncdfsf2_sse_only"
3722 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3723 (float_truncate:SF
3724 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3725 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3726 "cvtsd2ss\t{%1, %0|%0, %1}"
3727 [(set_attr "type" "ssecvt")
3728 (set_attr "athlon_decode" "vector,double")
3729 (set_attr "mode" "SF")])
3730
3731 (define_insn "*truncdfsf2_sse_only_nooverlap"
3732 [(set (match_operand:SF 0 "register_operand" "=&Y")
3733 (float_truncate:SF
3734 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3735 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3736 "#"
3737 [(set_attr "type" "ssecvt")
3738 (set_attr "mode" "DF")])
3739
3740 (define_split
3741 [(set (match_operand:SF 0 "memory_operand" "")
3742 (float_truncate:SF
3743 (match_operand:DF 1 "register_operand" "")))
3744 (clobber (match_operand:SF 2 "memory_operand" ""))]
3745 "TARGET_80387"
3746 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3747 "")
3748
3749 ; Avoid possible reformatting penalty on the destination by first
3750 ; zeroing it out
3751 (define_split
3752 [(set (match_operand:SF 0 "register_operand" "")
3753 (float_truncate:SF
3754 (match_operand:DF 1 "nonimmediate_operand" "")))
3755 (clobber (match_operand 2 "" ""))]
3756 "TARGET_80387 && reload_completed
3757 && SSE_REG_P (operands[0])
3758 && !STACK_REG_P (operands[1])"
3759 [(const_int 0)]
3760 {
3761 rtx src, dest;
3762 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3763 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3764 else
3765 {
3766 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3767 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3768 /* simplify_gen_subreg refuses to widen memory references. */
3769 if (GET_CODE (src) == SUBREG)
3770 alter_subreg (&src);
3771 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3772 abort ();
3773 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3774 emit_insn (gen_cvtsd2ss (dest, dest, src));
3775 }
3776 DONE;
3777 })
3778
3779 (define_split
3780 [(set (match_operand:SF 0 "register_operand" "")
3781 (float_truncate:SF
3782 (match_operand:DF 1 "nonimmediate_operand" "")))]
3783 "TARGET_80387 && reload_completed
3784 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3785 [(const_int 0)]
3786 {
3787 rtx src, dest;
3788 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3789 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3790 /* simplify_gen_subreg refuses to widen memory references. */
3791 if (GET_CODE (src) == SUBREG)
3792 alter_subreg (&src);
3793 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3794 abort ();
3795 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3796 emit_insn (gen_cvtsd2ss (dest, dest, src));
3797 DONE;
3798 })
3799
3800 (define_split
3801 [(set (match_operand:SF 0 "register_operand" "")
3802 (float_truncate:SF
3803 (match_operand:DF 1 "fp_register_operand" "")))
3804 (clobber (match_operand:SF 2 "memory_operand" ""))]
3805 "TARGET_80387 && reload_completed"
3806 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3807 (set (match_dup 0) (match_dup 2))]
3808 "")
3809
3810 (define_expand "truncxfsf2"
3811 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3812 (float_truncate:SF
3813 (match_operand:XF 1 "register_operand" "")))
3814 (clobber (match_dup 2))])]
3815 "TARGET_80387"
3816 "
3817 if (flag_unsafe_math_optimizations)
3818 {
3819 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3820 emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3821 if (reg != operands[0])
3822 emit_move_insn (operands[0], reg);
3823 DONE;
3824 }
3825 else
3826 operands[2] = assign_386_stack_local (SFmode, 0);
3827 ")
3828
3829 (define_insn "truncxfsf2_noop"
3830 [(set (match_operand:SF 0 "register_operand" "=f")
3831 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3832 "TARGET_80387 && flag_unsafe_math_optimizations"
3833 {
3834 return output_387_reg_move (insn, operands);
3835 }
3836 [(set_attr "type" "fmov")
3837 (set_attr "mode" "SF")])
3838
3839 (define_insn "*truncxfsf2_1"
3840 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3841 (float_truncate:SF
3842 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3843 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3844 "TARGET_80387"
3845 {
3846 switch (which_alternative)
3847 {
3848 case 0:
3849 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850 return "fstp%z0\t%y0";
3851 else
3852 return "fst%z0\t%y0";
3853 default:
3854 abort();
3855 }
3856 }
3857 [(set_attr "type" "fmov,multi,multi,multi")
3858 (set_attr "mode" "SF")])
3859
3860 (define_insn "*truncxfsf2_2"
3861 [(set (match_operand:SF 0 "memory_operand" "=m")
3862 (float_truncate:SF
3863 (match_operand:XF 1 "register_operand" "f")))]
3864 "TARGET_80387"
3865 {
3866 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3867 return "fstp%z0\t%y0";
3868 else
3869 return "fst%z0\t%y0";
3870 }
3871 [(set_attr "type" "fmov")
3872 (set_attr "mode" "SF")])
3873
3874 (define_split
3875 [(set (match_operand:SF 0 "memory_operand" "")
3876 (float_truncate:SF
3877 (match_operand:XF 1 "register_operand" "")))
3878 (clobber (match_operand:SF 2 "memory_operand" ""))]
3879 "TARGET_80387"
3880 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3881 "")
3882
3883 (define_split
3884 [(set (match_operand:SF 0 "register_operand" "")
3885 (float_truncate:SF
3886 (match_operand:XF 1 "register_operand" "")))
3887 (clobber (match_operand:SF 2 "memory_operand" ""))]
3888 "TARGET_80387 && reload_completed"
3889 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3890 (set (match_dup 0) (match_dup 2))]
3891 "")
3892
3893 (define_expand "truncxfdf2"
3894 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3895 (float_truncate:DF
3896 (match_operand:XF 1 "register_operand" "")))
3897 (clobber (match_dup 2))])]
3898 "TARGET_80387"
3899 "
3900 if (flag_unsafe_math_optimizations)
3901 {
3902 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3903 emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3904 if (reg != operands[0])
3905 emit_move_insn (operands[0], reg);
3906 DONE;
3907 }
3908 else
3909 operands[2] = assign_386_stack_local (DFmode, 0);
3910 ")
3911
3912 (define_insn "truncxfdf2_noop"
3913 [(set (match_operand:DF 0 "register_operand" "=f")
3914 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3915 "TARGET_80387 && flag_unsafe_math_optimizations"
3916 {
3917 return output_387_reg_move (insn, operands);
3918 }
3919 [(set_attr "type" "fmov")
3920 (set_attr "mode" "DF")])
3921
3922 (define_insn "*truncxfdf2_1"
3923 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3924 (float_truncate:DF
3925 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3926 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3927 "TARGET_80387"
3928 {
3929 switch (which_alternative)
3930 {
3931 case 0:
3932 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933 return "fstp%z0\t%y0";
3934 else
3935 return "fst%z0\t%y0";
3936 default:
3937 abort();
3938 }
3939 abort ();
3940 }
3941 [(set_attr "type" "fmov,multi,multi,multi")
3942 (set_attr "mode" "DF")])
3943
3944 (define_insn "*truncxfdf2_2"
3945 [(set (match_operand:DF 0 "memory_operand" "=m")
3946 (float_truncate:DF
3947 (match_operand:XF 1 "register_operand" "f")))]
3948 "TARGET_80387"
3949 {
3950 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3951 return "fstp%z0\t%y0";
3952 else
3953 return "fst%z0\t%y0";
3954 }
3955 [(set_attr "type" "fmov")
3956 (set_attr "mode" "DF")])
3957
3958 (define_split
3959 [(set (match_operand:DF 0 "memory_operand" "")
3960 (float_truncate:DF
3961 (match_operand:XF 1 "register_operand" "")))
3962 (clobber (match_operand:DF 2 "memory_operand" ""))]
3963 "TARGET_80387"
3964 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3965 "")
3966
3967 (define_split
3968 [(set (match_operand:DF 0 "register_operand" "")
3969 (float_truncate:DF
3970 (match_operand:XF 1 "register_operand" "")))
3971 (clobber (match_operand:DF 2 "memory_operand" ""))]
3972 "TARGET_80387 && reload_completed"
3973 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3974 (set (match_dup 0) (match_dup 2))]
3975 "")
3976
3977 \f
3978 ;; %%% Break up all these bad boys.
3979
3980 ;; Signed conversion to DImode.
3981
3982 (define_expand "fix_truncxfdi2"
3983 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3984 (fix:DI (match_operand:XF 1 "register_operand" "")))
3985 (clobber (reg:CC FLAGS_REG))])]
3986 "TARGET_80387"
3987 "")
3988
3989 (define_expand "fix_truncdfdi2"
3990 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3991 (fix:DI (match_operand:DF 1 "register_operand" "")))
3992 (clobber (reg:CC FLAGS_REG))])]
3993 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
3994 {
3995 if (TARGET_64BIT && TARGET_SSE2)
3996 {
3997 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3998 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
3999 if (out != operands[0])
4000 emit_move_insn (operands[0], out);
4001 DONE;
4002 }
4003 })
4004
4005 (define_expand "fix_truncsfdi2"
4006 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4007 (fix:DI (match_operand:SF 1 "register_operand" "")))
4008 (clobber (reg:CC FLAGS_REG))])]
4009 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4010 {
4011 if (TARGET_SSE && TARGET_64BIT)
4012 {
4013 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4014 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4015 if (out != operands[0])
4016 emit_move_insn (operands[0], out);
4017 DONE;
4018 }
4019 })
4020
4021 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4022 ;; of the machinery.
4023 (define_insn_and_split "*fix_truncdi_1"
4024 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4025 (fix:DI (match_operand 1 "register_operand" "f,f")))
4026 (clobber (reg:CC FLAGS_REG))]
4027 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4028 && !reload_completed && !reload_in_progress
4029 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4030 "#"
4031 "&& 1"
4032 [(const_int 0)]
4033 {
4034 ix86_optimize_mode_switching = 1;
4035 operands[2] = assign_386_stack_local (HImode, 1);
4036 operands[3] = assign_386_stack_local (HImode, 2);
4037 if (memory_operand (operands[0], VOIDmode))
4038 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4039 operands[2], operands[3]));
4040 else
4041 {
4042 operands[4] = assign_386_stack_local (DImode, 0);
4043 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4044 operands[2], operands[3],
4045 operands[4]));
4046 }
4047 DONE;
4048 }
4049 [(set_attr "type" "fistp")
4050 (set_attr "i387_cw" "trunc")
4051 (set_attr "mode" "DI")])
4052
4053 (define_insn "fix_truncdi_nomemory"
4054 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4055 (fix:DI (match_operand 1 "register_operand" "f,f")))
4056 (use (match_operand:HI 2 "memory_operand" "m,m"))
4057 (use (match_operand:HI 3 "memory_operand" "m,m"))
4058 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4059 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4060 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4061 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4062 "#"
4063 [(set_attr "type" "fistp")
4064 (set_attr "i387_cw" "trunc")
4065 (set_attr "mode" "DI")])
4066
4067 (define_insn "fix_truncdi_memory"
4068 [(set (match_operand:DI 0 "memory_operand" "=m")
4069 (fix:DI (match_operand 1 "register_operand" "f")))
4070 (use (match_operand:HI 2 "memory_operand" "m"))
4071 (use (match_operand:HI 3 "memory_operand" "m"))
4072 (clobber (match_scratch:DF 4 "=&1f"))]
4073 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4074 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4075 "* return output_fix_trunc (insn, operands);"
4076 [(set_attr "type" "fistp")
4077 (set_attr "i387_cw" "trunc")
4078 (set_attr "mode" "DI")])
4079
4080 (define_split
4081 [(set (match_operand:DI 0 "register_operand" "")
4082 (fix:DI (match_operand 1 "register_operand" "")))
4083 (use (match_operand:HI 2 "memory_operand" ""))
4084 (use (match_operand:HI 3 "memory_operand" ""))
4085 (clobber (match_operand:DI 4 "memory_operand" ""))
4086 (clobber (match_scratch 5 ""))]
4087 "reload_completed"
4088 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4089 (use (match_dup 2))
4090 (use (match_dup 3))
4091 (clobber (match_dup 5))])
4092 (set (match_dup 0) (match_dup 4))]
4093 "")
4094
4095 (define_split
4096 [(set (match_operand:DI 0 "memory_operand" "")
4097 (fix:DI (match_operand 1 "register_operand" "")))
4098 (use (match_operand:HI 2 "memory_operand" ""))
4099 (use (match_operand:HI 3 "memory_operand" ""))
4100 (clobber (match_operand:DI 4 "memory_operand" ""))
4101 (clobber (match_scratch 5 ""))]
4102 "reload_completed"
4103 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4104 (use (match_dup 2))
4105 (use (match_dup 3))
4106 (clobber (match_dup 5))])]
4107 "")
4108
4109 ;; When SSE available, it is always faster to use it!
4110 (define_insn "fix_truncsfdi_sse"
4111 [(set (match_operand:DI 0 "register_operand" "=r,r")
4112 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4113 "TARGET_64BIT && TARGET_SSE"
4114 "cvttss2si{q}\t{%1, %0|%0, %1}"
4115 [(set_attr "type" "sseicvt")
4116 (set_attr "mode" "SF")
4117 (set_attr "athlon_decode" "double,vector")])
4118
4119 ;; Avoid vector decoded form of the instruction.
4120 (define_peephole2
4121 [(match_scratch:SF 2 "x")
4122 (set (match_operand:DI 0 "register_operand" "")
4123 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4124 "TARGET_K8 && !optimize_size"
4125 [(set (match_dup 2) (match_dup 1))
4126 (set (match_dup 0) (fix:DI (match_dup 2)))]
4127 "")
4128
4129 (define_insn "fix_truncdfdi_sse"
4130 [(set (match_operand:DI 0 "register_operand" "=r,r")
4131 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4132 "TARGET_64BIT && TARGET_SSE2"
4133 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4134 [(set_attr "type" "sseicvt,sseicvt")
4135 (set_attr "mode" "DF")
4136 (set_attr "athlon_decode" "double,vector")])
4137
4138 ;; Avoid vector decoded form of the instruction.
4139 (define_peephole2
4140 [(match_scratch:DF 2 "Y")
4141 (set (match_operand:DI 0 "register_operand" "")
4142 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4143 "TARGET_K8 && !optimize_size"
4144 [(set (match_dup 2) (match_dup 1))
4145 (set (match_dup 0) (fix:DI (match_dup 2)))]
4146 "")
4147
4148 ;; Signed conversion to SImode.
4149
4150 (define_expand "fix_truncxfsi2"
4151 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4152 (fix:SI (match_operand:XF 1 "register_operand" "")))
4153 (clobber (reg:CC FLAGS_REG))])]
4154 "TARGET_80387"
4155 "")
4156
4157 (define_expand "fix_truncdfsi2"
4158 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159 (fix:SI (match_operand:DF 1 "register_operand" "")))
4160 (clobber (reg:CC FLAGS_REG))])]
4161 "TARGET_80387 || TARGET_SSE2"
4162 {
4163 if (TARGET_SSE2)
4164 {
4165 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4166 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4167 if (out != operands[0])
4168 emit_move_insn (operands[0], out);
4169 DONE;
4170 }
4171 })
4172
4173 (define_expand "fix_truncsfsi2"
4174 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4175 (fix:SI (match_operand:SF 1 "register_operand" "")))
4176 (clobber (reg:CC FLAGS_REG))])]
4177 "TARGET_80387 || TARGET_SSE"
4178 {
4179 if (TARGET_SSE)
4180 {
4181 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4182 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4183 if (out != operands[0])
4184 emit_move_insn (operands[0], out);
4185 DONE;
4186 }
4187 })
4188
4189 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4190 ;; of the machinery.
4191 (define_insn_and_split "*fix_truncsi_1"
4192 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4193 (fix:SI (match_operand 1 "register_operand" "f,f")))
4194 (clobber (reg:CC FLAGS_REG))]
4195 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4196 && !reload_completed && !reload_in_progress
4197 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4198 "#"
4199 "&& 1"
4200 [(const_int 0)]
4201 {
4202 ix86_optimize_mode_switching = 1;
4203 operands[2] = assign_386_stack_local (HImode, 1);
4204 operands[3] = assign_386_stack_local (HImode, 2);
4205 if (memory_operand (operands[0], VOIDmode))
4206 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4207 operands[2], operands[3]));
4208 else
4209 {
4210 operands[4] = assign_386_stack_local (SImode, 0);
4211 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4212 operands[2], operands[3],
4213 operands[4]));
4214 }
4215 DONE;
4216 }
4217 [(set_attr "type" "fistp")
4218 (set_attr "i387_cw" "trunc")
4219 (set_attr "mode" "SI")])
4220
4221 (define_insn "fix_truncsi_nomemory"
4222 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4223 (fix:SI (match_operand 1 "register_operand" "f,f")))
4224 (use (match_operand:HI 2 "memory_operand" "m,m"))
4225 (use (match_operand:HI 3 "memory_operand" "m,m"))
4226 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4227 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4228 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4229 "#"
4230 [(set_attr "type" "fistp")
4231 (set_attr "i387_cw" "trunc")
4232 (set_attr "mode" "SI")])
4233
4234 (define_insn "fix_truncsi_memory"
4235 [(set (match_operand:SI 0 "memory_operand" "=m")
4236 (fix:SI (match_operand 1 "register_operand" "f")))
4237 (use (match_operand:HI 2 "memory_operand" "m"))
4238 (use (match_operand:HI 3 "memory_operand" "m"))]
4239 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4240 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4241 "* return output_fix_trunc (insn, operands);"
4242 [(set_attr "type" "fistp")
4243 (set_attr "i387_cw" "trunc")
4244 (set_attr "mode" "SI")])
4245
4246 ;; When SSE available, it is always faster to use it!
4247 (define_insn "fix_truncsfsi_sse"
4248 [(set (match_operand:SI 0 "register_operand" "=r,r")
4249 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4250 "TARGET_SSE"
4251 "cvttss2si\t{%1, %0|%0, %1}"
4252 [(set_attr "type" "sseicvt")
4253 (set_attr "mode" "DF")
4254 (set_attr "athlon_decode" "double,vector")])
4255
4256 ;; Avoid vector decoded form of the instruction.
4257 (define_peephole2
4258 [(match_scratch:SF 2 "x")
4259 (set (match_operand:SI 0 "register_operand" "")
4260 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4261 "TARGET_K8 && !optimize_size"
4262 [(set (match_dup 2) (match_dup 1))
4263 (set (match_dup 0) (fix:SI (match_dup 2)))]
4264 "")
4265
4266 (define_insn "fix_truncdfsi_sse"
4267 [(set (match_operand:SI 0 "register_operand" "=r,r")
4268 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4269 "TARGET_SSE2"
4270 "cvttsd2si\t{%1, %0|%0, %1}"
4271 [(set_attr "type" "sseicvt")
4272 (set_attr "mode" "DF")
4273 (set_attr "athlon_decode" "double,vector")])
4274
4275 ;; Avoid vector decoded form of the instruction.
4276 (define_peephole2
4277 [(match_scratch:DF 2 "Y")
4278 (set (match_operand:SI 0 "register_operand" "")
4279 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4280 "TARGET_K8 && !optimize_size"
4281 [(set (match_dup 2) (match_dup 1))
4282 (set (match_dup 0) (fix:SI (match_dup 2)))]
4283 "")
4284
4285 (define_split
4286 [(set (match_operand:SI 0 "register_operand" "")
4287 (fix:SI (match_operand 1 "register_operand" "")))
4288 (use (match_operand:HI 2 "memory_operand" ""))
4289 (use (match_operand:HI 3 "memory_operand" ""))
4290 (clobber (match_operand:SI 4 "memory_operand" ""))]
4291 "reload_completed"
4292 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4293 (use (match_dup 2))
4294 (use (match_dup 3))])
4295 (set (match_dup 0) (match_dup 4))]
4296 "")
4297
4298 (define_split
4299 [(set (match_operand:SI 0 "memory_operand" "")
4300 (fix:SI (match_operand 1 "register_operand" "")))
4301 (use (match_operand:HI 2 "memory_operand" ""))
4302 (use (match_operand:HI 3 "memory_operand" ""))
4303 (clobber (match_operand:SI 4 "memory_operand" ""))]
4304 "reload_completed"
4305 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4306 (use (match_dup 2))
4307 (use (match_dup 3))])]
4308 "")
4309
4310 ;; Signed conversion to HImode.
4311
4312 (define_expand "fix_truncxfhi2"
4313 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4314 (fix:HI (match_operand:XF 1 "register_operand" "")))
4315 (clobber (reg:CC FLAGS_REG))])]
4316 "TARGET_80387"
4317 "")
4318
4319 (define_expand "fix_truncdfhi2"
4320 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4321 (fix:HI (match_operand:DF 1 "register_operand" "")))
4322 (clobber (reg:CC FLAGS_REG))])]
4323 "TARGET_80387 && !TARGET_SSE2"
4324 "")
4325
4326 (define_expand "fix_truncsfhi2"
4327 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328 (fix:HI (match_operand:SF 1 "register_operand" "")))
4329 (clobber (reg:CC FLAGS_REG))])]
4330 "TARGET_80387 && !TARGET_SSE"
4331 "")
4332
4333 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4334 ;; of the machinery.
4335 (define_insn_and_split "*fix_trunchi_1"
4336 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4337 (fix:HI (match_operand 1 "register_operand" "f,f")))
4338 (clobber (reg:CC FLAGS_REG))]
4339 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4340 && !reload_completed && !reload_in_progress
4341 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4342 "#"
4343 "&& 1"
4344 [(const_int 0)]
4345 {
4346 ix86_optimize_mode_switching = 1;
4347 operands[2] = assign_386_stack_local (HImode, 1);
4348 operands[3] = assign_386_stack_local (HImode, 2);
4349 if (memory_operand (operands[0], VOIDmode))
4350 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4351 operands[2], operands[3]));
4352 else
4353 {
4354 operands[4] = assign_386_stack_local (HImode, 0);
4355 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4356 operands[2], operands[3],
4357 operands[4]));
4358 }
4359 DONE;
4360 }
4361 [(set_attr "type" "fistp")
4362 (set_attr "i387_cw" "trunc")
4363 (set_attr "mode" "HI")])
4364
4365 (define_insn "fix_trunchi_nomemory"
4366 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4367 (fix:HI (match_operand 1 "register_operand" "f,f")))
4368 (use (match_operand:HI 2 "memory_operand" "m,m"))
4369 (use (match_operand:HI 3 "memory_operand" "m,m"))
4370 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4371 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4372 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4373 "#"
4374 [(set_attr "type" "fistp")
4375 (set_attr "i387_cw" "trunc")
4376 (set_attr "mode" "HI")])
4377
4378 (define_insn "fix_trunchi_memory"
4379 [(set (match_operand:HI 0 "memory_operand" "=m")
4380 (fix:HI (match_operand 1 "register_operand" "f")))
4381 (use (match_operand:HI 2 "memory_operand" "m"))
4382 (use (match_operand:HI 3 "memory_operand" "m"))]
4383 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4384 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4385 "* return output_fix_trunc (insn, operands);"
4386 [(set_attr "type" "fistp")
4387 (set_attr "i387_cw" "trunc")
4388 (set_attr "mode" "HI")])
4389
4390 (define_split
4391 [(set (match_operand:HI 0 "memory_operand" "")
4392 (fix:HI (match_operand 1 "register_operand" "")))
4393 (use (match_operand:HI 2 "memory_operand" ""))
4394 (use (match_operand:HI 3 "memory_operand" ""))
4395 (clobber (match_operand:HI 4 "memory_operand" ""))]
4396 "reload_completed"
4397 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4398 (use (match_dup 2))
4399 (use (match_dup 3))])]
4400 "")
4401
4402 (define_split
4403 [(set (match_operand:HI 0 "register_operand" "")
4404 (fix:HI (match_operand 1 "register_operand" "")))
4405 (use (match_operand:HI 2 "memory_operand" ""))
4406 (use (match_operand:HI 3 "memory_operand" ""))
4407 (clobber (match_operand:HI 4 "memory_operand" ""))]
4408 "reload_completed"
4409 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4410 (use (match_dup 2))
4411 (use (match_dup 3))
4412 (clobber (match_dup 4))])
4413 (set (match_dup 0) (match_dup 4))]
4414 "")
4415
4416 (define_insn "x86_fnstcw_1"
4417 [(set (match_operand:HI 0 "memory_operand" "=m")
4418 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4419 "TARGET_80387"
4420 "fnstcw\t%0"
4421 [(set_attr "length" "2")
4422 (set_attr "mode" "HI")
4423 (set_attr "unit" "i387")])
4424
4425 (define_insn "x86_fldcw_1"
4426 [(set (reg:HI FPSR_REG)
4427 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4428 "TARGET_80387"
4429 "fldcw\t%0"
4430 [(set_attr "length" "2")
4431 (set_attr "mode" "HI")
4432 (set_attr "unit" "i387")
4433 (set_attr "athlon_decode" "vector")])
4434 \f
4435 ;; Conversion between fixed point and floating point.
4436
4437 ;; Even though we only accept memory inputs, the backend _really_
4438 ;; wants to be able to do this between registers.
4439
4440 (define_expand "floathisf2"
4441 [(set (match_operand:SF 0 "register_operand" "")
4442 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4443 "TARGET_80387 || TARGET_SSE_MATH"
4444 {
4445 if (TARGET_SSE_MATH)
4446 {
4447 emit_insn (gen_floatsisf2 (operands[0],
4448 convert_to_mode (SImode, operands[1], 0)));
4449 DONE;
4450 }
4451 })
4452
4453 (define_insn "*floathisf2_i387"
4454 [(set (match_operand:SF 0 "register_operand" "=f,f")
4455 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4456 "TARGET_80387 && !TARGET_SSE_MATH"
4457 "@
4458 fild%z1\t%1
4459 #"
4460 [(set_attr "type" "fmov,multi")
4461 (set_attr "mode" "SF")
4462 (set_attr "fp_int_src" "true")])
4463
4464 (define_expand "floatsisf2"
4465 [(set (match_operand:SF 0 "register_operand" "")
4466 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4467 "TARGET_80387 || TARGET_SSE_MATH"
4468 "")
4469
4470 (define_insn "*floatsisf2_mixed"
4471 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4472 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4473 "TARGET_MIX_SSE_I387"
4474 "@
4475 fild%z1\t%1
4476 #
4477 cvtsi2ss\t{%1, %0|%0, %1}
4478 cvtsi2ss\t{%1, %0|%0, %1}"
4479 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4480 (set_attr "mode" "SF")
4481 (set_attr "athlon_decode" "*,*,vector,double")
4482 (set_attr "fp_int_src" "true")])
4483
4484 (define_insn "*floatsisf2_sse"
4485 [(set (match_operand:SF 0 "register_operand" "=x,x")
4486 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4487 "TARGET_SSE_MATH"
4488 "cvtsi2ss\t{%1, %0|%0, %1}"
4489 [(set_attr "type" "sseicvt")
4490 (set_attr "mode" "SF")
4491 (set_attr "athlon_decode" "vector,double")
4492 (set_attr "fp_int_src" "true")])
4493
4494 ; Avoid possible reformatting penalty on the destination by first
4495 ; zeroing it out
4496 (define_split
4497 [(set (match_operand:SF 0 "register_operand" "")
4498 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4499 "reload_completed
4500 && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4501 && SSE_REG_P (operands[0])"
4502 [(const_int 0)]
4503 {
4504 rtx dest;
4505 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4506 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4507 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4508 DONE;
4509 })
4510
4511 (define_insn "*floatsisf2_i387"
4512 [(set (match_operand:SF 0 "register_operand" "=f,f")
4513 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4514 "TARGET_80387"
4515 "@
4516 fild%z1\t%1
4517 #"
4518 [(set_attr "type" "fmov,multi")
4519 (set_attr "mode" "SF")
4520 (set_attr "fp_int_src" "true")])
4521
4522 (define_expand "floatdisf2"
4523 [(set (match_operand:SF 0 "register_operand" "")
4524 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4525 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4526 "")
4527
4528 (define_insn "*floatdisf2_mixed"
4529 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4530 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4531 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4532 "@
4533 fild%z1\t%1
4534 #
4535 cvtsi2ss{q}\t{%1, %0|%0, %1}
4536 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4537 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4538 (set_attr "mode" "SF")
4539 (set_attr "athlon_decode" "*,*,vector,double")
4540 (set_attr "fp_int_src" "true")])
4541
4542 (define_insn "*floatdisf2_sse"
4543 [(set (match_operand:SF 0 "register_operand" "=x,x")
4544 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4545 "TARGET_64BIT && TARGET_SSE_MATH"
4546 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4547 [(set_attr "type" "sseicvt")
4548 (set_attr "mode" "SF")
4549 (set_attr "athlon_decode" "vector,double")
4550 (set_attr "fp_int_src" "true")])
4551
4552 ; Avoid possible reformatting penalty on the destination by first
4553 ; zeroing it out
4554 (define_split
4555 [(set (match_operand:SF 0 "register_operand" "")
4556 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4557 "reload_completed
4558 && TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE_PARTIAL_REGS
4559 && SSE_REG_P (operands[0])"
4560 [(const_int 0)]
4561 {
4562 rtx dest;
4563 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4564 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4565 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4566 DONE;
4567 })
4568
4569 (define_insn "*floatdisf2_i387"
4570 [(set (match_operand:SF 0 "register_operand" "=f,f")
4571 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4572 "TARGET_80387"
4573 "@
4574 fild%z1\t%1
4575 #"
4576 [(set_attr "type" "fmov,multi")
4577 (set_attr "mode" "SF")
4578 (set_attr "fp_int_src" "true")])
4579
4580 (define_expand "floathidf2"
4581 [(set (match_operand:DF 0 "register_operand" "")
4582 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4583 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4584 {
4585 if (TARGET_SSE2 && TARGET_SSE_MATH)
4586 {
4587 emit_insn (gen_floatsidf2 (operands[0],
4588 convert_to_mode (SImode, operands[1], 0)));
4589 DONE;
4590 }
4591 })
4592
4593 (define_insn "*floathidf2_i387"
4594 [(set (match_operand:DF 0 "register_operand" "=f,f")
4595 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4596 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
4597 "@
4598 fild%z1\t%1
4599 #"
4600 [(set_attr "type" "fmov,multi")
4601 (set_attr "mode" "DF")
4602 (set_attr "fp_int_src" "true")])
4603
4604 (define_expand "floatsidf2"
4605 [(set (match_operand:DF 0 "register_operand" "")
4606 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4607 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4608 "")
4609
4610 (define_insn "*floatsidf2_mixed"
4611 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4612 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4613 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4614 "@
4615 fild%z1\t%1
4616 #
4617 cvtsi2sd\t{%1, %0|%0, %1}
4618 cvtsi2sd\t{%1, %0|%0, %1}"
4619 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4620 (set_attr "mode" "DF")
4621 (set_attr "athlon_decode" "*,*,double,direct")
4622 (set_attr "fp_int_src" "true")])
4623
4624 (define_insn "*floatsidf2_sse"
4625 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4626 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4627 "TARGET_SSE2 && TARGET_SSE_MATH"
4628 "cvtsi2sd\t{%1, %0|%0, %1}"
4629 [(set_attr "type" "sseicvt")
4630 (set_attr "mode" "DF")
4631 (set_attr "athlon_decode" "double,direct")
4632 (set_attr "fp_int_src" "true")])
4633
4634 (define_insn "*floatsidf2_i387"
4635 [(set (match_operand:DF 0 "register_operand" "=f,f")
4636 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4637 "TARGET_80387"
4638 "@
4639 fild%z1\t%1
4640 #"
4641 [(set_attr "type" "fmov,multi")
4642 (set_attr "mode" "DF")
4643 (set_attr "fp_int_src" "true")])
4644
4645 (define_expand "floatdidf2"
4646 [(set (match_operand:DF 0 "register_operand" "")
4647 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4648 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4649 "")
4650
4651 (define_insn "*floatdidf2_mixed"
4652 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4653 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4654 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4655 "@
4656 fild%z1\t%1
4657 #
4658 cvtsi2sd{q}\t{%1, %0|%0, %1}
4659 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4660 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4661 (set_attr "mode" "DF")
4662 (set_attr "athlon_decode" "*,*,double,direct")
4663 (set_attr "fp_int_src" "true")])
4664
4665 (define_insn "*floatdidf2_sse"
4666 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4667 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4668 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4669 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4670 [(set_attr "type" "sseicvt")
4671 (set_attr "mode" "DF")
4672 (set_attr "athlon_decode" "double,direct")
4673 (set_attr "fp_int_src" "true")])
4674
4675 (define_insn "*floatdidf2_i387"
4676 [(set (match_operand:DF 0 "register_operand" "=f,f")
4677 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4678 "TARGET_80387"
4679 "@
4680 fild%z1\t%1
4681 #"
4682 [(set_attr "type" "fmov,multi")
4683 (set_attr "mode" "DF")
4684 (set_attr "fp_int_src" "true")])
4685
4686 (define_insn "floathixf2"
4687 [(set (match_operand:XF 0 "register_operand" "=f,f")
4688 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4689 "TARGET_80387"
4690 "@
4691 fild%z1\t%1
4692 #"
4693 [(set_attr "type" "fmov,multi")
4694 (set_attr "mode" "XF")
4695 (set_attr "fp_int_src" "true")])
4696
4697 (define_insn "floatsixf2"
4698 [(set (match_operand:XF 0 "register_operand" "=f,f")
4699 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4700 "TARGET_80387"
4701 "@
4702 fild%z1\t%1
4703 #"
4704 [(set_attr "type" "fmov,multi")
4705 (set_attr "mode" "XF")
4706 (set_attr "fp_int_src" "true")])
4707
4708 (define_insn "floatdixf2"
4709 [(set (match_operand:XF 0 "register_operand" "=f,f")
4710 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4711 "TARGET_80387"
4712 "@
4713 fild%z1\t%1
4714 #"
4715 [(set_attr "type" "fmov,multi")
4716 (set_attr "mode" "XF")
4717 (set_attr "fp_int_src" "true")])
4718
4719 ;; %%% Kill these when reload knows how to do it.
4720 (define_split
4721 [(set (match_operand 0 "fp_register_operand" "")
4722 (float (match_operand 1 "register_operand" "")))]
4723 "reload_completed
4724 && TARGET_80387
4725 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4726 [(const_int 0)]
4727 {
4728 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4729 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4730 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4731 ix86_free_from_memory (GET_MODE (operands[1]));
4732 DONE;
4733 })
4734
4735 (define_expand "floatunssisf2"
4736 [(use (match_operand:SF 0 "register_operand" ""))
4737 (use (match_operand:SI 1 "register_operand" ""))]
4738 "!TARGET_64BIT && TARGET_SSE_MATH"
4739 "x86_emit_floatuns (operands); DONE;")
4740
4741 (define_expand "floatunsdisf2"
4742 [(use (match_operand:SF 0 "register_operand" ""))
4743 (use (match_operand:DI 1 "register_operand" ""))]
4744 "TARGET_64BIT && TARGET_SSE_MATH"
4745 "x86_emit_floatuns (operands); DONE;")
4746
4747 (define_expand "floatunsdidf2"
4748 [(use (match_operand:DF 0 "register_operand" ""))
4749 (use (match_operand:DI 1 "register_operand" ""))]
4750 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4751 "x86_emit_floatuns (operands); DONE;")
4752 \f
4753 ;; SSE extract/set expanders
4754
4755 (define_expand "vec_setv2df"
4756 [(match_operand:V2DF 0 "register_operand" "")
4757 (match_operand:DF 1 "register_operand" "")
4758 (match_operand 2 "const_int_operand" "")]
4759 "TARGET_SSE2"
4760 {
4761 switch (INTVAL (operands[2]))
4762 {
4763 case 0:
4764 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4765 simplify_gen_subreg (V2DFmode, operands[1],
4766 DFmode, 0)));
4767 break;
4768 case 1:
4769 {
4770 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4771
4772 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4773 }
4774 break;
4775 default:
4776 abort ();
4777 }
4778 DONE;
4779 })
4780
4781 (define_expand "vec_extractv2df"
4782 [(match_operand:DF 0 "register_operand" "")
4783 (match_operand:V2DF 1 "register_operand" "")
4784 (match_operand 2 "const_int_operand" "")]
4785 "TARGET_SSE2"
4786 {
4787 switch (INTVAL (operands[2]))
4788 {
4789 case 0:
4790 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4791 break;
4792 case 1:
4793 {
4794 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4795
4796 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4797 }
4798 break;
4799 default:
4800 abort ();
4801 }
4802 DONE;
4803 })
4804
4805 (define_expand "vec_initv2df"
4806 [(match_operand:V2DF 0 "register_operand" "")
4807 (match_operand 1 "" "")]
4808 "TARGET_SSE2"
4809 {
4810 ix86_expand_vector_init (operands[0], operands[1]);
4811 DONE;
4812 })
4813
4814 (define_expand "vec_setv4sf"
4815 [(match_operand:V4SF 0 "register_operand" "")
4816 (match_operand:SF 1 "register_operand" "")
4817 (match_operand 2 "const_int_operand" "")]
4818 "TARGET_SSE"
4819 {
4820 switch (INTVAL (operands[2]))
4821 {
4822 case 0:
4823 emit_insn (gen_sse_movss (operands[0], operands[0],
4824 simplify_gen_subreg (V4SFmode, operands[1],
4825 SFmode, 0)));
4826 break;
4827 case 1:
4828 {
4829 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4830 rtx tmp = gen_reg_rtx (V4SFmode);
4831
4832 emit_move_insn (tmp, operands[0]);
4833 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4834 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4835 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4836 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4837 }
4838 break;
4839 case 2:
4840 {
4841 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4842 rtx tmp = gen_reg_rtx (V4SFmode);
4843
4844 emit_move_insn (tmp, operands[0]);
4845 emit_insn (gen_sse_movss (tmp, tmp, op1));
4846 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4847 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4848 }
4849 break;
4850 case 3:
4851 {
4852 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4853 rtx tmp = gen_reg_rtx (V4SFmode);
4854
4855 emit_move_insn (tmp, operands[0]);
4856 emit_insn (gen_sse_movss (tmp, tmp, op1));
4857 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4858 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4859 }
4860 break;
4861 default:
4862 abort ();
4863 }
4864 DONE;
4865 })
4866
4867 (define_expand "vec_extractv4sf"
4868 [(match_operand:SF 0 "register_operand" "")
4869 (match_operand:V4SF 1 "register_operand" "")
4870 (match_operand 2 "const_int_operand" "")]
4871 "TARGET_SSE"
4872 {
4873 switch (INTVAL (operands[2]))
4874 {
4875 case 0:
4876 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4877 break;
4878 case 1:
4879 {
4880 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4881 rtx tmp = gen_reg_rtx (V4SFmode);
4882
4883 emit_move_insn (tmp, operands[1]);
4884 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4885 const1_rtx));
4886 }
4887 break;
4888 case 2:
4889 {
4890 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4891 rtx tmp = gen_reg_rtx (V4SFmode);
4892
4893 emit_move_insn (tmp, operands[1]);
4894 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4895 }
4896 break;
4897 case 3:
4898 {
4899 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4900 rtx tmp = gen_reg_rtx (V4SFmode);
4901
4902 emit_move_insn (tmp, operands[1]);
4903 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4904 GEN_INT (3)));
4905 }
4906 break;
4907 default:
4908 abort ();
4909 }
4910 DONE;
4911 })
4912
4913 (define_expand "vec_initv4sf"
4914 [(match_operand:V4SF 0 "register_operand" "")
4915 (match_operand 1 "" "")]
4916 "TARGET_SSE"
4917 {
4918 ix86_expand_vector_init (operands[0], operands[1]);
4919 DONE;
4920 })
4921 \f
4922 ;; Add instructions
4923
4924 ;; %%% splits for addsidi3
4925 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4926 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4927 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4928
4929 (define_expand "adddi3"
4930 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4931 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4932 (match_operand:DI 2 "x86_64_general_operand" "")))
4933 (clobber (reg:CC FLAGS_REG))]
4934 ""
4935 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4936
4937 (define_insn "*adddi3_1"
4938 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4939 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4940 (match_operand:DI 2 "general_operand" "roiF,riF")))
4941 (clobber (reg:CC FLAGS_REG))]
4942 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4943 "#")
4944
4945 (define_split
4946 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4947 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4948 (match_operand:DI 2 "general_operand" "")))
4949 (clobber (reg:CC FLAGS_REG))]
4950 "!TARGET_64BIT && reload_completed"
4951 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4952 UNSPEC_ADD_CARRY))
4953 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4954 (parallel [(set (match_dup 3)
4955 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4956 (match_dup 4))
4957 (match_dup 5)))
4958 (clobber (reg:CC FLAGS_REG))])]
4959 "split_di (operands+0, 1, operands+0, operands+3);
4960 split_di (operands+1, 1, operands+1, operands+4);
4961 split_di (operands+2, 1, operands+2, operands+5);")
4962
4963 (define_insn "adddi3_carry_rex64"
4964 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4965 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4966 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4967 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4968 (clobber (reg:CC FLAGS_REG))]
4969 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4970 "adc{q}\t{%2, %0|%0, %2}"
4971 [(set_attr "type" "alu")
4972 (set_attr "pent_pair" "pu")
4973 (set_attr "mode" "DI")])
4974
4975 (define_insn "*adddi3_cc_rex64"
4976 [(set (reg:CC FLAGS_REG)
4977 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4978 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4979 UNSPEC_ADD_CARRY))
4980 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4981 (plus:DI (match_dup 1) (match_dup 2)))]
4982 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4983 "add{q}\t{%2, %0|%0, %2}"
4984 [(set_attr "type" "alu")
4985 (set_attr "mode" "DI")])
4986
4987 (define_insn "addqi3_carry"
4988 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4989 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4990 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4991 (match_operand:QI 2 "general_operand" "qi,qm")))
4992 (clobber (reg:CC FLAGS_REG))]
4993 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4994 "adc{b}\t{%2, %0|%0, %2}"
4995 [(set_attr "type" "alu")
4996 (set_attr "pent_pair" "pu")
4997 (set_attr "mode" "QI")])
4998
4999 (define_insn "addhi3_carry"
5000 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5001 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5002 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5003 (match_operand:HI 2 "general_operand" "ri,rm")))
5004 (clobber (reg:CC FLAGS_REG))]
5005 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5006 "adc{w}\t{%2, %0|%0, %2}"
5007 [(set_attr "type" "alu")
5008 (set_attr "pent_pair" "pu")
5009 (set_attr "mode" "HI")])
5010
5011 (define_insn "addsi3_carry"
5012 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5013 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5014 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5015 (match_operand:SI 2 "general_operand" "ri,rm")))
5016 (clobber (reg:CC FLAGS_REG))]
5017 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5018 "adc{l}\t{%2, %0|%0, %2}"
5019 [(set_attr "type" "alu")
5020 (set_attr "pent_pair" "pu")
5021 (set_attr "mode" "SI")])
5022
5023 (define_insn "*addsi3_carry_zext"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (zero_extend:DI
5026 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5027 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5028 (match_operand:SI 2 "general_operand" "rim"))))
5029 (clobber (reg:CC FLAGS_REG))]
5030 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5031 "adc{l}\t{%2, %k0|%k0, %2}"
5032 [(set_attr "type" "alu")
5033 (set_attr "pent_pair" "pu")
5034 (set_attr "mode" "SI")])
5035
5036 (define_insn "*addsi3_cc"
5037 [(set (reg:CC FLAGS_REG)
5038 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5039 (match_operand:SI 2 "general_operand" "ri,rm")]
5040 UNSPEC_ADD_CARRY))
5041 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5042 (plus:SI (match_dup 1) (match_dup 2)))]
5043 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5044 "add{l}\t{%2, %0|%0, %2}"
5045 [(set_attr "type" "alu")
5046 (set_attr "mode" "SI")])
5047
5048 (define_insn "addqi3_cc"
5049 [(set (reg:CC FLAGS_REG)
5050 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5051 (match_operand:QI 2 "general_operand" "qi,qm")]
5052 UNSPEC_ADD_CARRY))
5053 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5054 (plus:QI (match_dup 1) (match_dup 2)))]
5055 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5056 "add{b}\t{%2, %0|%0, %2}"
5057 [(set_attr "type" "alu")
5058 (set_attr "mode" "QI")])
5059
5060 (define_expand "addsi3"
5061 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5062 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5063 (match_operand:SI 2 "general_operand" "")))
5064 (clobber (reg:CC FLAGS_REG))])]
5065 ""
5066 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5067
5068 (define_insn "*lea_1"
5069 [(set (match_operand:SI 0 "register_operand" "=r")
5070 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5071 "!TARGET_64BIT"
5072 "lea{l}\t{%a1, %0|%0, %a1}"
5073 [(set_attr "type" "lea")
5074 (set_attr "mode" "SI")])
5075
5076 (define_insn "*lea_1_rex64"
5077 [(set (match_operand:SI 0 "register_operand" "=r")
5078 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5079 "TARGET_64BIT"
5080 "lea{l}\t{%a1, %0|%0, %a1}"
5081 [(set_attr "type" "lea")
5082 (set_attr "mode" "SI")])
5083
5084 (define_insn "*lea_1_zext"
5085 [(set (match_operand:DI 0 "register_operand" "=r")
5086 (zero_extend:DI
5087 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5088 "TARGET_64BIT"
5089 "lea{l}\t{%a1, %k0|%k0, %a1}"
5090 [(set_attr "type" "lea")
5091 (set_attr "mode" "SI")])
5092
5093 (define_insn "*lea_2_rex64"
5094 [(set (match_operand:DI 0 "register_operand" "=r")
5095 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5096 "TARGET_64BIT"
5097 "lea{q}\t{%a1, %0|%0, %a1}"
5098 [(set_attr "type" "lea")
5099 (set_attr "mode" "DI")])
5100
5101 ;; The lea patterns for non-Pmodes needs to be matched by several
5102 ;; insns converted to real lea by splitters.
5103
5104 (define_insn_and_split "*lea_general_1"
5105 [(set (match_operand 0 "register_operand" "=r")
5106 (plus (plus (match_operand 1 "index_register_operand" "l")
5107 (match_operand 2 "register_operand" "r"))
5108 (match_operand 3 "immediate_operand" "i")))]
5109 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5110 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5111 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5112 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5113 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5114 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5115 || GET_MODE (operands[3]) == VOIDmode)"
5116 "#"
5117 "&& reload_completed"
5118 [(const_int 0)]
5119 {
5120 rtx pat;
5121 operands[0] = gen_lowpart (SImode, operands[0]);
5122 operands[1] = gen_lowpart (Pmode, operands[1]);
5123 operands[2] = gen_lowpart (Pmode, operands[2]);
5124 operands[3] = gen_lowpart (Pmode, operands[3]);
5125 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5126 operands[3]);
5127 if (Pmode != SImode)
5128 pat = gen_rtx_SUBREG (SImode, pat, 0);
5129 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5130 DONE;
5131 }
5132 [(set_attr "type" "lea")
5133 (set_attr "mode" "SI")])
5134
5135 (define_insn_and_split "*lea_general_1_zext"
5136 [(set (match_operand:DI 0 "register_operand" "=r")
5137 (zero_extend:DI
5138 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5139 (match_operand:SI 2 "register_operand" "r"))
5140 (match_operand:SI 3 "immediate_operand" "i"))))]
5141 "TARGET_64BIT"
5142 "#"
5143 "&& reload_completed"
5144 [(set (match_dup 0)
5145 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5146 (match_dup 2))
5147 (match_dup 3)) 0)))]
5148 {
5149 operands[1] = gen_lowpart (Pmode, operands[1]);
5150 operands[2] = gen_lowpart (Pmode, operands[2]);
5151 operands[3] = gen_lowpart (Pmode, operands[3]);
5152 }
5153 [(set_attr "type" "lea")
5154 (set_attr "mode" "SI")])
5155
5156 (define_insn_and_split "*lea_general_2"
5157 [(set (match_operand 0 "register_operand" "=r")
5158 (plus (mult (match_operand 1 "index_register_operand" "l")
5159 (match_operand 2 "const248_operand" "i"))
5160 (match_operand 3 "nonmemory_operand" "ri")))]
5161 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5162 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5163 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5164 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5165 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5166 || GET_MODE (operands[3]) == VOIDmode)"
5167 "#"
5168 "&& reload_completed"
5169 [(const_int 0)]
5170 {
5171 rtx pat;
5172 operands[0] = gen_lowpart (SImode, operands[0]);
5173 operands[1] = gen_lowpart (Pmode, operands[1]);
5174 operands[3] = gen_lowpart (Pmode, operands[3]);
5175 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5176 operands[3]);
5177 if (Pmode != SImode)
5178 pat = gen_rtx_SUBREG (SImode, pat, 0);
5179 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5180 DONE;
5181 }
5182 [(set_attr "type" "lea")
5183 (set_attr "mode" "SI")])
5184
5185 (define_insn_and_split "*lea_general_2_zext"
5186 [(set (match_operand:DI 0 "register_operand" "=r")
5187 (zero_extend:DI
5188 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5189 (match_operand:SI 2 "const248_operand" "n"))
5190 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5191 "TARGET_64BIT"
5192 "#"
5193 "&& reload_completed"
5194 [(set (match_dup 0)
5195 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5196 (match_dup 2))
5197 (match_dup 3)) 0)))]
5198 {
5199 operands[1] = gen_lowpart (Pmode, operands[1]);
5200 operands[3] = gen_lowpart (Pmode, operands[3]);
5201 }
5202 [(set_attr "type" "lea")
5203 (set_attr "mode" "SI")])
5204
5205 (define_insn_and_split "*lea_general_3"
5206 [(set (match_operand 0 "register_operand" "=r")
5207 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5208 (match_operand 2 "const248_operand" "i"))
5209 (match_operand 3 "register_operand" "r"))
5210 (match_operand 4 "immediate_operand" "i")))]
5211 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5212 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5213 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5214 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5215 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5216 "#"
5217 "&& reload_completed"
5218 [(const_int 0)]
5219 {
5220 rtx pat;
5221 operands[0] = gen_lowpart (SImode, operands[0]);
5222 operands[1] = gen_lowpart (Pmode, operands[1]);
5223 operands[3] = gen_lowpart (Pmode, operands[3]);
5224 operands[4] = gen_lowpart (Pmode, operands[4]);
5225 pat = gen_rtx_PLUS (Pmode,
5226 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5227 operands[2]),
5228 operands[3]),
5229 operands[4]);
5230 if (Pmode != SImode)
5231 pat = gen_rtx_SUBREG (SImode, pat, 0);
5232 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5233 DONE;
5234 }
5235 [(set_attr "type" "lea")
5236 (set_attr "mode" "SI")])
5237
5238 (define_insn_and_split "*lea_general_3_zext"
5239 [(set (match_operand:DI 0 "register_operand" "=r")
5240 (zero_extend:DI
5241 (plus:SI (plus:SI (mult:SI
5242 (match_operand:SI 1 "index_register_operand" "l")
5243 (match_operand:SI 2 "const248_operand" "n"))
5244 (match_operand:SI 3 "register_operand" "r"))
5245 (match_operand:SI 4 "immediate_operand" "i"))))]
5246 "TARGET_64BIT"
5247 "#"
5248 "&& reload_completed"
5249 [(set (match_dup 0)
5250 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5251 (match_dup 2))
5252 (match_dup 3))
5253 (match_dup 4)) 0)))]
5254 {
5255 operands[1] = gen_lowpart (Pmode, operands[1]);
5256 operands[3] = gen_lowpart (Pmode, operands[3]);
5257 operands[4] = gen_lowpart (Pmode, operands[4]);
5258 }
5259 [(set_attr "type" "lea")
5260 (set_attr "mode" "SI")])
5261
5262 (define_insn "*adddi_1_rex64"
5263 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5264 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5265 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5266 (clobber (reg:CC FLAGS_REG))]
5267 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5268 {
5269 switch (get_attr_type (insn))
5270 {
5271 case TYPE_LEA:
5272 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5273 return "lea{q}\t{%a2, %0|%0, %a2}";
5274
5275 case TYPE_INCDEC:
5276 if (! rtx_equal_p (operands[0], operands[1]))
5277 abort ();
5278 if (operands[2] == const1_rtx)
5279 return "inc{q}\t%0";
5280 else if (operands[2] == constm1_rtx)
5281 return "dec{q}\t%0";
5282 else
5283 abort ();
5284
5285 default:
5286 if (! rtx_equal_p (operands[0], operands[1]))
5287 abort ();
5288
5289 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5290 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5291 if (GET_CODE (operands[2]) == CONST_INT
5292 /* Avoid overflows. */
5293 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5294 && (INTVAL (operands[2]) == 128
5295 || (INTVAL (operands[2]) < 0
5296 && INTVAL (operands[2]) != -128)))
5297 {
5298 operands[2] = GEN_INT (-INTVAL (operands[2]));
5299 return "sub{q}\t{%2, %0|%0, %2}";
5300 }
5301 return "add{q}\t{%2, %0|%0, %2}";
5302 }
5303 }
5304 [(set (attr "type")
5305 (cond [(eq_attr "alternative" "2")
5306 (const_string "lea")
5307 ; Current assemblers are broken and do not allow @GOTOFF in
5308 ; ought but a memory context.
5309 (match_operand:DI 2 "pic_symbolic_operand" "")
5310 (const_string "lea")
5311 (match_operand:DI 2 "incdec_operand" "")
5312 (const_string "incdec")
5313 ]
5314 (const_string "alu")))
5315 (set_attr "mode" "DI")])
5316
5317 ;; Convert lea to the lea pattern to avoid flags dependency.
5318 (define_split
5319 [(set (match_operand:DI 0 "register_operand" "")
5320 (plus:DI (match_operand:DI 1 "register_operand" "")
5321 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5322 (clobber (reg:CC FLAGS_REG))]
5323 "TARGET_64BIT && reload_completed
5324 && true_regnum (operands[0]) != true_regnum (operands[1])"
5325 [(set (match_dup 0)
5326 (plus:DI (match_dup 1)
5327 (match_dup 2)))]
5328 "")
5329
5330 (define_insn "*adddi_2_rex64"
5331 [(set (reg FLAGS_REG)
5332 (compare
5333 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5334 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5335 (const_int 0)))
5336 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5337 (plus:DI (match_dup 1) (match_dup 2)))]
5338 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5339 && ix86_binary_operator_ok (PLUS, DImode, operands)
5340 /* Current assemblers are broken and do not allow @GOTOFF in
5341 ought but a memory context. */
5342 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5343 {
5344 switch (get_attr_type (insn))
5345 {
5346 case TYPE_INCDEC:
5347 if (! rtx_equal_p (operands[0], operands[1]))
5348 abort ();
5349 if (operands[2] == const1_rtx)
5350 return "inc{q}\t%0";
5351 else if (operands[2] == constm1_rtx)
5352 return "dec{q}\t%0";
5353 else
5354 abort ();
5355
5356 default:
5357 if (! rtx_equal_p (operands[0], operands[1]))
5358 abort ();
5359 /* ???? We ought to handle there the 32bit case too
5360 - do we need new constraint? */
5361 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5363 if (GET_CODE (operands[2]) == CONST_INT
5364 /* Avoid overflows. */
5365 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366 && (INTVAL (operands[2]) == 128
5367 || (INTVAL (operands[2]) < 0
5368 && INTVAL (operands[2]) != -128)))
5369 {
5370 operands[2] = GEN_INT (-INTVAL (operands[2]));
5371 return "sub{q}\t{%2, %0|%0, %2}";
5372 }
5373 return "add{q}\t{%2, %0|%0, %2}";
5374 }
5375 }
5376 [(set (attr "type")
5377 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378 (const_string "incdec")
5379 (const_string "alu")))
5380 (set_attr "mode" "DI")])
5381
5382 (define_insn "*adddi_3_rex64"
5383 [(set (reg FLAGS_REG)
5384 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5385 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5386 (clobber (match_scratch:DI 0 "=r"))]
5387 "TARGET_64BIT
5388 && ix86_match_ccmode (insn, CCZmode)
5389 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5390 /* Current assemblers are broken and do not allow @GOTOFF in
5391 ought but a memory context. */
5392 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5393 {
5394 switch (get_attr_type (insn))
5395 {
5396 case TYPE_INCDEC:
5397 if (! rtx_equal_p (operands[0], operands[1]))
5398 abort ();
5399 if (operands[2] == const1_rtx)
5400 return "inc{q}\t%0";
5401 else if (operands[2] == constm1_rtx)
5402 return "dec{q}\t%0";
5403 else
5404 abort ();
5405
5406 default:
5407 if (! rtx_equal_p (operands[0], operands[1]))
5408 abort ();
5409 /* ???? We ought to handle there the 32bit case too
5410 - do we need new constraint? */
5411 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5412 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5413 if (GET_CODE (operands[2]) == CONST_INT
5414 /* Avoid overflows. */
5415 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5416 && (INTVAL (operands[2]) == 128
5417 || (INTVAL (operands[2]) < 0
5418 && INTVAL (operands[2]) != -128)))
5419 {
5420 operands[2] = GEN_INT (-INTVAL (operands[2]));
5421 return "sub{q}\t{%2, %0|%0, %2}";
5422 }
5423 return "add{q}\t{%2, %0|%0, %2}";
5424 }
5425 }
5426 [(set (attr "type")
5427 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5428 (const_string "incdec")
5429 (const_string "alu")))
5430 (set_attr "mode" "DI")])
5431
5432 ; For comparisons against 1, -1 and 128, we may generate better code
5433 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5434 ; is matched then. We can't accept general immediate, because for
5435 ; case of overflows, the result is messed up.
5436 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5437 ; when negated.
5438 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5439 ; only for comparisons not depending on it.
5440 (define_insn "*adddi_4_rex64"
5441 [(set (reg FLAGS_REG)
5442 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5443 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5444 (clobber (match_scratch:DI 0 "=rm"))]
5445 "TARGET_64BIT
5446 && ix86_match_ccmode (insn, CCGCmode)"
5447 {
5448 switch (get_attr_type (insn))
5449 {
5450 case TYPE_INCDEC:
5451 if (operands[2] == constm1_rtx)
5452 return "inc{q}\t%0";
5453 else if (operands[2] == const1_rtx)
5454 return "dec{q}\t%0";
5455 else
5456 abort();
5457
5458 default:
5459 if (! rtx_equal_p (operands[0], operands[1]))
5460 abort ();
5461 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5462 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5463 if ((INTVAL (operands[2]) == -128
5464 || (INTVAL (operands[2]) > 0
5465 && INTVAL (operands[2]) != 128))
5466 /* Avoid overflows. */
5467 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5468 return "sub{q}\t{%2, %0|%0, %2}";
5469 operands[2] = GEN_INT (-INTVAL (operands[2]));
5470 return "add{q}\t{%2, %0|%0, %2}";
5471 }
5472 }
5473 [(set (attr "type")
5474 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5475 (const_string "incdec")
5476 (const_string "alu")))
5477 (set_attr "mode" "DI")])
5478
5479 (define_insn "*adddi_5_rex64"
5480 [(set (reg FLAGS_REG)
5481 (compare
5482 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5483 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5484 (const_int 0)))
5485 (clobber (match_scratch:DI 0 "=r"))]
5486 "TARGET_64BIT
5487 && ix86_match_ccmode (insn, CCGOCmode)
5488 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5489 /* Current assemblers are broken and do not allow @GOTOFF in
5490 ought but a memory context. */
5491 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5492 {
5493 switch (get_attr_type (insn))
5494 {
5495 case TYPE_INCDEC:
5496 if (! rtx_equal_p (operands[0], operands[1]))
5497 abort ();
5498 if (operands[2] == const1_rtx)
5499 return "inc{q}\t%0";
5500 else if (operands[2] == constm1_rtx)
5501 return "dec{q}\t%0";
5502 else
5503 abort();
5504
5505 default:
5506 if (! rtx_equal_p (operands[0], operands[1]))
5507 abort ();
5508 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5509 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5510 if (GET_CODE (operands[2]) == CONST_INT
5511 /* Avoid overflows. */
5512 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5513 && (INTVAL (operands[2]) == 128
5514 || (INTVAL (operands[2]) < 0
5515 && INTVAL (operands[2]) != -128)))
5516 {
5517 operands[2] = GEN_INT (-INTVAL (operands[2]));
5518 return "sub{q}\t{%2, %0|%0, %2}";
5519 }
5520 return "add{q}\t{%2, %0|%0, %2}";
5521 }
5522 }
5523 [(set (attr "type")
5524 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5525 (const_string "incdec")
5526 (const_string "alu")))
5527 (set_attr "mode" "DI")])
5528
5529
5530 (define_insn "*addsi_1"
5531 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5532 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5533 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5534 (clobber (reg:CC FLAGS_REG))]
5535 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5536 {
5537 switch (get_attr_type (insn))
5538 {
5539 case TYPE_LEA:
5540 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5541 return "lea{l}\t{%a2, %0|%0, %a2}";
5542
5543 case TYPE_INCDEC:
5544 if (! rtx_equal_p (operands[0], operands[1]))
5545 abort ();
5546 if (operands[2] == const1_rtx)
5547 return "inc{l}\t%0";
5548 else if (operands[2] == constm1_rtx)
5549 return "dec{l}\t%0";
5550 else
5551 abort();
5552
5553 default:
5554 if (! rtx_equal_p (operands[0], operands[1]))
5555 abort ();
5556
5557 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5558 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5559 if (GET_CODE (operands[2]) == CONST_INT
5560 && (INTVAL (operands[2]) == 128
5561 || (INTVAL (operands[2]) < 0
5562 && INTVAL (operands[2]) != -128)))
5563 {
5564 operands[2] = GEN_INT (-INTVAL (operands[2]));
5565 return "sub{l}\t{%2, %0|%0, %2}";
5566 }
5567 return "add{l}\t{%2, %0|%0, %2}";
5568 }
5569 }
5570 [(set (attr "type")
5571 (cond [(eq_attr "alternative" "2")
5572 (const_string "lea")
5573 ; Current assemblers are broken and do not allow @GOTOFF in
5574 ; ought but a memory context.
5575 (match_operand:SI 2 "pic_symbolic_operand" "")
5576 (const_string "lea")
5577 (match_operand:SI 2 "incdec_operand" "")
5578 (const_string "incdec")
5579 ]
5580 (const_string "alu")))
5581 (set_attr "mode" "SI")])
5582
5583 ;; Convert lea to the lea pattern to avoid flags dependency.
5584 (define_split
5585 [(set (match_operand 0 "register_operand" "")
5586 (plus (match_operand 1 "register_operand" "")
5587 (match_operand 2 "nonmemory_operand" "")))
5588 (clobber (reg:CC FLAGS_REG))]
5589 "reload_completed
5590 && true_regnum (operands[0]) != true_regnum (operands[1])"
5591 [(const_int 0)]
5592 {
5593 rtx pat;
5594 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5595 may confuse gen_lowpart. */
5596 if (GET_MODE (operands[0]) != Pmode)
5597 {
5598 operands[1] = gen_lowpart (Pmode, operands[1]);
5599 operands[2] = gen_lowpart (Pmode, operands[2]);
5600 }
5601 operands[0] = gen_lowpart (SImode, operands[0]);
5602 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5603 if (Pmode != SImode)
5604 pat = gen_rtx_SUBREG (SImode, pat, 0);
5605 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5606 DONE;
5607 })
5608
5609 ;; It may seem that nonimmediate operand is proper one for operand 1.
5610 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5611 ;; we take care in ix86_binary_operator_ok to not allow two memory
5612 ;; operands so proper swapping will be done in reload. This allow
5613 ;; patterns constructed from addsi_1 to match.
5614 (define_insn "addsi_1_zext"
5615 [(set (match_operand:DI 0 "register_operand" "=r,r")
5616 (zero_extend:DI
5617 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5618 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5619 (clobber (reg:CC FLAGS_REG))]
5620 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5621 {
5622 switch (get_attr_type (insn))
5623 {
5624 case TYPE_LEA:
5625 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5626 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5627
5628 case TYPE_INCDEC:
5629 if (operands[2] == const1_rtx)
5630 return "inc{l}\t%k0";
5631 else if (operands[2] == constm1_rtx)
5632 return "dec{l}\t%k0";
5633 else
5634 abort();
5635
5636 default:
5637 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5638 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5639 if (GET_CODE (operands[2]) == CONST_INT
5640 && (INTVAL (operands[2]) == 128
5641 || (INTVAL (operands[2]) < 0
5642 && INTVAL (operands[2]) != -128)))
5643 {
5644 operands[2] = GEN_INT (-INTVAL (operands[2]));
5645 return "sub{l}\t{%2, %k0|%k0, %2}";
5646 }
5647 return "add{l}\t{%2, %k0|%k0, %2}";
5648 }
5649 }
5650 [(set (attr "type")
5651 (cond [(eq_attr "alternative" "1")
5652 (const_string "lea")
5653 ; Current assemblers are broken and do not allow @GOTOFF in
5654 ; ought but a memory context.
5655 (match_operand:SI 2 "pic_symbolic_operand" "")
5656 (const_string "lea")
5657 (match_operand:SI 2 "incdec_operand" "")
5658 (const_string "incdec")
5659 ]
5660 (const_string "alu")))
5661 (set_attr "mode" "SI")])
5662
5663 ;; Convert lea to the lea pattern to avoid flags dependency.
5664 (define_split
5665 [(set (match_operand:DI 0 "register_operand" "")
5666 (zero_extend:DI
5667 (plus:SI (match_operand:SI 1 "register_operand" "")
5668 (match_operand:SI 2 "nonmemory_operand" ""))))
5669 (clobber (reg:CC FLAGS_REG))]
5670 "TARGET_64BIT && reload_completed
5671 && true_regnum (operands[0]) != true_regnum (operands[1])"
5672 [(set (match_dup 0)
5673 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5674 {
5675 operands[1] = gen_lowpart (Pmode, operands[1]);
5676 operands[2] = gen_lowpart (Pmode, operands[2]);
5677 })
5678
5679 (define_insn "*addsi_2"
5680 [(set (reg FLAGS_REG)
5681 (compare
5682 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5683 (match_operand:SI 2 "general_operand" "rmni,rni"))
5684 (const_int 0)))
5685 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5686 (plus:SI (match_dup 1) (match_dup 2)))]
5687 "ix86_match_ccmode (insn, CCGOCmode)
5688 && ix86_binary_operator_ok (PLUS, SImode, operands)
5689 /* Current assemblers are broken and do not allow @GOTOFF in
5690 ought but a memory context. */
5691 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5692 {
5693 switch (get_attr_type (insn))
5694 {
5695 case TYPE_INCDEC:
5696 if (! rtx_equal_p (operands[0], operands[1]))
5697 abort ();
5698 if (operands[2] == const1_rtx)
5699 return "inc{l}\t%0";
5700 else if (operands[2] == constm1_rtx)
5701 return "dec{l}\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 (GET_CODE (operands[2]) == CONST_INT
5711 && (INTVAL (operands[2]) == 128
5712 || (INTVAL (operands[2]) < 0
5713 && INTVAL (operands[2]) != -128)))
5714 {
5715 operands[2] = GEN_INT (-INTVAL (operands[2]));
5716 return "sub{l}\t{%2, %0|%0, %2}";
5717 }
5718 return "add{l}\t{%2, %0|%0, %2}";
5719 }
5720 }
5721 [(set (attr "type")
5722 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5723 (const_string "incdec")
5724 (const_string "alu")))
5725 (set_attr "mode" "SI")])
5726
5727 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5728 (define_insn "*addsi_2_zext"
5729 [(set (reg FLAGS_REG)
5730 (compare
5731 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5732 (match_operand:SI 2 "general_operand" "rmni"))
5733 (const_int 0)))
5734 (set (match_operand:DI 0 "register_operand" "=r")
5735 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5736 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5737 && ix86_binary_operator_ok (PLUS, SImode, operands)
5738 /* Current assemblers are broken and do not allow @GOTOFF in
5739 ought but a memory context. */
5740 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5741 {
5742 switch (get_attr_type (insn))
5743 {
5744 case TYPE_INCDEC:
5745 if (operands[2] == const1_rtx)
5746 return "inc{l}\t%k0";
5747 else if (operands[2] == constm1_rtx)
5748 return "dec{l}\t%k0";
5749 else
5750 abort();
5751
5752 default:
5753 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5754 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5755 if (GET_CODE (operands[2]) == CONST_INT
5756 && (INTVAL (operands[2]) == 128
5757 || (INTVAL (operands[2]) < 0
5758 && INTVAL (operands[2]) != -128)))
5759 {
5760 operands[2] = GEN_INT (-INTVAL (operands[2]));
5761 return "sub{l}\t{%2, %k0|%k0, %2}";
5762 }
5763 return "add{l}\t{%2, %k0|%k0, %2}";
5764 }
5765 }
5766 [(set (attr "type")
5767 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5768 (const_string "incdec")
5769 (const_string "alu")))
5770 (set_attr "mode" "SI")])
5771
5772 (define_insn "*addsi_3"
5773 [(set (reg FLAGS_REG)
5774 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5775 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5776 (clobber (match_scratch:SI 0 "=r"))]
5777 "ix86_match_ccmode (insn, CCZmode)
5778 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5779 /* Current assemblers are broken and do not allow @GOTOFF in
5780 ought but a memory context. */
5781 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5782 {
5783 switch (get_attr_type (insn))
5784 {
5785 case TYPE_INCDEC:
5786 if (! rtx_equal_p (operands[0], operands[1]))
5787 abort ();
5788 if (operands[2] == const1_rtx)
5789 return "inc{l}\t%0";
5790 else if (operands[2] == constm1_rtx)
5791 return "dec{l}\t%0";
5792 else
5793 abort();
5794
5795 default:
5796 if (! rtx_equal_p (operands[0], operands[1]))
5797 abort ();
5798 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5800 if (GET_CODE (operands[2]) == CONST_INT
5801 && (INTVAL (operands[2]) == 128
5802 || (INTVAL (operands[2]) < 0
5803 && INTVAL (operands[2]) != -128)))
5804 {
5805 operands[2] = GEN_INT (-INTVAL (operands[2]));
5806 return "sub{l}\t{%2, %0|%0, %2}";
5807 }
5808 return "add{l}\t{%2, %0|%0, %2}";
5809 }
5810 }
5811 [(set (attr "type")
5812 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5813 (const_string "incdec")
5814 (const_string "alu")))
5815 (set_attr "mode" "SI")])
5816
5817 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5818 (define_insn "*addsi_3_zext"
5819 [(set (reg FLAGS_REG)
5820 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5821 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5822 (set (match_operand:DI 0 "register_operand" "=r")
5823 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5824 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5825 && ix86_binary_operator_ok (PLUS, SImode, operands)
5826 /* Current assemblers are broken and do not allow @GOTOFF in
5827 ought but a memory context. */
5828 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5829 {
5830 switch (get_attr_type (insn))
5831 {
5832 case TYPE_INCDEC:
5833 if (operands[2] == const1_rtx)
5834 return "inc{l}\t%k0";
5835 else if (operands[2] == constm1_rtx)
5836 return "dec{l}\t%k0";
5837 else
5838 abort();
5839
5840 default:
5841 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5843 if (GET_CODE (operands[2]) == CONST_INT
5844 && (INTVAL (operands[2]) == 128
5845 || (INTVAL (operands[2]) < 0
5846 && INTVAL (operands[2]) != -128)))
5847 {
5848 operands[2] = GEN_INT (-INTVAL (operands[2]));
5849 return "sub{l}\t{%2, %k0|%k0, %2}";
5850 }
5851 return "add{l}\t{%2, %k0|%k0, %2}";
5852 }
5853 }
5854 [(set (attr "type")
5855 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5856 (const_string "incdec")
5857 (const_string "alu")))
5858 (set_attr "mode" "SI")])
5859
5860 ; For comparisons against 1, -1 and 128, we may generate better code
5861 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5862 ; is matched then. We can't accept general immediate, because for
5863 ; case of overflows, the result is messed up.
5864 ; This pattern also don't hold of 0x80000000, since the value overflows
5865 ; when negated.
5866 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5867 ; only for comparisons not depending on it.
5868 (define_insn "*addsi_4"
5869 [(set (reg FLAGS_REG)
5870 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5871 (match_operand:SI 2 "const_int_operand" "n")))
5872 (clobber (match_scratch:SI 0 "=rm"))]
5873 "ix86_match_ccmode (insn, CCGCmode)
5874 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5875 {
5876 switch (get_attr_type (insn))
5877 {
5878 case TYPE_INCDEC:
5879 if (operands[2] == constm1_rtx)
5880 return "inc{l}\t%0";
5881 else if (operands[2] == const1_rtx)
5882 return "dec{l}\t%0";
5883 else
5884 abort();
5885
5886 default:
5887 if (! rtx_equal_p (operands[0], operands[1]))
5888 abort ();
5889 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5890 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5891 if ((INTVAL (operands[2]) == -128
5892 || (INTVAL (operands[2]) > 0
5893 && INTVAL (operands[2]) != 128)))
5894 return "sub{l}\t{%2, %0|%0, %2}";
5895 operands[2] = GEN_INT (-INTVAL (operands[2]));
5896 return "add{l}\t{%2, %0|%0, %2}";
5897 }
5898 }
5899 [(set (attr "type")
5900 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "SI")])
5904
5905 (define_insn "*addsi_5"
5906 [(set (reg FLAGS_REG)
5907 (compare
5908 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5909 (match_operand:SI 2 "general_operand" "rmni"))
5910 (const_int 0)))
5911 (clobber (match_scratch:SI 0 "=r"))]
5912 "ix86_match_ccmode (insn, CCGOCmode)
5913 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5914 /* Current assemblers are broken and do not allow @GOTOFF in
5915 ought but a memory context. */
5916 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5917 {
5918 switch (get_attr_type (insn))
5919 {
5920 case TYPE_INCDEC:
5921 if (! rtx_equal_p (operands[0], operands[1]))
5922 abort ();
5923 if (operands[2] == const1_rtx)
5924 return "inc{l}\t%0";
5925 else if (operands[2] == constm1_rtx)
5926 return "dec{l}\t%0";
5927 else
5928 abort();
5929
5930 default:
5931 if (! rtx_equal_p (operands[0], operands[1]))
5932 abort ();
5933 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5934 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5935 if (GET_CODE (operands[2]) == CONST_INT
5936 && (INTVAL (operands[2]) == 128
5937 || (INTVAL (operands[2]) < 0
5938 && INTVAL (operands[2]) != -128)))
5939 {
5940 operands[2] = GEN_INT (-INTVAL (operands[2]));
5941 return "sub{l}\t{%2, %0|%0, %2}";
5942 }
5943 return "add{l}\t{%2, %0|%0, %2}";
5944 }
5945 }
5946 [(set (attr "type")
5947 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5948 (const_string "incdec")
5949 (const_string "alu")))
5950 (set_attr "mode" "SI")])
5951
5952 (define_expand "addhi3"
5953 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5954 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5955 (match_operand:HI 2 "general_operand" "")))
5956 (clobber (reg:CC FLAGS_REG))])]
5957 "TARGET_HIMODE_MATH"
5958 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5959
5960 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5961 ;; type optimizations enabled by define-splits. This is not important
5962 ;; for PII, and in fact harmful because of partial register stalls.
5963
5964 (define_insn "*addhi_1_lea"
5965 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5966 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5967 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5968 (clobber (reg:CC FLAGS_REG))]
5969 "!TARGET_PARTIAL_REG_STALL
5970 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5971 {
5972 switch (get_attr_type (insn))
5973 {
5974 case TYPE_LEA:
5975 return "#";
5976 case TYPE_INCDEC:
5977 if (operands[2] == const1_rtx)
5978 return "inc{w}\t%0";
5979 else if (operands[2] == constm1_rtx)
5980 return "dec{w}\t%0";
5981 abort();
5982
5983 default:
5984 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5985 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5986 if (GET_CODE (operands[2]) == CONST_INT
5987 && (INTVAL (operands[2]) == 128
5988 || (INTVAL (operands[2]) < 0
5989 && INTVAL (operands[2]) != -128)))
5990 {
5991 operands[2] = GEN_INT (-INTVAL (operands[2]));
5992 return "sub{w}\t{%2, %0|%0, %2}";
5993 }
5994 return "add{w}\t{%2, %0|%0, %2}";
5995 }
5996 }
5997 [(set (attr "type")
5998 (if_then_else (eq_attr "alternative" "2")
5999 (const_string "lea")
6000 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6001 (const_string "incdec")
6002 (const_string "alu"))))
6003 (set_attr "mode" "HI,HI,SI")])
6004
6005 (define_insn "*addhi_1"
6006 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6007 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6008 (match_operand:HI 2 "general_operand" "ri,rm")))
6009 (clobber (reg:CC FLAGS_REG))]
6010 "TARGET_PARTIAL_REG_STALL
6011 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6012 {
6013 switch (get_attr_type (insn))
6014 {
6015 case TYPE_INCDEC:
6016 if (operands[2] == const1_rtx)
6017 return "inc{w}\t%0";
6018 else if (operands[2] == constm1_rtx)
6019 return "dec{w}\t%0";
6020 abort();
6021
6022 default:
6023 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6024 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6025 if (GET_CODE (operands[2]) == CONST_INT
6026 && (INTVAL (operands[2]) == 128
6027 || (INTVAL (operands[2]) < 0
6028 && INTVAL (operands[2]) != -128)))
6029 {
6030 operands[2] = GEN_INT (-INTVAL (operands[2]));
6031 return "sub{w}\t{%2, %0|%0, %2}";
6032 }
6033 return "add{w}\t{%2, %0|%0, %2}";
6034 }
6035 }
6036 [(set (attr "type")
6037 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6038 (const_string "incdec")
6039 (const_string "alu")))
6040 (set_attr "mode" "HI")])
6041
6042 (define_insn "*addhi_2"
6043 [(set (reg FLAGS_REG)
6044 (compare
6045 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6046 (match_operand:HI 2 "general_operand" "rmni,rni"))
6047 (const_int 0)))
6048 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6049 (plus:HI (match_dup 1) (match_dup 2)))]
6050 "ix86_match_ccmode (insn, CCGOCmode)
6051 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6052 {
6053 switch (get_attr_type (insn))
6054 {
6055 case TYPE_INCDEC:
6056 if (operands[2] == const1_rtx)
6057 return "inc{w}\t%0";
6058 else if (operands[2] == constm1_rtx)
6059 return "dec{w}\t%0";
6060 abort();
6061
6062 default:
6063 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6065 if (GET_CODE (operands[2]) == CONST_INT
6066 && (INTVAL (operands[2]) == 128
6067 || (INTVAL (operands[2]) < 0
6068 && INTVAL (operands[2]) != -128)))
6069 {
6070 operands[2] = GEN_INT (-INTVAL (operands[2]));
6071 return "sub{w}\t{%2, %0|%0, %2}";
6072 }
6073 return "add{w}\t{%2, %0|%0, %2}";
6074 }
6075 }
6076 [(set (attr "type")
6077 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078 (const_string "incdec")
6079 (const_string "alu")))
6080 (set_attr "mode" "HI")])
6081
6082 (define_insn "*addhi_3"
6083 [(set (reg FLAGS_REG)
6084 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6085 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6086 (clobber (match_scratch:HI 0 "=r"))]
6087 "ix86_match_ccmode (insn, CCZmode)
6088 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6089 {
6090 switch (get_attr_type (insn))
6091 {
6092 case TYPE_INCDEC:
6093 if (operands[2] == const1_rtx)
6094 return "inc{w}\t%0";
6095 else if (operands[2] == constm1_rtx)
6096 return "dec{w}\t%0";
6097 abort();
6098
6099 default:
6100 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6102 if (GET_CODE (operands[2]) == CONST_INT
6103 && (INTVAL (operands[2]) == 128
6104 || (INTVAL (operands[2]) < 0
6105 && INTVAL (operands[2]) != -128)))
6106 {
6107 operands[2] = GEN_INT (-INTVAL (operands[2]));
6108 return "sub{w}\t{%2, %0|%0, %2}";
6109 }
6110 return "add{w}\t{%2, %0|%0, %2}";
6111 }
6112 }
6113 [(set (attr "type")
6114 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6115 (const_string "incdec")
6116 (const_string "alu")))
6117 (set_attr "mode" "HI")])
6118
6119 ; See comments above addsi_3_imm for details.
6120 (define_insn "*addhi_4"
6121 [(set (reg FLAGS_REG)
6122 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6123 (match_operand:HI 2 "const_int_operand" "n")))
6124 (clobber (match_scratch:HI 0 "=rm"))]
6125 "ix86_match_ccmode (insn, CCGCmode)
6126 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6127 {
6128 switch (get_attr_type (insn))
6129 {
6130 case TYPE_INCDEC:
6131 if (operands[2] == constm1_rtx)
6132 return "inc{w}\t%0";
6133 else if (operands[2] == const1_rtx)
6134 return "dec{w}\t%0";
6135 else
6136 abort();
6137
6138 default:
6139 if (! rtx_equal_p (operands[0], operands[1]))
6140 abort ();
6141 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6143 if ((INTVAL (operands[2]) == -128
6144 || (INTVAL (operands[2]) > 0
6145 && INTVAL (operands[2]) != 128)))
6146 return "sub{w}\t{%2, %0|%0, %2}";
6147 operands[2] = GEN_INT (-INTVAL (operands[2]));
6148 return "add{w}\t{%2, %0|%0, %2}";
6149 }
6150 }
6151 [(set (attr "type")
6152 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6153 (const_string "incdec")
6154 (const_string "alu")))
6155 (set_attr "mode" "SI")])
6156
6157
6158 (define_insn "*addhi_5"
6159 [(set (reg FLAGS_REG)
6160 (compare
6161 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6162 (match_operand:HI 2 "general_operand" "rmni"))
6163 (const_int 0)))
6164 (clobber (match_scratch:HI 0 "=r"))]
6165 "ix86_match_ccmode (insn, CCGOCmode)
6166 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6167 {
6168 switch (get_attr_type (insn))
6169 {
6170 case TYPE_INCDEC:
6171 if (operands[2] == const1_rtx)
6172 return "inc{w}\t%0";
6173 else if (operands[2] == constm1_rtx)
6174 return "dec{w}\t%0";
6175 abort();
6176
6177 default:
6178 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6179 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6180 if (GET_CODE (operands[2]) == CONST_INT
6181 && (INTVAL (operands[2]) == 128
6182 || (INTVAL (operands[2]) < 0
6183 && INTVAL (operands[2]) != -128)))
6184 {
6185 operands[2] = GEN_INT (-INTVAL (operands[2]));
6186 return "sub{w}\t{%2, %0|%0, %2}";
6187 }
6188 return "add{w}\t{%2, %0|%0, %2}";
6189 }
6190 }
6191 [(set (attr "type")
6192 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6193 (const_string "incdec")
6194 (const_string "alu")))
6195 (set_attr "mode" "HI")])
6196
6197 (define_expand "addqi3"
6198 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6199 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6200 (match_operand:QI 2 "general_operand" "")))
6201 (clobber (reg:CC FLAGS_REG))])]
6202 "TARGET_QIMODE_MATH"
6203 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6204
6205 ;; %%% Potential partial reg stall on alternative 2. What to do?
6206 (define_insn "*addqi_1_lea"
6207 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6208 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6209 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6210 (clobber (reg:CC FLAGS_REG))]
6211 "!TARGET_PARTIAL_REG_STALL
6212 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6213 {
6214 int widen = (which_alternative == 2);
6215 switch (get_attr_type (insn))
6216 {
6217 case TYPE_LEA:
6218 return "#";
6219 case TYPE_INCDEC:
6220 if (operands[2] == const1_rtx)
6221 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6222 else if (operands[2] == constm1_rtx)
6223 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6224 abort();
6225
6226 default:
6227 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6228 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6229 if (GET_CODE (operands[2]) == CONST_INT
6230 && (INTVAL (operands[2]) == 128
6231 || (INTVAL (operands[2]) < 0
6232 && INTVAL (operands[2]) != -128)))
6233 {
6234 operands[2] = GEN_INT (-INTVAL (operands[2]));
6235 if (widen)
6236 return "sub{l}\t{%2, %k0|%k0, %2}";
6237 else
6238 return "sub{b}\t{%2, %0|%0, %2}";
6239 }
6240 if (widen)
6241 return "add{l}\t{%k2, %k0|%k0, %k2}";
6242 else
6243 return "add{b}\t{%2, %0|%0, %2}";
6244 }
6245 }
6246 [(set (attr "type")
6247 (if_then_else (eq_attr "alternative" "3")
6248 (const_string "lea")
6249 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250 (const_string "incdec")
6251 (const_string "alu"))))
6252 (set_attr "mode" "QI,QI,SI,SI")])
6253
6254 (define_insn "*addqi_1"
6255 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6256 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6257 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6258 (clobber (reg:CC FLAGS_REG))]
6259 "TARGET_PARTIAL_REG_STALL
6260 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6261 {
6262 int widen = (which_alternative == 2);
6263 switch (get_attr_type (insn))
6264 {
6265 case TYPE_INCDEC:
6266 if (operands[2] == const1_rtx)
6267 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6268 else if (operands[2] == constm1_rtx)
6269 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6270 abort();
6271
6272 default:
6273 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6274 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6275 if (GET_CODE (operands[2]) == CONST_INT
6276 && (INTVAL (operands[2]) == 128
6277 || (INTVAL (operands[2]) < 0
6278 && INTVAL (operands[2]) != -128)))
6279 {
6280 operands[2] = GEN_INT (-INTVAL (operands[2]));
6281 if (widen)
6282 return "sub{l}\t{%2, %k0|%k0, %2}";
6283 else
6284 return "sub{b}\t{%2, %0|%0, %2}";
6285 }
6286 if (widen)
6287 return "add{l}\t{%k2, %k0|%k0, %k2}";
6288 else
6289 return "add{b}\t{%2, %0|%0, %2}";
6290 }
6291 }
6292 [(set (attr "type")
6293 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294 (const_string "incdec")
6295 (const_string "alu")))
6296 (set_attr "mode" "QI,QI,SI")])
6297
6298 (define_insn "*addqi_1_slp"
6299 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6300 (plus:QI (match_dup 0)
6301 (match_operand:QI 1 "general_operand" "qn,qnm")))
6302 (clobber (reg:CC FLAGS_REG))]
6303 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6304 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6305 {
6306 switch (get_attr_type (insn))
6307 {
6308 case TYPE_INCDEC:
6309 if (operands[1] == const1_rtx)
6310 return "inc{b}\t%0";
6311 else if (operands[1] == constm1_rtx)
6312 return "dec{b}\t%0";
6313 abort();
6314
6315 default:
6316 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6317 if (GET_CODE (operands[1]) == CONST_INT
6318 && INTVAL (operands[1]) < 0)
6319 {
6320 operands[1] = GEN_INT (-INTVAL (operands[1]));
6321 return "sub{b}\t{%1, %0|%0, %1}";
6322 }
6323 return "add{b}\t{%1, %0|%0, %1}";
6324 }
6325 }
6326 [(set (attr "type")
6327 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6328 (const_string "incdec")
6329 (const_string "alu1")))
6330 (set_attr "mode" "QI")])
6331
6332 (define_insn "*addqi_2"
6333 [(set (reg FLAGS_REG)
6334 (compare
6335 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6336 (match_operand:QI 2 "general_operand" "qmni,qni"))
6337 (const_int 0)))
6338 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6339 (plus:QI (match_dup 1) (match_dup 2)))]
6340 "ix86_match_ccmode (insn, CCGOCmode)
6341 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6342 {
6343 switch (get_attr_type (insn))
6344 {
6345 case TYPE_INCDEC:
6346 if (operands[2] == const1_rtx)
6347 return "inc{b}\t%0";
6348 else if (operands[2] == constm1_rtx
6349 || (GET_CODE (operands[2]) == CONST_INT
6350 && INTVAL (operands[2]) == 255))
6351 return "dec{b}\t%0";
6352 abort();
6353
6354 default:
6355 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6356 if (GET_CODE (operands[2]) == CONST_INT
6357 && INTVAL (operands[2]) < 0)
6358 {
6359 operands[2] = GEN_INT (-INTVAL (operands[2]));
6360 return "sub{b}\t{%2, %0|%0, %2}";
6361 }
6362 return "add{b}\t{%2, %0|%0, %2}";
6363 }
6364 }
6365 [(set (attr "type")
6366 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6367 (const_string "incdec")
6368 (const_string "alu")))
6369 (set_attr "mode" "QI")])
6370
6371 (define_insn "*addqi_3"
6372 [(set (reg FLAGS_REG)
6373 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6374 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6375 (clobber (match_scratch:QI 0 "=q"))]
6376 "ix86_match_ccmode (insn, CCZmode)
6377 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6378 {
6379 switch (get_attr_type (insn))
6380 {
6381 case TYPE_INCDEC:
6382 if (operands[2] == const1_rtx)
6383 return "inc{b}\t%0";
6384 else if (operands[2] == constm1_rtx
6385 || (GET_CODE (operands[2]) == CONST_INT
6386 && INTVAL (operands[2]) == 255))
6387 return "dec{b}\t%0";
6388 abort();
6389
6390 default:
6391 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6392 if (GET_CODE (operands[2]) == CONST_INT
6393 && INTVAL (operands[2]) < 0)
6394 {
6395 operands[2] = GEN_INT (-INTVAL (operands[2]));
6396 return "sub{b}\t{%2, %0|%0, %2}";
6397 }
6398 return "add{b}\t{%2, %0|%0, %2}";
6399 }
6400 }
6401 [(set (attr "type")
6402 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6403 (const_string "incdec")
6404 (const_string "alu")))
6405 (set_attr "mode" "QI")])
6406
6407 ; See comments above addsi_3_imm for details.
6408 (define_insn "*addqi_4"
6409 [(set (reg FLAGS_REG)
6410 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6411 (match_operand:QI 2 "const_int_operand" "n")))
6412 (clobber (match_scratch:QI 0 "=qm"))]
6413 "ix86_match_ccmode (insn, CCGCmode)
6414 && (INTVAL (operands[2]) & 0xff) != 0x80"
6415 {
6416 switch (get_attr_type (insn))
6417 {
6418 case TYPE_INCDEC:
6419 if (operands[2] == constm1_rtx
6420 || (GET_CODE (operands[2]) == CONST_INT
6421 && INTVAL (operands[2]) == 255))
6422 return "inc{b}\t%0";
6423 else if (operands[2] == const1_rtx)
6424 return "dec{b}\t%0";
6425 else
6426 abort();
6427
6428 default:
6429 if (! rtx_equal_p (operands[0], operands[1]))
6430 abort ();
6431 if (INTVAL (operands[2]) < 0)
6432 {
6433 operands[2] = GEN_INT (-INTVAL (operands[2]));
6434 return "add{b}\t{%2, %0|%0, %2}";
6435 }
6436 return "sub{b}\t{%2, %0|%0, %2}";
6437 }
6438 }
6439 [(set (attr "type")
6440 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6441 (const_string "incdec")
6442 (const_string "alu")))
6443 (set_attr "mode" "QI")])
6444
6445
6446 (define_insn "*addqi_5"
6447 [(set (reg FLAGS_REG)
6448 (compare
6449 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6450 (match_operand:QI 2 "general_operand" "qmni"))
6451 (const_int 0)))
6452 (clobber (match_scratch:QI 0 "=q"))]
6453 "ix86_match_ccmode (insn, CCGOCmode)
6454 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6455 {
6456 switch (get_attr_type (insn))
6457 {
6458 case TYPE_INCDEC:
6459 if (operands[2] == const1_rtx)
6460 return "inc{b}\t%0";
6461 else if (operands[2] == constm1_rtx
6462 || (GET_CODE (operands[2]) == CONST_INT
6463 && INTVAL (operands[2]) == 255))
6464 return "dec{b}\t%0";
6465 abort();
6466
6467 default:
6468 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6469 if (GET_CODE (operands[2]) == CONST_INT
6470 && INTVAL (operands[2]) < 0)
6471 {
6472 operands[2] = GEN_INT (-INTVAL (operands[2]));
6473 return "sub{b}\t{%2, %0|%0, %2}";
6474 }
6475 return "add{b}\t{%2, %0|%0, %2}";
6476 }
6477 }
6478 [(set (attr "type")
6479 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6480 (const_string "incdec")
6481 (const_string "alu")))
6482 (set_attr "mode" "QI")])
6483
6484
6485 (define_insn "addqi_ext_1"
6486 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6487 (const_int 8)
6488 (const_int 8))
6489 (plus:SI
6490 (zero_extract:SI
6491 (match_operand 1 "ext_register_operand" "0")
6492 (const_int 8)
6493 (const_int 8))
6494 (match_operand:QI 2 "general_operand" "Qmn")))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "!TARGET_64BIT"
6497 {
6498 switch (get_attr_type (insn))
6499 {
6500 case TYPE_INCDEC:
6501 if (operands[2] == const1_rtx)
6502 return "inc{b}\t%h0";
6503 else if (operands[2] == constm1_rtx
6504 || (GET_CODE (operands[2]) == CONST_INT
6505 && INTVAL (operands[2]) == 255))
6506 return "dec{b}\t%h0";
6507 abort();
6508
6509 default:
6510 return "add{b}\t{%2, %h0|%h0, %2}";
6511 }
6512 }
6513 [(set (attr "type")
6514 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6515 (const_string "incdec")
6516 (const_string "alu")))
6517 (set_attr "mode" "QI")])
6518
6519 (define_insn "*addqi_ext_1_rex64"
6520 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6521 (const_int 8)
6522 (const_int 8))
6523 (plus:SI
6524 (zero_extract:SI
6525 (match_operand 1 "ext_register_operand" "0")
6526 (const_int 8)
6527 (const_int 8))
6528 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6529 (clobber (reg:CC FLAGS_REG))]
6530 "TARGET_64BIT"
6531 {
6532 switch (get_attr_type (insn))
6533 {
6534 case TYPE_INCDEC:
6535 if (operands[2] == const1_rtx)
6536 return "inc{b}\t%h0";
6537 else if (operands[2] == constm1_rtx
6538 || (GET_CODE (operands[2]) == CONST_INT
6539 && INTVAL (operands[2]) == 255))
6540 return "dec{b}\t%h0";
6541 abort();
6542
6543 default:
6544 return "add{b}\t{%2, %h0|%h0, %2}";
6545 }
6546 }
6547 [(set (attr "type")
6548 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6549 (const_string "incdec")
6550 (const_string "alu")))
6551 (set_attr "mode" "QI")])
6552
6553 (define_insn "*addqi_ext_2"
6554 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6555 (const_int 8)
6556 (const_int 8))
6557 (plus:SI
6558 (zero_extract:SI
6559 (match_operand 1 "ext_register_operand" "%0")
6560 (const_int 8)
6561 (const_int 8))
6562 (zero_extract:SI
6563 (match_operand 2 "ext_register_operand" "Q")
6564 (const_int 8)
6565 (const_int 8))))
6566 (clobber (reg:CC FLAGS_REG))]
6567 ""
6568 "add{b}\t{%h2, %h0|%h0, %h2}"
6569 [(set_attr "type" "alu")
6570 (set_attr "mode" "QI")])
6571
6572 ;; The patterns that match these are at the end of this file.
6573
6574 (define_expand "addxf3"
6575 [(set (match_operand:XF 0 "register_operand" "")
6576 (plus:XF (match_operand:XF 1 "register_operand" "")
6577 (match_operand:XF 2 "register_operand" "")))]
6578 "TARGET_80387"
6579 "")
6580
6581 (define_expand "adddf3"
6582 [(set (match_operand:DF 0 "register_operand" "")
6583 (plus:DF (match_operand:DF 1 "register_operand" "")
6584 (match_operand:DF 2 "nonimmediate_operand" "")))]
6585 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6586 "")
6587
6588 (define_expand "addsf3"
6589 [(set (match_operand:SF 0 "register_operand" "")
6590 (plus:SF (match_operand:SF 1 "register_operand" "")
6591 (match_operand:SF 2 "nonimmediate_operand" "")))]
6592 "TARGET_80387 || TARGET_SSE_MATH"
6593 "")
6594 \f
6595 ;; Subtract instructions
6596
6597 ;; %%% splits for subsidi3
6598
6599 (define_expand "subdi3"
6600 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6601 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6602 (match_operand:DI 2 "x86_64_general_operand" "")))
6603 (clobber (reg:CC FLAGS_REG))])]
6604 ""
6605 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6606
6607 (define_insn "*subdi3_1"
6608 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6609 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6610 (match_operand:DI 2 "general_operand" "roiF,riF")))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6613 "#")
6614
6615 (define_split
6616 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6617 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6618 (match_operand:DI 2 "general_operand" "")))
6619 (clobber (reg:CC FLAGS_REG))]
6620 "!TARGET_64BIT && reload_completed"
6621 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6622 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6623 (parallel [(set (match_dup 3)
6624 (minus:SI (match_dup 4)
6625 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6626 (match_dup 5))))
6627 (clobber (reg:CC FLAGS_REG))])]
6628 "split_di (operands+0, 1, operands+0, operands+3);
6629 split_di (operands+1, 1, operands+1, operands+4);
6630 split_di (operands+2, 1, operands+2, operands+5);")
6631
6632 (define_insn "subdi3_carry_rex64"
6633 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6634 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6635 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6636 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6637 (clobber (reg:CC FLAGS_REG))]
6638 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6639 "sbb{q}\t{%2, %0|%0, %2}"
6640 [(set_attr "type" "alu")
6641 (set_attr "pent_pair" "pu")
6642 (set_attr "mode" "DI")])
6643
6644 (define_insn "*subdi_1_rex64"
6645 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6646 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6647 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6648 (clobber (reg:CC FLAGS_REG))]
6649 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6650 "sub{q}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "mode" "DI")])
6653
6654 (define_insn "*subdi_2_rex64"
6655 [(set (reg FLAGS_REG)
6656 (compare
6657 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6658 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6659 (const_int 0)))
6660 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6661 (minus:DI (match_dup 1) (match_dup 2)))]
6662 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6663 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6664 "sub{q}\t{%2, %0|%0, %2}"
6665 [(set_attr "type" "alu")
6666 (set_attr "mode" "DI")])
6667
6668 (define_insn "*subdi_3_rex63"
6669 [(set (reg FLAGS_REG)
6670 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6671 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6672 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6673 (minus:DI (match_dup 1) (match_dup 2)))]
6674 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6675 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6676 "sub{q}\t{%2, %0|%0, %2}"
6677 [(set_attr "type" "alu")
6678 (set_attr "mode" "DI")])
6679
6680 (define_insn "subqi3_carry"
6681 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6682 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6683 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6684 (match_operand:QI 2 "general_operand" "qi,qm"))))
6685 (clobber (reg:CC FLAGS_REG))]
6686 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6687 "sbb{b}\t{%2, %0|%0, %2}"
6688 [(set_attr "type" "alu")
6689 (set_attr "pent_pair" "pu")
6690 (set_attr "mode" "QI")])
6691
6692 (define_insn "subhi3_carry"
6693 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6694 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6695 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6696 (match_operand:HI 2 "general_operand" "ri,rm"))))
6697 (clobber (reg:CC FLAGS_REG))]
6698 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6699 "sbb{w}\t{%2, %0|%0, %2}"
6700 [(set_attr "type" "alu")
6701 (set_attr "pent_pair" "pu")
6702 (set_attr "mode" "HI")])
6703
6704 (define_insn "subsi3_carry"
6705 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6706 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6707 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6708 (match_operand:SI 2 "general_operand" "ri,rm"))))
6709 (clobber (reg:CC FLAGS_REG))]
6710 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6711 "sbb{l}\t{%2, %0|%0, %2}"
6712 [(set_attr "type" "alu")
6713 (set_attr "pent_pair" "pu")
6714 (set_attr "mode" "SI")])
6715
6716 (define_insn "subsi3_carry_zext"
6717 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6718 (zero_extend:DI
6719 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6720 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6721 (match_operand:SI 2 "general_operand" "ri,rm")))))
6722 (clobber (reg:CC FLAGS_REG))]
6723 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6724 "sbb{l}\t{%2, %k0|%k0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "pent_pair" "pu")
6727 (set_attr "mode" "SI")])
6728
6729 (define_expand "subsi3"
6730 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6731 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6732 (match_operand:SI 2 "general_operand" "")))
6733 (clobber (reg:CC FLAGS_REG))])]
6734 ""
6735 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6736
6737 (define_insn "*subsi_1"
6738 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6739 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6740 (match_operand:SI 2 "general_operand" "ri,rm")))
6741 (clobber (reg:CC FLAGS_REG))]
6742 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6743 "sub{l}\t{%2, %0|%0, %2}"
6744 [(set_attr "type" "alu")
6745 (set_attr "mode" "SI")])
6746
6747 (define_insn "*subsi_1_zext"
6748 [(set (match_operand:DI 0 "register_operand" "=r")
6749 (zero_extend:DI
6750 (minus:SI (match_operand:SI 1 "register_operand" "0")
6751 (match_operand:SI 2 "general_operand" "rim"))))
6752 (clobber (reg:CC FLAGS_REG))]
6753 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6754 "sub{l}\t{%2, %k0|%k0, %2}"
6755 [(set_attr "type" "alu")
6756 (set_attr "mode" "SI")])
6757
6758 (define_insn "*subsi_2"
6759 [(set (reg FLAGS_REG)
6760 (compare
6761 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6762 (match_operand:SI 2 "general_operand" "ri,rm"))
6763 (const_int 0)))
6764 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6765 (minus:SI (match_dup 1) (match_dup 2)))]
6766 "ix86_match_ccmode (insn, CCGOCmode)
6767 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6768 "sub{l}\t{%2, %0|%0, %2}"
6769 [(set_attr "type" "alu")
6770 (set_attr "mode" "SI")])
6771
6772 (define_insn "*subsi_2_zext"
6773 [(set (reg FLAGS_REG)
6774 (compare
6775 (minus:SI (match_operand:SI 1 "register_operand" "0")
6776 (match_operand:SI 2 "general_operand" "rim"))
6777 (const_int 0)))
6778 (set (match_operand:DI 0 "register_operand" "=r")
6779 (zero_extend:DI
6780 (minus:SI (match_dup 1)
6781 (match_dup 2))))]
6782 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6783 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6784 "sub{l}\t{%2, %k0|%k0, %2}"
6785 [(set_attr "type" "alu")
6786 (set_attr "mode" "SI")])
6787
6788 (define_insn "*subsi_3"
6789 [(set (reg FLAGS_REG)
6790 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6791 (match_operand:SI 2 "general_operand" "ri,rm")))
6792 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6793 (minus:SI (match_dup 1) (match_dup 2)))]
6794 "ix86_match_ccmode (insn, CCmode)
6795 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6796 "sub{l}\t{%2, %0|%0, %2}"
6797 [(set_attr "type" "alu")
6798 (set_attr "mode" "SI")])
6799
6800 (define_insn "*subsi_3_zext"
6801 [(set (reg FLAGS_REG)
6802 (compare (match_operand:SI 1 "register_operand" "0")
6803 (match_operand:SI 2 "general_operand" "rim")))
6804 (set (match_operand:DI 0 "register_operand" "=r")
6805 (zero_extend:DI
6806 (minus:SI (match_dup 1)
6807 (match_dup 2))))]
6808 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6809 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6810 "sub{q}\t{%2, %0|%0, %2}"
6811 [(set_attr "type" "alu")
6812 (set_attr "mode" "DI")])
6813
6814 (define_expand "subhi3"
6815 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6816 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6817 (match_operand:HI 2 "general_operand" "")))
6818 (clobber (reg:CC FLAGS_REG))])]
6819 "TARGET_HIMODE_MATH"
6820 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6821
6822 (define_insn "*subhi_1"
6823 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6824 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6825 (match_operand:HI 2 "general_operand" "ri,rm")))
6826 (clobber (reg:CC FLAGS_REG))]
6827 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6828 "sub{w}\t{%2, %0|%0, %2}"
6829 [(set_attr "type" "alu")
6830 (set_attr "mode" "HI")])
6831
6832 (define_insn "*subhi_2"
6833 [(set (reg FLAGS_REG)
6834 (compare
6835 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6836 (match_operand:HI 2 "general_operand" "ri,rm"))
6837 (const_int 0)))
6838 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6839 (minus:HI (match_dup 1) (match_dup 2)))]
6840 "ix86_match_ccmode (insn, CCGOCmode)
6841 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6842 "sub{w}\t{%2, %0|%0, %2}"
6843 [(set_attr "type" "alu")
6844 (set_attr "mode" "HI")])
6845
6846 (define_insn "*subhi_3"
6847 [(set (reg FLAGS_REG)
6848 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6849 (match_operand:HI 2 "general_operand" "ri,rm")))
6850 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6851 (minus:HI (match_dup 1) (match_dup 2)))]
6852 "ix86_match_ccmode (insn, CCmode)
6853 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6854 "sub{w}\t{%2, %0|%0, %2}"
6855 [(set_attr "type" "alu")
6856 (set_attr "mode" "HI")])
6857
6858 (define_expand "subqi3"
6859 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6860 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6861 (match_operand:QI 2 "general_operand" "")))
6862 (clobber (reg:CC FLAGS_REG))])]
6863 "TARGET_QIMODE_MATH"
6864 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6865
6866 (define_insn "*subqi_1"
6867 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6868 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6869 (match_operand:QI 2 "general_operand" "qn,qmn")))
6870 (clobber (reg:CC FLAGS_REG))]
6871 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6872 "sub{b}\t{%2, %0|%0, %2}"
6873 [(set_attr "type" "alu")
6874 (set_attr "mode" "QI")])
6875
6876 (define_insn "*subqi_1_slp"
6877 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6878 (minus:QI (match_dup 0)
6879 (match_operand:QI 1 "general_operand" "qn,qmn")))
6880 (clobber (reg:CC FLAGS_REG))]
6881 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6882 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6883 "sub{b}\t{%1, %0|%0, %1}"
6884 [(set_attr "type" "alu1")
6885 (set_attr "mode" "QI")])
6886
6887 (define_insn "*subqi_2"
6888 [(set (reg FLAGS_REG)
6889 (compare
6890 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6891 (match_operand:QI 2 "general_operand" "qi,qm"))
6892 (const_int 0)))
6893 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6894 (minus:HI (match_dup 1) (match_dup 2)))]
6895 "ix86_match_ccmode (insn, CCGOCmode)
6896 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6897 "sub{b}\t{%2, %0|%0, %2}"
6898 [(set_attr "type" "alu")
6899 (set_attr "mode" "QI")])
6900
6901 (define_insn "*subqi_3"
6902 [(set (reg FLAGS_REG)
6903 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6904 (match_operand:QI 2 "general_operand" "qi,qm")))
6905 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6906 (minus:HI (match_dup 1) (match_dup 2)))]
6907 "ix86_match_ccmode (insn, CCmode)
6908 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6909 "sub{b}\t{%2, %0|%0, %2}"
6910 [(set_attr "type" "alu")
6911 (set_attr "mode" "QI")])
6912
6913 ;; The patterns that match these are at the end of this file.
6914
6915 (define_expand "subxf3"
6916 [(set (match_operand:XF 0 "register_operand" "")
6917 (minus:XF (match_operand:XF 1 "register_operand" "")
6918 (match_operand:XF 2 "register_operand" "")))]
6919 "TARGET_80387"
6920 "")
6921
6922 (define_expand "subdf3"
6923 [(set (match_operand:DF 0 "register_operand" "")
6924 (minus:DF (match_operand:DF 1 "register_operand" "")
6925 (match_operand:DF 2 "nonimmediate_operand" "")))]
6926 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6927 "")
6928
6929 (define_expand "subsf3"
6930 [(set (match_operand:SF 0 "register_operand" "")
6931 (minus:SF (match_operand:SF 1 "register_operand" "")
6932 (match_operand:SF 2 "nonimmediate_operand" "")))]
6933 "TARGET_80387 || TARGET_SSE_MATH"
6934 "")
6935 \f
6936 ;; Multiply instructions
6937
6938 (define_expand "muldi3"
6939 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6940 (mult:DI (match_operand:DI 1 "register_operand" "")
6941 (match_operand:DI 2 "x86_64_general_operand" "")))
6942 (clobber (reg:CC FLAGS_REG))])]
6943 "TARGET_64BIT"
6944 "")
6945
6946 (define_insn "*muldi3_1_rex64"
6947 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6948 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6949 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6950 (clobber (reg:CC FLAGS_REG))]
6951 "TARGET_64BIT
6952 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6953 "@
6954 imul{q}\t{%2, %1, %0|%0, %1, %2}
6955 imul{q}\t{%2, %1, %0|%0, %1, %2}
6956 imul{q}\t{%2, %0|%0, %2}"
6957 [(set_attr "type" "imul")
6958 (set_attr "prefix_0f" "0,0,1")
6959 (set (attr "athlon_decode")
6960 (cond [(eq_attr "cpu" "athlon")
6961 (const_string "vector")
6962 (eq_attr "alternative" "1")
6963 (const_string "vector")
6964 (and (eq_attr "alternative" "2")
6965 (match_operand 1 "memory_operand" ""))
6966 (const_string "vector")]
6967 (const_string "direct")))
6968 (set_attr "mode" "DI")])
6969
6970 (define_expand "mulsi3"
6971 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6972 (mult:SI (match_operand:SI 1 "register_operand" "")
6973 (match_operand:SI 2 "general_operand" "")))
6974 (clobber (reg:CC FLAGS_REG))])]
6975 ""
6976 "")
6977
6978 (define_insn "*mulsi3_1"
6979 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6980 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6981 (match_operand:SI 2 "general_operand" "K,i,mr")))
6982 (clobber (reg:CC FLAGS_REG))]
6983 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6984 "@
6985 imul{l}\t{%2, %1, %0|%0, %1, %2}
6986 imul{l}\t{%2, %1, %0|%0, %1, %2}
6987 imul{l}\t{%2, %0|%0, %2}"
6988 [(set_attr "type" "imul")
6989 (set_attr "prefix_0f" "0,0,1")
6990 (set (attr "athlon_decode")
6991 (cond [(eq_attr "cpu" "athlon")
6992 (const_string "vector")
6993 (eq_attr "alternative" "1")
6994 (const_string "vector")
6995 (and (eq_attr "alternative" "2")
6996 (match_operand 1 "memory_operand" ""))
6997 (const_string "vector")]
6998 (const_string "direct")))
6999 (set_attr "mode" "SI")])
7000
7001 (define_insn "*mulsi3_1_zext"
7002 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7003 (zero_extend:DI
7004 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7005 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7006 (clobber (reg:CC FLAGS_REG))]
7007 "TARGET_64BIT
7008 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7009 "@
7010 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7011 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7012 imul{l}\t{%2, %k0|%k0, %2}"
7013 [(set_attr "type" "imul")
7014 (set_attr "prefix_0f" "0,0,1")
7015 (set (attr "athlon_decode")
7016 (cond [(eq_attr "cpu" "athlon")
7017 (const_string "vector")
7018 (eq_attr "alternative" "1")
7019 (const_string "vector")
7020 (and (eq_attr "alternative" "2")
7021 (match_operand 1 "memory_operand" ""))
7022 (const_string "vector")]
7023 (const_string "direct")))
7024 (set_attr "mode" "SI")])
7025
7026 (define_expand "mulhi3"
7027 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7028 (mult:HI (match_operand:HI 1 "register_operand" "")
7029 (match_operand:HI 2 "general_operand" "")))
7030 (clobber (reg:CC FLAGS_REG))])]
7031 "TARGET_HIMODE_MATH"
7032 "")
7033
7034 (define_insn "*mulhi3_1"
7035 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7036 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7037 (match_operand:HI 2 "general_operand" "K,i,mr")))
7038 (clobber (reg:CC FLAGS_REG))]
7039 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7040 "@
7041 imul{w}\t{%2, %1, %0|%0, %1, %2}
7042 imul{w}\t{%2, %1, %0|%0, %1, %2}
7043 imul{w}\t{%2, %0|%0, %2}"
7044 [(set_attr "type" "imul")
7045 (set_attr "prefix_0f" "0,0,1")
7046 (set (attr "athlon_decode")
7047 (cond [(eq_attr "cpu" "athlon")
7048 (const_string "vector")
7049 (eq_attr "alternative" "1,2")
7050 (const_string "vector")]
7051 (const_string "direct")))
7052 (set_attr "mode" "HI")])
7053
7054 (define_expand "mulqi3"
7055 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7056 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7057 (match_operand:QI 2 "register_operand" "")))
7058 (clobber (reg:CC FLAGS_REG))])]
7059 "TARGET_QIMODE_MATH"
7060 "")
7061
7062 (define_insn "*mulqi3_1"
7063 [(set (match_operand:QI 0 "register_operand" "=a")
7064 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7065 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7066 (clobber (reg:CC FLAGS_REG))]
7067 "TARGET_QIMODE_MATH
7068 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7069 "mul{b}\t%2"
7070 [(set_attr "type" "imul")
7071 (set_attr "length_immediate" "0")
7072 (set (attr "athlon_decode")
7073 (if_then_else (eq_attr "cpu" "athlon")
7074 (const_string "vector")
7075 (const_string "direct")))
7076 (set_attr "mode" "QI")])
7077
7078 (define_expand "umulqihi3"
7079 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7080 (mult:HI (zero_extend:HI
7081 (match_operand:QI 1 "nonimmediate_operand" ""))
7082 (zero_extend:HI
7083 (match_operand:QI 2 "register_operand" ""))))
7084 (clobber (reg:CC FLAGS_REG))])]
7085 "TARGET_QIMODE_MATH"
7086 "")
7087
7088 (define_insn "*umulqihi3_1"
7089 [(set (match_operand:HI 0 "register_operand" "=a")
7090 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7091 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7092 (clobber (reg:CC FLAGS_REG))]
7093 "TARGET_QIMODE_MATH
7094 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7095 "mul{b}\t%2"
7096 [(set_attr "type" "imul")
7097 (set_attr "length_immediate" "0")
7098 (set (attr "athlon_decode")
7099 (if_then_else (eq_attr "cpu" "athlon")
7100 (const_string "vector")
7101 (const_string "direct")))
7102 (set_attr "mode" "QI")])
7103
7104 (define_expand "mulqihi3"
7105 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7106 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7107 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7108 (clobber (reg:CC FLAGS_REG))])]
7109 "TARGET_QIMODE_MATH"
7110 "")
7111
7112 (define_insn "*mulqihi3_insn"
7113 [(set (match_operand:HI 0 "register_operand" "=a")
7114 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7115 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7116 (clobber (reg:CC FLAGS_REG))]
7117 "TARGET_QIMODE_MATH
7118 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7119 "imul{b}\t%2"
7120 [(set_attr "type" "imul")
7121 (set_attr "length_immediate" "0")
7122 (set (attr "athlon_decode")
7123 (if_then_else (eq_attr "cpu" "athlon")
7124 (const_string "vector")
7125 (const_string "direct")))
7126 (set_attr "mode" "QI")])
7127
7128 (define_expand "umulditi3"
7129 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7130 (mult:TI (zero_extend:TI
7131 (match_operand:DI 1 "nonimmediate_operand" ""))
7132 (zero_extend:TI
7133 (match_operand:DI 2 "register_operand" ""))))
7134 (clobber (reg:CC FLAGS_REG))])]
7135 "TARGET_64BIT"
7136 "")
7137
7138 (define_insn "*umulditi3_insn"
7139 [(set (match_operand:TI 0 "register_operand" "=A")
7140 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7141 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7142 (clobber (reg:CC FLAGS_REG))]
7143 "TARGET_64BIT
7144 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7145 "mul{q}\t%2"
7146 [(set_attr "type" "imul")
7147 (set_attr "length_immediate" "0")
7148 (set (attr "athlon_decode")
7149 (if_then_else (eq_attr "cpu" "athlon")
7150 (const_string "vector")
7151 (const_string "double")))
7152 (set_attr "mode" "DI")])
7153
7154 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7155 (define_expand "umulsidi3"
7156 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7157 (mult:DI (zero_extend:DI
7158 (match_operand:SI 1 "nonimmediate_operand" ""))
7159 (zero_extend:DI
7160 (match_operand:SI 2 "register_operand" ""))))
7161 (clobber (reg:CC FLAGS_REG))])]
7162 "!TARGET_64BIT"
7163 "")
7164
7165 (define_insn "*umulsidi3_insn"
7166 [(set (match_operand:DI 0 "register_operand" "=A")
7167 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7168 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7169 (clobber (reg:CC FLAGS_REG))]
7170 "!TARGET_64BIT
7171 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7172 "mul{l}\t%2"
7173 [(set_attr "type" "imul")
7174 (set_attr "length_immediate" "0")
7175 (set (attr "athlon_decode")
7176 (if_then_else (eq_attr "cpu" "athlon")
7177 (const_string "vector")
7178 (const_string "double")))
7179 (set_attr "mode" "SI")])
7180
7181 (define_expand "mulditi3"
7182 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7183 (mult:TI (sign_extend:TI
7184 (match_operand:DI 1 "nonimmediate_operand" ""))
7185 (sign_extend:TI
7186 (match_operand:DI 2 "register_operand" ""))))
7187 (clobber (reg:CC FLAGS_REG))])]
7188 "TARGET_64BIT"
7189 "")
7190
7191 (define_insn "*mulditi3_insn"
7192 [(set (match_operand:TI 0 "register_operand" "=A")
7193 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7194 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7195 (clobber (reg:CC FLAGS_REG))]
7196 "TARGET_64BIT
7197 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7198 "imul{q}\t%2"
7199 [(set_attr "type" "imul")
7200 (set_attr "length_immediate" "0")
7201 (set (attr "athlon_decode")
7202 (if_then_else (eq_attr "cpu" "athlon")
7203 (const_string "vector")
7204 (const_string "double")))
7205 (set_attr "mode" "DI")])
7206
7207 (define_expand "mulsidi3"
7208 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7209 (mult:DI (sign_extend:DI
7210 (match_operand:SI 1 "nonimmediate_operand" ""))
7211 (sign_extend:DI
7212 (match_operand:SI 2 "register_operand" ""))))
7213 (clobber (reg:CC FLAGS_REG))])]
7214 "!TARGET_64BIT"
7215 "")
7216
7217 (define_insn "*mulsidi3_insn"
7218 [(set (match_operand:DI 0 "register_operand" "=A")
7219 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7220 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7221 (clobber (reg:CC FLAGS_REG))]
7222 "!TARGET_64BIT
7223 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7224 "imul{l}\t%2"
7225 [(set_attr "type" "imul")
7226 (set_attr "length_immediate" "0")
7227 (set (attr "athlon_decode")
7228 (if_then_else (eq_attr "cpu" "athlon")
7229 (const_string "vector")
7230 (const_string "double")))
7231 (set_attr "mode" "SI")])
7232
7233 (define_expand "umuldi3_highpart"
7234 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7235 (truncate:DI
7236 (lshiftrt:TI
7237 (mult:TI (zero_extend:TI
7238 (match_operand:DI 1 "nonimmediate_operand" ""))
7239 (zero_extend:TI
7240 (match_operand:DI 2 "register_operand" "")))
7241 (const_int 64))))
7242 (clobber (match_scratch:DI 3 ""))
7243 (clobber (reg:CC FLAGS_REG))])]
7244 "TARGET_64BIT"
7245 "")
7246
7247 (define_insn "*umuldi3_highpart_rex64"
7248 [(set (match_operand:DI 0 "register_operand" "=d")
7249 (truncate:DI
7250 (lshiftrt:TI
7251 (mult:TI (zero_extend:TI
7252 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7253 (zero_extend:TI
7254 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7255 (const_int 64))))
7256 (clobber (match_scratch:DI 3 "=1"))
7257 (clobber (reg:CC FLAGS_REG))]
7258 "TARGET_64BIT
7259 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7260 "mul{q}\t%2"
7261 [(set_attr "type" "imul")
7262 (set_attr "length_immediate" "0")
7263 (set (attr "athlon_decode")
7264 (if_then_else (eq_attr "cpu" "athlon")
7265 (const_string "vector")
7266 (const_string "double")))
7267 (set_attr "mode" "DI")])
7268
7269 (define_expand "umulsi3_highpart"
7270 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7271 (truncate:SI
7272 (lshiftrt:DI
7273 (mult:DI (zero_extend:DI
7274 (match_operand:SI 1 "nonimmediate_operand" ""))
7275 (zero_extend:DI
7276 (match_operand:SI 2 "register_operand" "")))
7277 (const_int 32))))
7278 (clobber (match_scratch:SI 3 ""))
7279 (clobber (reg:CC FLAGS_REG))])]
7280 ""
7281 "")
7282
7283 (define_insn "*umulsi3_highpart_insn"
7284 [(set (match_operand:SI 0 "register_operand" "=d")
7285 (truncate:SI
7286 (lshiftrt:DI
7287 (mult:DI (zero_extend:DI
7288 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7289 (zero_extend:DI
7290 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7291 (const_int 32))))
7292 (clobber (match_scratch:SI 3 "=1"))
7293 (clobber (reg:CC FLAGS_REG))]
7294 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7295 "mul{l}\t%2"
7296 [(set_attr "type" "imul")
7297 (set_attr "length_immediate" "0")
7298 (set (attr "athlon_decode")
7299 (if_then_else (eq_attr "cpu" "athlon")
7300 (const_string "vector")
7301 (const_string "double")))
7302 (set_attr "mode" "SI")])
7303
7304 (define_insn "*umulsi3_highpart_zext"
7305 [(set (match_operand:DI 0 "register_operand" "=d")
7306 (zero_extend:DI (truncate:SI
7307 (lshiftrt:DI
7308 (mult:DI (zero_extend:DI
7309 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7310 (zero_extend:DI
7311 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7312 (const_int 32)))))
7313 (clobber (match_scratch:SI 3 "=1"))
7314 (clobber (reg:CC FLAGS_REG))]
7315 "TARGET_64BIT
7316 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7317 "mul{l}\t%2"
7318 [(set_attr "type" "imul")
7319 (set_attr "length_immediate" "0")
7320 (set (attr "athlon_decode")
7321 (if_then_else (eq_attr "cpu" "athlon")
7322 (const_string "vector")
7323 (const_string "double")))
7324 (set_attr "mode" "SI")])
7325
7326 (define_expand "smuldi3_highpart"
7327 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7328 (truncate:DI
7329 (lshiftrt:TI
7330 (mult:TI (sign_extend:TI
7331 (match_operand:DI 1 "nonimmediate_operand" ""))
7332 (sign_extend:TI
7333 (match_operand:DI 2 "register_operand" "")))
7334 (const_int 64))))
7335 (clobber (match_scratch:DI 3 ""))
7336 (clobber (reg:CC FLAGS_REG))])]
7337 "TARGET_64BIT"
7338 "")
7339
7340 (define_insn "*smuldi3_highpart_rex64"
7341 [(set (match_operand:DI 0 "register_operand" "=d")
7342 (truncate:DI
7343 (lshiftrt:TI
7344 (mult:TI (sign_extend:TI
7345 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7346 (sign_extend:TI
7347 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7348 (const_int 64))))
7349 (clobber (match_scratch:DI 3 "=1"))
7350 (clobber (reg:CC FLAGS_REG))]
7351 "TARGET_64BIT
7352 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7353 "imul{q}\t%2"
7354 [(set_attr "type" "imul")
7355 (set (attr "athlon_decode")
7356 (if_then_else (eq_attr "cpu" "athlon")
7357 (const_string "vector")
7358 (const_string "double")))
7359 (set_attr "mode" "DI")])
7360
7361 (define_expand "smulsi3_highpart"
7362 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7363 (truncate:SI
7364 (lshiftrt:DI
7365 (mult:DI (sign_extend:DI
7366 (match_operand:SI 1 "nonimmediate_operand" ""))
7367 (sign_extend:DI
7368 (match_operand:SI 2 "register_operand" "")))
7369 (const_int 32))))
7370 (clobber (match_scratch:SI 3 ""))
7371 (clobber (reg:CC FLAGS_REG))])]
7372 ""
7373 "")
7374
7375 (define_insn "*smulsi3_highpart_insn"
7376 [(set (match_operand:SI 0 "register_operand" "=d")
7377 (truncate:SI
7378 (lshiftrt:DI
7379 (mult:DI (sign_extend:DI
7380 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7381 (sign_extend:DI
7382 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7383 (const_int 32))))
7384 (clobber (match_scratch:SI 3 "=1"))
7385 (clobber (reg:CC FLAGS_REG))]
7386 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7387 "imul{l}\t%2"
7388 [(set_attr "type" "imul")
7389 (set (attr "athlon_decode")
7390 (if_then_else (eq_attr "cpu" "athlon")
7391 (const_string "vector")
7392 (const_string "double")))
7393 (set_attr "mode" "SI")])
7394
7395 (define_insn "*smulsi3_highpart_zext"
7396 [(set (match_operand:DI 0 "register_operand" "=d")
7397 (zero_extend:DI (truncate:SI
7398 (lshiftrt:DI
7399 (mult:DI (sign_extend:DI
7400 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7401 (sign_extend:DI
7402 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7403 (const_int 32)))))
7404 (clobber (match_scratch:SI 3 "=1"))
7405 (clobber (reg:CC FLAGS_REG))]
7406 "TARGET_64BIT
7407 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7408 "imul{l}\t%2"
7409 [(set_attr "type" "imul")
7410 (set (attr "athlon_decode")
7411 (if_then_else (eq_attr "cpu" "athlon")
7412 (const_string "vector")
7413 (const_string "double")))
7414 (set_attr "mode" "SI")])
7415
7416 ;; The patterns that match these are at the end of this file.
7417
7418 (define_expand "mulxf3"
7419 [(set (match_operand:XF 0 "register_operand" "")
7420 (mult:XF (match_operand:XF 1 "register_operand" "")
7421 (match_operand:XF 2 "register_operand" "")))]
7422 "TARGET_80387"
7423 "")
7424
7425 (define_expand "muldf3"
7426 [(set (match_operand:DF 0 "register_operand" "")
7427 (mult:DF (match_operand:DF 1 "register_operand" "")
7428 (match_operand:DF 2 "nonimmediate_operand" "")))]
7429 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7430 "")
7431
7432 (define_expand "mulsf3"
7433 [(set (match_operand:SF 0 "register_operand" "")
7434 (mult:SF (match_operand:SF 1 "register_operand" "")
7435 (match_operand:SF 2 "nonimmediate_operand" "")))]
7436 "TARGET_80387 || TARGET_SSE_MATH"
7437 "")
7438 \f
7439 ;; Divide instructions
7440
7441 (define_insn "divqi3"
7442 [(set (match_operand:QI 0 "register_operand" "=a")
7443 (div:QI (match_operand:HI 1 "register_operand" "0")
7444 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7445 (clobber (reg:CC FLAGS_REG))]
7446 "TARGET_QIMODE_MATH"
7447 "idiv{b}\t%2"
7448 [(set_attr "type" "idiv")
7449 (set_attr "mode" "QI")])
7450
7451 (define_insn "udivqi3"
7452 [(set (match_operand:QI 0 "register_operand" "=a")
7453 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7454 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7455 (clobber (reg:CC FLAGS_REG))]
7456 "TARGET_QIMODE_MATH"
7457 "div{b}\t%2"
7458 [(set_attr "type" "idiv")
7459 (set_attr "mode" "QI")])
7460
7461 ;; The patterns that match these are at the end of this file.
7462
7463 (define_expand "divxf3"
7464 [(set (match_operand:XF 0 "register_operand" "")
7465 (div:XF (match_operand:XF 1 "register_operand" "")
7466 (match_operand:XF 2 "register_operand" "")))]
7467 "TARGET_80387"
7468 "")
7469
7470 (define_expand "divdf3"
7471 [(set (match_operand:DF 0 "register_operand" "")
7472 (div:DF (match_operand:DF 1 "register_operand" "")
7473 (match_operand:DF 2 "nonimmediate_operand" "")))]
7474 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7475 "")
7476
7477 (define_expand "divsf3"
7478 [(set (match_operand:SF 0 "register_operand" "")
7479 (div:SF (match_operand:SF 1 "register_operand" "")
7480 (match_operand:SF 2 "nonimmediate_operand" "")))]
7481 "TARGET_80387 || TARGET_SSE_MATH"
7482 "")
7483 \f
7484 ;; Remainder instructions.
7485
7486 (define_expand "divmoddi4"
7487 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7488 (div:DI (match_operand:DI 1 "register_operand" "")
7489 (match_operand:DI 2 "nonimmediate_operand" "")))
7490 (set (match_operand:DI 3 "register_operand" "")
7491 (mod:DI (match_dup 1) (match_dup 2)))
7492 (clobber (reg:CC FLAGS_REG))])]
7493 "TARGET_64BIT"
7494 "")
7495
7496 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7497 ;; Penalize eax case slightly because it results in worse scheduling
7498 ;; of code.
7499 (define_insn "*divmoddi4_nocltd_rex64"
7500 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7501 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7502 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7503 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7504 (mod:DI (match_dup 2) (match_dup 3)))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7507 "#"
7508 [(set_attr "type" "multi")])
7509
7510 (define_insn "*divmoddi4_cltd_rex64"
7511 [(set (match_operand:DI 0 "register_operand" "=a")
7512 (div:DI (match_operand:DI 2 "register_operand" "a")
7513 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7514 (set (match_operand:DI 1 "register_operand" "=&d")
7515 (mod:DI (match_dup 2) (match_dup 3)))
7516 (clobber (reg:CC FLAGS_REG))]
7517 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7518 "#"
7519 [(set_attr "type" "multi")])
7520
7521 (define_insn "*divmoddi_noext_rex64"
7522 [(set (match_operand:DI 0 "register_operand" "=a")
7523 (div:DI (match_operand:DI 1 "register_operand" "0")
7524 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7525 (set (match_operand:DI 3 "register_operand" "=d")
7526 (mod:DI (match_dup 1) (match_dup 2)))
7527 (use (match_operand:DI 4 "register_operand" "3"))
7528 (clobber (reg:CC FLAGS_REG))]
7529 "TARGET_64BIT"
7530 "idiv{q}\t%2"
7531 [(set_attr "type" "idiv")
7532 (set_attr "mode" "DI")])
7533
7534 (define_split
7535 [(set (match_operand:DI 0 "register_operand" "")
7536 (div:DI (match_operand:DI 1 "register_operand" "")
7537 (match_operand:DI 2 "nonimmediate_operand" "")))
7538 (set (match_operand:DI 3 "register_operand" "")
7539 (mod:DI (match_dup 1) (match_dup 2)))
7540 (clobber (reg:CC FLAGS_REG))]
7541 "TARGET_64BIT && reload_completed"
7542 [(parallel [(set (match_dup 3)
7543 (ashiftrt:DI (match_dup 4) (const_int 63)))
7544 (clobber (reg:CC FLAGS_REG))])
7545 (parallel [(set (match_dup 0)
7546 (div:DI (reg:DI 0) (match_dup 2)))
7547 (set (match_dup 3)
7548 (mod:DI (reg:DI 0) (match_dup 2)))
7549 (use (match_dup 3))
7550 (clobber (reg:CC FLAGS_REG))])]
7551 {
7552 /* Avoid use of cltd in favor of a mov+shift. */
7553 if (!TARGET_USE_CLTD && !optimize_size)
7554 {
7555 if (true_regnum (operands[1]))
7556 emit_move_insn (operands[0], operands[1]);
7557 else
7558 emit_move_insn (operands[3], operands[1]);
7559 operands[4] = operands[3];
7560 }
7561 else
7562 {
7563 if (true_regnum (operands[1]))
7564 abort();
7565 operands[4] = operands[1];
7566 }
7567 })
7568
7569
7570 (define_expand "divmodsi4"
7571 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7572 (div:SI (match_operand:SI 1 "register_operand" "")
7573 (match_operand:SI 2 "nonimmediate_operand" "")))
7574 (set (match_operand:SI 3 "register_operand" "")
7575 (mod:SI (match_dup 1) (match_dup 2)))
7576 (clobber (reg:CC FLAGS_REG))])]
7577 ""
7578 "")
7579
7580 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7581 ;; Penalize eax case slightly because it results in worse scheduling
7582 ;; of code.
7583 (define_insn "*divmodsi4_nocltd"
7584 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7585 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7586 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7587 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7588 (mod:SI (match_dup 2) (match_dup 3)))
7589 (clobber (reg:CC FLAGS_REG))]
7590 "!optimize_size && !TARGET_USE_CLTD"
7591 "#"
7592 [(set_attr "type" "multi")])
7593
7594 (define_insn "*divmodsi4_cltd"
7595 [(set (match_operand:SI 0 "register_operand" "=a")
7596 (div:SI (match_operand:SI 2 "register_operand" "a")
7597 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7598 (set (match_operand:SI 1 "register_operand" "=&d")
7599 (mod:SI (match_dup 2) (match_dup 3)))
7600 (clobber (reg:CC FLAGS_REG))]
7601 "optimize_size || TARGET_USE_CLTD"
7602 "#"
7603 [(set_attr "type" "multi")])
7604
7605 (define_insn "*divmodsi_noext"
7606 [(set (match_operand:SI 0 "register_operand" "=a")
7607 (div:SI (match_operand:SI 1 "register_operand" "0")
7608 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7609 (set (match_operand:SI 3 "register_operand" "=d")
7610 (mod:SI (match_dup 1) (match_dup 2)))
7611 (use (match_operand:SI 4 "register_operand" "3"))
7612 (clobber (reg:CC FLAGS_REG))]
7613 ""
7614 "idiv{l}\t%2"
7615 [(set_attr "type" "idiv")
7616 (set_attr "mode" "SI")])
7617
7618 (define_split
7619 [(set (match_operand:SI 0 "register_operand" "")
7620 (div:SI (match_operand:SI 1 "register_operand" "")
7621 (match_operand:SI 2 "nonimmediate_operand" "")))
7622 (set (match_operand:SI 3 "register_operand" "")
7623 (mod:SI (match_dup 1) (match_dup 2)))
7624 (clobber (reg:CC FLAGS_REG))]
7625 "reload_completed"
7626 [(parallel [(set (match_dup 3)
7627 (ashiftrt:SI (match_dup 4) (const_int 31)))
7628 (clobber (reg:CC FLAGS_REG))])
7629 (parallel [(set (match_dup 0)
7630 (div:SI (reg:SI 0) (match_dup 2)))
7631 (set (match_dup 3)
7632 (mod:SI (reg:SI 0) (match_dup 2)))
7633 (use (match_dup 3))
7634 (clobber (reg:CC FLAGS_REG))])]
7635 {
7636 /* Avoid use of cltd in favor of a mov+shift. */
7637 if (!TARGET_USE_CLTD && !optimize_size)
7638 {
7639 if (true_regnum (operands[1]))
7640 emit_move_insn (operands[0], operands[1]);
7641 else
7642 emit_move_insn (operands[3], operands[1]);
7643 operands[4] = operands[3];
7644 }
7645 else
7646 {
7647 if (true_regnum (operands[1]))
7648 abort();
7649 operands[4] = operands[1];
7650 }
7651 })
7652 ;; %%% Split me.
7653 (define_insn "divmodhi4"
7654 [(set (match_operand:HI 0 "register_operand" "=a")
7655 (div:HI (match_operand:HI 1 "register_operand" "0")
7656 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7657 (set (match_operand:HI 3 "register_operand" "=&d")
7658 (mod:HI (match_dup 1) (match_dup 2)))
7659 (clobber (reg:CC FLAGS_REG))]
7660 "TARGET_HIMODE_MATH"
7661 "cwtd\;idiv{w}\t%2"
7662 [(set_attr "type" "multi")
7663 (set_attr "length_immediate" "0")
7664 (set_attr "mode" "SI")])
7665
7666 (define_insn "udivmoddi4"
7667 [(set (match_operand:DI 0 "register_operand" "=a")
7668 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7669 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7670 (set (match_operand:DI 3 "register_operand" "=&d")
7671 (umod:DI (match_dup 1) (match_dup 2)))
7672 (clobber (reg:CC FLAGS_REG))]
7673 "TARGET_64BIT"
7674 "xor{q}\t%3, %3\;div{q}\t%2"
7675 [(set_attr "type" "multi")
7676 (set_attr "length_immediate" "0")
7677 (set_attr "mode" "DI")])
7678
7679 (define_insn "*udivmoddi4_noext"
7680 [(set (match_operand:DI 0 "register_operand" "=a")
7681 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7682 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7683 (set (match_operand:DI 3 "register_operand" "=d")
7684 (umod:DI (match_dup 1) (match_dup 2)))
7685 (use (match_dup 3))
7686 (clobber (reg:CC FLAGS_REG))]
7687 "TARGET_64BIT"
7688 "div{q}\t%2"
7689 [(set_attr "type" "idiv")
7690 (set_attr "mode" "DI")])
7691
7692 (define_split
7693 [(set (match_operand:DI 0 "register_operand" "")
7694 (udiv:DI (match_operand:DI 1 "register_operand" "")
7695 (match_operand:DI 2 "nonimmediate_operand" "")))
7696 (set (match_operand:DI 3 "register_operand" "")
7697 (umod:DI (match_dup 1) (match_dup 2)))
7698 (clobber (reg:CC FLAGS_REG))]
7699 "TARGET_64BIT && reload_completed"
7700 [(set (match_dup 3) (const_int 0))
7701 (parallel [(set (match_dup 0)
7702 (udiv:DI (match_dup 1) (match_dup 2)))
7703 (set (match_dup 3)
7704 (umod:DI (match_dup 1) (match_dup 2)))
7705 (use (match_dup 3))
7706 (clobber (reg:CC FLAGS_REG))])]
7707 "")
7708
7709 (define_insn "udivmodsi4"
7710 [(set (match_operand:SI 0 "register_operand" "=a")
7711 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7712 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7713 (set (match_operand:SI 3 "register_operand" "=&d")
7714 (umod:SI (match_dup 1) (match_dup 2)))
7715 (clobber (reg:CC FLAGS_REG))]
7716 ""
7717 "xor{l}\t%3, %3\;div{l}\t%2"
7718 [(set_attr "type" "multi")
7719 (set_attr "length_immediate" "0")
7720 (set_attr "mode" "SI")])
7721
7722 (define_insn "*udivmodsi4_noext"
7723 [(set (match_operand:SI 0 "register_operand" "=a")
7724 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7725 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7726 (set (match_operand:SI 3 "register_operand" "=d")
7727 (umod:SI (match_dup 1) (match_dup 2)))
7728 (use (match_dup 3))
7729 (clobber (reg:CC FLAGS_REG))]
7730 ""
7731 "div{l}\t%2"
7732 [(set_attr "type" "idiv")
7733 (set_attr "mode" "SI")])
7734
7735 (define_split
7736 [(set (match_operand:SI 0 "register_operand" "")
7737 (udiv:SI (match_operand:SI 1 "register_operand" "")
7738 (match_operand:SI 2 "nonimmediate_operand" "")))
7739 (set (match_operand:SI 3 "register_operand" "")
7740 (umod:SI (match_dup 1) (match_dup 2)))
7741 (clobber (reg:CC FLAGS_REG))]
7742 "reload_completed"
7743 [(set (match_dup 3) (const_int 0))
7744 (parallel [(set (match_dup 0)
7745 (udiv:SI (match_dup 1) (match_dup 2)))
7746 (set (match_dup 3)
7747 (umod:SI (match_dup 1) (match_dup 2)))
7748 (use (match_dup 3))
7749 (clobber (reg:CC FLAGS_REG))])]
7750 "")
7751
7752 (define_expand "udivmodhi4"
7753 [(set (match_dup 4) (const_int 0))
7754 (parallel [(set (match_operand:HI 0 "register_operand" "")
7755 (udiv:HI (match_operand:HI 1 "register_operand" "")
7756 (match_operand:HI 2 "nonimmediate_operand" "")))
7757 (set (match_operand:HI 3 "register_operand" "")
7758 (umod:HI (match_dup 1) (match_dup 2)))
7759 (use (match_dup 4))
7760 (clobber (reg:CC FLAGS_REG))])]
7761 "TARGET_HIMODE_MATH"
7762 "operands[4] = gen_reg_rtx (HImode);")
7763
7764 (define_insn "*udivmodhi_noext"
7765 [(set (match_operand:HI 0 "register_operand" "=a")
7766 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7767 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7768 (set (match_operand:HI 3 "register_operand" "=d")
7769 (umod:HI (match_dup 1) (match_dup 2)))
7770 (use (match_operand:HI 4 "register_operand" "3"))
7771 (clobber (reg:CC FLAGS_REG))]
7772 ""
7773 "div{w}\t%2"
7774 [(set_attr "type" "idiv")
7775 (set_attr "mode" "HI")])
7776
7777 ;; We cannot use div/idiv for double division, because it causes
7778 ;; "division by zero" on the overflow and that's not what we expect
7779 ;; from truncate. Because true (non truncating) double division is
7780 ;; never generated, we can't create this insn anyway.
7781 ;
7782 ;(define_insn ""
7783 ; [(set (match_operand:SI 0 "register_operand" "=a")
7784 ; (truncate:SI
7785 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7786 ; (zero_extend:DI
7787 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7788 ; (set (match_operand:SI 3 "register_operand" "=d")
7789 ; (truncate:SI
7790 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7791 ; (clobber (reg:CC FLAGS_REG))]
7792 ; ""
7793 ; "div{l}\t{%2, %0|%0, %2}"
7794 ; [(set_attr "type" "idiv")])
7795 \f
7796 ;;- Logical AND instructions
7797
7798 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7799 ;; Note that this excludes ah.
7800
7801 (define_insn "*testdi_1_rex64"
7802 [(set (reg FLAGS_REG)
7803 (compare
7804 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7805 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7806 (const_int 0)))]
7807 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7808 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7809 "@
7810 test{l}\t{%k1, %k0|%k0, %k1}
7811 test{l}\t{%k1, %k0|%k0, %k1}
7812 test{q}\t{%1, %0|%0, %1}
7813 test{q}\t{%1, %0|%0, %1}
7814 test{q}\t{%1, %0|%0, %1}"
7815 [(set_attr "type" "test")
7816 (set_attr "modrm" "0,1,0,1,1")
7817 (set_attr "mode" "SI,SI,DI,DI,DI")
7818 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7819
7820 (define_insn "testsi_1"
7821 [(set (reg FLAGS_REG)
7822 (compare
7823 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7824 (match_operand:SI 1 "general_operand" "in,in,rin"))
7825 (const_int 0)))]
7826 "ix86_match_ccmode (insn, CCNOmode)
7827 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7828 "test{l}\t{%1, %0|%0, %1}"
7829 [(set_attr "type" "test")
7830 (set_attr "modrm" "0,1,1")
7831 (set_attr "mode" "SI")
7832 (set_attr "pent_pair" "uv,np,uv")])
7833
7834 (define_expand "testsi_ccno_1"
7835 [(set (reg:CCNO FLAGS_REG)
7836 (compare:CCNO
7837 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7838 (match_operand:SI 1 "nonmemory_operand" ""))
7839 (const_int 0)))]
7840 ""
7841 "")
7842
7843 (define_insn "*testhi_1"
7844 [(set (reg FLAGS_REG)
7845 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7846 (match_operand:HI 1 "general_operand" "n,n,rn"))
7847 (const_int 0)))]
7848 "ix86_match_ccmode (insn, CCNOmode)
7849 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7850 "test{w}\t{%1, %0|%0, %1}"
7851 [(set_attr "type" "test")
7852 (set_attr "modrm" "0,1,1")
7853 (set_attr "mode" "HI")
7854 (set_attr "pent_pair" "uv,np,uv")])
7855
7856 (define_expand "testqi_ccz_1"
7857 [(set (reg:CCZ FLAGS_REG)
7858 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7859 (match_operand:QI 1 "nonmemory_operand" ""))
7860 (const_int 0)))]
7861 ""
7862 "")
7863
7864 (define_insn "*testqi_1_maybe_si"
7865 [(set (reg FLAGS_REG)
7866 (compare
7867 (and:QI
7868 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7869 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7870 (const_int 0)))]
7871 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7872 && ix86_match_ccmode (insn,
7873 GET_CODE (operands[1]) == CONST_INT
7874 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7875 {
7876 if (which_alternative == 3)
7877 {
7878 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7879 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7880 return "test{l}\t{%1, %k0|%k0, %1}";
7881 }
7882 return "test{b}\t{%1, %0|%0, %1}";
7883 }
7884 [(set_attr "type" "test")
7885 (set_attr "modrm" "0,1,1,1")
7886 (set_attr "mode" "QI,QI,QI,SI")
7887 (set_attr "pent_pair" "uv,np,uv,np")])
7888
7889 (define_insn "*testqi_1"
7890 [(set (reg FLAGS_REG)
7891 (compare
7892 (and:QI
7893 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7894 (match_operand:QI 1 "general_operand" "n,n,qn"))
7895 (const_int 0)))]
7896 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7897 && ix86_match_ccmode (insn, CCNOmode)"
7898 "test{b}\t{%1, %0|%0, %1}"
7899 [(set_attr "type" "test")
7900 (set_attr "modrm" "0,1,1")
7901 (set_attr "mode" "QI")
7902 (set_attr "pent_pair" "uv,np,uv")])
7903
7904 (define_expand "testqi_ext_ccno_0"
7905 [(set (reg:CCNO FLAGS_REG)
7906 (compare:CCNO
7907 (and:SI
7908 (zero_extract:SI
7909 (match_operand 0 "ext_register_operand" "")
7910 (const_int 8)
7911 (const_int 8))
7912 (match_operand 1 "const_int_operand" ""))
7913 (const_int 0)))]
7914 ""
7915 "")
7916
7917 (define_insn "*testqi_ext_0"
7918 [(set (reg FLAGS_REG)
7919 (compare
7920 (and:SI
7921 (zero_extract:SI
7922 (match_operand 0 "ext_register_operand" "Q")
7923 (const_int 8)
7924 (const_int 8))
7925 (match_operand 1 "const_int_operand" "n"))
7926 (const_int 0)))]
7927 "ix86_match_ccmode (insn, CCNOmode)"
7928 "test{b}\t{%1, %h0|%h0, %1}"
7929 [(set_attr "type" "test")
7930 (set_attr "mode" "QI")
7931 (set_attr "length_immediate" "1")
7932 (set_attr "pent_pair" "np")])
7933
7934 (define_insn "*testqi_ext_1"
7935 [(set (reg FLAGS_REG)
7936 (compare
7937 (and:SI
7938 (zero_extract:SI
7939 (match_operand 0 "ext_register_operand" "Q")
7940 (const_int 8)
7941 (const_int 8))
7942 (zero_extend:SI
7943 (match_operand:QI 1 "general_operand" "Qm")))
7944 (const_int 0)))]
7945 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7946 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7947 "test{b}\t{%1, %h0|%h0, %1}"
7948 [(set_attr "type" "test")
7949 (set_attr "mode" "QI")])
7950
7951 (define_insn "*testqi_ext_1_rex64"
7952 [(set (reg FLAGS_REG)
7953 (compare
7954 (and:SI
7955 (zero_extract:SI
7956 (match_operand 0 "ext_register_operand" "Q")
7957 (const_int 8)
7958 (const_int 8))
7959 (zero_extend:SI
7960 (match_operand:QI 1 "register_operand" "Q")))
7961 (const_int 0)))]
7962 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7963 "test{b}\t{%1, %h0|%h0, %1}"
7964 [(set_attr "type" "test")
7965 (set_attr "mode" "QI")])
7966
7967 (define_insn "*testqi_ext_2"
7968 [(set (reg FLAGS_REG)
7969 (compare
7970 (and:SI
7971 (zero_extract:SI
7972 (match_operand 0 "ext_register_operand" "Q")
7973 (const_int 8)
7974 (const_int 8))
7975 (zero_extract:SI
7976 (match_operand 1 "ext_register_operand" "Q")
7977 (const_int 8)
7978 (const_int 8)))
7979 (const_int 0)))]
7980 "ix86_match_ccmode (insn, CCNOmode)"
7981 "test{b}\t{%h1, %h0|%h0, %h1}"
7982 [(set_attr "type" "test")
7983 (set_attr "mode" "QI")])
7984
7985 ;; Combine likes to form bit extractions for some tests. Humor it.
7986 (define_insn "*testqi_ext_3"
7987 [(set (reg FLAGS_REG)
7988 (compare (zero_extract:SI
7989 (match_operand 0 "nonimmediate_operand" "rm")
7990 (match_operand:SI 1 "const_int_operand" "")
7991 (match_operand:SI 2 "const_int_operand" ""))
7992 (const_int 0)))]
7993 "ix86_match_ccmode (insn, CCNOmode)
7994 && (GET_MODE (operands[0]) == SImode
7995 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7996 || GET_MODE (operands[0]) == HImode
7997 || GET_MODE (operands[0]) == QImode)"
7998 "#")
7999
8000 (define_insn "*testqi_ext_3_rex64"
8001 [(set (reg FLAGS_REG)
8002 (compare (zero_extract:DI
8003 (match_operand 0 "nonimmediate_operand" "rm")
8004 (match_operand:DI 1 "const_int_operand" "")
8005 (match_operand:DI 2 "const_int_operand" ""))
8006 (const_int 0)))]
8007 "TARGET_64BIT
8008 && ix86_match_ccmode (insn, CCNOmode)
8009 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8010 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8011 /* Ensure that resulting mask is zero or sign extended operand. */
8012 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8013 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8014 && INTVAL (operands[1]) > 32))
8015 && (GET_MODE (operands[0]) == SImode
8016 || GET_MODE (operands[0]) == DImode
8017 || GET_MODE (operands[0]) == HImode
8018 || GET_MODE (operands[0]) == QImode)"
8019 "#")
8020
8021 (define_split
8022 [(set (match_operand 0 "flags_reg_operand" "")
8023 (match_operator 1 "compare_operator"
8024 [(zero_extract
8025 (match_operand 2 "nonimmediate_operand" "")
8026 (match_operand 3 "const_int_operand" "")
8027 (match_operand 4 "const_int_operand" ""))
8028 (const_int 0)]))]
8029 "ix86_match_ccmode (insn, CCNOmode)"
8030 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8031 {
8032 rtx val = operands[2];
8033 HOST_WIDE_INT len = INTVAL (operands[3]);
8034 HOST_WIDE_INT pos = INTVAL (operands[4]);
8035 HOST_WIDE_INT mask;
8036 enum machine_mode mode, submode;
8037
8038 mode = GET_MODE (val);
8039 if (GET_CODE (val) == MEM)
8040 {
8041 /* ??? Combine likes to put non-volatile mem extractions in QImode
8042 no matter the size of the test. So find a mode that works. */
8043 if (! MEM_VOLATILE_P (val))
8044 {
8045 mode = smallest_mode_for_size (pos + len, MODE_INT);
8046 val = adjust_address (val, mode, 0);
8047 }
8048 }
8049 else if (GET_CODE (val) == SUBREG
8050 && (submode = GET_MODE (SUBREG_REG (val)),
8051 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8052 && pos + len <= GET_MODE_BITSIZE (submode))
8053 {
8054 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8055 mode = submode;
8056 val = SUBREG_REG (val);
8057 }
8058 else if (mode == HImode && pos + len <= 8)
8059 {
8060 /* Small HImode tests can be converted to QImode. */
8061 mode = QImode;
8062 val = gen_lowpart (QImode, val);
8063 }
8064
8065 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8066 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8067
8068 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8069 })
8070
8071 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8072 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8073 ;; this is relatively important trick.
8074 ;; Do the conversion only post-reload to avoid limiting of the register class
8075 ;; to QI regs.
8076 (define_split
8077 [(set (match_operand 0 "flags_reg_operand" "")
8078 (match_operator 1 "compare_operator"
8079 [(and (match_operand 2 "register_operand" "")
8080 (match_operand 3 "const_int_operand" ""))
8081 (const_int 0)]))]
8082 "reload_completed
8083 && QI_REG_P (operands[2])
8084 && GET_MODE (operands[2]) != QImode
8085 && ((ix86_match_ccmode (insn, CCZmode)
8086 && !(INTVAL (operands[3]) & ~(255 << 8)))
8087 || (ix86_match_ccmode (insn, CCNOmode)
8088 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8089 [(set (match_dup 0)
8090 (match_op_dup 1
8091 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8092 (match_dup 3))
8093 (const_int 0)]))]
8094 "operands[2] = gen_lowpart (SImode, operands[2]);
8095 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8096
8097 (define_split
8098 [(set (match_operand 0 "flags_reg_operand" "")
8099 (match_operator 1 "compare_operator"
8100 [(and (match_operand 2 "nonimmediate_operand" "")
8101 (match_operand 3 "const_int_operand" ""))
8102 (const_int 0)]))]
8103 "reload_completed
8104 && GET_MODE (operands[2]) != QImode
8105 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8106 && ((ix86_match_ccmode (insn, CCZmode)
8107 && !(INTVAL (operands[3]) & ~255))
8108 || (ix86_match_ccmode (insn, CCNOmode)
8109 && !(INTVAL (operands[3]) & ~127)))"
8110 [(set (match_dup 0)
8111 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8112 (const_int 0)]))]
8113 "operands[2] = gen_lowpart (QImode, operands[2]);
8114 operands[3] = gen_lowpart (QImode, operands[3]);")
8115
8116
8117 ;; %%% This used to optimize known byte-wide and operations to memory,
8118 ;; and sometimes to QImode registers. If this is considered useful,
8119 ;; it should be done with splitters.
8120
8121 (define_expand "anddi3"
8122 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8123 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8124 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8125 (clobber (reg:CC FLAGS_REG))]
8126 "TARGET_64BIT"
8127 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8128
8129 (define_insn "*anddi_1_rex64"
8130 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8131 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8132 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8133 (clobber (reg:CC FLAGS_REG))]
8134 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8135 {
8136 switch (get_attr_type (insn))
8137 {
8138 case TYPE_IMOVX:
8139 {
8140 enum machine_mode mode;
8141
8142 if (GET_CODE (operands[2]) != CONST_INT)
8143 abort ();
8144 if (INTVAL (operands[2]) == 0xff)
8145 mode = QImode;
8146 else if (INTVAL (operands[2]) == 0xffff)
8147 mode = HImode;
8148 else
8149 abort ();
8150
8151 operands[1] = gen_lowpart (mode, operands[1]);
8152 if (mode == QImode)
8153 return "movz{bq|x}\t{%1,%0|%0, %1}";
8154 else
8155 return "movz{wq|x}\t{%1,%0|%0, %1}";
8156 }
8157
8158 default:
8159 if (! rtx_equal_p (operands[0], operands[1]))
8160 abort ();
8161 if (get_attr_mode (insn) == MODE_SI)
8162 return "and{l}\t{%k2, %k0|%k0, %k2}";
8163 else
8164 return "and{q}\t{%2, %0|%0, %2}";
8165 }
8166 }
8167 [(set_attr "type" "alu,alu,alu,imovx")
8168 (set_attr "length_immediate" "*,*,*,0")
8169 (set_attr "mode" "SI,DI,DI,DI")])
8170
8171 (define_insn "*anddi_2"
8172 [(set (reg FLAGS_REG)
8173 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8174 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8175 (const_int 0)))
8176 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8177 (and:DI (match_dup 1) (match_dup 2)))]
8178 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8179 && ix86_binary_operator_ok (AND, DImode, operands)"
8180 "@
8181 and{l}\t{%k2, %k0|%k0, %k2}
8182 and{q}\t{%2, %0|%0, %2}
8183 and{q}\t{%2, %0|%0, %2}"
8184 [(set_attr "type" "alu")
8185 (set_attr "mode" "SI,DI,DI")])
8186
8187 (define_expand "andsi3"
8188 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8189 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8190 (match_operand:SI 2 "general_operand" "")))
8191 (clobber (reg:CC FLAGS_REG))]
8192 ""
8193 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8194
8195 (define_insn "*andsi_1"
8196 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8197 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8198 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8199 (clobber (reg:CC FLAGS_REG))]
8200 "ix86_binary_operator_ok (AND, SImode, operands)"
8201 {
8202 switch (get_attr_type (insn))
8203 {
8204 case TYPE_IMOVX:
8205 {
8206 enum machine_mode mode;
8207
8208 if (GET_CODE (operands[2]) != CONST_INT)
8209 abort ();
8210 if (INTVAL (operands[2]) == 0xff)
8211 mode = QImode;
8212 else if (INTVAL (operands[2]) == 0xffff)
8213 mode = HImode;
8214 else
8215 abort ();
8216
8217 operands[1] = gen_lowpart (mode, operands[1]);
8218 if (mode == QImode)
8219 return "movz{bl|x}\t{%1,%0|%0, %1}";
8220 else
8221 return "movz{wl|x}\t{%1,%0|%0, %1}";
8222 }
8223
8224 default:
8225 if (! rtx_equal_p (operands[0], operands[1]))
8226 abort ();
8227 return "and{l}\t{%2, %0|%0, %2}";
8228 }
8229 }
8230 [(set_attr "type" "alu,alu,imovx")
8231 (set_attr "length_immediate" "*,*,0")
8232 (set_attr "mode" "SI")])
8233
8234 (define_split
8235 [(set (match_operand 0 "register_operand" "")
8236 (and (match_dup 0)
8237 (const_int -65536)))
8238 (clobber (reg:CC FLAGS_REG))]
8239 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8240 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8241 "operands[1] = gen_lowpart (HImode, operands[0]);")
8242
8243 (define_split
8244 [(set (match_operand 0 "ext_register_operand" "")
8245 (and (match_dup 0)
8246 (const_int -256)))
8247 (clobber (reg:CC FLAGS_REG))]
8248 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8249 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8250 "operands[1] = gen_lowpart (QImode, operands[0]);")
8251
8252 (define_split
8253 [(set (match_operand 0 "ext_register_operand" "")
8254 (and (match_dup 0)
8255 (const_int -65281)))
8256 (clobber (reg:CC FLAGS_REG))]
8257 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8258 [(parallel [(set (zero_extract:SI (match_dup 0)
8259 (const_int 8)
8260 (const_int 8))
8261 (xor:SI
8262 (zero_extract:SI (match_dup 0)
8263 (const_int 8)
8264 (const_int 8))
8265 (zero_extract:SI (match_dup 0)
8266 (const_int 8)
8267 (const_int 8))))
8268 (clobber (reg:CC FLAGS_REG))])]
8269 "operands[0] = gen_lowpart (SImode, operands[0]);")
8270
8271 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8272 (define_insn "*andsi_1_zext"
8273 [(set (match_operand:DI 0 "register_operand" "=r")
8274 (zero_extend:DI
8275 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8276 (match_operand:SI 2 "general_operand" "rim"))))
8277 (clobber (reg:CC FLAGS_REG))]
8278 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8279 "and{l}\t{%2, %k0|%k0, %2}"
8280 [(set_attr "type" "alu")
8281 (set_attr "mode" "SI")])
8282
8283 (define_insn "*andsi_2"
8284 [(set (reg FLAGS_REG)
8285 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8286 (match_operand:SI 2 "general_operand" "rim,ri"))
8287 (const_int 0)))
8288 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8289 (and:SI (match_dup 1) (match_dup 2)))]
8290 "ix86_match_ccmode (insn, CCNOmode)
8291 && ix86_binary_operator_ok (AND, SImode, operands)"
8292 "and{l}\t{%2, %0|%0, %2}"
8293 [(set_attr "type" "alu")
8294 (set_attr "mode" "SI")])
8295
8296 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8297 (define_insn "*andsi_2_zext"
8298 [(set (reg FLAGS_REG)
8299 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8300 (match_operand:SI 2 "general_operand" "rim"))
8301 (const_int 0)))
8302 (set (match_operand:DI 0 "register_operand" "=r")
8303 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8304 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8305 && ix86_binary_operator_ok (AND, SImode, operands)"
8306 "and{l}\t{%2, %k0|%k0, %2}"
8307 [(set_attr "type" "alu")
8308 (set_attr "mode" "SI")])
8309
8310 (define_expand "andhi3"
8311 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8312 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8313 (match_operand:HI 2 "general_operand" "")))
8314 (clobber (reg:CC FLAGS_REG))]
8315 "TARGET_HIMODE_MATH"
8316 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8317
8318 (define_insn "*andhi_1"
8319 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8320 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8321 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8322 (clobber (reg:CC FLAGS_REG))]
8323 "ix86_binary_operator_ok (AND, HImode, operands)"
8324 {
8325 switch (get_attr_type (insn))
8326 {
8327 case TYPE_IMOVX:
8328 if (GET_CODE (operands[2]) != CONST_INT)
8329 abort ();
8330 if (INTVAL (operands[2]) == 0xff)
8331 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8332 abort ();
8333
8334 default:
8335 if (! rtx_equal_p (operands[0], operands[1]))
8336 abort ();
8337
8338 return "and{w}\t{%2, %0|%0, %2}";
8339 }
8340 }
8341 [(set_attr "type" "alu,alu,imovx")
8342 (set_attr "length_immediate" "*,*,0")
8343 (set_attr "mode" "HI,HI,SI")])
8344
8345 (define_insn "*andhi_2"
8346 [(set (reg FLAGS_REG)
8347 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8348 (match_operand:HI 2 "general_operand" "rim,ri"))
8349 (const_int 0)))
8350 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8351 (and:HI (match_dup 1) (match_dup 2)))]
8352 "ix86_match_ccmode (insn, CCNOmode)
8353 && ix86_binary_operator_ok (AND, HImode, operands)"
8354 "and{w}\t{%2, %0|%0, %2}"
8355 [(set_attr "type" "alu")
8356 (set_attr "mode" "HI")])
8357
8358 (define_expand "andqi3"
8359 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8360 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8361 (match_operand:QI 2 "general_operand" "")))
8362 (clobber (reg:CC FLAGS_REG))]
8363 "TARGET_QIMODE_MATH"
8364 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8365
8366 ;; %%% Potential partial reg stall on alternative 2. What to do?
8367 (define_insn "*andqi_1"
8368 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8369 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8370 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8371 (clobber (reg:CC FLAGS_REG))]
8372 "ix86_binary_operator_ok (AND, QImode, operands)"
8373 "@
8374 and{b}\t{%2, %0|%0, %2}
8375 and{b}\t{%2, %0|%0, %2}
8376 and{l}\t{%k2, %k0|%k0, %k2}"
8377 [(set_attr "type" "alu")
8378 (set_attr "mode" "QI,QI,SI")])
8379
8380 (define_insn "*andqi_1_slp"
8381 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8382 (and:QI (match_dup 0)
8383 (match_operand:QI 1 "general_operand" "qi,qmi")))
8384 (clobber (reg:CC FLAGS_REG))]
8385 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8386 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8387 "and{b}\t{%1, %0|%0, %1}"
8388 [(set_attr "type" "alu1")
8389 (set_attr "mode" "QI")])
8390
8391 (define_insn "*andqi_2_maybe_si"
8392 [(set (reg FLAGS_REG)
8393 (compare (and:QI
8394 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8395 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8396 (const_int 0)))
8397 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8398 (and:QI (match_dup 1) (match_dup 2)))]
8399 "ix86_binary_operator_ok (AND, QImode, operands)
8400 && ix86_match_ccmode (insn,
8401 GET_CODE (operands[2]) == CONST_INT
8402 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8403 {
8404 if (which_alternative == 2)
8405 {
8406 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8407 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8408 return "and{l}\t{%2, %k0|%k0, %2}";
8409 }
8410 return "and{b}\t{%2, %0|%0, %2}";
8411 }
8412 [(set_attr "type" "alu")
8413 (set_attr "mode" "QI,QI,SI")])
8414
8415 (define_insn "*andqi_2"
8416 [(set (reg FLAGS_REG)
8417 (compare (and:QI
8418 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8419 (match_operand:QI 2 "general_operand" "qim,qi"))
8420 (const_int 0)))
8421 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8422 (and:QI (match_dup 1) (match_dup 2)))]
8423 "ix86_match_ccmode (insn, CCNOmode)
8424 && ix86_binary_operator_ok (AND, QImode, operands)"
8425 "and{b}\t{%2, %0|%0, %2}"
8426 [(set_attr "type" "alu")
8427 (set_attr "mode" "QI")])
8428
8429 (define_insn "*andqi_2_slp"
8430 [(set (reg FLAGS_REG)
8431 (compare (and:QI
8432 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8433 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8434 (const_int 0)))
8435 (set (strict_low_part (match_dup 0))
8436 (and:QI (match_dup 0) (match_dup 1)))]
8437 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8438 && ix86_match_ccmode (insn, CCNOmode)
8439 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8440 "and{b}\t{%1, %0|%0, %1}"
8441 [(set_attr "type" "alu1")
8442 (set_attr "mode" "QI")])
8443
8444 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8445 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8446 ;; for a QImode operand, which of course failed.
8447
8448 (define_insn "andqi_ext_0"
8449 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8450 (const_int 8)
8451 (const_int 8))
8452 (and:SI
8453 (zero_extract:SI
8454 (match_operand 1 "ext_register_operand" "0")
8455 (const_int 8)
8456 (const_int 8))
8457 (match_operand 2 "const_int_operand" "n")))
8458 (clobber (reg:CC FLAGS_REG))]
8459 ""
8460 "and{b}\t{%2, %h0|%h0, %2}"
8461 [(set_attr "type" "alu")
8462 (set_attr "length_immediate" "1")
8463 (set_attr "mode" "QI")])
8464
8465 ;; Generated by peephole translating test to and. This shows up
8466 ;; often in fp comparisons.
8467
8468 (define_insn "*andqi_ext_0_cc"
8469 [(set (reg FLAGS_REG)
8470 (compare
8471 (and:SI
8472 (zero_extract:SI
8473 (match_operand 1 "ext_register_operand" "0")
8474 (const_int 8)
8475 (const_int 8))
8476 (match_operand 2 "const_int_operand" "n"))
8477 (const_int 0)))
8478 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8479 (const_int 8)
8480 (const_int 8))
8481 (and:SI
8482 (zero_extract:SI
8483 (match_dup 1)
8484 (const_int 8)
8485 (const_int 8))
8486 (match_dup 2)))]
8487 "ix86_match_ccmode (insn, CCNOmode)"
8488 "and{b}\t{%2, %h0|%h0, %2}"
8489 [(set_attr "type" "alu")
8490 (set_attr "length_immediate" "1")
8491 (set_attr "mode" "QI")])
8492
8493 (define_insn "*andqi_ext_1"
8494 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8495 (const_int 8)
8496 (const_int 8))
8497 (and:SI
8498 (zero_extract:SI
8499 (match_operand 1 "ext_register_operand" "0")
8500 (const_int 8)
8501 (const_int 8))
8502 (zero_extend:SI
8503 (match_operand:QI 2 "general_operand" "Qm"))))
8504 (clobber (reg:CC FLAGS_REG))]
8505 "!TARGET_64BIT"
8506 "and{b}\t{%2, %h0|%h0, %2}"
8507 [(set_attr "type" "alu")
8508 (set_attr "length_immediate" "0")
8509 (set_attr "mode" "QI")])
8510
8511 (define_insn "*andqi_ext_1_rex64"
8512 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8513 (const_int 8)
8514 (const_int 8))
8515 (and:SI
8516 (zero_extract:SI
8517 (match_operand 1 "ext_register_operand" "0")
8518 (const_int 8)
8519 (const_int 8))
8520 (zero_extend:SI
8521 (match_operand 2 "ext_register_operand" "Q"))))
8522 (clobber (reg:CC FLAGS_REG))]
8523 "TARGET_64BIT"
8524 "and{b}\t{%2, %h0|%h0, %2}"
8525 [(set_attr "type" "alu")
8526 (set_attr "length_immediate" "0")
8527 (set_attr "mode" "QI")])
8528
8529 (define_insn "*andqi_ext_2"
8530 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8531 (const_int 8)
8532 (const_int 8))
8533 (and:SI
8534 (zero_extract:SI
8535 (match_operand 1 "ext_register_operand" "%0")
8536 (const_int 8)
8537 (const_int 8))
8538 (zero_extract:SI
8539 (match_operand 2 "ext_register_operand" "Q")
8540 (const_int 8)
8541 (const_int 8))))
8542 (clobber (reg:CC FLAGS_REG))]
8543 ""
8544 "and{b}\t{%h2, %h0|%h0, %h2}"
8545 [(set_attr "type" "alu")
8546 (set_attr "length_immediate" "0")
8547 (set_attr "mode" "QI")])
8548
8549 ;; Convert wide AND instructions with immediate operand to shorter QImode
8550 ;; equivalents when possible.
8551 ;; Don't do the splitting with memory operands, since it introduces risk
8552 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8553 ;; for size, but that can (should?) be handled by generic code instead.
8554 (define_split
8555 [(set (match_operand 0 "register_operand" "")
8556 (and (match_operand 1 "register_operand" "")
8557 (match_operand 2 "const_int_operand" "")))
8558 (clobber (reg:CC FLAGS_REG))]
8559 "reload_completed
8560 && QI_REG_P (operands[0])
8561 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8562 && !(~INTVAL (operands[2]) & ~(255 << 8))
8563 && GET_MODE (operands[0]) != QImode"
8564 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8565 (and:SI (zero_extract:SI (match_dup 1)
8566 (const_int 8) (const_int 8))
8567 (match_dup 2)))
8568 (clobber (reg:CC FLAGS_REG))])]
8569 "operands[0] = gen_lowpart (SImode, operands[0]);
8570 operands[1] = gen_lowpart (SImode, operands[1]);
8571 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8572
8573 ;; Since AND can be encoded with sign extended immediate, this is only
8574 ;; profitable when 7th bit is not set.
8575 (define_split
8576 [(set (match_operand 0 "register_operand" "")
8577 (and (match_operand 1 "general_operand" "")
8578 (match_operand 2 "const_int_operand" "")))
8579 (clobber (reg:CC FLAGS_REG))]
8580 "reload_completed
8581 && ANY_QI_REG_P (operands[0])
8582 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8583 && !(~INTVAL (operands[2]) & ~255)
8584 && !(INTVAL (operands[2]) & 128)
8585 && GET_MODE (operands[0]) != QImode"
8586 [(parallel [(set (strict_low_part (match_dup 0))
8587 (and:QI (match_dup 1)
8588 (match_dup 2)))
8589 (clobber (reg:CC FLAGS_REG))])]
8590 "operands[0] = gen_lowpart (QImode, operands[0]);
8591 operands[1] = gen_lowpart (QImode, operands[1]);
8592 operands[2] = gen_lowpart (QImode, operands[2]);")
8593 \f
8594 ;; Logical inclusive OR instructions
8595
8596 ;; %%% This used to optimize known byte-wide and operations to memory.
8597 ;; If this is considered useful, it should be done with splitters.
8598
8599 (define_expand "iordi3"
8600 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8601 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8602 (match_operand:DI 2 "x86_64_general_operand" "")))
8603 (clobber (reg:CC FLAGS_REG))]
8604 "TARGET_64BIT"
8605 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8606
8607 (define_insn "*iordi_1_rex64"
8608 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8609 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8610 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8611 (clobber (reg:CC FLAGS_REG))]
8612 "TARGET_64BIT
8613 && ix86_binary_operator_ok (IOR, DImode, operands)"
8614 "or{q}\t{%2, %0|%0, %2}"
8615 [(set_attr "type" "alu")
8616 (set_attr "mode" "DI")])
8617
8618 (define_insn "*iordi_2_rex64"
8619 [(set (reg FLAGS_REG)
8620 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8621 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8622 (const_int 0)))
8623 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8624 (ior:DI (match_dup 1) (match_dup 2)))]
8625 "TARGET_64BIT
8626 && ix86_match_ccmode (insn, CCNOmode)
8627 && ix86_binary_operator_ok (IOR, DImode, operands)"
8628 "or{q}\t{%2, %0|%0, %2}"
8629 [(set_attr "type" "alu")
8630 (set_attr "mode" "DI")])
8631
8632 (define_insn "*iordi_3_rex64"
8633 [(set (reg FLAGS_REG)
8634 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8635 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8636 (const_int 0)))
8637 (clobber (match_scratch:DI 0 "=r"))]
8638 "TARGET_64BIT
8639 && ix86_match_ccmode (insn, CCNOmode)
8640 && ix86_binary_operator_ok (IOR, DImode, operands)"
8641 "or{q}\t{%2, %0|%0, %2}"
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "DI")])
8644
8645
8646 (define_expand "iorsi3"
8647 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8648 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8649 (match_operand:SI 2 "general_operand" "")))
8650 (clobber (reg:CC FLAGS_REG))]
8651 ""
8652 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8653
8654 (define_insn "*iorsi_1"
8655 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8656 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8657 (match_operand:SI 2 "general_operand" "ri,rmi")))
8658 (clobber (reg:CC FLAGS_REG))]
8659 "ix86_binary_operator_ok (IOR, SImode, operands)"
8660 "or{l}\t{%2, %0|%0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8663
8664 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8665 (define_insn "*iorsi_1_zext"
8666 [(set (match_operand:DI 0 "register_operand" "=rm")
8667 (zero_extend:DI
8668 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8669 (match_operand:SI 2 "general_operand" "rim"))))
8670 (clobber (reg:CC FLAGS_REG))]
8671 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8672 "or{l}\t{%2, %k0|%k0, %2}"
8673 [(set_attr "type" "alu")
8674 (set_attr "mode" "SI")])
8675
8676 (define_insn "*iorsi_1_zext_imm"
8677 [(set (match_operand:DI 0 "register_operand" "=rm")
8678 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8679 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8680 (clobber (reg:CC FLAGS_REG))]
8681 "TARGET_64BIT"
8682 "or{l}\t{%2, %k0|%k0, %2}"
8683 [(set_attr "type" "alu")
8684 (set_attr "mode" "SI")])
8685
8686 (define_insn "*iorsi_2"
8687 [(set (reg FLAGS_REG)
8688 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8689 (match_operand:SI 2 "general_operand" "rim,ri"))
8690 (const_int 0)))
8691 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8692 (ior:SI (match_dup 1) (match_dup 2)))]
8693 "ix86_match_ccmode (insn, CCNOmode)
8694 && ix86_binary_operator_ok (IOR, SImode, operands)"
8695 "or{l}\t{%2, %0|%0, %2}"
8696 [(set_attr "type" "alu")
8697 (set_attr "mode" "SI")])
8698
8699 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8700 ;; ??? Special case for immediate operand is missing - it is tricky.
8701 (define_insn "*iorsi_2_zext"
8702 [(set (reg FLAGS_REG)
8703 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8704 (match_operand:SI 2 "general_operand" "rim"))
8705 (const_int 0)))
8706 (set (match_operand:DI 0 "register_operand" "=r")
8707 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8708 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8709 && ix86_binary_operator_ok (IOR, SImode, operands)"
8710 "or{l}\t{%2, %k0|%k0, %2}"
8711 [(set_attr "type" "alu")
8712 (set_attr "mode" "SI")])
8713
8714 (define_insn "*iorsi_2_zext_imm"
8715 [(set (reg FLAGS_REG)
8716 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8717 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8718 (const_int 0)))
8719 (set (match_operand:DI 0 "register_operand" "=r")
8720 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8721 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8722 && ix86_binary_operator_ok (IOR, SImode, operands)"
8723 "or{l}\t{%2, %k0|%k0, %2}"
8724 [(set_attr "type" "alu")
8725 (set_attr "mode" "SI")])
8726
8727 (define_insn "*iorsi_3"
8728 [(set (reg FLAGS_REG)
8729 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8730 (match_operand:SI 2 "general_operand" "rim"))
8731 (const_int 0)))
8732 (clobber (match_scratch:SI 0 "=r"))]
8733 "ix86_match_ccmode (insn, CCNOmode)
8734 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8735 "or{l}\t{%2, %0|%0, %2}"
8736 [(set_attr "type" "alu")
8737 (set_attr "mode" "SI")])
8738
8739 (define_expand "iorhi3"
8740 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8741 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8742 (match_operand:HI 2 "general_operand" "")))
8743 (clobber (reg:CC FLAGS_REG))]
8744 "TARGET_HIMODE_MATH"
8745 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8746
8747 (define_insn "*iorhi_1"
8748 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8749 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8750 (match_operand:HI 2 "general_operand" "rmi,ri")))
8751 (clobber (reg:CC FLAGS_REG))]
8752 "ix86_binary_operator_ok (IOR, HImode, operands)"
8753 "or{w}\t{%2, %0|%0, %2}"
8754 [(set_attr "type" "alu")
8755 (set_attr "mode" "HI")])
8756
8757 (define_insn "*iorhi_2"
8758 [(set (reg FLAGS_REG)
8759 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8760 (match_operand:HI 2 "general_operand" "rim,ri"))
8761 (const_int 0)))
8762 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8763 (ior:HI (match_dup 1) (match_dup 2)))]
8764 "ix86_match_ccmode (insn, CCNOmode)
8765 && ix86_binary_operator_ok (IOR, HImode, operands)"
8766 "or{w}\t{%2, %0|%0, %2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "HI")])
8769
8770 (define_insn "*iorhi_3"
8771 [(set (reg FLAGS_REG)
8772 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8773 (match_operand:HI 2 "general_operand" "rim"))
8774 (const_int 0)))
8775 (clobber (match_scratch:HI 0 "=r"))]
8776 "ix86_match_ccmode (insn, CCNOmode)
8777 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8778 "or{w}\t{%2, %0|%0, %2}"
8779 [(set_attr "type" "alu")
8780 (set_attr "mode" "HI")])
8781
8782 (define_expand "iorqi3"
8783 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8784 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8785 (match_operand:QI 2 "general_operand" "")))
8786 (clobber (reg:CC FLAGS_REG))]
8787 "TARGET_QIMODE_MATH"
8788 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8789
8790 ;; %%% Potential partial reg stall on alternative 2. What to do?
8791 (define_insn "*iorqi_1"
8792 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8793 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8794 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8795 (clobber (reg:CC FLAGS_REG))]
8796 "ix86_binary_operator_ok (IOR, QImode, operands)"
8797 "@
8798 or{b}\t{%2, %0|%0, %2}
8799 or{b}\t{%2, %0|%0, %2}
8800 or{l}\t{%k2, %k0|%k0, %k2}"
8801 [(set_attr "type" "alu")
8802 (set_attr "mode" "QI,QI,SI")])
8803
8804 (define_insn "*iorqi_1_slp"
8805 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8806 (ior:QI (match_dup 0)
8807 (match_operand:QI 1 "general_operand" "qmi,qi")))
8808 (clobber (reg:CC FLAGS_REG))]
8809 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8810 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8811 "or{b}\t{%1, %0|%0, %1}"
8812 [(set_attr "type" "alu1")
8813 (set_attr "mode" "QI")])
8814
8815 (define_insn "*iorqi_2"
8816 [(set (reg FLAGS_REG)
8817 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8818 (match_operand:QI 2 "general_operand" "qim,qi"))
8819 (const_int 0)))
8820 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8821 (ior:QI (match_dup 1) (match_dup 2)))]
8822 "ix86_match_ccmode (insn, CCNOmode)
8823 && ix86_binary_operator_ok (IOR, QImode, operands)"
8824 "or{b}\t{%2, %0|%0, %2}"
8825 [(set_attr "type" "alu")
8826 (set_attr "mode" "QI")])
8827
8828 (define_insn "*iorqi_2_slp"
8829 [(set (reg FLAGS_REG)
8830 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8831 (match_operand:QI 1 "general_operand" "qim,qi"))
8832 (const_int 0)))
8833 (set (strict_low_part (match_dup 0))
8834 (ior:QI (match_dup 0) (match_dup 1)))]
8835 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8836 && ix86_match_ccmode (insn, CCNOmode)
8837 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8838 "or{b}\t{%1, %0|%0, %1}"
8839 [(set_attr "type" "alu1")
8840 (set_attr "mode" "QI")])
8841
8842 (define_insn "*iorqi_3"
8843 [(set (reg FLAGS_REG)
8844 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8845 (match_operand:QI 2 "general_operand" "qim"))
8846 (const_int 0)))
8847 (clobber (match_scratch:QI 0 "=q"))]
8848 "ix86_match_ccmode (insn, CCNOmode)
8849 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8850 "or{b}\t{%2, %0|%0, %2}"
8851 [(set_attr "type" "alu")
8852 (set_attr "mode" "QI")])
8853
8854 (define_insn "iorqi_ext_0"
8855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8856 (const_int 8)
8857 (const_int 8))
8858 (ior:SI
8859 (zero_extract:SI
8860 (match_operand 1 "ext_register_operand" "0")
8861 (const_int 8)
8862 (const_int 8))
8863 (match_operand 2 "const_int_operand" "n")))
8864 (clobber (reg:CC FLAGS_REG))]
8865 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8866 "or{b}\t{%2, %h0|%h0, %2}"
8867 [(set_attr "type" "alu")
8868 (set_attr "length_immediate" "1")
8869 (set_attr "mode" "QI")])
8870
8871 (define_insn "*iorqi_ext_1"
8872 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8873 (const_int 8)
8874 (const_int 8))
8875 (ior:SI
8876 (zero_extract:SI
8877 (match_operand 1 "ext_register_operand" "0")
8878 (const_int 8)
8879 (const_int 8))
8880 (zero_extend:SI
8881 (match_operand:QI 2 "general_operand" "Qm"))))
8882 (clobber (reg:CC FLAGS_REG))]
8883 "!TARGET_64BIT
8884 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8885 "or{b}\t{%2, %h0|%h0, %2}"
8886 [(set_attr "type" "alu")
8887 (set_attr "length_immediate" "0")
8888 (set_attr "mode" "QI")])
8889
8890 (define_insn "*iorqi_ext_1_rex64"
8891 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8892 (const_int 8)
8893 (const_int 8))
8894 (ior:SI
8895 (zero_extract:SI
8896 (match_operand 1 "ext_register_operand" "0")
8897 (const_int 8)
8898 (const_int 8))
8899 (zero_extend:SI
8900 (match_operand 2 "ext_register_operand" "Q"))))
8901 (clobber (reg:CC FLAGS_REG))]
8902 "TARGET_64BIT
8903 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8904 "or{b}\t{%2, %h0|%h0, %2}"
8905 [(set_attr "type" "alu")
8906 (set_attr "length_immediate" "0")
8907 (set_attr "mode" "QI")])
8908
8909 (define_insn "*iorqi_ext_2"
8910 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8911 (const_int 8)
8912 (const_int 8))
8913 (ior:SI
8914 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8915 (const_int 8)
8916 (const_int 8))
8917 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8918 (const_int 8)
8919 (const_int 8))))
8920 (clobber (reg:CC FLAGS_REG))]
8921 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8922 "ior{b}\t{%h2, %h0|%h0, %h2}"
8923 [(set_attr "type" "alu")
8924 (set_attr "length_immediate" "0")
8925 (set_attr "mode" "QI")])
8926
8927 (define_split
8928 [(set (match_operand 0 "register_operand" "")
8929 (ior (match_operand 1 "register_operand" "")
8930 (match_operand 2 "const_int_operand" "")))
8931 (clobber (reg:CC FLAGS_REG))]
8932 "reload_completed
8933 && QI_REG_P (operands[0])
8934 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8935 && !(INTVAL (operands[2]) & ~(255 << 8))
8936 && GET_MODE (operands[0]) != QImode"
8937 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8938 (ior:SI (zero_extract:SI (match_dup 1)
8939 (const_int 8) (const_int 8))
8940 (match_dup 2)))
8941 (clobber (reg:CC FLAGS_REG))])]
8942 "operands[0] = gen_lowpart (SImode, operands[0]);
8943 operands[1] = gen_lowpart (SImode, operands[1]);
8944 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8945
8946 ;; Since OR can be encoded with sign extended immediate, this is only
8947 ;; profitable when 7th bit is set.
8948 (define_split
8949 [(set (match_operand 0 "register_operand" "")
8950 (ior (match_operand 1 "general_operand" "")
8951 (match_operand 2 "const_int_operand" "")))
8952 (clobber (reg:CC FLAGS_REG))]
8953 "reload_completed
8954 && ANY_QI_REG_P (operands[0])
8955 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8956 && !(INTVAL (operands[2]) & ~255)
8957 && (INTVAL (operands[2]) & 128)
8958 && GET_MODE (operands[0]) != QImode"
8959 [(parallel [(set (strict_low_part (match_dup 0))
8960 (ior:QI (match_dup 1)
8961 (match_dup 2)))
8962 (clobber (reg:CC FLAGS_REG))])]
8963 "operands[0] = gen_lowpart (QImode, operands[0]);
8964 operands[1] = gen_lowpart (QImode, operands[1]);
8965 operands[2] = gen_lowpart (QImode, operands[2]);")
8966 \f
8967 ;; Logical XOR instructions
8968
8969 ;; %%% This used to optimize known byte-wide and operations to memory.
8970 ;; If this is considered useful, it should be done with splitters.
8971
8972 (define_expand "xordi3"
8973 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8974 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8975 (match_operand:DI 2 "x86_64_general_operand" "")))
8976 (clobber (reg:CC FLAGS_REG))]
8977 "TARGET_64BIT"
8978 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8979
8980 (define_insn "*xordi_1_rex64"
8981 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8982 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8983 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8984 (clobber (reg:CC FLAGS_REG))]
8985 "TARGET_64BIT
8986 && ix86_binary_operator_ok (XOR, DImode, operands)"
8987 "@
8988 xor{q}\t{%2, %0|%0, %2}
8989 xor{q}\t{%2, %0|%0, %2}"
8990 [(set_attr "type" "alu")
8991 (set_attr "mode" "DI,DI")])
8992
8993 (define_insn "*xordi_2_rex64"
8994 [(set (reg FLAGS_REG)
8995 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8996 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8997 (const_int 0)))
8998 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8999 (xor:DI (match_dup 1) (match_dup 2)))]
9000 "TARGET_64BIT
9001 && ix86_match_ccmode (insn, CCNOmode)
9002 && ix86_binary_operator_ok (XOR, DImode, operands)"
9003 "@
9004 xor{q}\t{%2, %0|%0, %2}
9005 xor{q}\t{%2, %0|%0, %2}"
9006 [(set_attr "type" "alu")
9007 (set_attr "mode" "DI,DI")])
9008
9009 (define_insn "*xordi_3_rex64"
9010 [(set (reg FLAGS_REG)
9011 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9012 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9013 (const_int 0)))
9014 (clobber (match_scratch:DI 0 "=r"))]
9015 "TARGET_64BIT
9016 && ix86_match_ccmode (insn, CCNOmode)
9017 && ix86_binary_operator_ok (XOR, DImode, operands)"
9018 "xor{q}\t{%2, %0|%0, %2}"
9019 [(set_attr "type" "alu")
9020 (set_attr "mode" "DI")])
9021
9022 (define_expand "xorsi3"
9023 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9024 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9025 (match_operand:SI 2 "general_operand" "")))
9026 (clobber (reg:CC FLAGS_REG))]
9027 ""
9028 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9029
9030 (define_insn "*xorsi_1"
9031 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9032 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9033 (match_operand:SI 2 "general_operand" "ri,rm")))
9034 (clobber (reg:CC FLAGS_REG))]
9035 "ix86_binary_operator_ok (XOR, SImode, operands)"
9036 "xor{l}\t{%2, %0|%0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "SI")])
9039
9040 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9041 ;; Add speccase for immediates
9042 (define_insn "*xorsi_1_zext"
9043 [(set (match_operand:DI 0 "register_operand" "=r")
9044 (zero_extend:DI
9045 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9046 (match_operand:SI 2 "general_operand" "rim"))))
9047 (clobber (reg:CC FLAGS_REG))]
9048 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9049 "xor{l}\t{%2, %k0|%k0, %2}"
9050 [(set_attr "type" "alu")
9051 (set_attr "mode" "SI")])
9052
9053 (define_insn "*xorsi_1_zext_imm"
9054 [(set (match_operand:DI 0 "register_operand" "=r")
9055 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9056 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9057 (clobber (reg:CC FLAGS_REG))]
9058 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9059 "xor{l}\t{%2, %k0|%k0, %2}"
9060 [(set_attr "type" "alu")
9061 (set_attr "mode" "SI")])
9062
9063 (define_insn "*xorsi_2"
9064 [(set (reg FLAGS_REG)
9065 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9066 (match_operand:SI 2 "general_operand" "rim,ri"))
9067 (const_int 0)))
9068 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9069 (xor:SI (match_dup 1) (match_dup 2)))]
9070 "ix86_match_ccmode (insn, CCNOmode)
9071 && ix86_binary_operator_ok (XOR, SImode, operands)"
9072 "xor{l}\t{%2, %0|%0, %2}"
9073 [(set_attr "type" "alu")
9074 (set_attr "mode" "SI")])
9075
9076 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9077 ;; ??? Special case for immediate operand is missing - it is tricky.
9078 (define_insn "*xorsi_2_zext"
9079 [(set (reg FLAGS_REG)
9080 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9081 (match_operand:SI 2 "general_operand" "rim"))
9082 (const_int 0)))
9083 (set (match_operand:DI 0 "register_operand" "=r")
9084 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9085 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9086 && ix86_binary_operator_ok (XOR, SImode, operands)"
9087 "xor{l}\t{%2, %k0|%k0, %2}"
9088 [(set_attr "type" "alu")
9089 (set_attr "mode" "SI")])
9090
9091 (define_insn "*xorsi_2_zext_imm"
9092 [(set (reg FLAGS_REG)
9093 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9094 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9095 (const_int 0)))
9096 (set (match_operand:DI 0 "register_operand" "=r")
9097 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9098 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9099 && ix86_binary_operator_ok (XOR, SImode, operands)"
9100 "xor{l}\t{%2, %k0|%k0, %2}"
9101 [(set_attr "type" "alu")
9102 (set_attr "mode" "SI")])
9103
9104 (define_insn "*xorsi_3"
9105 [(set (reg FLAGS_REG)
9106 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9107 (match_operand:SI 2 "general_operand" "rim"))
9108 (const_int 0)))
9109 (clobber (match_scratch:SI 0 "=r"))]
9110 "ix86_match_ccmode (insn, CCNOmode)
9111 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9112 "xor{l}\t{%2, %0|%0, %2}"
9113 [(set_attr "type" "alu")
9114 (set_attr "mode" "SI")])
9115
9116 (define_expand "xorhi3"
9117 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9118 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9119 (match_operand:HI 2 "general_operand" "")))
9120 (clobber (reg:CC FLAGS_REG))]
9121 "TARGET_HIMODE_MATH"
9122 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9123
9124 (define_insn "*xorhi_1"
9125 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9126 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9127 (match_operand:HI 2 "general_operand" "rmi,ri")))
9128 (clobber (reg:CC FLAGS_REG))]
9129 "ix86_binary_operator_ok (XOR, HImode, operands)"
9130 "xor{w}\t{%2, %0|%0, %2}"
9131 [(set_attr "type" "alu")
9132 (set_attr "mode" "HI")])
9133
9134 (define_insn "*xorhi_2"
9135 [(set (reg FLAGS_REG)
9136 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9137 (match_operand:HI 2 "general_operand" "rim,ri"))
9138 (const_int 0)))
9139 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9140 (xor:HI (match_dup 1) (match_dup 2)))]
9141 "ix86_match_ccmode (insn, CCNOmode)
9142 && ix86_binary_operator_ok (XOR, HImode, operands)"
9143 "xor{w}\t{%2, %0|%0, %2}"
9144 [(set_attr "type" "alu")
9145 (set_attr "mode" "HI")])
9146
9147 (define_insn "*xorhi_3"
9148 [(set (reg FLAGS_REG)
9149 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9150 (match_operand:HI 2 "general_operand" "rim"))
9151 (const_int 0)))
9152 (clobber (match_scratch:HI 0 "=r"))]
9153 "ix86_match_ccmode (insn, CCNOmode)
9154 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9155 "xor{w}\t{%2, %0|%0, %2}"
9156 [(set_attr "type" "alu")
9157 (set_attr "mode" "HI")])
9158
9159 (define_expand "xorqi3"
9160 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9161 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9162 (match_operand:QI 2 "general_operand" "")))
9163 (clobber (reg:CC FLAGS_REG))]
9164 "TARGET_QIMODE_MATH"
9165 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9166
9167 ;; %%% Potential partial reg stall on alternative 2. What to do?
9168 (define_insn "*xorqi_1"
9169 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9170 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9171 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9172 (clobber (reg:CC FLAGS_REG))]
9173 "ix86_binary_operator_ok (XOR, QImode, operands)"
9174 "@
9175 xor{b}\t{%2, %0|%0, %2}
9176 xor{b}\t{%2, %0|%0, %2}
9177 xor{l}\t{%k2, %k0|%k0, %k2}"
9178 [(set_attr "type" "alu")
9179 (set_attr "mode" "QI,QI,SI")])
9180
9181 (define_insn "*xorqi_1_slp"
9182 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9183 (xor:QI (match_dup 0)
9184 (match_operand:QI 1 "general_operand" "qi,qmi")))
9185 (clobber (reg:CC FLAGS_REG))]
9186 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9187 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9188 "xor{b}\t{%1, %0|%0, %1}"
9189 [(set_attr "type" "alu1")
9190 (set_attr "mode" "QI")])
9191
9192 (define_insn "xorqi_ext_0"
9193 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9194 (const_int 8)
9195 (const_int 8))
9196 (xor:SI
9197 (zero_extract:SI
9198 (match_operand 1 "ext_register_operand" "0")
9199 (const_int 8)
9200 (const_int 8))
9201 (match_operand 2 "const_int_operand" "n")))
9202 (clobber (reg:CC FLAGS_REG))]
9203 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9204 "xor{b}\t{%2, %h0|%h0, %2}"
9205 [(set_attr "type" "alu")
9206 (set_attr "length_immediate" "1")
9207 (set_attr "mode" "QI")])
9208
9209 (define_insn "*xorqi_ext_1"
9210 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9211 (const_int 8)
9212 (const_int 8))
9213 (xor:SI
9214 (zero_extract:SI
9215 (match_operand 1 "ext_register_operand" "0")
9216 (const_int 8)
9217 (const_int 8))
9218 (zero_extend:SI
9219 (match_operand:QI 2 "general_operand" "Qm"))))
9220 (clobber (reg:CC FLAGS_REG))]
9221 "!TARGET_64BIT
9222 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9223 "xor{b}\t{%2, %h0|%h0, %2}"
9224 [(set_attr "type" "alu")
9225 (set_attr "length_immediate" "0")
9226 (set_attr "mode" "QI")])
9227
9228 (define_insn "*xorqi_ext_1_rex64"
9229 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9230 (const_int 8)
9231 (const_int 8))
9232 (xor:SI
9233 (zero_extract:SI
9234 (match_operand 1 "ext_register_operand" "0")
9235 (const_int 8)
9236 (const_int 8))
9237 (zero_extend:SI
9238 (match_operand 2 "ext_register_operand" "Q"))))
9239 (clobber (reg:CC FLAGS_REG))]
9240 "TARGET_64BIT
9241 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9242 "xor{b}\t{%2, %h0|%h0, %2}"
9243 [(set_attr "type" "alu")
9244 (set_attr "length_immediate" "0")
9245 (set_attr "mode" "QI")])
9246
9247 (define_insn "*xorqi_ext_2"
9248 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9249 (const_int 8)
9250 (const_int 8))
9251 (xor:SI
9252 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9253 (const_int 8)
9254 (const_int 8))
9255 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9256 (const_int 8)
9257 (const_int 8))))
9258 (clobber (reg:CC FLAGS_REG))]
9259 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9260 "xor{b}\t{%h2, %h0|%h0, %h2}"
9261 [(set_attr "type" "alu")
9262 (set_attr "length_immediate" "0")
9263 (set_attr "mode" "QI")])
9264
9265 (define_insn "*xorqi_cc_1"
9266 [(set (reg FLAGS_REG)
9267 (compare
9268 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9269 (match_operand:QI 2 "general_operand" "qim,qi"))
9270 (const_int 0)))
9271 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9272 (xor:QI (match_dup 1) (match_dup 2)))]
9273 "ix86_match_ccmode (insn, CCNOmode)
9274 && ix86_binary_operator_ok (XOR, QImode, operands)"
9275 "xor{b}\t{%2, %0|%0, %2}"
9276 [(set_attr "type" "alu")
9277 (set_attr "mode" "QI")])
9278
9279 (define_insn "*xorqi_2_slp"
9280 [(set (reg FLAGS_REG)
9281 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9282 (match_operand:QI 1 "general_operand" "qim,qi"))
9283 (const_int 0)))
9284 (set (strict_low_part (match_dup 0))
9285 (xor:QI (match_dup 0) (match_dup 1)))]
9286 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9287 && ix86_match_ccmode (insn, CCNOmode)
9288 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9289 "xor{b}\t{%1, %0|%0, %1}"
9290 [(set_attr "type" "alu1")
9291 (set_attr "mode" "QI")])
9292
9293 (define_insn "*xorqi_cc_2"
9294 [(set (reg FLAGS_REG)
9295 (compare
9296 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9297 (match_operand:QI 2 "general_operand" "qim"))
9298 (const_int 0)))
9299 (clobber (match_scratch:QI 0 "=q"))]
9300 "ix86_match_ccmode (insn, CCNOmode)
9301 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9302 "xor{b}\t{%2, %0|%0, %2}"
9303 [(set_attr "type" "alu")
9304 (set_attr "mode" "QI")])
9305
9306 (define_insn "*xorqi_cc_ext_1"
9307 [(set (reg FLAGS_REG)
9308 (compare
9309 (xor:SI
9310 (zero_extract:SI
9311 (match_operand 1 "ext_register_operand" "0")
9312 (const_int 8)
9313 (const_int 8))
9314 (match_operand:QI 2 "general_operand" "qmn"))
9315 (const_int 0)))
9316 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9317 (const_int 8)
9318 (const_int 8))
9319 (xor:SI
9320 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9321 (match_dup 2)))]
9322 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9323 "xor{b}\t{%2, %h0|%h0, %2}"
9324 [(set_attr "type" "alu")
9325 (set_attr "mode" "QI")])
9326
9327 (define_insn "*xorqi_cc_ext_1_rex64"
9328 [(set (reg FLAGS_REG)
9329 (compare
9330 (xor:SI
9331 (zero_extract:SI
9332 (match_operand 1 "ext_register_operand" "0")
9333 (const_int 8)
9334 (const_int 8))
9335 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9336 (const_int 0)))
9337 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9338 (const_int 8)
9339 (const_int 8))
9340 (xor:SI
9341 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9342 (match_dup 2)))]
9343 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9344 "xor{b}\t{%2, %h0|%h0, %2}"
9345 [(set_attr "type" "alu")
9346 (set_attr "mode" "QI")])
9347
9348 (define_expand "xorqi_cc_ext_1"
9349 [(parallel [
9350 (set (reg:CCNO FLAGS_REG)
9351 (compare:CCNO
9352 (xor:SI
9353 (zero_extract:SI
9354 (match_operand 1 "ext_register_operand" "")
9355 (const_int 8)
9356 (const_int 8))
9357 (match_operand:QI 2 "general_operand" ""))
9358 (const_int 0)))
9359 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9360 (const_int 8)
9361 (const_int 8))
9362 (xor:SI
9363 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9364 (match_dup 2)))])]
9365 ""
9366 "")
9367
9368 (define_split
9369 [(set (match_operand 0 "register_operand" "")
9370 (xor (match_operand 1 "register_operand" "")
9371 (match_operand 2 "const_int_operand" "")))
9372 (clobber (reg:CC FLAGS_REG))]
9373 "reload_completed
9374 && QI_REG_P (operands[0])
9375 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9376 && !(INTVAL (operands[2]) & ~(255 << 8))
9377 && GET_MODE (operands[0]) != QImode"
9378 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9379 (xor:SI (zero_extract:SI (match_dup 1)
9380 (const_int 8) (const_int 8))
9381 (match_dup 2)))
9382 (clobber (reg:CC FLAGS_REG))])]
9383 "operands[0] = gen_lowpart (SImode, operands[0]);
9384 operands[1] = gen_lowpart (SImode, operands[1]);
9385 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9386
9387 ;; Since XOR can be encoded with sign extended immediate, this is only
9388 ;; profitable when 7th bit is set.
9389 (define_split
9390 [(set (match_operand 0 "register_operand" "")
9391 (xor (match_operand 1 "general_operand" "")
9392 (match_operand 2 "const_int_operand" "")))
9393 (clobber (reg:CC FLAGS_REG))]
9394 "reload_completed
9395 && ANY_QI_REG_P (operands[0])
9396 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9397 && !(INTVAL (operands[2]) & ~255)
9398 && (INTVAL (operands[2]) & 128)
9399 && GET_MODE (operands[0]) != QImode"
9400 [(parallel [(set (strict_low_part (match_dup 0))
9401 (xor:QI (match_dup 1)
9402 (match_dup 2)))
9403 (clobber (reg:CC FLAGS_REG))])]
9404 "operands[0] = gen_lowpart (QImode, operands[0]);
9405 operands[1] = gen_lowpart (QImode, operands[1]);
9406 operands[2] = gen_lowpart (QImode, operands[2]);")
9407 \f
9408 ;; Negation instructions
9409
9410 (define_expand "negdi2"
9411 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9412 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9413 (clobber (reg:CC FLAGS_REG))])]
9414 ""
9415 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9416
9417 (define_insn "*negdi2_1"
9418 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9419 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9420 (clobber (reg:CC FLAGS_REG))]
9421 "!TARGET_64BIT
9422 && ix86_unary_operator_ok (NEG, DImode, operands)"
9423 "#")
9424
9425 (define_split
9426 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9427 (neg:DI (match_operand:DI 1 "general_operand" "")))
9428 (clobber (reg:CC FLAGS_REG))]
9429 "!TARGET_64BIT && reload_completed"
9430 [(parallel
9431 [(set (reg:CCZ FLAGS_REG)
9432 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9433 (set (match_dup 0) (neg:SI (match_dup 2)))])
9434 (parallel
9435 [(set (match_dup 1)
9436 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9437 (match_dup 3))
9438 (const_int 0)))
9439 (clobber (reg:CC FLAGS_REG))])
9440 (parallel
9441 [(set (match_dup 1)
9442 (neg:SI (match_dup 1)))
9443 (clobber (reg:CC FLAGS_REG))])]
9444 "split_di (operands+1, 1, operands+2, operands+3);
9445 split_di (operands+0, 1, operands+0, operands+1);")
9446
9447 (define_insn "*negdi2_1_rex64"
9448 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9449 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9450 (clobber (reg:CC FLAGS_REG))]
9451 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9452 "neg{q}\t%0"
9453 [(set_attr "type" "negnot")
9454 (set_attr "mode" "DI")])
9455
9456 ;; The problem with neg is that it does not perform (compare x 0),
9457 ;; it really performs (compare 0 x), which leaves us with the zero
9458 ;; flag being the only useful item.
9459
9460 (define_insn "*negdi2_cmpz_rex64"
9461 [(set (reg:CCZ FLAGS_REG)
9462 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9463 (const_int 0)))
9464 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9465 (neg:DI (match_dup 1)))]
9466 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9467 "neg{q}\t%0"
9468 [(set_attr "type" "negnot")
9469 (set_attr "mode" "DI")])
9470
9471
9472 (define_expand "negsi2"
9473 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9474 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9475 (clobber (reg:CC FLAGS_REG))])]
9476 ""
9477 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9478
9479 (define_insn "*negsi2_1"
9480 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9481 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9482 (clobber (reg:CC FLAGS_REG))]
9483 "ix86_unary_operator_ok (NEG, SImode, operands)"
9484 "neg{l}\t%0"
9485 [(set_attr "type" "negnot")
9486 (set_attr "mode" "SI")])
9487
9488 ;; Combine is quite creative about this pattern.
9489 (define_insn "*negsi2_1_zext"
9490 [(set (match_operand:DI 0 "register_operand" "=r")
9491 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9492 (const_int 32)))
9493 (const_int 32)))
9494 (clobber (reg:CC FLAGS_REG))]
9495 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9496 "neg{l}\t%k0"
9497 [(set_attr "type" "negnot")
9498 (set_attr "mode" "SI")])
9499
9500 ;; The problem with neg is that it does not perform (compare x 0),
9501 ;; it really performs (compare 0 x), which leaves us with the zero
9502 ;; flag being the only useful item.
9503
9504 (define_insn "*negsi2_cmpz"
9505 [(set (reg:CCZ FLAGS_REG)
9506 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9507 (const_int 0)))
9508 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9509 (neg:SI (match_dup 1)))]
9510 "ix86_unary_operator_ok (NEG, SImode, operands)"
9511 "neg{l}\t%0"
9512 [(set_attr "type" "negnot")
9513 (set_attr "mode" "SI")])
9514
9515 (define_insn "*negsi2_cmpz_zext"
9516 [(set (reg:CCZ FLAGS_REG)
9517 (compare:CCZ (lshiftrt:DI
9518 (neg:DI (ashift:DI
9519 (match_operand:DI 1 "register_operand" "0")
9520 (const_int 32)))
9521 (const_int 32))
9522 (const_int 0)))
9523 (set (match_operand:DI 0 "register_operand" "=r")
9524 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9525 (const_int 32)))
9526 (const_int 32)))]
9527 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9528 "neg{l}\t%k0"
9529 [(set_attr "type" "negnot")
9530 (set_attr "mode" "SI")])
9531
9532 (define_expand "neghi2"
9533 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9534 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9535 (clobber (reg:CC FLAGS_REG))])]
9536 "TARGET_HIMODE_MATH"
9537 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9538
9539 (define_insn "*neghi2_1"
9540 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9541 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9542 (clobber (reg:CC FLAGS_REG))]
9543 "ix86_unary_operator_ok (NEG, HImode, operands)"
9544 "neg{w}\t%0"
9545 [(set_attr "type" "negnot")
9546 (set_attr "mode" "HI")])
9547
9548 (define_insn "*neghi2_cmpz"
9549 [(set (reg:CCZ FLAGS_REG)
9550 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9551 (const_int 0)))
9552 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9553 (neg:HI (match_dup 1)))]
9554 "ix86_unary_operator_ok (NEG, HImode, operands)"
9555 "neg{w}\t%0"
9556 [(set_attr "type" "negnot")
9557 (set_attr "mode" "HI")])
9558
9559 (define_expand "negqi2"
9560 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9561 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9562 (clobber (reg:CC FLAGS_REG))])]
9563 "TARGET_QIMODE_MATH"
9564 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9565
9566 (define_insn "*negqi2_1"
9567 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9568 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9569 (clobber (reg:CC FLAGS_REG))]
9570 "ix86_unary_operator_ok (NEG, QImode, operands)"
9571 "neg{b}\t%0"
9572 [(set_attr "type" "negnot")
9573 (set_attr "mode" "QI")])
9574
9575 (define_insn "*negqi2_cmpz"
9576 [(set (reg:CCZ FLAGS_REG)
9577 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9578 (const_int 0)))
9579 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9580 (neg:QI (match_dup 1)))]
9581 "ix86_unary_operator_ok (NEG, QImode, operands)"
9582 "neg{b}\t%0"
9583 [(set_attr "type" "negnot")
9584 (set_attr "mode" "QI")])
9585
9586 ;; Changing of sign for FP values is doable using integer unit too.
9587
9588 (define_expand "negsf2"
9589 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9590 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9591 "TARGET_80387 || TARGET_SSE_MATH"
9592 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9593
9594 (define_expand "abssf2"
9595 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9596 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9597 "TARGET_80387 || TARGET_SSE_MATH"
9598 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9599
9600 (define_insn "*absnegsf2_mixed"
9601 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9602 (match_operator:SF 3 "absneg_operator"
9603 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#fr,0 ,0")]))
9604 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9605 (clobber (reg:CC FLAGS_REG))]
9606 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9607 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9608 "#")
9609
9610 (define_insn "*absnegsf2_sse"
9611 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#r,x#r,rm#x")
9612 (match_operator:SF 3 "absneg_operator"
9613 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#r,0")]))
9614 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X"))
9615 (clobber (reg:CC FLAGS_REG))]
9616 "TARGET_SSE_MATH
9617 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9618 "#")
9619
9620 (define_insn "*absnegsf2_i387"
9621 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9622 (match_operator:SF 3 "absneg_operator"
9623 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9624 (use (match_operand 2 "" ""))
9625 (clobber (reg:CC FLAGS_REG))]
9626 "TARGET_80387 && !TARGET_SSE_MATH
9627 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9628 "#")
9629
9630 (define_expand "negdf2"
9631 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9632 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9633 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9634 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9635
9636 (define_expand "absdf2"
9637 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9638 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9639 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9640 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9641
9642 (define_insn "*absnegdf2_mixed"
9643 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9644 (match_operator:DF 3 "absneg_operator"
9645 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#fr,0 ,0")]))
9646 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9647 (clobber (reg:CC FLAGS_REG))]
9648 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9649 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9650 "#")
9651
9652 (define_insn "*absnegdf2_sse"
9653 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#r,Y#r,rm#Y")
9654 (match_operator:DF 3 "absneg_operator"
9655 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#r,0")]))
9656 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X"))
9657 (clobber (reg:CC FLAGS_REG))]
9658 "TARGET_SSE2 && TARGET_SSE_MATH
9659 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9660 "#")
9661
9662 (define_insn "*absnegdf2_i387"
9663 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9664 (match_operator:DF 3 "absneg_operator"
9665 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9666 (use (match_operand 2 "" ""))
9667 (clobber (reg:CC FLAGS_REG))]
9668 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9669 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9670 "#")
9671
9672 (define_expand "negxf2"
9673 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9674 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9675 "TARGET_80387"
9676 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9677
9678 (define_expand "absxf2"
9679 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9680 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9681 "TARGET_80387"
9682 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9683
9684 (define_insn "*absnegxf2_i387"
9685 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9686 (match_operator:XF 3 "absneg_operator"
9687 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9688 (use (match_operand 2 "" ""))
9689 (clobber (reg:CC FLAGS_REG))]
9690 "TARGET_80387
9691 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9692 "#")
9693
9694 ;; Splitters for fp abs and neg.
9695
9696 (define_split
9697 [(set (match_operand 0 "fp_register_operand" "")
9698 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9699 (use (match_operand 2 "" ""))
9700 (clobber (reg:CC FLAGS_REG))]
9701 "reload_completed"
9702 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9703
9704 (define_split
9705 [(set (match_operand 0 "register_operand" "")
9706 (match_operator 3 "absneg_operator"
9707 [(match_operand 1 "register_operand" "")]))
9708 (use (match_operand 2 "nonimmediate_operand" ""))
9709 (clobber (reg:CC FLAGS_REG))]
9710 "reload_completed && SSE_REG_P (operands[0])"
9711 [(set (match_dup 0) (match_dup 3))]
9712 {
9713 enum machine_mode mode = GET_MODE (operands[0]);
9714 enum machine_mode vmode = GET_MODE (operands[2]);
9715 rtx tmp;
9716
9717 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9718 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9719 if (operands_match_p (operands[0], operands[2]))
9720 {
9721 tmp = operands[1];
9722 operands[1] = operands[2];
9723 operands[2] = tmp;
9724 }
9725 if (GET_CODE (operands[3]) == ABS)
9726 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9727 else
9728 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9729 operands[3] = tmp;
9730 })
9731
9732 (define_split
9733 [(set (match_operand:SF 0 "register_operand" "")
9734 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9735 (use (match_operand:V4SF 2 "" ""))
9736 (clobber (reg:CC FLAGS_REG))]
9737 "reload_completed"
9738 [(parallel [(set (match_dup 0) (match_dup 1))
9739 (clobber (reg:CC FLAGS_REG))])]
9740 {
9741 rtx tmp;
9742 operands[0] = gen_lowpart (SImode, operands[0]);
9743 if (GET_CODE (operands[1]) == ABS)
9744 {
9745 tmp = gen_int_mode (0x7fffffff, SImode);
9746 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9747 }
9748 else
9749 {
9750 tmp = gen_int_mode (0x80000000, SImode);
9751 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9752 }
9753 operands[1] = tmp;
9754 })
9755
9756 (define_split
9757 [(set (match_operand:DF 0 "register_operand" "")
9758 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9759 (use (match_operand 2 "" ""))
9760 (clobber (reg:CC FLAGS_REG))]
9761 "reload_completed"
9762 [(parallel [(set (match_dup 0) (match_dup 1))
9763 (clobber (reg:CC FLAGS_REG))])]
9764 {
9765 rtx tmp;
9766 if (TARGET_64BIT)
9767 {
9768 tmp = gen_lowpart (DImode, operands[0]);
9769 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9770 operands[0] = tmp;
9771
9772 if (GET_CODE (operands[1]) == ABS)
9773 tmp = const0_rtx;
9774 else
9775 tmp = gen_rtx_NOT (DImode, tmp);
9776 }
9777 else
9778 {
9779 operands[0] = gen_highpart (SImode, operands[0]);
9780 if (GET_CODE (operands[1]) == ABS)
9781 {
9782 tmp = gen_int_mode (0x7fffffff, SImode);
9783 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9784 }
9785 else
9786 {
9787 tmp = gen_int_mode (0x80000000, SImode);
9788 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9789 }
9790 }
9791 operands[1] = tmp;
9792 })
9793
9794 (define_split
9795 [(set (match_operand:XF 0 "register_operand" "")
9796 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9797 (use (match_operand 2 "" ""))
9798 (clobber (reg:CC FLAGS_REG))]
9799 "reload_completed"
9800 [(parallel [(set (match_dup 0) (match_dup 1))
9801 (clobber (reg:CC FLAGS_REG))])]
9802 {
9803 rtx tmp;
9804 operands[0] = gen_rtx_REG (SImode,
9805 true_regnum (operands[0])
9806 + (TARGET_64BIT ? 1 : 2));
9807 if (GET_CODE (operands[1]) == ABS)
9808 {
9809 tmp = GEN_INT (0x7fff);
9810 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9811 }
9812 else
9813 {
9814 tmp = GEN_INT (0x8000);
9815 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9816 }
9817 operands[1] = tmp;
9818 })
9819
9820 (define_split
9821 [(set (match_operand 0 "memory_operand" "")
9822 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9823 (use (match_operand 2 "" ""))
9824 (clobber (reg:CC FLAGS_REG))]
9825 "reload_completed"
9826 [(parallel [(set (match_dup 0) (match_dup 1))
9827 (clobber (reg:CC FLAGS_REG))])]
9828 {
9829 enum machine_mode mode = GET_MODE (operands[0]);
9830 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9831 rtx tmp;
9832
9833 operands[0] = adjust_address (operands[0], QImode, size - 1);
9834 if (GET_CODE (operands[1]) == ABS)
9835 {
9836 tmp = gen_int_mode (0x7f, QImode);
9837 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9838 }
9839 else
9840 {
9841 tmp = gen_int_mode (0x80, QImode);
9842 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9843 }
9844 operands[1] = tmp;
9845 })
9846
9847 ;; Conditionalize these after reload. If they match before reload, we
9848 ;; lose the clobber and ability to use integer instructions.
9849
9850 (define_insn "*negsf2_1"
9851 [(set (match_operand:SF 0 "register_operand" "=f")
9852 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9853 "TARGET_80387 && reload_completed"
9854 "fchs"
9855 [(set_attr "type" "fsgn")
9856 (set_attr "mode" "SF")])
9857
9858 (define_insn "*negdf2_1"
9859 [(set (match_operand:DF 0 "register_operand" "=f")
9860 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9861 "TARGET_80387 && reload_completed"
9862 "fchs"
9863 [(set_attr "type" "fsgn")
9864 (set_attr "mode" "DF")])
9865
9866 (define_insn "*negxf2_1"
9867 [(set (match_operand:XF 0 "register_operand" "=f")
9868 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9869 "TARGET_80387 && reload_completed"
9870 "fchs"
9871 [(set_attr "type" "fsgn")
9872 (set_attr "mode" "XF")])
9873
9874 (define_insn "*abssf2_1"
9875 [(set (match_operand:SF 0 "register_operand" "=f")
9876 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9877 "TARGET_80387 && reload_completed"
9878 "fabs"
9879 [(set_attr "type" "fsgn")
9880 (set_attr "mode" "SF")])
9881
9882 (define_insn "*absdf2_1"
9883 [(set (match_operand:DF 0 "register_operand" "=f")
9884 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9885 "TARGET_80387 && reload_completed"
9886 "fabs"
9887 [(set_attr "type" "fsgn")
9888 (set_attr "mode" "DF")])
9889
9890 (define_insn "*absxf2_1"
9891 [(set (match_operand:XF 0 "register_operand" "=f")
9892 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9893 "TARGET_80387 && reload_completed"
9894 "fabs"
9895 [(set_attr "type" "fsgn")
9896 (set_attr "mode" "DF")])
9897
9898 (define_insn "*negextendsfdf2"
9899 [(set (match_operand:DF 0 "register_operand" "=f")
9900 (neg:DF (float_extend:DF
9901 (match_operand:SF 1 "register_operand" "0"))))]
9902 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9903 "fchs"
9904 [(set_attr "type" "fsgn")
9905 (set_attr "mode" "DF")])
9906
9907 (define_insn "*negextenddfxf2"
9908 [(set (match_operand:XF 0 "register_operand" "=f")
9909 (neg:XF (float_extend:XF
9910 (match_operand:DF 1 "register_operand" "0"))))]
9911 "TARGET_80387"
9912 "fchs"
9913 [(set_attr "type" "fsgn")
9914 (set_attr "mode" "XF")])
9915
9916 (define_insn "*negextendsfxf2"
9917 [(set (match_operand:XF 0 "register_operand" "=f")
9918 (neg:XF (float_extend:XF
9919 (match_operand:SF 1 "register_operand" "0"))))]
9920 "TARGET_80387"
9921 "fchs"
9922 [(set_attr "type" "fsgn")
9923 (set_attr "mode" "XF")])
9924
9925 (define_insn "*absextendsfdf2"
9926 [(set (match_operand:DF 0 "register_operand" "=f")
9927 (abs:DF (float_extend:DF
9928 (match_operand:SF 1 "register_operand" "0"))))]
9929 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9930 "fabs"
9931 [(set_attr "type" "fsgn")
9932 (set_attr "mode" "DF")])
9933
9934 (define_insn "*absextenddfxf2"
9935 [(set (match_operand:XF 0 "register_operand" "=f")
9936 (abs:XF (float_extend:XF
9937 (match_operand:DF 1 "register_operand" "0"))))]
9938 "TARGET_80387"
9939 "fabs"
9940 [(set_attr "type" "fsgn")
9941 (set_attr "mode" "XF")])
9942
9943 (define_insn "*absextendsfxf2"
9944 [(set (match_operand:XF 0 "register_operand" "=f")
9945 (abs:XF (float_extend:XF
9946 (match_operand:SF 1 "register_operand" "0"))))]
9947 "TARGET_80387"
9948 "fabs"
9949 [(set_attr "type" "fsgn")
9950 (set_attr "mode" "XF")])
9951 \f
9952 ;; One complement instructions
9953
9954 (define_expand "one_cmpldi2"
9955 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9956 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9957 "TARGET_64BIT"
9958 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9959
9960 (define_insn "*one_cmpldi2_1_rex64"
9961 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9962 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9963 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9964 "not{q}\t%0"
9965 [(set_attr "type" "negnot")
9966 (set_attr "mode" "DI")])
9967
9968 (define_insn "*one_cmpldi2_2_rex64"
9969 [(set (reg FLAGS_REG)
9970 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9971 (const_int 0)))
9972 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9973 (not:DI (match_dup 1)))]
9974 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9975 && ix86_unary_operator_ok (NOT, DImode, operands)"
9976 "#"
9977 [(set_attr "type" "alu1")
9978 (set_attr "mode" "DI")])
9979
9980 (define_split
9981 [(set (match_operand 0 "flags_reg_operand" "")
9982 (match_operator 2 "compare_operator"
9983 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9984 (const_int 0)]))
9985 (set (match_operand:DI 1 "nonimmediate_operand" "")
9986 (not:DI (match_dup 3)))]
9987 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9988 [(parallel [(set (match_dup 0)
9989 (match_op_dup 2
9990 [(xor:DI (match_dup 3) (const_int -1))
9991 (const_int 0)]))
9992 (set (match_dup 1)
9993 (xor:DI (match_dup 3) (const_int -1)))])]
9994 "")
9995
9996 (define_expand "one_cmplsi2"
9997 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9998 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9999 ""
10000 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10001
10002 (define_insn "*one_cmplsi2_1"
10003 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10004 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10005 "ix86_unary_operator_ok (NOT, SImode, operands)"
10006 "not{l}\t%0"
10007 [(set_attr "type" "negnot")
10008 (set_attr "mode" "SI")])
10009
10010 ;; ??? Currently never generated - xor is used instead.
10011 (define_insn "*one_cmplsi2_1_zext"
10012 [(set (match_operand:DI 0 "register_operand" "=r")
10013 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10014 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10015 "not{l}\t%k0"
10016 [(set_attr "type" "negnot")
10017 (set_attr "mode" "SI")])
10018
10019 (define_insn "*one_cmplsi2_2"
10020 [(set (reg FLAGS_REG)
10021 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10022 (const_int 0)))
10023 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10024 (not:SI (match_dup 1)))]
10025 "ix86_match_ccmode (insn, CCNOmode)
10026 && ix86_unary_operator_ok (NOT, SImode, operands)"
10027 "#"
10028 [(set_attr "type" "alu1")
10029 (set_attr "mode" "SI")])
10030
10031 (define_split
10032 [(set (match_operand 0 "flags_reg_operand" "")
10033 (match_operator 2 "compare_operator"
10034 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10035 (const_int 0)]))
10036 (set (match_operand:SI 1 "nonimmediate_operand" "")
10037 (not:SI (match_dup 3)))]
10038 "ix86_match_ccmode (insn, CCNOmode)"
10039 [(parallel [(set (match_dup 0)
10040 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10041 (const_int 0)]))
10042 (set (match_dup 1)
10043 (xor:SI (match_dup 3) (const_int -1)))])]
10044 "")
10045
10046 ;; ??? Currently never generated - xor is used instead.
10047 (define_insn "*one_cmplsi2_2_zext"
10048 [(set (reg FLAGS_REG)
10049 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10050 (const_int 0)))
10051 (set (match_operand:DI 0 "register_operand" "=r")
10052 (zero_extend:DI (not:SI (match_dup 1))))]
10053 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10054 && ix86_unary_operator_ok (NOT, SImode, operands)"
10055 "#"
10056 [(set_attr "type" "alu1")
10057 (set_attr "mode" "SI")])
10058
10059 (define_split
10060 [(set (match_operand 0 "flags_reg_operand" "")
10061 (match_operator 2 "compare_operator"
10062 [(not:SI (match_operand:SI 3 "register_operand" ""))
10063 (const_int 0)]))
10064 (set (match_operand:DI 1 "register_operand" "")
10065 (zero_extend:DI (not:SI (match_dup 3))))]
10066 "ix86_match_ccmode (insn, CCNOmode)"
10067 [(parallel [(set (match_dup 0)
10068 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10069 (const_int 0)]))
10070 (set (match_dup 1)
10071 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10072 "")
10073
10074 (define_expand "one_cmplhi2"
10075 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10076 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10077 "TARGET_HIMODE_MATH"
10078 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10079
10080 (define_insn "*one_cmplhi2_1"
10081 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10082 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10083 "ix86_unary_operator_ok (NOT, HImode, operands)"
10084 "not{w}\t%0"
10085 [(set_attr "type" "negnot")
10086 (set_attr "mode" "HI")])
10087
10088 (define_insn "*one_cmplhi2_2"
10089 [(set (reg FLAGS_REG)
10090 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10091 (const_int 0)))
10092 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10093 (not:HI (match_dup 1)))]
10094 "ix86_match_ccmode (insn, CCNOmode)
10095 && ix86_unary_operator_ok (NEG, HImode, operands)"
10096 "#"
10097 [(set_attr "type" "alu1")
10098 (set_attr "mode" "HI")])
10099
10100 (define_split
10101 [(set (match_operand 0 "flags_reg_operand" "")
10102 (match_operator 2 "compare_operator"
10103 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10104 (const_int 0)]))
10105 (set (match_operand:HI 1 "nonimmediate_operand" "")
10106 (not:HI (match_dup 3)))]
10107 "ix86_match_ccmode (insn, CCNOmode)"
10108 [(parallel [(set (match_dup 0)
10109 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10110 (const_int 0)]))
10111 (set (match_dup 1)
10112 (xor:HI (match_dup 3) (const_int -1)))])]
10113 "")
10114
10115 ;; %%% Potential partial reg stall on alternative 1. What to do?
10116 (define_expand "one_cmplqi2"
10117 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10118 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10119 "TARGET_QIMODE_MATH"
10120 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10121
10122 (define_insn "*one_cmplqi2_1"
10123 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10124 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10125 "ix86_unary_operator_ok (NOT, QImode, operands)"
10126 "@
10127 not{b}\t%0
10128 not{l}\t%k0"
10129 [(set_attr "type" "negnot")
10130 (set_attr "mode" "QI,SI")])
10131
10132 (define_insn "*one_cmplqi2_2"
10133 [(set (reg FLAGS_REG)
10134 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10135 (const_int 0)))
10136 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10137 (not:QI (match_dup 1)))]
10138 "ix86_match_ccmode (insn, CCNOmode)
10139 && ix86_unary_operator_ok (NOT, QImode, operands)"
10140 "#"
10141 [(set_attr "type" "alu1")
10142 (set_attr "mode" "QI")])
10143
10144 (define_split
10145 [(set (match_operand 0 "flags_reg_operand" "")
10146 (match_operator 2 "compare_operator"
10147 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10148 (const_int 0)]))
10149 (set (match_operand:QI 1 "nonimmediate_operand" "")
10150 (not:QI (match_dup 3)))]
10151 "ix86_match_ccmode (insn, CCNOmode)"
10152 [(parallel [(set (match_dup 0)
10153 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10154 (const_int 0)]))
10155 (set (match_dup 1)
10156 (xor:QI (match_dup 3) (const_int -1)))])]
10157 "")
10158 \f
10159 ;; Arithmetic shift instructions
10160
10161 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10162 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10163 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10164 ;; from the assembler input.
10165 ;;
10166 ;; This instruction shifts the target reg/mem as usual, but instead of
10167 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10168 ;; is a left shift double, bits are taken from the high order bits of
10169 ;; reg, else if the insn is a shift right double, bits are taken from the
10170 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10171 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10172 ;;
10173 ;; Since sh[lr]d does not change the `reg' operand, that is done
10174 ;; separately, making all shifts emit pairs of shift double and normal
10175 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10176 ;; support a 63 bit shift, each shift where the count is in a reg expands
10177 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10178 ;;
10179 ;; If the shift count is a constant, we need never emit more than one
10180 ;; shift pair, instead using moves and sign extension for counts greater
10181 ;; than 31.
10182
10183 (define_expand "ashldi3"
10184 [(set (match_operand:DI 0 "shiftdi_operand" "")
10185 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10186 (match_operand:QI 2 "nonmemory_operand" "")))]
10187 ""
10188 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10189
10190 (define_insn "*ashldi3_1_rex64"
10191 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10192 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10193 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10194 (clobber (reg:CC FLAGS_REG))]
10195 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10196 {
10197 switch (get_attr_type (insn))
10198 {
10199 case TYPE_ALU:
10200 if (operands[2] != const1_rtx)
10201 abort ();
10202 if (!rtx_equal_p (operands[0], operands[1]))
10203 abort ();
10204 return "add{q}\t{%0, %0|%0, %0}";
10205
10206 case TYPE_LEA:
10207 if (GET_CODE (operands[2]) != CONST_INT
10208 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10209 abort ();
10210 operands[1] = gen_rtx_MULT (DImode, operands[1],
10211 GEN_INT (1 << INTVAL (operands[2])));
10212 return "lea{q}\t{%a1, %0|%0, %a1}";
10213
10214 default:
10215 if (REG_P (operands[2]))
10216 return "sal{q}\t{%b2, %0|%0, %b2}";
10217 else if (operands[2] == const1_rtx
10218 && (TARGET_SHIFT1 || optimize_size))
10219 return "sal{q}\t%0";
10220 else
10221 return "sal{q}\t{%2, %0|%0, %2}";
10222 }
10223 }
10224 [(set (attr "type")
10225 (cond [(eq_attr "alternative" "1")
10226 (const_string "lea")
10227 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10228 (const_int 0))
10229 (match_operand 0 "register_operand" ""))
10230 (match_operand 2 "const1_operand" ""))
10231 (const_string "alu")
10232 ]
10233 (const_string "ishift")))
10234 (set_attr "mode" "DI")])
10235
10236 ;; Convert lea to the lea pattern to avoid flags dependency.
10237 (define_split
10238 [(set (match_operand:DI 0 "register_operand" "")
10239 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10240 (match_operand:QI 2 "immediate_operand" "")))
10241 (clobber (reg:CC FLAGS_REG))]
10242 "TARGET_64BIT && reload_completed
10243 && true_regnum (operands[0]) != true_regnum (operands[1])"
10244 [(set (match_dup 0)
10245 (mult:DI (match_dup 1)
10246 (match_dup 2)))]
10247 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10248
10249 ;; This pattern can't accept a variable shift count, since shifts by
10250 ;; zero don't affect the flags. We assume that shifts by constant
10251 ;; zero are optimized away.
10252 (define_insn "*ashldi3_cmp_rex64"
10253 [(set (reg FLAGS_REG)
10254 (compare
10255 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10256 (match_operand:QI 2 "immediate_operand" "e"))
10257 (const_int 0)))
10258 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10259 (ashift:DI (match_dup 1) (match_dup 2)))]
10260 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10261 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10262 {
10263 switch (get_attr_type (insn))
10264 {
10265 case TYPE_ALU:
10266 if (operands[2] != const1_rtx)
10267 abort ();
10268 return "add{q}\t{%0, %0|%0, %0}";
10269
10270 default:
10271 if (REG_P (operands[2]))
10272 return "sal{q}\t{%b2, %0|%0, %b2}";
10273 else if (operands[2] == const1_rtx
10274 && (TARGET_SHIFT1 || optimize_size))
10275 return "sal{q}\t%0";
10276 else
10277 return "sal{q}\t{%2, %0|%0, %2}";
10278 }
10279 }
10280 [(set (attr "type")
10281 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10282 (const_int 0))
10283 (match_operand 0 "register_operand" ""))
10284 (match_operand 2 "const1_operand" ""))
10285 (const_string "alu")
10286 ]
10287 (const_string "ishift")))
10288 (set_attr "mode" "DI")])
10289
10290 (define_insn "*ashldi3_1"
10291 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10292 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10293 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10294 (clobber (reg:CC FLAGS_REG))]
10295 "!TARGET_64BIT"
10296 "#"
10297 [(set_attr "type" "multi")])
10298
10299 ;; By default we don't ask for a scratch register, because when DImode
10300 ;; values are manipulated, registers are already at a premium. But if
10301 ;; we have one handy, we won't turn it away.
10302 (define_peephole2
10303 [(match_scratch:SI 3 "r")
10304 (parallel [(set (match_operand:DI 0 "register_operand" "")
10305 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10306 (match_operand:QI 2 "nonmemory_operand" "")))
10307 (clobber (reg:CC FLAGS_REG))])
10308 (match_dup 3)]
10309 "!TARGET_64BIT && TARGET_CMOVE"
10310 [(const_int 0)]
10311 "ix86_split_ashldi (operands, operands[3]); DONE;")
10312
10313 (define_split
10314 [(set (match_operand:DI 0 "register_operand" "")
10315 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10316 (match_operand:QI 2 "nonmemory_operand" "")))
10317 (clobber (reg:CC FLAGS_REG))]
10318 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10319 [(const_int 0)]
10320 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10321
10322 (define_insn "x86_shld_1"
10323 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10324 (ior:SI (ashift:SI (match_dup 0)
10325 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10326 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10327 (minus:QI (const_int 32) (match_dup 2)))))
10328 (clobber (reg:CC FLAGS_REG))]
10329 ""
10330 "@
10331 shld{l}\t{%2, %1, %0|%0, %1, %2}
10332 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10333 [(set_attr "type" "ishift")
10334 (set_attr "prefix_0f" "1")
10335 (set_attr "mode" "SI")
10336 (set_attr "pent_pair" "np")
10337 (set_attr "athlon_decode" "vector")])
10338
10339 (define_expand "x86_shift_adj_1"
10340 [(set (reg:CCZ FLAGS_REG)
10341 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10342 (const_int 32))
10343 (const_int 0)))
10344 (set (match_operand:SI 0 "register_operand" "")
10345 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10346 (match_operand:SI 1 "register_operand" "")
10347 (match_dup 0)))
10348 (set (match_dup 1)
10349 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10350 (match_operand:SI 3 "register_operand" "r")
10351 (match_dup 1)))]
10352 "TARGET_CMOVE"
10353 "")
10354
10355 (define_expand "x86_shift_adj_2"
10356 [(use (match_operand:SI 0 "register_operand" ""))
10357 (use (match_operand:SI 1 "register_operand" ""))
10358 (use (match_operand:QI 2 "register_operand" ""))]
10359 ""
10360 {
10361 rtx label = gen_label_rtx ();
10362 rtx tmp;
10363
10364 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10365
10366 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10367 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10368 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10369 gen_rtx_LABEL_REF (VOIDmode, label),
10370 pc_rtx);
10371 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10372 JUMP_LABEL (tmp) = label;
10373
10374 emit_move_insn (operands[0], operands[1]);
10375 ix86_expand_clear (operands[1]);
10376
10377 emit_label (label);
10378 LABEL_NUSES (label) = 1;
10379
10380 DONE;
10381 })
10382
10383 (define_expand "ashlsi3"
10384 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10385 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10386 (match_operand:QI 2 "nonmemory_operand" "")))
10387 (clobber (reg:CC FLAGS_REG))]
10388 ""
10389 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10390
10391 (define_insn "*ashlsi3_1"
10392 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10393 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10394 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10395 (clobber (reg:CC FLAGS_REG))]
10396 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10397 {
10398 switch (get_attr_type (insn))
10399 {
10400 case TYPE_ALU:
10401 if (operands[2] != const1_rtx)
10402 abort ();
10403 if (!rtx_equal_p (operands[0], operands[1]))
10404 abort ();
10405 return "add{l}\t{%0, %0|%0, %0}";
10406
10407 case TYPE_LEA:
10408 return "#";
10409
10410 default:
10411 if (REG_P (operands[2]))
10412 return "sal{l}\t{%b2, %0|%0, %b2}";
10413 else if (operands[2] == const1_rtx
10414 && (TARGET_SHIFT1 || optimize_size))
10415 return "sal{l}\t%0";
10416 else
10417 return "sal{l}\t{%2, %0|%0, %2}";
10418 }
10419 }
10420 [(set (attr "type")
10421 (cond [(eq_attr "alternative" "1")
10422 (const_string "lea")
10423 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10424 (const_int 0))
10425 (match_operand 0 "register_operand" ""))
10426 (match_operand 2 "const1_operand" ""))
10427 (const_string "alu")
10428 ]
10429 (const_string "ishift")))
10430 (set_attr "mode" "SI")])
10431
10432 ;; Convert lea to the lea pattern to avoid flags dependency.
10433 (define_split
10434 [(set (match_operand 0 "register_operand" "")
10435 (ashift (match_operand 1 "index_register_operand" "")
10436 (match_operand:QI 2 "const_int_operand" "")))
10437 (clobber (reg:CC FLAGS_REG))]
10438 "reload_completed
10439 && true_regnum (operands[0]) != true_regnum (operands[1])
10440 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10441 [(const_int 0)]
10442 {
10443 rtx pat;
10444 enum machine_mode mode = GET_MODE (operands[0]);
10445
10446 if (GET_MODE_SIZE (mode) < 4)
10447 operands[0] = gen_lowpart (SImode, operands[0]);
10448 if (mode != Pmode)
10449 operands[1] = gen_lowpart (Pmode, operands[1]);
10450 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10451
10452 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10453 if (Pmode != SImode)
10454 pat = gen_rtx_SUBREG (SImode, pat, 0);
10455 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10456 DONE;
10457 })
10458
10459 ;; Rare case of shifting RSP is handled by generating move and shift
10460 (define_split
10461 [(set (match_operand 0 "register_operand" "")
10462 (ashift (match_operand 1 "register_operand" "")
10463 (match_operand:QI 2 "const_int_operand" "")))
10464 (clobber (reg:CC FLAGS_REG))]
10465 "reload_completed
10466 && true_regnum (operands[0]) != true_regnum (operands[1])"
10467 [(const_int 0)]
10468 {
10469 rtx pat, clob;
10470 emit_move_insn (operands[1], operands[0]);
10471 pat = gen_rtx_SET (VOIDmode, operands[0],
10472 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10473 operands[0], operands[2]));
10474 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10475 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10476 DONE;
10477 })
10478
10479 (define_insn "*ashlsi3_1_zext"
10480 [(set (match_operand:DI 0 "register_operand" "=r,r")
10481 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10482 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10483 (clobber (reg:CC FLAGS_REG))]
10484 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10485 {
10486 switch (get_attr_type (insn))
10487 {
10488 case TYPE_ALU:
10489 if (operands[2] != const1_rtx)
10490 abort ();
10491 return "add{l}\t{%k0, %k0|%k0, %k0}";
10492
10493 case TYPE_LEA:
10494 return "#";
10495
10496 default:
10497 if (REG_P (operands[2]))
10498 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10499 else if (operands[2] == const1_rtx
10500 && (TARGET_SHIFT1 || optimize_size))
10501 return "sal{l}\t%k0";
10502 else
10503 return "sal{l}\t{%2, %k0|%k0, %2}";
10504 }
10505 }
10506 [(set (attr "type")
10507 (cond [(eq_attr "alternative" "1")
10508 (const_string "lea")
10509 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10510 (const_int 0))
10511 (match_operand 2 "const1_operand" ""))
10512 (const_string "alu")
10513 ]
10514 (const_string "ishift")))
10515 (set_attr "mode" "SI")])
10516
10517 ;; Convert lea to the lea pattern to avoid flags dependency.
10518 (define_split
10519 [(set (match_operand:DI 0 "register_operand" "")
10520 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10521 (match_operand:QI 2 "const_int_operand" ""))))
10522 (clobber (reg:CC FLAGS_REG))]
10523 "TARGET_64BIT && reload_completed
10524 && true_regnum (operands[0]) != true_regnum (operands[1])"
10525 [(set (match_dup 0) (zero_extend:DI
10526 (subreg:SI (mult:SI (match_dup 1)
10527 (match_dup 2)) 0)))]
10528 {
10529 operands[1] = gen_lowpart (Pmode, operands[1]);
10530 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10531 })
10532
10533 ;; This pattern can't accept a variable shift count, since shifts by
10534 ;; zero don't affect the flags. We assume that shifts by constant
10535 ;; zero are optimized away.
10536 (define_insn "*ashlsi3_cmp"
10537 [(set (reg FLAGS_REG)
10538 (compare
10539 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10540 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10541 (const_int 0)))
10542 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10543 (ashift:SI (match_dup 1) (match_dup 2)))]
10544 "ix86_match_ccmode (insn, CCGOCmode)
10545 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10546 {
10547 switch (get_attr_type (insn))
10548 {
10549 case TYPE_ALU:
10550 if (operands[2] != const1_rtx)
10551 abort ();
10552 return "add{l}\t{%0, %0|%0, %0}";
10553
10554 default:
10555 if (REG_P (operands[2]))
10556 return "sal{l}\t{%b2, %0|%0, %b2}";
10557 else if (operands[2] == const1_rtx
10558 && (TARGET_SHIFT1 || optimize_size))
10559 return "sal{l}\t%0";
10560 else
10561 return "sal{l}\t{%2, %0|%0, %2}";
10562 }
10563 }
10564 [(set (attr "type")
10565 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10566 (const_int 0))
10567 (match_operand 0 "register_operand" ""))
10568 (match_operand 2 "const1_operand" ""))
10569 (const_string "alu")
10570 ]
10571 (const_string "ishift")))
10572 (set_attr "mode" "SI")])
10573
10574 (define_insn "*ashlsi3_cmp_zext"
10575 [(set (reg FLAGS_REG)
10576 (compare
10577 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10578 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10579 (const_int 0)))
10580 (set (match_operand:DI 0 "register_operand" "=r")
10581 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10582 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10583 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10584 {
10585 switch (get_attr_type (insn))
10586 {
10587 case TYPE_ALU:
10588 if (operands[2] != const1_rtx)
10589 abort ();
10590 return "add{l}\t{%k0, %k0|%k0, %k0}";
10591
10592 default:
10593 if (REG_P (operands[2]))
10594 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10595 else if (operands[2] == const1_rtx
10596 && (TARGET_SHIFT1 || optimize_size))
10597 return "sal{l}\t%k0";
10598 else
10599 return "sal{l}\t{%2, %k0|%k0, %2}";
10600 }
10601 }
10602 [(set (attr "type")
10603 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10604 (const_int 0))
10605 (match_operand 2 "const1_operand" ""))
10606 (const_string "alu")
10607 ]
10608 (const_string "ishift")))
10609 (set_attr "mode" "SI")])
10610
10611 (define_expand "ashlhi3"
10612 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10613 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10614 (match_operand:QI 2 "nonmemory_operand" "")))
10615 (clobber (reg:CC FLAGS_REG))]
10616 "TARGET_HIMODE_MATH"
10617 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10618
10619 (define_insn "*ashlhi3_1_lea"
10620 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10621 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10622 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10623 (clobber (reg:CC FLAGS_REG))]
10624 "!TARGET_PARTIAL_REG_STALL
10625 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10626 {
10627 switch (get_attr_type (insn))
10628 {
10629 case TYPE_LEA:
10630 return "#";
10631 case TYPE_ALU:
10632 if (operands[2] != const1_rtx)
10633 abort ();
10634 return "add{w}\t{%0, %0|%0, %0}";
10635
10636 default:
10637 if (REG_P (operands[2]))
10638 return "sal{w}\t{%b2, %0|%0, %b2}";
10639 else if (operands[2] == const1_rtx
10640 && (TARGET_SHIFT1 || optimize_size))
10641 return "sal{w}\t%0";
10642 else
10643 return "sal{w}\t{%2, %0|%0, %2}";
10644 }
10645 }
10646 [(set (attr "type")
10647 (cond [(eq_attr "alternative" "1")
10648 (const_string "lea")
10649 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10650 (const_int 0))
10651 (match_operand 0 "register_operand" ""))
10652 (match_operand 2 "const1_operand" ""))
10653 (const_string "alu")
10654 ]
10655 (const_string "ishift")))
10656 (set_attr "mode" "HI,SI")])
10657
10658 (define_insn "*ashlhi3_1"
10659 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10660 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10661 (match_operand:QI 2 "nonmemory_operand" "cI")))
10662 (clobber (reg:CC FLAGS_REG))]
10663 "TARGET_PARTIAL_REG_STALL
10664 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10665 {
10666 switch (get_attr_type (insn))
10667 {
10668 case TYPE_ALU:
10669 if (operands[2] != const1_rtx)
10670 abort ();
10671 return "add{w}\t{%0, %0|%0, %0}";
10672
10673 default:
10674 if (REG_P (operands[2]))
10675 return "sal{w}\t{%b2, %0|%0, %b2}";
10676 else if (operands[2] == const1_rtx
10677 && (TARGET_SHIFT1 || optimize_size))
10678 return "sal{w}\t%0";
10679 else
10680 return "sal{w}\t{%2, %0|%0, %2}";
10681 }
10682 }
10683 [(set (attr "type")
10684 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10685 (const_int 0))
10686 (match_operand 0 "register_operand" ""))
10687 (match_operand 2 "const1_operand" ""))
10688 (const_string "alu")
10689 ]
10690 (const_string "ishift")))
10691 (set_attr "mode" "HI")])
10692
10693 ;; This pattern can't accept a variable shift count, since shifts by
10694 ;; zero don't affect the flags. We assume that shifts by constant
10695 ;; zero are optimized away.
10696 (define_insn "*ashlhi3_cmp"
10697 [(set (reg FLAGS_REG)
10698 (compare
10699 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10700 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10701 (const_int 0)))
10702 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10703 (ashift:HI (match_dup 1) (match_dup 2)))]
10704 "ix86_match_ccmode (insn, CCGOCmode)
10705 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10706 {
10707 switch (get_attr_type (insn))
10708 {
10709 case TYPE_ALU:
10710 if (operands[2] != const1_rtx)
10711 abort ();
10712 return "add{w}\t{%0, %0|%0, %0}";
10713
10714 default:
10715 if (REG_P (operands[2]))
10716 return "sal{w}\t{%b2, %0|%0, %b2}";
10717 else if (operands[2] == const1_rtx
10718 && (TARGET_SHIFT1 || optimize_size))
10719 return "sal{w}\t%0";
10720 else
10721 return "sal{w}\t{%2, %0|%0, %2}";
10722 }
10723 }
10724 [(set (attr "type")
10725 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10726 (const_int 0))
10727 (match_operand 0 "register_operand" ""))
10728 (match_operand 2 "const1_operand" ""))
10729 (const_string "alu")
10730 ]
10731 (const_string "ishift")))
10732 (set_attr "mode" "HI")])
10733
10734 (define_expand "ashlqi3"
10735 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10736 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10737 (match_operand:QI 2 "nonmemory_operand" "")))
10738 (clobber (reg:CC FLAGS_REG))]
10739 "TARGET_QIMODE_MATH"
10740 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10741
10742 ;; %%% Potential partial reg stall on alternative 2. What to do?
10743
10744 (define_insn "*ashlqi3_1_lea"
10745 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10746 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10747 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10748 (clobber (reg:CC FLAGS_REG))]
10749 "!TARGET_PARTIAL_REG_STALL
10750 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10751 {
10752 switch (get_attr_type (insn))
10753 {
10754 case TYPE_LEA:
10755 return "#";
10756 case TYPE_ALU:
10757 if (operands[2] != const1_rtx)
10758 abort ();
10759 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10760 return "add{l}\t{%k0, %k0|%k0, %k0}";
10761 else
10762 return "add{b}\t{%0, %0|%0, %0}";
10763
10764 default:
10765 if (REG_P (operands[2]))
10766 {
10767 if (get_attr_mode (insn) == MODE_SI)
10768 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10769 else
10770 return "sal{b}\t{%b2, %0|%0, %b2}";
10771 }
10772 else if (operands[2] == const1_rtx
10773 && (TARGET_SHIFT1 || optimize_size))
10774 {
10775 if (get_attr_mode (insn) == MODE_SI)
10776 return "sal{l}\t%0";
10777 else
10778 return "sal{b}\t%0";
10779 }
10780 else
10781 {
10782 if (get_attr_mode (insn) == MODE_SI)
10783 return "sal{l}\t{%2, %k0|%k0, %2}";
10784 else
10785 return "sal{b}\t{%2, %0|%0, %2}";
10786 }
10787 }
10788 }
10789 [(set (attr "type")
10790 (cond [(eq_attr "alternative" "2")
10791 (const_string "lea")
10792 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10793 (const_int 0))
10794 (match_operand 0 "register_operand" ""))
10795 (match_operand 2 "const1_operand" ""))
10796 (const_string "alu")
10797 ]
10798 (const_string "ishift")))
10799 (set_attr "mode" "QI,SI,SI")])
10800
10801 (define_insn "*ashlqi3_1"
10802 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10803 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10804 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10805 (clobber (reg:CC FLAGS_REG))]
10806 "TARGET_PARTIAL_REG_STALL
10807 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10808 {
10809 switch (get_attr_type (insn))
10810 {
10811 case TYPE_ALU:
10812 if (operands[2] != const1_rtx)
10813 abort ();
10814 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10815 return "add{l}\t{%k0, %k0|%k0, %k0}";
10816 else
10817 return "add{b}\t{%0, %0|%0, %0}";
10818
10819 default:
10820 if (REG_P (operands[2]))
10821 {
10822 if (get_attr_mode (insn) == MODE_SI)
10823 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10824 else
10825 return "sal{b}\t{%b2, %0|%0, %b2}";
10826 }
10827 else if (operands[2] == const1_rtx
10828 && (TARGET_SHIFT1 || optimize_size))
10829 {
10830 if (get_attr_mode (insn) == MODE_SI)
10831 return "sal{l}\t%0";
10832 else
10833 return "sal{b}\t%0";
10834 }
10835 else
10836 {
10837 if (get_attr_mode (insn) == MODE_SI)
10838 return "sal{l}\t{%2, %k0|%k0, %2}";
10839 else
10840 return "sal{b}\t{%2, %0|%0, %2}";
10841 }
10842 }
10843 }
10844 [(set (attr "type")
10845 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10846 (const_int 0))
10847 (match_operand 0 "register_operand" ""))
10848 (match_operand 2 "const1_operand" ""))
10849 (const_string "alu")
10850 ]
10851 (const_string "ishift")))
10852 (set_attr "mode" "QI,SI")])
10853
10854 ;; This pattern can't accept a variable shift count, since shifts by
10855 ;; zero don't affect the flags. We assume that shifts by constant
10856 ;; zero are optimized away.
10857 (define_insn "*ashlqi3_cmp"
10858 [(set (reg FLAGS_REG)
10859 (compare
10860 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10861 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10862 (const_int 0)))
10863 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10864 (ashift:QI (match_dup 1) (match_dup 2)))]
10865 "ix86_match_ccmode (insn, CCGOCmode)
10866 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10867 {
10868 switch (get_attr_type (insn))
10869 {
10870 case TYPE_ALU:
10871 if (operands[2] != const1_rtx)
10872 abort ();
10873 return "add{b}\t{%0, %0|%0, %0}";
10874
10875 default:
10876 if (REG_P (operands[2]))
10877 return "sal{b}\t{%b2, %0|%0, %b2}";
10878 else if (operands[2] == const1_rtx
10879 && (TARGET_SHIFT1 || optimize_size))
10880 return "sal{b}\t%0";
10881 else
10882 return "sal{b}\t{%2, %0|%0, %2}";
10883 }
10884 }
10885 [(set (attr "type")
10886 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10887 (const_int 0))
10888 (match_operand 0 "register_operand" ""))
10889 (match_operand 2 "const1_operand" ""))
10890 (const_string "alu")
10891 ]
10892 (const_string "ishift")))
10893 (set_attr "mode" "QI")])
10894
10895 ;; See comment above `ashldi3' about how this works.
10896
10897 (define_expand "ashrdi3"
10898 [(set (match_operand:DI 0 "shiftdi_operand" "")
10899 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10900 (match_operand:QI 2 "nonmemory_operand" "")))]
10901 ""
10902 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10903
10904 (define_insn "*ashrdi3_63_rex64"
10905 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10906 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10907 (match_operand:DI 2 "const_int_operand" "i,i")))
10908 (clobber (reg:CC FLAGS_REG))]
10909 "TARGET_64BIT && INTVAL (operands[2]) == 63
10910 && (TARGET_USE_CLTD || optimize_size)
10911 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10912 "@
10913 {cqto|cqo}
10914 sar{q}\t{%2, %0|%0, %2}"
10915 [(set_attr "type" "imovx,ishift")
10916 (set_attr "prefix_0f" "0,*")
10917 (set_attr "length_immediate" "0,*")
10918 (set_attr "modrm" "0,1")
10919 (set_attr "mode" "DI")])
10920
10921 (define_insn "*ashrdi3_1_one_bit_rex64"
10922 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10923 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10924 (match_operand:QI 2 "const1_operand" "")))
10925 (clobber (reg:CC FLAGS_REG))]
10926 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10927 && (TARGET_SHIFT1 || optimize_size)"
10928 "sar{q}\t%0"
10929 [(set_attr "type" "ishift")
10930 (set (attr "length")
10931 (if_then_else (match_operand:DI 0 "register_operand" "")
10932 (const_string "2")
10933 (const_string "*")))])
10934
10935 (define_insn "*ashrdi3_1_rex64"
10936 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10937 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10938 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10939 (clobber (reg:CC FLAGS_REG))]
10940 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10941 "@
10942 sar{q}\t{%2, %0|%0, %2}
10943 sar{q}\t{%b2, %0|%0, %b2}"
10944 [(set_attr "type" "ishift")
10945 (set_attr "mode" "DI")])
10946
10947 ;; This pattern can't accept a variable shift count, since shifts by
10948 ;; zero don't affect the flags. We assume that shifts by constant
10949 ;; zero are optimized away.
10950 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10951 [(set (reg FLAGS_REG)
10952 (compare
10953 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10954 (match_operand:QI 2 "const1_operand" ""))
10955 (const_int 0)))
10956 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10957 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10958 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10959 && (TARGET_SHIFT1 || optimize_size)
10960 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10961 "sar{q}\t%0"
10962 [(set_attr "type" "ishift")
10963 (set (attr "length")
10964 (if_then_else (match_operand:DI 0 "register_operand" "")
10965 (const_string "2")
10966 (const_string "*")))])
10967
10968 ;; This pattern can't accept a variable shift count, since shifts by
10969 ;; zero don't affect the flags. We assume that shifts by constant
10970 ;; zero are optimized away.
10971 (define_insn "*ashrdi3_cmp_rex64"
10972 [(set (reg FLAGS_REG)
10973 (compare
10974 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10975 (match_operand:QI 2 "const_int_operand" "n"))
10976 (const_int 0)))
10977 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10978 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10979 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10980 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10981 "sar{q}\t{%2, %0|%0, %2}"
10982 [(set_attr "type" "ishift")
10983 (set_attr "mode" "DI")])
10984
10985 (define_insn "*ashrdi3_1"
10986 [(set (match_operand:DI 0 "register_operand" "=r")
10987 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10988 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10989 (clobber (reg:CC FLAGS_REG))]
10990 "!TARGET_64BIT"
10991 "#"
10992 [(set_attr "type" "multi")])
10993
10994 ;; By default we don't ask for a scratch register, because when DImode
10995 ;; values are manipulated, registers are already at a premium. But if
10996 ;; we have one handy, we won't turn it away.
10997 (define_peephole2
10998 [(match_scratch:SI 3 "r")
10999 (parallel [(set (match_operand:DI 0 "register_operand" "")
11000 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11001 (match_operand:QI 2 "nonmemory_operand" "")))
11002 (clobber (reg:CC FLAGS_REG))])
11003 (match_dup 3)]
11004 "!TARGET_64BIT && TARGET_CMOVE"
11005 [(const_int 0)]
11006 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11007
11008 (define_split
11009 [(set (match_operand:DI 0 "register_operand" "")
11010 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11011 (match_operand:QI 2 "nonmemory_operand" "")))
11012 (clobber (reg:CC FLAGS_REG))]
11013 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11014 [(const_int 0)]
11015 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11016
11017 (define_insn "x86_shrd_1"
11018 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11019 (ior:SI (ashiftrt:SI (match_dup 0)
11020 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11021 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11022 (minus:QI (const_int 32) (match_dup 2)))))
11023 (clobber (reg:CC FLAGS_REG))]
11024 ""
11025 "@
11026 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11027 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11028 [(set_attr "type" "ishift")
11029 (set_attr "prefix_0f" "1")
11030 (set_attr "pent_pair" "np")
11031 (set_attr "mode" "SI")])
11032
11033 (define_expand "x86_shift_adj_3"
11034 [(use (match_operand:SI 0 "register_operand" ""))
11035 (use (match_operand:SI 1 "register_operand" ""))
11036 (use (match_operand:QI 2 "register_operand" ""))]
11037 ""
11038 {
11039 rtx label = gen_label_rtx ();
11040 rtx tmp;
11041
11042 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11043
11044 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11045 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11046 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11047 gen_rtx_LABEL_REF (VOIDmode, label),
11048 pc_rtx);
11049 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11050 JUMP_LABEL (tmp) = label;
11051
11052 emit_move_insn (operands[0], operands[1]);
11053 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11054
11055 emit_label (label);
11056 LABEL_NUSES (label) = 1;
11057
11058 DONE;
11059 })
11060
11061 (define_insn "ashrsi3_31"
11062 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11063 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11064 (match_operand:SI 2 "const_int_operand" "i,i")))
11065 (clobber (reg:CC FLAGS_REG))]
11066 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11067 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11068 "@
11069 {cltd|cdq}
11070 sar{l}\t{%2, %0|%0, %2}"
11071 [(set_attr "type" "imovx,ishift")
11072 (set_attr "prefix_0f" "0,*")
11073 (set_attr "length_immediate" "0,*")
11074 (set_attr "modrm" "0,1")
11075 (set_attr "mode" "SI")])
11076
11077 (define_insn "*ashrsi3_31_zext"
11078 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11079 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11080 (match_operand:SI 2 "const_int_operand" "i,i"))))
11081 (clobber (reg:CC FLAGS_REG))]
11082 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11083 && INTVAL (operands[2]) == 31
11084 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11085 "@
11086 {cltd|cdq}
11087 sar{l}\t{%2, %k0|%k0, %2}"
11088 [(set_attr "type" "imovx,ishift")
11089 (set_attr "prefix_0f" "0,*")
11090 (set_attr "length_immediate" "0,*")
11091 (set_attr "modrm" "0,1")
11092 (set_attr "mode" "SI")])
11093
11094 (define_expand "ashrsi3"
11095 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11096 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11097 (match_operand:QI 2 "nonmemory_operand" "")))
11098 (clobber (reg:CC FLAGS_REG))]
11099 ""
11100 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11101
11102 (define_insn "*ashrsi3_1_one_bit"
11103 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11104 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11105 (match_operand:QI 2 "const1_operand" "")))
11106 (clobber (reg:CC FLAGS_REG))]
11107 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11108 && (TARGET_SHIFT1 || optimize_size)"
11109 "sar{l}\t%0"
11110 [(set_attr "type" "ishift")
11111 (set (attr "length")
11112 (if_then_else (match_operand:SI 0 "register_operand" "")
11113 (const_string "2")
11114 (const_string "*")))])
11115
11116 (define_insn "*ashrsi3_1_one_bit_zext"
11117 [(set (match_operand:DI 0 "register_operand" "=r")
11118 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11119 (match_operand:QI 2 "const1_operand" ""))))
11120 (clobber (reg:CC FLAGS_REG))]
11121 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11122 && (TARGET_SHIFT1 || optimize_size)"
11123 "sar{l}\t%k0"
11124 [(set_attr "type" "ishift")
11125 (set_attr "length" "2")])
11126
11127 (define_insn "*ashrsi3_1"
11128 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11129 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11130 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11131 (clobber (reg:CC FLAGS_REG))]
11132 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11133 "@
11134 sar{l}\t{%2, %0|%0, %2}
11135 sar{l}\t{%b2, %0|%0, %b2}"
11136 [(set_attr "type" "ishift")
11137 (set_attr "mode" "SI")])
11138
11139 (define_insn "*ashrsi3_1_zext"
11140 [(set (match_operand:DI 0 "register_operand" "=r,r")
11141 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11142 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11143 (clobber (reg:CC FLAGS_REG))]
11144 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11145 "@
11146 sar{l}\t{%2, %k0|%k0, %2}
11147 sar{l}\t{%b2, %k0|%k0, %b2}"
11148 [(set_attr "type" "ishift")
11149 (set_attr "mode" "SI")])
11150
11151 ;; This pattern can't accept a variable shift count, since shifts by
11152 ;; zero don't affect the flags. We assume that shifts by constant
11153 ;; zero are optimized away.
11154 (define_insn "*ashrsi3_one_bit_cmp"
11155 [(set (reg FLAGS_REG)
11156 (compare
11157 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11158 (match_operand:QI 2 "const1_operand" ""))
11159 (const_int 0)))
11160 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11161 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11162 "ix86_match_ccmode (insn, CCGOCmode)
11163 && (TARGET_SHIFT1 || optimize_size)
11164 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11165 "sar{l}\t%0"
11166 [(set_attr "type" "ishift")
11167 (set (attr "length")
11168 (if_then_else (match_operand:SI 0 "register_operand" "")
11169 (const_string "2")
11170 (const_string "*")))])
11171
11172 (define_insn "*ashrsi3_one_bit_cmp_zext"
11173 [(set (reg FLAGS_REG)
11174 (compare
11175 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11176 (match_operand:QI 2 "const1_operand" ""))
11177 (const_int 0)))
11178 (set (match_operand:DI 0 "register_operand" "=r")
11179 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11180 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11181 && (TARGET_SHIFT1 || optimize_size)
11182 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11183 "sar{l}\t%k0"
11184 [(set_attr "type" "ishift")
11185 (set_attr "length" "2")])
11186
11187 ;; This pattern can't accept a variable shift count, since shifts by
11188 ;; zero don't affect the flags. We assume that shifts by constant
11189 ;; zero are optimized away.
11190 (define_insn "*ashrsi3_cmp"
11191 [(set (reg FLAGS_REG)
11192 (compare
11193 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11194 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11195 (const_int 0)))
11196 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11197 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11198 "ix86_match_ccmode (insn, CCGOCmode)
11199 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11200 "sar{l}\t{%2, %0|%0, %2}"
11201 [(set_attr "type" "ishift")
11202 (set_attr "mode" "SI")])
11203
11204 (define_insn "*ashrsi3_cmp_zext"
11205 [(set (reg FLAGS_REG)
11206 (compare
11207 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11208 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11209 (const_int 0)))
11210 (set (match_operand:DI 0 "register_operand" "=r")
11211 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11212 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11213 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11214 "sar{l}\t{%2, %k0|%k0, %2}"
11215 [(set_attr "type" "ishift")
11216 (set_attr "mode" "SI")])
11217
11218 (define_expand "ashrhi3"
11219 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11220 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11221 (match_operand:QI 2 "nonmemory_operand" "")))
11222 (clobber (reg:CC FLAGS_REG))]
11223 "TARGET_HIMODE_MATH"
11224 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11225
11226 (define_insn "*ashrhi3_1_one_bit"
11227 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11228 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11229 (match_operand:QI 2 "const1_operand" "")))
11230 (clobber (reg:CC FLAGS_REG))]
11231 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11232 && (TARGET_SHIFT1 || optimize_size)"
11233 "sar{w}\t%0"
11234 [(set_attr "type" "ishift")
11235 (set (attr "length")
11236 (if_then_else (match_operand 0 "register_operand" "")
11237 (const_string "2")
11238 (const_string "*")))])
11239
11240 (define_insn "*ashrhi3_1"
11241 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11242 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11243 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11244 (clobber (reg:CC FLAGS_REG))]
11245 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11246 "@
11247 sar{w}\t{%2, %0|%0, %2}
11248 sar{w}\t{%b2, %0|%0, %b2}"
11249 [(set_attr "type" "ishift")
11250 (set_attr "mode" "HI")])
11251
11252 ;; This pattern can't accept a variable shift count, since shifts by
11253 ;; zero don't affect the flags. We assume that shifts by constant
11254 ;; zero are optimized away.
11255 (define_insn "*ashrhi3_one_bit_cmp"
11256 [(set (reg FLAGS_REG)
11257 (compare
11258 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11259 (match_operand:QI 2 "const1_operand" ""))
11260 (const_int 0)))
11261 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11262 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11263 "ix86_match_ccmode (insn, CCGOCmode)
11264 && (TARGET_SHIFT1 || optimize_size)
11265 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11266 "sar{w}\t%0"
11267 [(set_attr "type" "ishift")
11268 (set (attr "length")
11269 (if_then_else (match_operand 0 "register_operand" "")
11270 (const_string "2")
11271 (const_string "*")))])
11272
11273 ;; This pattern can't accept a variable shift count, since shifts by
11274 ;; zero don't affect the flags. We assume that shifts by constant
11275 ;; zero are optimized away.
11276 (define_insn "*ashrhi3_cmp"
11277 [(set (reg FLAGS_REG)
11278 (compare
11279 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11280 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11281 (const_int 0)))
11282 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11283 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11284 "ix86_match_ccmode (insn, CCGOCmode)
11285 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11286 "sar{w}\t{%2, %0|%0, %2}"
11287 [(set_attr "type" "ishift")
11288 (set_attr "mode" "HI")])
11289
11290 (define_expand "ashrqi3"
11291 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11292 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11293 (match_operand:QI 2 "nonmemory_operand" "")))
11294 (clobber (reg:CC FLAGS_REG))]
11295 "TARGET_QIMODE_MATH"
11296 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11297
11298 (define_insn "*ashrqi3_1_one_bit"
11299 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11300 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11301 (match_operand:QI 2 "const1_operand" "")))
11302 (clobber (reg:CC FLAGS_REG))]
11303 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11304 && (TARGET_SHIFT1 || optimize_size)"
11305 "sar{b}\t%0"
11306 [(set_attr "type" "ishift")
11307 (set (attr "length")
11308 (if_then_else (match_operand 0 "register_operand" "")
11309 (const_string "2")
11310 (const_string "*")))])
11311
11312 (define_insn "*ashrqi3_1_one_bit_slp"
11313 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11314 (ashiftrt:QI (match_dup 0)
11315 (match_operand:QI 1 "const1_operand" "")))
11316 (clobber (reg:CC FLAGS_REG))]
11317 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11318 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11319 && (TARGET_SHIFT1 || optimize_size)"
11320 "sar{b}\t%0"
11321 [(set_attr "type" "ishift1")
11322 (set (attr "length")
11323 (if_then_else (match_operand 0 "register_operand" "")
11324 (const_string "2")
11325 (const_string "*")))])
11326
11327 (define_insn "*ashrqi3_1"
11328 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11329 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11330 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11331 (clobber (reg:CC FLAGS_REG))]
11332 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11333 "@
11334 sar{b}\t{%2, %0|%0, %2}
11335 sar{b}\t{%b2, %0|%0, %b2}"
11336 [(set_attr "type" "ishift")
11337 (set_attr "mode" "QI")])
11338
11339 (define_insn "*ashrqi3_1_slp"
11340 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11341 (ashiftrt:QI (match_dup 0)
11342 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11343 (clobber (reg:CC FLAGS_REG))]
11344 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11345 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11346 "@
11347 sar{b}\t{%1, %0|%0, %1}
11348 sar{b}\t{%b1, %0|%0, %b1}"
11349 [(set_attr "type" "ishift1")
11350 (set_attr "mode" "QI")])
11351
11352 ;; This pattern can't accept a variable shift count, since shifts by
11353 ;; zero don't affect the flags. We assume that shifts by constant
11354 ;; zero are optimized away.
11355 (define_insn "*ashrqi3_one_bit_cmp"
11356 [(set (reg FLAGS_REG)
11357 (compare
11358 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11359 (match_operand:QI 2 "const1_operand" "I"))
11360 (const_int 0)))
11361 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11362 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11363 "ix86_match_ccmode (insn, CCGOCmode)
11364 && (TARGET_SHIFT1 || optimize_size)
11365 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11366 "sar{b}\t%0"
11367 [(set_attr "type" "ishift")
11368 (set (attr "length")
11369 (if_then_else (match_operand 0 "register_operand" "")
11370 (const_string "2")
11371 (const_string "*")))])
11372
11373 ;; This pattern can't accept a variable shift count, since shifts by
11374 ;; zero don't affect the flags. We assume that shifts by constant
11375 ;; zero are optimized away.
11376 (define_insn "*ashrqi3_cmp"
11377 [(set (reg FLAGS_REG)
11378 (compare
11379 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11380 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11381 (const_int 0)))
11382 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11383 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11384 "ix86_match_ccmode (insn, CCGOCmode)
11385 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11386 "sar{b}\t{%2, %0|%0, %2}"
11387 [(set_attr "type" "ishift")
11388 (set_attr "mode" "QI")])
11389 \f
11390 ;; Logical shift instructions
11391
11392 ;; See comment above `ashldi3' about how this works.
11393
11394 (define_expand "lshrdi3"
11395 [(set (match_operand:DI 0 "shiftdi_operand" "")
11396 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11397 (match_operand:QI 2 "nonmemory_operand" "")))]
11398 ""
11399 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11400
11401 (define_insn "*lshrdi3_1_one_bit_rex64"
11402 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11403 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11404 (match_operand:QI 2 "const1_operand" "")))
11405 (clobber (reg:CC FLAGS_REG))]
11406 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11407 && (TARGET_SHIFT1 || optimize_size)"
11408 "shr{q}\t%0"
11409 [(set_attr "type" "ishift")
11410 (set (attr "length")
11411 (if_then_else (match_operand:DI 0 "register_operand" "")
11412 (const_string "2")
11413 (const_string "*")))])
11414
11415 (define_insn "*lshrdi3_1_rex64"
11416 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11417 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11418 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11419 (clobber (reg:CC FLAGS_REG))]
11420 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11421 "@
11422 shr{q}\t{%2, %0|%0, %2}
11423 shr{q}\t{%b2, %0|%0, %b2}"
11424 [(set_attr "type" "ishift")
11425 (set_attr "mode" "DI")])
11426
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags. We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11431 [(set (reg FLAGS_REG)
11432 (compare
11433 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434 (match_operand:QI 2 "const1_operand" ""))
11435 (const_int 0)))
11436 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11437 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11438 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439 && (TARGET_SHIFT1 || optimize_size)
11440 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11441 "shr{q}\t%0"
11442 [(set_attr "type" "ishift")
11443 (set (attr "length")
11444 (if_then_else (match_operand:DI 0 "register_operand" "")
11445 (const_string "2")
11446 (const_string "*")))])
11447
11448 ;; This pattern can't accept a variable shift count, since shifts by
11449 ;; zero don't affect the flags. We assume that shifts by constant
11450 ;; zero are optimized away.
11451 (define_insn "*lshrdi3_cmp_rex64"
11452 [(set (reg FLAGS_REG)
11453 (compare
11454 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11455 (match_operand:QI 2 "const_int_operand" "e"))
11456 (const_int 0)))
11457 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11458 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11459 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11460 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11461 "shr{q}\t{%2, %0|%0, %2}"
11462 [(set_attr "type" "ishift")
11463 (set_attr "mode" "DI")])
11464
11465 (define_insn "*lshrdi3_1"
11466 [(set (match_operand:DI 0 "register_operand" "=r")
11467 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11468 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11469 (clobber (reg:CC FLAGS_REG))]
11470 "!TARGET_64BIT"
11471 "#"
11472 [(set_attr "type" "multi")])
11473
11474 ;; By default we don't ask for a scratch register, because when DImode
11475 ;; values are manipulated, registers are already at a premium. But if
11476 ;; we have one handy, we won't turn it away.
11477 (define_peephole2
11478 [(match_scratch:SI 3 "r")
11479 (parallel [(set (match_operand:DI 0 "register_operand" "")
11480 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11481 (match_operand:QI 2 "nonmemory_operand" "")))
11482 (clobber (reg:CC FLAGS_REG))])
11483 (match_dup 3)]
11484 "!TARGET_64BIT && TARGET_CMOVE"
11485 [(const_int 0)]
11486 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11487
11488 (define_split
11489 [(set (match_operand:DI 0 "register_operand" "")
11490 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11491 (match_operand:QI 2 "nonmemory_operand" "")))
11492 (clobber (reg:CC FLAGS_REG))]
11493 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11494 [(const_int 0)]
11495 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11496
11497 (define_expand "lshrsi3"
11498 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11499 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11500 (match_operand:QI 2 "nonmemory_operand" "")))
11501 (clobber (reg:CC FLAGS_REG))]
11502 ""
11503 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11504
11505 (define_insn "*lshrsi3_1_one_bit"
11506 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11507 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11508 (match_operand:QI 2 "const1_operand" "")))
11509 (clobber (reg:CC FLAGS_REG))]
11510 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11511 && (TARGET_SHIFT1 || optimize_size)"
11512 "shr{l}\t%0"
11513 [(set_attr "type" "ishift")
11514 (set (attr "length")
11515 (if_then_else (match_operand:SI 0 "register_operand" "")
11516 (const_string "2")
11517 (const_string "*")))])
11518
11519 (define_insn "*lshrsi3_1_one_bit_zext"
11520 [(set (match_operand:DI 0 "register_operand" "=r")
11521 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11522 (match_operand:QI 2 "const1_operand" "")))
11523 (clobber (reg:CC FLAGS_REG))]
11524 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11525 && (TARGET_SHIFT1 || optimize_size)"
11526 "shr{l}\t%k0"
11527 [(set_attr "type" "ishift")
11528 (set_attr "length" "2")])
11529
11530 (define_insn "*lshrsi3_1"
11531 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11532 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11533 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11534 (clobber (reg:CC FLAGS_REG))]
11535 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11536 "@
11537 shr{l}\t{%2, %0|%0, %2}
11538 shr{l}\t{%b2, %0|%0, %b2}"
11539 [(set_attr "type" "ishift")
11540 (set_attr "mode" "SI")])
11541
11542 (define_insn "*lshrsi3_1_zext"
11543 [(set (match_operand:DI 0 "register_operand" "=r,r")
11544 (zero_extend:DI
11545 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11546 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11547 (clobber (reg:CC FLAGS_REG))]
11548 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11549 "@
11550 shr{l}\t{%2, %k0|%k0, %2}
11551 shr{l}\t{%b2, %k0|%k0, %b2}"
11552 [(set_attr "type" "ishift")
11553 (set_attr "mode" "SI")])
11554
11555 ;; This pattern can't accept a variable shift count, since shifts by
11556 ;; zero don't affect the flags. We assume that shifts by constant
11557 ;; zero are optimized away.
11558 (define_insn "*lshrsi3_one_bit_cmp"
11559 [(set (reg FLAGS_REG)
11560 (compare
11561 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11562 (match_operand:QI 2 "const1_operand" ""))
11563 (const_int 0)))
11564 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11565 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11566 "ix86_match_ccmode (insn, CCGOCmode)
11567 && (TARGET_SHIFT1 || optimize_size)
11568 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11569 "shr{l}\t%0"
11570 [(set_attr "type" "ishift")
11571 (set (attr "length")
11572 (if_then_else (match_operand:SI 0 "register_operand" "")
11573 (const_string "2")
11574 (const_string "*")))])
11575
11576 (define_insn "*lshrsi3_cmp_one_bit_zext"
11577 [(set (reg FLAGS_REG)
11578 (compare
11579 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11580 (match_operand:QI 2 "const1_operand" ""))
11581 (const_int 0)))
11582 (set (match_operand:DI 0 "register_operand" "=r")
11583 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11584 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11585 && (TARGET_SHIFT1 || optimize_size)
11586 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11587 "shr{l}\t%k0"
11588 [(set_attr "type" "ishift")
11589 (set_attr "length" "2")])
11590
11591 ;; This pattern can't accept a variable shift count, since shifts by
11592 ;; zero don't affect the flags. We assume that shifts by constant
11593 ;; zero are optimized away.
11594 (define_insn "*lshrsi3_cmp"
11595 [(set (reg FLAGS_REG)
11596 (compare
11597 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11598 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11599 (const_int 0)))
11600 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11601 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11602 "ix86_match_ccmode (insn, CCGOCmode)
11603 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11604 "shr{l}\t{%2, %0|%0, %2}"
11605 [(set_attr "type" "ishift")
11606 (set_attr "mode" "SI")])
11607
11608 (define_insn "*lshrsi3_cmp_zext"
11609 [(set (reg FLAGS_REG)
11610 (compare
11611 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11612 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11613 (const_int 0)))
11614 (set (match_operand:DI 0 "register_operand" "=r")
11615 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11616 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11617 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11618 "shr{l}\t{%2, %k0|%k0, %2}"
11619 [(set_attr "type" "ishift")
11620 (set_attr "mode" "SI")])
11621
11622 (define_expand "lshrhi3"
11623 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11624 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11625 (match_operand:QI 2 "nonmemory_operand" "")))
11626 (clobber (reg:CC FLAGS_REG))]
11627 "TARGET_HIMODE_MATH"
11628 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11629
11630 (define_insn "*lshrhi3_1_one_bit"
11631 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11632 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11633 (match_operand:QI 2 "const1_operand" "")))
11634 (clobber (reg:CC FLAGS_REG))]
11635 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11636 && (TARGET_SHIFT1 || optimize_size)"
11637 "shr{w}\t%0"
11638 [(set_attr "type" "ishift")
11639 (set (attr "length")
11640 (if_then_else (match_operand 0 "register_operand" "")
11641 (const_string "2")
11642 (const_string "*")))])
11643
11644 (define_insn "*lshrhi3_1"
11645 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11646 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11647 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11648 (clobber (reg:CC FLAGS_REG))]
11649 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11650 "@
11651 shr{w}\t{%2, %0|%0, %2}
11652 shr{w}\t{%b2, %0|%0, %b2}"
11653 [(set_attr "type" "ishift")
11654 (set_attr "mode" "HI")])
11655
11656 ;; This pattern can't accept a variable shift count, since shifts by
11657 ;; zero don't affect the flags. We assume that shifts by constant
11658 ;; zero are optimized away.
11659 (define_insn "*lshrhi3_one_bit_cmp"
11660 [(set (reg FLAGS_REG)
11661 (compare
11662 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11663 (match_operand:QI 2 "const1_operand" ""))
11664 (const_int 0)))
11665 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11666 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11667 "ix86_match_ccmode (insn, CCGOCmode)
11668 && (TARGET_SHIFT1 || optimize_size)
11669 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11670 "shr{w}\t%0"
11671 [(set_attr "type" "ishift")
11672 (set (attr "length")
11673 (if_then_else (match_operand:SI 0 "register_operand" "")
11674 (const_string "2")
11675 (const_string "*")))])
11676
11677 ;; This pattern can't accept a variable shift count, since shifts by
11678 ;; zero don't affect the flags. We assume that shifts by constant
11679 ;; zero are optimized away.
11680 (define_insn "*lshrhi3_cmp"
11681 [(set (reg FLAGS_REG)
11682 (compare
11683 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11684 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11685 (const_int 0)))
11686 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11687 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11688 "ix86_match_ccmode (insn, CCGOCmode)
11689 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11690 "shr{w}\t{%2, %0|%0, %2}"
11691 [(set_attr "type" "ishift")
11692 (set_attr "mode" "HI")])
11693
11694 (define_expand "lshrqi3"
11695 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11696 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11697 (match_operand:QI 2 "nonmemory_operand" "")))
11698 (clobber (reg:CC FLAGS_REG))]
11699 "TARGET_QIMODE_MATH"
11700 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11701
11702 (define_insn "*lshrqi3_1_one_bit"
11703 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11704 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11705 (match_operand:QI 2 "const1_operand" "")))
11706 (clobber (reg:CC FLAGS_REG))]
11707 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11708 && (TARGET_SHIFT1 || optimize_size)"
11709 "shr{b}\t%0"
11710 [(set_attr "type" "ishift")
11711 (set (attr "length")
11712 (if_then_else (match_operand 0 "register_operand" "")
11713 (const_string "2")
11714 (const_string "*")))])
11715
11716 (define_insn "*lshrqi3_1_one_bit_slp"
11717 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11718 (lshiftrt:QI (match_dup 0)
11719 (match_operand:QI 1 "const1_operand" "")))
11720 (clobber (reg:CC FLAGS_REG))]
11721 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11722 && (TARGET_SHIFT1 || optimize_size)"
11723 "shr{b}\t%0"
11724 [(set_attr "type" "ishift1")
11725 (set (attr "length")
11726 (if_then_else (match_operand 0 "register_operand" "")
11727 (const_string "2")
11728 (const_string "*")))])
11729
11730 (define_insn "*lshrqi3_1"
11731 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11732 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11733 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11734 (clobber (reg:CC FLAGS_REG))]
11735 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11736 "@
11737 shr{b}\t{%2, %0|%0, %2}
11738 shr{b}\t{%b2, %0|%0, %b2}"
11739 [(set_attr "type" "ishift")
11740 (set_attr "mode" "QI")])
11741
11742 (define_insn "*lshrqi3_1_slp"
11743 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11744 (lshiftrt:QI (match_dup 0)
11745 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11746 (clobber (reg:CC FLAGS_REG))]
11747 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11748 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11749 "@
11750 shr{b}\t{%1, %0|%0, %1}
11751 shr{b}\t{%b1, %0|%0, %b1}"
11752 [(set_attr "type" "ishift1")
11753 (set_attr "mode" "QI")])
11754
11755 ;; This pattern can't accept a variable shift count, since shifts by
11756 ;; zero don't affect the flags. We assume that shifts by constant
11757 ;; zero are optimized away.
11758 (define_insn "*lshrqi2_one_bit_cmp"
11759 [(set (reg FLAGS_REG)
11760 (compare
11761 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11762 (match_operand:QI 2 "const1_operand" ""))
11763 (const_int 0)))
11764 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11765 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11766 "ix86_match_ccmode (insn, CCGOCmode)
11767 && (TARGET_SHIFT1 || optimize_size)
11768 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11769 "shr{b}\t%0"
11770 [(set_attr "type" "ishift")
11771 (set (attr "length")
11772 (if_then_else (match_operand:SI 0 "register_operand" "")
11773 (const_string "2")
11774 (const_string "*")))])
11775
11776 ;; This pattern can't accept a variable shift count, since shifts by
11777 ;; zero don't affect the flags. We assume that shifts by constant
11778 ;; zero are optimized away.
11779 (define_insn "*lshrqi2_cmp"
11780 [(set (reg FLAGS_REG)
11781 (compare
11782 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11783 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11784 (const_int 0)))
11785 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11786 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11787 "ix86_match_ccmode (insn, CCGOCmode)
11788 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11789 "shr{b}\t{%2, %0|%0, %2}"
11790 [(set_attr "type" "ishift")
11791 (set_attr "mode" "QI")])
11792 \f
11793 ;; Rotate instructions
11794
11795 (define_expand "rotldi3"
11796 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11797 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11798 (match_operand:QI 2 "nonmemory_operand" "")))
11799 (clobber (reg:CC FLAGS_REG))]
11800 "TARGET_64BIT"
11801 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11802
11803 (define_insn "*rotlsi3_1_one_bit_rex64"
11804 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11805 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11806 (match_operand:QI 2 "const1_operand" "")))
11807 (clobber (reg:CC FLAGS_REG))]
11808 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11809 && (TARGET_SHIFT1 || optimize_size)"
11810 "rol{q}\t%0"
11811 [(set_attr "type" "rotate")
11812 (set (attr "length")
11813 (if_then_else (match_operand:DI 0 "register_operand" "")
11814 (const_string "2")
11815 (const_string "*")))])
11816
11817 (define_insn "*rotldi3_1_rex64"
11818 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11819 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11820 (match_operand:QI 2 "nonmemory_operand" "e,c")))
11821 (clobber (reg:CC FLAGS_REG))]
11822 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11823 "@
11824 rol{q}\t{%2, %0|%0, %2}
11825 rol{q}\t{%b2, %0|%0, %b2}"
11826 [(set_attr "type" "rotate")
11827 (set_attr "mode" "DI")])
11828
11829 (define_expand "rotlsi3"
11830 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11831 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11832 (match_operand:QI 2 "nonmemory_operand" "")))
11833 (clobber (reg:CC FLAGS_REG))]
11834 ""
11835 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11836
11837 (define_insn "*rotlsi3_1_one_bit"
11838 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11839 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11840 (match_operand:QI 2 "const1_operand" "")))
11841 (clobber (reg:CC FLAGS_REG))]
11842 "ix86_binary_operator_ok (ROTATE, SImode, operands)
11843 && (TARGET_SHIFT1 || optimize_size)"
11844 "rol{l}\t%0"
11845 [(set_attr "type" "rotate")
11846 (set (attr "length")
11847 (if_then_else (match_operand:SI 0 "register_operand" "")
11848 (const_string "2")
11849 (const_string "*")))])
11850
11851 (define_insn "*rotlsi3_1_one_bit_zext"
11852 [(set (match_operand:DI 0 "register_operand" "=r")
11853 (zero_extend:DI
11854 (rotate:SI (match_operand:SI 1 "register_operand" "0")
11855 (match_operand:QI 2 "const1_operand" ""))))
11856 (clobber (reg:CC FLAGS_REG))]
11857 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11858 && (TARGET_SHIFT1 || optimize_size)"
11859 "rol{l}\t%k0"
11860 [(set_attr "type" "rotate")
11861 (set_attr "length" "2")])
11862
11863 (define_insn "*rotlsi3_1"
11864 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11865 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11866 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11867 (clobber (reg:CC FLAGS_REG))]
11868 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11869 "@
11870 rol{l}\t{%2, %0|%0, %2}
11871 rol{l}\t{%b2, %0|%0, %b2}"
11872 [(set_attr "type" "rotate")
11873 (set_attr "mode" "SI")])
11874
11875 (define_insn "*rotlsi3_1_zext"
11876 [(set (match_operand:DI 0 "register_operand" "=r,r")
11877 (zero_extend:DI
11878 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11879 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11880 (clobber (reg:CC FLAGS_REG))]
11881 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11882 "@
11883 rol{l}\t{%2, %k0|%k0, %2}
11884 rol{l}\t{%b2, %k0|%k0, %b2}"
11885 [(set_attr "type" "rotate")
11886 (set_attr "mode" "SI")])
11887
11888 (define_expand "rotlhi3"
11889 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11890 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11891 (match_operand:QI 2 "nonmemory_operand" "")))
11892 (clobber (reg:CC FLAGS_REG))]
11893 "TARGET_HIMODE_MATH"
11894 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11895
11896 (define_insn "*rotlhi3_1_one_bit"
11897 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11898 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11899 (match_operand:QI 2 "const1_operand" "")))
11900 (clobber (reg:CC FLAGS_REG))]
11901 "ix86_binary_operator_ok (ROTATE, HImode, operands)
11902 && (TARGET_SHIFT1 || optimize_size)"
11903 "rol{w}\t%0"
11904 [(set_attr "type" "rotate")
11905 (set (attr "length")
11906 (if_then_else (match_operand 0 "register_operand" "")
11907 (const_string "2")
11908 (const_string "*")))])
11909
11910 (define_insn "*rotlhi3_1"
11911 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11912 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11913 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11914 (clobber (reg:CC FLAGS_REG))]
11915 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11916 "@
11917 rol{w}\t{%2, %0|%0, %2}
11918 rol{w}\t{%b2, %0|%0, %b2}"
11919 [(set_attr "type" "rotate")
11920 (set_attr "mode" "HI")])
11921
11922 (define_expand "rotlqi3"
11923 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11924 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11925 (match_operand:QI 2 "nonmemory_operand" "")))
11926 (clobber (reg:CC FLAGS_REG))]
11927 "TARGET_QIMODE_MATH"
11928 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11929
11930 (define_insn "*rotlqi3_1_one_bit_slp"
11931 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11932 (rotate:QI (match_dup 0)
11933 (match_operand:QI 1 "const1_operand" "")))
11934 (clobber (reg:CC FLAGS_REG))]
11935 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11936 && (TARGET_SHIFT1 || optimize_size)"
11937 "rol{b}\t%0"
11938 [(set_attr "type" "rotate1")
11939 (set (attr "length")
11940 (if_then_else (match_operand 0 "register_operand" "")
11941 (const_string "2")
11942 (const_string "*")))])
11943
11944 (define_insn "*rotlqi3_1_one_bit"
11945 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11946 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11947 (match_operand:QI 2 "const1_operand" "")))
11948 (clobber (reg:CC FLAGS_REG))]
11949 "ix86_binary_operator_ok (ROTATE, QImode, operands)
11950 && (TARGET_SHIFT1 || optimize_size)"
11951 "rol{b}\t%0"
11952 [(set_attr "type" "rotate")
11953 (set (attr "length")
11954 (if_then_else (match_operand 0 "register_operand" "")
11955 (const_string "2")
11956 (const_string "*")))])
11957
11958 (define_insn "*rotlqi3_1_slp"
11959 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11960 (rotate:QI (match_dup 0)
11961 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11962 (clobber (reg:CC FLAGS_REG))]
11963 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11964 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11965 "@
11966 rol{b}\t{%1, %0|%0, %1}
11967 rol{b}\t{%b1, %0|%0, %b1}"
11968 [(set_attr "type" "rotate1")
11969 (set_attr "mode" "QI")])
11970
11971 (define_insn "*rotlqi3_1"
11972 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11973 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11974 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11975 (clobber (reg:CC FLAGS_REG))]
11976 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11977 "@
11978 rol{b}\t{%2, %0|%0, %2}
11979 rol{b}\t{%b2, %0|%0, %b2}"
11980 [(set_attr "type" "rotate")
11981 (set_attr "mode" "QI")])
11982
11983 (define_expand "rotrdi3"
11984 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11985 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11986 (match_operand:QI 2 "nonmemory_operand" "")))
11987 (clobber (reg:CC FLAGS_REG))]
11988 "TARGET_64BIT"
11989 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11990
11991 (define_insn "*rotrdi3_1_one_bit_rex64"
11992 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11993 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11994 (match_operand:QI 2 "const1_operand" "")))
11995 (clobber (reg:CC FLAGS_REG))]
11996 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11997 && (TARGET_SHIFT1 || optimize_size)"
11998 "ror{q}\t%0"
11999 [(set_attr "type" "rotate")
12000 (set (attr "length")
12001 (if_then_else (match_operand:DI 0 "register_operand" "")
12002 (const_string "2")
12003 (const_string "*")))])
12004
12005 (define_insn "*rotrdi3_1_rex64"
12006 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12007 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12008 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12009 (clobber (reg:CC FLAGS_REG))]
12010 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12011 "@
12012 ror{q}\t{%2, %0|%0, %2}
12013 ror{q}\t{%b2, %0|%0, %b2}"
12014 [(set_attr "type" "rotate")
12015 (set_attr "mode" "DI")])
12016
12017 (define_expand "rotrsi3"
12018 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12019 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12020 (match_operand:QI 2 "nonmemory_operand" "")))
12021 (clobber (reg:CC FLAGS_REG))]
12022 ""
12023 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12024
12025 (define_insn "*rotrsi3_1_one_bit"
12026 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12027 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12028 (match_operand:QI 2 "const1_operand" "")))
12029 (clobber (reg:CC FLAGS_REG))]
12030 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12031 && (TARGET_SHIFT1 || optimize_size)"
12032 "ror{l}\t%0"
12033 [(set_attr "type" "rotate")
12034 (set (attr "length")
12035 (if_then_else (match_operand:SI 0 "register_operand" "")
12036 (const_string "2")
12037 (const_string "*")))])
12038
12039 (define_insn "*rotrsi3_1_one_bit_zext"
12040 [(set (match_operand:DI 0 "register_operand" "=r")
12041 (zero_extend:DI
12042 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12043 (match_operand:QI 2 "const1_operand" ""))))
12044 (clobber (reg:CC FLAGS_REG))]
12045 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12046 && (TARGET_SHIFT1 || optimize_size)"
12047 "ror{l}\t%k0"
12048 [(set_attr "type" "rotate")
12049 (set (attr "length")
12050 (if_then_else (match_operand:SI 0 "register_operand" "")
12051 (const_string "2")
12052 (const_string "*")))])
12053
12054 (define_insn "*rotrsi3_1"
12055 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12056 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12057 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12058 (clobber (reg:CC FLAGS_REG))]
12059 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12060 "@
12061 ror{l}\t{%2, %0|%0, %2}
12062 ror{l}\t{%b2, %0|%0, %b2}"
12063 [(set_attr "type" "rotate")
12064 (set_attr "mode" "SI")])
12065
12066 (define_insn "*rotrsi3_1_zext"
12067 [(set (match_operand:DI 0 "register_operand" "=r,r")
12068 (zero_extend:DI
12069 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12070 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12071 (clobber (reg:CC FLAGS_REG))]
12072 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12073 "@
12074 ror{l}\t{%2, %k0|%k0, %2}
12075 ror{l}\t{%b2, %k0|%k0, %b2}"
12076 [(set_attr "type" "rotate")
12077 (set_attr "mode" "SI")])
12078
12079 (define_expand "rotrhi3"
12080 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12081 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12082 (match_operand:QI 2 "nonmemory_operand" "")))
12083 (clobber (reg:CC FLAGS_REG))]
12084 "TARGET_HIMODE_MATH"
12085 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12086
12087 (define_insn "*rotrhi3_one_bit"
12088 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12089 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12090 (match_operand:QI 2 "const1_operand" "")))
12091 (clobber (reg:CC FLAGS_REG))]
12092 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12093 && (TARGET_SHIFT1 || optimize_size)"
12094 "ror{w}\t%0"
12095 [(set_attr "type" "rotate")
12096 (set (attr "length")
12097 (if_then_else (match_operand 0 "register_operand" "")
12098 (const_string "2")
12099 (const_string "*")))])
12100
12101 (define_insn "*rotrhi3"
12102 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12103 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12104 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12105 (clobber (reg:CC FLAGS_REG))]
12106 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12107 "@
12108 ror{w}\t{%2, %0|%0, %2}
12109 ror{w}\t{%b2, %0|%0, %b2}"
12110 [(set_attr "type" "rotate")
12111 (set_attr "mode" "HI")])
12112
12113 (define_expand "rotrqi3"
12114 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12115 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12116 (match_operand:QI 2 "nonmemory_operand" "")))
12117 (clobber (reg:CC FLAGS_REG))]
12118 "TARGET_QIMODE_MATH"
12119 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12120
12121 (define_insn "*rotrqi3_1_one_bit"
12122 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12123 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12124 (match_operand:QI 2 "const1_operand" "")))
12125 (clobber (reg:CC FLAGS_REG))]
12126 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12127 && (TARGET_SHIFT1 || optimize_size)"
12128 "ror{b}\t%0"
12129 [(set_attr "type" "rotate")
12130 (set (attr "length")
12131 (if_then_else (match_operand 0 "register_operand" "")
12132 (const_string "2")
12133 (const_string "*")))])
12134
12135 (define_insn "*rotrqi3_1_one_bit_slp"
12136 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12137 (rotatert:QI (match_dup 0)
12138 (match_operand:QI 1 "const1_operand" "")))
12139 (clobber (reg:CC FLAGS_REG))]
12140 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12141 && (TARGET_SHIFT1 || optimize_size)"
12142 "ror{b}\t%0"
12143 [(set_attr "type" "rotate1")
12144 (set (attr "length")
12145 (if_then_else (match_operand 0 "register_operand" "")
12146 (const_string "2")
12147 (const_string "*")))])
12148
12149 (define_insn "*rotrqi3_1"
12150 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12151 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12152 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12153 (clobber (reg:CC FLAGS_REG))]
12154 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12155 "@
12156 ror{b}\t{%2, %0|%0, %2}
12157 ror{b}\t{%b2, %0|%0, %b2}"
12158 [(set_attr "type" "rotate")
12159 (set_attr "mode" "QI")])
12160
12161 (define_insn "*rotrqi3_1_slp"
12162 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12163 (rotatert:QI (match_dup 0)
12164 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12165 (clobber (reg:CC FLAGS_REG))]
12166 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12167 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12168 "@
12169 ror{b}\t{%1, %0|%0, %1}
12170 ror{b}\t{%b1, %0|%0, %b1}"
12171 [(set_attr "type" "rotate1")
12172 (set_attr "mode" "QI")])
12173 \f
12174 ;; Bit set / bit test instructions
12175
12176 (define_expand "extv"
12177 [(set (match_operand:SI 0 "register_operand" "")
12178 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12179 (match_operand:SI 2 "immediate_operand" "")
12180 (match_operand:SI 3 "immediate_operand" "")))]
12181 ""
12182 {
12183 /* Handle extractions from %ah et al. */
12184 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12185 FAIL;
12186
12187 /* From mips.md: extract_bit_field doesn't verify that our source
12188 matches the predicate, so check it again here. */
12189 if (! register_operand (operands[1], VOIDmode))
12190 FAIL;
12191 })
12192
12193 (define_expand "extzv"
12194 [(set (match_operand:SI 0 "register_operand" "")
12195 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12196 (match_operand:SI 2 "immediate_operand" "")
12197 (match_operand:SI 3 "immediate_operand" "")))]
12198 ""
12199 {
12200 /* Handle extractions from %ah et al. */
12201 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12202 FAIL;
12203
12204 /* From mips.md: extract_bit_field doesn't verify that our source
12205 matches the predicate, so check it again here. */
12206 if (! register_operand (operands[1], VOIDmode))
12207 FAIL;
12208 })
12209
12210 (define_expand "insv"
12211 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12212 (match_operand 1 "immediate_operand" "")
12213 (match_operand 2 "immediate_operand" ""))
12214 (match_operand 3 "register_operand" ""))]
12215 ""
12216 {
12217 /* Handle extractions from %ah et al. */
12218 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12219 FAIL;
12220
12221 /* From mips.md: insert_bit_field doesn't verify that our source
12222 matches the predicate, so check it again here. */
12223 if (! register_operand (operands[0], VOIDmode))
12224 FAIL;
12225
12226 if (TARGET_64BIT)
12227 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12228 else
12229 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12230
12231 DONE;
12232 })
12233
12234 ;; %%% bts, btr, btc, bt.
12235 ;; In general these instructions are *slow* when applied to memory,
12236 ;; since they enforce atomic operation. When applied to registers,
12237 ;; it depends on the cpu implementation. They're never faster than
12238 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12239 ;; no point. But in 64-bit, we can't hold the relevant immediates
12240 ;; within the instruction itself, so operating on bits in the high
12241 ;; 32-bits of a register becomes easier.
12242 ;;
12243 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12244 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12245 ;; negdf respectively, so they can never be disabled entirely.
12246
12247 (define_insn "*btsq"
12248 [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12249 (const_int 1)
12250 (match_operand 1 "const_0_to_63_operand" ""))
12251 (const_int 1))
12252 (clobber (reg:CC FLAGS_REG))]
12253 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12254 "bts{q} %1,%0"
12255 [(set_attr "type" "alu1")])
12256
12257 (define_insn "*btrq"
12258 [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12259 (const_int 1)
12260 (match_operand 1 "const_0_to_63_operand" ""))
12261 (const_int 0))
12262 (clobber (reg:CC FLAGS_REG))]
12263 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12264 "btr{q} %1,%0"
12265 [(set_attr "type" "alu1")])
12266
12267 (define_insn "*btcq"
12268 [(set (zero_extract:DI (match_operand 0 "register_operand" "+r")
12269 (const_int 1)
12270 (match_operand 1 "const_0_to_63_operand" ""))
12271 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12272 (clobber (reg:CC FLAGS_REG))]
12273 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12274 "btc{q} %1,%0"
12275 [(set_attr "type" "alu1")])
12276
12277 ;; Allow Nocona to avoid these instructions if a register is available.
12278
12279 (define_peephole2
12280 [(match_scratch:DI 2 "r")
12281 (parallel [(set (zero_extract:DI
12282 (match_operand 0 "register_operand" "")
12283 (const_int 1)
12284 (match_operand 1 "const_0_to_63_operand" ""))
12285 (const_int 1))
12286 (clobber (reg:CC FLAGS_REG))])]
12287 "TARGET_64BIT && !TARGET_USE_BT"
12288 [(const_int 0)]
12289 {
12290 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12291 rtx op1;
12292
12293 if (HOST_BITS_PER_WIDE_INT >= 64)
12294 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12295 else if (i < HOST_BITS_PER_WIDE_INT)
12296 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12297 else
12298 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12299
12300 op1 = immed_double_const (lo, hi, DImode);
12301 if (i >= 31)
12302 {
12303 emit_move_insn (operands[2], op1);
12304 op1 = operands[2];
12305 }
12306
12307 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12308 DONE;
12309 })
12310
12311 (define_peephole2
12312 [(match_scratch:DI 2 "r")
12313 (parallel [(set (zero_extract:DI
12314 (match_operand 0 "register_operand" "")
12315 (const_int 1)
12316 (match_operand 1 "const_0_to_63_operand" ""))
12317 (const_int 0))
12318 (clobber (reg:CC FLAGS_REG))])]
12319 "TARGET_64BIT && !TARGET_USE_BT"
12320 [(const_int 0)]
12321 {
12322 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12323 rtx op1;
12324
12325 if (HOST_BITS_PER_WIDE_INT >= 64)
12326 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12327 else if (i < HOST_BITS_PER_WIDE_INT)
12328 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12329 else
12330 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12331
12332 op1 = immed_double_const (~lo, ~hi, DImode);
12333 if (i >= 32)
12334 {
12335 emit_move_insn (operands[2], op1);
12336 op1 = operands[2];
12337 }
12338
12339 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12340 DONE;
12341 })
12342
12343 (define_peephole2
12344 [(match_scratch:DI 2 "r")
12345 (parallel [(set (zero_extract:DI
12346 (match_operand 0 "register_operand" "")
12347 (const_int 1)
12348 (match_operand 1 "const_0_to_63_operand" ""))
12349 (not:DI (zero_extract:DI
12350 (match_dup 0) (const_int 1) (match_dup 1))))
12351 (clobber (reg:CC FLAGS_REG))])]
12352 "TARGET_64BIT && !TARGET_USE_BT"
12353 [(const_int 0)]
12354 {
12355 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12356 rtx op1;
12357
12358 if (HOST_BITS_PER_WIDE_INT >= 64)
12359 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12360 else if (i < HOST_BITS_PER_WIDE_INT)
12361 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12362 else
12363 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12364
12365 op1 = immed_double_const (lo, hi, DImode);
12366 if (i >= 31)
12367 {
12368 emit_move_insn (operands[2], op1);
12369 op1 = operands[2];
12370 }
12371
12372 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12373 DONE;
12374 })
12375 \f
12376 ;; Store-flag instructions.
12377
12378 ;; For all sCOND expanders, also expand the compare or test insn that
12379 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12380
12381 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12382 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12383 ;; way, which can later delete the movzx if only QImode is needed.
12384
12385 (define_expand "seq"
12386 [(set (match_operand:QI 0 "register_operand" "")
12387 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12388 ""
12389 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12390
12391 (define_expand "sne"
12392 [(set (match_operand:QI 0 "register_operand" "")
12393 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12394 ""
12395 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12396
12397 (define_expand "sgt"
12398 [(set (match_operand:QI 0 "register_operand" "")
12399 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12400 ""
12401 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12402
12403 (define_expand "sgtu"
12404 [(set (match_operand:QI 0 "register_operand" "")
12405 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12406 ""
12407 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12408
12409 (define_expand "slt"
12410 [(set (match_operand:QI 0 "register_operand" "")
12411 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12412 ""
12413 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12414
12415 (define_expand "sltu"
12416 [(set (match_operand:QI 0 "register_operand" "")
12417 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12418 ""
12419 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12420
12421 (define_expand "sge"
12422 [(set (match_operand:QI 0 "register_operand" "")
12423 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12424 ""
12425 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12426
12427 (define_expand "sgeu"
12428 [(set (match_operand:QI 0 "register_operand" "")
12429 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12430 ""
12431 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12432
12433 (define_expand "sle"
12434 [(set (match_operand:QI 0 "register_operand" "")
12435 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12436 ""
12437 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12438
12439 (define_expand "sleu"
12440 [(set (match_operand:QI 0 "register_operand" "")
12441 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12442 ""
12443 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12444
12445 (define_expand "sunordered"
12446 [(set (match_operand:QI 0 "register_operand" "")
12447 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12448 "TARGET_80387 || TARGET_SSE"
12449 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12450
12451 (define_expand "sordered"
12452 [(set (match_operand:QI 0 "register_operand" "")
12453 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12454 "TARGET_80387"
12455 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12456
12457 (define_expand "suneq"
12458 [(set (match_operand:QI 0 "register_operand" "")
12459 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12460 "TARGET_80387 || TARGET_SSE"
12461 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12462
12463 (define_expand "sunge"
12464 [(set (match_operand:QI 0 "register_operand" "")
12465 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12466 "TARGET_80387 || TARGET_SSE"
12467 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12468
12469 (define_expand "sungt"
12470 [(set (match_operand:QI 0 "register_operand" "")
12471 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12472 "TARGET_80387 || TARGET_SSE"
12473 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12474
12475 (define_expand "sunle"
12476 [(set (match_operand:QI 0 "register_operand" "")
12477 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12478 "TARGET_80387 || TARGET_SSE"
12479 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12480
12481 (define_expand "sunlt"
12482 [(set (match_operand:QI 0 "register_operand" "")
12483 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12484 "TARGET_80387 || TARGET_SSE"
12485 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12486
12487 (define_expand "sltgt"
12488 [(set (match_operand:QI 0 "register_operand" "")
12489 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12490 "TARGET_80387 || TARGET_SSE"
12491 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12492
12493 (define_insn "*setcc_1"
12494 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12495 (match_operator:QI 1 "ix86_comparison_operator"
12496 [(reg FLAGS_REG) (const_int 0)]))]
12497 ""
12498 "set%C1\t%0"
12499 [(set_attr "type" "setcc")
12500 (set_attr "mode" "QI")])
12501
12502 (define_insn "*setcc_2"
12503 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12504 (match_operator:QI 1 "ix86_comparison_operator"
12505 [(reg FLAGS_REG) (const_int 0)]))]
12506 ""
12507 "set%C1\t%0"
12508 [(set_attr "type" "setcc")
12509 (set_attr "mode" "QI")])
12510
12511 ;; In general it is not safe to assume too much about CCmode registers,
12512 ;; so simplify-rtx stops when it sees a second one. Under certain
12513 ;; conditions this is safe on x86, so help combine not create
12514 ;;
12515 ;; seta %al
12516 ;; testb %al, %al
12517 ;; sete %al
12518
12519 (define_split
12520 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12521 (ne:QI (match_operator 1 "ix86_comparison_operator"
12522 [(reg FLAGS_REG) (const_int 0)])
12523 (const_int 0)))]
12524 ""
12525 [(set (match_dup 0) (match_dup 1))]
12526 {
12527 PUT_MODE (operands[1], QImode);
12528 })
12529
12530 (define_split
12531 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12532 (ne:QI (match_operator 1 "ix86_comparison_operator"
12533 [(reg FLAGS_REG) (const_int 0)])
12534 (const_int 0)))]
12535 ""
12536 [(set (match_dup 0) (match_dup 1))]
12537 {
12538 PUT_MODE (operands[1], QImode);
12539 })
12540
12541 (define_split
12542 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12543 (eq:QI (match_operator 1 "ix86_comparison_operator"
12544 [(reg FLAGS_REG) (const_int 0)])
12545 (const_int 0)))]
12546 ""
12547 [(set (match_dup 0) (match_dup 1))]
12548 {
12549 rtx new_op1 = copy_rtx (operands[1]);
12550 operands[1] = new_op1;
12551 PUT_MODE (new_op1, QImode);
12552 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12553 GET_MODE (XEXP (new_op1, 0))));
12554
12555 /* Make sure that (a) the CCmode we have for the flags is strong
12556 enough for the reversed compare or (b) we have a valid FP compare. */
12557 if (! ix86_comparison_operator (new_op1, VOIDmode))
12558 FAIL;
12559 })
12560
12561 (define_split
12562 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12563 (eq:QI (match_operator 1 "ix86_comparison_operator"
12564 [(reg FLAGS_REG) (const_int 0)])
12565 (const_int 0)))]
12566 ""
12567 [(set (match_dup 0) (match_dup 1))]
12568 {
12569 rtx new_op1 = copy_rtx (operands[1]);
12570 operands[1] = new_op1;
12571 PUT_MODE (new_op1, QImode);
12572 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12573 GET_MODE (XEXP (new_op1, 0))));
12574
12575 /* Make sure that (a) the CCmode we have for the flags is strong
12576 enough for the reversed compare or (b) we have a valid FP compare. */
12577 if (! ix86_comparison_operator (new_op1, VOIDmode))
12578 FAIL;
12579 })
12580
12581 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12582 ;; subsequent logical operations are used to imitate conditional moves.
12583 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12584 ;; it directly. Further holding this value in pseudo register might bring
12585 ;; problem in implicit normalization in spill code.
12586 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12587 ;; instructions after reload by splitting the conditional move patterns.
12588
12589 (define_insn "*sse_setccsf"
12590 [(set (match_operand:SF 0 "register_operand" "=x")
12591 (match_operator:SF 1 "sse_comparison_operator"
12592 [(match_operand:SF 2 "register_operand" "0")
12593 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12594 "TARGET_SSE && reload_completed"
12595 "cmp%D1ss\t{%3, %0|%0, %3}"
12596 [(set_attr "type" "ssecmp")
12597 (set_attr "mode" "SF")])
12598
12599 (define_insn "*sse_setccdf"
12600 [(set (match_operand:DF 0 "register_operand" "=Y")
12601 (match_operator:DF 1 "sse_comparison_operator"
12602 [(match_operand:DF 2 "register_operand" "0")
12603 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12604 "TARGET_SSE2 && reload_completed"
12605 "cmp%D1sd\t{%3, %0|%0, %3}"
12606 [(set_attr "type" "ssecmp")
12607 (set_attr "mode" "DF")])
12608 \f
12609 ;; Basic conditional jump instructions.
12610 ;; We ignore the overflow flag for signed branch instructions.
12611
12612 ;; For all bCOND expanders, also expand the compare or test insn that
12613 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12614
12615 (define_expand "beq"
12616 [(set (pc)
12617 (if_then_else (match_dup 1)
12618 (label_ref (match_operand 0 "" ""))
12619 (pc)))]
12620 ""
12621 "ix86_expand_branch (EQ, operands[0]); DONE;")
12622
12623 (define_expand "bne"
12624 [(set (pc)
12625 (if_then_else (match_dup 1)
12626 (label_ref (match_operand 0 "" ""))
12627 (pc)))]
12628 ""
12629 "ix86_expand_branch (NE, operands[0]); DONE;")
12630
12631 (define_expand "bgt"
12632 [(set (pc)
12633 (if_then_else (match_dup 1)
12634 (label_ref (match_operand 0 "" ""))
12635 (pc)))]
12636 ""
12637 "ix86_expand_branch (GT, operands[0]); DONE;")
12638
12639 (define_expand "bgtu"
12640 [(set (pc)
12641 (if_then_else (match_dup 1)
12642 (label_ref (match_operand 0 "" ""))
12643 (pc)))]
12644 ""
12645 "ix86_expand_branch (GTU, operands[0]); DONE;")
12646
12647 (define_expand "blt"
12648 [(set (pc)
12649 (if_then_else (match_dup 1)
12650 (label_ref (match_operand 0 "" ""))
12651 (pc)))]
12652 ""
12653 "ix86_expand_branch (LT, operands[0]); DONE;")
12654
12655 (define_expand "bltu"
12656 [(set (pc)
12657 (if_then_else (match_dup 1)
12658 (label_ref (match_operand 0 "" ""))
12659 (pc)))]
12660 ""
12661 "ix86_expand_branch (LTU, operands[0]); DONE;")
12662
12663 (define_expand "bge"
12664 [(set (pc)
12665 (if_then_else (match_dup 1)
12666 (label_ref (match_operand 0 "" ""))
12667 (pc)))]
12668 ""
12669 "ix86_expand_branch (GE, operands[0]); DONE;")
12670
12671 (define_expand "bgeu"
12672 [(set (pc)
12673 (if_then_else (match_dup 1)
12674 (label_ref (match_operand 0 "" ""))
12675 (pc)))]
12676 ""
12677 "ix86_expand_branch (GEU, operands[0]); DONE;")
12678
12679 (define_expand "ble"
12680 [(set (pc)
12681 (if_then_else (match_dup 1)
12682 (label_ref (match_operand 0 "" ""))
12683 (pc)))]
12684 ""
12685 "ix86_expand_branch (LE, operands[0]); DONE;")
12686
12687 (define_expand "bleu"
12688 [(set (pc)
12689 (if_then_else (match_dup 1)
12690 (label_ref (match_operand 0 "" ""))
12691 (pc)))]
12692 ""
12693 "ix86_expand_branch (LEU, operands[0]); DONE;")
12694
12695 (define_expand "bunordered"
12696 [(set (pc)
12697 (if_then_else (match_dup 1)
12698 (label_ref (match_operand 0 "" ""))
12699 (pc)))]
12700 "TARGET_80387 || TARGET_SSE"
12701 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12702
12703 (define_expand "bordered"
12704 [(set (pc)
12705 (if_then_else (match_dup 1)
12706 (label_ref (match_operand 0 "" ""))
12707 (pc)))]
12708 "TARGET_80387 || TARGET_SSE"
12709 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12710
12711 (define_expand "buneq"
12712 [(set (pc)
12713 (if_then_else (match_dup 1)
12714 (label_ref (match_operand 0 "" ""))
12715 (pc)))]
12716 "TARGET_80387 || TARGET_SSE"
12717 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12718
12719 (define_expand "bunge"
12720 [(set (pc)
12721 (if_then_else (match_dup 1)
12722 (label_ref (match_operand 0 "" ""))
12723 (pc)))]
12724 "TARGET_80387 || TARGET_SSE"
12725 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12726
12727 (define_expand "bungt"
12728 [(set (pc)
12729 (if_then_else (match_dup 1)
12730 (label_ref (match_operand 0 "" ""))
12731 (pc)))]
12732 "TARGET_80387 || TARGET_SSE"
12733 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12734
12735 (define_expand "bunle"
12736 [(set (pc)
12737 (if_then_else (match_dup 1)
12738 (label_ref (match_operand 0 "" ""))
12739 (pc)))]
12740 "TARGET_80387 || TARGET_SSE"
12741 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12742
12743 (define_expand "bunlt"
12744 [(set (pc)
12745 (if_then_else (match_dup 1)
12746 (label_ref (match_operand 0 "" ""))
12747 (pc)))]
12748 "TARGET_80387 || TARGET_SSE"
12749 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12750
12751 (define_expand "bltgt"
12752 [(set (pc)
12753 (if_then_else (match_dup 1)
12754 (label_ref (match_operand 0 "" ""))
12755 (pc)))]
12756 "TARGET_80387 || TARGET_SSE"
12757 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12758
12759 (define_insn "*jcc_1"
12760 [(set (pc)
12761 (if_then_else (match_operator 1 "ix86_comparison_operator"
12762 [(reg FLAGS_REG) (const_int 0)])
12763 (label_ref (match_operand 0 "" ""))
12764 (pc)))]
12765 ""
12766 "%+j%C1\t%l0"
12767 [(set_attr "type" "ibr")
12768 (set_attr "modrm" "0")
12769 (set (attr "length")
12770 (if_then_else (and (ge (minus (match_dup 0) (pc))
12771 (const_int -126))
12772 (lt (minus (match_dup 0) (pc))
12773 (const_int 128)))
12774 (const_int 2)
12775 (const_int 6)))])
12776
12777 (define_insn "*jcc_2"
12778 [(set (pc)
12779 (if_then_else (match_operator 1 "ix86_comparison_operator"
12780 [(reg FLAGS_REG) (const_int 0)])
12781 (pc)
12782 (label_ref (match_operand 0 "" ""))))]
12783 ""
12784 "%+j%c1\t%l0"
12785 [(set_attr "type" "ibr")
12786 (set_attr "modrm" "0")
12787 (set (attr "length")
12788 (if_then_else (and (ge (minus (match_dup 0) (pc))
12789 (const_int -126))
12790 (lt (minus (match_dup 0) (pc))
12791 (const_int 128)))
12792 (const_int 2)
12793 (const_int 6)))])
12794
12795 ;; In general it is not safe to assume too much about CCmode registers,
12796 ;; so simplify-rtx stops when it sees a second one. Under certain
12797 ;; conditions this is safe on x86, so help combine not create
12798 ;;
12799 ;; seta %al
12800 ;; testb %al, %al
12801 ;; je Lfoo
12802
12803 (define_split
12804 [(set (pc)
12805 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12806 [(reg FLAGS_REG) (const_int 0)])
12807 (const_int 0))
12808 (label_ref (match_operand 1 "" ""))
12809 (pc)))]
12810 ""
12811 [(set (pc)
12812 (if_then_else (match_dup 0)
12813 (label_ref (match_dup 1))
12814 (pc)))]
12815 {
12816 PUT_MODE (operands[0], VOIDmode);
12817 })
12818
12819 (define_split
12820 [(set (pc)
12821 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12822 [(reg FLAGS_REG) (const_int 0)])
12823 (const_int 0))
12824 (label_ref (match_operand 1 "" ""))
12825 (pc)))]
12826 ""
12827 [(set (pc)
12828 (if_then_else (match_dup 0)
12829 (label_ref (match_dup 1))
12830 (pc)))]
12831 {
12832 rtx new_op0 = copy_rtx (operands[0]);
12833 operands[0] = new_op0;
12834 PUT_MODE (new_op0, VOIDmode);
12835 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12836 GET_MODE (XEXP (new_op0, 0))));
12837
12838 /* Make sure that (a) the CCmode we have for the flags is strong
12839 enough for the reversed compare or (b) we have a valid FP compare. */
12840 if (! ix86_comparison_operator (new_op0, VOIDmode))
12841 FAIL;
12842 })
12843
12844 ;; Define combination compare-and-branch fp compare instructions to use
12845 ;; during early optimization. Splitting the operation apart early makes
12846 ;; for bad code when we want to reverse the operation.
12847
12848 (define_insn "*fp_jcc_1"
12849 [(set (pc)
12850 (if_then_else (match_operator 0 "comparison_operator"
12851 [(match_operand 1 "register_operand" "f")
12852 (match_operand 2 "register_operand" "f")])
12853 (label_ref (match_operand 3 "" ""))
12854 (pc)))
12855 (clobber (reg:CCFP FPSR_REG))
12856 (clobber (reg:CCFP FLAGS_REG))]
12857 "TARGET_CMOVE && TARGET_80387
12858 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12859 && FLOAT_MODE_P (GET_MODE (operands[1]))
12860 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12861 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12862 "#")
12863
12864 (define_insn "*fp_jcc_1_sse"
12865 [(set (pc)
12866 (if_then_else (match_operator 0 "comparison_operator"
12867 [(match_operand 1 "register_operand" "f#x,x#f")
12868 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12869 (label_ref (match_operand 3 "" ""))
12870 (pc)))
12871 (clobber (reg:CCFP FPSR_REG))
12872 (clobber (reg:CCFP FLAGS_REG))]
12873 "TARGET_80387
12874 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12875 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12876 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12877 "#")
12878
12879 (define_insn "*fp_jcc_1_sse_only"
12880 [(set (pc)
12881 (if_then_else (match_operator 0 "comparison_operator"
12882 [(match_operand 1 "register_operand" "x")
12883 (match_operand 2 "nonimmediate_operand" "xm")])
12884 (label_ref (match_operand 3 "" ""))
12885 (pc)))
12886 (clobber (reg:CCFP FPSR_REG))
12887 (clobber (reg:CCFP FLAGS_REG))]
12888 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12889 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12890 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12891 "#")
12892
12893 (define_insn "*fp_jcc_2"
12894 [(set (pc)
12895 (if_then_else (match_operator 0 "comparison_operator"
12896 [(match_operand 1 "register_operand" "f")
12897 (match_operand 2 "register_operand" "f")])
12898 (pc)
12899 (label_ref (match_operand 3 "" ""))))
12900 (clobber (reg:CCFP FPSR_REG))
12901 (clobber (reg:CCFP FLAGS_REG))]
12902 "TARGET_CMOVE && TARGET_80387
12903 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12904 && FLOAT_MODE_P (GET_MODE (operands[1]))
12905 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12906 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12907 "#")
12908
12909 (define_insn "*fp_jcc_2_sse"
12910 [(set (pc)
12911 (if_then_else (match_operator 0 "comparison_operator"
12912 [(match_operand 1 "register_operand" "f#x,x#f")
12913 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12914 (pc)
12915 (label_ref (match_operand 3 "" ""))))
12916 (clobber (reg:CCFP FPSR_REG))
12917 (clobber (reg:CCFP FLAGS_REG))]
12918 "TARGET_80387
12919 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12920 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12921 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12922 "#")
12923
12924 (define_insn "*fp_jcc_2_sse_only"
12925 [(set (pc)
12926 (if_then_else (match_operator 0 "comparison_operator"
12927 [(match_operand 1 "register_operand" "x")
12928 (match_operand 2 "nonimmediate_operand" "xm")])
12929 (pc)
12930 (label_ref (match_operand 3 "" ""))))
12931 (clobber (reg:CCFP FPSR_REG))
12932 (clobber (reg:CCFP FLAGS_REG))]
12933 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12934 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12935 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12936 "#")
12937
12938 (define_insn "*fp_jcc_3"
12939 [(set (pc)
12940 (if_then_else (match_operator 0 "comparison_operator"
12941 [(match_operand 1 "register_operand" "f")
12942 (match_operand 2 "nonimmediate_operand" "fm")])
12943 (label_ref (match_operand 3 "" ""))
12944 (pc)))
12945 (clobber (reg:CCFP FPSR_REG))
12946 (clobber (reg:CCFP FLAGS_REG))
12947 (clobber (match_scratch:HI 4 "=a"))]
12948 "TARGET_80387
12949 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12950 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12951 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12952 && SELECT_CC_MODE (GET_CODE (operands[0]),
12953 operands[1], operands[2]) == CCFPmode
12954 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12955 "#")
12956
12957 (define_insn "*fp_jcc_4"
12958 [(set (pc)
12959 (if_then_else (match_operator 0 "comparison_operator"
12960 [(match_operand 1 "register_operand" "f")
12961 (match_operand 2 "nonimmediate_operand" "fm")])
12962 (pc)
12963 (label_ref (match_operand 3 "" ""))))
12964 (clobber (reg:CCFP FPSR_REG))
12965 (clobber (reg:CCFP FLAGS_REG))
12966 (clobber (match_scratch:HI 4 "=a"))]
12967 "TARGET_80387
12968 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12969 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12970 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12971 && SELECT_CC_MODE (GET_CODE (operands[0]),
12972 operands[1], operands[2]) == CCFPmode
12973 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12974 "#")
12975
12976 (define_insn "*fp_jcc_5"
12977 [(set (pc)
12978 (if_then_else (match_operator 0 "comparison_operator"
12979 [(match_operand 1 "register_operand" "f")
12980 (match_operand 2 "register_operand" "f")])
12981 (label_ref (match_operand 3 "" ""))
12982 (pc)))
12983 (clobber (reg:CCFP FPSR_REG))
12984 (clobber (reg:CCFP FLAGS_REG))
12985 (clobber (match_scratch:HI 4 "=a"))]
12986 "TARGET_80387
12987 && FLOAT_MODE_P (GET_MODE (operands[1]))
12988 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12989 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12990 "#")
12991
12992 (define_insn "*fp_jcc_6"
12993 [(set (pc)
12994 (if_then_else (match_operator 0 "comparison_operator"
12995 [(match_operand 1 "register_operand" "f")
12996 (match_operand 2 "register_operand" "f")])
12997 (pc)
12998 (label_ref (match_operand 3 "" ""))))
12999 (clobber (reg:CCFP FPSR_REG))
13000 (clobber (reg:CCFP FLAGS_REG))
13001 (clobber (match_scratch:HI 4 "=a"))]
13002 "TARGET_80387
13003 && FLOAT_MODE_P (GET_MODE (operands[1]))
13004 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13005 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13006 "#")
13007
13008 (define_insn "*fp_jcc_7"
13009 [(set (pc)
13010 (if_then_else (match_operator 0 "comparison_operator"
13011 [(match_operand 1 "register_operand" "f")
13012 (match_operand 2 "const_double_operand" "C")])
13013 (label_ref (match_operand 3 "" ""))
13014 (pc)))
13015 (clobber (reg:CCFP FPSR_REG))
13016 (clobber (reg:CCFP FLAGS_REG))
13017 (clobber (match_scratch:HI 4 "=a"))]
13018 "TARGET_80387
13019 && FLOAT_MODE_P (GET_MODE (operands[1]))
13020 && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13021 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13022 && SELECT_CC_MODE (GET_CODE (operands[0]),
13023 operands[1], operands[2]) == CCFPmode
13024 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13025 "#")
13026
13027 ;; The order of operands in *fp_jcc_8 is forced by combine in
13028 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13029 ;; with a precedence over other operators and is always put in the first
13030 ;; place. Swap condition and operands to match ficom instruction.
13031
13032 (define_insn "*fp_jcc_8"
13033 [(set (pc)
13034 (if_then_else (match_operator 0 "comparison_operator"
13035 [(match_operator 1 "float_operator"
13036 [(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
13037 (match_operand 3 "register_operand" "f,f")])
13038 (label_ref (match_operand 4 "" ""))
13039 (pc)))
13040 (clobber (reg:CCFP FPSR_REG))
13041 (clobber (reg:CCFP FLAGS_REG))
13042 (clobber (match_scratch:HI 5 "=a,a"))]
13043 "TARGET_80387 && TARGET_USE_FIOP
13044 && FLOAT_MODE_P (GET_MODE (operands[3]))
13045 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13046 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13047 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13048 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13049 "#")
13050
13051 (define_split
13052 [(set (pc)
13053 (if_then_else (match_operator 0 "comparison_operator"
13054 [(match_operand 1 "register_operand" "")
13055 (match_operand 2 "nonimmediate_operand" "")])
13056 (match_operand 3 "" "")
13057 (match_operand 4 "" "")))
13058 (clobber (reg:CCFP FPSR_REG))
13059 (clobber (reg:CCFP FLAGS_REG))]
13060 "reload_completed"
13061 [(const_int 0)]
13062 {
13063 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13064 operands[3], operands[4], NULL_RTX, NULL_RTX);
13065 DONE;
13066 })
13067
13068 (define_split
13069 [(set (pc)
13070 (if_then_else (match_operator 0 "comparison_operator"
13071 [(match_operand 1 "register_operand" "")
13072 (match_operand 2 "general_operand" "")])
13073 (match_operand 3 "" "")
13074 (match_operand 4 "" "")))
13075 (clobber (reg:CCFP FPSR_REG))
13076 (clobber (reg:CCFP FLAGS_REG))
13077 (clobber (match_scratch:HI 5 "=a"))]
13078 "reload_completed"
13079 [(const_int 0)]
13080 {
13081 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13082 operands[3], operands[4], operands[5], NULL_RTX);
13083 DONE;
13084 })
13085
13086 (define_split
13087 [(set (pc)
13088 (if_then_else (match_operator 0 "comparison_operator"
13089 [(match_operator 1 "float_operator"
13090 [(match_operand:SI 2 "memory_operand" "")])
13091 (match_operand 3 "register_operand" "")])
13092 (match_operand 4 "" "")
13093 (match_operand 5 "" "")))
13094 (clobber (reg:CCFP FPSR_REG))
13095 (clobber (reg:CCFP FLAGS_REG))
13096 (clobber (match_scratch:HI 6 "=a"))]
13097 "reload_completed"
13098 [(const_int 0)]
13099 {
13100 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13101 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13102 operands[3], operands[7],
13103 operands[4], operands[5], operands[6], NULL_RTX);
13104 DONE;
13105 })
13106
13107 ;; %%% Kill this when reload knows how to do it.
13108 (define_split
13109 [(set (pc)
13110 (if_then_else (match_operator 0 "comparison_operator"
13111 [(match_operator 1 "float_operator"
13112 [(match_operand:SI 2 "register_operand" "")])
13113 (match_operand 3 "register_operand" "")])
13114 (match_operand 4 "" "")
13115 (match_operand 5 "" "")))
13116 (clobber (reg:CCFP FPSR_REG))
13117 (clobber (reg:CCFP FLAGS_REG))
13118 (clobber (match_scratch:HI 6 "=a"))]
13119 "reload_completed"
13120 [(const_int 0)]
13121 {
13122 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13123 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13124 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13125 operands[3], operands[7],
13126 operands[4], operands[5], operands[6], operands[2]);
13127 DONE;
13128 })
13129 \f
13130 ;; Unconditional and other jump instructions
13131
13132 (define_insn "jump"
13133 [(set (pc)
13134 (label_ref (match_operand 0 "" "")))]
13135 ""
13136 "jmp\t%l0"
13137 [(set_attr "type" "ibr")
13138 (set (attr "length")
13139 (if_then_else (and (ge (minus (match_dup 0) (pc))
13140 (const_int -126))
13141 (lt (minus (match_dup 0) (pc))
13142 (const_int 128)))
13143 (const_int 2)
13144 (const_int 5)))
13145 (set_attr "modrm" "0")])
13146
13147 (define_expand "indirect_jump"
13148 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13149 ""
13150 "")
13151
13152 (define_insn "*indirect_jump"
13153 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13154 "!TARGET_64BIT"
13155 "jmp\t%A0"
13156 [(set_attr "type" "ibr")
13157 (set_attr "length_immediate" "0")])
13158
13159 (define_insn "*indirect_jump_rtx64"
13160 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13161 "TARGET_64BIT"
13162 "jmp\t%A0"
13163 [(set_attr "type" "ibr")
13164 (set_attr "length_immediate" "0")])
13165
13166 (define_expand "tablejump"
13167 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13168 (use (label_ref (match_operand 1 "" "")))])]
13169 ""
13170 {
13171 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13172 relative. Convert the relative address to an absolute address. */
13173 if (flag_pic)
13174 {
13175 rtx op0, op1;
13176 enum rtx_code code;
13177
13178 if (TARGET_64BIT)
13179 {
13180 code = PLUS;
13181 op0 = operands[0];
13182 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13183 }
13184 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13185 {
13186 code = PLUS;
13187 op0 = operands[0];
13188 op1 = pic_offset_table_rtx;
13189 }
13190 else
13191 {
13192 code = MINUS;
13193 op0 = pic_offset_table_rtx;
13194 op1 = operands[0];
13195 }
13196
13197 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13198 OPTAB_DIRECT);
13199 }
13200 })
13201
13202 (define_insn "*tablejump_1"
13203 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13204 (use (label_ref (match_operand 1 "" "")))]
13205 "!TARGET_64BIT"
13206 "jmp\t%A0"
13207 [(set_attr "type" "ibr")
13208 (set_attr "length_immediate" "0")])
13209
13210 (define_insn "*tablejump_1_rtx64"
13211 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13212 (use (label_ref (match_operand 1 "" "")))]
13213 "TARGET_64BIT"
13214 "jmp\t%A0"
13215 [(set_attr "type" "ibr")
13216 (set_attr "length_immediate" "0")])
13217 \f
13218 ;; Loop instruction
13219 ;;
13220 ;; This is all complicated by the fact that since this is a jump insn
13221 ;; we must handle our own reloads.
13222
13223 (define_expand "doloop_end"
13224 [(use (match_operand 0 "" "")) ; loop pseudo
13225 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13226 (use (match_operand 2 "" "")) ; max iterations
13227 (use (match_operand 3 "" "")) ; loop level
13228 (use (match_operand 4 "" ""))] ; label
13229 "!TARGET_64BIT && TARGET_USE_LOOP"
13230 "
13231 {
13232 /* Only use cloop on innermost loops. */
13233 if (INTVAL (operands[3]) > 1)
13234 FAIL;
13235 if (GET_MODE (operands[0]) != SImode)
13236 FAIL;
13237 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13238 operands[0]));
13239 DONE;
13240 }")
13241
13242 (define_insn "doloop_end_internal"
13243 [(set (pc)
13244 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13245 (const_int 1))
13246 (label_ref (match_operand 0 "" ""))
13247 (pc)))
13248 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13249 (plus:SI (match_dup 1)
13250 (const_int -1)))
13251 (clobber (match_scratch:SI 3 "=X,X,r"))
13252 (clobber (reg:CC FLAGS_REG))]
13253 "!TARGET_64BIT && TARGET_USE_LOOP
13254 && (reload_in_progress || reload_completed
13255 || register_operand (operands[2], VOIDmode))"
13256 {
13257 if (which_alternative != 0)
13258 return "#";
13259 if (get_attr_length (insn) == 2)
13260 return "%+loop\t%l0";
13261 else
13262 return "dec{l}\t%1\;%+jne\t%l0";
13263 }
13264 [(set (attr "length")
13265 (if_then_else (and (eq_attr "alternative" "0")
13266 (and (ge (minus (match_dup 0) (pc))
13267 (const_int -126))
13268 (lt (minus (match_dup 0) (pc))
13269 (const_int 128))))
13270 (const_int 2)
13271 (const_int 16)))
13272 ;; We don't know the type before shorten branches. Optimistically expect
13273 ;; the loop instruction to match.
13274 (set (attr "type") (const_string "ibr"))])
13275
13276 (define_split
13277 [(set (pc)
13278 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13279 (const_int 1))
13280 (match_operand 0 "" "")
13281 (pc)))
13282 (set (match_dup 1)
13283 (plus:SI (match_dup 1)
13284 (const_int -1)))
13285 (clobber (match_scratch:SI 2 ""))
13286 (clobber (reg:CC FLAGS_REG))]
13287 "!TARGET_64BIT && TARGET_USE_LOOP
13288 && reload_completed
13289 && REGNO (operands[1]) != 2"
13290 [(parallel [(set (reg:CCZ FLAGS_REG)
13291 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13292 (const_int 0)))
13293 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13294 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13295 (match_dup 0)
13296 (pc)))]
13297 "")
13298
13299 (define_split
13300 [(set (pc)
13301 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13302 (const_int 1))
13303 (match_operand 0 "" "")
13304 (pc)))
13305 (set (match_operand:SI 2 "nonimmediate_operand" "")
13306 (plus:SI (match_dup 1)
13307 (const_int -1)))
13308 (clobber (match_scratch:SI 3 ""))
13309 (clobber (reg:CC FLAGS_REG))]
13310 "!TARGET_64BIT && TARGET_USE_LOOP
13311 && reload_completed
13312 && (! REG_P (operands[2])
13313 || ! rtx_equal_p (operands[1], operands[2]))"
13314 [(set (match_dup 3) (match_dup 1))
13315 (parallel [(set (reg:CCZ FLAGS_REG)
13316 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13317 (const_int 0)))
13318 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13319 (set (match_dup 2) (match_dup 3))
13320 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13321 (match_dup 0)
13322 (pc)))]
13323 "")
13324
13325 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13326
13327 (define_peephole2
13328 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13329 (set (match_operand:QI 1 "register_operand" "")
13330 (match_operator:QI 2 "ix86_comparison_operator"
13331 [(reg FLAGS_REG) (const_int 0)]))
13332 (set (match_operand 3 "q_regs_operand" "")
13333 (zero_extend (match_dup 1)))]
13334 "(peep2_reg_dead_p (3, operands[1])
13335 || operands_match_p (operands[1], operands[3]))
13336 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13337 [(set (match_dup 4) (match_dup 0))
13338 (set (strict_low_part (match_dup 5))
13339 (match_dup 2))]
13340 {
13341 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13342 operands[5] = gen_lowpart (QImode, operands[3]);
13343 ix86_expand_clear (operands[3]);
13344 })
13345
13346 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13347
13348 (define_peephole2
13349 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13350 (set (match_operand:QI 1 "register_operand" "")
13351 (match_operator:QI 2 "ix86_comparison_operator"
13352 [(reg FLAGS_REG) (const_int 0)]))
13353 (parallel [(set (match_operand 3 "q_regs_operand" "")
13354 (zero_extend (match_dup 1)))
13355 (clobber (reg:CC FLAGS_REG))])]
13356 "(peep2_reg_dead_p (3, operands[1])
13357 || operands_match_p (operands[1], operands[3]))
13358 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13359 [(set (match_dup 4) (match_dup 0))
13360 (set (strict_low_part (match_dup 5))
13361 (match_dup 2))]
13362 {
13363 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13364 operands[5] = gen_lowpart (QImode, operands[3]);
13365 ix86_expand_clear (operands[3]);
13366 })
13367 \f
13368 ;; Call instructions.
13369
13370 ;; The predicates normally associated with named expanders are not properly
13371 ;; checked for calls. This is a bug in the generic code, but it isn't that
13372 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13373
13374 ;; Call subroutine returning no value.
13375
13376 (define_expand "call_pop"
13377 [(parallel [(call (match_operand:QI 0 "" "")
13378 (match_operand:SI 1 "" ""))
13379 (set (reg:SI SP_REG)
13380 (plus:SI (reg:SI SP_REG)
13381 (match_operand:SI 3 "" "")))])]
13382 "!TARGET_64BIT"
13383 {
13384 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13385 DONE;
13386 })
13387
13388 (define_insn "*call_pop_0"
13389 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13390 (match_operand:SI 1 "" ""))
13391 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13392 (match_operand:SI 2 "immediate_operand" "")))]
13393 "!TARGET_64BIT"
13394 {
13395 if (SIBLING_CALL_P (insn))
13396 return "jmp\t%P0";
13397 else
13398 return "call\t%P0";
13399 }
13400 [(set_attr "type" "call")])
13401
13402 (define_insn "*call_pop_1"
13403 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13404 (match_operand:SI 1 "" ""))
13405 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13406 (match_operand:SI 2 "immediate_operand" "i")))]
13407 "!TARGET_64BIT"
13408 {
13409 if (constant_call_address_operand (operands[0], Pmode))
13410 {
13411 if (SIBLING_CALL_P (insn))
13412 return "jmp\t%P0";
13413 else
13414 return "call\t%P0";
13415 }
13416 if (SIBLING_CALL_P (insn))
13417 return "jmp\t%A0";
13418 else
13419 return "call\t%A0";
13420 }
13421 [(set_attr "type" "call")])
13422
13423 (define_expand "call"
13424 [(call (match_operand:QI 0 "" "")
13425 (match_operand 1 "" ""))
13426 (use (match_operand 2 "" ""))]
13427 ""
13428 {
13429 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13430 DONE;
13431 })
13432
13433 (define_expand "sibcall"
13434 [(call (match_operand:QI 0 "" "")
13435 (match_operand 1 "" ""))
13436 (use (match_operand 2 "" ""))]
13437 ""
13438 {
13439 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13440 DONE;
13441 })
13442
13443 (define_insn "*call_0"
13444 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13445 (match_operand 1 "" ""))]
13446 ""
13447 {
13448 if (SIBLING_CALL_P (insn))
13449 return "jmp\t%P0";
13450 else
13451 return "call\t%P0";
13452 }
13453 [(set_attr "type" "call")])
13454
13455 (define_insn "*call_1"
13456 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13457 (match_operand 1 "" ""))]
13458 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13459 {
13460 if (constant_call_address_operand (operands[0], Pmode))
13461 return "call\t%P0";
13462 return "call\t%A0";
13463 }
13464 [(set_attr "type" "call")])
13465
13466 (define_insn "*sibcall_1"
13467 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13468 (match_operand 1 "" ""))]
13469 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13470 {
13471 if (constant_call_address_operand (operands[0], Pmode))
13472 return "jmp\t%P0";
13473 return "jmp\t%A0";
13474 }
13475 [(set_attr "type" "call")])
13476
13477 (define_insn "*call_1_rex64"
13478 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13479 (match_operand 1 "" ""))]
13480 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13481 {
13482 if (constant_call_address_operand (operands[0], Pmode))
13483 return "call\t%P0";
13484 return "call\t%A0";
13485 }
13486 [(set_attr "type" "call")])
13487
13488 (define_insn "*sibcall_1_rex64"
13489 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13490 (match_operand 1 "" ""))]
13491 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13492 "jmp\t%P0"
13493 [(set_attr "type" "call")])
13494
13495 (define_insn "*sibcall_1_rex64_v"
13496 [(call (mem:QI (reg:DI 40))
13497 (match_operand 0 "" ""))]
13498 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13499 "jmp\t*%%r11"
13500 [(set_attr "type" "call")])
13501
13502
13503 ;; Call subroutine, returning value in operand 0
13504
13505 (define_expand "call_value_pop"
13506 [(parallel [(set (match_operand 0 "" "")
13507 (call (match_operand:QI 1 "" "")
13508 (match_operand:SI 2 "" "")))
13509 (set (reg:SI SP_REG)
13510 (plus:SI (reg:SI SP_REG)
13511 (match_operand:SI 4 "" "")))])]
13512 "!TARGET_64BIT"
13513 {
13514 ix86_expand_call (operands[0], operands[1], operands[2],
13515 operands[3], operands[4], 0);
13516 DONE;
13517 })
13518
13519 (define_expand "call_value"
13520 [(set (match_operand 0 "" "")
13521 (call (match_operand:QI 1 "" "")
13522 (match_operand:SI 2 "" "")))
13523 (use (match_operand:SI 3 "" ""))]
13524 ;; Operand 2 not used on the i386.
13525 ""
13526 {
13527 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13528 DONE;
13529 })
13530
13531 (define_expand "sibcall_value"
13532 [(set (match_operand 0 "" "")
13533 (call (match_operand:QI 1 "" "")
13534 (match_operand:SI 2 "" "")))
13535 (use (match_operand:SI 3 "" ""))]
13536 ;; Operand 2 not used on the i386.
13537 ""
13538 {
13539 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13540 DONE;
13541 })
13542
13543 ;; Call subroutine returning any type.
13544
13545 (define_expand "untyped_call"
13546 [(parallel [(call (match_operand 0 "" "")
13547 (const_int 0))
13548 (match_operand 1 "" "")
13549 (match_operand 2 "" "")])]
13550 ""
13551 {
13552 int i;
13553
13554 /* In order to give reg-stack an easier job in validating two
13555 coprocessor registers as containing a possible return value,
13556 simply pretend the untyped call returns a complex long double
13557 value. */
13558
13559 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13560 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13561 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13562 NULL, 0);
13563
13564 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13565 {
13566 rtx set = XVECEXP (operands[2], 0, i);
13567 emit_move_insn (SET_DEST (set), SET_SRC (set));
13568 }
13569
13570 /* The optimizer does not know that the call sets the function value
13571 registers we stored in the result block. We avoid problems by
13572 claiming that all hard registers are used and clobbered at this
13573 point. */
13574 emit_insn (gen_blockage (const0_rtx));
13575
13576 DONE;
13577 })
13578 \f
13579 ;; Prologue and epilogue instructions
13580
13581 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13582 ;; all of memory. This blocks insns from being moved across this point.
13583
13584 (define_insn "blockage"
13585 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13586 ""
13587 ""
13588 [(set_attr "length" "0")])
13589
13590 ;; Insn emitted into the body of a function to return from a function.
13591 ;; This is only done if the function's epilogue is known to be simple.
13592 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13593
13594 (define_expand "return"
13595 [(return)]
13596 "ix86_can_use_return_insn_p ()"
13597 {
13598 if (current_function_pops_args)
13599 {
13600 rtx popc = GEN_INT (current_function_pops_args);
13601 emit_jump_insn (gen_return_pop_internal (popc));
13602 DONE;
13603 }
13604 })
13605
13606 (define_insn "return_internal"
13607 [(return)]
13608 "reload_completed"
13609 "ret"
13610 [(set_attr "length" "1")
13611 (set_attr "length_immediate" "0")
13612 (set_attr "modrm" "0")])
13613
13614 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13615 ;; instruction Athlon and K8 have.
13616
13617 (define_insn "return_internal_long"
13618 [(return)
13619 (unspec [(const_int 0)] UNSPEC_REP)]
13620 "reload_completed"
13621 "rep {;} ret"
13622 [(set_attr "length" "1")
13623 (set_attr "length_immediate" "0")
13624 (set_attr "prefix_rep" "1")
13625 (set_attr "modrm" "0")])
13626
13627 (define_insn "return_pop_internal"
13628 [(return)
13629 (use (match_operand:SI 0 "const_int_operand" ""))]
13630 "reload_completed"
13631 "ret\t%0"
13632 [(set_attr "length" "3")
13633 (set_attr "length_immediate" "2")
13634 (set_attr "modrm" "0")])
13635
13636 (define_insn "return_indirect_internal"
13637 [(return)
13638 (use (match_operand:SI 0 "register_operand" "r"))]
13639 "reload_completed"
13640 "jmp\t%A0"
13641 [(set_attr "type" "ibr")
13642 (set_attr "length_immediate" "0")])
13643
13644 (define_insn "nop"
13645 [(const_int 0)]
13646 ""
13647 "nop"
13648 [(set_attr "length" "1")
13649 (set_attr "length_immediate" "0")
13650 (set_attr "modrm" "0")])
13651
13652 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13653 ;; branch prediction penalty for the third jump in a 16-byte
13654 ;; block on K8.
13655
13656 (define_insn "align"
13657 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13658 ""
13659 {
13660 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13661 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13662 #else
13663 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13664 The align insn is used to avoid 3 jump instructions in the row to improve
13665 branch prediction and the benefits hardly outweight the cost of extra 8
13666 nops on the average inserted by full alignment pseudo operation. */
13667 #endif
13668 return "";
13669 }
13670 [(set_attr "length" "16")])
13671
13672 (define_expand "prologue"
13673 [(const_int 1)]
13674 ""
13675 "ix86_expand_prologue (); DONE;")
13676
13677 (define_insn "set_got"
13678 [(set (match_operand:SI 0 "register_operand" "=r")
13679 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13680 (clobber (reg:CC FLAGS_REG))]
13681 "!TARGET_64BIT"
13682 { return output_set_got (operands[0]); }
13683 [(set_attr "type" "multi")
13684 (set_attr "length" "12")])
13685
13686 (define_expand "epilogue"
13687 [(const_int 1)]
13688 ""
13689 "ix86_expand_epilogue (1); DONE;")
13690
13691 (define_expand "sibcall_epilogue"
13692 [(const_int 1)]
13693 ""
13694 "ix86_expand_epilogue (0); DONE;")
13695
13696 (define_expand "eh_return"
13697 [(use (match_operand 0 "register_operand" ""))]
13698 ""
13699 {
13700 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13701
13702 /* Tricky bit: we write the address of the handler to which we will
13703 be returning into someone else's stack frame, one word below the
13704 stack address we wish to restore. */
13705 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13706 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13707 tmp = gen_rtx_MEM (Pmode, tmp);
13708 emit_move_insn (tmp, ra);
13709
13710 if (Pmode == SImode)
13711 emit_jump_insn (gen_eh_return_si (sa));
13712 else
13713 emit_jump_insn (gen_eh_return_di (sa));
13714 emit_barrier ();
13715 DONE;
13716 })
13717
13718 (define_insn_and_split "eh_return_si"
13719 [(set (pc)
13720 (unspec [(match_operand:SI 0 "register_operand" "c")]
13721 UNSPEC_EH_RETURN))]
13722 "!TARGET_64BIT"
13723 "#"
13724 "reload_completed"
13725 [(const_int 1)]
13726 "ix86_expand_epilogue (2); DONE;")
13727
13728 (define_insn_and_split "eh_return_di"
13729 [(set (pc)
13730 (unspec [(match_operand:DI 0 "register_operand" "c")]
13731 UNSPEC_EH_RETURN))]
13732 "TARGET_64BIT"
13733 "#"
13734 "reload_completed"
13735 [(const_int 1)]
13736 "ix86_expand_epilogue (2); DONE;")
13737
13738 (define_insn "leave"
13739 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13740 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13741 (clobber (mem:BLK (scratch)))]
13742 "!TARGET_64BIT"
13743 "leave"
13744 [(set_attr "type" "leave")])
13745
13746 (define_insn "leave_rex64"
13747 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13748 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13749 (clobber (mem:BLK (scratch)))]
13750 "TARGET_64BIT"
13751 "leave"
13752 [(set_attr "type" "leave")])
13753 \f
13754 (define_expand "ffssi2"
13755 [(parallel
13756 [(set (match_operand:SI 0 "register_operand" "")
13757 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13758 (clobber (match_scratch:SI 2 ""))
13759 (clobber (reg:CC FLAGS_REG))])]
13760 ""
13761 "")
13762
13763 (define_insn_and_split "*ffs_cmove"
13764 [(set (match_operand:SI 0 "register_operand" "=r")
13765 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13766 (clobber (match_scratch:SI 2 "=&r"))
13767 (clobber (reg:CC FLAGS_REG))]
13768 "TARGET_CMOVE"
13769 "#"
13770 "&& reload_completed"
13771 [(set (match_dup 2) (const_int -1))
13772 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13773 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13774 (set (match_dup 0) (if_then_else:SI
13775 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13776 (match_dup 2)
13777 (match_dup 0)))
13778 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13779 (clobber (reg:CC FLAGS_REG))])]
13780 "")
13781
13782 (define_insn_and_split "*ffs_no_cmove"
13783 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13784 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13785 (clobber (match_scratch:SI 2 "=&q"))
13786 (clobber (reg:CC FLAGS_REG))]
13787 ""
13788 "#"
13789 "reload_completed"
13790 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13791 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13792 (set (strict_low_part (match_dup 3))
13793 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13794 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13795 (clobber (reg:CC FLAGS_REG))])
13796 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13797 (clobber (reg:CC FLAGS_REG))])
13798 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13799 (clobber (reg:CC FLAGS_REG))])]
13800 {
13801 operands[3] = gen_lowpart (QImode, operands[2]);
13802 ix86_expand_clear (operands[2]);
13803 })
13804
13805 (define_insn "*ffssi_1"
13806 [(set (reg:CCZ FLAGS_REG)
13807 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13808 (const_int 0)))
13809 (set (match_operand:SI 0 "register_operand" "=r")
13810 (ctz:SI (match_dup 1)))]
13811 ""
13812 "bsf{l}\t{%1, %0|%0, %1}"
13813 [(set_attr "prefix_0f" "1")])
13814
13815 (define_expand "ffsdi2"
13816 [(parallel
13817 [(set (match_operand:DI 0 "register_operand" "")
13818 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13819 (clobber (match_scratch:DI 2 ""))
13820 (clobber (reg:CC FLAGS_REG))])]
13821 "TARGET_64BIT && TARGET_CMOVE"
13822 "")
13823
13824 (define_insn_and_split "*ffs_rex64"
13825 [(set (match_operand:DI 0 "register_operand" "=r")
13826 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13827 (clobber (match_scratch:DI 2 "=&r"))
13828 (clobber (reg:CC FLAGS_REG))]
13829 "TARGET_64BIT && TARGET_CMOVE"
13830 "#"
13831 "&& reload_completed"
13832 [(set (match_dup 2) (const_int -1))
13833 (parallel [(set (reg:CCZ FLAGS_REG)
13834 (compare:CCZ (match_dup 1) (const_int 0)))
13835 (set (match_dup 0) (ctz:DI (match_dup 1)))])
13836 (set (match_dup 0) (if_then_else:DI
13837 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13838 (match_dup 2)
13839 (match_dup 0)))
13840 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13841 (clobber (reg:CC FLAGS_REG))])]
13842 "")
13843
13844 (define_insn "*ffsdi_1"
13845 [(set (reg:CCZ FLAGS_REG)
13846 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13847 (const_int 0)))
13848 (set (match_operand:DI 0 "register_operand" "=r")
13849 (ctz:DI (match_dup 1)))]
13850 "TARGET_64BIT"
13851 "bsf{q}\t{%1, %0|%0, %1}"
13852 [(set_attr "prefix_0f" "1")])
13853
13854 (define_insn "ctzsi2"
13855 [(set (match_operand:SI 0 "register_operand" "=r")
13856 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13857 (clobber (reg:CC FLAGS_REG))]
13858 ""
13859 "bsf{l}\t{%1, %0|%0, %1}"
13860 [(set_attr "prefix_0f" "1")])
13861
13862 (define_insn "ctzdi2"
13863 [(set (match_operand:DI 0 "register_operand" "=r")
13864 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13865 (clobber (reg:CC FLAGS_REG))]
13866 "TARGET_64BIT"
13867 "bsf{q}\t{%1, %0|%0, %1}"
13868 [(set_attr "prefix_0f" "1")])
13869
13870 (define_expand "clzsi2"
13871 [(parallel
13872 [(set (match_operand:SI 0 "register_operand" "")
13873 (minus:SI (const_int 31)
13874 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13875 (clobber (reg:CC FLAGS_REG))])
13876 (parallel
13877 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13878 (clobber (reg:CC FLAGS_REG))])]
13879 ""
13880 "")
13881
13882 (define_insn "*bsr"
13883 [(set (match_operand:SI 0 "register_operand" "=r")
13884 (minus:SI (const_int 31)
13885 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13886 (clobber (reg:CC FLAGS_REG))]
13887 ""
13888 "bsr{l}\t{%1, %0|%0, %1}"
13889 [(set_attr "prefix_0f" "1")])
13890
13891 (define_expand "clzdi2"
13892 [(parallel
13893 [(set (match_operand:DI 0 "register_operand" "")
13894 (minus:DI (const_int 63)
13895 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13896 (clobber (reg:CC FLAGS_REG))])
13897 (parallel
13898 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13899 (clobber (reg:CC FLAGS_REG))])]
13900 "TARGET_64BIT"
13901 "")
13902
13903 (define_insn "*bsr_rex64"
13904 [(set (match_operand:DI 0 "register_operand" "=r")
13905 (minus:DI (const_int 63)
13906 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13907 (clobber (reg:CC FLAGS_REG))]
13908 "TARGET_64BIT"
13909 "bsr{q}\t{%1, %0|%0, %1}"
13910 [(set_attr "prefix_0f" "1")])
13911 \f
13912 ;; Thread-local storage patterns for ELF.
13913 ;;
13914 ;; Note that these code sequences must appear exactly as shown
13915 ;; in order to allow linker relaxation.
13916
13917 (define_insn "*tls_global_dynamic_32_gnu"
13918 [(set (match_operand:SI 0 "register_operand" "=a")
13919 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13920 (match_operand:SI 2 "tls_symbolic_operand" "")
13921 (match_operand:SI 3 "call_insn_operand" "")]
13922 UNSPEC_TLS_GD))
13923 (clobber (match_scratch:SI 4 "=d"))
13924 (clobber (match_scratch:SI 5 "=c"))
13925 (clobber (reg:CC FLAGS_REG))]
13926 "!TARGET_64BIT && TARGET_GNU_TLS"
13927 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13928 [(set_attr "type" "multi")
13929 (set_attr "length" "12")])
13930
13931 (define_insn "*tls_global_dynamic_32_sun"
13932 [(set (match_operand:SI 0 "register_operand" "=a")
13933 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13934 (match_operand:SI 2 "tls_symbolic_operand" "")
13935 (match_operand:SI 3 "call_insn_operand" "")]
13936 UNSPEC_TLS_GD))
13937 (clobber (match_scratch:SI 4 "=d"))
13938 (clobber (match_scratch:SI 5 "=c"))
13939 (clobber (reg:CC FLAGS_REG))]
13940 "!TARGET_64BIT && TARGET_SUN_TLS"
13941 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13942 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13943 [(set_attr "type" "multi")
13944 (set_attr "length" "14")])
13945
13946 (define_expand "tls_global_dynamic_32"
13947 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13948 (unspec:SI
13949 [(match_dup 2)
13950 (match_operand:SI 1 "tls_symbolic_operand" "")
13951 (match_dup 3)]
13952 UNSPEC_TLS_GD))
13953 (clobber (match_scratch:SI 4 ""))
13954 (clobber (match_scratch:SI 5 ""))
13955 (clobber (reg:CC FLAGS_REG))])]
13956 ""
13957 {
13958 if (flag_pic)
13959 operands[2] = pic_offset_table_rtx;
13960 else
13961 {
13962 operands[2] = gen_reg_rtx (Pmode);
13963 emit_insn (gen_set_got (operands[2]));
13964 }
13965 operands[3] = ix86_tls_get_addr ();
13966 })
13967
13968 (define_insn "*tls_global_dynamic_64"
13969 [(set (match_operand:DI 0 "register_operand" "=a")
13970 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13971 (match_operand:DI 3 "" "")))
13972 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13973 UNSPEC_TLS_GD)]
13974 "TARGET_64BIT"
13975 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13976 [(set_attr "type" "multi")
13977 (set_attr "length" "16")])
13978
13979 (define_expand "tls_global_dynamic_64"
13980 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13981 (call (mem:QI (match_dup 2)) (const_int 0)))
13982 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13983 UNSPEC_TLS_GD)])]
13984 ""
13985 {
13986 operands[2] = ix86_tls_get_addr ();
13987 })
13988
13989 (define_insn "*tls_local_dynamic_base_32_gnu"
13990 [(set (match_operand:SI 0 "register_operand" "=a")
13991 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13992 (match_operand:SI 2 "call_insn_operand" "")]
13993 UNSPEC_TLS_LD_BASE))
13994 (clobber (match_scratch:SI 3 "=d"))
13995 (clobber (match_scratch:SI 4 "=c"))
13996 (clobber (reg:CC FLAGS_REG))]
13997 "!TARGET_64BIT && TARGET_GNU_TLS"
13998 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13999 [(set_attr "type" "multi")
14000 (set_attr "length" "11")])
14001
14002 (define_insn "*tls_local_dynamic_base_32_sun"
14003 [(set (match_operand:SI 0 "register_operand" "=a")
14004 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14005 (match_operand:SI 2 "call_insn_operand" "")]
14006 UNSPEC_TLS_LD_BASE))
14007 (clobber (match_scratch:SI 3 "=d"))
14008 (clobber (match_scratch:SI 4 "=c"))
14009 (clobber (reg:CC FLAGS_REG))]
14010 "!TARGET_64BIT && TARGET_SUN_TLS"
14011 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14012 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14013 [(set_attr "type" "multi")
14014 (set_attr "length" "13")])
14015
14016 (define_expand "tls_local_dynamic_base_32"
14017 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14018 (unspec:SI [(match_dup 1) (match_dup 2)]
14019 UNSPEC_TLS_LD_BASE))
14020 (clobber (match_scratch:SI 3 ""))
14021 (clobber (match_scratch:SI 4 ""))
14022 (clobber (reg:CC FLAGS_REG))])]
14023 ""
14024 {
14025 if (flag_pic)
14026 operands[1] = pic_offset_table_rtx;
14027 else
14028 {
14029 operands[1] = gen_reg_rtx (Pmode);
14030 emit_insn (gen_set_got (operands[1]));
14031 }
14032 operands[2] = ix86_tls_get_addr ();
14033 })
14034
14035 (define_insn "*tls_local_dynamic_base_64"
14036 [(set (match_operand:DI 0 "register_operand" "=a")
14037 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14038 (match_operand:DI 2 "" "")))
14039 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14040 "TARGET_64BIT"
14041 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14042 [(set_attr "type" "multi")
14043 (set_attr "length" "12")])
14044
14045 (define_expand "tls_local_dynamic_base_64"
14046 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14047 (call (mem:QI (match_dup 1)) (const_int 0)))
14048 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14049 ""
14050 {
14051 operands[1] = ix86_tls_get_addr ();
14052 })
14053
14054 ;; Local dynamic of a single variable is a lose. Show combine how
14055 ;; to convert that back to global dynamic.
14056
14057 (define_insn_and_split "*tls_local_dynamic_32_once"
14058 [(set (match_operand:SI 0 "register_operand" "=a")
14059 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14060 (match_operand:SI 2 "call_insn_operand" "")]
14061 UNSPEC_TLS_LD_BASE)
14062 (const:SI (unspec:SI
14063 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14064 UNSPEC_DTPOFF))))
14065 (clobber (match_scratch:SI 4 "=d"))
14066 (clobber (match_scratch:SI 5 "=c"))
14067 (clobber (reg:CC FLAGS_REG))]
14068 ""
14069 "#"
14070 ""
14071 [(parallel [(set (match_dup 0)
14072 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14073 UNSPEC_TLS_GD))
14074 (clobber (match_dup 4))
14075 (clobber (match_dup 5))
14076 (clobber (reg:CC FLAGS_REG))])]
14077 "")
14078
14079 ;; Load and add the thread base pointer from %gs:0.
14080
14081 (define_insn "*load_tp_si"
14082 [(set (match_operand:SI 0 "register_operand" "=r")
14083 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14084 "!TARGET_64BIT"
14085 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14086 [(set_attr "type" "imov")
14087 (set_attr "modrm" "0")
14088 (set_attr "length" "7")
14089 (set_attr "memory" "load")
14090 (set_attr "imm_disp" "false")])
14091
14092 (define_insn "*add_tp_si"
14093 [(set (match_operand:SI 0 "register_operand" "=r")
14094 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14095 (match_operand:SI 1 "register_operand" "0")))
14096 (clobber (reg:CC FLAGS_REG))]
14097 "!TARGET_64BIT"
14098 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14099 [(set_attr "type" "alu")
14100 (set_attr "modrm" "0")
14101 (set_attr "length" "7")
14102 (set_attr "memory" "load")
14103 (set_attr "imm_disp" "false")])
14104
14105 (define_insn "*load_tp_di"
14106 [(set (match_operand:DI 0 "register_operand" "=r")
14107 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14108 "TARGET_64BIT"
14109 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14110 [(set_attr "type" "imov")
14111 (set_attr "modrm" "0")
14112 (set_attr "length" "7")
14113 (set_attr "memory" "load")
14114 (set_attr "imm_disp" "false")])
14115
14116 (define_insn "*add_tp_di"
14117 [(set (match_operand:DI 0 "register_operand" "=r")
14118 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14119 (match_operand:DI 1 "register_operand" "0")))
14120 (clobber (reg:CC FLAGS_REG))]
14121 "TARGET_64BIT"
14122 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14123 [(set_attr "type" "alu")
14124 (set_attr "modrm" "0")
14125 (set_attr "length" "7")
14126 (set_attr "memory" "load")
14127 (set_attr "imm_disp" "false")])
14128 \f
14129 ;; These patterns match the binary 387 instructions for addM3, subM3,
14130 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14131 ;; SFmode. The first is the normal insn, the second the same insn but
14132 ;; with one operand a conversion, and the third the same insn but with
14133 ;; the other operand a conversion. The conversion may be SFmode or
14134 ;; SImode if the target mode DFmode, but only SImode if the target mode
14135 ;; is SFmode.
14136
14137 ;; Gcc is slightly more smart about handling normal two address instructions
14138 ;; so use special patterns for add and mull.
14139 (define_insn "*fop_sf_comm_nosse"
14140 [(set (match_operand:SF 0 "register_operand" "=f")
14141 (match_operator:SF 3 "binary_fp_operator"
14142 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14143 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14144 "TARGET_80387 && !TARGET_SSE_MATH
14145 && COMMUTATIVE_ARITH_P (operands[3])
14146 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14147 "* return output_387_binary_op (insn, operands);"
14148 [(set (attr "type")
14149 (if_then_else (match_operand:SF 3 "mult_operator" "")
14150 (const_string "fmul")
14151 (const_string "fop")))
14152 (set_attr "mode" "SF")])
14153
14154 (define_insn "*fop_sf_comm"
14155 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14156 (match_operator:SF 3 "binary_fp_operator"
14157 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14158 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14159 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14160 && COMMUTATIVE_ARITH_P (operands[3])
14161 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14162 "* return output_387_binary_op (insn, operands);"
14163 [(set (attr "type")
14164 (if_then_else (eq_attr "alternative" "1")
14165 (if_then_else (match_operand:SF 3 "mult_operator" "")
14166 (const_string "ssemul")
14167 (const_string "sseadd"))
14168 (if_then_else (match_operand:SF 3 "mult_operator" "")
14169 (const_string "fmul")
14170 (const_string "fop"))))
14171 (set_attr "mode" "SF")])
14172
14173 (define_insn "*fop_sf_comm_sse"
14174 [(set (match_operand:SF 0 "register_operand" "=x")
14175 (match_operator:SF 3 "binary_fp_operator"
14176 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14177 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14178 "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14179 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14180 "* return output_387_binary_op (insn, operands);"
14181 [(set (attr "type")
14182 (if_then_else (match_operand:SF 3 "mult_operator" "")
14183 (const_string "ssemul")
14184 (const_string "sseadd")))
14185 (set_attr "mode" "SF")])
14186
14187 (define_insn "*fop_df_comm_nosse"
14188 [(set (match_operand:DF 0 "register_operand" "=f")
14189 (match_operator:DF 3 "binary_fp_operator"
14190 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14191 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14192 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14193 && COMMUTATIVE_ARITH_P (operands[3])
14194 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14195 "* return output_387_binary_op (insn, operands);"
14196 [(set (attr "type")
14197 (if_then_else (match_operand:SF 3 "mult_operator" "")
14198 (const_string "fmul")
14199 (const_string "fop")))
14200 (set_attr "mode" "DF")])
14201
14202 (define_insn "*fop_df_comm"
14203 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14204 (match_operator:DF 3 "binary_fp_operator"
14205 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14206 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14207 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14208 && COMMUTATIVE_ARITH_P (operands[3])
14209 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14210 "* return output_387_binary_op (insn, operands);"
14211 [(set (attr "type")
14212 (if_then_else (eq_attr "alternative" "1")
14213 (if_then_else (match_operand:SF 3 "mult_operator" "")
14214 (const_string "ssemul")
14215 (const_string "sseadd"))
14216 (if_then_else (match_operand:SF 3 "mult_operator" "")
14217 (const_string "fmul")
14218 (const_string "fop"))))
14219 (set_attr "mode" "DF")])
14220
14221 (define_insn "*fop_df_comm_sse"
14222 [(set (match_operand:DF 0 "register_operand" "=Y")
14223 (match_operator:DF 3 "binary_fp_operator"
14224 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14225 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14226 "TARGET_SSE2 && TARGET_SSE_MATH
14227 && COMMUTATIVE_ARITH_P (operands[3])
14228 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14229 "* return output_387_binary_op (insn, operands);"
14230 [(set (attr "type")
14231 (if_then_else (match_operand:SF 3 "mult_operator" "")
14232 (const_string "ssemul")
14233 (const_string "sseadd")))
14234 (set_attr "mode" "DF")])
14235
14236 (define_insn "*fop_xf_comm"
14237 [(set (match_operand:XF 0 "register_operand" "=f")
14238 (match_operator:XF 3 "binary_fp_operator"
14239 [(match_operand:XF 1 "register_operand" "%0")
14240 (match_operand:XF 2 "register_operand" "f")]))]
14241 "TARGET_80387
14242 && COMMUTATIVE_ARITH_P (operands[3])"
14243 "* return output_387_binary_op (insn, operands);"
14244 [(set (attr "type")
14245 (if_then_else (match_operand:XF 3 "mult_operator" "")
14246 (const_string "fmul")
14247 (const_string "fop")))
14248 (set_attr "mode" "XF")])
14249
14250 (define_insn "*fop_sf_1_nosse"
14251 [(set (match_operand:SF 0 "register_operand" "=f,f")
14252 (match_operator:SF 3 "binary_fp_operator"
14253 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14254 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14255 "TARGET_80387 && !TARGET_SSE_MATH
14256 && !COMMUTATIVE_ARITH_P (operands[3])
14257 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14258 "* return output_387_binary_op (insn, operands);"
14259 [(set (attr "type")
14260 (cond [(match_operand:SF 3 "mult_operator" "")
14261 (const_string "fmul")
14262 (match_operand:SF 3 "div_operator" "")
14263 (const_string "fdiv")
14264 ]
14265 (const_string "fop")))
14266 (set_attr "mode" "SF")])
14267
14268 (define_insn "*fop_sf_1"
14269 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14270 (match_operator:SF 3 "binary_fp_operator"
14271 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14272 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14273 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14274 && !COMMUTATIVE_ARITH_P (operands[3])
14275 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14276 "* return output_387_binary_op (insn, operands);"
14277 [(set (attr "type")
14278 (cond [(and (eq_attr "alternative" "2")
14279 (match_operand:SF 3 "mult_operator" ""))
14280 (const_string "ssemul")
14281 (and (eq_attr "alternative" "2")
14282 (match_operand:SF 3 "div_operator" ""))
14283 (const_string "ssediv")
14284 (eq_attr "alternative" "2")
14285 (const_string "sseadd")
14286 (match_operand:SF 3 "mult_operator" "")
14287 (const_string "fmul")
14288 (match_operand:SF 3 "div_operator" "")
14289 (const_string "fdiv")
14290 ]
14291 (const_string "fop")))
14292 (set_attr "mode" "SF")])
14293
14294 (define_insn "*fop_sf_1_sse"
14295 [(set (match_operand:SF 0 "register_operand" "=x")
14296 (match_operator:SF 3 "binary_fp_operator"
14297 [(match_operand:SF 1 "register_operand" "0")
14298 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14299 "TARGET_SSE_MATH
14300 && !COMMUTATIVE_ARITH_P (operands[3])"
14301 "* return output_387_binary_op (insn, operands);"
14302 [(set (attr "type")
14303 (cond [(match_operand:SF 3 "mult_operator" "")
14304 (const_string "ssemul")
14305 (match_operand:SF 3 "div_operator" "")
14306 (const_string "ssediv")
14307 ]
14308 (const_string "sseadd")))
14309 (set_attr "mode" "SF")])
14310
14311 ;; ??? Add SSE splitters for these!
14312 (define_insn "*fop_sf_2"
14313 [(set (match_operand:SF 0 "register_operand" "=f,f")
14314 (match_operator:SF 3 "binary_fp_operator"
14315 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14316 (match_operand:SF 2 "register_operand" "0,0")]))]
14317 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14318 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14319 [(set (attr "type")
14320 (cond [(match_operand:SF 3 "mult_operator" "")
14321 (const_string "fmul")
14322 (match_operand:SF 3 "div_operator" "")
14323 (const_string "fdiv")
14324 ]
14325 (const_string "fop")))
14326 (set_attr "fp_int_src" "true")
14327 (set_attr "mode" "SI")])
14328
14329 (define_insn "*fop_sf_3"
14330 [(set (match_operand:SF 0 "register_operand" "=f,f")
14331 (match_operator:SF 3 "binary_fp_operator"
14332 [(match_operand:SF 1 "register_operand" "0,0")
14333 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14334 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14335 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14336 [(set (attr "type")
14337 (cond [(match_operand:SF 3 "mult_operator" "")
14338 (const_string "fmul")
14339 (match_operand:SF 3 "div_operator" "")
14340 (const_string "fdiv")
14341 ]
14342 (const_string "fop")))
14343 (set_attr "fp_int_src" "true")
14344 (set_attr "mode" "SI")])
14345
14346 (define_insn "*fop_df_1_nosse"
14347 [(set (match_operand:DF 0 "register_operand" "=f,f")
14348 (match_operator:DF 3 "binary_fp_operator"
14349 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14350 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14351 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14352 && !COMMUTATIVE_ARITH_P (operands[3])
14353 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14354 "* return output_387_binary_op (insn, operands);"
14355 [(set (attr "type")
14356 (cond [(match_operand:DF 3 "mult_operator" "")
14357 (const_string "fmul")
14358 (match_operand:DF 3 "div_operator" "")
14359 (const_string "fdiv")
14360 ]
14361 (const_string "fop")))
14362 (set_attr "mode" "DF")])
14363
14364
14365 (define_insn "*fop_df_1"
14366 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14367 (match_operator:DF 3 "binary_fp_operator"
14368 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14369 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14370 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14371 && !COMMUTATIVE_ARITH_P (operands[3])
14372 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14373 "* return output_387_binary_op (insn, operands);"
14374 [(set (attr "type")
14375 (cond [(and (eq_attr "alternative" "2")
14376 (match_operand:SF 3 "mult_operator" ""))
14377 (const_string "ssemul")
14378 (and (eq_attr "alternative" "2")
14379 (match_operand:SF 3 "div_operator" ""))
14380 (const_string "ssediv")
14381 (eq_attr "alternative" "2")
14382 (const_string "sseadd")
14383 (match_operand:DF 3 "mult_operator" "")
14384 (const_string "fmul")
14385 (match_operand:DF 3 "div_operator" "")
14386 (const_string "fdiv")
14387 ]
14388 (const_string "fop")))
14389 (set_attr "mode" "DF")])
14390
14391 (define_insn "*fop_df_1_sse"
14392 [(set (match_operand:DF 0 "register_operand" "=Y")
14393 (match_operator:DF 3 "binary_fp_operator"
14394 [(match_operand:DF 1 "register_operand" "0")
14395 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14396 "TARGET_SSE2 && TARGET_SSE_MATH
14397 && !COMMUTATIVE_ARITH_P (operands[3])"
14398 "* return output_387_binary_op (insn, operands);"
14399 [(set_attr "mode" "DF")
14400 (set (attr "type")
14401 (cond [(match_operand:SF 3 "mult_operator" "")
14402 (const_string "ssemul")
14403 (match_operand:SF 3 "div_operator" "")
14404 (const_string "ssediv")
14405 ]
14406 (const_string "sseadd")))])
14407
14408 ;; ??? Add SSE splitters for these!
14409 (define_insn "*fop_df_2"
14410 [(set (match_operand:DF 0 "register_operand" "=f,f")
14411 (match_operator:DF 3 "binary_fp_operator"
14412 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14413 (match_operand:DF 2 "register_operand" "0,0")]))]
14414 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14415 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14416 [(set (attr "type")
14417 (cond [(match_operand:DF 3 "mult_operator" "")
14418 (const_string "fmul")
14419 (match_operand:DF 3 "div_operator" "")
14420 (const_string "fdiv")
14421 ]
14422 (const_string "fop")))
14423 (set_attr "fp_int_src" "true")
14424 (set_attr "mode" "SI")])
14425
14426 (define_insn "*fop_df_3"
14427 [(set (match_operand:DF 0 "register_operand" "=f,f")
14428 (match_operator:DF 3 "binary_fp_operator"
14429 [(match_operand:DF 1 "register_operand" "0,0")
14430 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14431 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14432 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14433 [(set (attr "type")
14434 (cond [(match_operand:DF 3 "mult_operator" "")
14435 (const_string "fmul")
14436 (match_operand:DF 3 "div_operator" "")
14437 (const_string "fdiv")
14438 ]
14439 (const_string "fop")))
14440 (set_attr "fp_int_src" "true")
14441 (set_attr "mode" "SI")])
14442
14443 (define_insn "*fop_df_4"
14444 [(set (match_operand:DF 0 "register_operand" "=f,f")
14445 (match_operator:DF 3 "binary_fp_operator"
14446 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14447 (match_operand:DF 2 "register_operand" "0,f")]))]
14448 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14449 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14450 "* return output_387_binary_op (insn, operands);"
14451 [(set (attr "type")
14452 (cond [(match_operand:DF 3 "mult_operator" "")
14453 (const_string "fmul")
14454 (match_operand:DF 3 "div_operator" "")
14455 (const_string "fdiv")
14456 ]
14457 (const_string "fop")))
14458 (set_attr "mode" "SF")])
14459
14460 (define_insn "*fop_df_5"
14461 [(set (match_operand:DF 0 "register_operand" "=f,f")
14462 (match_operator:DF 3 "binary_fp_operator"
14463 [(match_operand:DF 1 "register_operand" "0,f")
14464 (float_extend:DF
14465 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14466 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14467 "* return output_387_binary_op (insn, operands);"
14468 [(set (attr "type")
14469 (cond [(match_operand:DF 3 "mult_operator" "")
14470 (const_string "fmul")
14471 (match_operand:DF 3 "div_operator" "")
14472 (const_string "fdiv")
14473 ]
14474 (const_string "fop")))
14475 (set_attr "mode" "SF")])
14476
14477 (define_insn "*fop_df_6"
14478 [(set (match_operand:DF 0 "register_operand" "=f,f")
14479 (match_operator:DF 3 "binary_fp_operator"
14480 [(float_extend:DF
14481 (match_operand:SF 1 "register_operand" "0,f"))
14482 (float_extend:DF
14483 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14484 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14485 "* return output_387_binary_op (insn, operands);"
14486 [(set (attr "type")
14487 (cond [(match_operand:DF 3 "mult_operator" "")
14488 (const_string "fmul")
14489 (match_operand:DF 3 "div_operator" "")
14490 (const_string "fdiv")
14491 ]
14492 (const_string "fop")))
14493 (set_attr "mode" "SF")])
14494
14495 (define_insn "*fop_xf_1"
14496 [(set (match_operand:XF 0 "register_operand" "=f,f")
14497 (match_operator:XF 3 "binary_fp_operator"
14498 [(match_operand:XF 1 "register_operand" "0,f")
14499 (match_operand:XF 2 "register_operand" "f,0")]))]
14500 "TARGET_80387
14501 && !COMMUTATIVE_ARITH_P (operands[3])"
14502 "* return output_387_binary_op (insn, operands);"
14503 [(set (attr "type")
14504 (cond [(match_operand:XF 3 "mult_operator" "")
14505 (const_string "fmul")
14506 (match_operand:XF 3 "div_operator" "")
14507 (const_string "fdiv")
14508 ]
14509 (const_string "fop")))
14510 (set_attr "mode" "XF")])
14511
14512 (define_insn "*fop_xf_2"
14513 [(set (match_operand:XF 0 "register_operand" "=f,f")
14514 (match_operator:XF 3 "binary_fp_operator"
14515 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14516 (match_operand:XF 2 "register_operand" "0,0")]))]
14517 "TARGET_80387 && TARGET_USE_FIOP"
14518 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14519 [(set (attr "type")
14520 (cond [(match_operand:XF 3 "mult_operator" "")
14521 (const_string "fmul")
14522 (match_operand:XF 3 "div_operator" "")
14523 (const_string "fdiv")
14524 ]
14525 (const_string "fop")))
14526 (set_attr "fp_int_src" "true")
14527 (set_attr "mode" "SI")])
14528
14529 (define_insn "*fop_xf_3"
14530 [(set (match_operand:XF 0 "register_operand" "=f,f")
14531 (match_operator:XF 3 "binary_fp_operator"
14532 [(match_operand:XF 1 "register_operand" "0,0")
14533 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14534 "TARGET_80387 && TARGET_USE_FIOP"
14535 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14536 [(set (attr "type")
14537 (cond [(match_operand:XF 3 "mult_operator" "")
14538 (const_string "fmul")
14539 (match_operand:XF 3 "div_operator" "")
14540 (const_string "fdiv")
14541 ]
14542 (const_string "fop")))
14543 (set_attr "fp_int_src" "true")
14544 (set_attr "mode" "SI")])
14545
14546 (define_insn "*fop_xf_4"
14547 [(set (match_operand:XF 0 "register_operand" "=f,f")
14548 (match_operator:XF 3 "binary_fp_operator"
14549 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14550 (match_operand:XF 2 "register_operand" "0,f")]))]
14551 "TARGET_80387"
14552 "* return output_387_binary_op (insn, operands);"
14553 [(set (attr "type")
14554 (cond [(match_operand:XF 3 "mult_operator" "")
14555 (const_string "fmul")
14556 (match_operand:XF 3 "div_operator" "")
14557 (const_string "fdiv")
14558 ]
14559 (const_string "fop")))
14560 (set_attr "mode" "SF")])
14561
14562 (define_insn "*fop_xf_5"
14563 [(set (match_operand:XF 0 "register_operand" "=f,f")
14564 (match_operator:XF 3 "binary_fp_operator"
14565 [(match_operand:XF 1 "register_operand" "0,f")
14566 (float_extend:XF
14567 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14568 "TARGET_80387"
14569 "* return output_387_binary_op (insn, operands);"
14570 [(set (attr "type")
14571 (cond [(match_operand:XF 3 "mult_operator" "")
14572 (const_string "fmul")
14573 (match_operand:XF 3 "div_operator" "")
14574 (const_string "fdiv")
14575 ]
14576 (const_string "fop")))
14577 (set_attr "mode" "SF")])
14578
14579 (define_insn "*fop_xf_6"
14580 [(set (match_operand:XF 0 "register_operand" "=f,f")
14581 (match_operator:XF 3 "binary_fp_operator"
14582 [(float_extend:XF
14583 (match_operand 1 "register_operand" "0,f"))
14584 (float_extend:XF
14585 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14586 "TARGET_80387"
14587 "* return output_387_binary_op (insn, operands);"
14588 [(set (attr "type")
14589 (cond [(match_operand:XF 3 "mult_operator" "")
14590 (const_string "fmul")
14591 (match_operand:XF 3 "div_operator" "")
14592 (const_string "fdiv")
14593 ]
14594 (const_string "fop")))
14595 (set_attr "mode" "SF")])
14596
14597 (define_split
14598 [(set (match_operand 0 "register_operand" "")
14599 (match_operator 3 "binary_fp_operator"
14600 [(float (match_operand:SI 1 "register_operand" ""))
14601 (match_operand 2 "register_operand" "")]))]
14602 "TARGET_80387 && reload_completed
14603 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14604 [(const_int 0)]
14605 {
14606 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14607 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14608 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14609 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14610 GET_MODE (operands[3]),
14611 operands[4],
14612 operands[2])));
14613 ix86_free_from_memory (GET_MODE (operands[1]));
14614 DONE;
14615 })
14616
14617 (define_split
14618 [(set (match_operand 0 "register_operand" "")
14619 (match_operator 3 "binary_fp_operator"
14620 [(match_operand 1 "register_operand" "")
14621 (float (match_operand:SI 2 "register_operand" ""))]))]
14622 "TARGET_80387 && reload_completed
14623 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14624 [(const_int 0)]
14625 {
14626 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14627 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14628 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14629 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14630 GET_MODE (operands[3]),
14631 operands[1],
14632 operands[4])));
14633 ix86_free_from_memory (GET_MODE (operands[2]));
14634 DONE;
14635 })
14636 \f
14637 ;; FPU special functions.
14638
14639 (define_expand "sqrtsf2"
14640 [(set (match_operand:SF 0 "register_operand" "")
14641 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14642 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14643 {
14644 if (!TARGET_SSE_MATH)
14645 operands[1] = force_reg (SFmode, operands[1]);
14646 })
14647
14648 (define_insn "sqrtsf2_1"
14649 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14650 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14651 "TARGET_USE_FANCY_MATH_387
14652 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14653 "@
14654 fsqrt
14655 sqrtss\t{%1, %0|%0, %1}"
14656 [(set_attr "type" "fpspc,sse")
14657 (set_attr "mode" "SF,SF")
14658 (set_attr "athlon_decode" "direct,*")])
14659
14660 (define_insn "sqrtsf2_1_sse_only"
14661 [(set (match_operand:SF 0 "register_operand" "=x")
14662 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14663 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14664 "sqrtss\t{%1, %0|%0, %1}"
14665 [(set_attr "type" "sse")
14666 (set_attr "mode" "SF")
14667 (set_attr "athlon_decode" "*")])
14668
14669 (define_insn "sqrtsf2_i387"
14670 [(set (match_operand:SF 0 "register_operand" "=f")
14671 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14672 "TARGET_USE_FANCY_MATH_387
14673 && !TARGET_SSE_MATH"
14674 "fsqrt"
14675 [(set_attr "type" "fpspc")
14676 (set_attr "mode" "SF")
14677 (set_attr "athlon_decode" "direct")])
14678
14679 (define_expand "sqrtdf2"
14680 [(set (match_operand:DF 0 "register_operand" "")
14681 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14682 "TARGET_USE_FANCY_MATH_387
14683 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14684 {
14685 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14686 operands[1] = force_reg (DFmode, operands[1]);
14687 })
14688
14689 (define_insn "sqrtdf2_1"
14690 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14691 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14692 "TARGET_USE_FANCY_MATH_387
14693 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14694 "@
14695 fsqrt
14696 sqrtsd\t{%1, %0|%0, %1}"
14697 [(set_attr "type" "fpspc,sse")
14698 (set_attr "mode" "DF,DF")
14699 (set_attr "athlon_decode" "direct,*")])
14700
14701 (define_insn "sqrtdf2_1_sse_only"
14702 [(set (match_operand:DF 0 "register_operand" "=Y")
14703 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14704 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14705 "sqrtsd\t{%1, %0|%0, %1}"
14706 [(set_attr "type" "sse")
14707 (set_attr "mode" "DF")
14708 (set_attr "athlon_decode" "*")])
14709
14710 (define_insn "sqrtdf2_i387"
14711 [(set (match_operand:DF 0 "register_operand" "=f")
14712 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14713 "TARGET_USE_FANCY_MATH_387
14714 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14715 "fsqrt"
14716 [(set_attr "type" "fpspc")
14717 (set_attr "mode" "DF")
14718 (set_attr "athlon_decode" "direct")])
14719
14720 (define_insn "*sqrtextendsfdf2"
14721 [(set (match_operand:DF 0 "register_operand" "=f")
14722 (sqrt:DF (float_extend:DF
14723 (match_operand:SF 1 "register_operand" "0"))))]
14724 "TARGET_USE_FANCY_MATH_387
14725 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14726 "fsqrt"
14727 [(set_attr "type" "fpspc")
14728 (set_attr "mode" "DF")
14729 (set_attr "athlon_decode" "direct")])
14730
14731 (define_insn "sqrtxf2"
14732 [(set (match_operand:XF 0 "register_operand" "=f")
14733 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14734 "TARGET_USE_FANCY_MATH_387
14735 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14736 "fsqrt"
14737 [(set_attr "type" "fpspc")
14738 (set_attr "mode" "XF")
14739 (set_attr "athlon_decode" "direct")])
14740
14741 (define_insn "*sqrtextenddfxf2"
14742 [(set (match_operand:XF 0 "register_operand" "=f")
14743 (sqrt:XF (float_extend:XF
14744 (match_operand:DF 1 "register_operand" "0"))))]
14745 "TARGET_USE_FANCY_MATH_387"
14746 "fsqrt"
14747 [(set_attr "type" "fpspc")
14748 (set_attr "mode" "XF")
14749 (set_attr "athlon_decode" "direct")])
14750
14751 (define_insn "*sqrtextendsfxf2"
14752 [(set (match_operand:XF 0 "register_operand" "=f")
14753 (sqrt:XF (float_extend:XF
14754 (match_operand:SF 1 "register_operand" "0"))))]
14755 "TARGET_USE_FANCY_MATH_387"
14756 "fsqrt"
14757 [(set_attr "type" "fpspc")
14758 (set_attr "mode" "XF")
14759 (set_attr "athlon_decode" "direct")])
14760
14761 (define_insn "fpremxf4"
14762 [(set (match_operand:XF 0 "register_operand" "=f")
14763 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14764 (match_operand:XF 3 "register_operand" "1")]
14765 UNSPEC_FPREM_F))
14766 (set (match_operand:XF 1 "register_operand" "=u")
14767 (unspec:XF [(match_dup 2) (match_dup 3)]
14768 UNSPEC_FPREM_U))
14769 (set (reg:CCFP FPSR_REG)
14770 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14771 "TARGET_USE_FANCY_MATH_387
14772 && flag_unsafe_math_optimizations"
14773 "fprem"
14774 [(set_attr "type" "fpspc")
14775 (set_attr "mode" "XF")])
14776
14777 (define_expand "fmodsf3"
14778 [(use (match_operand:SF 0 "register_operand" ""))
14779 (use (match_operand:SF 1 "register_operand" ""))
14780 (use (match_operand:SF 2 "register_operand" ""))]
14781 "TARGET_USE_FANCY_MATH_387
14782 && flag_unsafe_math_optimizations"
14783 {
14784 rtx label = gen_label_rtx ();
14785
14786 rtx op1 = gen_reg_rtx (XFmode);
14787 rtx op2 = gen_reg_rtx (XFmode);
14788
14789 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14790 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14791
14792 emit_label (label);
14793
14794 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14795 ix86_emit_fp_unordered_jump (label);
14796
14797 emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14798 DONE;
14799 })
14800
14801 (define_expand "fmoddf3"
14802 [(use (match_operand:DF 0 "register_operand" ""))
14803 (use (match_operand:DF 1 "register_operand" ""))
14804 (use (match_operand:DF 2 "register_operand" ""))]
14805 "TARGET_USE_FANCY_MATH_387
14806 && flag_unsafe_math_optimizations"
14807 {
14808 rtx label = gen_label_rtx ();
14809
14810 rtx op1 = gen_reg_rtx (XFmode);
14811 rtx op2 = gen_reg_rtx (XFmode);
14812
14813 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14814 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14815
14816 emit_label (label);
14817
14818 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14819 ix86_emit_fp_unordered_jump (label);
14820
14821 emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14822 DONE;
14823 })
14824
14825 (define_expand "fmodxf3"
14826 [(use (match_operand:XF 0 "register_operand" ""))
14827 (use (match_operand:XF 1 "register_operand" ""))
14828 (use (match_operand:XF 2 "register_operand" ""))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && flag_unsafe_math_optimizations"
14831 {
14832 rtx label = gen_label_rtx ();
14833
14834 emit_label (label);
14835
14836 emit_insn (gen_fpremxf4 (operands[1], operands[2],
14837 operands[1], operands[2]));
14838 ix86_emit_fp_unordered_jump (label);
14839
14840 emit_move_insn (operands[0], operands[1]);
14841 DONE;
14842 })
14843
14844 (define_insn "fprem1xf4"
14845 [(set (match_operand:XF 0 "register_operand" "=f")
14846 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14847 (match_operand:XF 3 "register_operand" "1")]
14848 UNSPEC_FPREM1_F))
14849 (set (match_operand:XF 1 "register_operand" "=u")
14850 (unspec:XF [(match_dup 2) (match_dup 3)]
14851 UNSPEC_FPREM1_U))
14852 (set (reg:CCFP FPSR_REG)
14853 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14854 "TARGET_USE_FANCY_MATH_387
14855 && flag_unsafe_math_optimizations"
14856 "fprem1"
14857 [(set_attr "type" "fpspc")
14858 (set_attr "mode" "XF")])
14859
14860 (define_expand "dremsf3"
14861 [(use (match_operand:SF 0 "register_operand" ""))
14862 (use (match_operand:SF 1 "register_operand" ""))
14863 (use (match_operand:SF 2 "register_operand" ""))]
14864 "TARGET_USE_FANCY_MATH_387
14865 && flag_unsafe_math_optimizations"
14866 {
14867 rtx label = gen_label_rtx ();
14868
14869 rtx op1 = gen_reg_rtx (XFmode);
14870 rtx op2 = gen_reg_rtx (XFmode);
14871
14872 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14873 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14874
14875 emit_label (label);
14876
14877 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14878 ix86_emit_fp_unordered_jump (label);
14879
14880 emit_insn (gen_truncxfsf2_noop (operands[0], op1));
14881 DONE;
14882 })
14883
14884 (define_expand "dremdf3"
14885 [(use (match_operand:DF 0 "register_operand" ""))
14886 (use (match_operand:DF 1 "register_operand" ""))
14887 (use (match_operand:DF 2 "register_operand" ""))]
14888 "TARGET_USE_FANCY_MATH_387
14889 && flag_unsafe_math_optimizations"
14890 {
14891 rtx label = gen_label_rtx ();
14892
14893 rtx op1 = gen_reg_rtx (XFmode);
14894 rtx op2 = gen_reg_rtx (XFmode);
14895
14896 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14897 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14898
14899 emit_label (label);
14900
14901 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14902 ix86_emit_fp_unordered_jump (label);
14903
14904 emit_insn (gen_truncxfdf2_noop (operands[0], op1));
14905 DONE;
14906 })
14907
14908 (define_expand "dremxf3"
14909 [(use (match_operand:XF 0 "register_operand" ""))
14910 (use (match_operand:XF 1 "register_operand" ""))
14911 (use (match_operand:XF 2 "register_operand" ""))]
14912 "TARGET_USE_FANCY_MATH_387
14913 && flag_unsafe_math_optimizations"
14914 {
14915 rtx label = gen_label_rtx ();
14916
14917 emit_label (label);
14918
14919 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14920 operands[1], operands[2]));
14921 ix86_emit_fp_unordered_jump (label);
14922
14923 emit_move_insn (operands[0], operands[1]);
14924 DONE;
14925 })
14926
14927 (define_insn "*sindf2"
14928 [(set (match_operand:DF 0 "register_operand" "=f")
14929 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14930 "TARGET_USE_FANCY_MATH_387
14931 && flag_unsafe_math_optimizations"
14932 "fsin"
14933 [(set_attr "type" "fpspc")
14934 (set_attr "mode" "DF")])
14935
14936 (define_insn "*sinsf2"
14937 [(set (match_operand:SF 0 "register_operand" "=f")
14938 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && flag_unsafe_math_optimizations"
14941 "fsin"
14942 [(set_attr "type" "fpspc")
14943 (set_attr "mode" "SF")])
14944
14945 (define_insn "*sinextendsfdf2"
14946 [(set (match_operand:DF 0 "register_operand" "=f")
14947 (unspec:DF [(float_extend:DF
14948 (match_operand:SF 1 "register_operand" "0"))]
14949 UNSPEC_SIN))]
14950 "TARGET_USE_FANCY_MATH_387
14951 && flag_unsafe_math_optimizations"
14952 "fsin"
14953 [(set_attr "type" "fpspc")
14954 (set_attr "mode" "DF")])
14955
14956 (define_insn "*sinxf2"
14957 [(set (match_operand:XF 0 "register_operand" "=f")
14958 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14959 "TARGET_USE_FANCY_MATH_387
14960 && flag_unsafe_math_optimizations"
14961 "fsin"
14962 [(set_attr "type" "fpspc")
14963 (set_attr "mode" "XF")])
14964
14965 (define_insn "*cosdf2"
14966 [(set (match_operand:DF 0 "register_operand" "=f")
14967 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14968 "TARGET_USE_FANCY_MATH_387
14969 && flag_unsafe_math_optimizations"
14970 "fcos"
14971 [(set_attr "type" "fpspc")
14972 (set_attr "mode" "DF")])
14973
14974 (define_insn "*cossf2"
14975 [(set (match_operand:SF 0 "register_operand" "=f")
14976 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14977 "TARGET_USE_FANCY_MATH_387
14978 && flag_unsafe_math_optimizations"
14979 "fcos"
14980 [(set_attr "type" "fpspc")
14981 (set_attr "mode" "SF")])
14982
14983 (define_insn "*cosextendsfdf2"
14984 [(set (match_operand:DF 0 "register_operand" "=f")
14985 (unspec:DF [(float_extend:DF
14986 (match_operand:SF 1 "register_operand" "0"))]
14987 UNSPEC_COS))]
14988 "TARGET_USE_FANCY_MATH_387
14989 && flag_unsafe_math_optimizations"
14990 "fcos"
14991 [(set_attr "type" "fpspc")
14992 (set_attr "mode" "DF")])
14993
14994 (define_insn "*cosxf2"
14995 [(set (match_operand:XF 0 "register_operand" "=f")
14996 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14997 "TARGET_USE_FANCY_MATH_387
14998 && flag_unsafe_math_optimizations"
14999 "fcos"
15000 [(set_attr "type" "fpspc")
15001 (set_attr "mode" "XF")])
15002
15003 ;; With sincos pattern defined, sin and cos builtin function will be
15004 ;; expanded to sincos pattern with one of its outputs left unused.
15005 ;; Cse pass will detected, if two sincos patterns can be combined,
15006 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15007 ;; depending on the unused output.
15008
15009 (define_insn "sincosdf3"
15010 [(set (match_operand:DF 0 "register_operand" "=f")
15011 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15012 UNSPEC_SINCOS_COS))
15013 (set (match_operand:DF 1 "register_operand" "=u")
15014 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15015 "TARGET_USE_FANCY_MATH_387
15016 && flag_unsafe_math_optimizations"
15017 "fsincos"
15018 [(set_attr "type" "fpspc")
15019 (set_attr "mode" "DF")])
15020
15021 (define_split
15022 [(set (match_operand:DF 0 "register_operand" "")
15023 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15024 UNSPEC_SINCOS_COS))
15025 (set (match_operand:DF 1 "register_operand" "")
15026 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15027 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15028 && !reload_completed && !reload_in_progress"
15029 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15030 "")
15031
15032 (define_split
15033 [(set (match_operand:DF 0 "register_operand" "")
15034 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15035 UNSPEC_SINCOS_COS))
15036 (set (match_operand:DF 1 "register_operand" "")
15037 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15038 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15039 && !reload_completed && !reload_in_progress"
15040 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15041 "")
15042
15043 (define_insn "sincossf3"
15044 [(set (match_operand:SF 0 "register_operand" "=f")
15045 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15046 UNSPEC_SINCOS_COS))
15047 (set (match_operand:SF 1 "register_operand" "=u")
15048 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15049 "TARGET_USE_FANCY_MATH_387
15050 && flag_unsafe_math_optimizations"
15051 "fsincos"
15052 [(set_attr "type" "fpspc")
15053 (set_attr "mode" "SF")])
15054
15055 (define_split
15056 [(set (match_operand:SF 0 "register_operand" "")
15057 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15058 UNSPEC_SINCOS_COS))
15059 (set (match_operand:SF 1 "register_operand" "")
15060 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15061 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15062 && !reload_completed && !reload_in_progress"
15063 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15064 "")
15065
15066 (define_split
15067 [(set (match_operand:SF 0 "register_operand" "")
15068 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15069 UNSPEC_SINCOS_COS))
15070 (set (match_operand:SF 1 "register_operand" "")
15071 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15072 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15073 && !reload_completed && !reload_in_progress"
15074 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15075 "")
15076
15077 (define_insn "*sincosextendsfdf3"
15078 [(set (match_operand:DF 0 "register_operand" "=f")
15079 (unspec:DF [(float_extend:DF
15080 (match_operand:SF 2 "register_operand" "0"))]
15081 UNSPEC_SINCOS_COS))
15082 (set (match_operand:DF 1 "register_operand" "=u")
15083 (unspec:DF [(float_extend:DF
15084 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15085 "TARGET_USE_FANCY_MATH_387
15086 && flag_unsafe_math_optimizations"
15087 "fsincos"
15088 [(set_attr "type" "fpspc")
15089 (set_attr "mode" "DF")])
15090
15091 (define_split
15092 [(set (match_operand:DF 0 "register_operand" "")
15093 (unspec:DF [(float_extend:DF
15094 (match_operand:SF 2 "register_operand" ""))]
15095 UNSPEC_SINCOS_COS))
15096 (set (match_operand:DF 1 "register_operand" "")
15097 (unspec:DF [(float_extend:DF
15098 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15099 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15100 && !reload_completed && !reload_in_progress"
15101 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15102 (match_dup 2))] UNSPEC_SIN))]
15103 "")
15104
15105 (define_split
15106 [(set (match_operand:DF 0 "register_operand" "")
15107 (unspec:DF [(float_extend:DF
15108 (match_operand:SF 2 "register_operand" ""))]
15109 UNSPEC_SINCOS_COS))
15110 (set (match_operand:DF 1 "register_operand" "")
15111 (unspec:DF [(float_extend:DF
15112 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15113 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15114 && !reload_completed && !reload_in_progress"
15115 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15116 (match_dup 2))] UNSPEC_COS))]
15117 "")
15118
15119 (define_insn "sincosxf3"
15120 [(set (match_operand:XF 0 "register_operand" "=f")
15121 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15122 UNSPEC_SINCOS_COS))
15123 (set (match_operand:XF 1 "register_operand" "=u")
15124 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15125 "TARGET_USE_FANCY_MATH_387
15126 && flag_unsafe_math_optimizations"
15127 "fsincos"
15128 [(set_attr "type" "fpspc")
15129 (set_attr "mode" "XF")])
15130
15131 (define_split
15132 [(set (match_operand:XF 0 "register_operand" "")
15133 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15134 UNSPEC_SINCOS_COS))
15135 (set (match_operand:XF 1 "register_operand" "")
15136 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15137 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15138 && !reload_completed && !reload_in_progress"
15139 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15140 "")
15141
15142 (define_split
15143 [(set (match_operand:XF 0 "register_operand" "")
15144 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15145 UNSPEC_SINCOS_COS))
15146 (set (match_operand:XF 1 "register_operand" "")
15147 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15148 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15149 && !reload_completed && !reload_in_progress"
15150 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15151 "")
15152
15153 (define_insn "*tandf3_1"
15154 [(set (match_operand:DF 0 "register_operand" "=f")
15155 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15156 UNSPEC_TAN_ONE))
15157 (set (match_operand:DF 1 "register_operand" "=u")
15158 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15159 "TARGET_USE_FANCY_MATH_387
15160 && flag_unsafe_math_optimizations"
15161 "fptan"
15162 [(set_attr "type" "fpspc")
15163 (set_attr "mode" "DF")])
15164
15165 ;; optimize sequence: fptan
15166 ;; fstp %st(0)
15167 ;; fld1
15168 ;; into fptan insn.
15169
15170 (define_peephole2
15171 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15172 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15173 UNSPEC_TAN_ONE))
15174 (set (match_operand:DF 1 "register_operand" "")
15175 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15176 (set (match_dup 0)
15177 (match_operand:DF 3 "immediate_operand" ""))]
15178 "standard_80387_constant_p (operands[3]) == 2"
15179 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15180 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15181 "")
15182
15183 (define_expand "tandf2"
15184 [(parallel [(set (match_dup 2)
15185 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15186 UNSPEC_TAN_ONE))
15187 (set (match_operand:DF 0 "register_operand" "")
15188 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15189 "TARGET_USE_FANCY_MATH_387
15190 && flag_unsafe_math_optimizations"
15191 {
15192 operands[2] = gen_reg_rtx (DFmode);
15193 })
15194
15195 (define_insn "*tansf3_1"
15196 [(set (match_operand:SF 0 "register_operand" "=f")
15197 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15198 UNSPEC_TAN_ONE))
15199 (set (match_operand:SF 1 "register_operand" "=u")
15200 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15201 "TARGET_USE_FANCY_MATH_387
15202 && flag_unsafe_math_optimizations"
15203 "fptan"
15204 [(set_attr "type" "fpspc")
15205 (set_attr "mode" "SF")])
15206
15207 ;; optimize sequence: fptan
15208 ;; fstp %st(0)
15209 ;; fld1
15210 ;; into fptan insn.
15211
15212 (define_peephole2
15213 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15214 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15215 UNSPEC_TAN_ONE))
15216 (set (match_operand:SF 1 "register_operand" "")
15217 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15218 (set (match_dup 0)
15219 (match_operand:SF 3 "immediate_operand" ""))]
15220 "standard_80387_constant_p (operands[3]) == 2"
15221 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15222 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15223 "")
15224
15225 (define_expand "tansf2"
15226 [(parallel [(set (match_dup 2)
15227 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15228 UNSPEC_TAN_ONE))
15229 (set (match_operand:SF 0 "register_operand" "")
15230 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15231 "TARGET_USE_FANCY_MATH_387
15232 && flag_unsafe_math_optimizations"
15233 {
15234 operands[2] = gen_reg_rtx (SFmode);
15235 })
15236
15237 (define_insn "*tanxf3_1"
15238 [(set (match_operand:XF 0 "register_operand" "=f")
15239 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15240 UNSPEC_TAN_ONE))
15241 (set (match_operand:XF 1 "register_operand" "=u")
15242 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15243 "TARGET_USE_FANCY_MATH_387
15244 && flag_unsafe_math_optimizations"
15245 "fptan"
15246 [(set_attr "type" "fpspc")
15247 (set_attr "mode" "XF")])
15248
15249 ;; optimize sequence: fptan
15250 ;; fstp %st(0)
15251 ;; fld1
15252 ;; into fptan insn.
15253
15254 (define_peephole2
15255 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15256 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15257 UNSPEC_TAN_ONE))
15258 (set (match_operand:XF 1 "register_operand" "")
15259 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15260 (set (match_dup 0)
15261 (match_operand:XF 3 "immediate_operand" ""))]
15262 "standard_80387_constant_p (operands[3]) == 2"
15263 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15264 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15265 "")
15266
15267 (define_expand "tanxf2"
15268 [(parallel [(set (match_dup 2)
15269 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15270 UNSPEC_TAN_ONE))
15271 (set (match_operand:XF 0 "register_operand" "")
15272 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15273 "TARGET_USE_FANCY_MATH_387
15274 && flag_unsafe_math_optimizations"
15275 {
15276 operands[2] = gen_reg_rtx (XFmode);
15277 })
15278
15279 (define_insn "atan2df3_1"
15280 [(set (match_operand:DF 0 "register_operand" "=f")
15281 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15282 (match_operand:DF 1 "register_operand" "u")]
15283 UNSPEC_FPATAN))
15284 (clobber (match_scratch:DF 3 "=1"))]
15285 "TARGET_USE_FANCY_MATH_387
15286 && flag_unsafe_math_optimizations"
15287 "fpatan"
15288 [(set_attr "type" "fpspc")
15289 (set_attr "mode" "DF")])
15290
15291 (define_expand "atan2df3"
15292 [(use (match_operand:DF 0 "register_operand" "=f"))
15293 (use (match_operand:DF 2 "register_operand" "0"))
15294 (use (match_operand:DF 1 "register_operand" "u"))]
15295 "TARGET_USE_FANCY_MATH_387
15296 && flag_unsafe_math_optimizations"
15297 {
15298 rtx copy = gen_reg_rtx (DFmode);
15299 emit_move_insn (copy, operands[1]);
15300 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15301 DONE;
15302 })
15303
15304 (define_expand "atandf2"
15305 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15306 (unspec:DF [(match_dup 2)
15307 (match_operand:DF 1 "register_operand" "")]
15308 UNSPEC_FPATAN))
15309 (clobber (match_scratch:DF 3 ""))])]
15310 "TARGET_USE_FANCY_MATH_387
15311 && flag_unsafe_math_optimizations"
15312 {
15313 operands[2] = gen_reg_rtx (DFmode);
15314 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15315 })
15316
15317 (define_insn "atan2sf3_1"
15318 [(set (match_operand:SF 0 "register_operand" "=f")
15319 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15320 (match_operand:SF 1 "register_operand" "u")]
15321 UNSPEC_FPATAN))
15322 (clobber (match_scratch:SF 3 "=1"))]
15323 "TARGET_USE_FANCY_MATH_387
15324 && flag_unsafe_math_optimizations"
15325 "fpatan"
15326 [(set_attr "type" "fpspc")
15327 (set_attr "mode" "SF")])
15328
15329 (define_expand "atan2sf3"
15330 [(use (match_operand:SF 0 "register_operand" "=f"))
15331 (use (match_operand:SF 2 "register_operand" "0"))
15332 (use (match_operand:SF 1 "register_operand" "u"))]
15333 "TARGET_USE_FANCY_MATH_387
15334 && flag_unsafe_math_optimizations"
15335 {
15336 rtx copy = gen_reg_rtx (SFmode);
15337 emit_move_insn (copy, operands[1]);
15338 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15339 DONE;
15340 })
15341
15342 (define_expand "atansf2"
15343 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15344 (unspec:SF [(match_dup 2)
15345 (match_operand:SF 1 "register_operand" "")]
15346 UNSPEC_FPATAN))
15347 (clobber (match_scratch:SF 3 ""))])]
15348 "TARGET_USE_FANCY_MATH_387
15349 && flag_unsafe_math_optimizations"
15350 {
15351 operands[2] = gen_reg_rtx (SFmode);
15352 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15353 })
15354
15355 (define_insn "atan2xf3_1"
15356 [(set (match_operand:XF 0 "register_operand" "=f")
15357 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15358 (match_operand:XF 1 "register_operand" "u")]
15359 UNSPEC_FPATAN))
15360 (clobber (match_scratch:XF 3 "=1"))]
15361 "TARGET_USE_FANCY_MATH_387
15362 && flag_unsafe_math_optimizations"
15363 "fpatan"
15364 [(set_attr "type" "fpspc")
15365 (set_attr "mode" "XF")])
15366
15367 (define_expand "atan2xf3"
15368 [(use (match_operand:XF 0 "register_operand" "=f"))
15369 (use (match_operand:XF 2 "register_operand" "0"))
15370 (use (match_operand:XF 1 "register_operand" "u"))]
15371 "TARGET_USE_FANCY_MATH_387
15372 && flag_unsafe_math_optimizations"
15373 {
15374 rtx copy = gen_reg_rtx (XFmode);
15375 emit_move_insn (copy, operands[1]);
15376 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15377 DONE;
15378 })
15379
15380 (define_expand "atanxf2"
15381 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15382 (unspec:XF [(match_dup 2)
15383 (match_operand:XF 1 "register_operand" "")]
15384 UNSPEC_FPATAN))
15385 (clobber (match_scratch:XF 3 ""))])]
15386 "TARGET_USE_FANCY_MATH_387
15387 && flag_unsafe_math_optimizations"
15388 {
15389 operands[2] = gen_reg_rtx (XFmode);
15390 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15391 })
15392
15393 (define_expand "asindf2"
15394 [(set (match_dup 2)
15395 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15396 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15397 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15398 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15399 (parallel [(set (match_dup 7)
15400 (unspec:XF [(match_dup 6) (match_dup 2)]
15401 UNSPEC_FPATAN))
15402 (clobber (match_scratch:XF 8 ""))])
15403 (set (match_operand:DF 0 "register_operand" "")
15404 (float_truncate:DF (match_dup 7)))]
15405 "TARGET_USE_FANCY_MATH_387
15406 && flag_unsafe_math_optimizations"
15407 {
15408 int i;
15409
15410 for (i=2; i<8; i++)
15411 operands[i] = gen_reg_rtx (XFmode);
15412
15413 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15414 })
15415
15416 (define_expand "asinsf2"
15417 [(set (match_dup 2)
15418 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15419 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15420 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15421 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15422 (parallel [(set (match_dup 7)
15423 (unspec:XF [(match_dup 6) (match_dup 2)]
15424 UNSPEC_FPATAN))
15425 (clobber (match_scratch:XF 8 ""))])
15426 (set (match_operand:SF 0 "register_operand" "")
15427 (float_truncate:SF (match_dup 7)))]
15428 "TARGET_USE_FANCY_MATH_387
15429 && flag_unsafe_math_optimizations"
15430 {
15431 int i;
15432
15433 for (i=2; i<8; i++)
15434 operands[i] = gen_reg_rtx (XFmode);
15435
15436 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15437 })
15438
15439 (define_expand "asinxf2"
15440 [(set (match_dup 2)
15441 (mult:XF (match_operand:XF 1 "register_operand" "")
15442 (match_dup 1)))
15443 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15444 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15445 (parallel [(set (match_operand:XF 0 "register_operand" "")
15446 (unspec:XF [(match_dup 5) (match_dup 1)]
15447 UNSPEC_FPATAN))
15448 (clobber (match_scratch:XF 6 ""))])]
15449 "TARGET_USE_FANCY_MATH_387
15450 && flag_unsafe_math_optimizations"
15451 {
15452 int i;
15453
15454 for (i=2; i<6; i++)
15455 operands[i] = gen_reg_rtx (XFmode);
15456
15457 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15458 })
15459
15460 (define_expand "acosdf2"
15461 [(set (match_dup 2)
15462 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15463 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15464 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15465 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15466 (parallel [(set (match_dup 7)
15467 (unspec:XF [(match_dup 2) (match_dup 6)]
15468 UNSPEC_FPATAN))
15469 (clobber (match_scratch:XF 8 ""))])
15470 (set (match_operand:DF 0 "register_operand" "")
15471 (float_truncate:DF (match_dup 7)))]
15472 "TARGET_USE_FANCY_MATH_387
15473 && flag_unsafe_math_optimizations"
15474 {
15475 int i;
15476
15477 for (i=2; i<8; i++)
15478 operands[i] = gen_reg_rtx (XFmode);
15479
15480 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15481 })
15482
15483 (define_expand "acossf2"
15484 [(set (match_dup 2)
15485 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15486 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15487 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15488 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15489 (parallel [(set (match_dup 7)
15490 (unspec:XF [(match_dup 2) (match_dup 6)]
15491 UNSPEC_FPATAN))
15492 (clobber (match_scratch:XF 8 ""))])
15493 (set (match_operand:SF 0 "register_operand" "")
15494 (float_truncate:SF (match_dup 7)))]
15495 "TARGET_USE_FANCY_MATH_387
15496 && flag_unsafe_math_optimizations"
15497 {
15498 int i;
15499
15500 for (i=2; i<8; i++)
15501 operands[i] = gen_reg_rtx (XFmode);
15502
15503 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15504 })
15505
15506 (define_expand "acosxf2"
15507 [(set (match_dup 2)
15508 (mult:XF (match_operand:XF 1 "register_operand" "")
15509 (match_dup 1)))
15510 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15511 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15512 (parallel [(set (match_operand:XF 0 "register_operand" "")
15513 (unspec:XF [(match_dup 1) (match_dup 5)]
15514 UNSPEC_FPATAN))
15515 (clobber (match_scratch:XF 6 ""))])]
15516 "TARGET_USE_FANCY_MATH_387
15517 && flag_unsafe_math_optimizations"
15518 {
15519 int i;
15520
15521 for (i=2; i<6; i++)
15522 operands[i] = gen_reg_rtx (XFmode);
15523
15524 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15525 })
15526
15527 (define_insn "fyl2x_xf3"
15528 [(set (match_operand:XF 0 "register_operand" "=f")
15529 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15530 (match_operand:XF 1 "register_operand" "u")]
15531 UNSPEC_FYL2X))
15532 (clobber (match_scratch:XF 3 "=1"))]
15533 "TARGET_USE_FANCY_MATH_387
15534 && flag_unsafe_math_optimizations"
15535 "fyl2x"
15536 [(set_attr "type" "fpspc")
15537 (set_attr "mode" "XF")])
15538
15539 (define_expand "logsf2"
15540 [(set (match_dup 2)
15541 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15542 (parallel [(set (match_dup 4)
15543 (unspec:XF [(match_dup 2)
15544 (match_dup 3)] UNSPEC_FYL2X))
15545 (clobber (match_scratch:XF 5 ""))])
15546 (set (match_operand:SF 0 "register_operand" "")
15547 (float_truncate:SF (match_dup 4)))]
15548 "TARGET_USE_FANCY_MATH_387
15549 && flag_unsafe_math_optimizations"
15550 {
15551 rtx temp;
15552
15553 operands[2] = gen_reg_rtx (XFmode);
15554 operands[3] = gen_reg_rtx (XFmode);
15555 operands[4] = gen_reg_rtx (XFmode);
15556
15557 temp = standard_80387_constant_rtx (4); /* fldln2 */
15558 emit_move_insn (operands[3], temp);
15559 })
15560
15561 (define_expand "logdf2"
15562 [(set (match_dup 2)
15563 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15564 (parallel [(set (match_dup 4)
15565 (unspec:XF [(match_dup 2)
15566 (match_dup 3)] UNSPEC_FYL2X))
15567 (clobber (match_scratch:XF 5 ""))])
15568 (set (match_operand:DF 0 "register_operand" "")
15569 (float_truncate:DF (match_dup 4)))]
15570 "TARGET_USE_FANCY_MATH_387
15571 && flag_unsafe_math_optimizations"
15572 {
15573 rtx temp;
15574
15575 operands[2] = gen_reg_rtx (XFmode);
15576 operands[3] = gen_reg_rtx (XFmode);
15577 operands[4] = gen_reg_rtx (XFmode);
15578
15579 temp = standard_80387_constant_rtx (4); /* fldln2 */
15580 emit_move_insn (operands[3], temp);
15581 })
15582
15583 (define_expand "logxf2"
15584 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15585 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15586 (match_dup 2)] UNSPEC_FYL2X))
15587 (clobber (match_scratch:XF 3 ""))])]
15588 "TARGET_USE_FANCY_MATH_387
15589 && flag_unsafe_math_optimizations"
15590 {
15591 rtx temp;
15592
15593 operands[2] = gen_reg_rtx (XFmode);
15594 temp = standard_80387_constant_rtx (4); /* fldln2 */
15595 emit_move_insn (operands[2], temp);
15596 })
15597
15598 (define_expand "log10sf2"
15599 [(set (match_dup 2)
15600 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15601 (parallel [(set (match_dup 4)
15602 (unspec:XF [(match_dup 2)
15603 (match_dup 3)] UNSPEC_FYL2X))
15604 (clobber (match_scratch:XF 5 ""))])
15605 (set (match_operand:SF 0 "register_operand" "")
15606 (float_truncate:SF (match_dup 4)))]
15607 "TARGET_USE_FANCY_MATH_387
15608 && flag_unsafe_math_optimizations"
15609 {
15610 rtx temp;
15611
15612 operands[2] = gen_reg_rtx (XFmode);
15613 operands[3] = gen_reg_rtx (XFmode);
15614 operands[4] = gen_reg_rtx (XFmode);
15615
15616 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15617 emit_move_insn (operands[3], temp);
15618 })
15619
15620 (define_expand "log10df2"
15621 [(set (match_dup 2)
15622 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15623 (parallel [(set (match_dup 4)
15624 (unspec:XF [(match_dup 2)
15625 (match_dup 3)] UNSPEC_FYL2X))
15626 (clobber (match_scratch:XF 5 ""))])
15627 (set (match_operand:DF 0 "register_operand" "")
15628 (float_truncate:DF (match_dup 4)))]
15629 "TARGET_USE_FANCY_MATH_387
15630 && flag_unsafe_math_optimizations"
15631 {
15632 rtx temp;
15633
15634 operands[2] = gen_reg_rtx (XFmode);
15635 operands[3] = gen_reg_rtx (XFmode);
15636 operands[4] = gen_reg_rtx (XFmode);
15637
15638 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15639 emit_move_insn (operands[3], temp);
15640 })
15641
15642 (define_expand "log10xf2"
15643 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15644 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15645 (match_dup 2)] UNSPEC_FYL2X))
15646 (clobber (match_scratch:XF 3 ""))])]
15647 "TARGET_USE_FANCY_MATH_387
15648 && flag_unsafe_math_optimizations"
15649 {
15650 rtx temp;
15651
15652 operands[2] = gen_reg_rtx (XFmode);
15653 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15654 emit_move_insn (operands[2], temp);
15655 })
15656
15657 (define_expand "log2sf2"
15658 [(set (match_dup 2)
15659 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15660 (parallel [(set (match_dup 4)
15661 (unspec:XF [(match_dup 2)
15662 (match_dup 3)] UNSPEC_FYL2X))
15663 (clobber (match_scratch:XF 5 ""))])
15664 (set (match_operand:SF 0 "register_operand" "")
15665 (float_truncate:SF (match_dup 4)))]
15666 "TARGET_USE_FANCY_MATH_387
15667 && flag_unsafe_math_optimizations"
15668 {
15669 operands[2] = gen_reg_rtx (XFmode);
15670 operands[3] = gen_reg_rtx (XFmode);
15671 operands[4] = gen_reg_rtx (XFmode);
15672
15673 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15674 })
15675
15676 (define_expand "log2df2"
15677 [(set (match_dup 2)
15678 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15679 (parallel [(set (match_dup 4)
15680 (unspec:XF [(match_dup 2)
15681 (match_dup 3)] UNSPEC_FYL2X))
15682 (clobber (match_scratch:XF 5 ""))])
15683 (set (match_operand:DF 0 "register_operand" "")
15684 (float_truncate:DF (match_dup 4)))]
15685 "TARGET_USE_FANCY_MATH_387
15686 && flag_unsafe_math_optimizations"
15687 {
15688 operands[2] = gen_reg_rtx (XFmode);
15689 operands[3] = gen_reg_rtx (XFmode);
15690 operands[4] = gen_reg_rtx (XFmode);
15691
15692 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15693 })
15694
15695 (define_expand "log2xf2"
15696 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15697 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15698 (match_dup 2)] UNSPEC_FYL2X))
15699 (clobber (match_scratch:XF 3 ""))])]
15700 "TARGET_USE_FANCY_MATH_387
15701 && flag_unsafe_math_optimizations"
15702 {
15703 operands[2] = gen_reg_rtx (XFmode);
15704 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15705 })
15706
15707 (define_insn "fyl2xp1_xf3"
15708 [(set (match_operand:XF 0 "register_operand" "=f")
15709 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15710 (match_operand:XF 1 "register_operand" "u")]
15711 UNSPEC_FYL2XP1))
15712 (clobber (match_scratch:XF 3 "=1"))]
15713 "TARGET_USE_FANCY_MATH_387
15714 && flag_unsafe_math_optimizations"
15715 "fyl2xp1"
15716 [(set_attr "type" "fpspc")
15717 (set_attr "mode" "XF")])
15718
15719 (define_expand "log1psf2"
15720 [(use (match_operand:XF 0 "register_operand" ""))
15721 (use (match_operand:XF 1 "register_operand" ""))]
15722 "TARGET_USE_FANCY_MATH_387
15723 && flag_unsafe_math_optimizations"
15724 {
15725 rtx op0 = gen_reg_rtx (XFmode);
15726 rtx op1 = gen_reg_rtx (XFmode);
15727
15728 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15729 ix86_emit_i387_log1p (op0, op1);
15730 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15731 DONE;
15732 })
15733
15734 (define_expand "log1pdf2"
15735 [(use (match_operand:XF 0 "register_operand" ""))
15736 (use (match_operand:XF 1 "register_operand" ""))]
15737 "TARGET_USE_FANCY_MATH_387
15738 && flag_unsafe_math_optimizations"
15739 {
15740 rtx op0 = gen_reg_rtx (XFmode);
15741 rtx op1 = gen_reg_rtx (XFmode);
15742
15743 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15744 ix86_emit_i387_log1p (op0, op1);
15745 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15746 DONE;
15747 })
15748
15749 (define_expand "log1pxf2"
15750 [(use (match_operand:XF 0 "register_operand" ""))
15751 (use (match_operand:XF 1 "register_operand" ""))]
15752 "TARGET_USE_FANCY_MATH_387
15753 && flag_unsafe_math_optimizations"
15754 {
15755 ix86_emit_i387_log1p (operands[0], operands[1]);
15756 DONE;
15757 })
15758
15759 (define_insn "*fxtractxf3"
15760 [(set (match_operand:XF 0 "register_operand" "=f")
15761 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15762 UNSPEC_XTRACT_FRACT))
15763 (set (match_operand:XF 1 "register_operand" "=u")
15764 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15765 "TARGET_USE_FANCY_MATH_387
15766 && flag_unsafe_math_optimizations"
15767 "fxtract"
15768 [(set_attr "type" "fpspc")
15769 (set_attr "mode" "XF")])
15770
15771 (define_expand "logbsf2"
15772 [(set (match_dup 2)
15773 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15774 (parallel [(set (match_dup 3)
15775 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15776 (set (match_dup 4)
15777 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15778 (set (match_operand:SF 0 "register_operand" "")
15779 (float_truncate:SF (match_dup 4)))]
15780 "TARGET_USE_FANCY_MATH_387
15781 && flag_unsafe_math_optimizations"
15782 {
15783 operands[2] = gen_reg_rtx (XFmode);
15784 operands[3] = gen_reg_rtx (XFmode);
15785 operands[4] = gen_reg_rtx (XFmode);
15786 })
15787
15788 (define_expand "logbdf2"
15789 [(set (match_dup 2)
15790 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15791 (parallel [(set (match_dup 3)
15792 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15793 (set (match_dup 4)
15794 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15795 (set (match_operand:DF 0 "register_operand" "")
15796 (float_truncate:DF (match_dup 4)))]
15797 "TARGET_USE_FANCY_MATH_387
15798 && flag_unsafe_math_optimizations"
15799 {
15800 operands[2] = gen_reg_rtx (XFmode);
15801 operands[3] = gen_reg_rtx (XFmode);
15802 operands[4] = gen_reg_rtx (XFmode);
15803 })
15804
15805 (define_expand "logbxf2"
15806 [(parallel [(set (match_dup 2)
15807 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15808 UNSPEC_XTRACT_FRACT))
15809 (set (match_operand:XF 0 "register_operand" "")
15810 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15811 "TARGET_USE_FANCY_MATH_387
15812 && flag_unsafe_math_optimizations"
15813 {
15814 operands[2] = gen_reg_rtx (XFmode);
15815 })
15816
15817 (define_expand "ilogbsi2"
15818 [(parallel [(set (match_dup 2)
15819 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15820 UNSPEC_XTRACT_FRACT))
15821 (set (match_operand:XF 3 "register_operand" "")
15822 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15823 (parallel [(set (match_operand:SI 0 "register_operand" "")
15824 (fix:SI (match_dup 3)))
15825 (clobber (reg:CC FLAGS_REG))])]
15826 "TARGET_USE_FANCY_MATH_387
15827 && flag_unsafe_math_optimizations"
15828 {
15829 operands[2] = gen_reg_rtx (XFmode);
15830 operands[3] = gen_reg_rtx (XFmode);
15831 })
15832
15833 (define_insn "*f2xm1xf2"
15834 [(set (match_operand:XF 0 "register_operand" "=f")
15835 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15836 UNSPEC_F2XM1))]
15837 "TARGET_USE_FANCY_MATH_387
15838 && flag_unsafe_math_optimizations"
15839 "f2xm1"
15840 [(set_attr "type" "fpspc")
15841 (set_attr "mode" "XF")])
15842
15843 (define_insn "*fscalexf4"
15844 [(set (match_operand:XF 0 "register_operand" "=f")
15845 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15846 (match_operand:XF 3 "register_operand" "1")]
15847 UNSPEC_FSCALE_FRACT))
15848 (set (match_operand:XF 1 "register_operand" "=u")
15849 (unspec:XF [(match_dup 2) (match_dup 3)]
15850 UNSPEC_FSCALE_EXP))]
15851 "TARGET_USE_FANCY_MATH_387
15852 && flag_unsafe_math_optimizations"
15853 "fscale"
15854 [(set_attr "type" "fpspc")
15855 (set_attr "mode" "XF")])
15856
15857 (define_expand "expsf2"
15858 [(set (match_dup 2)
15859 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15860 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15861 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15862 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15863 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15864 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15865 (parallel [(set (match_dup 10)
15866 (unspec:XF [(match_dup 9) (match_dup 5)]
15867 UNSPEC_FSCALE_FRACT))
15868 (set (match_dup 11)
15869 (unspec:XF [(match_dup 9) (match_dup 5)]
15870 UNSPEC_FSCALE_EXP))])
15871 (set (match_operand:SF 0 "register_operand" "")
15872 (float_truncate:SF (match_dup 10)))]
15873 "TARGET_USE_FANCY_MATH_387
15874 && flag_unsafe_math_optimizations"
15875 {
15876 rtx temp;
15877 int i;
15878
15879 for (i=2; i<12; i++)
15880 operands[i] = gen_reg_rtx (XFmode);
15881 temp = standard_80387_constant_rtx (5); /* fldl2e */
15882 emit_move_insn (operands[3], temp);
15883 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15884 })
15885
15886 (define_expand "expdf2"
15887 [(set (match_dup 2)
15888 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15889 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15890 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15891 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15892 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15893 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15894 (parallel [(set (match_dup 10)
15895 (unspec:XF [(match_dup 9) (match_dup 5)]
15896 UNSPEC_FSCALE_FRACT))
15897 (set (match_dup 11)
15898 (unspec:XF [(match_dup 9) (match_dup 5)]
15899 UNSPEC_FSCALE_EXP))])
15900 (set (match_operand:DF 0 "register_operand" "")
15901 (float_truncate:DF (match_dup 10)))]
15902 "TARGET_USE_FANCY_MATH_387
15903 && flag_unsafe_math_optimizations"
15904 {
15905 rtx temp;
15906 int i;
15907
15908 for (i=2; i<12; i++)
15909 operands[i] = gen_reg_rtx (XFmode);
15910 temp = standard_80387_constant_rtx (5); /* fldl2e */
15911 emit_move_insn (operands[3], temp);
15912 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15913 })
15914
15915 (define_expand "expxf2"
15916 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15917 (match_dup 2)))
15918 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15919 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15920 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15921 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15922 (parallel [(set (match_operand:XF 0 "register_operand" "")
15923 (unspec:XF [(match_dup 8) (match_dup 4)]
15924 UNSPEC_FSCALE_FRACT))
15925 (set (match_dup 9)
15926 (unspec:XF [(match_dup 8) (match_dup 4)]
15927 UNSPEC_FSCALE_EXP))])]
15928 "TARGET_USE_FANCY_MATH_387
15929 && flag_unsafe_math_optimizations"
15930 {
15931 rtx temp;
15932 int i;
15933
15934 for (i=2; i<10; i++)
15935 operands[i] = gen_reg_rtx (XFmode);
15936 temp = standard_80387_constant_rtx (5); /* fldl2e */
15937 emit_move_insn (operands[2], temp);
15938 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15939 })
15940
15941 (define_expand "exp10sf2"
15942 [(set (match_dup 2)
15943 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15944 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15945 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15946 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15947 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15948 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15949 (parallel [(set (match_dup 10)
15950 (unspec:XF [(match_dup 9) (match_dup 5)]
15951 UNSPEC_FSCALE_FRACT))
15952 (set (match_dup 11)
15953 (unspec:XF [(match_dup 9) (match_dup 5)]
15954 UNSPEC_FSCALE_EXP))])
15955 (set (match_operand:SF 0 "register_operand" "")
15956 (float_truncate:SF (match_dup 10)))]
15957 "TARGET_USE_FANCY_MATH_387
15958 && flag_unsafe_math_optimizations"
15959 {
15960 rtx temp;
15961 int i;
15962
15963 for (i=2; i<12; i++)
15964 operands[i] = gen_reg_rtx (XFmode);
15965 temp = standard_80387_constant_rtx (6); /* fldl2t */
15966 emit_move_insn (operands[3], temp);
15967 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15968 })
15969
15970 (define_expand "exp10df2"
15971 [(set (match_dup 2)
15972 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15973 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15974 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15975 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15976 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15977 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15978 (parallel [(set (match_dup 10)
15979 (unspec:XF [(match_dup 9) (match_dup 5)]
15980 UNSPEC_FSCALE_FRACT))
15981 (set (match_dup 11)
15982 (unspec:XF [(match_dup 9) (match_dup 5)]
15983 UNSPEC_FSCALE_EXP))])
15984 (set (match_operand:DF 0 "register_operand" "")
15985 (float_truncate:DF (match_dup 10)))]
15986 "TARGET_USE_FANCY_MATH_387
15987 && flag_unsafe_math_optimizations"
15988 {
15989 rtx temp;
15990 int i;
15991
15992 for (i=2; i<12; i++)
15993 operands[i] = gen_reg_rtx (XFmode);
15994 temp = standard_80387_constant_rtx (6); /* fldl2t */
15995 emit_move_insn (operands[3], temp);
15996 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15997 })
15998
15999 (define_expand "exp10xf2"
16000 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16001 (match_dup 2)))
16002 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16003 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16004 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16005 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16006 (parallel [(set (match_operand:XF 0 "register_operand" "")
16007 (unspec:XF [(match_dup 8) (match_dup 4)]
16008 UNSPEC_FSCALE_FRACT))
16009 (set (match_dup 9)
16010 (unspec:XF [(match_dup 8) (match_dup 4)]
16011 UNSPEC_FSCALE_EXP))])]
16012 "TARGET_USE_FANCY_MATH_387
16013 && flag_unsafe_math_optimizations"
16014 {
16015 rtx temp;
16016 int i;
16017
16018 for (i=2; i<10; i++)
16019 operands[i] = gen_reg_rtx (XFmode);
16020 temp = standard_80387_constant_rtx (6); /* fldl2t */
16021 emit_move_insn (operands[2], temp);
16022 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16023 })
16024
16025 (define_expand "exp2sf2"
16026 [(set (match_dup 2)
16027 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16028 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16029 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16030 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16031 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16032 (parallel [(set (match_dup 8)
16033 (unspec:XF [(match_dup 7) (match_dup 3)]
16034 UNSPEC_FSCALE_FRACT))
16035 (set (match_dup 9)
16036 (unspec:XF [(match_dup 7) (match_dup 3)]
16037 UNSPEC_FSCALE_EXP))])
16038 (set (match_operand:SF 0 "register_operand" "")
16039 (float_truncate:SF (match_dup 8)))]
16040 "TARGET_USE_FANCY_MATH_387
16041 && flag_unsafe_math_optimizations"
16042 {
16043 int i;
16044
16045 for (i=2; i<10; i++)
16046 operands[i] = gen_reg_rtx (XFmode);
16047 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16048 })
16049
16050 (define_expand "exp2df2"
16051 [(set (match_dup 2)
16052 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16053 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16054 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16055 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16056 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16057 (parallel [(set (match_dup 8)
16058 (unspec:XF [(match_dup 7) (match_dup 3)]
16059 UNSPEC_FSCALE_FRACT))
16060 (set (match_dup 9)
16061 (unspec:XF [(match_dup 7) (match_dup 3)]
16062 UNSPEC_FSCALE_EXP))])
16063 (set (match_operand:DF 0 "register_operand" "")
16064 (float_truncate:DF (match_dup 8)))]
16065 "TARGET_USE_FANCY_MATH_387
16066 && flag_unsafe_math_optimizations"
16067 {
16068 int i;
16069
16070 for (i=2; i<10; i++)
16071 operands[i] = gen_reg_rtx (XFmode);
16072 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16073 })
16074
16075 (define_expand "exp2xf2"
16076 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16077 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16078 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16079 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16080 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16081 (parallel [(set (match_operand:XF 0 "register_operand" "")
16082 (unspec:XF [(match_dup 7) (match_dup 3)]
16083 UNSPEC_FSCALE_FRACT))
16084 (set (match_dup 8)
16085 (unspec:XF [(match_dup 7) (match_dup 3)]
16086 UNSPEC_FSCALE_EXP))])]
16087 "TARGET_USE_FANCY_MATH_387
16088 && flag_unsafe_math_optimizations"
16089 {
16090 int i;
16091
16092 for (i=2; i<9; i++)
16093 operands[i] = gen_reg_rtx (XFmode);
16094 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16095 })
16096
16097 (define_expand "expm1df2"
16098 [(set (match_dup 2)
16099 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16100 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16101 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16102 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16103 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16104 (parallel [(set (match_dup 8)
16105 (unspec:XF [(match_dup 7) (match_dup 5)]
16106 UNSPEC_FSCALE_FRACT))
16107 (set (match_dup 9)
16108 (unspec:XF [(match_dup 7) (match_dup 5)]
16109 UNSPEC_FSCALE_EXP))])
16110 (parallel [(set (match_dup 11)
16111 (unspec:XF [(match_dup 10) (match_dup 9)]
16112 UNSPEC_FSCALE_FRACT))
16113 (set (match_dup 12)
16114 (unspec:XF [(match_dup 10) (match_dup 9)]
16115 UNSPEC_FSCALE_EXP))])
16116 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16117 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16118 (set (match_operand:DF 0 "register_operand" "")
16119 (float_truncate:DF (match_dup 14)))]
16120 "TARGET_USE_FANCY_MATH_387
16121 && flag_unsafe_math_optimizations"
16122 {
16123 rtx temp;
16124 int i;
16125
16126 for (i=2; i<15; i++)
16127 operands[i] = gen_reg_rtx (XFmode);
16128 temp = standard_80387_constant_rtx (5); /* fldl2e */
16129 emit_move_insn (operands[3], temp);
16130 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16131 })
16132
16133 (define_expand "expm1sf2"
16134 [(set (match_dup 2)
16135 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16136 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16137 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16138 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16139 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16140 (parallel [(set (match_dup 8)
16141 (unspec:XF [(match_dup 7) (match_dup 5)]
16142 UNSPEC_FSCALE_FRACT))
16143 (set (match_dup 9)
16144 (unspec:XF [(match_dup 7) (match_dup 5)]
16145 UNSPEC_FSCALE_EXP))])
16146 (parallel [(set (match_dup 11)
16147 (unspec:XF [(match_dup 10) (match_dup 9)]
16148 UNSPEC_FSCALE_FRACT))
16149 (set (match_dup 12)
16150 (unspec:XF [(match_dup 10) (match_dup 9)]
16151 UNSPEC_FSCALE_EXP))])
16152 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16153 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16154 (set (match_operand:SF 0 "register_operand" "")
16155 (float_truncate:SF (match_dup 14)))]
16156 "TARGET_USE_FANCY_MATH_387
16157 && flag_unsafe_math_optimizations"
16158 {
16159 rtx temp;
16160 int i;
16161
16162 for (i=2; i<15; i++)
16163 operands[i] = gen_reg_rtx (XFmode);
16164 temp = standard_80387_constant_rtx (5); /* fldl2e */
16165 emit_move_insn (operands[3], temp);
16166 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16167 })
16168
16169 (define_expand "expm1xf2"
16170 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16171 (match_dup 2)))
16172 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16173 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16174 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16175 (parallel [(set (match_dup 7)
16176 (unspec:XF [(match_dup 6) (match_dup 4)]
16177 UNSPEC_FSCALE_FRACT))
16178 (set (match_dup 8)
16179 (unspec:XF [(match_dup 6) (match_dup 4)]
16180 UNSPEC_FSCALE_EXP))])
16181 (parallel [(set (match_dup 10)
16182 (unspec:XF [(match_dup 9) (match_dup 8)]
16183 UNSPEC_FSCALE_FRACT))
16184 (set (match_dup 11)
16185 (unspec:XF [(match_dup 9) (match_dup 8)]
16186 UNSPEC_FSCALE_EXP))])
16187 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16188 (set (match_operand:XF 0 "register_operand" "")
16189 (plus:XF (match_dup 12) (match_dup 7)))]
16190 "TARGET_USE_FANCY_MATH_387
16191 && flag_unsafe_math_optimizations"
16192 {
16193 rtx temp;
16194 int i;
16195
16196 for (i=2; i<13; i++)
16197 operands[i] = gen_reg_rtx (XFmode);
16198 temp = standard_80387_constant_rtx (5); /* fldl2e */
16199 emit_move_insn (operands[2], temp);
16200 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16201 })
16202 \f
16203
16204 (define_insn "frndintxf2"
16205 [(set (match_operand:XF 0 "register_operand" "=f")
16206 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16207 UNSPEC_FRNDINT))]
16208 "TARGET_USE_FANCY_MATH_387
16209 && flag_unsafe_math_optimizations"
16210 "frndint"
16211 [(set_attr "type" "fpspc")
16212 (set_attr "mode" "XF")])
16213
16214 (define_expand "rintdf2"
16215 [(use (match_operand:DF 0 "register_operand" ""))
16216 (use (match_operand:DF 1 "register_operand" ""))]
16217 "TARGET_USE_FANCY_MATH_387
16218 && flag_unsafe_math_optimizations"
16219 {
16220 rtx op0 = gen_reg_rtx (XFmode);
16221 rtx op1 = gen_reg_rtx (XFmode);
16222
16223 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16224 emit_insn (gen_frndintxf2 (op0, op1));
16225
16226 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16227 DONE;
16228 })
16229
16230 (define_expand "rintsf2"
16231 [(use (match_operand:SF 0 "register_operand" ""))
16232 (use (match_operand:SF 1 "register_operand" ""))]
16233 "TARGET_USE_FANCY_MATH_387
16234 && flag_unsafe_math_optimizations"
16235 {
16236 rtx op0 = gen_reg_rtx (XFmode);
16237 rtx op1 = gen_reg_rtx (XFmode);
16238
16239 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16240 emit_insn (gen_frndintxf2 (op0, op1));
16241
16242 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16243 DONE;
16244 })
16245
16246 (define_expand "rintxf2"
16247 [(use (match_operand:XF 0 "register_operand" ""))
16248 (use (match_operand:XF 1 "register_operand" ""))]
16249 "TARGET_USE_FANCY_MATH_387
16250 && flag_unsafe_math_optimizations"
16251 {
16252 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16253 DONE;
16254 })
16255
16256 (define_insn "frndintxf2_floor"
16257 [(set (match_operand:XF 0 "register_operand" "=f")
16258 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16259 UNSPEC_FRNDINT_FLOOR))
16260 (use (match_operand:HI 2 "memory_operand" "m"))
16261 (use (match_operand:HI 3 "memory_operand" "m"))]
16262 "TARGET_USE_FANCY_MATH_387
16263 && flag_unsafe_math_optimizations"
16264 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16265 [(set_attr "type" "frndint")
16266 (set_attr "i387_cw" "floor")
16267 (set_attr "mode" "XF")])
16268
16269 (define_expand "floordf2"
16270 [(use (match_operand:DF 0 "register_operand" ""))
16271 (use (match_operand:DF 1 "register_operand" ""))]
16272 "TARGET_USE_FANCY_MATH_387
16273 && flag_unsafe_math_optimizations"
16274 {
16275 rtx op0 = gen_reg_rtx (XFmode);
16276 rtx op1 = gen_reg_rtx (XFmode);
16277 rtx op2 = assign_386_stack_local (HImode, 1);
16278 rtx op3 = assign_386_stack_local (HImode, 2);
16279
16280 ix86_optimize_mode_switching = 1;
16281
16282 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16283 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16284
16285 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16286 DONE;
16287 })
16288
16289 (define_expand "floorsf2"
16290 [(use (match_operand:SF 0 "register_operand" ""))
16291 (use (match_operand:SF 1 "register_operand" ""))]
16292 "TARGET_USE_FANCY_MATH_387
16293 && flag_unsafe_math_optimizations"
16294 {
16295 rtx op0 = gen_reg_rtx (XFmode);
16296 rtx op1 = gen_reg_rtx (XFmode);
16297 rtx op2 = assign_386_stack_local (HImode, 1);
16298 rtx op3 = assign_386_stack_local (HImode, 2);
16299
16300 ix86_optimize_mode_switching = 1;
16301
16302 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16303 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16304
16305 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16306 DONE;
16307 })
16308
16309 (define_expand "floorxf2"
16310 [(use (match_operand:XF 0 "register_operand" ""))
16311 (use (match_operand:XF 1 "register_operand" ""))]
16312 "TARGET_USE_FANCY_MATH_387
16313 && flag_unsafe_math_optimizations"
16314 {
16315 rtx op2 = assign_386_stack_local (HImode, 1);
16316 rtx op3 = assign_386_stack_local (HImode, 2);
16317
16318 ix86_optimize_mode_switching = 1;
16319
16320 emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16321 DONE;
16322 })
16323
16324 (define_insn "frndintxf2_ceil"
16325 [(set (match_operand:XF 0 "register_operand" "=f")
16326 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16327 UNSPEC_FRNDINT_CEIL))
16328 (use (match_operand:HI 2 "memory_operand" "m"))
16329 (use (match_operand:HI 3 "memory_operand" "m"))]
16330 "TARGET_USE_FANCY_MATH_387
16331 && flag_unsafe_math_optimizations"
16332 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16333 [(set_attr "type" "frndint")
16334 (set_attr "i387_cw" "ceil")
16335 (set_attr "mode" "XF")])
16336
16337 (define_expand "ceildf2"
16338 [(use (match_operand:DF 0 "register_operand" ""))
16339 (use (match_operand:DF 1 "register_operand" ""))]
16340 "TARGET_USE_FANCY_MATH_387
16341 && flag_unsafe_math_optimizations"
16342 {
16343 rtx op0 = gen_reg_rtx (XFmode);
16344 rtx op1 = gen_reg_rtx (XFmode);
16345 rtx op2 = assign_386_stack_local (HImode, 1);
16346 rtx op3 = assign_386_stack_local (HImode, 2);
16347
16348 ix86_optimize_mode_switching = 1;
16349
16350 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16351 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16352
16353 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16354 DONE;
16355 })
16356
16357 (define_expand "ceilsf2"
16358 [(use (match_operand:SF 0 "register_operand" ""))
16359 (use (match_operand:SF 1 "register_operand" ""))]
16360 "TARGET_USE_FANCY_MATH_387
16361 && flag_unsafe_math_optimizations"
16362 {
16363 rtx op0 = gen_reg_rtx (XFmode);
16364 rtx op1 = gen_reg_rtx (XFmode);
16365 rtx op2 = assign_386_stack_local (HImode, 1);
16366 rtx op3 = assign_386_stack_local (HImode, 2);
16367
16368 ix86_optimize_mode_switching = 1;
16369
16370 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16371 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16372
16373 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16374 DONE;
16375 })
16376
16377 (define_expand "ceilxf2"
16378 [(use (match_operand:XF 0 "register_operand" ""))
16379 (use (match_operand:XF 1 "register_operand" ""))]
16380 "TARGET_USE_FANCY_MATH_387
16381 && flag_unsafe_math_optimizations"
16382 {
16383 rtx op2 = assign_386_stack_local (HImode, 1);
16384 rtx op3 = assign_386_stack_local (HImode, 2);
16385
16386 ix86_optimize_mode_switching = 1;
16387
16388 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16389 DONE;
16390 })
16391
16392 (define_insn "frndintxf2_trunc"
16393 [(set (match_operand:XF 0 "register_operand" "=f")
16394 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16395 UNSPEC_FRNDINT_TRUNC))
16396 (use (match_operand:HI 2 "memory_operand" "m"))
16397 (use (match_operand:HI 3 "memory_operand" "m"))]
16398 "TARGET_USE_FANCY_MATH_387
16399 && flag_unsafe_math_optimizations"
16400 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16401 [(set_attr "type" "frndint")
16402 (set_attr "i387_cw" "trunc")
16403 (set_attr "mode" "XF")])
16404
16405 (define_expand "btruncdf2"
16406 [(use (match_operand:DF 0 "register_operand" ""))
16407 (use (match_operand:DF 1 "register_operand" ""))]
16408 "TARGET_USE_FANCY_MATH_387
16409 && flag_unsafe_math_optimizations"
16410 {
16411 rtx op0 = gen_reg_rtx (XFmode);
16412 rtx op1 = gen_reg_rtx (XFmode);
16413 rtx op2 = assign_386_stack_local (HImode, 1);
16414 rtx op3 = assign_386_stack_local (HImode, 2);
16415
16416 ix86_optimize_mode_switching = 1;
16417
16418 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16419 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16420
16421 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16422 DONE;
16423 })
16424
16425 (define_expand "btruncsf2"
16426 [(use (match_operand:SF 0 "register_operand" ""))
16427 (use (match_operand:SF 1 "register_operand" ""))]
16428 "TARGET_USE_FANCY_MATH_387
16429 && flag_unsafe_math_optimizations"
16430 {
16431 rtx op0 = gen_reg_rtx (XFmode);
16432 rtx op1 = gen_reg_rtx (XFmode);
16433 rtx op2 = assign_386_stack_local (HImode, 1);
16434 rtx op3 = assign_386_stack_local (HImode, 2);
16435
16436 ix86_optimize_mode_switching = 1;
16437
16438 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16439 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16440
16441 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16442 DONE;
16443 })
16444
16445 (define_expand "btruncxf2"
16446 [(use (match_operand:XF 0 "register_operand" ""))
16447 (use (match_operand:XF 1 "register_operand" ""))]
16448 "TARGET_USE_FANCY_MATH_387
16449 && flag_unsafe_math_optimizations"
16450 {
16451 rtx op2 = assign_386_stack_local (HImode, 1);
16452 rtx op3 = assign_386_stack_local (HImode, 2);
16453
16454 ix86_optimize_mode_switching = 1;
16455
16456 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16457 DONE;
16458 })
16459
16460 (define_insn "frndintxf2_mask_pm"
16461 [(set (match_operand:XF 0 "register_operand" "=f")
16462 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16463 UNSPEC_FRNDINT_MASK_PM))
16464 (use (match_operand:HI 2 "memory_operand" "m"))
16465 (use (match_operand:HI 3 "memory_operand" "m"))]
16466 "TARGET_USE_FANCY_MATH_387
16467 && flag_unsafe_math_optimizations"
16468 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16469 [(set_attr "type" "frndint")
16470 (set_attr "i387_cw" "mask_pm")
16471 (set_attr "mode" "XF")])
16472
16473 (define_expand "nearbyintdf2"
16474 [(use (match_operand:DF 0 "register_operand" ""))
16475 (use (match_operand:DF 1 "register_operand" ""))]
16476 "TARGET_USE_FANCY_MATH_387
16477 && flag_unsafe_math_optimizations"
16478 {
16479 rtx op0 = gen_reg_rtx (XFmode);
16480 rtx op1 = gen_reg_rtx (XFmode);
16481 rtx op2 = assign_386_stack_local (HImode, 1);
16482 rtx op3 = assign_386_stack_local (HImode, 2);
16483
16484 ix86_optimize_mode_switching = 1;
16485
16486 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16487 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16488
16489 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16490 DONE;
16491 })
16492
16493 (define_expand "nearbyintsf2"
16494 [(use (match_operand:SF 0 "register_operand" ""))
16495 (use (match_operand:SF 1 "register_operand" ""))]
16496 "TARGET_USE_FANCY_MATH_387
16497 && flag_unsafe_math_optimizations"
16498 {
16499 rtx op0 = gen_reg_rtx (XFmode);
16500 rtx op1 = gen_reg_rtx (XFmode);
16501 rtx op2 = assign_386_stack_local (HImode, 1);
16502 rtx op3 = assign_386_stack_local (HImode, 2);
16503
16504 ix86_optimize_mode_switching = 1;
16505
16506 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16507 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16508
16509 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16510 DONE;
16511 })
16512
16513 (define_expand "nearbyintxf2"
16514 [(use (match_operand:XF 0 "register_operand" ""))
16515 (use (match_operand:XF 1 "register_operand" ""))]
16516 "TARGET_USE_FANCY_MATH_387
16517 && flag_unsafe_math_optimizations"
16518 {
16519 rtx op2 = assign_386_stack_local (HImode, 1);
16520 rtx op3 = assign_386_stack_local (HImode, 2);
16521
16522 ix86_optimize_mode_switching = 1;
16523
16524 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16525 op2, op3));
16526 DONE;
16527 })
16528
16529 \f
16530 ;; Block operation instructions
16531
16532 (define_insn "cld"
16533 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16534 ""
16535 "cld"
16536 [(set_attr "type" "cld")])
16537
16538 (define_expand "movmemsi"
16539 [(use (match_operand:BLK 0 "memory_operand" ""))
16540 (use (match_operand:BLK 1 "memory_operand" ""))
16541 (use (match_operand:SI 2 "nonmemory_operand" ""))
16542 (use (match_operand:SI 3 "const_int_operand" ""))]
16543 "! optimize_size"
16544 {
16545 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16546 DONE;
16547 else
16548 FAIL;
16549 })
16550
16551 (define_expand "movmemdi"
16552 [(use (match_operand:BLK 0 "memory_operand" ""))
16553 (use (match_operand:BLK 1 "memory_operand" ""))
16554 (use (match_operand:DI 2 "nonmemory_operand" ""))
16555 (use (match_operand:DI 3 "const_int_operand" ""))]
16556 "TARGET_64BIT"
16557 {
16558 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16559 DONE;
16560 else
16561 FAIL;
16562 })
16563
16564 ;; Most CPUs don't like single string operations
16565 ;; Handle this case here to simplify previous expander.
16566
16567 (define_expand "strmov"
16568 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16569 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16570 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16571 (clobber (reg:CC FLAGS_REG))])
16572 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16573 (clobber (reg:CC FLAGS_REG))])]
16574 ""
16575 {
16576 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16577
16578 /* If .md ever supports :P for Pmode, these can be directly
16579 in the pattern above. */
16580 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16581 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16582
16583 if (TARGET_SINGLE_STRINGOP || optimize_size)
16584 {
16585 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16586 operands[2], operands[3],
16587 operands[5], operands[6]));
16588 DONE;
16589 }
16590
16591 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16592 })
16593
16594 (define_expand "strmov_singleop"
16595 [(parallel [(set (match_operand 1 "memory_operand" "")
16596 (match_operand 3 "memory_operand" ""))
16597 (set (match_operand 0 "register_operand" "")
16598 (match_operand 4 "" ""))
16599 (set (match_operand 2 "register_operand" "")
16600 (match_operand 5 "" ""))
16601 (use (reg:SI DIRFLAG_REG))])]
16602 "TARGET_SINGLE_STRINGOP || optimize_size"
16603 "")
16604
16605 (define_insn "*strmovdi_rex_1"
16606 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16607 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16608 (set (match_operand:DI 0 "register_operand" "=D")
16609 (plus:DI (match_dup 2)
16610 (const_int 8)))
16611 (set (match_operand:DI 1 "register_operand" "=S")
16612 (plus:DI (match_dup 3)
16613 (const_int 8)))
16614 (use (reg:SI DIRFLAG_REG))]
16615 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16616 "movsq"
16617 [(set_attr "type" "str")
16618 (set_attr "mode" "DI")
16619 (set_attr "memory" "both")])
16620
16621 (define_insn "*strmovsi_1"
16622 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16623 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16624 (set (match_operand:SI 0 "register_operand" "=D")
16625 (plus:SI (match_dup 2)
16626 (const_int 4)))
16627 (set (match_operand:SI 1 "register_operand" "=S")
16628 (plus:SI (match_dup 3)
16629 (const_int 4)))
16630 (use (reg:SI DIRFLAG_REG))]
16631 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16632 "{movsl|movsd}"
16633 [(set_attr "type" "str")
16634 (set_attr "mode" "SI")
16635 (set_attr "memory" "both")])
16636
16637 (define_insn "*strmovsi_rex_1"
16638 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16639 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16640 (set (match_operand:DI 0 "register_operand" "=D")
16641 (plus:DI (match_dup 2)
16642 (const_int 4)))
16643 (set (match_operand:DI 1 "register_operand" "=S")
16644 (plus:DI (match_dup 3)
16645 (const_int 4)))
16646 (use (reg:SI DIRFLAG_REG))]
16647 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16648 "{movsl|movsd}"
16649 [(set_attr "type" "str")
16650 (set_attr "mode" "SI")
16651 (set_attr "memory" "both")])
16652
16653 (define_insn "*strmovhi_1"
16654 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16655 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16656 (set (match_operand:SI 0 "register_operand" "=D")
16657 (plus:SI (match_dup 2)
16658 (const_int 2)))
16659 (set (match_operand:SI 1 "register_operand" "=S")
16660 (plus:SI (match_dup 3)
16661 (const_int 2)))
16662 (use (reg:SI DIRFLAG_REG))]
16663 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16664 "movsw"
16665 [(set_attr "type" "str")
16666 (set_attr "memory" "both")
16667 (set_attr "mode" "HI")])
16668
16669 (define_insn "*strmovhi_rex_1"
16670 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16671 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16672 (set (match_operand:DI 0 "register_operand" "=D")
16673 (plus:DI (match_dup 2)
16674 (const_int 2)))
16675 (set (match_operand:DI 1 "register_operand" "=S")
16676 (plus:DI (match_dup 3)
16677 (const_int 2)))
16678 (use (reg:SI DIRFLAG_REG))]
16679 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16680 "movsw"
16681 [(set_attr "type" "str")
16682 (set_attr "memory" "both")
16683 (set_attr "mode" "HI")])
16684
16685 (define_insn "*strmovqi_1"
16686 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16687 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16688 (set (match_operand:SI 0 "register_operand" "=D")
16689 (plus:SI (match_dup 2)
16690 (const_int 1)))
16691 (set (match_operand:SI 1 "register_operand" "=S")
16692 (plus:SI (match_dup 3)
16693 (const_int 1)))
16694 (use (reg:SI DIRFLAG_REG))]
16695 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16696 "movsb"
16697 [(set_attr "type" "str")
16698 (set_attr "memory" "both")
16699 (set_attr "mode" "QI")])
16700
16701 (define_insn "*strmovqi_rex_1"
16702 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16703 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16704 (set (match_operand:DI 0 "register_operand" "=D")
16705 (plus:DI (match_dup 2)
16706 (const_int 1)))
16707 (set (match_operand:DI 1 "register_operand" "=S")
16708 (plus:DI (match_dup 3)
16709 (const_int 1)))
16710 (use (reg:SI DIRFLAG_REG))]
16711 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16712 "movsb"
16713 [(set_attr "type" "str")
16714 (set_attr "memory" "both")
16715 (set_attr "mode" "QI")])
16716
16717 (define_expand "rep_mov"
16718 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16719 (set (match_operand 0 "register_operand" "")
16720 (match_operand 5 "" ""))
16721 (set (match_operand 2 "register_operand" "")
16722 (match_operand 6 "" ""))
16723 (set (match_operand 1 "memory_operand" "")
16724 (match_operand 3 "memory_operand" ""))
16725 (use (match_dup 4))
16726 (use (reg:SI DIRFLAG_REG))])]
16727 ""
16728 "")
16729
16730 (define_insn "*rep_movdi_rex64"
16731 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16732 (set (match_operand:DI 0 "register_operand" "=D")
16733 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16734 (const_int 3))
16735 (match_operand:DI 3 "register_operand" "0")))
16736 (set (match_operand:DI 1 "register_operand" "=S")
16737 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16738 (match_operand:DI 4 "register_operand" "1")))
16739 (set (mem:BLK (match_dup 3))
16740 (mem:BLK (match_dup 4)))
16741 (use (match_dup 5))
16742 (use (reg:SI DIRFLAG_REG))]
16743 "TARGET_64BIT"
16744 "{rep\;movsq|rep movsq}"
16745 [(set_attr "type" "str")
16746 (set_attr "prefix_rep" "1")
16747 (set_attr "memory" "both")
16748 (set_attr "mode" "DI")])
16749
16750 (define_insn "*rep_movsi"
16751 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16752 (set (match_operand:SI 0 "register_operand" "=D")
16753 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16754 (const_int 2))
16755 (match_operand:SI 3 "register_operand" "0")))
16756 (set (match_operand:SI 1 "register_operand" "=S")
16757 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16758 (match_operand:SI 4 "register_operand" "1")))
16759 (set (mem:BLK (match_dup 3))
16760 (mem:BLK (match_dup 4)))
16761 (use (match_dup 5))
16762 (use (reg:SI DIRFLAG_REG))]
16763 "!TARGET_64BIT"
16764 "{rep\;movsl|rep movsd}"
16765 [(set_attr "type" "str")
16766 (set_attr "prefix_rep" "1")
16767 (set_attr "memory" "both")
16768 (set_attr "mode" "SI")])
16769
16770 (define_insn "*rep_movsi_rex64"
16771 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16772 (set (match_operand:DI 0 "register_operand" "=D")
16773 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16774 (const_int 2))
16775 (match_operand:DI 3 "register_operand" "0")))
16776 (set (match_operand:DI 1 "register_operand" "=S")
16777 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16778 (match_operand:DI 4 "register_operand" "1")))
16779 (set (mem:BLK (match_dup 3))
16780 (mem:BLK (match_dup 4)))
16781 (use (match_dup 5))
16782 (use (reg:SI DIRFLAG_REG))]
16783 "TARGET_64BIT"
16784 "{rep\;movsl|rep movsd}"
16785 [(set_attr "type" "str")
16786 (set_attr "prefix_rep" "1")
16787 (set_attr "memory" "both")
16788 (set_attr "mode" "SI")])
16789
16790 (define_insn "*rep_movqi"
16791 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16792 (set (match_operand:SI 0 "register_operand" "=D")
16793 (plus:SI (match_operand:SI 3 "register_operand" "0")
16794 (match_operand:SI 5 "register_operand" "2")))
16795 (set (match_operand:SI 1 "register_operand" "=S")
16796 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16797 (set (mem:BLK (match_dup 3))
16798 (mem:BLK (match_dup 4)))
16799 (use (match_dup 5))
16800 (use (reg:SI DIRFLAG_REG))]
16801 "!TARGET_64BIT"
16802 "{rep\;movsb|rep movsb}"
16803 [(set_attr "type" "str")
16804 (set_attr "prefix_rep" "1")
16805 (set_attr "memory" "both")
16806 (set_attr "mode" "SI")])
16807
16808 (define_insn "*rep_movqi_rex64"
16809 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16810 (set (match_operand:DI 0 "register_operand" "=D")
16811 (plus:DI (match_operand:DI 3 "register_operand" "0")
16812 (match_operand:DI 5 "register_operand" "2")))
16813 (set (match_operand:DI 1 "register_operand" "=S")
16814 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16815 (set (mem:BLK (match_dup 3))
16816 (mem:BLK (match_dup 4)))
16817 (use (match_dup 5))
16818 (use (reg:SI DIRFLAG_REG))]
16819 "TARGET_64BIT"
16820 "{rep\;movsb|rep movsb}"
16821 [(set_attr "type" "str")
16822 (set_attr "prefix_rep" "1")
16823 (set_attr "memory" "both")
16824 (set_attr "mode" "SI")])
16825
16826 (define_expand "clrmemsi"
16827 [(use (match_operand:BLK 0 "memory_operand" ""))
16828 (use (match_operand:SI 1 "nonmemory_operand" ""))
16829 (use (match_operand 2 "const_int_operand" ""))]
16830 ""
16831 {
16832 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16833 DONE;
16834 else
16835 FAIL;
16836 })
16837
16838 (define_expand "clrmemdi"
16839 [(use (match_operand:BLK 0 "memory_operand" ""))
16840 (use (match_operand:DI 1 "nonmemory_operand" ""))
16841 (use (match_operand 2 "const_int_operand" ""))]
16842 "TARGET_64BIT"
16843 {
16844 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
16845 DONE;
16846 else
16847 FAIL;
16848 })
16849
16850 ;; Most CPUs don't like single string operations
16851 ;; Handle this case here to simplify previous expander.
16852
16853 (define_expand "strset"
16854 [(set (match_operand 1 "memory_operand" "")
16855 (match_operand 2 "register_operand" ""))
16856 (parallel [(set (match_operand 0 "register_operand" "")
16857 (match_dup 3))
16858 (clobber (reg:CC FLAGS_REG))])]
16859 ""
16860 {
16861 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16862 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16863
16864 /* If .md ever supports :P for Pmode, this can be directly
16865 in the pattern above. */
16866 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16867 GEN_INT (GET_MODE_SIZE (GET_MODE
16868 (operands[2]))));
16869 if (TARGET_SINGLE_STRINGOP || optimize_size)
16870 {
16871 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16872 operands[3]));
16873 DONE;
16874 }
16875 })
16876
16877 (define_expand "strset_singleop"
16878 [(parallel [(set (match_operand 1 "memory_operand" "")
16879 (match_operand 2 "register_operand" ""))
16880 (set (match_operand 0 "register_operand" "")
16881 (match_operand 3 "" ""))
16882 (use (reg:SI DIRFLAG_REG))])]
16883 "TARGET_SINGLE_STRINGOP || optimize_size"
16884 "")
16885
16886 (define_insn "*strsetdi_rex_1"
16887 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16888 (match_operand:DI 2 "register_operand" "a"))
16889 (set (match_operand:DI 0 "register_operand" "=D")
16890 (plus:DI (match_dup 1)
16891 (const_int 8)))
16892 (use (reg:SI DIRFLAG_REG))]
16893 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16894 "stosq"
16895 [(set_attr "type" "str")
16896 (set_attr "memory" "store")
16897 (set_attr "mode" "DI")])
16898
16899 (define_insn "*strsetsi_1"
16900 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16901 (match_operand:SI 2 "register_operand" "a"))
16902 (set (match_operand:SI 0 "register_operand" "=D")
16903 (plus:SI (match_dup 1)
16904 (const_int 4)))
16905 (use (reg:SI DIRFLAG_REG))]
16906 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16907 "{stosl|stosd}"
16908 [(set_attr "type" "str")
16909 (set_attr "memory" "store")
16910 (set_attr "mode" "SI")])
16911
16912 (define_insn "*strsetsi_rex_1"
16913 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16914 (match_operand:SI 2 "register_operand" "a"))
16915 (set (match_operand:DI 0 "register_operand" "=D")
16916 (plus:DI (match_dup 1)
16917 (const_int 4)))
16918 (use (reg:SI DIRFLAG_REG))]
16919 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16920 "{stosl|stosd}"
16921 [(set_attr "type" "str")
16922 (set_attr "memory" "store")
16923 (set_attr "mode" "SI")])
16924
16925 (define_insn "*strsethi_1"
16926 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16927 (match_operand:HI 2 "register_operand" "a"))
16928 (set (match_operand:SI 0 "register_operand" "=D")
16929 (plus:SI (match_dup 1)
16930 (const_int 2)))
16931 (use (reg:SI DIRFLAG_REG))]
16932 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16933 "stosw"
16934 [(set_attr "type" "str")
16935 (set_attr "memory" "store")
16936 (set_attr "mode" "HI")])
16937
16938 (define_insn "*strsethi_rex_1"
16939 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16940 (match_operand:HI 2 "register_operand" "a"))
16941 (set (match_operand:DI 0 "register_operand" "=D")
16942 (plus:DI (match_dup 1)
16943 (const_int 2)))
16944 (use (reg:SI DIRFLAG_REG))]
16945 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16946 "stosw"
16947 [(set_attr "type" "str")
16948 (set_attr "memory" "store")
16949 (set_attr "mode" "HI")])
16950
16951 (define_insn "*strsetqi_1"
16952 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16953 (match_operand:QI 2 "register_operand" "a"))
16954 (set (match_operand:SI 0 "register_operand" "=D")
16955 (plus:SI (match_dup 1)
16956 (const_int 1)))
16957 (use (reg:SI DIRFLAG_REG))]
16958 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16959 "stosb"
16960 [(set_attr "type" "str")
16961 (set_attr "memory" "store")
16962 (set_attr "mode" "QI")])
16963
16964 (define_insn "*strsetqi_rex_1"
16965 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16966 (match_operand:QI 2 "register_operand" "a"))
16967 (set (match_operand:DI 0 "register_operand" "=D")
16968 (plus:DI (match_dup 1)
16969 (const_int 1)))
16970 (use (reg:SI DIRFLAG_REG))]
16971 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16972 "stosb"
16973 [(set_attr "type" "str")
16974 (set_attr "memory" "store")
16975 (set_attr "mode" "QI")])
16976
16977 (define_expand "rep_stos"
16978 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16979 (set (match_operand 0 "register_operand" "")
16980 (match_operand 4 "" ""))
16981 (set (match_operand 2 "memory_operand" "") (const_int 0))
16982 (use (match_operand 3 "register_operand" ""))
16983 (use (match_dup 1))
16984 (use (reg:SI DIRFLAG_REG))])]
16985 ""
16986 "")
16987
16988 (define_insn "*rep_stosdi_rex64"
16989 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16990 (set (match_operand:DI 0 "register_operand" "=D")
16991 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16992 (const_int 3))
16993 (match_operand:DI 3 "register_operand" "0")))
16994 (set (mem:BLK (match_dup 3))
16995 (const_int 0))
16996 (use (match_operand:DI 2 "register_operand" "a"))
16997 (use (match_dup 4))
16998 (use (reg:SI DIRFLAG_REG))]
16999 "TARGET_64BIT"
17000 "{rep\;stosq|rep stosq}"
17001 [(set_attr "type" "str")
17002 (set_attr "prefix_rep" "1")
17003 (set_attr "memory" "store")
17004 (set_attr "mode" "DI")])
17005
17006 (define_insn "*rep_stossi"
17007 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17008 (set (match_operand:SI 0 "register_operand" "=D")
17009 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17010 (const_int 2))
17011 (match_operand:SI 3 "register_operand" "0")))
17012 (set (mem:BLK (match_dup 3))
17013 (const_int 0))
17014 (use (match_operand:SI 2 "register_operand" "a"))
17015 (use (match_dup 4))
17016 (use (reg:SI DIRFLAG_REG))]
17017 "!TARGET_64BIT"
17018 "{rep\;stosl|rep stosd}"
17019 [(set_attr "type" "str")
17020 (set_attr "prefix_rep" "1")
17021 (set_attr "memory" "store")
17022 (set_attr "mode" "SI")])
17023
17024 (define_insn "*rep_stossi_rex64"
17025 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17026 (set (match_operand:DI 0 "register_operand" "=D")
17027 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17028 (const_int 2))
17029 (match_operand:DI 3 "register_operand" "0")))
17030 (set (mem:BLK (match_dup 3))
17031 (const_int 0))
17032 (use (match_operand:SI 2 "register_operand" "a"))
17033 (use (match_dup 4))
17034 (use (reg:SI DIRFLAG_REG))]
17035 "TARGET_64BIT"
17036 "{rep\;stosl|rep stosd}"
17037 [(set_attr "type" "str")
17038 (set_attr "prefix_rep" "1")
17039 (set_attr "memory" "store")
17040 (set_attr "mode" "SI")])
17041
17042 (define_insn "*rep_stosqi"
17043 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17044 (set (match_operand:SI 0 "register_operand" "=D")
17045 (plus:SI (match_operand:SI 3 "register_operand" "0")
17046 (match_operand:SI 4 "register_operand" "1")))
17047 (set (mem:BLK (match_dup 3))
17048 (const_int 0))
17049 (use (match_operand:QI 2 "register_operand" "a"))
17050 (use (match_dup 4))
17051 (use (reg:SI DIRFLAG_REG))]
17052 "!TARGET_64BIT"
17053 "{rep\;stosb|rep stosb}"
17054 [(set_attr "type" "str")
17055 (set_attr "prefix_rep" "1")
17056 (set_attr "memory" "store")
17057 (set_attr "mode" "QI")])
17058
17059 (define_insn "*rep_stosqi_rex64"
17060 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17061 (set (match_operand:DI 0 "register_operand" "=D")
17062 (plus:DI (match_operand:DI 3 "register_operand" "0")
17063 (match_operand:DI 4 "register_operand" "1")))
17064 (set (mem:BLK (match_dup 3))
17065 (const_int 0))
17066 (use (match_operand:QI 2 "register_operand" "a"))
17067 (use (match_dup 4))
17068 (use (reg:SI DIRFLAG_REG))]
17069 "TARGET_64BIT"
17070 "{rep\;stosb|rep stosb}"
17071 [(set_attr "type" "str")
17072 (set_attr "prefix_rep" "1")
17073 (set_attr "memory" "store")
17074 (set_attr "mode" "QI")])
17075
17076 (define_expand "cmpstrsi"
17077 [(set (match_operand:SI 0 "register_operand" "")
17078 (compare:SI (match_operand:BLK 1 "general_operand" "")
17079 (match_operand:BLK 2 "general_operand" "")))
17080 (use (match_operand 3 "general_operand" ""))
17081 (use (match_operand 4 "immediate_operand" ""))]
17082 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17083 {
17084 rtx addr1, addr2, out, outlow, count, countreg, align;
17085
17086 /* Can't use this if the user has appropriated esi or edi. */
17087 if (global_regs[4] || global_regs[5])
17088 FAIL;
17089
17090 out = operands[0];
17091 if (GET_CODE (out) != REG)
17092 out = gen_reg_rtx (SImode);
17093
17094 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17095 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17096 if (addr1 != XEXP (operands[1], 0))
17097 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17098 if (addr2 != XEXP (operands[2], 0))
17099 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17100
17101 count = operands[3];
17102 countreg = ix86_zero_extend_to_Pmode (count);
17103
17104 /* %%% Iff we are testing strict equality, we can use known alignment
17105 to good advantage. This may be possible with combine, particularly
17106 once cc0 is dead. */
17107 align = operands[4];
17108
17109 emit_insn (gen_cld ());
17110 if (GET_CODE (count) == CONST_INT)
17111 {
17112 if (INTVAL (count) == 0)
17113 {
17114 emit_move_insn (operands[0], const0_rtx);
17115 DONE;
17116 }
17117 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17118 operands[1], operands[2]));
17119 }
17120 else
17121 {
17122 if (TARGET_64BIT)
17123 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17124 else
17125 emit_insn (gen_cmpsi_1 (countreg, countreg));
17126 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17127 operands[1], operands[2]));
17128 }
17129
17130 outlow = gen_lowpart (QImode, out);
17131 emit_insn (gen_cmpintqi (outlow));
17132 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17133
17134 if (operands[0] != out)
17135 emit_move_insn (operands[0], out);
17136
17137 DONE;
17138 })
17139
17140 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17141
17142 (define_expand "cmpintqi"
17143 [(set (match_dup 1)
17144 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17145 (set (match_dup 2)
17146 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17147 (parallel [(set (match_operand:QI 0 "register_operand" "")
17148 (minus:QI (match_dup 1)
17149 (match_dup 2)))
17150 (clobber (reg:CC FLAGS_REG))])]
17151 ""
17152 "operands[1] = gen_reg_rtx (QImode);
17153 operands[2] = gen_reg_rtx (QImode);")
17154
17155 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17156 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17157
17158 (define_expand "cmpstrqi_nz_1"
17159 [(parallel [(set (reg:CC FLAGS_REG)
17160 (compare:CC (match_operand 4 "memory_operand" "")
17161 (match_operand 5 "memory_operand" "")))
17162 (use (match_operand 2 "register_operand" ""))
17163 (use (match_operand:SI 3 "immediate_operand" ""))
17164 (use (reg:SI DIRFLAG_REG))
17165 (clobber (match_operand 0 "register_operand" ""))
17166 (clobber (match_operand 1 "register_operand" ""))
17167 (clobber (match_dup 2))])]
17168 ""
17169 "")
17170
17171 (define_insn "*cmpstrqi_nz_1"
17172 [(set (reg:CC FLAGS_REG)
17173 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17174 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17175 (use (match_operand:SI 6 "register_operand" "2"))
17176 (use (match_operand:SI 3 "immediate_operand" "i"))
17177 (use (reg:SI DIRFLAG_REG))
17178 (clobber (match_operand:SI 0 "register_operand" "=S"))
17179 (clobber (match_operand:SI 1 "register_operand" "=D"))
17180 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17181 "!TARGET_64BIT"
17182 "repz{\;| }cmpsb"
17183 [(set_attr "type" "str")
17184 (set_attr "mode" "QI")
17185 (set_attr "prefix_rep" "1")])
17186
17187 (define_insn "*cmpstrqi_nz_rex_1"
17188 [(set (reg:CC FLAGS_REG)
17189 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17190 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17191 (use (match_operand:DI 6 "register_operand" "2"))
17192 (use (match_operand:SI 3 "immediate_operand" "i"))
17193 (use (reg:SI DIRFLAG_REG))
17194 (clobber (match_operand:DI 0 "register_operand" "=S"))
17195 (clobber (match_operand:DI 1 "register_operand" "=D"))
17196 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17197 "TARGET_64BIT"
17198 "repz{\;| }cmpsb"
17199 [(set_attr "type" "str")
17200 (set_attr "mode" "QI")
17201 (set_attr "prefix_rep" "1")])
17202
17203 ;; The same, but the count is not known to not be zero.
17204
17205 (define_expand "cmpstrqi_1"
17206 [(parallel [(set (reg:CC FLAGS_REG)
17207 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17208 (const_int 0))
17209 (compare:CC (match_operand 4 "memory_operand" "")
17210 (match_operand 5 "memory_operand" ""))
17211 (const_int 0)))
17212 (use (match_operand:SI 3 "immediate_operand" ""))
17213 (use (reg:CC FLAGS_REG))
17214 (use (reg:SI DIRFLAG_REG))
17215 (clobber (match_operand 0 "register_operand" ""))
17216 (clobber (match_operand 1 "register_operand" ""))
17217 (clobber (match_dup 2))])]
17218 ""
17219 "")
17220
17221 (define_insn "*cmpstrqi_1"
17222 [(set (reg:CC FLAGS_REG)
17223 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17224 (const_int 0))
17225 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17226 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17227 (const_int 0)))
17228 (use (match_operand:SI 3 "immediate_operand" "i"))
17229 (use (reg:CC FLAGS_REG))
17230 (use (reg:SI DIRFLAG_REG))
17231 (clobber (match_operand:SI 0 "register_operand" "=S"))
17232 (clobber (match_operand:SI 1 "register_operand" "=D"))
17233 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17234 "!TARGET_64BIT"
17235 "repz{\;| }cmpsb"
17236 [(set_attr "type" "str")
17237 (set_attr "mode" "QI")
17238 (set_attr "prefix_rep" "1")])
17239
17240 (define_insn "*cmpstrqi_rex_1"
17241 [(set (reg:CC FLAGS_REG)
17242 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17243 (const_int 0))
17244 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17245 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17246 (const_int 0)))
17247 (use (match_operand:SI 3 "immediate_operand" "i"))
17248 (use (reg:CC FLAGS_REG))
17249 (use (reg:SI DIRFLAG_REG))
17250 (clobber (match_operand:DI 0 "register_operand" "=S"))
17251 (clobber (match_operand:DI 1 "register_operand" "=D"))
17252 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17253 "TARGET_64BIT"
17254 "repz{\;| }cmpsb"
17255 [(set_attr "type" "str")
17256 (set_attr "mode" "QI")
17257 (set_attr "prefix_rep" "1")])
17258
17259 (define_expand "strlensi"
17260 [(set (match_operand:SI 0 "register_operand" "")
17261 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17262 (match_operand:QI 2 "immediate_operand" "")
17263 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17264 ""
17265 {
17266 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17267 DONE;
17268 else
17269 FAIL;
17270 })
17271
17272 (define_expand "strlendi"
17273 [(set (match_operand:DI 0 "register_operand" "")
17274 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17275 (match_operand:QI 2 "immediate_operand" "")
17276 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17277 ""
17278 {
17279 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17280 DONE;
17281 else
17282 FAIL;
17283 })
17284
17285 (define_expand "strlenqi_1"
17286 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17287 (use (reg:SI DIRFLAG_REG))
17288 (clobber (match_operand 1 "register_operand" ""))
17289 (clobber (reg:CC FLAGS_REG))])]
17290 ""
17291 "")
17292
17293 (define_insn "*strlenqi_1"
17294 [(set (match_operand:SI 0 "register_operand" "=&c")
17295 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17296 (match_operand:QI 2 "register_operand" "a")
17297 (match_operand:SI 3 "immediate_operand" "i")
17298 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17299 (use (reg:SI DIRFLAG_REG))
17300 (clobber (match_operand:SI 1 "register_operand" "=D"))
17301 (clobber (reg:CC FLAGS_REG))]
17302 "!TARGET_64BIT"
17303 "repnz{\;| }scasb"
17304 [(set_attr "type" "str")
17305 (set_attr "mode" "QI")
17306 (set_attr "prefix_rep" "1")])
17307
17308 (define_insn "*strlenqi_rex_1"
17309 [(set (match_operand:DI 0 "register_operand" "=&c")
17310 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17311 (match_operand:QI 2 "register_operand" "a")
17312 (match_operand:DI 3 "immediate_operand" "i")
17313 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17314 (use (reg:SI DIRFLAG_REG))
17315 (clobber (match_operand:DI 1 "register_operand" "=D"))
17316 (clobber (reg:CC FLAGS_REG))]
17317 "TARGET_64BIT"
17318 "repnz{\;| }scasb"
17319 [(set_attr "type" "str")
17320 (set_attr "mode" "QI")
17321 (set_attr "prefix_rep" "1")])
17322
17323 ;; Peephole optimizations to clean up after cmpstr*. This should be
17324 ;; handled in combine, but it is not currently up to the task.
17325 ;; When used for their truth value, the cmpstr* expanders generate
17326 ;; code like this:
17327 ;;
17328 ;; repz cmpsb
17329 ;; seta %al
17330 ;; setb %dl
17331 ;; cmpb %al, %dl
17332 ;; jcc label
17333 ;;
17334 ;; The intermediate three instructions are unnecessary.
17335
17336 ;; This one handles cmpstr*_nz_1...
17337 (define_peephole2
17338 [(parallel[
17339 (set (reg:CC FLAGS_REG)
17340 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17341 (mem:BLK (match_operand 5 "register_operand" ""))))
17342 (use (match_operand 6 "register_operand" ""))
17343 (use (match_operand:SI 3 "immediate_operand" ""))
17344 (use (reg:SI DIRFLAG_REG))
17345 (clobber (match_operand 0 "register_operand" ""))
17346 (clobber (match_operand 1 "register_operand" ""))
17347 (clobber (match_operand 2 "register_operand" ""))])
17348 (set (match_operand:QI 7 "register_operand" "")
17349 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17350 (set (match_operand:QI 8 "register_operand" "")
17351 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17352 (set (reg FLAGS_REG)
17353 (compare (match_dup 7) (match_dup 8)))
17354 ]
17355 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17356 [(parallel[
17357 (set (reg:CC FLAGS_REG)
17358 (compare:CC (mem:BLK (match_dup 4))
17359 (mem:BLK (match_dup 5))))
17360 (use (match_dup 6))
17361 (use (match_dup 3))
17362 (use (reg:SI DIRFLAG_REG))
17363 (clobber (match_dup 0))
17364 (clobber (match_dup 1))
17365 (clobber (match_dup 2))])]
17366 "")
17367
17368 ;; ...and this one handles cmpstr*_1.
17369 (define_peephole2
17370 [(parallel[
17371 (set (reg:CC FLAGS_REG)
17372 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17373 (const_int 0))
17374 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17375 (mem:BLK (match_operand 5 "register_operand" "")))
17376 (const_int 0)))
17377 (use (match_operand:SI 3 "immediate_operand" ""))
17378 (use (reg:CC FLAGS_REG))
17379 (use (reg:SI DIRFLAG_REG))
17380 (clobber (match_operand 0 "register_operand" ""))
17381 (clobber (match_operand 1 "register_operand" ""))
17382 (clobber (match_operand 2 "register_operand" ""))])
17383 (set (match_operand:QI 7 "register_operand" "")
17384 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17385 (set (match_operand:QI 8 "register_operand" "")
17386 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17387 (set (reg FLAGS_REG)
17388 (compare (match_dup 7) (match_dup 8)))
17389 ]
17390 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17391 [(parallel[
17392 (set (reg:CC FLAGS_REG)
17393 (if_then_else:CC (ne (match_dup 6)
17394 (const_int 0))
17395 (compare:CC (mem:BLK (match_dup 4))
17396 (mem:BLK (match_dup 5)))
17397 (const_int 0)))
17398 (use (match_dup 3))
17399 (use (reg:CC FLAGS_REG))
17400 (use (reg:SI DIRFLAG_REG))
17401 (clobber (match_dup 0))
17402 (clobber (match_dup 1))
17403 (clobber (match_dup 2))])]
17404 "")
17405
17406
17407 \f
17408 ;; Conditional move instructions.
17409
17410 (define_expand "movdicc"
17411 [(set (match_operand:DI 0 "register_operand" "")
17412 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17413 (match_operand:DI 2 "general_operand" "")
17414 (match_operand:DI 3 "general_operand" "")))]
17415 "TARGET_64BIT"
17416 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17417
17418 (define_insn "x86_movdicc_0_m1_rex64"
17419 [(set (match_operand:DI 0 "register_operand" "=r")
17420 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17421 (const_int -1)
17422 (const_int 0)))
17423 (clobber (reg:CC FLAGS_REG))]
17424 "TARGET_64BIT"
17425 "sbb{q}\t%0, %0"
17426 ; Since we don't have the proper number of operands for an alu insn,
17427 ; fill in all the blanks.
17428 [(set_attr "type" "alu")
17429 (set_attr "pent_pair" "pu")
17430 (set_attr "memory" "none")
17431 (set_attr "imm_disp" "false")
17432 (set_attr "mode" "DI")
17433 (set_attr "length_immediate" "0")])
17434
17435 (define_insn "movdicc_c_rex64"
17436 [(set (match_operand:DI 0 "register_operand" "=r,r")
17437 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17438 [(reg FLAGS_REG) (const_int 0)])
17439 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17440 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17441 "TARGET_64BIT && TARGET_CMOVE
17442 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17443 "@
17444 cmov%O2%C1\t{%2, %0|%0, %2}
17445 cmov%O2%c1\t{%3, %0|%0, %3}"
17446 [(set_attr "type" "icmov")
17447 (set_attr "mode" "DI")])
17448
17449 (define_expand "movsicc"
17450 [(set (match_operand:SI 0 "register_operand" "")
17451 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17452 (match_operand:SI 2 "general_operand" "")
17453 (match_operand:SI 3 "general_operand" "")))]
17454 ""
17455 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17456
17457 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17458 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17459 ;; So just document what we're doing explicitly.
17460
17461 (define_insn "x86_movsicc_0_m1"
17462 [(set (match_operand:SI 0 "register_operand" "=r")
17463 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17464 (const_int -1)
17465 (const_int 0)))
17466 (clobber (reg:CC FLAGS_REG))]
17467 ""
17468 "sbb{l}\t%0, %0"
17469 ; Since we don't have the proper number of operands for an alu insn,
17470 ; fill in all the blanks.
17471 [(set_attr "type" "alu")
17472 (set_attr "pent_pair" "pu")
17473 (set_attr "memory" "none")
17474 (set_attr "imm_disp" "false")
17475 (set_attr "mode" "SI")
17476 (set_attr "length_immediate" "0")])
17477
17478 (define_insn "*movsicc_noc"
17479 [(set (match_operand:SI 0 "register_operand" "=r,r")
17480 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17481 [(reg FLAGS_REG) (const_int 0)])
17482 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17483 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17484 "TARGET_CMOVE
17485 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17486 "@
17487 cmov%O2%C1\t{%2, %0|%0, %2}
17488 cmov%O2%c1\t{%3, %0|%0, %3}"
17489 [(set_attr "type" "icmov")
17490 (set_attr "mode" "SI")])
17491
17492 (define_expand "movhicc"
17493 [(set (match_operand:HI 0 "register_operand" "")
17494 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17495 (match_operand:HI 2 "general_operand" "")
17496 (match_operand:HI 3 "general_operand" "")))]
17497 "TARGET_HIMODE_MATH"
17498 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17499
17500 (define_insn "*movhicc_noc"
17501 [(set (match_operand:HI 0 "register_operand" "=r,r")
17502 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17503 [(reg FLAGS_REG) (const_int 0)])
17504 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17505 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17506 "TARGET_CMOVE
17507 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17508 "@
17509 cmov%O2%C1\t{%2, %0|%0, %2}
17510 cmov%O2%c1\t{%3, %0|%0, %3}"
17511 [(set_attr "type" "icmov")
17512 (set_attr "mode" "HI")])
17513
17514 (define_expand "movqicc"
17515 [(set (match_operand:QI 0 "register_operand" "")
17516 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17517 (match_operand:QI 2 "general_operand" "")
17518 (match_operand:QI 3 "general_operand" "")))]
17519 "TARGET_QIMODE_MATH"
17520 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17521
17522 (define_insn_and_split "*movqicc_noc"
17523 [(set (match_operand:QI 0 "register_operand" "=r,r")
17524 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17525 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17526 (match_operand:QI 2 "register_operand" "r,0")
17527 (match_operand:QI 3 "register_operand" "0,r")))]
17528 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17529 "#"
17530 "&& reload_completed"
17531 [(set (match_dup 0)
17532 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17533 (match_dup 2)
17534 (match_dup 3)))]
17535 "operands[0] = gen_lowpart (SImode, operands[0]);
17536 operands[2] = gen_lowpart (SImode, operands[2]);
17537 operands[3] = gen_lowpart (SImode, operands[3]);"
17538 [(set_attr "type" "icmov")
17539 (set_attr "mode" "SI")])
17540
17541 (define_expand "movsfcc"
17542 [(set (match_operand:SF 0 "register_operand" "")
17543 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17544 (match_operand:SF 2 "register_operand" "")
17545 (match_operand:SF 3 "register_operand" "")))]
17546 "TARGET_CMOVE"
17547 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17548
17549 (define_insn "*movsfcc_1"
17550 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17551 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17552 [(reg FLAGS_REG) (const_int 0)])
17553 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17554 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17555 "TARGET_CMOVE
17556 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17557 "@
17558 fcmov%F1\t{%2, %0|%0, %2}
17559 fcmov%f1\t{%3, %0|%0, %3}
17560 cmov%O2%C1\t{%2, %0|%0, %2}
17561 cmov%O2%c1\t{%3, %0|%0, %3}"
17562 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17563 (set_attr "mode" "SF,SF,SI,SI")])
17564
17565 (define_expand "movdfcc"
17566 [(set (match_operand:DF 0 "register_operand" "")
17567 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17568 (match_operand:DF 2 "register_operand" "")
17569 (match_operand:DF 3 "register_operand" "")))]
17570 "TARGET_CMOVE"
17571 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17572
17573 (define_insn "*movdfcc_1"
17574 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17575 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17576 [(reg FLAGS_REG) (const_int 0)])
17577 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17578 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17579 "!TARGET_64BIT && TARGET_CMOVE
17580 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17581 "@
17582 fcmov%F1\t{%2, %0|%0, %2}
17583 fcmov%f1\t{%3, %0|%0, %3}
17584 #
17585 #"
17586 [(set_attr "type" "fcmov,fcmov,multi,multi")
17587 (set_attr "mode" "DF")])
17588
17589 (define_insn "*movdfcc_1_rex64"
17590 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17591 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17592 [(reg FLAGS_REG) (const_int 0)])
17593 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17594 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17595 "TARGET_64BIT && TARGET_CMOVE
17596 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17597 "@
17598 fcmov%F1\t{%2, %0|%0, %2}
17599 fcmov%f1\t{%3, %0|%0, %3}
17600 cmov%O2%C1\t{%2, %0|%0, %2}
17601 cmov%O2%c1\t{%3, %0|%0, %3}"
17602 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17603 (set_attr "mode" "DF")])
17604
17605 (define_split
17606 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17607 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17608 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17609 (match_operand:DF 2 "nonimmediate_operand" "")
17610 (match_operand:DF 3 "nonimmediate_operand" "")))]
17611 "!TARGET_64BIT && reload_completed"
17612 [(set (match_dup 2)
17613 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17614 (match_dup 5)
17615 (match_dup 7)))
17616 (set (match_dup 3)
17617 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17618 (match_dup 6)
17619 (match_dup 8)))]
17620 "split_di (operands+2, 1, operands+5, operands+6);
17621 split_di (operands+3, 1, operands+7, operands+8);
17622 split_di (operands, 1, operands+2, operands+3);")
17623
17624 (define_expand "movxfcc"
17625 [(set (match_operand:XF 0 "register_operand" "")
17626 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17627 (match_operand:XF 2 "register_operand" "")
17628 (match_operand:XF 3 "register_operand" "")))]
17629 "TARGET_CMOVE"
17630 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17631
17632 (define_insn "*movxfcc_1"
17633 [(set (match_operand:XF 0 "register_operand" "=f,f")
17634 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17635 [(reg FLAGS_REG) (const_int 0)])
17636 (match_operand:XF 2 "register_operand" "f,0")
17637 (match_operand:XF 3 "register_operand" "0,f")))]
17638 "TARGET_CMOVE"
17639 "@
17640 fcmov%F1\t{%2, %0|%0, %2}
17641 fcmov%f1\t{%3, %0|%0, %3}"
17642 [(set_attr "type" "fcmov")
17643 (set_attr "mode" "XF")])
17644
17645 (define_expand "minsf3"
17646 [(parallel [
17647 (set (match_operand:SF 0 "register_operand" "")
17648 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17649 (match_operand:SF 2 "nonimmediate_operand" ""))
17650 (match_dup 1)
17651 (match_dup 2)))
17652 (clobber (reg:CC FLAGS_REG))])]
17653 "TARGET_SSE"
17654 "")
17655
17656 (define_insn "*minsf"
17657 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17658 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17659 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17660 (match_dup 1)
17661 (match_dup 2)))
17662 (clobber (reg:CC FLAGS_REG))]
17663 "TARGET_SSE && TARGET_IEEE_FP"
17664 "#")
17665
17666 (define_insn "*minsf_nonieee"
17667 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17668 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17669 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17670 (match_dup 1)
17671 (match_dup 2)))
17672 (clobber (reg:CC FLAGS_REG))]
17673 "TARGET_SSE && !TARGET_IEEE_FP
17674 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17675 "#")
17676
17677 (define_split
17678 [(set (match_operand:SF 0 "register_operand" "")
17679 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17680 (match_operand:SF 2 "nonimmediate_operand" ""))
17681 (match_operand:SF 3 "register_operand" "")
17682 (match_operand:SF 4 "nonimmediate_operand" "")))
17683 (clobber (reg:CC FLAGS_REG))]
17684 "SSE_REG_P (operands[0]) && reload_completed
17685 && ((operands_match_p (operands[1], operands[3])
17686 && operands_match_p (operands[2], operands[4]))
17687 || (operands_match_p (operands[1], operands[4])
17688 && operands_match_p (operands[2], operands[3])))"
17689 [(set (match_dup 0)
17690 (if_then_else:SF (lt (match_dup 1)
17691 (match_dup 2))
17692 (match_dup 1)
17693 (match_dup 2)))])
17694
17695 ;; Conditional addition patterns
17696 (define_expand "addqicc"
17697 [(match_operand:QI 0 "register_operand" "")
17698 (match_operand 1 "comparison_operator" "")
17699 (match_operand:QI 2 "register_operand" "")
17700 (match_operand:QI 3 "const_int_operand" "")]
17701 ""
17702 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17703
17704 (define_expand "addhicc"
17705 [(match_operand:HI 0 "register_operand" "")
17706 (match_operand 1 "comparison_operator" "")
17707 (match_operand:HI 2 "register_operand" "")
17708 (match_operand:HI 3 "const_int_operand" "")]
17709 ""
17710 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17711
17712 (define_expand "addsicc"
17713 [(match_operand:SI 0 "register_operand" "")
17714 (match_operand 1 "comparison_operator" "")
17715 (match_operand:SI 2 "register_operand" "")
17716 (match_operand:SI 3 "const_int_operand" "")]
17717 ""
17718 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17719
17720 (define_expand "adddicc"
17721 [(match_operand:DI 0 "register_operand" "")
17722 (match_operand 1 "comparison_operator" "")
17723 (match_operand:DI 2 "register_operand" "")
17724 (match_operand:DI 3 "const_int_operand" "")]
17725 "TARGET_64BIT"
17726 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17727
17728 ;; We can't represent the LT test directly. Do this by swapping the operands.
17729
17730 (define_split
17731 [(set (match_operand:SF 0 "fp_register_operand" "")
17732 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17733 (match_operand:SF 2 "register_operand" ""))
17734 (match_operand:SF 3 "register_operand" "")
17735 (match_operand:SF 4 "register_operand" "")))
17736 (clobber (reg:CC FLAGS_REG))]
17737 "reload_completed
17738 && ((operands_match_p (operands[1], operands[3])
17739 && operands_match_p (operands[2], operands[4]))
17740 || (operands_match_p (operands[1], operands[4])
17741 && operands_match_p (operands[2], operands[3])))"
17742 [(set (reg:CCFP FLAGS_REG)
17743 (compare:CCFP (match_dup 2)
17744 (match_dup 1)))
17745 (set (match_dup 0)
17746 (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17747 (match_dup 1)
17748 (match_dup 2)))])
17749
17750 (define_insn "*minsf_sse"
17751 [(set (match_operand:SF 0 "register_operand" "=x")
17752 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17753 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17754 (match_dup 1)
17755 (match_dup 2)))]
17756 "TARGET_SSE && reload_completed"
17757 "minss\t{%2, %0|%0, %2}"
17758 [(set_attr "type" "sse")
17759 (set_attr "mode" "SF")])
17760
17761 (define_expand "mindf3"
17762 [(parallel [
17763 (set (match_operand:DF 0 "register_operand" "")
17764 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17765 (match_operand:DF 2 "nonimmediate_operand" ""))
17766 (match_dup 1)
17767 (match_dup 2)))
17768 (clobber (reg:CC FLAGS_REG))])]
17769 "TARGET_SSE2 && TARGET_SSE_MATH"
17770 "#")
17771
17772 (define_insn "*mindf"
17773 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17774 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17775 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17776 (match_dup 1)
17777 (match_dup 2)))
17778 (clobber (reg:CC FLAGS_REG))]
17779 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17780 "#")
17781
17782 (define_insn "*mindf_nonieee"
17783 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17784 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17785 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17786 (match_dup 1)
17787 (match_dup 2)))
17788 (clobber (reg:CC FLAGS_REG))]
17789 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17790 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17791 "#")
17792
17793 (define_split
17794 [(set (match_operand:DF 0 "register_operand" "")
17795 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17796 (match_operand:DF 2 "nonimmediate_operand" ""))
17797 (match_operand:DF 3 "register_operand" "")
17798 (match_operand:DF 4 "nonimmediate_operand" "")))
17799 (clobber (reg:CC FLAGS_REG))]
17800 "SSE_REG_P (operands[0]) && reload_completed
17801 && ((operands_match_p (operands[1], operands[3])
17802 && operands_match_p (operands[2], operands[4]))
17803 || (operands_match_p (operands[1], operands[4])
17804 && operands_match_p (operands[2], operands[3])))"
17805 [(set (match_dup 0)
17806 (if_then_else:DF (lt (match_dup 1)
17807 (match_dup 2))
17808 (match_dup 1)
17809 (match_dup 2)))])
17810
17811 ;; We can't represent the LT test directly. Do this by swapping the operands.
17812 (define_split
17813 [(set (match_operand:DF 0 "fp_register_operand" "")
17814 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17815 (match_operand:DF 2 "register_operand" ""))
17816 (match_operand:DF 3 "register_operand" "")
17817 (match_operand:DF 4 "register_operand" "")))
17818 (clobber (reg:CC FLAGS_REG))]
17819 "reload_completed
17820 && ((operands_match_p (operands[1], operands[3])
17821 && operands_match_p (operands[2], operands[4]))
17822 || (operands_match_p (operands[1], operands[4])
17823 && operands_match_p (operands[2], operands[3])))"
17824 [(set (reg:CCFP FLAGS_REG)
17825 (compare:CCFP (match_dup 2)
17826 (match_dup 1)))
17827 (set (match_dup 0)
17828 (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17829 (match_dup 1)
17830 (match_dup 2)))])
17831
17832 (define_insn "*mindf_sse"
17833 [(set (match_operand:DF 0 "register_operand" "=Y")
17834 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17835 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17836 (match_dup 1)
17837 (match_dup 2)))]
17838 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17839 "minsd\t{%2, %0|%0, %2}"
17840 [(set_attr "type" "sse")
17841 (set_attr "mode" "DF")])
17842
17843 (define_expand "maxsf3"
17844 [(parallel [
17845 (set (match_operand:SF 0 "register_operand" "")
17846 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17847 (match_operand:SF 2 "nonimmediate_operand" ""))
17848 (match_dup 1)
17849 (match_dup 2)))
17850 (clobber (reg:CC FLAGS_REG))])]
17851 "TARGET_SSE"
17852 "#")
17853
17854 (define_insn "*maxsf"
17855 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17856 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17857 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17858 (match_dup 1)
17859 (match_dup 2)))
17860 (clobber (reg:CC FLAGS_REG))]
17861 "TARGET_SSE && TARGET_IEEE_FP"
17862 "#")
17863
17864 (define_insn "*maxsf_nonieee"
17865 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17866 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17867 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17868 (match_dup 1)
17869 (match_dup 2)))
17870 (clobber (reg:CC FLAGS_REG))]
17871 "TARGET_SSE && !TARGET_IEEE_FP
17872 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17873 "#")
17874
17875 (define_split
17876 [(set (match_operand:SF 0 "register_operand" "")
17877 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17878 (match_operand:SF 2 "nonimmediate_operand" ""))
17879 (match_operand:SF 3 "register_operand" "")
17880 (match_operand:SF 4 "nonimmediate_operand" "")))
17881 (clobber (reg:CC FLAGS_REG))]
17882 "SSE_REG_P (operands[0]) && reload_completed
17883 && ((operands_match_p (operands[1], operands[3])
17884 && operands_match_p (operands[2], operands[4]))
17885 || (operands_match_p (operands[1], operands[4])
17886 && operands_match_p (operands[2], operands[3])))"
17887 [(set (match_dup 0)
17888 (if_then_else:SF (gt (match_dup 1)
17889 (match_dup 2))
17890 (match_dup 1)
17891 (match_dup 2)))])
17892
17893 (define_split
17894 [(set (match_operand:SF 0 "fp_register_operand" "")
17895 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17896 (match_operand:SF 2 "register_operand" ""))
17897 (match_operand:SF 3 "register_operand" "")
17898 (match_operand:SF 4 "register_operand" "")))
17899 (clobber (reg:CC FLAGS_REG))]
17900 "reload_completed
17901 && ((operands_match_p (operands[1], operands[3])
17902 && operands_match_p (operands[2], operands[4]))
17903 || (operands_match_p (operands[1], operands[4])
17904 && operands_match_p (operands[2], operands[3])))"
17905 [(set (reg:CCFP FLAGS_REG)
17906 (compare:CCFP (match_dup 1)
17907 (match_dup 2)))
17908 (set (match_dup 0)
17909 (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17910 (match_dup 1)
17911 (match_dup 2)))])
17912
17913 (define_insn "*maxsf_sse"
17914 [(set (match_operand:SF 0 "register_operand" "=x")
17915 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17916 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17917 (match_dup 1)
17918 (match_dup 2)))]
17919 "TARGET_SSE && reload_completed"
17920 "maxss\t{%2, %0|%0, %2}"
17921 [(set_attr "type" "sse")
17922 (set_attr "mode" "SF")])
17923
17924 (define_expand "maxdf3"
17925 [(parallel [
17926 (set (match_operand:DF 0 "register_operand" "")
17927 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17928 (match_operand:DF 2 "nonimmediate_operand" ""))
17929 (match_dup 1)
17930 (match_dup 2)))
17931 (clobber (reg:CC FLAGS_REG))])]
17932 "TARGET_SSE2 && TARGET_SSE_MATH"
17933 "#")
17934
17935 (define_insn "*maxdf"
17936 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17937 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17938 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17939 (match_dup 1)
17940 (match_dup 2)))
17941 (clobber (reg:CC FLAGS_REG))]
17942 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17943 "#")
17944
17945 (define_insn "*maxdf_nonieee"
17946 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17947 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17948 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17949 (match_dup 1)
17950 (match_dup 2)))
17951 (clobber (reg:CC FLAGS_REG))]
17952 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17953 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17954 "#")
17955
17956 (define_split
17957 [(set (match_operand:DF 0 "register_operand" "")
17958 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17959 (match_operand:DF 2 "nonimmediate_operand" ""))
17960 (match_operand:DF 3 "register_operand" "")
17961 (match_operand:DF 4 "nonimmediate_operand" "")))
17962 (clobber (reg:CC FLAGS_REG))]
17963 "SSE_REG_P (operands[0]) && reload_completed
17964 && ((operands_match_p (operands[1], operands[3])
17965 && operands_match_p (operands[2], operands[4]))
17966 || (operands_match_p (operands[1], operands[4])
17967 && operands_match_p (operands[2], operands[3])))"
17968 [(set (match_dup 0)
17969 (if_then_else:DF (gt (match_dup 1)
17970 (match_dup 2))
17971 (match_dup 1)
17972 (match_dup 2)))])
17973
17974 (define_split
17975 [(set (match_operand:DF 0 "fp_register_operand" "")
17976 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17977 (match_operand:DF 2 "register_operand" ""))
17978 (match_operand:DF 3 "register_operand" "")
17979 (match_operand:DF 4 "register_operand" "")))
17980 (clobber (reg:CC FLAGS_REG))]
17981 "reload_completed
17982 && ((operands_match_p (operands[1], operands[3])
17983 && operands_match_p (operands[2], operands[4]))
17984 || (operands_match_p (operands[1], operands[4])
17985 && operands_match_p (operands[2], operands[3])))"
17986 [(set (reg:CCFP FLAGS_REG)
17987 (compare:CCFP (match_dup 1)
17988 (match_dup 2)))
17989 (set (match_dup 0)
17990 (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
17991 (match_dup 1)
17992 (match_dup 2)))])
17993
17994 (define_insn "*maxdf_sse"
17995 [(set (match_operand:DF 0 "register_operand" "=Y")
17996 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17997 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17998 (match_dup 1)
17999 (match_dup 2)))]
18000 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18001 "maxsd\t{%2, %0|%0, %2}"
18002 [(set_attr "type" "sse")
18003 (set_attr "mode" "DF")])
18004 \f
18005 ;; Misc patterns (?)
18006
18007 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18008 ;; Otherwise there will be nothing to keep
18009 ;;
18010 ;; [(set (reg ebp) (reg esp))]
18011 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18012 ;; (clobber (eflags)]
18013 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18014 ;;
18015 ;; in proper program order.
18016 (define_insn "pro_epilogue_adjust_stack_1"
18017 [(set (match_operand:SI 0 "register_operand" "=r,r")
18018 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18019 (match_operand:SI 2 "immediate_operand" "i,i")))
18020 (clobber (reg:CC FLAGS_REG))
18021 (clobber (mem:BLK (scratch)))]
18022 "!TARGET_64BIT"
18023 {
18024 switch (get_attr_type (insn))
18025 {
18026 case TYPE_IMOV:
18027 return "mov{l}\t{%1, %0|%0, %1}";
18028
18029 case TYPE_ALU:
18030 if (GET_CODE (operands[2]) == CONST_INT
18031 && (INTVAL (operands[2]) == 128
18032 || (INTVAL (operands[2]) < 0
18033 && INTVAL (operands[2]) != -128)))
18034 {
18035 operands[2] = GEN_INT (-INTVAL (operands[2]));
18036 return "sub{l}\t{%2, %0|%0, %2}";
18037 }
18038 return "add{l}\t{%2, %0|%0, %2}";
18039
18040 case TYPE_LEA:
18041 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18042 return "lea{l}\t{%a2, %0|%0, %a2}";
18043
18044 default:
18045 abort ();
18046 }
18047 }
18048 [(set (attr "type")
18049 (cond [(eq_attr "alternative" "0")
18050 (const_string "alu")
18051 (match_operand:SI 2 "const0_operand" "")
18052 (const_string "imov")
18053 ]
18054 (const_string "lea")))
18055 (set_attr "mode" "SI")])
18056
18057 (define_insn "pro_epilogue_adjust_stack_rex64"
18058 [(set (match_operand:DI 0 "register_operand" "=r,r")
18059 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18060 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18061 (clobber (reg:CC FLAGS_REG))
18062 (clobber (mem:BLK (scratch)))]
18063 "TARGET_64BIT"
18064 {
18065 switch (get_attr_type (insn))
18066 {
18067 case TYPE_IMOV:
18068 return "mov{q}\t{%1, %0|%0, %1}";
18069
18070 case TYPE_ALU:
18071 if (GET_CODE (operands[2]) == CONST_INT
18072 /* Avoid overflows. */
18073 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18074 && (INTVAL (operands[2]) == 128
18075 || (INTVAL (operands[2]) < 0
18076 && INTVAL (operands[2]) != -128)))
18077 {
18078 operands[2] = GEN_INT (-INTVAL (operands[2]));
18079 return "sub{q}\t{%2, %0|%0, %2}";
18080 }
18081 return "add{q}\t{%2, %0|%0, %2}";
18082
18083 case TYPE_LEA:
18084 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18085 return "lea{q}\t{%a2, %0|%0, %a2}";
18086
18087 default:
18088 abort ();
18089 }
18090 }
18091 [(set (attr "type")
18092 (cond [(eq_attr "alternative" "0")
18093 (const_string "alu")
18094 (match_operand:DI 2 "const0_operand" "")
18095 (const_string "imov")
18096 ]
18097 (const_string "lea")))
18098 (set_attr "mode" "DI")])
18099
18100 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18101 [(set (match_operand:DI 0 "register_operand" "=r,r")
18102 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18103 (match_operand:DI 3 "immediate_operand" "i,i")))
18104 (use (match_operand:DI 2 "register_operand" "r,r"))
18105 (clobber (reg:CC FLAGS_REG))
18106 (clobber (mem:BLK (scratch)))]
18107 "TARGET_64BIT"
18108 {
18109 switch (get_attr_type (insn))
18110 {
18111 case TYPE_ALU:
18112 return "add{q}\t{%2, %0|%0, %2}";
18113
18114 case TYPE_LEA:
18115 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18116 return "lea{q}\t{%a2, %0|%0, %a2}";
18117
18118 default:
18119 abort ();
18120 }
18121 }
18122 [(set_attr "type" "alu,lea")
18123 (set_attr "mode" "DI")])
18124
18125 ;; Placeholder for the conditional moves. This one is split either to SSE
18126 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
18127 ;; fact is that compares supported by the cmp??ss instructions are exactly
18128 ;; swapped of those supported by cmove sequence.
18129 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18130 ;; supported by i387 comparisons and we do need to emit two conditional moves
18131 ;; in tandem.
18132
18133 (define_insn "sse_movsfcc"
18134 [(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")
18135 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18136 [(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")
18137 (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")])
18138 (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")
18139 (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")))
18140 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18141 (clobber (reg:CC FLAGS_REG))]
18142 "TARGET_SSE
18143 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18144 /* Avoid combine from being smart and converting min/max
18145 instruction patterns into conditional moves. */
18146 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18147 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18148 || !rtx_equal_p (operands[4], operands[2])
18149 || !rtx_equal_p (operands[5], operands[3]))
18150 && (!TARGET_IEEE_FP
18151 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18152 "#")
18153
18154 (define_insn "sse_movsfcc_eq"
18155 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18156 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18157 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18158 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18159 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18160 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18161 (clobber (reg:CC FLAGS_REG))]
18162 "TARGET_SSE
18163 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18164 "#")
18165
18166 (define_insn "sse_movdfcc"
18167 [(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")
18168 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18169 [(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")
18170 (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")])
18171 (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")
18172 (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")))
18173 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18174 (clobber (reg:CC FLAGS_REG))]
18175 "TARGET_SSE2
18176 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18177 /* Avoid combine from being smart and converting min/max
18178 instruction patterns into conditional moves. */
18179 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18180 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18181 || !rtx_equal_p (operands[4], operands[2])
18182 || !rtx_equal_p (operands[5], operands[3]))
18183 && (!TARGET_IEEE_FP
18184 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18185 "#")
18186
18187 (define_insn "sse_movdfcc_eq"
18188 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18189 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18190 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18191 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18192 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18193 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18194 (clobber (reg:CC FLAGS_REG))]
18195 "TARGET_SSE
18196 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18197 "#")
18198
18199 ;; For non-sse moves just expand the usual cmove sequence.
18200 (define_split
18201 [(set (match_operand 0 "register_operand" "")
18202 (if_then_else (match_operator 1 "comparison_operator"
18203 [(match_operand 4 "nonimmediate_operand" "")
18204 (match_operand 5 "register_operand" "")])
18205 (match_operand 2 "nonimmediate_operand" "")
18206 (match_operand 3 "nonimmediate_operand" "")))
18207 (clobber (match_operand 6 "" ""))
18208 (clobber (reg:CC FLAGS_REG))]
18209 "!SSE_REG_P (operands[0]) && reload_completed
18210 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18211 [(const_int 0)]
18212 {
18213 ix86_compare_op0 = operands[5];
18214 ix86_compare_op1 = operands[4];
18215 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18216 VOIDmode, operands[5], operands[4]);
18217 ix86_expand_fp_movcc (operands);
18218 DONE;
18219 })
18220
18221 ;; Split SSE based conditional move into sequence:
18222 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
18223 ;; and op2, op0 - zero op2 if comparison was false
18224 ;; nand op0, op3 - load op3 to op0 if comparison was false
18225 ;; or op2, op0 - get the nonzero one into the result.
18226 (define_split
18227 [(set (match_operand:SF 0 "register_operand" "")
18228 (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18229 [(match_operand:SF 4 "register_operand" "")
18230 (match_operand:SF 5 "nonimmediate_operand" "")])
18231 (match_operand:SF 2 "register_operand" "")
18232 (match_operand:SF 3 "register_operand" "")))
18233 (clobber (match_operand 6 "" ""))
18234 (clobber (reg:CC FLAGS_REG))]
18235 "SSE_REG_P (operands[0]) && reload_completed"
18236 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18237 (set (match_dup 2) (and:V4SF (match_dup 2)
18238 (match_dup 8)))
18239 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18240 (match_dup 3)))
18241 (set (match_dup 0) (ior:V4SF (match_dup 6)
18242 (match_dup 7)))]
18243 {
18244 /* If op2 == op3, op3 would be clobbered before it is used. */
18245 if (operands_match_p (operands[2], operands[3]))
18246 {
18247 emit_move_insn (operands[0], operands[2]);
18248 DONE;
18249 }
18250
18251 PUT_MODE (operands[1], GET_MODE (operands[0]));
18252 if (operands_match_p (operands[0], operands[4]))
18253 operands[6] = operands[4], operands[7] = operands[2];
18254 else
18255 operands[6] = operands[2], operands[7] = operands[4];
18256 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18257 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18258 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18259 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18260 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18261 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18262 })
18263
18264 (define_split
18265 [(set (match_operand:DF 0 "register_operand" "")
18266 (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18267 [(match_operand:DF 4 "register_operand" "")
18268 (match_operand:DF 5 "nonimmediate_operand" "")])
18269 (match_operand:DF 2 "register_operand" "")
18270 (match_operand:DF 3 "register_operand" "")))
18271 (clobber (match_operand 6 "" ""))
18272 (clobber (reg:CC FLAGS_REG))]
18273 "SSE_REG_P (operands[0]) && reload_completed"
18274 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18275 (set (match_dup 2) (and:V2DF (match_dup 2)
18276 (match_dup 8)))
18277 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18278 (match_dup 3)))
18279 (set (match_dup 0) (ior:V2DF (match_dup 6)
18280 (match_dup 7)))]
18281 {
18282 if (GET_MODE (operands[2]) == DFmode
18283 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18284 {
18285 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18286 emit_insn (gen_sse2_unpcklpd (op, op, op));
18287 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18288 emit_insn (gen_sse2_unpcklpd (op, op, op));
18289 }
18290
18291 /* If op2 == op3, op3 would be clobbered before it is used. */
18292 if (operands_match_p (operands[2], operands[3]))
18293 {
18294 emit_move_insn (operands[0], operands[2]);
18295 DONE;
18296 }
18297
18298 PUT_MODE (operands[1], GET_MODE (operands[0]));
18299 if (operands_match_p (operands[0], operands[4]))
18300 operands[6] = operands[4], operands[7] = operands[2];
18301 else
18302 operands[6] = operands[2], operands[7] = operands[4];
18303 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18304 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18305 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18306 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18307 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18308 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18309 })
18310
18311 ;; Special case of conditional move we can handle effectively.
18312 ;; Do not brother with the integer/floating point case, since these are
18313 ;; bot considerably slower, unlike in the generic case.
18314 (define_insn "*sse_movsfcc_const0_1"
18315 [(set (match_operand:SF 0 "register_operand" "=&x")
18316 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18317 [(match_operand:SF 4 "register_operand" "0")
18318 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18319 (match_operand:SF 2 "register_operand" "x")
18320 (match_operand:SF 3 "const0_operand" "X")))]
18321 "TARGET_SSE"
18322 "#")
18323
18324 (define_insn "*sse_movsfcc_const0_2"
18325 [(set (match_operand:SF 0 "register_operand" "=&x")
18326 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18327 [(match_operand:SF 4 "register_operand" "0")
18328 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18329 (match_operand:SF 2 "const0_operand" "X")
18330 (match_operand:SF 3 "register_operand" "x")))]
18331 "TARGET_SSE"
18332 "#")
18333
18334 (define_insn "*sse_movsfcc_const0_3"
18335 [(set (match_operand:SF 0 "register_operand" "=&x")
18336 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18337 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18338 (match_operand:SF 5 "register_operand" "0")])
18339 (match_operand:SF 2 "register_operand" "x")
18340 (match_operand:SF 3 "const0_operand" "X")))]
18341 "TARGET_SSE"
18342 "#")
18343
18344 (define_insn "*sse_movsfcc_const0_4"
18345 [(set (match_operand:SF 0 "register_operand" "=&x")
18346 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18347 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18348 (match_operand:SF 5 "register_operand" "0")])
18349 (match_operand:SF 2 "const0_operand" "X")
18350 (match_operand:SF 3 "register_operand" "x")))]
18351 "TARGET_SSE"
18352 "#")
18353
18354 (define_insn "*sse_movdfcc_const0_1"
18355 [(set (match_operand:DF 0 "register_operand" "=&Y")
18356 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18357 [(match_operand:DF 4 "register_operand" "0")
18358 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18359 (match_operand:DF 2 "register_operand" "Y")
18360 (match_operand:DF 3 "const0_operand" "X")))]
18361 "TARGET_SSE2"
18362 "#")
18363
18364 (define_insn "*sse_movdfcc_const0_2"
18365 [(set (match_operand:DF 0 "register_operand" "=&Y")
18366 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18367 [(match_operand:DF 4 "register_operand" "0")
18368 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18369 (match_operand:DF 2 "const0_operand" "X")
18370 (match_operand:DF 3 "register_operand" "Y")))]
18371 "TARGET_SSE2"
18372 "#")
18373
18374 (define_insn "*sse_movdfcc_const0_3"
18375 [(set (match_operand:DF 0 "register_operand" "=&Y")
18376 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18377 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18378 (match_operand:DF 5 "register_operand" "0")])
18379 (match_operand:DF 2 "register_operand" "Y")
18380 (match_operand:DF 3 "const0_operand" "X")))]
18381 "TARGET_SSE2"
18382 "#")
18383
18384 (define_insn "*sse_movdfcc_const0_4"
18385 [(set (match_operand:DF 0 "register_operand" "=&Y")
18386 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18387 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18388 (match_operand:DF 5 "register_operand" "0")])
18389 (match_operand:DF 2 "const0_operand" "X")
18390 (match_operand:DF 3 "register_operand" "Y")))]
18391 "TARGET_SSE2"
18392 "#")
18393
18394 (define_split
18395 [(set (match_operand:SF 0 "register_operand" "")
18396 (if_then_else (match_operator 1 "comparison_operator"
18397 [(match_operand:SF 4 "nonimmediate_operand" "")
18398 (match_operand:SF 5 "nonimmediate_operand" "")])
18399 (match_operand:SF 2 "nonmemory_operand" "")
18400 (match_operand:SF 3 "nonmemory_operand" "")))]
18401 "SSE_REG_P (operands[0]) && reload_completed
18402 && (const0_operand (operands[2], GET_MODE (operands[0]))
18403 || const0_operand (operands[3], GET_MODE (operands[0])))"
18404 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18405 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18406 {
18407 PUT_MODE (operands[1], GET_MODE (operands[0]));
18408 if (!sse_comparison_operator (operands[1], VOIDmode)
18409 || !rtx_equal_p (operands[0], operands[4]))
18410 {
18411 rtx tmp = operands[5];
18412 operands[5] = operands[4];
18413 operands[4] = tmp;
18414 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18415 }
18416 if (!rtx_equal_p (operands[0], operands[4]))
18417 abort ();
18418 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18419 if (const0_operand (operands[2], GET_MODE (operands[2])))
18420 {
18421 operands[7] = operands[3];
18422 operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18423 }
18424 else
18425 {
18426 operands[7] = operands[2];
18427 operands[6] = operands[8];
18428 }
18429 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18430 })
18431
18432 (define_split
18433 [(set (match_operand:DF 0 "register_operand" "")
18434 (if_then_else (match_operator 1 "comparison_operator"
18435 [(match_operand:DF 4 "nonimmediate_operand" "")
18436 (match_operand:DF 5 "nonimmediate_operand" "")])
18437 (match_operand:DF 2 "nonmemory_operand" "")
18438 (match_operand:DF 3 "nonmemory_operand" "")))]
18439 "SSE_REG_P (operands[0]) && reload_completed
18440 && (const0_operand (operands[2], GET_MODE (operands[0]))
18441 || const0_operand (operands[3], GET_MODE (operands[0])))"
18442 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18443 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18444 {
18445 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18446 && GET_MODE (operands[2]) == DFmode)
18447 {
18448 if (REG_P (operands[2]))
18449 {
18450 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18451 emit_insn (gen_sse2_unpcklpd (op, op, op));
18452 }
18453 if (REG_P (operands[3]))
18454 {
18455 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18456 emit_insn (gen_sse2_unpcklpd (op, op, op));
18457 }
18458 }
18459 PUT_MODE (operands[1], GET_MODE (operands[0]));
18460 if (!sse_comparison_operator (operands[1], VOIDmode)
18461 || !rtx_equal_p (operands[0], operands[4]))
18462 {
18463 rtx tmp = operands[5];
18464 operands[5] = operands[4];
18465 operands[4] = tmp;
18466 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18467 }
18468 if (!rtx_equal_p (operands[0], operands[4]))
18469 abort ();
18470 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18471 if (const0_operand (operands[2], GET_MODE (operands[2])))
18472 {
18473 operands[7] = operands[3];
18474 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18475 }
18476 else
18477 {
18478 operands[7] = operands[2];
18479 operands[6] = operands[8];
18480 }
18481 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18482 })
18483
18484 (define_expand "allocate_stack_worker"
18485 [(match_operand:SI 0 "register_operand" "")]
18486 "TARGET_STACK_PROBE"
18487 {
18488 if (reload_completed)
18489 {
18490 if (TARGET_64BIT)
18491 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18492 else
18493 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18494 }
18495 else
18496 {
18497 if (TARGET_64BIT)
18498 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18499 else
18500 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18501 }
18502 DONE;
18503 })
18504
18505 (define_insn "allocate_stack_worker_1"
18506 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18507 UNSPECV_STACK_PROBE)
18508 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18509 (clobber (match_scratch:SI 1 "=0"))
18510 (clobber (reg:CC FLAGS_REG))]
18511 "!TARGET_64BIT && TARGET_STACK_PROBE"
18512 "call\t__alloca"
18513 [(set_attr "type" "multi")
18514 (set_attr "length" "5")])
18515
18516 (define_expand "allocate_stack_worker_postreload"
18517 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18518 UNSPECV_STACK_PROBE)
18519 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18520 (clobber (match_dup 0))
18521 (clobber (reg:CC FLAGS_REG))])]
18522 ""
18523 "")
18524
18525 (define_insn "allocate_stack_worker_rex64"
18526 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18527 UNSPECV_STACK_PROBE)
18528 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18529 (clobber (match_scratch:DI 1 "=0"))
18530 (clobber (reg:CC FLAGS_REG))]
18531 "TARGET_64BIT && TARGET_STACK_PROBE"
18532 "call\t__alloca"
18533 [(set_attr "type" "multi")
18534 (set_attr "length" "5")])
18535
18536 (define_expand "allocate_stack_worker_rex64_postreload"
18537 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18538 UNSPECV_STACK_PROBE)
18539 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18540 (clobber (match_dup 0))
18541 (clobber (reg:CC FLAGS_REG))])]
18542 ""
18543 "")
18544
18545 (define_expand "allocate_stack"
18546 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18547 (minus:SI (reg:SI SP_REG)
18548 (match_operand:SI 1 "general_operand" "")))
18549 (clobber (reg:CC FLAGS_REG))])
18550 (parallel [(set (reg:SI SP_REG)
18551 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18552 (clobber (reg:CC FLAGS_REG))])]
18553 "TARGET_STACK_PROBE"
18554 {
18555 #ifdef CHECK_STACK_LIMIT
18556 if (GET_CODE (operands[1]) == CONST_INT
18557 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18558 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18559 operands[1]));
18560 else
18561 #endif
18562 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18563 operands[1])));
18564
18565 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18566 DONE;
18567 })
18568
18569 (define_expand "builtin_setjmp_receiver"
18570 [(label_ref (match_operand 0 "" ""))]
18571 "!TARGET_64BIT && flag_pic"
18572 {
18573 emit_insn (gen_set_got (pic_offset_table_rtx));
18574 DONE;
18575 })
18576 \f
18577 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18578
18579 (define_split
18580 [(set (match_operand 0 "register_operand" "")
18581 (match_operator 3 "promotable_binary_operator"
18582 [(match_operand 1 "register_operand" "")
18583 (match_operand 2 "aligned_operand" "")]))
18584 (clobber (reg:CC FLAGS_REG))]
18585 "! TARGET_PARTIAL_REG_STALL && reload_completed
18586 && ((GET_MODE (operands[0]) == HImode
18587 && ((!optimize_size && !TARGET_FAST_PREFIX)
18588 || GET_CODE (operands[2]) != CONST_INT
18589 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18590 || (GET_MODE (operands[0]) == QImode
18591 && (TARGET_PROMOTE_QImode || optimize_size)))"
18592 [(parallel [(set (match_dup 0)
18593 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18594 (clobber (reg:CC FLAGS_REG))])]
18595 "operands[0] = gen_lowpart (SImode, operands[0]);
18596 operands[1] = gen_lowpart (SImode, operands[1]);
18597 if (GET_CODE (operands[3]) != ASHIFT)
18598 operands[2] = gen_lowpart (SImode, operands[2]);
18599 PUT_MODE (operands[3], SImode);")
18600
18601 ; Promote the QImode tests, as i386 has encoding of the AND
18602 ; instruction with 32-bit sign-extended immediate and thus the
18603 ; instruction size is unchanged, except in the %eax case for
18604 ; which it is increased by one byte, hence the ! optimize_size.
18605 (define_split
18606 [(set (match_operand 0 "flags_reg_operand" "")
18607 (match_operator 2 "compare_operator"
18608 [(and (match_operand 3 "aligned_operand" "")
18609 (match_operand 4 "const_int_operand" ""))
18610 (const_int 0)]))
18611 (set (match_operand 1 "register_operand" "")
18612 (and (match_dup 3) (match_dup 4)))]
18613 "! TARGET_PARTIAL_REG_STALL && reload_completed
18614 /* Ensure that the operand will remain sign-extended immediate. */
18615 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18616 && ! optimize_size
18617 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18618 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18619 [(parallel [(set (match_dup 0)
18620 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18621 (const_int 0)]))
18622 (set (match_dup 1)
18623 (and:SI (match_dup 3) (match_dup 4)))])]
18624 {
18625 operands[4]
18626 = gen_int_mode (INTVAL (operands[4])
18627 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18628 operands[1] = gen_lowpart (SImode, operands[1]);
18629 operands[3] = gen_lowpart (SImode, operands[3]);
18630 })
18631
18632 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18633 ; the TEST instruction with 32-bit sign-extended immediate and thus
18634 ; the instruction size would at least double, which is not what we
18635 ; want even with ! optimize_size.
18636 (define_split
18637 [(set (match_operand 0 "flags_reg_operand" "")
18638 (match_operator 1 "compare_operator"
18639 [(and (match_operand:HI 2 "aligned_operand" "")
18640 (match_operand:HI 3 "const_int_operand" ""))
18641 (const_int 0)]))]
18642 "! TARGET_PARTIAL_REG_STALL && reload_completed
18643 /* Ensure that the operand will remain sign-extended immediate. */
18644 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18645 && ! TARGET_FAST_PREFIX
18646 && ! optimize_size"
18647 [(set (match_dup 0)
18648 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18649 (const_int 0)]))]
18650 {
18651 operands[3]
18652 = gen_int_mode (INTVAL (operands[3])
18653 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18654 operands[2] = gen_lowpart (SImode, operands[2]);
18655 })
18656
18657 (define_split
18658 [(set (match_operand 0 "register_operand" "")
18659 (neg (match_operand 1 "register_operand" "")))
18660 (clobber (reg:CC FLAGS_REG))]
18661 "! TARGET_PARTIAL_REG_STALL && reload_completed
18662 && (GET_MODE (operands[0]) == HImode
18663 || (GET_MODE (operands[0]) == QImode
18664 && (TARGET_PROMOTE_QImode || optimize_size)))"
18665 [(parallel [(set (match_dup 0)
18666 (neg:SI (match_dup 1)))
18667 (clobber (reg:CC FLAGS_REG))])]
18668 "operands[0] = gen_lowpart (SImode, operands[0]);
18669 operands[1] = gen_lowpart (SImode, operands[1]);")
18670
18671 (define_split
18672 [(set (match_operand 0 "register_operand" "")
18673 (not (match_operand 1 "register_operand" "")))]
18674 "! TARGET_PARTIAL_REG_STALL && reload_completed
18675 && (GET_MODE (operands[0]) == HImode
18676 || (GET_MODE (operands[0]) == QImode
18677 && (TARGET_PROMOTE_QImode || optimize_size)))"
18678 [(set (match_dup 0)
18679 (not:SI (match_dup 1)))]
18680 "operands[0] = gen_lowpart (SImode, operands[0]);
18681 operands[1] = gen_lowpart (SImode, operands[1]);")
18682
18683 (define_split
18684 [(set (match_operand 0 "register_operand" "")
18685 (if_then_else (match_operator 1 "comparison_operator"
18686 [(reg FLAGS_REG) (const_int 0)])
18687 (match_operand 2 "register_operand" "")
18688 (match_operand 3 "register_operand" "")))]
18689 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18690 && (GET_MODE (operands[0]) == HImode
18691 || (GET_MODE (operands[0]) == QImode
18692 && (TARGET_PROMOTE_QImode || optimize_size)))"
18693 [(set (match_dup 0)
18694 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18695 "operands[0] = gen_lowpart (SImode, operands[0]);
18696 operands[2] = gen_lowpart (SImode, operands[2]);
18697 operands[3] = gen_lowpart (SImode, operands[3]);")
18698
18699 \f
18700 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18701 ;; transform a complex memory operation into two memory to register operations.
18702
18703 ;; Don't push memory operands
18704 (define_peephole2
18705 [(set (match_operand:SI 0 "push_operand" "")
18706 (match_operand:SI 1 "memory_operand" ""))
18707 (match_scratch:SI 2 "r")]
18708 "! optimize_size && ! TARGET_PUSH_MEMORY"
18709 [(set (match_dup 2) (match_dup 1))
18710 (set (match_dup 0) (match_dup 2))]
18711 "")
18712
18713 (define_peephole2
18714 [(set (match_operand:DI 0 "push_operand" "")
18715 (match_operand:DI 1 "memory_operand" ""))
18716 (match_scratch:DI 2 "r")]
18717 "! optimize_size && ! TARGET_PUSH_MEMORY"
18718 [(set (match_dup 2) (match_dup 1))
18719 (set (match_dup 0) (match_dup 2))]
18720 "")
18721
18722 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18723 ;; SImode pushes.
18724 (define_peephole2
18725 [(set (match_operand:SF 0 "push_operand" "")
18726 (match_operand:SF 1 "memory_operand" ""))
18727 (match_scratch:SF 2 "r")]
18728 "! optimize_size && ! TARGET_PUSH_MEMORY"
18729 [(set (match_dup 2) (match_dup 1))
18730 (set (match_dup 0) (match_dup 2))]
18731 "")
18732
18733 (define_peephole2
18734 [(set (match_operand:HI 0 "push_operand" "")
18735 (match_operand:HI 1 "memory_operand" ""))
18736 (match_scratch:HI 2 "r")]
18737 "! optimize_size && ! TARGET_PUSH_MEMORY"
18738 [(set (match_dup 2) (match_dup 1))
18739 (set (match_dup 0) (match_dup 2))]
18740 "")
18741
18742 (define_peephole2
18743 [(set (match_operand:QI 0 "push_operand" "")
18744 (match_operand:QI 1 "memory_operand" ""))
18745 (match_scratch:QI 2 "q")]
18746 "! optimize_size && ! TARGET_PUSH_MEMORY"
18747 [(set (match_dup 2) (match_dup 1))
18748 (set (match_dup 0) (match_dup 2))]
18749 "")
18750
18751 ;; Don't move an immediate directly to memory when the instruction
18752 ;; gets too big.
18753 (define_peephole2
18754 [(match_scratch:SI 1 "r")
18755 (set (match_operand:SI 0 "memory_operand" "")
18756 (const_int 0))]
18757 "! optimize_size
18758 && ! TARGET_USE_MOV0
18759 && TARGET_SPLIT_LONG_MOVES
18760 && get_attr_length (insn) >= ix86_cost->large_insn
18761 && peep2_regno_dead_p (0, FLAGS_REG)"
18762 [(parallel [(set (match_dup 1) (const_int 0))
18763 (clobber (reg:CC FLAGS_REG))])
18764 (set (match_dup 0) (match_dup 1))]
18765 "")
18766
18767 (define_peephole2
18768 [(match_scratch:HI 1 "r")
18769 (set (match_operand:HI 0 "memory_operand" "")
18770 (const_int 0))]
18771 "! optimize_size
18772 && ! TARGET_USE_MOV0
18773 && TARGET_SPLIT_LONG_MOVES
18774 && get_attr_length (insn) >= ix86_cost->large_insn
18775 && peep2_regno_dead_p (0, FLAGS_REG)"
18776 [(parallel [(set (match_dup 2) (const_int 0))
18777 (clobber (reg:CC FLAGS_REG))])
18778 (set (match_dup 0) (match_dup 1))]
18779 "operands[2] = gen_lowpart (SImode, operands[1]);")
18780
18781 (define_peephole2
18782 [(match_scratch:QI 1 "q")
18783 (set (match_operand:QI 0 "memory_operand" "")
18784 (const_int 0))]
18785 "! optimize_size
18786 && ! TARGET_USE_MOV0
18787 && TARGET_SPLIT_LONG_MOVES
18788 && get_attr_length (insn) >= ix86_cost->large_insn
18789 && peep2_regno_dead_p (0, FLAGS_REG)"
18790 [(parallel [(set (match_dup 2) (const_int 0))
18791 (clobber (reg:CC FLAGS_REG))])
18792 (set (match_dup 0) (match_dup 1))]
18793 "operands[2] = gen_lowpart (SImode, operands[1]);")
18794
18795 (define_peephole2
18796 [(match_scratch:SI 2 "r")
18797 (set (match_operand:SI 0 "memory_operand" "")
18798 (match_operand:SI 1 "immediate_operand" ""))]
18799 "! optimize_size
18800 && get_attr_length (insn) >= ix86_cost->large_insn
18801 && TARGET_SPLIT_LONG_MOVES"
18802 [(set (match_dup 2) (match_dup 1))
18803 (set (match_dup 0) (match_dup 2))]
18804 "")
18805
18806 (define_peephole2
18807 [(match_scratch:HI 2 "r")
18808 (set (match_operand:HI 0 "memory_operand" "")
18809 (match_operand:HI 1 "immediate_operand" ""))]
18810 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18811 && TARGET_SPLIT_LONG_MOVES"
18812 [(set (match_dup 2) (match_dup 1))
18813 (set (match_dup 0) (match_dup 2))]
18814 "")
18815
18816 (define_peephole2
18817 [(match_scratch:QI 2 "q")
18818 (set (match_operand:QI 0 "memory_operand" "")
18819 (match_operand:QI 1 "immediate_operand" ""))]
18820 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18821 && TARGET_SPLIT_LONG_MOVES"
18822 [(set (match_dup 2) (match_dup 1))
18823 (set (match_dup 0) (match_dup 2))]
18824 "")
18825
18826 ;; Don't compare memory with zero, load and use a test instead.
18827 (define_peephole2
18828 [(set (match_operand 0 "flags_reg_operand" "")
18829 (match_operator 1 "compare_operator"
18830 [(match_operand:SI 2 "memory_operand" "")
18831 (const_int 0)]))
18832 (match_scratch:SI 3 "r")]
18833 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18834 [(set (match_dup 3) (match_dup 2))
18835 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18836 "")
18837
18838 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18839 ;; Don't split NOTs with a displacement operand, because resulting XOR
18840 ;; will not be pairable anyway.
18841 ;;
18842 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18843 ;; represented using a modRM byte. The XOR replacement is long decoded,
18844 ;; so this split helps here as well.
18845 ;;
18846 ;; Note: Can't do this as a regular split because we can't get proper
18847 ;; lifetime information then.
18848
18849 (define_peephole2
18850 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18851 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18852 "!optimize_size
18853 && peep2_regno_dead_p (0, FLAGS_REG)
18854 && ((TARGET_PENTIUM
18855 && (GET_CODE (operands[0]) != MEM
18856 || !memory_displacement_operand (operands[0], SImode)))
18857 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18858 [(parallel [(set (match_dup 0)
18859 (xor:SI (match_dup 1) (const_int -1)))
18860 (clobber (reg:CC FLAGS_REG))])]
18861 "")
18862
18863 (define_peephole2
18864 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18865 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18866 "!optimize_size
18867 && peep2_regno_dead_p (0, FLAGS_REG)
18868 && ((TARGET_PENTIUM
18869 && (GET_CODE (operands[0]) != MEM
18870 || !memory_displacement_operand (operands[0], HImode)))
18871 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18872 [(parallel [(set (match_dup 0)
18873 (xor:HI (match_dup 1) (const_int -1)))
18874 (clobber (reg:CC FLAGS_REG))])]
18875 "")
18876
18877 (define_peephole2
18878 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18879 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18880 "!optimize_size
18881 && peep2_regno_dead_p (0, FLAGS_REG)
18882 && ((TARGET_PENTIUM
18883 && (GET_CODE (operands[0]) != MEM
18884 || !memory_displacement_operand (operands[0], QImode)))
18885 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18886 [(parallel [(set (match_dup 0)
18887 (xor:QI (match_dup 1) (const_int -1)))
18888 (clobber (reg:CC FLAGS_REG))])]
18889 "")
18890
18891 ;; Non pairable "test imm, reg" instructions can be translated to
18892 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18893 ;; byte opcode instead of two, have a short form for byte operands),
18894 ;; so do it for other CPUs as well. Given that the value was dead,
18895 ;; this should not create any new dependencies. Pass on the sub-word
18896 ;; versions if we're concerned about partial register stalls.
18897
18898 (define_peephole2
18899 [(set (match_operand 0 "flags_reg_operand" "")
18900 (match_operator 1 "compare_operator"
18901 [(and:SI (match_operand:SI 2 "register_operand" "")
18902 (match_operand:SI 3 "immediate_operand" ""))
18903 (const_int 0)]))]
18904 "ix86_match_ccmode (insn, CCNOmode)
18905 && (true_regnum (operands[2]) != 0
18906 || (GET_CODE (operands[3]) == CONST_INT
18907 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18908 && peep2_reg_dead_p (1, operands[2])"
18909 [(parallel
18910 [(set (match_dup 0)
18911 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18912 (const_int 0)]))
18913 (set (match_dup 2)
18914 (and:SI (match_dup 2) (match_dup 3)))])]
18915 "")
18916
18917 ;; We don't need to handle HImode case, because it will be promoted to SImode
18918 ;; on ! TARGET_PARTIAL_REG_STALL
18919
18920 (define_peephole2
18921 [(set (match_operand 0 "flags_reg_operand" "")
18922 (match_operator 1 "compare_operator"
18923 [(and:QI (match_operand:QI 2 "register_operand" "")
18924 (match_operand:QI 3 "immediate_operand" ""))
18925 (const_int 0)]))]
18926 "! TARGET_PARTIAL_REG_STALL
18927 && ix86_match_ccmode (insn, CCNOmode)
18928 && true_regnum (operands[2]) != 0
18929 && peep2_reg_dead_p (1, operands[2])"
18930 [(parallel
18931 [(set (match_dup 0)
18932 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18933 (const_int 0)]))
18934 (set (match_dup 2)
18935 (and:QI (match_dup 2) (match_dup 3)))])]
18936 "")
18937
18938 (define_peephole2
18939 [(set (match_operand 0 "flags_reg_operand" "")
18940 (match_operator 1 "compare_operator"
18941 [(and:SI
18942 (zero_extract:SI
18943 (match_operand 2 "ext_register_operand" "")
18944 (const_int 8)
18945 (const_int 8))
18946 (match_operand 3 "const_int_operand" ""))
18947 (const_int 0)]))]
18948 "! TARGET_PARTIAL_REG_STALL
18949 && ix86_match_ccmode (insn, CCNOmode)
18950 && true_regnum (operands[2]) != 0
18951 && peep2_reg_dead_p (1, operands[2])"
18952 [(parallel [(set (match_dup 0)
18953 (match_op_dup 1
18954 [(and:SI
18955 (zero_extract:SI
18956 (match_dup 2)
18957 (const_int 8)
18958 (const_int 8))
18959 (match_dup 3))
18960 (const_int 0)]))
18961 (set (zero_extract:SI (match_dup 2)
18962 (const_int 8)
18963 (const_int 8))
18964 (and:SI
18965 (zero_extract:SI
18966 (match_dup 2)
18967 (const_int 8)
18968 (const_int 8))
18969 (match_dup 3)))])]
18970 "")
18971
18972 ;; Don't do logical operations with memory inputs.
18973 (define_peephole2
18974 [(match_scratch:SI 2 "r")
18975 (parallel [(set (match_operand:SI 0 "register_operand" "")
18976 (match_operator:SI 3 "arith_or_logical_operator"
18977 [(match_dup 0)
18978 (match_operand:SI 1 "memory_operand" "")]))
18979 (clobber (reg:CC FLAGS_REG))])]
18980 "! optimize_size && ! TARGET_READ_MODIFY"
18981 [(set (match_dup 2) (match_dup 1))
18982 (parallel [(set (match_dup 0)
18983 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18984 (clobber (reg:CC FLAGS_REG))])]
18985 "")
18986
18987 (define_peephole2
18988 [(match_scratch:SI 2 "r")
18989 (parallel [(set (match_operand:SI 0 "register_operand" "")
18990 (match_operator:SI 3 "arith_or_logical_operator"
18991 [(match_operand:SI 1 "memory_operand" "")
18992 (match_dup 0)]))
18993 (clobber (reg:CC FLAGS_REG))])]
18994 "! optimize_size && ! TARGET_READ_MODIFY"
18995 [(set (match_dup 2) (match_dup 1))
18996 (parallel [(set (match_dup 0)
18997 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18998 (clobber (reg:CC FLAGS_REG))])]
18999 "")
19000
19001 ; Don't do logical operations with memory outputs
19002 ;
19003 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19004 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19005 ; the same decoder scheduling characteristics as the original.
19006
19007 (define_peephole2
19008 [(match_scratch:SI 2 "r")
19009 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19010 (match_operator:SI 3 "arith_or_logical_operator"
19011 [(match_dup 0)
19012 (match_operand:SI 1 "nonmemory_operand" "")]))
19013 (clobber (reg:CC FLAGS_REG))])]
19014 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19015 [(set (match_dup 2) (match_dup 0))
19016 (parallel [(set (match_dup 2)
19017 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19018 (clobber (reg:CC FLAGS_REG))])
19019 (set (match_dup 0) (match_dup 2))]
19020 "")
19021
19022 (define_peephole2
19023 [(match_scratch:SI 2 "r")
19024 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19025 (match_operator:SI 3 "arith_or_logical_operator"
19026 [(match_operand:SI 1 "nonmemory_operand" "")
19027 (match_dup 0)]))
19028 (clobber (reg:CC FLAGS_REG))])]
19029 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19030 [(set (match_dup 2) (match_dup 0))
19031 (parallel [(set (match_dup 2)
19032 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19033 (clobber (reg:CC FLAGS_REG))])
19034 (set (match_dup 0) (match_dup 2))]
19035 "")
19036
19037 ;; Attempt to always use XOR for zeroing registers.
19038 (define_peephole2
19039 [(set (match_operand 0 "register_operand" "")
19040 (const_int 0))]
19041 "(GET_MODE (operands[0]) == QImode
19042 || GET_MODE (operands[0]) == HImode
19043 || GET_MODE (operands[0]) == SImode
19044 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19045 && (! TARGET_USE_MOV0 || optimize_size)
19046 && peep2_regno_dead_p (0, FLAGS_REG)"
19047 [(parallel [(set (match_dup 0) (const_int 0))
19048 (clobber (reg:CC FLAGS_REG))])]
19049 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19050 operands[0]);")
19051
19052 (define_peephole2
19053 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19054 (const_int 0))]
19055 "(GET_MODE (operands[0]) == QImode
19056 || GET_MODE (operands[0]) == HImode)
19057 && (! TARGET_USE_MOV0 || optimize_size)
19058 && peep2_regno_dead_p (0, FLAGS_REG)"
19059 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19060 (clobber (reg:CC FLAGS_REG))])])
19061
19062 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19063 (define_peephole2
19064 [(set (match_operand 0 "register_operand" "")
19065 (const_int -1))]
19066 "(GET_MODE (operands[0]) == HImode
19067 || GET_MODE (operands[0]) == SImode
19068 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19069 && (optimize_size || TARGET_PENTIUM)
19070 && peep2_regno_dead_p (0, FLAGS_REG)"
19071 [(parallel [(set (match_dup 0) (const_int -1))
19072 (clobber (reg:CC FLAGS_REG))])]
19073 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19074 operands[0]);")
19075
19076 ;; Attempt to convert simple leas to adds. These can be created by
19077 ;; move expanders.
19078 (define_peephole2
19079 [(set (match_operand:SI 0 "register_operand" "")
19080 (plus:SI (match_dup 0)
19081 (match_operand:SI 1 "nonmemory_operand" "")))]
19082 "peep2_regno_dead_p (0, FLAGS_REG)"
19083 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19084 (clobber (reg:CC FLAGS_REG))])]
19085 "")
19086
19087 (define_peephole2
19088 [(set (match_operand:SI 0 "register_operand" "")
19089 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19090 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19091 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19092 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19093 (clobber (reg:CC FLAGS_REG))])]
19094 "operands[2] = gen_lowpart (SImode, operands[2]);")
19095
19096 (define_peephole2
19097 [(set (match_operand:DI 0 "register_operand" "")
19098 (plus:DI (match_dup 0)
19099 (match_operand:DI 1 "x86_64_general_operand" "")))]
19100 "peep2_regno_dead_p (0, FLAGS_REG)"
19101 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19102 (clobber (reg:CC FLAGS_REG))])]
19103 "")
19104
19105 (define_peephole2
19106 [(set (match_operand:SI 0 "register_operand" "")
19107 (mult:SI (match_dup 0)
19108 (match_operand:SI 1 "const_int_operand" "")))]
19109 "exact_log2 (INTVAL (operands[1])) >= 0
19110 && peep2_regno_dead_p (0, FLAGS_REG)"
19111 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19112 (clobber (reg:CC FLAGS_REG))])]
19113 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19114
19115 (define_peephole2
19116 [(set (match_operand:DI 0 "register_operand" "")
19117 (mult:DI (match_dup 0)
19118 (match_operand:DI 1 "const_int_operand" "")))]
19119 "exact_log2 (INTVAL (operands[1])) >= 0
19120 && peep2_regno_dead_p (0, FLAGS_REG)"
19121 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19122 (clobber (reg:CC FLAGS_REG))])]
19123 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19124
19125 (define_peephole2
19126 [(set (match_operand:SI 0 "register_operand" "")
19127 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19128 (match_operand:DI 2 "const_int_operand" "")) 0))]
19129 "exact_log2 (INTVAL (operands[2])) >= 0
19130 && REGNO (operands[0]) == REGNO (operands[1])
19131 && peep2_regno_dead_p (0, FLAGS_REG)"
19132 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19133 (clobber (reg:CC FLAGS_REG))])]
19134 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19135
19136 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19137 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19138 ;; many CPUs it is also faster, since special hardware to avoid esp
19139 ;; dependencies is present.
19140
19141 ;; While some of these conversions may be done using splitters, we use peepholes
19142 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19143
19144 ;; Convert prologue esp subtractions to push.
19145 ;; We need register to push. In order to keep verify_flow_info happy we have
19146 ;; two choices
19147 ;; - use scratch and clobber it in order to avoid dependencies
19148 ;; - use already live register
19149 ;; We can't use the second way right now, since there is no reliable way how to
19150 ;; verify that given register is live. First choice will also most likely in
19151 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19152 ;; call clobbered registers are dead. We may want to use base pointer as an
19153 ;; alternative when no register is available later.
19154
19155 (define_peephole2
19156 [(match_scratch:SI 0 "r")
19157 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19158 (clobber (reg:CC FLAGS_REG))
19159 (clobber (mem:BLK (scratch)))])]
19160 "optimize_size || !TARGET_SUB_ESP_4"
19161 [(clobber (match_dup 0))
19162 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19163 (clobber (mem:BLK (scratch)))])])
19164
19165 (define_peephole2
19166 [(match_scratch:SI 0 "r")
19167 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19168 (clobber (reg:CC FLAGS_REG))
19169 (clobber (mem:BLK (scratch)))])]
19170 "optimize_size || !TARGET_SUB_ESP_8"
19171 [(clobber (match_dup 0))
19172 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19173 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19174 (clobber (mem:BLK (scratch)))])])
19175
19176 ;; Convert esp subtractions to push.
19177 (define_peephole2
19178 [(match_scratch:SI 0 "r")
19179 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19180 (clobber (reg:CC FLAGS_REG))])]
19181 "optimize_size || !TARGET_SUB_ESP_4"
19182 [(clobber (match_dup 0))
19183 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19184
19185 (define_peephole2
19186 [(match_scratch:SI 0 "r")
19187 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19188 (clobber (reg:CC FLAGS_REG))])]
19189 "optimize_size || !TARGET_SUB_ESP_8"
19190 [(clobber (match_dup 0))
19191 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19192 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19193
19194 ;; Convert epilogue deallocator to pop.
19195 (define_peephole2
19196 [(match_scratch:SI 0 "r")
19197 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19198 (clobber (reg:CC FLAGS_REG))
19199 (clobber (mem:BLK (scratch)))])]
19200 "optimize_size || !TARGET_ADD_ESP_4"
19201 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19202 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19203 (clobber (mem:BLK (scratch)))])]
19204 "")
19205
19206 ;; Two pops case is tricky, since pop causes dependency on destination register.
19207 ;; We use two registers if available.
19208 (define_peephole2
19209 [(match_scratch:SI 0 "r")
19210 (match_scratch:SI 1 "r")
19211 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19212 (clobber (reg:CC FLAGS_REG))
19213 (clobber (mem:BLK (scratch)))])]
19214 "optimize_size || !TARGET_ADD_ESP_8"
19215 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19216 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19217 (clobber (mem:BLK (scratch)))])
19218 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19219 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19220 "")
19221
19222 (define_peephole2
19223 [(match_scratch:SI 0 "r")
19224 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19225 (clobber (reg:CC FLAGS_REG))
19226 (clobber (mem:BLK (scratch)))])]
19227 "optimize_size"
19228 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19229 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19230 (clobber (mem:BLK (scratch)))])
19231 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19232 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19233 "")
19234
19235 ;; Convert esp additions to pop.
19236 (define_peephole2
19237 [(match_scratch:SI 0 "r")
19238 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19239 (clobber (reg:CC FLAGS_REG))])]
19240 ""
19241 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19242 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19243 "")
19244
19245 ;; Two pops case is tricky, since pop causes dependency on destination register.
19246 ;; We use two registers if available.
19247 (define_peephole2
19248 [(match_scratch:SI 0 "r")
19249 (match_scratch:SI 1 "r")
19250 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19251 (clobber (reg:CC FLAGS_REG))])]
19252 ""
19253 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19254 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19255 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19256 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19257 "")
19258
19259 (define_peephole2
19260 [(match_scratch:SI 0 "r")
19261 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19262 (clobber (reg:CC FLAGS_REG))])]
19263 "optimize_size"
19264 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19265 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19266 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19267 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19268 "")
19269 \f
19270 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19271 ;; required and register dies. Similarly for 128 to plus -128.
19272 (define_peephole2
19273 [(set (match_operand 0 "flags_reg_operand" "")
19274 (match_operator 1 "compare_operator"
19275 [(match_operand 2 "register_operand" "")
19276 (match_operand 3 "const_int_operand" "")]))]
19277 "(INTVAL (operands[3]) == -1
19278 || INTVAL (operands[3]) == 1
19279 || INTVAL (operands[3]) == 128)
19280 && ix86_match_ccmode (insn, CCGCmode)
19281 && peep2_reg_dead_p (1, operands[2])"
19282 [(parallel [(set (match_dup 0)
19283 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19284 (clobber (match_dup 2))])]
19285 "")
19286 \f
19287 (define_peephole2
19288 [(match_scratch:DI 0 "r")
19289 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19290 (clobber (reg:CC FLAGS_REG))
19291 (clobber (mem:BLK (scratch)))])]
19292 "optimize_size || !TARGET_SUB_ESP_4"
19293 [(clobber (match_dup 0))
19294 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19295 (clobber (mem:BLK (scratch)))])])
19296
19297 (define_peephole2
19298 [(match_scratch:DI 0 "r")
19299 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19300 (clobber (reg:CC FLAGS_REG))
19301 (clobber (mem:BLK (scratch)))])]
19302 "optimize_size || !TARGET_SUB_ESP_8"
19303 [(clobber (match_dup 0))
19304 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19305 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19306 (clobber (mem:BLK (scratch)))])])
19307
19308 ;; Convert esp subtractions to push.
19309 (define_peephole2
19310 [(match_scratch:DI 0 "r")
19311 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19312 (clobber (reg:CC FLAGS_REG))])]
19313 "optimize_size || !TARGET_SUB_ESP_4"
19314 [(clobber (match_dup 0))
19315 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19316
19317 (define_peephole2
19318 [(match_scratch:DI 0 "r")
19319 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19320 (clobber (reg:CC FLAGS_REG))])]
19321 "optimize_size || !TARGET_SUB_ESP_8"
19322 [(clobber (match_dup 0))
19323 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19324 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19325
19326 ;; Convert epilogue deallocator to pop.
19327 (define_peephole2
19328 [(match_scratch:DI 0 "r")
19329 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19330 (clobber (reg:CC FLAGS_REG))
19331 (clobber (mem:BLK (scratch)))])]
19332 "optimize_size || !TARGET_ADD_ESP_4"
19333 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19334 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19335 (clobber (mem:BLK (scratch)))])]
19336 "")
19337
19338 ;; Two pops case is tricky, since pop causes dependency on destination register.
19339 ;; We use two registers if available.
19340 (define_peephole2
19341 [(match_scratch:DI 0 "r")
19342 (match_scratch:DI 1 "r")
19343 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19344 (clobber (reg:CC FLAGS_REG))
19345 (clobber (mem:BLK (scratch)))])]
19346 "optimize_size || !TARGET_ADD_ESP_8"
19347 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19348 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19349 (clobber (mem:BLK (scratch)))])
19350 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19351 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19352 "")
19353
19354 (define_peephole2
19355 [(match_scratch:DI 0 "r")
19356 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19357 (clobber (reg:CC FLAGS_REG))
19358 (clobber (mem:BLK (scratch)))])]
19359 "optimize_size"
19360 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19361 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19362 (clobber (mem:BLK (scratch)))])
19363 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19364 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19365 "")
19366
19367 ;; Convert esp additions to pop.
19368 (define_peephole2
19369 [(match_scratch:DI 0 "r")
19370 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19371 (clobber (reg:CC FLAGS_REG))])]
19372 ""
19373 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19374 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19375 "")
19376
19377 ;; Two pops case is tricky, since pop causes dependency on destination register.
19378 ;; We use two registers if available.
19379 (define_peephole2
19380 [(match_scratch:DI 0 "r")
19381 (match_scratch:DI 1 "r")
19382 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19383 (clobber (reg:CC FLAGS_REG))])]
19384 ""
19385 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19386 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19387 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19388 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19389 "")
19390
19391 (define_peephole2
19392 [(match_scratch:DI 0 "r")
19393 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19394 (clobber (reg:CC FLAGS_REG))])]
19395 "optimize_size"
19396 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19397 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19398 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19399 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19400 "")
19401 \f
19402 ;; Convert imul by three, five and nine into lea
19403 (define_peephole2
19404 [(parallel
19405 [(set (match_operand:SI 0 "register_operand" "")
19406 (mult:SI (match_operand:SI 1 "register_operand" "")
19407 (match_operand:SI 2 "const_int_operand" "")))
19408 (clobber (reg:CC FLAGS_REG))])]
19409 "INTVAL (operands[2]) == 3
19410 || INTVAL (operands[2]) == 5
19411 || INTVAL (operands[2]) == 9"
19412 [(set (match_dup 0)
19413 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19414 (match_dup 1)))]
19415 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19416
19417 (define_peephole2
19418 [(parallel
19419 [(set (match_operand:SI 0 "register_operand" "")
19420 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19421 (match_operand:SI 2 "const_int_operand" "")))
19422 (clobber (reg:CC FLAGS_REG))])]
19423 "!optimize_size
19424 && (INTVAL (operands[2]) == 3
19425 || INTVAL (operands[2]) == 5
19426 || INTVAL (operands[2]) == 9)"
19427 [(set (match_dup 0) (match_dup 1))
19428 (set (match_dup 0)
19429 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19430 (match_dup 0)))]
19431 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19432
19433 (define_peephole2
19434 [(parallel
19435 [(set (match_operand:DI 0 "register_operand" "")
19436 (mult:DI (match_operand:DI 1 "register_operand" "")
19437 (match_operand:DI 2 "const_int_operand" "")))
19438 (clobber (reg:CC FLAGS_REG))])]
19439 "TARGET_64BIT
19440 && (INTVAL (operands[2]) == 3
19441 || INTVAL (operands[2]) == 5
19442 || INTVAL (operands[2]) == 9)"
19443 [(set (match_dup 0)
19444 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19445 (match_dup 1)))]
19446 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19447
19448 (define_peephole2
19449 [(parallel
19450 [(set (match_operand:DI 0 "register_operand" "")
19451 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19452 (match_operand:DI 2 "const_int_operand" "")))
19453 (clobber (reg:CC FLAGS_REG))])]
19454 "TARGET_64BIT
19455 && !optimize_size
19456 && (INTVAL (operands[2]) == 3
19457 || INTVAL (operands[2]) == 5
19458 || INTVAL (operands[2]) == 9)"
19459 [(set (match_dup 0) (match_dup 1))
19460 (set (match_dup 0)
19461 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19462 (match_dup 0)))]
19463 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19464
19465 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19466 ;; imul $32bit_imm, reg, reg is direct decoded.
19467 (define_peephole2
19468 [(match_scratch:DI 3 "r")
19469 (parallel [(set (match_operand:DI 0 "register_operand" "")
19470 (mult:DI (match_operand:DI 1 "memory_operand" "")
19471 (match_operand:DI 2 "immediate_operand" "")))
19472 (clobber (reg:CC FLAGS_REG))])]
19473 "TARGET_K8 && !optimize_size
19474 && (GET_CODE (operands[2]) != CONST_INT
19475 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19476 [(set (match_dup 3) (match_dup 1))
19477 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19478 (clobber (reg:CC FLAGS_REG))])]
19479 "")
19480
19481 (define_peephole2
19482 [(match_scratch:SI 3 "r")
19483 (parallel [(set (match_operand:SI 0 "register_operand" "")
19484 (mult:SI (match_operand:SI 1 "memory_operand" "")
19485 (match_operand:SI 2 "immediate_operand" "")))
19486 (clobber (reg:CC FLAGS_REG))])]
19487 "TARGET_K8 && !optimize_size
19488 && (GET_CODE (operands[2]) != CONST_INT
19489 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19490 [(set (match_dup 3) (match_dup 1))
19491 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19492 (clobber (reg:CC FLAGS_REG))])]
19493 "")
19494
19495 (define_peephole2
19496 [(match_scratch:SI 3 "r")
19497 (parallel [(set (match_operand:DI 0 "register_operand" "")
19498 (zero_extend:DI
19499 (mult:SI (match_operand:SI 1 "memory_operand" "")
19500 (match_operand:SI 2 "immediate_operand" ""))))
19501 (clobber (reg:CC FLAGS_REG))])]
19502 "TARGET_K8 && !optimize_size
19503 && (GET_CODE (operands[2]) != CONST_INT
19504 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19505 [(set (match_dup 3) (match_dup 1))
19506 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19507 (clobber (reg:CC FLAGS_REG))])]
19508 "")
19509
19510 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19511 ;; Convert it into imul reg, reg
19512 ;; It would be better to force assembler to encode instruction using long
19513 ;; immediate, but there is apparently no way to do so.
19514 (define_peephole2
19515 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19516 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19517 (match_operand:DI 2 "const_int_operand" "")))
19518 (clobber (reg:CC FLAGS_REG))])
19519 (match_scratch:DI 3 "r")]
19520 "TARGET_K8 && !optimize_size
19521 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19522 [(set (match_dup 3) (match_dup 2))
19523 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19524 (clobber (reg:CC FLAGS_REG))])]
19525 {
19526 if (!rtx_equal_p (operands[0], operands[1]))
19527 emit_move_insn (operands[0], operands[1]);
19528 })
19529
19530 (define_peephole2
19531 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19532 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19533 (match_operand:SI 2 "const_int_operand" "")))
19534 (clobber (reg:CC FLAGS_REG))])
19535 (match_scratch:SI 3 "r")]
19536 "TARGET_K8 && !optimize_size
19537 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19538 [(set (match_dup 3) (match_dup 2))
19539 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19540 (clobber (reg:CC FLAGS_REG))])]
19541 {
19542 if (!rtx_equal_p (operands[0], operands[1]))
19543 emit_move_insn (operands[0], operands[1]);
19544 })
19545
19546 (define_peephole2
19547 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19548 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19549 (match_operand:HI 2 "immediate_operand" "")))
19550 (clobber (reg:CC FLAGS_REG))])
19551 (match_scratch:HI 3 "r")]
19552 "TARGET_K8 && !optimize_size"
19553 [(set (match_dup 3) (match_dup 2))
19554 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19555 (clobber (reg:CC FLAGS_REG))])]
19556 {
19557 if (!rtx_equal_p (operands[0], operands[1]))
19558 emit_move_insn (operands[0], operands[1]);
19559 })
19560 \f
19561 ;; Call-value patterns last so that the wildcard operand does not
19562 ;; disrupt insn-recog's switch tables.
19563
19564 (define_insn "*call_value_pop_0"
19565 [(set (match_operand 0 "" "")
19566 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19567 (match_operand:SI 2 "" "")))
19568 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19569 (match_operand:SI 3 "immediate_operand" "")))]
19570 "!TARGET_64BIT"
19571 {
19572 if (SIBLING_CALL_P (insn))
19573 return "jmp\t%P1";
19574 else
19575 return "call\t%P1";
19576 }
19577 [(set_attr "type" "callv")])
19578
19579 (define_insn "*call_value_pop_1"
19580 [(set (match_operand 0 "" "")
19581 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19582 (match_operand:SI 2 "" "")))
19583 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19584 (match_operand:SI 3 "immediate_operand" "i")))]
19585 "!TARGET_64BIT"
19586 {
19587 if (constant_call_address_operand (operands[1], Pmode))
19588 {
19589 if (SIBLING_CALL_P (insn))
19590 return "jmp\t%P1";
19591 else
19592 return "call\t%P1";
19593 }
19594 if (SIBLING_CALL_P (insn))
19595 return "jmp\t%A1";
19596 else
19597 return "call\t%A1";
19598 }
19599 [(set_attr "type" "callv")])
19600
19601 (define_insn "*call_value_0"
19602 [(set (match_operand 0 "" "")
19603 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19604 (match_operand:SI 2 "" "")))]
19605 "!TARGET_64BIT"
19606 {
19607 if (SIBLING_CALL_P (insn))
19608 return "jmp\t%P1";
19609 else
19610 return "call\t%P1";
19611 }
19612 [(set_attr "type" "callv")])
19613
19614 (define_insn "*call_value_0_rex64"
19615 [(set (match_operand 0 "" "")
19616 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19617 (match_operand:DI 2 "const_int_operand" "")))]
19618 "TARGET_64BIT"
19619 {
19620 if (SIBLING_CALL_P (insn))
19621 return "jmp\t%P1";
19622 else
19623 return "call\t%P1";
19624 }
19625 [(set_attr "type" "callv")])
19626
19627 (define_insn "*call_value_1"
19628 [(set (match_operand 0 "" "")
19629 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19630 (match_operand:SI 2 "" "")))]
19631 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19632 {
19633 if (constant_call_address_operand (operands[1], Pmode))
19634 return "call\t%P1";
19635 return "call\t%A1";
19636 }
19637 [(set_attr "type" "callv")])
19638
19639 (define_insn "*sibcall_value_1"
19640 [(set (match_operand 0 "" "")
19641 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19642 (match_operand:SI 2 "" "")))]
19643 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19644 {
19645 if (constant_call_address_operand (operands[1], Pmode))
19646 return "jmp\t%P1";
19647 return "jmp\t%A1";
19648 }
19649 [(set_attr "type" "callv")])
19650
19651 (define_insn "*call_value_1_rex64"
19652 [(set (match_operand 0 "" "")
19653 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19654 (match_operand:DI 2 "" "")))]
19655 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19656 {
19657 if (constant_call_address_operand (operands[1], Pmode))
19658 return "call\t%P1";
19659 return "call\t%A1";
19660 }
19661 [(set_attr "type" "callv")])
19662
19663 (define_insn "*sibcall_value_1_rex64"
19664 [(set (match_operand 0 "" "")
19665 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19666 (match_operand:DI 2 "" "")))]
19667 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19668 "jmp\t%P1"
19669 [(set_attr "type" "callv")])
19670
19671 (define_insn "*sibcall_value_1_rex64_v"
19672 [(set (match_operand 0 "" "")
19673 (call (mem:QI (reg:DI 40))
19674 (match_operand:DI 1 "" "")))]
19675 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19676 "jmp\t*%%r11"
19677 [(set_attr "type" "callv")])
19678 \f
19679 (define_insn "trap"
19680 [(trap_if (const_int 1) (const_int 5))]
19681 ""
19682 "int\t$5")
19683
19684 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19685 ;;; for the sake of bounds checking. By emitting bounds checks as
19686 ;;; conditional traps rather than as conditional jumps around
19687 ;;; unconditional traps we avoid introducing spurious basic-block
19688 ;;; boundaries and facilitate elimination of redundant checks. In
19689 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19690 ;;; interrupt 5.
19691 ;;;
19692 ;;; FIXME: Static branch prediction rules for ix86 are such that
19693 ;;; forward conditional branches predict as untaken. As implemented
19694 ;;; below, pseudo conditional traps violate that rule. We should use
19695 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19696 ;;; section loaded at the end of the text segment and branch forward
19697 ;;; there on bounds-failure, and then jump back immediately (in case
19698 ;;; the system chooses to ignore bounds violations, or to report
19699 ;;; violations and continue execution).
19700
19701 (define_expand "conditional_trap"
19702 [(trap_if (match_operator 0 "comparison_operator"
19703 [(match_dup 2) (const_int 0)])
19704 (match_operand 1 "const_int_operand" ""))]
19705 ""
19706 {
19707 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19708 ix86_expand_compare (GET_CODE (operands[0]),
19709 NULL, NULL),
19710 operands[1]));
19711 DONE;
19712 })
19713
19714 (define_insn "*conditional_trap_1"
19715 [(trap_if (match_operator 0 "comparison_operator"
19716 [(reg FLAGS_REG) (const_int 0)])
19717 (match_operand 1 "const_int_operand" ""))]
19718 ""
19719 {
19720 operands[2] = gen_label_rtx ();
19721 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19722 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19723 CODE_LABEL_NUMBER (operands[2]));
19724 RET;
19725 })
19726
19727 ;; Pentium III SIMD instructions.
19728
19729 ;; Moves for SSE/MMX regs.
19730
19731 (define_insn "movv4sf_internal"
19732 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19733 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19734 "TARGET_SSE"
19735 "@
19736 xorps\t%0, %0
19737 movaps\t{%1, %0|%0, %1}
19738 movaps\t{%1, %0|%0, %1}"
19739 [(set_attr "type" "ssemov")
19740 (set_attr "mode" "V4SF")])
19741
19742 (define_split
19743 [(set (match_operand:V4SF 0 "register_operand" "")
19744 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19745 "TARGET_SSE && reload_completed"
19746 [(set (match_dup 0)
19747 (vec_merge:V4SF
19748 (vec_duplicate:V4SF (match_dup 1))
19749 (match_dup 2)
19750 (const_int 1)))]
19751 {
19752 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19753 operands[2] = CONST0_RTX (V4SFmode);
19754 })
19755
19756 (define_insn "movv4si_internal"
19757 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19758 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19759 "TARGET_SSE"
19760 {
19761 switch (which_alternative)
19762 {
19763 case 0:
19764 if (get_attr_mode (insn) == MODE_V4SF)
19765 return "xorps\t%0, %0";
19766 else
19767 return "pxor\t%0, %0";
19768 case 1:
19769 case 2:
19770 if (get_attr_mode (insn) == MODE_V4SF)
19771 return "movaps\t{%1, %0|%0, %1}";
19772 else
19773 return "movdqa\t{%1, %0|%0, %1}";
19774 default:
19775 abort ();
19776 }
19777 }
19778 [(set_attr "type" "ssemov")
19779 (set (attr "mode")
19780 (cond [(eq_attr "alternative" "0,1")
19781 (if_then_else
19782 (ne (symbol_ref "optimize_size")
19783 (const_int 0))
19784 (const_string "V4SF")
19785 (const_string "TI"))
19786 (eq_attr "alternative" "2")
19787 (if_then_else
19788 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19789 (const_int 0))
19790 (ne (symbol_ref "optimize_size")
19791 (const_int 0)))
19792 (const_string "V4SF")
19793 (const_string "TI"))]
19794 (const_string "TI")))])
19795
19796 (define_insn "movv2di_internal"
19797 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19798 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19799 "TARGET_SSE"
19800 {
19801 switch (which_alternative)
19802 {
19803 case 0:
19804 if (get_attr_mode (insn) == MODE_V4SF)
19805 return "xorps\t%0, %0";
19806 else
19807 return "pxor\t%0, %0";
19808 case 1:
19809 case 2:
19810 if (get_attr_mode (insn) == MODE_V4SF)
19811 return "movaps\t{%1, %0|%0, %1}";
19812 else
19813 return "movdqa\t{%1, %0|%0, %1}";
19814 default:
19815 abort ();
19816 }
19817 }
19818 [(set_attr "type" "ssemov")
19819 (set (attr "mode")
19820 (cond [(eq_attr "alternative" "0,1")
19821 (if_then_else
19822 (ne (symbol_ref "optimize_size")
19823 (const_int 0))
19824 (const_string "V4SF")
19825 (const_string "TI"))
19826 (eq_attr "alternative" "2")
19827 (if_then_else
19828 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19829 (const_int 0))
19830 (ne (symbol_ref "optimize_size")
19831 (const_int 0)))
19832 (const_string "V4SF")
19833 (const_string "TI"))]
19834 (const_string "TI")))])
19835
19836 (define_split
19837 [(set (match_operand:V2DF 0 "register_operand" "")
19838 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19839 "TARGET_SSE2 && reload_completed"
19840 [(set (match_dup 0)
19841 (vec_merge:V2DF
19842 (vec_duplicate:V2DF (match_dup 1))
19843 (match_dup 2)
19844 (const_int 1)))]
19845 {
19846 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19847 operands[2] = CONST0_RTX (V2DFmode);
19848 })
19849
19850 (define_insn "movv8qi_internal"
19851 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19852 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19853 "TARGET_MMX
19854 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19855 "@
19856 pxor\t%0, %0
19857 movq\t{%1, %0|%0, %1}
19858 movq\t{%1, %0|%0, %1}
19859 movdq2q\t{%1, %0|%0, %1}
19860 movq2dq\t{%1, %0|%0, %1}
19861 movq\t{%1, %0|%0, %1}
19862 movq\t{%1, %0|%0, %1}"
19863 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19864 (set_attr "mode" "DI")])
19865
19866 (define_insn "movv4hi_internal"
19867 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19868 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19869 "TARGET_MMX
19870 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19871 "@
19872 pxor\t%0, %0
19873 movq\t{%1, %0|%0, %1}
19874 movq\t{%1, %0|%0, %1}
19875 movdq2q\t{%1, %0|%0, %1}
19876 movq2dq\t{%1, %0|%0, %1}
19877 movq\t{%1, %0|%0, %1}
19878 movq\t{%1, %0|%0, %1}"
19879 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19880 (set_attr "mode" "DI")])
19881
19882 (define_insn "*movv2si_internal"
19883 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
19884 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
19885 "TARGET_MMX
19886 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19887 "@
19888 pxor\t%0, %0
19889 movq\t{%1, %0|%0, %1}
19890 movq\t{%1, %0|%0, %1}
19891 movdq2q\t{%1, %0|%0, %1}
19892 movq2dq\t{%1, %0|%0, %1}
19893 movq\t{%1, %0|%0, %1}
19894 movq\t{%1, %0|%0, %1}"
19895 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19896 (set_attr "mode" "DI")])
19897
19898 (define_insn "movv2sf_internal"
19899 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
19900 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
19901 "TARGET_3DNOW
19902 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19903 "@
19904 pxor\t%0, %0
19905 movq\t{%1, %0|%0, %1}
19906 movq\t{%1, %0|%0, %1}
19907 movdq2q\t{%1, %0|%0, %1}
19908 movq2dq\t{%1, %0|%0, %1}
19909 movlps\t{%1, %0|%0, %1}
19910 movlps\t{%1, %0|%0, %1}"
19911 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
19912 (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
19913
19914 (define_expand "movti"
19915 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19916 (match_operand:TI 1 "nonimmediate_operand" ""))]
19917 "TARGET_SSE || TARGET_64BIT"
19918 {
19919 if (TARGET_64BIT)
19920 ix86_expand_move (TImode, operands);
19921 else
19922 ix86_expand_vector_move (TImode, operands);
19923 DONE;
19924 })
19925
19926 (define_expand "movtf"
19927 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19928 (match_operand:TF 1 "nonimmediate_operand" ""))]
19929 "TARGET_64BIT"
19930 {
19931 if (TARGET_64BIT)
19932 ix86_expand_move (TFmode, operands);
19933 else
19934 ix86_expand_vector_move (TFmode, operands);
19935 DONE;
19936 })
19937
19938 (define_insn "movv2df_internal"
19939 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19940 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19941 "TARGET_SSE2
19942 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19943 {
19944 switch (which_alternative)
19945 {
19946 case 0:
19947 if (get_attr_mode (insn) == MODE_V4SF)
19948 return "xorps\t%0, %0";
19949 else
19950 return "xorpd\t%0, %0";
19951 case 1:
19952 case 2:
19953 if (get_attr_mode (insn) == MODE_V4SF)
19954 return "movaps\t{%1, %0|%0, %1}";
19955 else
19956 return "movapd\t{%1, %0|%0, %1}";
19957 default:
19958 abort ();
19959 }
19960 }
19961 [(set_attr "type" "ssemov")
19962 (set (attr "mode")
19963 (cond [(eq_attr "alternative" "0,1")
19964 (if_then_else
19965 (ne (symbol_ref "optimize_size")
19966 (const_int 0))
19967 (const_string "V4SF")
19968 (const_string "V2DF"))
19969 (eq_attr "alternative" "2")
19970 (if_then_else
19971 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19972 (const_int 0))
19973 (ne (symbol_ref "optimize_size")
19974 (const_int 0)))
19975 (const_string "V4SF")
19976 (const_string "V2DF"))]
19977 (const_string "V2DF")))])
19978
19979 (define_insn "movv8hi_internal"
19980 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19981 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19982 "TARGET_SSE2
19983 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19984 {
19985 switch (which_alternative)
19986 {
19987 case 0:
19988 if (get_attr_mode (insn) == MODE_V4SF)
19989 return "xorps\t%0, %0";
19990 else
19991 return "pxor\t%0, %0";
19992 case 1:
19993 case 2:
19994 if (get_attr_mode (insn) == MODE_V4SF)
19995 return "movaps\t{%1, %0|%0, %1}";
19996 else
19997 return "movdqa\t{%1, %0|%0, %1}";
19998 default:
19999 abort ();
20000 }
20001 }
20002 [(set_attr "type" "ssemov")
20003 (set (attr "mode")
20004 (cond [(eq_attr "alternative" "0,1")
20005 (if_then_else
20006 (ne (symbol_ref "optimize_size")
20007 (const_int 0))
20008 (const_string "V4SF")
20009 (const_string "TI"))
20010 (eq_attr "alternative" "2")
20011 (if_then_else
20012 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20013 (const_int 0))
20014 (ne (symbol_ref "optimize_size")
20015 (const_int 0)))
20016 (const_string "V4SF")
20017 (const_string "TI"))]
20018 (const_string "TI")))])
20019
20020 (define_insn "movv16qi_internal"
20021 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20022 (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20023 "TARGET_SSE2
20024 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20025 {
20026 switch (which_alternative)
20027 {
20028 case 0:
20029 if (get_attr_mode (insn) == MODE_V4SF)
20030 return "xorps\t%0, %0";
20031 else
20032 return "pxor\t%0, %0";
20033 case 1:
20034 case 2:
20035 if (get_attr_mode (insn) == MODE_V4SF)
20036 return "movaps\t{%1, %0|%0, %1}";
20037 else
20038 return "movdqa\t{%1, %0|%0, %1}";
20039 default:
20040 abort ();
20041 }
20042 }
20043 [(set_attr "type" "ssemov")
20044 (set (attr "mode")
20045 (cond [(eq_attr "alternative" "0,1")
20046 (if_then_else
20047 (ne (symbol_ref "optimize_size")
20048 (const_int 0))
20049 (const_string "V4SF")
20050 (const_string "TI"))
20051 (eq_attr "alternative" "2")
20052 (if_then_else
20053 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20054 (const_int 0))
20055 (ne (symbol_ref "optimize_size")
20056 (const_int 0)))
20057 (const_string "V4SF")
20058 (const_string "TI"))]
20059 (const_string "TI")))])
20060
20061 (define_expand "movv2df"
20062 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20063 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20064 "TARGET_SSE2"
20065 {
20066 ix86_expand_vector_move (V2DFmode, operands);
20067 DONE;
20068 })
20069
20070 (define_expand "movv8hi"
20071 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20072 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20073 "TARGET_SSE2"
20074 {
20075 ix86_expand_vector_move (V8HImode, operands);
20076 DONE;
20077 })
20078
20079 (define_expand "movv16qi"
20080 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20081 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20082 "TARGET_SSE2"
20083 {
20084 ix86_expand_vector_move (V16QImode, operands);
20085 DONE;
20086 })
20087
20088 (define_expand "movv4sf"
20089 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20090 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20091 "TARGET_SSE"
20092 {
20093 ix86_expand_vector_move (V4SFmode, operands);
20094 DONE;
20095 })
20096
20097 (define_expand "movv4si"
20098 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20099 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20100 "TARGET_SSE"
20101 {
20102 ix86_expand_vector_move (V4SImode, operands);
20103 DONE;
20104 })
20105
20106 (define_expand "movv2di"
20107 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20108 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20109 "TARGET_SSE"
20110 {
20111 ix86_expand_vector_move (V2DImode, operands);
20112 DONE;
20113 })
20114
20115 (define_expand "movv2si"
20116 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20117 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20118 "TARGET_MMX"
20119 {
20120 ix86_expand_vector_move (V2SImode, operands);
20121 DONE;
20122 })
20123
20124 (define_expand "movv4hi"
20125 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20126 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20127 "TARGET_MMX"
20128 {
20129 ix86_expand_vector_move (V4HImode, operands);
20130 DONE;
20131 })
20132
20133 (define_expand "movv8qi"
20134 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20135 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20136 "TARGET_MMX"
20137 {
20138 ix86_expand_vector_move (V8QImode, operands);
20139 DONE;
20140 })
20141
20142 (define_expand "movv2sf"
20143 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20144 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20145 "TARGET_3DNOW"
20146 {
20147 ix86_expand_vector_move (V2SFmode, operands);
20148 DONE;
20149 })
20150
20151 (define_insn "*pushti"
20152 [(set (match_operand:TI 0 "push_operand" "=<")
20153 (match_operand:TI 1 "register_operand" "x"))]
20154 "TARGET_SSE"
20155 "#")
20156
20157 (define_insn "*pushv2df"
20158 [(set (match_operand:V2DF 0 "push_operand" "=<")
20159 (match_operand:V2DF 1 "register_operand" "x"))]
20160 "TARGET_SSE"
20161 "#")
20162
20163 (define_insn "*pushv2di"
20164 [(set (match_operand:V2DI 0 "push_operand" "=<")
20165 (match_operand:V2DI 1 "register_operand" "x"))]
20166 "TARGET_SSE2"
20167 "#")
20168
20169 (define_insn "*pushv8hi"
20170 [(set (match_operand:V8HI 0 "push_operand" "=<")
20171 (match_operand:V8HI 1 "register_operand" "x"))]
20172 "TARGET_SSE2"
20173 "#")
20174
20175 (define_insn "*pushv16qi"
20176 [(set (match_operand:V16QI 0 "push_operand" "=<")
20177 (match_operand:V16QI 1 "register_operand" "x"))]
20178 "TARGET_SSE2"
20179 "#")
20180
20181 (define_insn "*pushv4sf"
20182 [(set (match_operand:V4SF 0 "push_operand" "=<")
20183 (match_operand:V4SF 1 "register_operand" "x"))]
20184 "TARGET_SSE"
20185 "#")
20186
20187 (define_insn "*pushv4si"
20188 [(set (match_operand:V4SI 0 "push_operand" "=<")
20189 (match_operand:V4SI 1 "register_operand" "x"))]
20190 "TARGET_SSE2"
20191 "#")
20192
20193 (define_insn "*pushv2si"
20194 [(set (match_operand:V2SI 0 "push_operand" "=<")
20195 (match_operand:V2SI 1 "register_operand" "y"))]
20196 "TARGET_MMX"
20197 "#")
20198
20199 (define_insn "*pushv4hi"
20200 [(set (match_operand:V4HI 0 "push_operand" "=<")
20201 (match_operand:V4HI 1 "register_operand" "y"))]
20202 "TARGET_MMX"
20203 "#")
20204
20205 (define_insn "*pushv8qi"
20206 [(set (match_operand:V8QI 0 "push_operand" "=<")
20207 (match_operand:V8QI 1 "register_operand" "y"))]
20208 "TARGET_MMX"
20209 "#")
20210
20211 (define_insn "*pushv2sf"
20212 [(set (match_operand:V2SF 0 "push_operand" "=<")
20213 (match_operand:V2SF 1 "register_operand" "y"))]
20214 "TARGET_3DNOW"
20215 "#")
20216
20217 (define_split
20218 [(set (match_operand 0 "push_operand" "")
20219 (match_operand 1 "register_operand" ""))]
20220 "!TARGET_64BIT && reload_completed
20221 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20222 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20223 (set (match_dup 2) (match_dup 1))]
20224 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20225 stack_pointer_rtx);
20226 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20227
20228 (define_split
20229 [(set (match_operand 0 "push_operand" "")
20230 (match_operand 1 "register_operand" ""))]
20231 "TARGET_64BIT && reload_completed
20232 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20233 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20234 (set (match_dup 2) (match_dup 1))]
20235 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20236 stack_pointer_rtx);
20237 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20238
20239
20240 (define_insn "movti_internal"
20241 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20242 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20243 "TARGET_SSE && !TARGET_64BIT
20244 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20245 {
20246 switch (which_alternative)
20247 {
20248 case 0:
20249 if (get_attr_mode (insn) == MODE_V4SF)
20250 return "xorps\t%0, %0";
20251 else
20252 return "pxor\t%0, %0";
20253 case 1:
20254 case 2:
20255 if (get_attr_mode (insn) == MODE_V4SF)
20256 return "movaps\t{%1, %0|%0, %1}";
20257 else
20258 return "movdqa\t{%1, %0|%0, %1}";
20259 default:
20260 abort ();
20261 }
20262 }
20263 [(set_attr "type" "ssemov,ssemov,ssemov")
20264 (set (attr "mode")
20265 (cond [(eq_attr "alternative" "0,1")
20266 (if_then_else
20267 (ne (symbol_ref "optimize_size")
20268 (const_int 0))
20269 (const_string "V4SF")
20270 (const_string "TI"))
20271 (eq_attr "alternative" "2")
20272 (if_then_else
20273 (ne (symbol_ref "optimize_size")
20274 (const_int 0))
20275 (const_string "V4SF")
20276 (const_string "TI"))]
20277 (const_string "TI")))])
20278
20279 (define_insn "*movti_rex64"
20280 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20281 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20282 "TARGET_64BIT
20283 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20284 {
20285 switch (which_alternative)
20286 {
20287 case 0:
20288 case 1:
20289 return "#";
20290 case 2:
20291 if (get_attr_mode (insn) == MODE_V4SF)
20292 return "xorps\t%0, %0";
20293 else
20294 return "pxor\t%0, %0";
20295 case 3:
20296 case 4:
20297 if (get_attr_mode (insn) == MODE_V4SF)
20298 return "movaps\t{%1, %0|%0, %1}";
20299 else
20300 return "movdqa\t{%1, %0|%0, %1}";
20301 default:
20302 abort ();
20303 }
20304 }
20305 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20306 (set (attr "mode")
20307 (cond [(eq_attr "alternative" "2,3")
20308 (if_then_else
20309 (ne (symbol_ref "optimize_size")
20310 (const_int 0))
20311 (const_string "V4SF")
20312 (const_string "TI"))
20313 (eq_attr "alternative" "4")
20314 (if_then_else
20315 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20316 (const_int 0))
20317 (ne (symbol_ref "optimize_size")
20318 (const_int 0)))
20319 (const_string "V4SF")
20320 (const_string "TI"))]
20321 (const_string "DI")))])
20322
20323 (define_insn "*movtf_rex64"
20324 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20325 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20326 "TARGET_64BIT
20327 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20328 {
20329 switch (which_alternative)
20330 {
20331 case 0:
20332 case 1:
20333 return "#";
20334 case 2:
20335 if (get_attr_mode (insn) == MODE_V4SF)
20336 return "xorps\t%0, %0";
20337 else
20338 return "pxor\t%0, %0";
20339 case 3:
20340 case 4:
20341 if (get_attr_mode (insn) == MODE_V4SF)
20342 return "movaps\t{%1, %0|%0, %1}";
20343 else
20344 return "movdqa\t{%1, %0|%0, %1}";
20345 default:
20346 abort ();
20347 }
20348 }
20349 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20350 (set (attr "mode")
20351 (cond [(eq_attr "alternative" "2,3")
20352 (if_then_else
20353 (ne (symbol_ref "optimize_size")
20354 (const_int 0))
20355 (const_string "V4SF")
20356 (const_string "TI"))
20357 (eq_attr "alternative" "4")
20358 (if_then_else
20359 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20360 (const_int 0))
20361 (ne (symbol_ref "optimize_size")
20362 (const_int 0)))
20363 (const_string "V4SF")
20364 (const_string "TI"))]
20365 (const_string "DI")))])
20366
20367 (define_split
20368 [(set (match_operand:TI 0 "nonimmediate_operand" "")
20369 (match_operand:TI 1 "general_operand" ""))]
20370 "reload_completed && !SSE_REG_P (operands[0])
20371 && !SSE_REG_P (operands[1])"
20372 [(const_int 0)]
20373 "ix86_split_long_move (operands); DONE;")
20374
20375 (define_split
20376 [(set (match_operand:TF 0 "nonimmediate_operand" "")
20377 (match_operand:TF 1 "general_operand" ""))]
20378 "reload_completed && !SSE_REG_P (operands[0])
20379 && !SSE_REG_P (operands[1])"
20380 [(const_int 0)]
20381 "ix86_split_long_move (operands); DONE;")
20382
20383 ;; These two patterns are useful for specifying exactly whether to use
20384 ;; movaps or movups
20385 (define_expand "sse_movaps"
20386 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20387 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20388 UNSPEC_MOVA))]
20389 "TARGET_SSE"
20390 {
20391 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20392 {
20393 rtx tmp = gen_reg_rtx (V4SFmode);
20394 emit_insn (gen_sse_movaps (tmp, operands[1]));
20395 emit_move_insn (operands[0], tmp);
20396 DONE;
20397 }
20398 })
20399
20400 (define_insn "*sse_movaps_1"
20401 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20402 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20403 UNSPEC_MOVA))]
20404 "TARGET_SSE
20405 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20406 "movaps\t{%1, %0|%0, %1}"
20407 [(set_attr "type" "ssemov,ssemov")
20408 (set_attr "mode" "V4SF")])
20409
20410 (define_expand "sse_movups"
20411 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20412 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20413 UNSPEC_MOVU))]
20414 "TARGET_SSE"
20415 {
20416 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20417 {
20418 rtx tmp = gen_reg_rtx (V4SFmode);
20419 emit_insn (gen_sse_movups (tmp, operands[1]));
20420 emit_move_insn (operands[0], tmp);
20421 DONE;
20422 }
20423 })
20424
20425 (define_insn "*sse_movups_1"
20426 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20427 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20428 UNSPEC_MOVU))]
20429 "TARGET_SSE
20430 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20431 "movups\t{%1, %0|%0, %1}"
20432 [(set_attr "type" "ssecvt,ssecvt")
20433 (set_attr "mode" "V4SF")])
20434
20435 ;; SSE Strange Moves.
20436
20437 (define_insn "sse_movmskps"
20438 [(set (match_operand:SI 0 "register_operand" "=r")
20439 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20440 UNSPEC_MOVMSK))]
20441 "TARGET_SSE"
20442 "movmskps\t{%1, %0|%0, %1}"
20443 [(set_attr "type" "ssecvt")
20444 (set_attr "mode" "V4SF")])
20445
20446 (define_insn "mmx_pmovmskb"
20447 [(set (match_operand:SI 0 "register_operand" "=r")
20448 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20449 UNSPEC_MOVMSK))]
20450 "TARGET_SSE || TARGET_3DNOW_A"
20451 "pmovmskb\t{%1, %0|%0, %1}"
20452 [(set_attr "type" "ssecvt")
20453 (set_attr "mode" "V4SF")])
20454
20455
20456 (define_insn "mmx_maskmovq"
20457 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20458 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20459 (match_operand:V8QI 2 "register_operand" "y")]
20460 UNSPEC_MASKMOV))]
20461 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20462 ;; @@@ check ordering of operands in intel/nonintel syntax
20463 "maskmovq\t{%2, %1|%1, %2}"
20464 [(set_attr "type" "mmxcvt")
20465 (set_attr "mode" "DI")])
20466
20467 (define_insn "mmx_maskmovq_rex"
20468 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20469 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20470 (match_operand:V8QI 2 "register_operand" "y")]
20471 UNSPEC_MASKMOV))]
20472 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20473 ;; @@@ check ordering of operands in intel/nonintel syntax
20474 "maskmovq\t{%2, %1|%1, %2}"
20475 [(set_attr "type" "mmxcvt")
20476 (set_attr "mode" "DI")])
20477
20478 (define_insn "sse_movntv4sf"
20479 [(set (match_operand:V4SF 0 "memory_operand" "=m")
20480 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20481 UNSPEC_MOVNT))]
20482 "TARGET_SSE"
20483 "movntps\t{%1, %0|%0, %1}"
20484 [(set_attr "type" "ssemov")
20485 (set_attr "mode" "V4SF")])
20486
20487 (define_insn "sse_movntdi"
20488 [(set (match_operand:DI 0 "memory_operand" "=m")
20489 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20490 UNSPEC_MOVNT))]
20491 "TARGET_SSE || TARGET_3DNOW_A"
20492 "movntq\t{%1, %0|%0, %1}"
20493 [(set_attr "type" "mmxmov")
20494 (set_attr "mode" "DI")])
20495
20496 (define_insn "sse_movhlps"
20497 [(set (match_operand:V4SF 0 "register_operand" "=x")
20498 (vec_merge:V4SF
20499 (match_operand:V4SF 1 "register_operand" "0")
20500 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20501 (parallel [(const_int 2)
20502 (const_int 3)
20503 (const_int 0)
20504 (const_int 1)]))
20505 (const_int 3)))]
20506 "TARGET_SSE"
20507 "movhlps\t{%2, %0|%0, %2}"
20508 [(set_attr "type" "ssecvt")
20509 (set_attr "mode" "V4SF")])
20510
20511 (define_insn "sse_movlhps"
20512 [(set (match_operand:V4SF 0 "register_operand" "=x")
20513 (vec_merge:V4SF
20514 (match_operand:V4SF 1 "register_operand" "0")
20515 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20516 (parallel [(const_int 2)
20517 (const_int 3)
20518 (const_int 0)
20519 (const_int 1)]))
20520 (const_int 12)))]
20521 "TARGET_SSE"
20522 "movlhps\t{%2, %0|%0, %2}"
20523 [(set_attr "type" "ssecvt")
20524 (set_attr "mode" "V4SF")])
20525
20526 (define_insn "sse_movhps"
20527 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20528 (vec_merge:V4SF
20529 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20530 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20531 (const_int 12)))]
20532 "TARGET_SSE
20533 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20534 "movhps\t{%2, %0|%0, %2}"
20535 [(set_attr "type" "ssecvt")
20536 (set_attr "mode" "V4SF")])
20537
20538 (define_insn "sse_movlps"
20539 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20540 (vec_merge:V4SF
20541 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20542 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20543 (const_int 3)))]
20544 "TARGET_SSE
20545 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20546 "movlps\t{%2, %0|%0, %2}"
20547 [(set_attr "type" "ssecvt")
20548 (set_attr "mode" "V4SF")])
20549
20550 (define_expand "sse_loadss"
20551 [(match_operand:V4SF 0 "register_operand" "")
20552 (match_operand:SF 1 "memory_operand" "")]
20553 "TARGET_SSE"
20554 {
20555 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20556 CONST0_RTX (V4SFmode)));
20557 DONE;
20558 })
20559
20560 (define_insn "sse_loadss_1"
20561 [(set (match_operand:V4SF 0 "register_operand" "=x")
20562 (vec_merge:V4SF
20563 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20564 (match_operand:V4SF 2 "const0_operand" "X")
20565 (const_int 1)))]
20566 "TARGET_SSE"
20567 "movss\t{%1, %0|%0, %1}"
20568 [(set_attr "type" "ssemov")
20569 (set_attr "mode" "SF")])
20570
20571 (define_insn "sse_movss"
20572 [(set (match_operand:V4SF 0 "register_operand" "=x")
20573 (vec_merge:V4SF
20574 (match_operand:V4SF 1 "register_operand" "0")
20575 (match_operand:V4SF 2 "register_operand" "x")
20576 (const_int 14)))]
20577 "TARGET_SSE"
20578 "movss\t{%2, %0|%0, %2}"
20579 [(set_attr "type" "ssemov")
20580 (set_attr "mode" "SF")])
20581
20582 (define_insn "sse_storess"
20583 [(set (match_operand:SF 0 "memory_operand" "=m")
20584 (vec_select:SF
20585 (match_operand:V4SF 1 "register_operand" "x")
20586 (parallel [(const_int 0)])))]
20587 "TARGET_SSE"
20588 "movss\t{%1, %0|%0, %1}"
20589 [(set_attr "type" "ssemov")
20590 (set_attr "mode" "SF")])
20591
20592 (define_insn "sse_shufps"
20593 [(set (match_operand:V4SF 0 "register_operand" "=x")
20594 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20595 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20596 (match_operand:SI 3 "immediate_operand" "i")]
20597 UNSPEC_SHUFFLE))]
20598 "TARGET_SSE"
20599 ;; @@@ check operand order for intel/nonintel syntax
20600 "shufps\t{%3, %2, %0|%0, %2, %3}"
20601 [(set_attr "type" "ssecvt")
20602 (set_attr "mode" "V4SF")])
20603
20604
20605 ;; SSE arithmetic
20606
20607 (define_insn "addv4sf3"
20608 [(set (match_operand:V4SF 0 "register_operand" "=x")
20609 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20610 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20611 "TARGET_SSE"
20612 "addps\t{%2, %0|%0, %2}"
20613 [(set_attr "type" "sseadd")
20614 (set_attr "mode" "V4SF")])
20615
20616 (define_insn "vmaddv4sf3"
20617 [(set (match_operand:V4SF 0 "register_operand" "=x")
20618 (vec_merge:V4SF
20619 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20620 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20621 (match_dup 1)
20622 (const_int 1)))]
20623 "TARGET_SSE"
20624 "addss\t{%2, %0|%0, %2}"
20625 [(set_attr "type" "sseadd")
20626 (set_attr "mode" "SF")])
20627
20628 (define_insn "subv4sf3"
20629 [(set (match_operand:V4SF 0 "register_operand" "=x")
20630 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20631 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20632 "TARGET_SSE"
20633 "subps\t{%2, %0|%0, %2}"
20634 [(set_attr "type" "sseadd")
20635 (set_attr "mode" "V4SF")])
20636
20637 (define_insn "vmsubv4sf3"
20638 [(set (match_operand:V4SF 0 "register_operand" "=x")
20639 (vec_merge:V4SF
20640 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20641 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20642 (match_dup 1)
20643 (const_int 1)))]
20644 "TARGET_SSE"
20645 "subss\t{%2, %0|%0, %2}"
20646 [(set_attr "type" "sseadd")
20647 (set_attr "mode" "SF")])
20648
20649 ;; ??? Should probably be done by generic code instead.
20650 (define_expand "negv4sf2"
20651 [(set (match_operand:V4SF 0 "register_operand" "")
20652 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20653 (match_dup 2)))]
20654 "TARGET_SSE"
20655 {
20656 rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20657 rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20658 operands[2] = force_reg (V4SFmode, vm0);
20659 })
20660
20661 (define_insn "mulv4sf3"
20662 [(set (match_operand:V4SF 0 "register_operand" "=x")
20663 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20664 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20665 "TARGET_SSE"
20666 "mulps\t{%2, %0|%0, %2}"
20667 [(set_attr "type" "ssemul")
20668 (set_attr "mode" "V4SF")])
20669
20670 (define_insn "vmmulv4sf3"
20671 [(set (match_operand:V4SF 0 "register_operand" "=x")
20672 (vec_merge:V4SF
20673 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20674 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20675 (match_dup 1)
20676 (const_int 1)))]
20677 "TARGET_SSE"
20678 "mulss\t{%2, %0|%0, %2}"
20679 [(set_attr "type" "ssemul")
20680 (set_attr "mode" "SF")])
20681
20682 (define_insn "divv4sf3"
20683 [(set (match_operand:V4SF 0 "register_operand" "=x")
20684 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20685 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20686 "TARGET_SSE"
20687 "divps\t{%2, %0|%0, %2}"
20688 [(set_attr "type" "ssediv")
20689 (set_attr "mode" "V4SF")])
20690
20691 (define_insn "vmdivv4sf3"
20692 [(set (match_operand:V4SF 0 "register_operand" "=x")
20693 (vec_merge:V4SF
20694 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20695 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20696 (match_dup 1)
20697 (const_int 1)))]
20698 "TARGET_SSE"
20699 "divss\t{%2, %0|%0, %2}"
20700 [(set_attr "type" "ssediv")
20701 (set_attr "mode" "SF")])
20702
20703
20704 ;; SSE square root/reciprocal
20705
20706 (define_insn "rcpv4sf2"
20707 [(set (match_operand:V4SF 0 "register_operand" "=x")
20708 (unspec:V4SF
20709 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20710 "TARGET_SSE"
20711 "rcpps\t{%1, %0|%0, %1}"
20712 [(set_attr "type" "sse")
20713 (set_attr "mode" "V4SF")])
20714
20715 (define_insn "vmrcpv4sf2"
20716 [(set (match_operand:V4SF 0 "register_operand" "=x")
20717 (vec_merge:V4SF
20718 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20719 UNSPEC_RCP)
20720 (match_operand:V4SF 2 "register_operand" "0")
20721 (const_int 1)))]
20722 "TARGET_SSE"
20723 "rcpss\t{%1, %0|%0, %1}"
20724 [(set_attr "type" "sse")
20725 (set_attr "mode" "SF")])
20726
20727 (define_insn "rsqrtv4sf2"
20728 [(set (match_operand:V4SF 0 "register_operand" "=x")
20729 (unspec:V4SF
20730 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20731 "TARGET_SSE"
20732 "rsqrtps\t{%1, %0|%0, %1}"
20733 [(set_attr "type" "sse")
20734 (set_attr "mode" "V4SF")])
20735
20736 (define_insn "vmrsqrtv4sf2"
20737 [(set (match_operand:V4SF 0 "register_operand" "=x")
20738 (vec_merge:V4SF
20739 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20740 UNSPEC_RSQRT)
20741 (match_operand:V4SF 2 "register_operand" "0")
20742 (const_int 1)))]
20743 "TARGET_SSE"
20744 "rsqrtss\t{%1, %0|%0, %1}"
20745 [(set_attr "type" "sse")
20746 (set_attr "mode" "SF")])
20747
20748 (define_insn "sqrtv4sf2"
20749 [(set (match_operand:V4SF 0 "register_operand" "=x")
20750 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20751 "TARGET_SSE"
20752 "sqrtps\t{%1, %0|%0, %1}"
20753 [(set_attr "type" "sse")
20754 (set_attr "mode" "V4SF")])
20755
20756 (define_insn "vmsqrtv4sf2"
20757 [(set (match_operand:V4SF 0 "register_operand" "=x")
20758 (vec_merge:V4SF
20759 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20760 (match_operand:V4SF 2 "register_operand" "0")
20761 (const_int 1)))]
20762 "TARGET_SSE"
20763 "sqrtss\t{%1, %0|%0, %1}"
20764 [(set_attr "type" "sse")
20765 (set_attr "mode" "SF")])
20766
20767 ;; SSE logical operations.
20768
20769 ;; SSE defines logical operations on floating point values. This brings
20770 ;; interesting challenge to RTL representation where logicals are only valid
20771 ;; on integral types. We deal with this by representing the floating point
20772 ;; logical as logical on arguments casted to TImode as this is what hardware
20773 ;; really does. Unfortunately hardware requires the type information to be
20774 ;; present and thus we must avoid subregs from being simplified and eliminated
20775 ;; in later compilation phases.
20776 ;;
20777 ;; We have following variants from each instruction:
20778 ;; sse_andsf3 - the operation taking V4SF vector operands
20779 ;; and doing TImode cast on them
20780 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20781 ;; TImode, since backend insist on eliminating casts
20782 ;; on memory operands
20783 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20784 ;; We cannot accept memory operand here as instruction reads
20785 ;; whole scalar. This is generated only post reload by GCC
20786 ;; scalar float operations that expands to logicals (fabs)
20787 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20788 ;; memory operand. Eventually combine can be able
20789 ;; to synthesize these using splitter.
20790 ;; sse2_anddf3, *sse2_anddf3_memory
20791 ;;
20792 ;;
20793 ;; These are not called andti3 etc. because we really really don't want
20794 ;; the compiler to widen DImode ands to TImode ands and then try to move
20795 ;; into DImode subregs of SSE registers, and them together, and move out
20796 ;; of DImode subregs again!
20797 ;; SSE1 single precision floating point logical operation
20798 (define_expand "sse_andv4sf3"
20799 [(set (match_operand:V4SF 0 "register_operand" "")
20800 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20801 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20802 "TARGET_SSE"
20803 "")
20804
20805 (define_insn "*sse_andv4sf3"
20806 [(set (match_operand:V4SF 0 "register_operand" "=x")
20807 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20808 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20809 "TARGET_SSE
20810 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20811 "andps\t{%2, %0|%0, %2}"
20812 [(set_attr "type" "sselog")
20813 (set_attr "mode" "V4SF")])
20814
20815 (define_expand "sse_nandv4sf3"
20816 [(set (match_operand:V4SF 0 "register_operand" "")
20817 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20818 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20819 "TARGET_SSE"
20820 "")
20821
20822 (define_insn "*sse_nandv4sf3"
20823 [(set (match_operand:V4SF 0 "register_operand" "=x")
20824 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20825 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20826 "TARGET_SSE"
20827 "andnps\t{%2, %0|%0, %2}"
20828 [(set_attr "type" "sselog")
20829 (set_attr "mode" "V4SF")])
20830
20831 (define_expand "sse_iorv4sf3"
20832 [(set (match_operand:V4SF 0 "register_operand" "")
20833 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20834 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20835 "TARGET_SSE"
20836 "")
20837
20838 (define_insn "*sse_iorv4sf3"
20839 [(set (match_operand:V4SF 0 "register_operand" "=x")
20840 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20841 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20842 "TARGET_SSE
20843 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20844 "orps\t{%2, %0|%0, %2}"
20845 [(set_attr "type" "sselog")
20846 (set_attr "mode" "V4SF")])
20847
20848 (define_expand "sse_xorv4sf3"
20849 [(set (match_operand:V4SF 0 "register_operand" "")
20850 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20851 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20852 "TARGET_SSE"
20853 "")
20854
20855 (define_insn "*sse_xorv4sf3"
20856 [(set (match_operand:V4SF 0 "register_operand" "=x")
20857 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20858 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20859 "TARGET_SSE
20860 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20861 "xorps\t{%2, %0|%0, %2}"
20862 [(set_attr "type" "sselog")
20863 (set_attr "mode" "V4SF")])
20864
20865 ;; SSE2 double precision floating point logical operation
20866
20867 (define_expand "sse2_andv2df3"
20868 [(set (match_operand:V2DF 0 "register_operand" "")
20869 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20870 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20871 "TARGET_SSE2"
20872 "")
20873
20874 (define_insn "*sse2_andv2df3"
20875 [(set (match_operand:V2DF 0 "register_operand" "=x")
20876 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20877 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20878 "TARGET_SSE2
20879 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20880 "andpd\t{%2, %0|%0, %2}"
20881 [(set_attr "type" "sselog")
20882 (set_attr "mode" "V2DF")])
20883
20884 (define_expand "sse2_nandv2df3"
20885 [(set (match_operand:V2DF 0 "register_operand" "")
20886 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20887 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20888 "TARGET_SSE2"
20889 "")
20890
20891 (define_insn "*sse2_nandv2df3"
20892 [(set (match_operand:V2DF 0 "register_operand" "=x")
20893 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20894 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20895 "TARGET_SSE2"
20896 "andnpd\t{%2, %0|%0, %2}"
20897 [(set_attr "type" "sselog")
20898 (set_attr "mode" "V2DF")])
20899
20900 (define_expand "sse2_iorv2df3"
20901 [(set (match_operand:V2DF 0 "register_operand" "")
20902 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20903 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20904 "TARGET_SSE2"
20905 "")
20906
20907 (define_insn "*sse2_iorv2df3"
20908 [(set (match_operand:V2DF 0 "register_operand" "=x")
20909 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20910 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20911 "TARGET_SSE2
20912 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20913 "orpd\t{%2, %0|%0, %2}"
20914 [(set_attr "type" "sselog")
20915 (set_attr "mode" "V2DF")])
20916
20917 (define_expand "sse2_xorv2df3"
20918 [(set (match_operand:V2DF 0 "register_operand" "")
20919 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20920 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20921 "TARGET_SSE2"
20922 "")
20923
20924 (define_insn "*sse2_xorv2df3"
20925 [(set (match_operand:V2DF 0 "register_operand" "=x")
20926 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20927 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20928 "TARGET_SSE2
20929 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20930 "xorpd\t{%2, %0|%0, %2}"
20931 [(set_attr "type" "sselog")
20932 (set_attr "mode" "V2DF")])
20933
20934 ;; SSE2 integral logicals. These patterns must always come after floating
20935 ;; point ones since we don't want compiler to use integer opcodes on floating
20936 ;; point SSE values to avoid matching of subregs in the match_operand.
20937 (define_insn "*sse2_andti3"
20938 [(set (match_operand:TI 0 "register_operand" "=x")
20939 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20940 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20941 "TARGET_SSE2
20942 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20943 "pand\t{%2, %0|%0, %2}"
20944 [(set_attr "type" "sselog")
20945 (set_attr "mode" "TI")])
20946
20947 (define_insn "sse2_andv2di3"
20948 [(set (match_operand:V2DI 0 "register_operand" "=x")
20949 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20950 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20951 "TARGET_SSE2
20952 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20953 "pand\t{%2, %0|%0, %2}"
20954 [(set_attr "type" "sselog")
20955 (set_attr "mode" "TI")])
20956
20957 (define_insn "*sse2_nandti3"
20958 [(set (match_operand:TI 0 "register_operand" "=x")
20959 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20960 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20961 "TARGET_SSE2"
20962 "pandn\t{%2, %0|%0, %2}"
20963 [(set_attr "type" "sselog")
20964 (set_attr "mode" "TI")])
20965
20966 (define_insn "sse2_nandv2di3"
20967 [(set (match_operand:V2DI 0 "register_operand" "=x")
20968 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20969 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20970 "TARGET_SSE2
20971 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20972 "pandn\t{%2, %0|%0, %2}"
20973 [(set_attr "type" "sselog")
20974 (set_attr "mode" "TI")])
20975
20976 (define_insn "*sse2_iorti3"
20977 [(set (match_operand:TI 0 "register_operand" "=x")
20978 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20979 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20980 "TARGET_SSE2
20981 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20982 "por\t{%2, %0|%0, %2}"
20983 [(set_attr "type" "sselog")
20984 (set_attr "mode" "TI")])
20985
20986 (define_insn "sse2_iorv2di3"
20987 [(set (match_operand:V2DI 0 "register_operand" "=x")
20988 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20989 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20990 "TARGET_SSE2
20991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20992 "por\t{%2, %0|%0, %2}"
20993 [(set_attr "type" "sselog")
20994 (set_attr "mode" "TI")])
20995
20996 (define_insn "*sse2_xorti3"
20997 [(set (match_operand:TI 0 "register_operand" "=x")
20998 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20999 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21000 "TARGET_SSE2
21001 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21002 "pxor\t{%2, %0|%0, %2}"
21003 [(set_attr "type" "sselog")
21004 (set_attr "mode" "TI")])
21005
21006 (define_insn "sse2_xorv2di3"
21007 [(set (match_operand:V2DI 0 "register_operand" "=x")
21008 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21009 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21010 "TARGET_SSE2
21011 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21012 "pxor\t{%2, %0|%0, %2}"
21013 [(set_attr "type" "sselog")
21014 (set_attr "mode" "TI")])
21015
21016 ;; Use xor, but don't show input operands so they aren't live before
21017 ;; this insn.
21018 (define_insn "sse_clrv4sf"
21019 [(set (match_operand:V4SF 0 "register_operand" "=x")
21020 (match_operand:V4SF 1 "const0_operand" "X"))]
21021 "TARGET_SSE"
21022 {
21023 if (get_attr_mode (insn) == MODE_TI)
21024 return "pxor\t{%0, %0|%0, %0}";
21025 else
21026 return "xorps\t{%0, %0|%0, %0}";
21027 }
21028 [(set_attr "type" "sselog")
21029 (set_attr "memory" "none")
21030 (set (attr "mode")
21031 (if_then_else
21032 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21033 (const_int 0))
21034 (ne (symbol_ref "TARGET_SSE2")
21035 (const_int 0)))
21036 (eq (symbol_ref "optimize_size")
21037 (const_int 0)))
21038 (const_string "TI")
21039 (const_string "V4SF")))])
21040
21041 ;; Use xor, but don't show input operands so they aren't live before
21042 ;; this insn.
21043 (define_insn "sse_clrv2df"
21044 [(set (match_operand:V2DF 0 "register_operand" "=x")
21045 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21046 "TARGET_SSE2"
21047 "xorpd\t{%0, %0|%0, %0}"
21048 [(set_attr "type" "sselog")
21049 (set_attr "memory" "none")
21050 (set_attr "mode" "V4SF")])
21051
21052 ;; SSE mask-generating compares
21053
21054 (define_insn "maskcmpv4sf3"
21055 [(set (match_operand:V4SI 0 "register_operand" "=x")
21056 (match_operator:V4SI 3 "sse_comparison_operator"
21057 [(match_operand:V4SF 1 "register_operand" "0")
21058 (match_operand:V4SF 2 "register_operand" "x")]))]
21059 "TARGET_SSE"
21060 "cmp%D3ps\t{%2, %0|%0, %2}"
21061 [(set_attr "type" "ssecmp")
21062 (set_attr "mode" "V4SF")])
21063
21064 (define_insn "maskncmpv4sf3"
21065 [(set (match_operand:V4SI 0 "register_operand" "=x")
21066 (not:V4SI
21067 (match_operator:V4SI 3 "sse_comparison_operator"
21068 [(match_operand:V4SF 1 "register_operand" "0")
21069 (match_operand:V4SF 2 "register_operand" "x")])))]
21070 "TARGET_SSE"
21071 {
21072 if (GET_CODE (operands[3]) == UNORDERED)
21073 return "cmpordps\t{%2, %0|%0, %2}";
21074 else
21075 return "cmpn%D3ps\t{%2, %0|%0, %2}";
21076 }
21077 [(set_attr "type" "ssecmp")
21078 (set_attr "mode" "V4SF")])
21079
21080 (define_insn "vmmaskcmpv4sf3"
21081 [(set (match_operand:V4SI 0 "register_operand" "=x")
21082 (vec_merge:V4SI
21083 (match_operator:V4SI 3 "sse_comparison_operator"
21084 [(match_operand:V4SF 1 "register_operand" "0")
21085 (match_operand:V4SF 2 "register_operand" "x")])
21086 (subreg:V4SI (match_dup 1) 0)
21087 (const_int 1)))]
21088 "TARGET_SSE"
21089 "cmp%D3ss\t{%2, %0|%0, %2}"
21090 [(set_attr "type" "ssecmp")
21091 (set_attr "mode" "SF")])
21092
21093 (define_insn "vmmaskncmpv4sf3"
21094 [(set (match_operand:V4SI 0 "register_operand" "=x")
21095 (vec_merge:V4SI
21096 (not:V4SI
21097 (match_operator:V4SI 3 "sse_comparison_operator"
21098 [(match_operand:V4SF 1 "register_operand" "0")
21099 (match_operand:V4SF 2 "register_operand" "x")]))
21100 (subreg:V4SI (match_dup 1) 0)
21101 (const_int 1)))]
21102 "TARGET_SSE"
21103 {
21104 if (GET_CODE (operands[3]) == UNORDERED)
21105 return "cmpordss\t{%2, %0|%0, %2}";
21106 else
21107 return "cmpn%D3ss\t{%2, %0|%0, %2}";
21108 }
21109 [(set_attr "type" "ssecmp")
21110 (set_attr "mode" "SF")])
21111
21112 (define_insn "sse_comi"
21113 [(set (reg:CCFP FLAGS_REG)
21114 (compare:CCFP (vec_select:SF
21115 (match_operand:V4SF 0 "register_operand" "x")
21116 (parallel [(const_int 0)]))
21117 (vec_select:SF
21118 (match_operand:V4SF 1 "register_operand" "x")
21119 (parallel [(const_int 0)]))))]
21120 "TARGET_SSE"
21121 "comiss\t{%1, %0|%0, %1}"
21122 [(set_attr "type" "ssecomi")
21123 (set_attr "mode" "SF")])
21124
21125 (define_insn "sse_ucomi"
21126 [(set (reg:CCFPU FLAGS_REG)
21127 (compare:CCFPU (vec_select:SF
21128 (match_operand:V4SF 0 "register_operand" "x")
21129 (parallel [(const_int 0)]))
21130 (vec_select:SF
21131 (match_operand:V4SF 1 "register_operand" "x")
21132 (parallel [(const_int 0)]))))]
21133 "TARGET_SSE"
21134 "ucomiss\t{%1, %0|%0, %1}"
21135 [(set_attr "type" "ssecomi")
21136 (set_attr "mode" "SF")])
21137
21138
21139 ;; SSE unpack
21140
21141 (define_insn "sse_unpckhps"
21142 [(set (match_operand:V4SF 0 "register_operand" "=x")
21143 (vec_merge:V4SF
21144 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21145 (parallel [(const_int 2)
21146 (const_int 0)
21147 (const_int 3)
21148 (const_int 1)]))
21149 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21150 (parallel [(const_int 0)
21151 (const_int 2)
21152 (const_int 1)
21153 (const_int 3)]))
21154 (const_int 5)))]
21155 "TARGET_SSE"
21156 "unpckhps\t{%2, %0|%0, %2}"
21157 [(set_attr "type" "ssecvt")
21158 (set_attr "mode" "V4SF")])
21159
21160 (define_insn "sse_unpcklps"
21161 [(set (match_operand:V4SF 0 "register_operand" "=x")
21162 (vec_merge:V4SF
21163 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21164 (parallel [(const_int 0)
21165 (const_int 2)
21166 (const_int 1)
21167 (const_int 3)]))
21168 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21169 (parallel [(const_int 2)
21170 (const_int 0)
21171 (const_int 3)
21172 (const_int 1)]))
21173 (const_int 5)))]
21174 "TARGET_SSE"
21175 "unpcklps\t{%2, %0|%0, %2}"
21176 [(set_attr "type" "ssecvt")
21177 (set_attr "mode" "V4SF")])
21178
21179
21180 ;; SSE min/max
21181
21182 (define_insn "smaxv4sf3"
21183 [(set (match_operand:V4SF 0 "register_operand" "=x")
21184 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21185 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21186 "TARGET_SSE"
21187 "maxps\t{%2, %0|%0, %2}"
21188 [(set_attr "type" "sse")
21189 (set_attr "mode" "V4SF")])
21190
21191 (define_insn "vmsmaxv4sf3"
21192 [(set (match_operand:V4SF 0 "register_operand" "=x")
21193 (vec_merge:V4SF
21194 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21195 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21196 (match_dup 1)
21197 (const_int 1)))]
21198 "TARGET_SSE"
21199 "maxss\t{%2, %0|%0, %2}"
21200 [(set_attr "type" "sse")
21201 (set_attr "mode" "SF")])
21202
21203 (define_insn "sminv4sf3"
21204 [(set (match_operand:V4SF 0 "register_operand" "=x")
21205 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21206 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21207 "TARGET_SSE"
21208 "minps\t{%2, %0|%0, %2}"
21209 [(set_attr "type" "sse")
21210 (set_attr "mode" "V4SF")])
21211
21212 (define_insn "vmsminv4sf3"
21213 [(set (match_operand:V4SF 0 "register_operand" "=x")
21214 (vec_merge:V4SF
21215 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21216 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21217 (match_dup 1)
21218 (const_int 1)))]
21219 "TARGET_SSE"
21220 "minss\t{%2, %0|%0, %2}"
21221 [(set_attr "type" "sse")
21222 (set_attr "mode" "SF")])
21223
21224 ;; SSE <-> integer/MMX conversions
21225
21226 (define_insn "cvtpi2ps"
21227 [(set (match_operand:V4SF 0 "register_operand" "=x")
21228 (vec_merge:V4SF
21229 (match_operand:V4SF 1 "register_operand" "0")
21230 (vec_duplicate:V4SF
21231 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21232 (const_int 12)))]
21233 "TARGET_SSE"
21234 "cvtpi2ps\t{%2, %0|%0, %2}"
21235 [(set_attr "type" "ssecvt")
21236 (set_attr "mode" "V4SF")])
21237
21238 (define_insn "cvtps2pi"
21239 [(set (match_operand:V2SI 0 "register_operand" "=y")
21240 (vec_select:V2SI
21241 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21242 (parallel [(const_int 0) (const_int 1)])))]
21243 "TARGET_SSE"
21244 "cvtps2pi\t{%1, %0|%0, %1}"
21245 [(set_attr "type" "ssecvt")
21246 (set_attr "mode" "V4SF")])
21247
21248 (define_insn "cvttps2pi"
21249 [(set (match_operand:V2SI 0 "register_operand" "=y")
21250 (vec_select:V2SI
21251 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21252 UNSPEC_FIX)
21253 (parallel [(const_int 0) (const_int 1)])))]
21254 "TARGET_SSE"
21255 "cvttps2pi\t{%1, %0|%0, %1}"
21256 [(set_attr "type" "ssecvt")
21257 (set_attr "mode" "SF")])
21258
21259 (define_insn "cvtsi2ss"
21260 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21261 (vec_merge:V4SF
21262 (match_operand:V4SF 1 "register_operand" "0,0")
21263 (vec_duplicate:V4SF
21264 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21265 (const_int 14)))]
21266 "TARGET_SSE"
21267 "cvtsi2ss\t{%2, %0|%0, %2}"
21268 [(set_attr "type" "sseicvt")
21269 (set_attr "athlon_decode" "vector,double")
21270 (set_attr "mode" "SF")])
21271
21272 (define_insn "cvtsi2ssq"
21273 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21274 (vec_merge:V4SF
21275 (match_operand:V4SF 1 "register_operand" "0,0")
21276 (vec_duplicate:V4SF
21277 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21278 (const_int 14)))]
21279 "TARGET_SSE && TARGET_64BIT"
21280 "cvtsi2ssq\t{%2, %0|%0, %2}"
21281 [(set_attr "type" "sseicvt")
21282 (set_attr "athlon_decode" "vector,double")
21283 (set_attr "mode" "SF")])
21284
21285 (define_insn "cvtss2si"
21286 [(set (match_operand:SI 0 "register_operand" "=r,r")
21287 (vec_select:SI
21288 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21289 (parallel [(const_int 0)])))]
21290 "TARGET_SSE"
21291 "cvtss2si\t{%1, %0|%0, %1}"
21292 [(set_attr "type" "sseicvt")
21293 (set_attr "athlon_decode" "double,vector")
21294 (set_attr "mode" "SI")])
21295
21296 (define_insn "cvtss2siq"
21297 [(set (match_operand:DI 0 "register_operand" "=r,r")
21298 (vec_select:DI
21299 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21300 (parallel [(const_int 0)])))]
21301 "TARGET_SSE"
21302 "cvtss2siq\t{%1, %0|%0, %1}"
21303 [(set_attr "type" "sseicvt")
21304 (set_attr "athlon_decode" "double,vector")
21305 (set_attr "mode" "DI")])
21306
21307 (define_insn "cvttss2si"
21308 [(set (match_operand:SI 0 "register_operand" "=r,r")
21309 (vec_select:SI
21310 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21311 UNSPEC_FIX)
21312 (parallel [(const_int 0)])))]
21313 "TARGET_SSE"
21314 "cvttss2si\t{%1, %0|%0, %1}"
21315 [(set_attr "type" "sseicvt")
21316 (set_attr "mode" "SF")
21317 (set_attr "athlon_decode" "double,vector")])
21318
21319 (define_insn "cvttss2siq"
21320 [(set (match_operand:DI 0 "register_operand" "=r,r")
21321 (vec_select:DI
21322 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21323 UNSPEC_FIX)
21324 (parallel [(const_int 0)])))]
21325 "TARGET_SSE && TARGET_64BIT"
21326 "cvttss2siq\t{%1, %0|%0, %1}"
21327 [(set_attr "type" "sseicvt")
21328 (set_attr "mode" "SF")
21329 (set_attr "athlon_decode" "double,vector")])
21330
21331
21332 ;; MMX insns
21333
21334 ;; MMX arithmetic
21335
21336 (define_insn "addv8qi3"
21337 [(set (match_operand:V8QI 0 "register_operand" "=y")
21338 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21339 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21340 "TARGET_MMX"
21341 "paddb\t{%2, %0|%0, %2}"
21342 [(set_attr "type" "mmxadd")
21343 (set_attr "mode" "DI")])
21344
21345 (define_insn "addv4hi3"
21346 [(set (match_operand:V4HI 0 "register_operand" "=y")
21347 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21348 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21349 "TARGET_MMX"
21350 "paddw\t{%2, %0|%0, %2}"
21351 [(set_attr "type" "mmxadd")
21352 (set_attr "mode" "DI")])
21353
21354 (define_insn "addv2si3"
21355 [(set (match_operand:V2SI 0 "register_operand" "=y")
21356 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21357 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21358 "TARGET_MMX"
21359 "paddd\t{%2, %0|%0, %2}"
21360 [(set_attr "type" "mmxadd")
21361 (set_attr "mode" "DI")])
21362
21363 (define_insn "mmx_adddi3"
21364 [(set (match_operand:DI 0 "register_operand" "=y")
21365 (unspec:DI
21366 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21367 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21368 UNSPEC_NOP))]
21369 "TARGET_MMX"
21370 "paddq\t{%2, %0|%0, %2}"
21371 [(set_attr "type" "mmxadd")
21372 (set_attr "mode" "DI")])
21373
21374 (define_insn "ssaddv8qi3"
21375 [(set (match_operand:V8QI 0 "register_operand" "=y")
21376 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21377 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21378 "TARGET_MMX"
21379 "paddsb\t{%2, %0|%0, %2}"
21380 [(set_attr "type" "mmxadd")
21381 (set_attr "mode" "DI")])
21382
21383 (define_insn "ssaddv4hi3"
21384 [(set (match_operand:V4HI 0 "register_operand" "=y")
21385 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21386 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21387 "TARGET_MMX"
21388 "paddsw\t{%2, %0|%0, %2}"
21389 [(set_attr "type" "mmxadd")
21390 (set_attr "mode" "DI")])
21391
21392 (define_insn "usaddv8qi3"
21393 [(set (match_operand:V8QI 0 "register_operand" "=y")
21394 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21395 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21396 "TARGET_MMX"
21397 "paddusb\t{%2, %0|%0, %2}"
21398 [(set_attr "type" "mmxadd")
21399 (set_attr "mode" "DI")])
21400
21401 (define_insn "usaddv4hi3"
21402 [(set (match_operand:V4HI 0 "register_operand" "=y")
21403 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21404 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21405 "TARGET_MMX"
21406 "paddusw\t{%2, %0|%0, %2}"
21407 [(set_attr "type" "mmxadd")
21408 (set_attr "mode" "DI")])
21409
21410 (define_insn "subv8qi3"
21411 [(set (match_operand:V8QI 0 "register_operand" "=y")
21412 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21413 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21414 "TARGET_MMX"
21415 "psubb\t{%2, %0|%0, %2}"
21416 [(set_attr "type" "mmxadd")
21417 (set_attr "mode" "DI")])
21418
21419 (define_insn "subv4hi3"
21420 [(set (match_operand:V4HI 0 "register_operand" "=y")
21421 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21422 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21423 "TARGET_MMX"
21424 "psubw\t{%2, %0|%0, %2}"
21425 [(set_attr "type" "mmxadd")
21426 (set_attr "mode" "DI")])
21427
21428 (define_insn "subv2si3"
21429 [(set (match_operand:V2SI 0 "register_operand" "=y")
21430 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21431 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21432 "TARGET_MMX"
21433 "psubd\t{%2, %0|%0, %2}"
21434 [(set_attr "type" "mmxadd")
21435 (set_attr "mode" "DI")])
21436
21437 (define_insn "mmx_subdi3"
21438 [(set (match_operand:DI 0 "register_operand" "=y")
21439 (unspec:DI
21440 [(minus:DI (match_operand:DI 1 "register_operand" "0")
21441 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21442 UNSPEC_NOP))]
21443 "TARGET_MMX"
21444 "psubq\t{%2, %0|%0, %2}"
21445 [(set_attr "type" "mmxadd")
21446 (set_attr "mode" "DI")])
21447
21448 (define_insn "sssubv8qi3"
21449 [(set (match_operand:V8QI 0 "register_operand" "=y")
21450 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21451 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21452 "TARGET_MMX"
21453 "psubsb\t{%2, %0|%0, %2}"
21454 [(set_attr "type" "mmxadd")
21455 (set_attr "mode" "DI")])
21456
21457 (define_insn "sssubv4hi3"
21458 [(set (match_operand:V4HI 0 "register_operand" "=y")
21459 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21460 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21461 "TARGET_MMX"
21462 "psubsw\t{%2, %0|%0, %2}"
21463 [(set_attr "type" "mmxadd")
21464 (set_attr "mode" "DI")])
21465
21466 (define_insn "ussubv8qi3"
21467 [(set (match_operand:V8QI 0 "register_operand" "=y")
21468 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21469 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21470 "TARGET_MMX"
21471 "psubusb\t{%2, %0|%0, %2}"
21472 [(set_attr "type" "mmxadd")
21473 (set_attr "mode" "DI")])
21474
21475 (define_insn "ussubv4hi3"
21476 [(set (match_operand:V4HI 0 "register_operand" "=y")
21477 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21478 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21479 "TARGET_MMX"
21480 "psubusw\t{%2, %0|%0, %2}"
21481 [(set_attr "type" "mmxadd")
21482 (set_attr "mode" "DI")])
21483
21484 (define_insn "mulv4hi3"
21485 [(set (match_operand:V4HI 0 "register_operand" "=y")
21486 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21487 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21488 "TARGET_MMX"
21489 "pmullw\t{%2, %0|%0, %2}"
21490 [(set_attr "type" "mmxmul")
21491 (set_attr "mode" "DI")])
21492
21493 (define_insn "smulv4hi3_highpart"
21494 [(set (match_operand:V4HI 0 "register_operand" "=y")
21495 (truncate:V4HI
21496 (lshiftrt:V4SI
21497 (mult:V4SI (sign_extend:V4SI
21498 (match_operand:V4HI 1 "register_operand" "0"))
21499 (sign_extend:V4SI
21500 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21501 (const_int 16))))]
21502 "TARGET_MMX"
21503 "pmulhw\t{%2, %0|%0, %2}"
21504 [(set_attr "type" "mmxmul")
21505 (set_attr "mode" "DI")])
21506
21507 (define_insn "umulv4hi3_highpart"
21508 [(set (match_operand:V4HI 0 "register_operand" "=y")
21509 (truncate:V4HI
21510 (lshiftrt:V4SI
21511 (mult:V4SI (zero_extend:V4SI
21512 (match_operand:V4HI 1 "register_operand" "0"))
21513 (zero_extend:V4SI
21514 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21515 (const_int 16))))]
21516 "TARGET_SSE || TARGET_3DNOW_A"
21517 "pmulhuw\t{%2, %0|%0, %2}"
21518 [(set_attr "type" "mmxmul")
21519 (set_attr "mode" "DI")])
21520
21521 (define_insn "mmx_pmaddwd"
21522 [(set (match_operand:V2SI 0 "register_operand" "=y")
21523 (plus:V2SI
21524 (mult:V2SI
21525 (sign_extend:V2SI
21526 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21527 (parallel [(const_int 0) (const_int 2)])))
21528 (sign_extend:V2SI
21529 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21530 (parallel [(const_int 0) (const_int 2)]))))
21531 (mult:V2SI
21532 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21533 (parallel [(const_int 1)
21534 (const_int 3)])))
21535 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21536 (parallel [(const_int 1)
21537 (const_int 3)]))))))]
21538 "TARGET_MMX"
21539 "pmaddwd\t{%2, %0|%0, %2}"
21540 [(set_attr "type" "mmxmul")
21541 (set_attr "mode" "DI")])
21542
21543
21544 ;; MMX logical operations
21545 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21546 ;; normal code that also wants to use the FPU from getting broken.
21547 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21548 (define_insn "mmx_iordi3"
21549 [(set (match_operand:DI 0 "register_operand" "=y")
21550 (unspec:DI
21551 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21552 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21553 UNSPEC_NOP))]
21554 "TARGET_MMX"
21555 "por\t{%2, %0|%0, %2}"
21556 [(set_attr "type" "mmxadd")
21557 (set_attr "mode" "DI")])
21558
21559 (define_insn "mmx_xordi3"
21560 [(set (match_operand:DI 0 "register_operand" "=y")
21561 (unspec:DI
21562 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21563 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21564 UNSPEC_NOP))]
21565 "TARGET_MMX"
21566 "pxor\t{%2, %0|%0, %2}"
21567 [(set_attr "type" "mmxadd")
21568 (set_attr "mode" "DI")
21569 (set_attr "memory" "none")])
21570
21571 ;; Same as pxor, but don't show input operands so that we don't think
21572 ;; they are live.
21573 (define_insn "mmx_clrdi"
21574 [(set (match_operand:DI 0 "register_operand" "=y")
21575 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21576 "TARGET_MMX"
21577 "pxor\t{%0, %0|%0, %0}"
21578 [(set_attr "type" "mmxadd")
21579 (set_attr "mode" "DI")
21580 (set_attr "memory" "none")])
21581
21582 (define_insn "mmx_anddi3"
21583 [(set (match_operand:DI 0 "register_operand" "=y")
21584 (unspec:DI
21585 [(and:DI (match_operand:DI 1 "register_operand" "%0")
21586 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21587 UNSPEC_NOP))]
21588 "TARGET_MMX"
21589 "pand\t{%2, %0|%0, %2}"
21590 [(set_attr "type" "mmxadd")
21591 (set_attr "mode" "DI")])
21592
21593 (define_insn "mmx_nanddi3"
21594 [(set (match_operand:DI 0 "register_operand" "=y")
21595 (unspec:DI
21596 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21597 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21598 UNSPEC_NOP))]
21599 "TARGET_MMX"
21600 "pandn\t{%2, %0|%0, %2}"
21601 [(set_attr "type" "mmxadd")
21602 (set_attr "mode" "DI")])
21603
21604
21605 ;; MMX unsigned averages/sum of absolute differences
21606
21607 (define_insn "mmx_uavgv8qi3"
21608 [(set (match_operand:V8QI 0 "register_operand" "=y")
21609 (ashiftrt:V8QI
21610 (plus:V8QI (plus:V8QI
21611 (match_operand:V8QI 1 "register_operand" "0")
21612 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21613 (const_vector:V8QI [(const_int 1)
21614 (const_int 1)
21615 (const_int 1)
21616 (const_int 1)
21617 (const_int 1)
21618 (const_int 1)
21619 (const_int 1)
21620 (const_int 1)]))
21621 (const_int 1)))]
21622 "TARGET_SSE || TARGET_3DNOW_A"
21623 "pavgb\t{%2, %0|%0, %2}"
21624 [(set_attr "type" "mmxshft")
21625 (set_attr "mode" "DI")])
21626
21627 (define_insn "mmx_uavgv4hi3"
21628 [(set (match_operand:V4HI 0 "register_operand" "=y")
21629 (ashiftrt:V4HI
21630 (plus:V4HI (plus:V4HI
21631 (match_operand:V4HI 1 "register_operand" "0")
21632 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21633 (const_vector:V4HI [(const_int 1)
21634 (const_int 1)
21635 (const_int 1)
21636 (const_int 1)]))
21637 (const_int 1)))]
21638 "TARGET_SSE || TARGET_3DNOW_A"
21639 "pavgw\t{%2, %0|%0, %2}"
21640 [(set_attr "type" "mmxshft")
21641 (set_attr "mode" "DI")])
21642
21643 (define_insn "mmx_psadbw"
21644 [(set (match_operand:DI 0 "register_operand" "=y")
21645 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21646 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21647 UNSPEC_PSADBW))]
21648 "TARGET_SSE || TARGET_3DNOW_A"
21649 "psadbw\t{%2, %0|%0, %2}"
21650 [(set_attr "type" "mmxshft")
21651 (set_attr "mode" "DI")])
21652
21653
21654 ;; MMX insert/extract/shuffle
21655
21656 (define_insn "mmx_pinsrw"
21657 [(set (match_operand:V4HI 0 "register_operand" "=y")
21658 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21659 (vec_duplicate:V4HI
21660 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21661 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21662 "TARGET_SSE || TARGET_3DNOW_A"
21663 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21664 [(set_attr "type" "mmxcvt")
21665 (set_attr "mode" "DI")])
21666
21667 (define_insn "mmx_pextrw"
21668 [(set (match_operand:SI 0 "register_operand" "=r")
21669 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21670 (parallel
21671 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21672 "TARGET_SSE || TARGET_3DNOW_A"
21673 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21674 [(set_attr "type" "mmxcvt")
21675 (set_attr "mode" "DI")])
21676
21677 (define_insn "mmx_pshufw"
21678 [(set (match_operand:V4HI 0 "register_operand" "=y")
21679 (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21680 (match_operand:SI 2 "immediate_operand" "i")]
21681 UNSPEC_SHUFFLE))]
21682 "TARGET_SSE || TARGET_3DNOW_A"
21683 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21684 [(set_attr "type" "mmxcvt")
21685 (set_attr "mode" "DI")])
21686
21687
21688 ;; MMX mask-generating comparisons
21689
21690 (define_insn "eqv8qi3"
21691 [(set (match_operand:V8QI 0 "register_operand" "=y")
21692 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21693 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21694 "TARGET_MMX"
21695 "pcmpeqb\t{%2, %0|%0, %2}"
21696 [(set_attr "type" "mmxcmp")
21697 (set_attr "mode" "DI")])
21698
21699 (define_insn "eqv4hi3"
21700 [(set (match_operand:V4HI 0 "register_operand" "=y")
21701 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21702 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21703 "TARGET_MMX"
21704 "pcmpeqw\t{%2, %0|%0, %2}"
21705 [(set_attr "type" "mmxcmp")
21706 (set_attr "mode" "DI")])
21707
21708 (define_insn "eqv2si3"
21709 [(set (match_operand:V2SI 0 "register_operand" "=y")
21710 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21711 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21712 "TARGET_MMX"
21713 "pcmpeqd\t{%2, %0|%0, %2}"
21714 [(set_attr "type" "mmxcmp")
21715 (set_attr "mode" "DI")])
21716
21717 (define_insn "gtv8qi3"
21718 [(set (match_operand:V8QI 0 "register_operand" "=y")
21719 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21720 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21721 "TARGET_MMX"
21722 "pcmpgtb\t{%2, %0|%0, %2}"
21723 [(set_attr "type" "mmxcmp")
21724 (set_attr "mode" "DI")])
21725
21726 (define_insn "gtv4hi3"
21727 [(set (match_operand:V4HI 0 "register_operand" "=y")
21728 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21729 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21730 "TARGET_MMX"
21731 "pcmpgtw\t{%2, %0|%0, %2}"
21732 [(set_attr "type" "mmxcmp")
21733 (set_attr "mode" "DI")])
21734
21735 (define_insn "gtv2si3"
21736 [(set (match_operand:V2SI 0 "register_operand" "=y")
21737 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21738 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21739 "TARGET_MMX"
21740 "pcmpgtd\t{%2, %0|%0, %2}"
21741 [(set_attr "type" "mmxcmp")
21742 (set_attr "mode" "DI")])
21743
21744
21745 ;; MMX max/min insns
21746
21747 (define_insn "umaxv8qi3"
21748 [(set (match_operand:V8QI 0 "register_operand" "=y")
21749 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21750 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21751 "TARGET_SSE || TARGET_3DNOW_A"
21752 "pmaxub\t{%2, %0|%0, %2}"
21753 [(set_attr "type" "mmxadd")
21754 (set_attr "mode" "DI")])
21755
21756 (define_insn "smaxv4hi3"
21757 [(set (match_operand:V4HI 0 "register_operand" "=y")
21758 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21759 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21760 "TARGET_SSE || TARGET_3DNOW_A"
21761 "pmaxsw\t{%2, %0|%0, %2}"
21762 [(set_attr "type" "mmxadd")
21763 (set_attr "mode" "DI")])
21764
21765 (define_insn "uminv8qi3"
21766 [(set (match_operand:V8QI 0 "register_operand" "=y")
21767 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21768 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21769 "TARGET_SSE || TARGET_3DNOW_A"
21770 "pminub\t{%2, %0|%0, %2}"
21771 [(set_attr "type" "mmxadd")
21772 (set_attr "mode" "DI")])
21773
21774 (define_insn "sminv4hi3"
21775 [(set (match_operand:V4HI 0 "register_operand" "=y")
21776 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21777 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21778 "TARGET_SSE || TARGET_3DNOW_A"
21779 "pminsw\t{%2, %0|%0, %2}"
21780 [(set_attr "type" "mmxadd")
21781 (set_attr "mode" "DI")])
21782
21783
21784 ;; MMX shifts
21785
21786 (define_insn "ashrv4hi3"
21787 [(set (match_operand:V4HI 0 "register_operand" "=y")
21788 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21789 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21790 "TARGET_MMX"
21791 "psraw\t{%2, %0|%0, %2}"
21792 [(set_attr "type" "mmxshft")
21793 (set_attr "mode" "DI")])
21794
21795 (define_insn "ashrv2si3"
21796 [(set (match_operand:V2SI 0 "register_operand" "=y")
21797 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21798 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21799 "TARGET_MMX"
21800 "psrad\t{%2, %0|%0, %2}"
21801 [(set_attr "type" "mmxshft")
21802 (set_attr "mode" "DI")])
21803
21804 (define_insn "lshrv4hi3"
21805 [(set (match_operand:V4HI 0 "register_operand" "=y")
21806 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21807 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21808 "TARGET_MMX"
21809 "psrlw\t{%2, %0|%0, %2}"
21810 [(set_attr "type" "mmxshft")
21811 (set_attr "mode" "DI")])
21812
21813 (define_insn "lshrv2si3"
21814 [(set (match_operand:V2SI 0 "register_operand" "=y")
21815 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21816 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21817 "TARGET_MMX"
21818 "psrld\t{%2, %0|%0, %2}"
21819 [(set_attr "type" "mmxshft")
21820 (set_attr "mode" "DI")])
21821
21822 ;; See logical MMX insns.
21823 (define_insn "mmx_lshrdi3"
21824 [(set (match_operand:DI 0 "register_operand" "=y")
21825 (unspec:DI
21826 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21827 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21828 UNSPEC_NOP))]
21829 "TARGET_MMX"
21830 "psrlq\t{%2, %0|%0, %2}"
21831 [(set_attr "type" "mmxshft")
21832 (set_attr "mode" "DI")])
21833
21834 (define_insn "ashlv4hi3"
21835 [(set (match_operand:V4HI 0 "register_operand" "=y")
21836 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21837 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21838 "TARGET_MMX"
21839 "psllw\t{%2, %0|%0, %2}"
21840 [(set_attr "type" "mmxshft")
21841 (set_attr "mode" "DI")])
21842
21843 (define_insn "ashlv2si3"
21844 [(set (match_operand:V2SI 0 "register_operand" "=y")
21845 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21846 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21847 "TARGET_MMX"
21848 "pslld\t{%2, %0|%0, %2}"
21849 [(set_attr "type" "mmxshft")
21850 (set_attr "mode" "DI")])
21851
21852 ;; See logical MMX insns.
21853 (define_insn "mmx_ashldi3"
21854 [(set (match_operand:DI 0 "register_operand" "=y")
21855 (unspec:DI
21856 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21857 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21858 UNSPEC_NOP))]
21859 "TARGET_MMX"
21860 "psllq\t{%2, %0|%0, %2}"
21861 [(set_attr "type" "mmxshft")
21862 (set_attr "mode" "DI")])
21863
21864
21865 ;; MMX pack/unpack insns.
21866
21867 (define_insn "mmx_packsswb"
21868 [(set (match_operand:V8QI 0 "register_operand" "=y")
21869 (vec_concat:V8QI
21870 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21871 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21872 "TARGET_MMX"
21873 "packsswb\t{%2, %0|%0, %2}"
21874 [(set_attr "type" "mmxshft")
21875 (set_attr "mode" "DI")])
21876
21877 (define_insn "mmx_packssdw"
21878 [(set (match_operand:V4HI 0 "register_operand" "=y")
21879 (vec_concat:V4HI
21880 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21881 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21882 "TARGET_MMX"
21883 "packssdw\t{%2, %0|%0, %2}"
21884 [(set_attr "type" "mmxshft")
21885 (set_attr "mode" "DI")])
21886
21887 (define_insn "mmx_packuswb"
21888 [(set (match_operand:V8QI 0 "register_operand" "=y")
21889 (vec_concat:V8QI
21890 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21891 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21892 "TARGET_MMX"
21893 "packuswb\t{%2, %0|%0, %2}"
21894 [(set_attr "type" "mmxshft")
21895 (set_attr "mode" "DI")])
21896
21897 (define_insn "mmx_punpckhbw"
21898 [(set (match_operand:V8QI 0 "register_operand" "=y")
21899 (vec_merge:V8QI
21900 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21901 (parallel [(const_int 4)
21902 (const_int 0)
21903 (const_int 5)
21904 (const_int 1)
21905 (const_int 6)
21906 (const_int 2)
21907 (const_int 7)
21908 (const_int 3)]))
21909 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21910 (parallel [(const_int 0)
21911 (const_int 4)
21912 (const_int 1)
21913 (const_int 5)
21914 (const_int 2)
21915 (const_int 6)
21916 (const_int 3)
21917 (const_int 7)]))
21918 (const_int 85)))]
21919 "TARGET_MMX"
21920 "punpckhbw\t{%2, %0|%0, %2}"
21921 [(set_attr "type" "mmxcvt")
21922 (set_attr "mode" "DI")])
21923
21924 (define_insn "mmx_punpckhwd"
21925 [(set (match_operand:V4HI 0 "register_operand" "=y")
21926 (vec_merge:V4HI
21927 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21928 (parallel [(const_int 0)
21929 (const_int 2)
21930 (const_int 1)
21931 (const_int 3)]))
21932 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21933 (parallel [(const_int 2)
21934 (const_int 0)
21935 (const_int 3)
21936 (const_int 1)]))
21937 (const_int 5)))]
21938 "TARGET_MMX"
21939 "punpckhwd\t{%2, %0|%0, %2}"
21940 [(set_attr "type" "mmxcvt")
21941 (set_attr "mode" "DI")])
21942
21943 (define_insn "mmx_punpckhdq"
21944 [(set (match_operand:V2SI 0 "register_operand" "=y")
21945 (vec_merge:V2SI
21946 (match_operand:V2SI 1 "register_operand" "0")
21947 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21948 (parallel [(const_int 1)
21949 (const_int 0)]))
21950 (const_int 1)))]
21951 "TARGET_MMX"
21952 "punpckhdq\t{%2, %0|%0, %2}"
21953 [(set_attr "type" "mmxcvt")
21954 (set_attr "mode" "DI")])
21955
21956 (define_insn "mmx_punpcklbw"
21957 [(set (match_operand:V8QI 0 "register_operand" "=y")
21958 (vec_merge:V8QI
21959 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21960 (parallel [(const_int 0)
21961 (const_int 4)
21962 (const_int 1)
21963 (const_int 5)
21964 (const_int 2)
21965 (const_int 6)
21966 (const_int 3)
21967 (const_int 7)]))
21968 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21969 (parallel [(const_int 4)
21970 (const_int 0)
21971 (const_int 5)
21972 (const_int 1)
21973 (const_int 6)
21974 (const_int 2)
21975 (const_int 7)
21976 (const_int 3)]))
21977 (const_int 85)))]
21978 "TARGET_MMX"
21979 "punpcklbw\t{%2, %0|%0, %2}"
21980 [(set_attr "type" "mmxcvt")
21981 (set_attr "mode" "DI")])
21982
21983 (define_insn "mmx_punpcklwd"
21984 [(set (match_operand:V4HI 0 "register_operand" "=y")
21985 (vec_merge:V4HI
21986 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21987 (parallel [(const_int 2)
21988 (const_int 0)
21989 (const_int 3)
21990 (const_int 1)]))
21991 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21992 (parallel [(const_int 0)
21993 (const_int 2)
21994 (const_int 1)
21995 (const_int 3)]))
21996 (const_int 5)))]
21997 "TARGET_MMX"
21998 "punpcklwd\t{%2, %0|%0, %2}"
21999 [(set_attr "type" "mmxcvt")
22000 (set_attr "mode" "DI")])
22001
22002 (define_insn "mmx_punpckldq"
22003 [(set (match_operand:V2SI 0 "register_operand" "=y")
22004 (vec_merge:V2SI
22005 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22006 (parallel [(const_int 1)
22007 (const_int 0)]))
22008 (match_operand:V2SI 2 "register_operand" "y")
22009 (const_int 1)))]
22010 "TARGET_MMX"
22011 "punpckldq\t{%2, %0|%0, %2}"
22012 [(set_attr "type" "mmxcvt")
22013 (set_attr "mode" "DI")])
22014
22015
22016 ;; Miscellaneous stuff
22017
22018 (define_insn "emms"
22019 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22020 (clobber (reg:XF 8))
22021 (clobber (reg:XF 9))
22022 (clobber (reg:XF 10))
22023 (clobber (reg:XF 11))
22024 (clobber (reg:XF 12))
22025 (clobber (reg:XF 13))
22026 (clobber (reg:XF 14))
22027 (clobber (reg:XF 15))
22028 (clobber (reg:DI 29))
22029 (clobber (reg:DI 30))
22030 (clobber (reg:DI 31))
22031 (clobber (reg:DI 32))
22032 (clobber (reg:DI 33))
22033 (clobber (reg:DI 34))
22034 (clobber (reg:DI 35))
22035 (clobber (reg:DI 36))]
22036 "TARGET_MMX"
22037 "emms"
22038 [(set_attr "type" "mmx")
22039 (set_attr "memory" "unknown")])
22040
22041 (define_insn "ldmxcsr"
22042 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22043 UNSPECV_LDMXCSR)]
22044 "TARGET_SSE"
22045 "ldmxcsr\t%0"
22046 [(set_attr "type" "sse")
22047 (set_attr "memory" "load")])
22048
22049 (define_insn "stmxcsr"
22050 [(set (match_operand:SI 0 "memory_operand" "=m")
22051 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22052 "TARGET_SSE"
22053 "stmxcsr\t%0"
22054 [(set_attr "type" "sse")
22055 (set_attr "memory" "store")])
22056
22057 (define_expand "sfence"
22058 [(set (match_dup 0)
22059 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22060 "TARGET_SSE || TARGET_3DNOW_A"
22061 {
22062 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22063 MEM_VOLATILE_P (operands[0]) = 1;
22064 })
22065
22066 (define_insn "*sfence_insn"
22067 [(set (match_operand:BLK 0 "" "")
22068 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22069 "TARGET_SSE || TARGET_3DNOW_A"
22070 "sfence"
22071 [(set_attr "type" "sse")
22072 (set_attr "memory" "unknown")])
22073
22074 (define_expand "sse_prologue_save"
22075 [(parallel [(set (match_operand:BLK 0 "" "")
22076 (unspec:BLK [(reg:DI 21)
22077 (reg:DI 22)
22078 (reg:DI 23)
22079 (reg:DI 24)
22080 (reg:DI 25)
22081 (reg:DI 26)
22082 (reg:DI 27)
22083 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22084 (use (match_operand:DI 1 "register_operand" ""))
22085 (use (match_operand:DI 2 "immediate_operand" ""))
22086 (use (label_ref:DI (match_operand 3 "" "")))])]
22087 "TARGET_64BIT"
22088 "")
22089
22090 (define_insn "*sse_prologue_save_insn"
22091 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22092 (match_operand:DI 4 "const_int_operand" "n")))
22093 (unspec:BLK [(reg:DI 21)
22094 (reg:DI 22)
22095 (reg:DI 23)
22096 (reg:DI 24)
22097 (reg:DI 25)
22098 (reg:DI 26)
22099 (reg:DI 27)
22100 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22101 (use (match_operand:DI 1 "register_operand" "r"))
22102 (use (match_operand:DI 2 "const_int_operand" "i"))
22103 (use (label_ref:DI (match_operand 3 "" "X")))]
22104 "TARGET_64BIT
22105 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22106 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22107 "*
22108 {
22109 int i;
22110 operands[0] = gen_rtx_MEM (Pmode,
22111 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22112 output_asm_insn (\"jmp\\t%A1\", operands);
22113 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22114 {
22115 operands[4] = adjust_address (operands[0], DImode, i*16);
22116 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22117 PUT_MODE (operands[4], TImode);
22118 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22119 output_asm_insn (\"rex\", operands);
22120 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22121 }
22122 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22123 CODE_LABEL_NUMBER (operands[3]));
22124 RET;
22125 }
22126 "
22127 [(set_attr "type" "other")
22128 (set_attr "length_immediate" "0")
22129 (set_attr "length_address" "0")
22130 (set_attr "length" "135")
22131 (set_attr "memory" "store")
22132 (set_attr "modrm" "0")
22133 (set_attr "mode" "DI")])
22134
22135 ;; 3Dnow! instructions
22136
22137 (define_insn "addv2sf3"
22138 [(set (match_operand:V2SF 0 "register_operand" "=y")
22139 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22140 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22141 "TARGET_3DNOW"
22142 "pfadd\\t{%2, %0|%0, %2}"
22143 [(set_attr "type" "mmxadd")
22144 (set_attr "mode" "V2SF")])
22145
22146 (define_insn "subv2sf3"
22147 [(set (match_operand:V2SF 0 "register_operand" "=y")
22148 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22149 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22150 "TARGET_3DNOW"
22151 "pfsub\\t{%2, %0|%0, %2}"
22152 [(set_attr "type" "mmxadd")
22153 (set_attr "mode" "V2SF")])
22154
22155 (define_insn "subrv2sf3"
22156 [(set (match_operand:V2SF 0 "register_operand" "=y")
22157 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22158 (match_operand:V2SF 1 "register_operand" "0")))]
22159 "TARGET_3DNOW"
22160 "pfsubr\\t{%2, %0|%0, %2}"
22161 [(set_attr "type" "mmxadd")
22162 (set_attr "mode" "V2SF")])
22163
22164 (define_insn "gtv2sf3"
22165 [(set (match_operand:V2SI 0 "register_operand" "=y")
22166 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22167 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22168 "TARGET_3DNOW"
22169 "pfcmpgt\\t{%2, %0|%0, %2}"
22170 [(set_attr "type" "mmxcmp")
22171 (set_attr "mode" "V2SF")])
22172
22173 (define_insn "gev2sf3"
22174 [(set (match_operand:V2SI 0 "register_operand" "=y")
22175 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22176 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22177 "TARGET_3DNOW"
22178 "pfcmpge\\t{%2, %0|%0, %2}"
22179 [(set_attr "type" "mmxcmp")
22180 (set_attr "mode" "V2SF")])
22181
22182 (define_insn "eqv2sf3"
22183 [(set (match_operand:V2SI 0 "register_operand" "=y")
22184 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22185 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22186 "TARGET_3DNOW"
22187 "pfcmpeq\\t{%2, %0|%0, %2}"
22188 [(set_attr "type" "mmxcmp")
22189 (set_attr "mode" "V2SF")])
22190
22191 (define_insn "pfmaxv2sf3"
22192 [(set (match_operand:V2SF 0 "register_operand" "=y")
22193 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22194 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22195 "TARGET_3DNOW"
22196 "pfmax\\t{%2, %0|%0, %2}"
22197 [(set_attr "type" "mmxadd")
22198 (set_attr "mode" "V2SF")])
22199
22200 (define_insn "pfminv2sf3"
22201 [(set (match_operand:V2SF 0 "register_operand" "=y")
22202 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22203 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22204 "TARGET_3DNOW"
22205 "pfmin\\t{%2, %0|%0, %2}"
22206 [(set_attr "type" "mmxadd")
22207 (set_attr "mode" "V2SF")])
22208
22209 (define_insn "mulv2sf3"
22210 [(set (match_operand:V2SF 0 "register_operand" "=y")
22211 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22212 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22213 "TARGET_3DNOW"
22214 "pfmul\\t{%2, %0|%0, %2}"
22215 [(set_attr "type" "mmxmul")
22216 (set_attr "mode" "V2SF")])
22217
22218 (define_insn "femms"
22219 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22220 (clobber (reg:XF 8))
22221 (clobber (reg:XF 9))
22222 (clobber (reg:XF 10))
22223 (clobber (reg:XF 11))
22224 (clobber (reg:XF 12))
22225 (clobber (reg:XF 13))
22226 (clobber (reg:XF 14))
22227 (clobber (reg:XF 15))
22228 (clobber (reg:DI 29))
22229 (clobber (reg:DI 30))
22230 (clobber (reg:DI 31))
22231 (clobber (reg:DI 32))
22232 (clobber (reg:DI 33))
22233 (clobber (reg:DI 34))
22234 (clobber (reg:DI 35))
22235 (clobber (reg:DI 36))]
22236 "TARGET_3DNOW"
22237 "femms"
22238 [(set_attr "type" "mmx")
22239 (set_attr "memory" "none")])
22240
22241 (define_insn "pf2id"
22242 [(set (match_operand:V2SI 0 "register_operand" "=y")
22243 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22244 "TARGET_3DNOW"
22245 "pf2id\\t{%1, %0|%0, %1}"
22246 [(set_attr "type" "mmxcvt")
22247 (set_attr "mode" "V2SF")])
22248
22249 (define_insn "pf2iw"
22250 [(set (match_operand:V2SI 0 "register_operand" "=y")
22251 (sign_extend:V2SI
22252 (ss_truncate:V2HI
22253 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22254 "TARGET_3DNOW_A"
22255 "pf2iw\\t{%1, %0|%0, %1}"
22256 [(set_attr "type" "mmxcvt")
22257 (set_attr "mode" "V2SF")])
22258
22259 (define_insn "pfacc"
22260 [(set (match_operand:V2SF 0 "register_operand" "=y")
22261 (vec_concat:V2SF
22262 (plus:SF
22263 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22264 (parallel [(const_int 0)]))
22265 (vec_select:SF (match_dup 1)
22266 (parallel [(const_int 1)])))
22267 (plus:SF
22268 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22269 (parallel [(const_int 0)]))
22270 (vec_select:SF (match_dup 2)
22271 (parallel [(const_int 1)])))))]
22272 "TARGET_3DNOW"
22273 "pfacc\\t{%2, %0|%0, %2}"
22274 [(set_attr "type" "mmxadd")
22275 (set_attr "mode" "V2SF")])
22276
22277 (define_insn "pfnacc"
22278 [(set (match_operand:V2SF 0 "register_operand" "=y")
22279 (vec_concat:V2SF
22280 (minus:SF
22281 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22282 (parallel [(const_int 0)]))
22283 (vec_select:SF (match_dup 1)
22284 (parallel [(const_int 1)])))
22285 (minus:SF
22286 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22287 (parallel [(const_int 0)]))
22288 (vec_select:SF (match_dup 2)
22289 (parallel [(const_int 1)])))))]
22290 "TARGET_3DNOW_A"
22291 "pfnacc\\t{%2, %0|%0, %2}"
22292 [(set_attr "type" "mmxadd")
22293 (set_attr "mode" "V2SF")])
22294
22295 (define_insn "pfpnacc"
22296 [(set (match_operand:V2SF 0 "register_operand" "=y")
22297 (vec_concat:V2SF
22298 (minus:SF
22299 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22300 (parallel [(const_int 0)]))
22301 (vec_select:SF (match_dup 1)
22302 (parallel [(const_int 1)])))
22303 (plus:SF
22304 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22305 (parallel [(const_int 0)]))
22306 (vec_select:SF (match_dup 2)
22307 (parallel [(const_int 1)])))))]
22308 "TARGET_3DNOW_A"
22309 "pfpnacc\\t{%2, %0|%0, %2}"
22310 [(set_attr "type" "mmxadd")
22311 (set_attr "mode" "V2SF")])
22312
22313 (define_insn "pi2fw"
22314 [(set (match_operand:V2SF 0 "register_operand" "=y")
22315 (float:V2SF
22316 (vec_concat:V2SI
22317 (sign_extend:SI
22318 (truncate:HI
22319 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22320 (parallel [(const_int 0)]))))
22321 (sign_extend:SI
22322 (truncate:HI
22323 (vec_select:SI (match_dup 1)
22324 (parallel [(const_int 1)])))))))]
22325 "TARGET_3DNOW_A"
22326 "pi2fw\\t{%1, %0|%0, %1}"
22327 [(set_attr "type" "mmxcvt")
22328 (set_attr "mode" "V2SF")])
22329
22330 (define_insn "floatv2si2"
22331 [(set (match_operand:V2SF 0 "register_operand" "=y")
22332 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22333 "TARGET_3DNOW"
22334 "pi2fd\\t{%1, %0|%0, %1}"
22335 [(set_attr "type" "mmxcvt")
22336 (set_attr "mode" "V2SF")])
22337
22338 ;; This insn is identical to pavgb in operation, but the opcode is
22339 ;; different. To avoid accidentally matching pavgb, use an unspec.
22340
22341 (define_insn "pavgusb"
22342 [(set (match_operand:V8QI 0 "register_operand" "=y")
22343 (unspec:V8QI
22344 [(match_operand:V8QI 1 "register_operand" "0")
22345 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22346 UNSPEC_PAVGUSB))]
22347 "TARGET_3DNOW"
22348 "pavgusb\\t{%2, %0|%0, %2}"
22349 [(set_attr "type" "mmxshft")
22350 (set_attr "mode" "TI")])
22351
22352 ;; 3DNow reciprocal and sqrt
22353
22354 (define_insn "pfrcpv2sf2"
22355 [(set (match_operand:V2SF 0 "register_operand" "=y")
22356 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22357 UNSPEC_PFRCP))]
22358 "TARGET_3DNOW"
22359 "pfrcp\\t{%1, %0|%0, %1}"
22360 [(set_attr "type" "mmx")
22361 (set_attr "mode" "TI")])
22362
22363 (define_insn "pfrcpit1v2sf3"
22364 [(set (match_operand:V2SF 0 "register_operand" "=y")
22365 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22366 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22367 UNSPEC_PFRCPIT1))]
22368 "TARGET_3DNOW"
22369 "pfrcpit1\\t{%2, %0|%0, %2}"
22370 [(set_attr "type" "mmx")
22371 (set_attr "mode" "TI")])
22372
22373 (define_insn "pfrcpit2v2sf3"
22374 [(set (match_operand:V2SF 0 "register_operand" "=y")
22375 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22376 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22377 UNSPEC_PFRCPIT2))]
22378 "TARGET_3DNOW"
22379 "pfrcpit2\\t{%2, %0|%0, %2}"
22380 [(set_attr "type" "mmx")
22381 (set_attr "mode" "TI")])
22382
22383 (define_insn "pfrsqrtv2sf2"
22384 [(set (match_operand:V2SF 0 "register_operand" "=y")
22385 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22386 UNSPEC_PFRSQRT))]
22387 "TARGET_3DNOW"
22388 "pfrsqrt\\t{%1, %0|%0, %1}"
22389 [(set_attr "type" "mmx")
22390 (set_attr "mode" "TI")])
22391
22392 (define_insn "pfrsqit1v2sf3"
22393 [(set (match_operand:V2SF 0 "register_operand" "=y")
22394 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22395 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22396 UNSPEC_PFRSQIT1))]
22397 "TARGET_3DNOW"
22398 "pfrsqit1\\t{%2, %0|%0, %2}"
22399 [(set_attr "type" "mmx")
22400 (set_attr "mode" "TI")])
22401
22402 (define_insn "pmulhrwv4hi3"
22403 [(set (match_operand:V4HI 0 "register_operand" "=y")
22404 (truncate:V4HI
22405 (lshiftrt:V4SI
22406 (plus:V4SI
22407 (mult:V4SI
22408 (sign_extend:V4SI
22409 (match_operand:V4HI 1 "register_operand" "0"))
22410 (sign_extend:V4SI
22411 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22412 (const_vector:V4SI [(const_int 32768)
22413 (const_int 32768)
22414 (const_int 32768)
22415 (const_int 32768)]))
22416 (const_int 16))))]
22417 "TARGET_3DNOW"
22418 "pmulhrw\\t{%2, %0|%0, %2}"
22419 [(set_attr "type" "mmxmul")
22420 (set_attr "mode" "TI")])
22421
22422 (define_insn "pswapdv2si2"
22423 [(set (match_operand:V2SI 0 "register_operand" "=y")
22424 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22425 (parallel [(const_int 1) (const_int 0)])))]
22426 "TARGET_3DNOW_A"
22427 "pswapd\\t{%1, %0|%0, %1}"
22428 [(set_attr "type" "mmxcvt")
22429 (set_attr "mode" "TI")])
22430
22431 (define_insn "pswapdv2sf2"
22432 [(set (match_operand:V2SF 0 "register_operand" "=y")
22433 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22434 (parallel [(const_int 1) (const_int 0)])))]
22435 "TARGET_3DNOW_A"
22436 "pswapd\\t{%1, %0|%0, %1}"
22437 [(set_attr "type" "mmxcvt")
22438 (set_attr "mode" "TI")])
22439
22440 (define_expand "prefetch"
22441 [(prefetch (match_operand 0 "address_operand" "")
22442 (match_operand:SI 1 "const_int_operand" "")
22443 (match_operand:SI 2 "const_int_operand" ""))]
22444 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22445 {
22446 int rw = INTVAL (operands[1]);
22447 int locality = INTVAL (operands[2]);
22448
22449 if (rw != 0 && rw != 1)
22450 abort ();
22451 if (locality < 0 || locality > 3)
22452 abort ();
22453 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22454 abort ();
22455
22456 /* Use 3dNOW prefetch in case we are asking for write prefetch not
22457 suported by SSE counterpart or the SSE prefetch is not available
22458 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22459 of locality. */
22460 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22461 operands[2] = GEN_INT (3);
22462 else
22463 operands[1] = const0_rtx;
22464 })
22465
22466 (define_insn "*prefetch_sse"
22467 [(prefetch (match_operand:SI 0 "address_operand" "p")
22468 (const_int 0)
22469 (match_operand:SI 1 "const_int_operand" ""))]
22470 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22471 {
22472 static const char * const patterns[4] = {
22473 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22474 };
22475
22476 int locality = INTVAL (operands[1]);
22477 if (locality < 0 || locality > 3)
22478 abort ();
22479
22480 return patterns[locality];
22481 }
22482 [(set_attr "type" "sse")
22483 (set_attr "memory" "none")])
22484
22485 (define_insn "*prefetch_sse_rex"
22486 [(prefetch (match_operand:DI 0 "address_operand" "p")
22487 (const_int 0)
22488 (match_operand:SI 1 "const_int_operand" ""))]
22489 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22490 {
22491 static const char * const patterns[4] = {
22492 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22493 };
22494
22495 int locality = INTVAL (operands[1]);
22496 if (locality < 0 || locality > 3)
22497 abort ();
22498
22499 return patterns[locality];
22500 }
22501 [(set_attr "type" "sse")
22502 (set_attr "memory" "none")])
22503
22504 (define_insn "*prefetch_3dnow"
22505 [(prefetch (match_operand:SI 0 "address_operand" "p")
22506 (match_operand:SI 1 "const_int_operand" "n")
22507 (const_int 3))]
22508 "TARGET_3DNOW && !TARGET_64BIT"
22509 {
22510 if (INTVAL (operands[1]) == 0)
22511 return "prefetch\t%a0";
22512 else
22513 return "prefetchw\t%a0";
22514 }
22515 [(set_attr "type" "mmx")
22516 (set_attr "memory" "none")])
22517
22518 (define_insn "*prefetch_3dnow_rex"
22519 [(prefetch (match_operand:DI 0 "address_operand" "p")
22520 (match_operand:SI 1 "const_int_operand" "n")
22521 (const_int 3))]
22522 "TARGET_3DNOW && TARGET_64BIT"
22523 {
22524 if (INTVAL (operands[1]) == 0)
22525 return "prefetch\t%a0";
22526 else
22527 return "prefetchw\t%a0";
22528 }
22529 [(set_attr "type" "mmx")
22530 (set_attr "memory" "none")])
22531
22532 ;; SSE2 support
22533
22534 (define_insn "addv2df3"
22535 [(set (match_operand:V2DF 0 "register_operand" "=x")
22536 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22537 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22538 "TARGET_SSE2"
22539 "addpd\t{%2, %0|%0, %2}"
22540 [(set_attr "type" "sseadd")
22541 (set_attr "mode" "V2DF")])
22542
22543 (define_insn "vmaddv2df3"
22544 [(set (match_operand:V2DF 0 "register_operand" "=x")
22545 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22546 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22547 (match_dup 1)
22548 (const_int 1)))]
22549 "TARGET_SSE2"
22550 "addsd\t{%2, %0|%0, %2}"
22551 [(set_attr "type" "sseadd")
22552 (set_attr "mode" "DF")])
22553
22554 (define_insn "subv2df3"
22555 [(set (match_operand:V2DF 0 "register_operand" "=x")
22556 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22557 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22558 "TARGET_SSE2"
22559 "subpd\t{%2, %0|%0, %2}"
22560 [(set_attr "type" "sseadd")
22561 (set_attr "mode" "V2DF")])
22562
22563 (define_insn "vmsubv2df3"
22564 [(set (match_operand:V2DF 0 "register_operand" "=x")
22565 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22566 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22567 (match_dup 1)
22568 (const_int 1)))]
22569 "TARGET_SSE2"
22570 "subsd\t{%2, %0|%0, %2}"
22571 [(set_attr "type" "sseadd")
22572 (set_attr "mode" "DF")])
22573
22574 (define_insn "mulv2df3"
22575 [(set (match_operand:V2DF 0 "register_operand" "=x")
22576 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22577 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22578 "TARGET_SSE2"
22579 "mulpd\t{%2, %0|%0, %2}"
22580 [(set_attr "type" "ssemul")
22581 (set_attr "mode" "V2DF")])
22582
22583 (define_insn "vmmulv2df3"
22584 [(set (match_operand:V2DF 0 "register_operand" "=x")
22585 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22586 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22587 (match_dup 1)
22588 (const_int 1)))]
22589 "TARGET_SSE2"
22590 "mulsd\t{%2, %0|%0, %2}"
22591 [(set_attr "type" "ssemul")
22592 (set_attr "mode" "DF")])
22593
22594 (define_insn "divv2df3"
22595 [(set (match_operand:V2DF 0 "register_operand" "=x")
22596 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22597 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22598 "TARGET_SSE2"
22599 "divpd\t{%2, %0|%0, %2}"
22600 [(set_attr "type" "ssediv")
22601 (set_attr "mode" "V2DF")])
22602
22603 (define_insn "vmdivv2df3"
22604 [(set (match_operand:V2DF 0 "register_operand" "=x")
22605 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22606 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22607 (match_dup 1)
22608 (const_int 1)))]
22609 "TARGET_SSE2"
22610 "divsd\t{%2, %0|%0, %2}"
22611 [(set_attr "type" "ssediv")
22612 (set_attr "mode" "DF")])
22613
22614 ;; SSE min/max
22615
22616 (define_insn "smaxv2df3"
22617 [(set (match_operand:V2DF 0 "register_operand" "=x")
22618 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22619 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22620 "TARGET_SSE2"
22621 "maxpd\t{%2, %0|%0, %2}"
22622 [(set_attr "type" "sseadd")
22623 (set_attr "mode" "V2DF")])
22624
22625 (define_insn "vmsmaxv2df3"
22626 [(set (match_operand:V2DF 0 "register_operand" "=x")
22627 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22628 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22629 (match_dup 1)
22630 (const_int 1)))]
22631 "TARGET_SSE2"
22632 "maxsd\t{%2, %0|%0, %2}"
22633 [(set_attr "type" "sseadd")
22634 (set_attr "mode" "DF")])
22635
22636 (define_insn "sminv2df3"
22637 [(set (match_operand:V2DF 0 "register_operand" "=x")
22638 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22639 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22640 "TARGET_SSE2"
22641 "minpd\t{%2, %0|%0, %2}"
22642 [(set_attr "type" "sseadd")
22643 (set_attr "mode" "V2DF")])
22644
22645 (define_insn "vmsminv2df3"
22646 [(set (match_operand:V2DF 0 "register_operand" "=x")
22647 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22648 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22649 (match_dup 1)
22650 (const_int 1)))]
22651 "TARGET_SSE2"
22652 "minsd\t{%2, %0|%0, %2}"
22653 [(set_attr "type" "sseadd")
22654 (set_attr "mode" "DF")])
22655 ;; SSE2 square root. There doesn't appear to be an extension for the
22656 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22657
22658 (define_insn "sqrtv2df2"
22659 [(set (match_operand:V2DF 0 "register_operand" "=x")
22660 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22661 "TARGET_SSE2"
22662 "sqrtpd\t{%1, %0|%0, %1}"
22663 [(set_attr "type" "sse")
22664 (set_attr "mode" "V2DF")])
22665
22666 (define_insn "vmsqrtv2df2"
22667 [(set (match_operand:V2DF 0 "register_operand" "=x")
22668 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22669 (match_operand:V2DF 2 "register_operand" "0")
22670 (const_int 1)))]
22671 "TARGET_SSE2"
22672 "sqrtsd\t{%1, %0|%0, %1}"
22673 [(set_attr "type" "sse")
22674 (set_attr "mode" "SF")])
22675
22676 ;; SSE mask-generating compares
22677
22678 (define_insn "maskcmpv2df3"
22679 [(set (match_operand:V2DI 0 "register_operand" "=x")
22680 (match_operator:V2DI 3 "sse_comparison_operator"
22681 [(match_operand:V2DF 1 "register_operand" "0")
22682 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22683 "TARGET_SSE2"
22684 "cmp%D3pd\t{%2, %0|%0, %2}"
22685 [(set_attr "type" "ssecmp")
22686 (set_attr "mode" "V2DF")])
22687
22688 (define_insn "maskncmpv2df3"
22689 [(set (match_operand:V2DI 0 "register_operand" "=x")
22690 (not:V2DI
22691 (match_operator:V2DI 3 "sse_comparison_operator"
22692 [(match_operand:V2DF 1 "register_operand" "0")
22693 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22694 "TARGET_SSE2"
22695 {
22696 if (GET_CODE (operands[3]) == UNORDERED)
22697 return "cmpordps\t{%2, %0|%0, %2}";
22698 else
22699 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22700 }
22701 [(set_attr "type" "ssecmp")
22702 (set_attr "mode" "V2DF")])
22703
22704 (define_insn "vmmaskcmpv2df3"
22705 [(set (match_operand:V2DI 0 "register_operand" "=x")
22706 (vec_merge:V2DI
22707 (match_operator:V2DI 3 "sse_comparison_operator"
22708 [(match_operand:V2DF 1 "register_operand" "0")
22709 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22710 (subreg:V2DI (match_dup 1) 0)
22711 (const_int 1)))]
22712 "TARGET_SSE2"
22713 "cmp%D3sd\t{%2, %0|%0, %2}"
22714 [(set_attr "type" "ssecmp")
22715 (set_attr "mode" "DF")])
22716
22717 (define_insn "vmmaskncmpv2df3"
22718 [(set (match_operand:V2DI 0 "register_operand" "=x")
22719 (vec_merge:V2DI
22720 (not:V2DI
22721 (match_operator:V2DI 3 "sse_comparison_operator"
22722 [(match_operand:V2DF 1 "register_operand" "0")
22723 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22724 (subreg:V2DI (match_dup 1) 0)
22725 (const_int 1)))]
22726 "TARGET_SSE2"
22727 {
22728 if (GET_CODE (operands[3]) == UNORDERED)
22729 return "cmpordsd\t{%2, %0|%0, %2}";
22730 else
22731 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22732 }
22733 [(set_attr "type" "ssecmp")
22734 (set_attr "mode" "DF")])
22735
22736 (define_insn "sse2_comi"
22737 [(set (reg:CCFP FLAGS_REG)
22738 (compare:CCFP (vec_select:DF
22739 (match_operand:V2DF 0 "register_operand" "x")
22740 (parallel [(const_int 0)]))
22741 (vec_select:DF
22742 (match_operand:V2DF 1 "register_operand" "x")
22743 (parallel [(const_int 0)]))))]
22744 "TARGET_SSE2"
22745 "comisd\t{%1, %0|%0, %1}"
22746 [(set_attr "type" "ssecomi")
22747 (set_attr "mode" "DF")])
22748
22749 (define_insn "sse2_ucomi"
22750 [(set (reg:CCFPU FLAGS_REG)
22751 (compare:CCFPU (vec_select:DF
22752 (match_operand:V2DF 0 "register_operand" "x")
22753 (parallel [(const_int 0)]))
22754 (vec_select:DF
22755 (match_operand:V2DF 1 "register_operand" "x")
22756 (parallel [(const_int 0)]))))]
22757 "TARGET_SSE2"
22758 "ucomisd\t{%1, %0|%0, %1}"
22759 [(set_attr "type" "ssecomi")
22760 (set_attr "mode" "DF")])
22761
22762 ;; SSE Strange Moves.
22763
22764 (define_insn "sse2_movmskpd"
22765 [(set (match_operand:SI 0 "register_operand" "=r")
22766 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22767 UNSPEC_MOVMSK))]
22768 "TARGET_SSE2"
22769 "movmskpd\t{%1, %0|%0, %1}"
22770 [(set_attr "type" "ssecvt")
22771 (set_attr "mode" "V2DF")])
22772
22773 (define_insn "sse2_pmovmskb"
22774 [(set (match_operand:SI 0 "register_operand" "=r")
22775 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22776 UNSPEC_MOVMSK))]
22777 "TARGET_SSE2"
22778 "pmovmskb\t{%1, %0|%0, %1}"
22779 [(set_attr "type" "ssecvt")
22780 (set_attr "mode" "V2DF")])
22781
22782 (define_insn "sse2_maskmovdqu"
22783 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22784 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22785 (match_operand:V16QI 2 "register_operand" "x")]
22786 UNSPEC_MASKMOV))]
22787 "TARGET_SSE2"
22788 ;; @@@ check ordering of operands in intel/nonintel syntax
22789 "maskmovdqu\t{%2, %1|%1, %2}"
22790 [(set_attr "type" "ssecvt")
22791 (set_attr "mode" "TI")])
22792
22793 (define_insn "sse2_maskmovdqu_rex64"
22794 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22795 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22796 (match_operand:V16QI 2 "register_operand" "x")]
22797 UNSPEC_MASKMOV))]
22798 "TARGET_SSE2"
22799 ;; @@@ check ordering of operands in intel/nonintel syntax
22800 "maskmovdqu\t{%2, %1|%1, %2}"
22801 [(set_attr "type" "ssecvt")
22802 (set_attr "mode" "TI")])
22803
22804 (define_insn "sse2_movntv2df"
22805 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22806 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22807 UNSPEC_MOVNT))]
22808 "TARGET_SSE2"
22809 "movntpd\t{%1, %0|%0, %1}"
22810 [(set_attr "type" "ssecvt")
22811 (set_attr "mode" "V2DF")])
22812
22813 (define_insn "sse2_movntv2di"
22814 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22815 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22816 UNSPEC_MOVNT))]
22817 "TARGET_SSE2"
22818 "movntdq\t{%1, %0|%0, %1}"
22819 [(set_attr "type" "ssecvt")
22820 (set_attr "mode" "TI")])
22821
22822 (define_insn "sse2_movntsi"
22823 [(set (match_operand:SI 0 "memory_operand" "=m")
22824 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22825 UNSPEC_MOVNT))]
22826 "TARGET_SSE2"
22827 "movnti\t{%1, %0|%0, %1}"
22828 [(set_attr "type" "ssecvt")
22829 (set_attr "mode" "V2DF")])
22830
22831 ;; SSE <-> integer/MMX conversions
22832
22833 ;; Conversions between SI and SF
22834
22835 (define_insn "cvtdq2ps"
22836 [(set (match_operand:V4SF 0 "register_operand" "=x")
22837 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22838 "TARGET_SSE2"
22839 "cvtdq2ps\t{%1, %0|%0, %1}"
22840 [(set_attr "type" "ssecvt")
22841 (set_attr "mode" "V2DF")])
22842
22843 (define_insn "cvtps2dq"
22844 [(set (match_operand:V4SI 0 "register_operand" "=x")
22845 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22846 "TARGET_SSE2"
22847 "cvtps2dq\t{%1, %0|%0, %1}"
22848 [(set_attr "type" "ssecvt")
22849 (set_attr "mode" "TI")])
22850
22851 (define_insn "cvttps2dq"
22852 [(set (match_operand:V4SI 0 "register_operand" "=x")
22853 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22854 UNSPEC_FIX))]
22855 "TARGET_SSE2"
22856 "cvttps2dq\t{%1, %0|%0, %1}"
22857 [(set_attr "type" "ssecvt")
22858 (set_attr "mode" "TI")])
22859
22860 ;; Conversions between SI and DF
22861
22862 (define_insn "cvtdq2pd"
22863 [(set (match_operand:V2DF 0 "register_operand" "=x")
22864 (float:V2DF (vec_select:V2SI
22865 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22866 (parallel
22867 [(const_int 0)
22868 (const_int 1)]))))]
22869 "TARGET_SSE2"
22870 "cvtdq2pd\t{%1, %0|%0, %1}"
22871 [(set_attr "type" "ssecvt")
22872 (set_attr "mode" "V2DF")])
22873
22874 (define_insn "cvtpd2dq"
22875 [(set (match_operand:V4SI 0 "register_operand" "=x")
22876 (vec_concat:V4SI
22877 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22878 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22879 "TARGET_SSE2"
22880 "cvtpd2dq\t{%1, %0|%0, %1}"
22881 [(set_attr "type" "ssecvt")
22882 (set_attr "mode" "TI")])
22883
22884 (define_insn "cvttpd2dq"
22885 [(set (match_operand:V4SI 0 "register_operand" "=x")
22886 (vec_concat:V4SI
22887 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22888 UNSPEC_FIX)
22889 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22890 "TARGET_SSE2"
22891 "cvttpd2dq\t{%1, %0|%0, %1}"
22892 [(set_attr "type" "ssecvt")
22893 (set_attr "mode" "TI")])
22894
22895 (define_insn "cvtpd2pi"
22896 [(set (match_operand:V2SI 0 "register_operand" "=y")
22897 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22898 "TARGET_SSE2"
22899 "cvtpd2pi\t{%1, %0|%0, %1}"
22900 [(set_attr "type" "ssecvt")
22901 (set_attr "mode" "TI")])
22902
22903 (define_insn "cvttpd2pi"
22904 [(set (match_operand:V2SI 0 "register_operand" "=y")
22905 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22906 UNSPEC_FIX))]
22907 "TARGET_SSE2"
22908 "cvttpd2pi\t{%1, %0|%0, %1}"
22909 [(set_attr "type" "ssecvt")
22910 (set_attr "mode" "TI")])
22911
22912 (define_insn "cvtpi2pd"
22913 [(set (match_operand:V2DF 0 "register_operand" "=x")
22914 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22915 "TARGET_SSE2"
22916 "cvtpi2pd\t{%1, %0|%0, %1}"
22917 [(set_attr "type" "ssecvt")
22918 (set_attr "mode" "TI")])
22919
22920 ;; Conversions between SI and DF
22921
22922 (define_insn "cvtsd2si"
22923 [(set (match_operand:SI 0 "register_operand" "=r,r")
22924 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22925 (parallel [(const_int 0)]))))]
22926 "TARGET_SSE2"
22927 "cvtsd2si\t{%1, %0|%0, %1}"
22928 [(set_attr "type" "sseicvt")
22929 (set_attr "athlon_decode" "double,vector")
22930 (set_attr "mode" "SI")])
22931
22932 (define_insn "cvtsd2siq"
22933 [(set (match_operand:DI 0 "register_operand" "=r,r")
22934 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22935 (parallel [(const_int 0)]))))]
22936 "TARGET_SSE2 && TARGET_64BIT"
22937 "cvtsd2siq\t{%1, %0|%0, %1}"
22938 [(set_attr "type" "sseicvt")
22939 (set_attr "athlon_decode" "double,vector")
22940 (set_attr "mode" "DI")])
22941
22942 (define_insn "cvttsd2si"
22943 [(set (match_operand:SI 0 "register_operand" "=r,r")
22944 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22945 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22946 "TARGET_SSE2"
22947 "cvttsd2si\t{%1, %0|%0, %1}"
22948 [(set_attr "type" "sseicvt")
22949 (set_attr "mode" "SI")
22950 (set_attr "athlon_decode" "double,vector")])
22951
22952 (define_insn "cvttsd2siq"
22953 [(set (match_operand:DI 0 "register_operand" "=r,r")
22954 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22955 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22956 "TARGET_SSE2 && TARGET_64BIT"
22957 "cvttsd2siq\t{%1, %0|%0, %1}"
22958 [(set_attr "type" "sseicvt")
22959 (set_attr "mode" "DI")
22960 (set_attr "athlon_decode" "double,vector")])
22961
22962 (define_insn "cvtsi2sd"
22963 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22964 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22965 (vec_duplicate:V2DF
22966 (float:DF
22967 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22968 (const_int 2)))]
22969 "TARGET_SSE2"
22970 "cvtsi2sd\t{%2, %0|%0, %2}"
22971 [(set_attr "type" "sseicvt")
22972 (set_attr "mode" "DF")
22973 (set_attr "athlon_decode" "double,direct")])
22974
22975 (define_insn "cvtsi2sdq"
22976 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22977 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22978 (vec_duplicate:V2DF
22979 (float:DF
22980 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22981 (const_int 2)))]
22982 "TARGET_SSE2 && TARGET_64BIT"
22983 "cvtsi2sdq\t{%2, %0|%0, %2}"
22984 [(set_attr "type" "sseicvt")
22985 (set_attr "mode" "DF")
22986 (set_attr "athlon_decode" "double,direct")])
22987
22988 ;; Conversions between SF and DF
22989
22990 (define_insn "cvtsd2ss"
22991 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22992 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22993 (vec_duplicate:V4SF
22994 (float_truncate:V2SF
22995 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22996 (const_int 14)))]
22997 "TARGET_SSE2"
22998 "cvtsd2ss\t{%2, %0|%0, %2}"
22999 [(set_attr "type" "ssecvt")
23000 (set_attr "athlon_decode" "vector,double")
23001 (set_attr "mode" "SF")])
23002
23003 (define_insn "cvtss2sd"
23004 [(set (match_operand:V2DF 0 "register_operand" "=x")
23005 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23006 (float_extend:V2DF
23007 (vec_select:V2SF
23008 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23009 (parallel [(const_int 0)
23010 (const_int 1)])))
23011 (const_int 2)))]
23012 "TARGET_SSE2"
23013 "cvtss2sd\t{%2, %0|%0, %2}"
23014 [(set_attr "type" "ssecvt")
23015 (set_attr "mode" "DF")])
23016
23017 (define_insn "cvtpd2ps"
23018 [(set (match_operand:V4SF 0 "register_operand" "=x")
23019 (subreg:V4SF
23020 (vec_concat:V4SI
23021 (subreg:V2SI (float_truncate:V2SF
23022 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23023 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23024 "TARGET_SSE2"
23025 "cvtpd2ps\t{%1, %0|%0, %1}"
23026 [(set_attr "type" "ssecvt")
23027 (set_attr "mode" "V4SF")])
23028
23029 (define_insn "cvtps2pd"
23030 [(set (match_operand:V2DF 0 "register_operand" "=x")
23031 (float_extend:V2DF
23032 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23033 (parallel [(const_int 0)
23034 (const_int 1)]))))]
23035 "TARGET_SSE2"
23036 "cvtps2pd\t{%1, %0|%0, %1}"
23037 [(set_attr "type" "ssecvt")
23038 (set_attr "mode" "V2DF")])
23039
23040 ;; SSE2 variants of MMX insns
23041
23042 ;; MMX arithmetic
23043
23044 (define_insn "addv16qi3"
23045 [(set (match_operand:V16QI 0 "register_operand" "=x")
23046 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23047 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23048 "TARGET_SSE2"
23049 "paddb\t{%2, %0|%0, %2}"
23050 [(set_attr "type" "sseiadd")
23051 (set_attr "mode" "TI")])
23052
23053 (define_insn "addv8hi3"
23054 [(set (match_operand:V8HI 0 "register_operand" "=x")
23055 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23056 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23057 "TARGET_SSE2"
23058 "paddw\t{%2, %0|%0, %2}"
23059 [(set_attr "type" "sseiadd")
23060 (set_attr "mode" "TI")])
23061
23062 (define_insn "addv4si3"
23063 [(set (match_operand:V4SI 0 "register_operand" "=x")
23064 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23065 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23066 "TARGET_SSE2"
23067 "paddd\t{%2, %0|%0, %2}"
23068 [(set_attr "type" "sseiadd")
23069 (set_attr "mode" "TI")])
23070
23071 (define_insn "addv2di3"
23072 [(set (match_operand:V2DI 0 "register_operand" "=x")
23073 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23074 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23075 "TARGET_SSE2"
23076 "paddq\t{%2, %0|%0, %2}"
23077 [(set_attr "type" "sseiadd")
23078 (set_attr "mode" "TI")])
23079
23080 (define_insn "ssaddv16qi3"
23081 [(set (match_operand:V16QI 0 "register_operand" "=x")
23082 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23083 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23084 "TARGET_SSE2"
23085 "paddsb\t{%2, %0|%0, %2}"
23086 [(set_attr "type" "sseiadd")
23087 (set_attr "mode" "TI")])
23088
23089 (define_insn "ssaddv8hi3"
23090 [(set (match_operand:V8HI 0 "register_operand" "=x")
23091 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23092 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23093 "TARGET_SSE2"
23094 "paddsw\t{%2, %0|%0, %2}"
23095 [(set_attr "type" "sseiadd")
23096 (set_attr "mode" "TI")])
23097
23098 (define_insn "usaddv16qi3"
23099 [(set (match_operand:V16QI 0 "register_operand" "=x")
23100 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23101 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23102 "TARGET_SSE2"
23103 "paddusb\t{%2, %0|%0, %2}"
23104 [(set_attr "type" "sseiadd")
23105 (set_attr "mode" "TI")])
23106
23107 (define_insn "usaddv8hi3"
23108 [(set (match_operand:V8HI 0 "register_operand" "=x")
23109 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23110 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23111 "TARGET_SSE2"
23112 "paddusw\t{%2, %0|%0, %2}"
23113 [(set_attr "type" "sseiadd")
23114 (set_attr "mode" "TI")])
23115
23116 (define_insn "subv16qi3"
23117 [(set (match_operand:V16QI 0 "register_operand" "=x")
23118 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23119 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23120 "TARGET_SSE2"
23121 "psubb\t{%2, %0|%0, %2}"
23122 [(set_attr "type" "sseiadd")
23123 (set_attr "mode" "TI")])
23124
23125 (define_insn "subv8hi3"
23126 [(set (match_operand:V8HI 0 "register_operand" "=x")
23127 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23128 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23129 "TARGET_SSE2"
23130 "psubw\t{%2, %0|%0, %2}"
23131 [(set_attr "type" "sseiadd")
23132 (set_attr "mode" "TI")])
23133
23134 (define_insn "subv4si3"
23135 [(set (match_operand:V4SI 0 "register_operand" "=x")
23136 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23137 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23138 "TARGET_SSE2"
23139 "psubd\t{%2, %0|%0, %2}"
23140 [(set_attr "type" "sseiadd")
23141 (set_attr "mode" "TI")])
23142
23143 (define_insn "subv2di3"
23144 [(set (match_operand:V2DI 0 "register_operand" "=x")
23145 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23146 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23147 "TARGET_SSE2"
23148 "psubq\t{%2, %0|%0, %2}"
23149 [(set_attr "type" "sseiadd")
23150 (set_attr "mode" "TI")])
23151
23152 (define_insn "sssubv16qi3"
23153 [(set (match_operand:V16QI 0 "register_operand" "=x")
23154 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23155 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23156 "TARGET_SSE2"
23157 "psubsb\t{%2, %0|%0, %2}"
23158 [(set_attr "type" "sseiadd")
23159 (set_attr "mode" "TI")])
23160
23161 (define_insn "sssubv8hi3"
23162 [(set (match_operand:V8HI 0 "register_operand" "=x")
23163 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23164 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23165 "TARGET_SSE2"
23166 "psubsw\t{%2, %0|%0, %2}"
23167 [(set_attr "type" "sseiadd")
23168 (set_attr "mode" "TI")])
23169
23170 (define_insn "ussubv16qi3"
23171 [(set (match_operand:V16QI 0 "register_operand" "=x")
23172 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23173 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23174 "TARGET_SSE2"
23175 "psubusb\t{%2, %0|%0, %2}"
23176 [(set_attr "type" "sseiadd")
23177 (set_attr "mode" "TI")])
23178
23179 (define_insn "ussubv8hi3"
23180 [(set (match_operand:V8HI 0 "register_operand" "=x")
23181 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23182 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23183 "TARGET_SSE2"
23184 "psubusw\t{%2, %0|%0, %2}"
23185 [(set_attr "type" "sseiadd")
23186 (set_attr "mode" "TI")])
23187
23188 (define_insn "mulv8hi3"
23189 [(set (match_operand:V8HI 0 "register_operand" "=x")
23190 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23191 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23192 "TARGET_SSE2"
23193 "pmullw\t{%2, %0|%0, %2}"
23194 [(set_attr "type" "sseimul")
23195 (set_attr "mode" "TI")])
23196
23197 (define_insn "smulv8hi3_highpart"
23198 [(set (match_operand:V8HI 0 "register_operand" "=x")
23199 (truncate:V8HI
23200 (lshiftrt:V8SI
23201 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23202 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23203 (const_int 16))))]
23204 "TARGET_SSE2"
23205 "pmulhw\t{%2, %0|%0, %2}"
23206 [(set_attr "type" "sseimul")
23207 (set_attr "mode" "TI")])
23208
23209 (define_insn "umulv8hi3_highpart"
23210 [(set (match_operand:V8HI 0 "register_operand" "=x")
23211 (truncate:V8HI
23212 (lshiftrt:V8SI
23213 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23214 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23215 (const_int 16))))]
23216 "TARGET_SSE2"
23217 "pmulhuw\t{%2, %0|%0, %2}"
23218 [(set_attr "type" "sseimul")
23219 (set_attr "mode" "TI")])
23220
23221 (define_insn "sse2_umulsidi3"
23222 [(set (match_operand:DI 0 "register_operand" "=y")
23223 (mult:DI (zero_extend:DI (vec_select:SI
23224 (match_operand:V2SI 1 "register_operand" "0")
23225 (parallel [(const_int 0)])))
23226 (zero_extend:DI (vec_select:SI
23227 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23228 (parallel [(const_int 0)])))))]
23229 "TARGET_SSE2"
23230 "pmuludq\t{%2, %0|%0, %2}"
23231 [(set_attr "type" "mmxmul")
23232 (set_attr "mode" "DI")])
23233
23234 (define_insn "sse2_umulv2siv2di3"
23235 [(set (match_operand:V2DI 0 "register_operand" "=x")
23236 (mult:V2DI (zero_extend:V2DI
23237 (vec_select:V2SI
23238 (match_operand:V4SI 1 "register_operand" "0")
23239 (parallel [(const_int 0) (const_int 2)])))
23240 (zero_extend:V2DI
23241 (vec_select:V2SI
23242 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23243 (parallel [(const_int 0) (const_int 2)])))))]
23244 "TARGET_SSE2"
23245 "pmuludq\t{%2, %0|%0, %2}"
23246 [(set_attr "type" "sseimul")
23247 (set_attr "mode" "TI")])
23248
23249 (define_insn "sse2_pmaddwd"
23250 [(set (match_operand:V4SI 0 "register_operand" "=x")
23251 (plus:V4SI
23252 (mult:V4SI
23253 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23254 (parallel [(const_int 0)
23255 (const_int 2)
23256 (const_int 4)
23257 (const_int 6)])))
23258 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23259 (parallel [(const_int 0)
23260 (const_int 2)
23261 (const_int 4)
23262 (const_int 6)]))))
23263 (mult:V4SI
23264 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23265 (parallel [(const_int 1)
23266 (const_int 3)
23267 (const_int 5)
23268 (const_int 7)])))
23269 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23270 (parallel [(const_int 1)
23271 (const_int 3)
23272 (const_int 5)
23273 (const_int 7)]))))))]
23274 "TARGET_SSE2"
23275 "pmaddwd\t{%2, %0|%0, %2}"
23276 [(set_attr "type" "sseiadd")
23277 (set_attr "mode" "TI")])
23278
23279 ;; Same as pxor, but don't show input operands so that we don't think
23280 ;; they are live.
23281 (define_insn "sse2_clrti"
23282 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23283 "TARGET_SSE2"
23284 {
23285 if (get_attr_mode (insn) == MODE_TI)
23286 return "pxor\t%0, %0";
23287 else
23288 return "xorps\t%0, %0";
23289 }
23290 [(set_attr "type" "ssemov")
23291 (set_attr "memory" "none")
23292 (set (attr "mode")
23293 (if_then_else
23294 (ne (symbol_ref "optimize_size")
23295 (const_int 0))
23296 (const_string "V4SF")
23297 (const_string "TI")))])
23298
23299 ;; MMX unsigned averages/sum of absolute differences
23300
23301 (define_insn "sse2_uavgv16qi3"
23302 [(set (match_operand:V16QI 0 "register_operand" "=x")
23303 (ashiftrt:V16QI
23304 (plus:V16QI (plus:V16QI
23305 (match_operand:V16QI 1 "register_operand" "0")
23306 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23307 (const_vector:V16QI [(const_int 1) (const_int 1)
23308 (const_int 1) (const_int 1)
23309 (const_int 1) (const_int 1)
23310 (const_int 1) (const_int 1)
23311 (const_int 1) (const_int 1)
23312 (const_int 1) (const_int 1)
23313 (const_int 1) (const_int 1)
23314 (const_int 1) (const_int 1)]))
23315 (const_int 1)))]
23316 "TARGET_SSE2"
23317 "pavgb\t{%2, %0|%0, %2}"
23318 [(set_attr "type" "sseiadd")
23319 (set_attr "mode" "TI")])
23320
23321 (define_insn "sse2_uavgv8hi3"
23322 [(set (match_operand:V8HI 0 "register_operand" "=x")
23323 (ashiftrt:V8HI
23324 (plus:V8HI (plus:V8HI
23325 (match_operand:V8HI 1 "register_operand" "0")
23326 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23327 (const_vector:V8HI [(const_int 1) (const_int 1)
23328 (const_int 1) (const_int 1)
23329 (const_int 1) (const_int 1)
23330 (const_int 1) (const_int 1)]))
23331 (const_int 1)))]
23332 "TARGET_SSE2"
23333 "pavgw\t{%2, %0|%0, %2}"
23334 [(set_attr "type" "sseiadd")
23335 (set_attr "mode" "TI")])
23336
23337 ;; @@@ this isn't the right representation.
23338 (define_insn "sse2_psadbw"
23339 [(set (match_operand:V2DI 0 "register_operand" "=x")
23340 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23341 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23342 UNSPEC_PSADBW))]
23343 "TARGET_SSE2"
23344 "psadbw\t{%2, %0|%0, %2}"
23345 [(set_attr "type" "sseiadd")
23346 (set_attr "mode" "TI")])
23347
23348
23349 ;; MMX insert/extract/shuffle
23350
23351 (define_insn "sse2_pinsrw"
23352 [(set (match_operand:V8HI 0 "register_operand" "=x")
23353 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23354 (vec_duplicate:V8HI
23355 (truncate:HI
23356 (match_operand:SI 2 "nonimmediate_operand" "rm")))
23357 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23358 "TARGET_SSE2"
23359 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23360 [(set_attr "type" "ssecvt")
23361 (set_attr "mode" "TI")])
23362
23363 (define_insn "sse2_pextrw"
23364 [(set (match_operand:SI 0 "register_operand" "=r")
23365 (zero_extend:SI
23366 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23367 (parallel
23368 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23369 "TARGET_SSE2"
23370 "pextrw\t{%2, %1, %0|%0, %1, %2}"
23371 [(set_attr "type" "ssecvt")
23372 (set_attr "mode" "TI")])
23373
23374 (define_insn "sse2_pshufd"
23375 [(set (match_operand:V4SI 0 "register_operand" "=x")
23376 (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23377 (match_operand:SI 2 "immediate_operand" "i")]
23378 UNSPEC_SHUFFLE))]
23379 "TARGET_SSE2"
23380 "pshufd\t{%2, %1, %0|%0, %1, %2}"
23381 [(set_attr "type" "ssecvt")
23382 (set_attr "mode" "TI")])
23383
23384 (define_insn "sse2_pshuflw"
23385 [(set (match_operand:V8HI 0 "register_operand" "=x")
23386 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23387 (match_operand:SI 2 "immediate_operand" "i")]
23388 UNSPEC_PSHUFLW))]
23389 "TARGET_SSE2"
23390 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23391 [(set_attr "type" "ssecvt")
23392 (set_attr "mode" "TI")])
23393
23394 (define_insn "sse2_pshufhw"
23395 [(set (match_operand:V8HI 0 "register_operand" "=x")
23396 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23397 (match_operand:SI 2 "immediate_operand" "i")]
23398 UNSPEC_PSHUFHW))]
23399 "TARGET_SSE2"
23400 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23401 [(set_attr "type" "ssecvt")
23402 (set_attr "mode" "TI")])
23403
23404 ;; MMX mask-generating comparisons
23405
23406 (define_insn "eqv16qi3"
23407 [(set (match_operand:V16QI 0 "register_operand" "=x")
23408 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23409 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23410 "TARGET_SSE2"
23411 "pcmpeqb\t{%2, %0|%0, %2}"
23412 [(set_attr "type" "ssecmp")
23413 (set_attr "mode" "TI")])
23414
23415 (define_insn "eqv8hi3"
23416 [(set (match_operand:V8HI 0 "register_operand" "=x")
23417 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23418 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23419 "TARGET_SSE2"
23420 "pcmpeqw\t{%2, %0|%0, %2}"
23421 [(set_attr "type" "ssecmp")
23422 (set_attr "mode" "TI")])
23423
23424 (define_insn "eqv4si3"
23425 [(set (match_operand:V4SI 0 "register_operand" "=x")
23426 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23427 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23428 "TARGET_SSE2"
23429 "pcmpeqd\t{%2, %0|%0, %2}"
23430 [(set_attr "type" "ssecmp")
23431 (set_attr "mode" "TI")])
23432
23433 (define_insn "gtv16qi3"
23434 [(set (match_operand:V16QI 0 "register_operand" "=x")
23435 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23436 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23437 "TARGET_SSE2"
23438 "pcmpgtb\t{%2, %0|%0, %2}"
23439 [(set_attr "type" "ssecmp")
23440 (set_attr "mode" "TI")])
23441
23442 (define_insn "gtv8hi3"
23443 [(set (match_operand:V8HI 0 "register_operand" "=x")
23444 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23445 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23446 "TARGET_SSE2"
23447 "pcmpgtw\t{%2, %0|%0, %2}"
23448 [(set_attr "type" "ssecmp")
23449 (set_attr "mode" "TI")])
23450
23451 (define_insn "gtv4si3"
23452 [(set (match_operand:V4SI 0 "register_operand" "=x")
23453 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23454 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23455 "TARGET_SSE2"
23456 "pcmpgtd\t{%2, %0|%0, %2}"
23457 [(set_attr "type" "ssecmp")
23458 (set_attr "mode" "TI")])
23459
23460
23461 ;; MMX max/min insns
23462
23463 (define_insn "umaxv16qi3"
23464 [(set (match_operand:V16QI 0 "register_operand" "=x")
23465 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23466 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23467 "TARGET_SSE2"
23468 "pmaxub\t{%2, %0|%0, %2}"
23469 [(set_attr "type" "sseiadd")
23470 (set_attr "mode" "TI")])
23471
23472 (define_insn "smaxv8hi3"
23473 [(set (match_operand:V8HI 0 "register_operand" "=x")
23474 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23475 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23476 "TARGET_SSE2"
23477 "pmaxsw\t{%2, %0|%0, %2}"
23478 [(set_attr "type" "sseiadd")
23479 (set_attr "mode" "TI")])
23480
23481 (define_insn "uminv16qi3"
23482 [(set (match_operand:V16QI 0 "register_operand" "=x")
23483 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23484 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23485 "TARGET_SSE2"
23486 "pminub\t{%2, %0|%0, %2}"
23487 [(set_attr "type" "sseiadd")
23488 (set_attr "mode" "TI")])
23489
23490 (define_insn "sminv8hi3"
23491 [(set (match_operand:V8HI 0 "register_operand" "=x")
23492 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23493 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23494 "TARGET_SSE2"
23495 "pminsw\t{%2, %0|%0, %2}"
23496 [(set_attr "type" "sseiadd")
23497 (set_attr "mode" "TI")])
23498
23499
23500 ;; MMX shifts
23501
23502 (define_insn "ashrv8hi3"
23503 [(set (match_operand:V8HI 0 "register_operand" "=x")
23504 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23505 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23506 "TARGET_SSE2"
23507 "psraw\t{%2, %0|%0, %2}"
23508 [(set_attr "type" "sseishft")
23509 (set_attr "mode" "TI")])
23510
23511 (define_insn "ashrv4si3"
23512 [(set (match_operand:V4SI 0 "register_operand" "=x")
23513 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23514 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23515 "TARGET_SSE2"
23516 "psrad\t{%2, %0|%0, %2}"
23517 [(set_attr "type" "sseishft")
23518 (set_attr "mode" "TI")])
23519
23520 (define_insn "lshrv8hi3"
23521 [(set (match_operand:V8HI 0 "register_operand" "=x")
23522 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23523 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23524 "TARGET_SSE2"
23525 "psrlw\t{%2, %0|%0, %2}"
23526 [(set_attr "type" "sseishft")
23527 (set_attr "mode" "TI")])
23528
23529 (define_insn "lshrv4si3"
23530 [(set (match_operand:V4SI 0 "register_operand" "=x")
23531 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23532 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23533 "TARGET_SSE2"
23534 "psrld\t{%2, %0|%0, %2}"
23535 [(set_attr "type" "sseishft")
23536 (set_attr "mode" "TI")])
23537
23538 (define_insn "lshrv2di3"
23539 [(set (match_operand:V2DI 0 "register_operand" "=x")
23540 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23541 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23542 "TARGET_SSE2"
23543 "psrlq\t{%2, %0|%0, %2}"
23544 [(set_attr "type" "sseishft")
23545 (set_attr "mode" "TI")])
23546
23547 (define_insn "ashlv8hi3"
23548 [(set (match_operand:V8HI 0 "register_operand" "=x")
23549 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23550 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23551 "TARGET_SSE2"
23552 "psllw\t{%2, %0|%0, %2}"
23553 [(set_attr "type" "sseishft")
23554 (set_attr "mode" "TI")])
23555
23556 (define_insn "ashlv4si3"
23557 [(set (match_operand:V4SI 0 "register_operand" "=x")
23558 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23559 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23560 "TARGET_SSE2"
23561 "pslld\t{%2, %0|%0, %2}"
23562 [(set_attr "type" "sseishft")
23563 (set_attr "mode" "TI")])
23564
23565 (define_insn "ashlv2di3"
23566 [(set (match_operand:V2DI 0 "register_operand" "=x")
23567 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23568 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23569 "TARGET_SSE2"
23570 "psllq\t{%2, %0|%0, %2}"
23571 [(set_attr "type" "sseishft")
23572 (set_attr "mode" "TI")])
23573
23574 (define_insn "ashrv8hi3_ti"
23575 [(set (match_operand:V8HI 0 "register_operand" "=x")
23576 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23577 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23578 "TARGET_SSE2"
23579 "psraw\t{%2, %0|%0, %2}"
23580 [(set_attr "type" "sseishft")
23581 (set_attr "mode" "TI")])
23582
23583 (define_insn "ashrv4si3_ti"
23584 [(set (match_operand:V4SI 0 "register_operand" "=x")
23585 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23586 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23587 "TARGET_SSE2"
23588 "psrad\t{%2, %0|%0, %2}"
23589 [(set_attr "type" "sseishft")
23590 (set_attr "mode" "TI")])
23591
23592 (define_insn "lshrv8hi3_ti"
23593 [(set (match_operand:V8HI 0 "register_operand" "=x")
23594 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23595 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23596 "TARGET_SSE2"
23597 "psrlw\t{%2, %0|%0, %2}"
23598 [(set_attr "type" "sseishft")
23599 (set_attr "mode" "TI")])
23600
23601 (define_insn "lshrv4si3_ti"
23602 [(set (match_operand:V4SI 0 "register_operand" "=x")
23603 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23604 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23605 "TARGET_SSE2"
23606 "psrld\t{%2, %0|%0, %2}"
23607 [(set_attr "type" "sseishft")
23608 (set_attr "mode" "TI")])
23609
23610 (define_insn "lshrv2di3_ti"
23611 [(set (match_operand:V2DI 0 "register_operand" "=x")
23612 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23613 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23614 "TARGET_SSE2"
23615 "psrlq\t{%2, %0|%0, %2}"
23616 [(set_attr "type" "sseishft")
23617 (set_attr "mode" "TI")])
23618
23619 (define_insn "ashlv8hi3_ti"
23620 [(set (match_operand:V8HI 0 "register_operand" "=x")
23621 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23622 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23623 "TARGET_SSE2"
23624 "psllw\t{%2, %0|%0, %2}"
23625 [(set_attr "type" "sseishft")
23626 (set_attr "mode" "TI")])
23627
23628 (define_insn "ashlv4si3_ti"
23629 [(set (match_operand:V4SI 0 "register_operand" "=x")
23630 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23631 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23632 "TARGET_SSE2"
23633 "pslld\t{%2, %0|%0, %2}"
23634 [(set_attr "type" "sseishft")
23635 (set_attr "mode" "TI")])
23636
23637 (define_insn "ashlv2di3_ti"
23638 [(set (match_operand:V2DI 0 "register_operand" "=x")
23639 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23640 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23641 "TARGET_SSE2"
23642 "psllq\t{%2, %0|%0, %2}"
23643 [(set_attr "type" "sseishft")
23644 (set_attr "mode" "TI")])
23645
23646 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23647 ;; we wouldn't need here it since we never generate TImode arithmetic.
23648
23649 ;; There has to be some kind of prize for the weirdest new instruction...
23650 (define_insn "sse2_ashlti3"
23651 [(set (match_operand:TI 0 "register_operand" "=x")
23652 (unspec:TI
23653 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23654 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23655 (const_int 8)))] UNSPEC_NOP))]
23656 "TARGET_SSE2"
23657 "pslldq\t{%2, %0|%0, %2}"
23658 [(set_attr "type" "sseishft")
23659 (set_attr "mode" "TI")])
23660
23661 (define_insn "sse2_lshrti3"
23662 [(set (match_operand:TI 0 "register_operand" "=x")
23663 (unspec:TI
23664 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23665 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23666 (const_int 8)))] UNSPEC_NOP))]
23667 "TARGET_SSE2"
23668 "psrldq\t{%2, %0|%0, %2}"
23669 [(set_attr "type" "sseishft")
23670 (set_attr "mode" "TI")])
23671
23672 ;; SSE unpack
23673
23674 (define_insn "sse2_unpckhpd"
23675 [(set (match_operand:V2DF 0 "register_operand" "=x")
23676 (vec_concat:V2DF
23677 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23678 (parallel [(const_int 1)]))
23679 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23680 (parallel [(const_int 1)]))))]
23681 "TARGET_SSE2"
23682 "unpckhpd\t{%2, %0|%0, %2}"
23683 [(set_attr "type" "ssecvt")
23684 (set_attr "mode" "V2DF")])
23685
23686 (define_insn "sse2_unpcklpd"
23687 [(set (match_operand:V2DF 0 "register_operand" "=x")
23688 (vec_concat:V2DF
23689 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23690 (parallel [(const_int 0)]))
23691 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23692 (parallel [(const_int 0)]))))]
23693 "TARGET_SSE2"
23694 "unpcklpd\t{%2, %0|%0, %2}"
23695 [(set_attr "type" "ssecvt")
23696 (set_attr "mode" "V2DF")])
23697
23698 ;; MMX pack/unpack insns.
23699
23700 (define_insn "sse2_packsswb"
23701 [(set (match_operand:V16QI 0 "register_operand" "=x")
23702 (vec_concat:V16QI
23703 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23704 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23705 "TARGET_SSE2"
23706 "packsswb\t{%2, %0|%0, %2}"
23707 [(set_attr "type" "ssecvt")
23708 (set_attr "mode" "TI")])
23709
23710 (define_insn "sse2_packssdw"
23711 [(set (match_operand:V8HI 0 "register_operand" "=x")
23712 (vec_concat:V8HI
23713 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23714 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23715 "TARGET_SSE2"
23716 "packssdw\t{%2, %0|%0, %2}"
23717 [(set_attr "type" "ssecvt")
23718 (set_attr "mode" "TI")])
23719
23720 (define_insn "sse2_packuswb"
23721 [(set (match_operand:V16QI 0 "register_operand" "=x")
23722 (vec_concat:V16QI
23723 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23724 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23725 "TARGET_SSE2"
23726 "packuswb\t{%2, %0|%0, %2}"
23727 [(set_attr "type" "ssecvt")
23728 (set_attr "mode" "TI")])
23729
23730 (define_insn "sse2_punpckhbw"
23731 [(set (match_operand:V16QI 0 "register_operand" "=x")
23732 (vec_merge:V16QI
23733 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23734 (parallel [(const_int 8) (const_int 0)
23735 (const_int 9) (const_int 1)
23736 (const_int 10) (const_int 2)
23737 (const_int 11) (const_int 3)
23738 (const_int 12) (const_int 4)
23739 (const_int 13) (const_int 5)
23740 (const_int 14) (const_int 6)
23741 (const_int 15) (const_int 7)]))
23742 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23743 (parallel [(const_int 0) (const_int 8)
23744 (const_int 1) (const_int 9)
23745 (const_int 2) (const_int 10)
23746 (const_int 3) (const_int 11)
23747 (const_int 4) (const_int 12)
23748 (const_int 5) (const_int 13)
23749 (const_int 6) (const_int 14)
23750 (const_int 7) (const_int 15)]))
23751 (const_int 21845)))]
23752 "TARGET_SSE2"
23753 "punpckhbw\t{%2, %0|%0, %2}"
23754 [(set_attr "type" "ssecvt")
23755 (set_attr "mode" "TI")])
23756
23757 (define_insn "sse2_punpckhwd"
23758 [(set (match_operand:V8HI 0 "register_operand" "=x")
23759 (vec_merge:V8HI
23760 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23761 (parallel [(const_int 4) (const_int 0)
23762 (const_int 5) (const_int 1)
23763 (const_int 6) (const_int 2)
23764 (const_int 7) (const_int 3)]))
23765 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23766 (parallel [(const_int 0) (const_int 4)
23767 (const_int 1) (const_int 5)
23768 (const_int 2) (const_int 6)
23769 (const_int 3) (const_int 7)]))
23770 (const_int 85)))]
23771 "TARGET_SSE2"
23772 "punpckhwd\t{%2, %0|%0, %2}"
23773 [(set_attr "type" "ssecvt")
23774 (set_attr "mode" "TI")])
23775
23776 (define_insn "sse2_punpckhdq"
23777 [(set (match_operand:V4SI 0 "register_operand" "=x")
23778 (vec_merge:V4SI
23779 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23780 (parallel [(const_int 2) (const_int 0)
23781 (const_int 3) (const_int 1)]))
23782 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23783 (parallel [(const_int 0) (const_int 2)
23784 (const_int 1) (const_int 3)]))
23785 (const_int 5)))]
23786 "TARGET_SSE2"
23787 "punpckhdq\t{%2, %0|%0, %2}"
23788 [(set_attr "type" "ssecvt")
23789 (set_attr "mode" "TI")])
23790
23791 (define_insn "sse2_punpcklbw"
23792 [(set (match_operand:V16QI 0 "register_operand" "=x")
23793 (vec_merge:V16QI
23794 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23795 (parallel [(const_int 0) (const_int 8)
23796 (const_int 1) (const_int 9)
23797 (const_int 2) (const_int 10)
23798 (const_int 3) (const_int 11)
23799 (const_int 4) (const_int 12)
23800 (const_int 5) (const_int 13)
23801 (const_int 6) (const_int 14)
23802 (const_int 7) (const_int 15)]))
23803 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23804 (parallel [(const_int 8) (const_int 0)
23805 (const_int 9) (const_int 1)
23806 (const_int 10) (const_int 2)
23807 (const_int 11) (const_int 3)
23808 (const_int 12) (const_int 4)
23809 (const_int 13) (const_int 5)
23810 (const_int 14) (const_int 6)
23811 (const_int 15) (const_int 7)]))
23812 (const_int 21845)))]
23813 "TARGET_SSE2"
23814 "punpcklbw\t{%2, %0|%0, %2}"
23815 [(set_attr "type" "ssecvt")
23816 (set_attr "mode" "TI")])
23817
23818 (define_insn "sse2_punpcklwd"
23819 [(set (match_operand:V8HI 0 "register_operand" "=x")
23820 (vec_merge:V8HI
23821 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23822 (parallel [(const_int 0) (const_int 4)
23823 (const_int 1) (const_int 5)
23824 (const_int 2) (const_int 6)
23825 (const_int 3) (const_int 7)]))
23826 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23827 (parallel [(const_int 4) (const_int 0)
23828 (const_int 5) (const_int 1)
23829 (const_int 6) (const_int 2)
23830 (const_int 7) (const_int 3)]))
23831 (const_int 85)))]
23832 "TARGET_SSE2"
23833 "punpcklwd\t{%2, %0|%0, %2}"
23834 [(set_attr "type" "ssecvt")
23835 (set_attr "mode" "TI")])
23836
23837 (define_insn "sse2_punpckldq"
23838 [(set (match_operand:V4SI 0 "register_operand" "=x")
23839 (vec_merge:V4SI
23840 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23841 (parallel [(const_int 0) (const_int 2)
23842 (const_int 1) (const_int 3)]))
23843 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23844 (parallel [(const_int 2) (const_int 0)
23845 (const_int 3) (const_int 1)]))
23846 (const_int 5)))]
23847 "TARGET_SSE2"
23848 "punpckldq\t{%2, %0|%0, %2}"
23849 [(set_attr "type" "ssecvt")
23850 (set_attr "mode" "TI")])
23851
23852 (define_insn "sse2_punpcklqdq"
23853 [(set (match_operand:V2DI 0 "register_operand" "=x")
23854 (vec_merge:V2DI
23855 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23856 (parallel [(const_int 1)
23857 (const_int 0)]))
23858 (match_operand:V2DI 1 "register_operand" "0")
23859 (const_int 1)))]
23860 "TARGET_SSE2"
23861 "punpcklqdq\t{%2, %0|%0, %2}"
23862 [(set_attr "type" "ssecvt")
23863 (set_attr "mode" "TI")])
23864
23865 (define_insn "sse2_punpckhqdq"
23866 [(set (match_operand:V2DI 0 "register_operand" "=x")
23867 (vec_merge:V2DI
23868 (match_operand:V2DI 1 "register_operand" "0")
23869 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23870 (parallel [(const_int 1)
23871 (const_int 0)]))
23872 (const_int 1)))]
23873 "TARGET_SSE2"
23874 "punpckhqdq\t{%2, %0|%0, %2}"
23875 [(set_attr "type" "ssecvt")
23876 (set_attr "mode" "TI")])
23877
23878 ;; SSE2 moves
23879
23880 (define_insn "sse2_movapd"
23881 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23882 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23883 UNSPEC_MOVA))]
23884 "TARGET_SSE2
23885 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23886 "movapd\t{%1, %0|%0, %1}"
23887 [(set_attr "type" "ssemov")
23888 (set_attr "mode" "V2DF")])
23889
23890 (define_insn "sse2_movupd"
23891 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23892 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23893 UNSPEC_MOVU))]
23894 "TARGET_SSE2
23895 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23896 "movupd\t{%1, %0|%0, %1}"
23897 [(set_attr "type" "ssecvt")
23898 (set_attr "mode" "V2DF")])
23899
23900 (define_insn "sse2_movdqa"
23901 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23902 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23903 UNSPEC_MOVA))]
23904 "TARGET_SSE2
23905 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23906 "movdqa\t{%1, %0|%0, %1}"
23907 [(set_attr "type" "ssemov")
23908 (set_attr "mode" "TI")])
23909
23910 (define_insn "sse2_movdqu"
23911 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23912 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23913 UNSPEC_MOVU))]
23914 "TARGET_SSE2
23915 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23916 "movdqu\t{%1, %0|%0, %1}"
23917 [(set_attr "type" "ssecvt")
23918 (set_attr "mode" "TI")])
23919
23920 (define_insn "sse2_movdq2q"
23921 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23922 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23923 (parallel [(const_int 0)])))]
23924 "TARGET_SSE2 && !TARGET_64BIT"
23925 "@
23926 movq\t{%1, %0|%0, %1}
23927 movdq2q\t{%1, %0|%0, %1}"
23928 [(set_attr "type" "ssecvt")
23929 (set_attr "mode" "TI")])
23930
23931 (define_insn "sse2_movdq2q_rex64"
23932 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23933 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23934 (parallel [(const_int 0)])))]
23935 "TARGET_SSE2 && TARGET_64BIT"
23936 "@
23937 movq\t{%1, %0|%0, %1}
23938 movdq2q\t{%1, %0|%0, %1}
23939 movd\t{%1, %0|%0, %1}"
23940 [(set_attr "type" "ssecvt")
23941 (set_attr "mode" "TI")])
23942
23943 (define_insn "sse2_movq2dq"
23944 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23945 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23946 (const_int 0)))]
23947 "TARGET_SSE2 && !TARGET_64BIT"
23948 "@
23949 movq\t{%1, %0|%0, %1}
23950 movq2dq\t{%1, %0|%0, %1}"
23951 [(set_attr "type" "ssecvt,ssemov")
23952 (set_attr "mode" "TI")])
23953
23954 (define_insn "sse2_movq2dq_rex64"
23955 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23956 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23957 (const_int 0)))]
23958 "TARGET_SSE2 && TARGET_64BIT"
23959 "@
23960 movq\t{%1, %0|%0, %1}
23961 movq2dq\t{%1, %0|%0, %1}
23962 movd\t{%1, %0|%0, %1}"
23963 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23964 (set_attr "mode" "TI")])
23965
23966 (define_insn "sse2_movq"
23967 [(set (match_operand:V2DI 0 "register_operand" "=x")
23968 (vec_concat:V2DI (vec_select:DI
23969 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23970 (parallel [(const_int 0)]))
23971 (const_int 0)))]
23972 "TARGET_SSE2"
23973 "movq\t{%1, %0|%0, %1}"
23974 [(set_attr "type" "ssemov")
23975 (set_attr "mode" "TI")])
23976
23977 (define_insn "sse2_loadd"
23978 [(set (match_operand:V4SI 0 "register_operand" "=x")
23979 (vec_merge:V4SI
23980 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23981 (const_vector:V4SI [(const_int 0)
23982 (const_int 0)
23983 (const_int 0)
23984 (const_int 0)])
23985 (const_int 1)))]
23986 "TARGET_SSE2"
23987 "movd\t{%1, %0|%0, %1}"
23988 [(set_attr "type" "ssemov")
23989 (set_attr "mode" "TI")])
23990
23991 (define_insn "sse2_stored"
23992 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23993 (vec_select:SI
23994 (match_operand:V4SI 1 "register_operand" "x")
23995 (parallel [(const_int 0)])))]
23996 "TARGET_SSE2"
23997 "movd\t{%1, %0|%0, %1}"
23998 [(set_attr "type" "ssemov")
23999 (set_attr "mode" "TI")])
24000
24001 (define_insn "sse2_movhpd"
24002 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24003 (vec_merge:V2DF
24004 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24005 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24006 (const_int 1)))]
24007 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24008 "movhpd\t{%2, %0|%0, %2}"
24009 [(set_attr "type" "ssecvt")
24010 (set_attr "mode" "V2DF")])
24011
24012 (define_expand "sse2_loadsd"
24013 [(match_operand:V2DF 0 "register_operand" "")
24014 (match_operand:DF 1 "memory_operand" "")]
24015 "TARGET_SSE2"
24016 {
24017 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24018 CONST0_RTX (V2DFmode)));
24019 DONE;
24020 })
24021
24022 (define_insn "sse2_loadsd_1"
24023 [(set (match_operand:V2DF 0 "register_operand" "=x")
24024 (vec_merge:V2DF
24025 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24026 (match_operand:V2DF 2 "const0_operand" "X")
24027 (const_int 1)))]
24028 "TARGET_SSE2"
24029 "movsd\t{%1, %0|%0, %1}"
24030 [(set_attr "type" "ssecvt")
24031 (set_attr "mode" "DF")])
24032
24033 (define_insn "sse2_movsd"
24034 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24035 (vec_merge:V2DF
24036 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24037 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24038 (const_int 2)))]
24039 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24040 "@movsd\t{%2, %0|%0, %2}
24041 movlpd\t{%2, %0|%0, %2}
24042 movlpd\t{%2, %0|%0, %2}"
24043 [(set_attr "type" "ssecvt")
24044 (set_attr "mode" "DF,V2DF,V2DF")])
24045
24046 (define_insn "sse2_storesd"
24047 [(set (match_operand:DF 0 "memory_operand" "=m")
24048 (vec_select:DF
24049 (match_operand:V2DF 1 "register_operand" "x")
24050 (parallel [(const_int 0)])))]
24051 "TARGET_SSE2"
24052 "movsd\t{%1, %0|%0, %1}"
24053 [(set_attr "type" "ssecvt")
24054 (set_attr "mode" "DF")])
24055
24056 (define_insn "sse2_shufpd"
24057 [(set (match_operand:V2DF 0 "register_operand" "=x")
24058 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24059 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24060 (match_operand:SI 3 "immediate_operand" "i")]
24061 UNSPEC_SHUFFLE))]
24062 "TARGET_SSE2"
24063 ;; @@@ check operand order for intel/nonintel syntax
24064 "shufpd\t{%3, %2, %0|%0, %2, %3}"
24065 [(set_attr "type" "ssecvt")
24066 (set_attr "mode" "V2DF")])
24067
24068 (define_insn "sse2_clflush"
24069 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24070 UNSPECV_CLFLUSH)]
24071 "TARGET_SSE2"
24072 "clflush\t%a0"
24073 [(set_attr "type" "sse")
24074 (set_attr "memory" "unknown")])
24075
24076 (define_expand "sse2_mfence"
24077 [(set (match_dup 0)
24078 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24079 "TARGET_SSE2"
24080 {
24081 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24082 MEM_VOLATILE_P (operands[0]) = 1;
24083 })
24084
24085 (define_insn "*mfence_insn"
24086 [(set (match_operand:BLK 0 "" "")
24087 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24088 "TARGET_SSE2"
24089 "mfence"
24090 [(set_attr "type" "sse")
24091 (set_attr "memory" "unknown")])
24092
24093 (define_expand "sse2_lfence"
24094 [(set (match_dup 0)
24095 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24096 "TARGET_SSE2"
24097 {
24098 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24099 MEM_VOLATILE_P (operands[0]) = 1;
24100 })
24101
24102 (define_insn "*lfence_insn"
24103 [(set (match_operand:BLK 0 "" "")
24104 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24105 "TARGET_SSE2"
24106 "lfence"
24107 [(set_attr "type" "sse")
24108 (set_attr "memory" "unknown")])
24109
24110 ;; SSE3
24111
24112 (define_insn "mwait"
24113 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24114 (match_operand:SI 1 "register_operand" "c")]
24115 UNSPECV_MWAIT)]
24116 "TARGET_SSE3"
24117 "mwait\t%0, %1"
24118 [(set_attr "length" "3")])
24119
24120 (define_insn "monitor"
24121 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24122 (match_operand:SI 1 "register_operand" "c")
24123 (match_operand:SI 2 "register_operand" "d")]
24124 UNSPECV_MONITOR)]
24125 "TARGET_SSE3"
24126 "monitor\t%0, %1, %2"
24127 [(set_attr "length" "3")])
24128
24129 ;; SSE3 arithmetic
24130
24131 (define_insn "addsubv4sf3"
24132 [(set (match_operand:V4SF 0 "register_operand" "=x")
24133 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24134 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24135 UNSPEC_ADDSUB))]
24136 "TARGET_SSE3"
24137 "addsubps\t{%2, %0|%0, %2}"
24138 [(set_attr "type" "sseadd")
24139 (set_attr "mode" "V4SF")])
24140
24141 (define_insn "addsubv2df3"
24142 [(set (match_operand:V2DF 0 "register_operand" "=x")
24143 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24144 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24145 UNSPEC_ADDSUB))]
24146 "TARGET_SSE3"
24147 "addsubpd\t{%2, %0|%0, %2}"
24148 [(set_attr "type" "sseadd")
24149 (set_attr "mode" "V2DF")])
24150
24151 (define_insn "haddv4sf3"
24152 [(set (match_operand:V4SF 0 "register_operand" "=x")
24153 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24154 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24155 UNSPEC_HADD))]
24156 "TARGET_SSE3"
24157 "haddps\t{%2, %0|%0, %2}"
24158 [(set_attr "type" "sseadd")
24159 (set_attr "mode" "V4SF")])
24160
24161 (define_insn "haddv2df3"
24162 [(set (match_operand:V2DF 0 "register_operand" "=x")
24163 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24164 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24165 UNSPEC_HADD))]
24166 "TARGET_SSE3"
24167 "haddpd\t{%2, %0|%0, %2}"
24168 [(set_attr "type" "sseadd")
24169 (set_attr "mode" "V2DF")])
24170
24171 (define_insn "hsubv4sf3"
24172 [(set (match_operand:V4SF 0 "register_operand" "=x")
24173 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24174 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24175 UNSPEC_HSUB))]
24176 "TARGET_SSE3"
24177 "hsubps\t{%2, %0|%0, %2}"
24178 [(set_attr "type" "sseadd")
24179 (set_attr "mode" "V4SF")])
24180
24181 (define_insn "hsubv2df3"
24182 [(set (match_operand:V2DF 0 "register_operand" "=x")
24183 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24184 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24185 UNSPEC_HSUB))]
24186 "TARGET_SSE3"
24187 "hsubpd\t{%2, %0|%0, %2}"
24188 [(set_attr "type" "sseadd")
24189 (set_attr "mode" "V2DF")])
24190
24191 (define_insn "movshdup"
24192 [(set (match_operand:V4SF 0 "register_operand" "=x")
24193 (unspec:V4SF
24194 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24195 "TARGET_SSE3"
24196 "movshdup\t{%1, %0|%0, %1}"
24197 [(set_attr "type" "sse")
24198 (set_attr "mode" "V4SF")])
24199
24200 (define_insn "movsldup"
24201 [(set (match_operand:V4SF 0 "register_operand" "=x")
24202 (unspec:V4SF
24203 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24204 "TARGET_SSE3"
24205 "movsldup\t{%1, %0|%0, %1}"
24206 [(set_attr "type" "sse")
24207 (set_attr "mode" "V4SF")])
24208
24209 (define_insn "lddqu"
24210 [(set (match_operand:V16QI 0 "register_operand" "=x")
24211 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24212 UNSPEC_LDQQU))]
24213 "TARGET_SSE3"
24214 "lddqu\t{%1, %0|%0, %1}"
24215 [(set_attr "type" "ssecvt")
24216 (set_attr "mode" "TI")])
24217
24218 (define_insn "loadddup"
24219 [(set (match_operand:V2DF 0 "register_operand" "=x")
24220 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24221 "TARGET_SSE3"
24222 "movddup\t{%1, %0|%0, %1}"
24223 [(set_attr "type" "ssecvt")
24224 (set_attr "mode" "DF")])
24225
24226 (define_insn "movddup"
24227 [(set (match_operand:V2DF 0 "register_operand" "=x")
24228 (vec_duplicate:V2DF
24229 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24230 (parallel [(const_int 0)]))))]
24231 "TARGET_SSE3"
24232 "movddup\t{%1, %0|%0, %1}"
24233 [(set_attr "type" "ssecvt")
24234 (set_attr "mode" "DF")])
This page took 1.000705 seconds and 4 git commands to generate.