Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / gcc / config / i386 / i386.md
1 ; GCC machine description for Intel X86.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000 Free Software
3 ;; Foundation, Inc.
4 ;; Mostly by William Schelter.
5
6 ;; This file is part of GNU CC.
7
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA. */
22
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
25
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27
28 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
29 ;; updates for most instructions.
30
31 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
32 ;; constraint letters.
33
34 ;; the special asm out single letter directives following a '%' are:
35 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;;     operands[1].
37 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
38 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
39 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
40 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
41 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
42 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
43 ;; 'J' Print the appropriate jump operand.
44
45 ;; 'b' Print the QImode name of the register for the indicated operand.
46 ;;     %b0 would print %al if operands[0] is reg 0.
47 ;; 'w' Likewise, print the HImode name of the register.
48 ;; 'k' Likewise, print the SImode name of the register.
49 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
50 ;; 'y' Print "st(0)" instead of "st" as a register.
51
52 ;; UNSPEC usage:
53 ;; 0  This is a `scas' operation.  The mode of the UNSPEC is always SImode.
54 ;;    operand 0 is the memory address to scan.
55 ;;    operand 1 is a register containing the value to scan for.  The mode
56 ;;       of the scas opcode will be the same as the mode of this operand.
57 ;;    operand 2 is the known alignment of operand 0.
58 ;; 1  This is a `sin' operation.  The mode of the UNSPEC is MODE_FLOAT.
59 ;;    operand 0 is the argument for `sin'.
60 ;; 2  This is a `cos' operation.  The mode of the UNSPEC is MODE_FLOAT.
61 ;;    operand 0 is the argument for `cos'.
62 ;; 3  This is part of a `stack probe' operation.  The mode of the UNSPEC is 
63 ;;    always SImode.  operand 0 is the size of the stack allocation.
64 ;; 4  This is the source of a fake SET of the frame pointer which is used to
65 ;;    prevent insns referencing it being scheduled across the initial
66 ;;    decrement of the stack pointer.
67 ;; 5  This is a `bsf' operation.
68 ;; 6  This is the @GOT offset of a PIC address.
69 ;; 7  This is the @GOTOFF offset of a PIC address.
70 ;; 8  This is a reference to a symbol's @PLT address.
71 \f
72 ;; This shadows the processor_type enumeration, so changes must be made
73 ;; to i386.h at the same time.
74
75 ;; $FreeBSD: src/contrib/gcc/config/i386/i386.md,v 1.7.2.2 2001/04/10 19:23:24 obrien Exp $
76
77 (define_attr "type"
78   "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul"
79   (const_string "integer"))
80
81 (define_attr "memory" "none,load,store"
82   (cond [(eq_attr "type" "idiv,lea")
83          (const_string "none")
84
85          (eq_attr "type" "fld")
86          (const_string "load")
87
88          (eq_attr "type" "test")
89          (if_then_else (match_operand 0 "memory_operand" "")
90                        (const_string "load")
91                        (const_string "none"))
92
93          (eq_attr "type" "compare,fcompare")
94          (if_then_else (ior (match_operand 0 "memory_operand" "")
95                             (match_operand 1 "memory_operand" ""))
96                        (const_string "load")
97                        (const_string "none"))
98
99          (and (eq_attr "type" "integer,memory,fpop")
100               (match_operand 0 "memory_operand" ""))
101          (const_string "store")
102
103          (and (eq_attr "type" "integer,memory,fpop")
104               (match_operand 1 "memory_operand" ""))
105          (const_string "load")
106
107          (and (eq_attr "type" "binary,imul,fpmul,fpdiv")
108               (ior (match_operand 1 "memory_operand" "")
109                    (match_operand 2 "memory_operand" "")))
110          (const_string "load")]
111
112         (const_string "none")))
113
114 ;; Functional units
115
116 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
117 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
118
119 ; pentiumpro has a reservation station with 5 ports
120 ; port  0 has integer, float add, integer divide, float divide, float 
121 ;        multiply, and shifter units.
122 ; port  1 has integer, and jump units.
123 ; port  2 has the load address generation unit
124 ; ports 3 and 4 have the store address generation units
125
126 ; pentium has two integer pipelines, the main u pipe and the secondary v pipe.
127 ; and a float pipeline
128
129 ;; Floating point
130
131 (define_function_unit "fp" 1 0
132  (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486"))
133  5 5)
134
135 (define_function_unit "fp" 1 0
136  (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro")) 
137  3 0)
138
139 (define_function_unit "fp" 1 0
140  (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium")) 
141  7 0)
142
143 (define_function_unit "fp" 1 0
144  (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro")) 
145  5 0)
146
147 (define_function_unit "fp" 1 0
148  (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro")) 
149  10 10)
150
151 (define_function_unit "fp" 1 0
152  (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro")) 
153  6 0)
154
155 (define_function_unit "fp" 1 0
156  (eq_attr "type" "fpdiv") 
157  10 10)
158
159 (define_function_unit "fp" 1 0
160   (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6"))
161  1 0)
162
163 ;; K6 FPU is not pipelined.
164 (define_function_unit "fp" 1 0
165   (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6"))
166  2 2)
167
168 ;; i386 and i486 have one integer unit, which need not be modeled
169
170 (define_function_unit "integer" 2 0
171   (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro"))
172  1 0)
173
174 (define_function_unit "integer" 2 0
175   (and (eq_attr "cpu" "k6")
176        (and (eq_attr "type" "integer,binary,test,compare")
177             (eq_attr "memory" "!load")))
178   1 0)
179
180 ;; Internally, K6 converts REG OP MEM instructions into a load (2 cycles)
181 ;; and a register operation (1 cycle).
182 (define_function_unit "integer" 2 0
183   (and (eq_attr "cpu" "k6")
184        (and (eq_attr "type" "integer,binary,test,compare")
185             (eq_attr "memory" "load")))
186   3 0)
187
188 ;; Multiplies use one of the integer units
189 (define_function_unit "integer" 2 0
190   (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul"))
191   11 11)
192
193 (define_function_unit "integer" 2 0
194   (and (eq_attr "cpu" "k6") (eq_attr "type" "imul"))
195   2 2)
196
197 (define_function_unit "integer" 2 0
198   (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv"))
199   25 25)
200
201 (define_function_unit "integer" 2 0
202   (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv"))
203   17 17)
204
205 ;; Pentium Pro and K6 have a separate load unit.
206 (define_function_unit "load" 1 0
207   (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load"))
208   3 0)
209
210 (define_function_unit "load" 1 0
211   (and (eq_attr "cpu" "k6") (eq_attr "memory" "load"))
212   2 0)
213
214 ;; Pentium Pro and K6 have a separate store unit.
215 (define_function_unit "store" 1 0
216   (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store"))
217   1 0)
218
219 ;; lea executes in the K6 store unit with 1 cycle latency
220 (define_function_unit "store" 1 0
221   (and (eq_attr "cpu" "k6") (eq_attr "type" "lea"))
222   1 0)
223
224 \f
225 ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
226 ;; But restricting MEM here would mean that gcc could not remove a redundant
227 ;; test in cases like "incl MEM / je TARGET".
228 ;;
229 ;; We don't want to allow a constant operand for test insns because
230 ;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
231 ;; be folded while optimizing anyway.
232
233 ;; All test insns have expanders that save the operands away without
234 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
235 ;; after the tstM or cmp) will actually emit the tstM or cmpM.
236
237 ;; Processor type -- this attribute must exactly match the processor_type
238 ;; enumeration in i386.h.
239
240 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6"
241   (const (symbol_ref "ix86_cpu")))
242
243 (define_insn "tstsi_1"
244   [(set (cc0)
245         (match_operand:SI 0 "nonimmediate_operand" "rm"))]
246   ""
247   "*
248 {
249   if (REG_P (operands[0]))
250     return AS2 (test%L0,%0,%0);
251
252   operands[1] = const0_rtx;
253   return AS2 (cmp%L0,%1,%0);
254 }"
255   [(set_attr "type" "test")])
256
257 (define_expand "tstsi"
258   [(set (cc0)
259         (match_operand:SI 0 "nonimmediate_operand" ""))]
260   ""
261   "
262 {
263   i386_compare_gen = gen_tstsi_1;
264   i386_compare_op0 = operands[0];
265   i386_compare_op1 = const0_rtx;
266   DONE;
267 }")
268
269 (define_insn "tsthi_1"
270   [(set (cc0)
271         (match_operand:HI 0 "nonimmediate_operand" "rm"))]
272   ""
273   "*
274 {
275   if (REG_P (operands[0]))
276     return AS2 (test%W0,%0,%0);
277
278   operands[1] = const0_rtx;
279   return AS2 (cmp%W0,%1,%0);
280 }"
281   [(set_attr "type" "test")])
282
283 (define_expand "tsthi"
284   [(set (cc0)
285         (match_operand:HI 0 "nonimmediate_operand" ""))]
286   ""
287   "
288 {
289   i386_compare_gen = gen_tsthi_1;
290   i386_compare_op0 = operands[0];
291   i386_compare_op1 = const0_rtx;
292   DONE;
293 }")
294
295 (define_insn "tstqi_1"
296   [(set (cc0)
297         (match_operand:QI 0 "nonimmediate_operand" "qm"))]
298   ""
299   "*
300 {
301   if (REG_P (operands[0]))
302     return AS2 (test%B0,%0,%0);
303
304   operands[1] = const0_rtx;
305   return AS2 (cmp%B0,%1,%0);
306 }"
307   [(set_attr "type" "test")])
308
309 (define_expand "tstqi"
310   [(set (cc0)
311         (match_operand:QI 0 "nonimmediate_operand" ""))]
312   ""
313   "
314 {
315   i386_compare_gen = gen_tstqi_1;
316   i386_compare_op0 = operands[0];
317   i386_compare_op1 = const0_rtx;
318   DONE;
319 }")
320
321 (define_insn "tstsf_cc"
322   [(set (cc0)
323         (match_operand:SF 0 "register_operand" "f"))
324    (clobber (match_scratch:HI 1 "=a"))]
325   "TARGET_80387 && ! TARGET_IEEE_FP"
326   "*
327 {
328   if (! STACK_TOP_P (operands[0]))
329     abort ();
330
331   output_asm_insn (\"ftst\", operands);
332
333   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
334     output_asm_insn (AS1 (fstp,%y0), operands);
335
336   return output_fp_cc0_set (insn);
337 }"
338   [(set_attr "type" "test")])
339
340 ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
341 ;; isn't IEEE compliant.
342
343 (define_expand "tstsf"
344   [(parallel [(set (cc0)
345                    (match_operand:SF 0 "register_operand" ""))
346               (clobber (match_scratch:HI 1 ""))])]
347   "TARGET_80387 && ! TARGET_IEEE_FP"
348   "
349 {
350   i386_compare_gen = gen_tstsf_cc;
351   i386_compare_op0 = operands[0];
352   i386_compare_op1 = const0_rtx;
353   DONE;
354 }")
355
356 (define_insn "tstdf_cc"
357   [(set (cc0)
358         (match_operand:DF 0 "register_operand" "f"))
359    (clobber (match_scratch:HI 1 "=a"))]
360   "TARGET_80387 && ! TARGET_IEEE_FP"
361   "*
362 {
363   if (! STACK_TOP_P (operands[0]))
364     abort ();
365
366   output_asm_insn (\"ftst\", operands);
367
368   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
369     output_asm_insn (AS1 (fstp,%y0), operands);
370
371   return output_fp_cc0_set (insn);
372 }"
373   [(set_attr "type" "test")])
374
375 ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
376 ;; isn't IEEE compliant.
377
378 (define_expand "tstdf"
379   [(parallel [(set (cc0)
380                    (match_operand:DF 0 "register_operand" ""))
381               (clobber (match_scratch:HI 1 ""))])]
382   "TARGET_80387 && ! TARGET_IEEE_FP"
383   "
384 {
385   i386_compare_gen = gen_tstdf_cc;
386   i386_compare_op0 = operands[0];
387   i386_compare_op1 = const0_rtx;
388   DONE;
389 }")
390
391 (define_insn "tstxf_cc"
392   [(set (cc0)
393         (match_operand:XF 0 "register_operand" "f"))
394    (clobber (match_scratch:HI 1 "=a"))]
395   "TARGET_80387 && ! TARGET_IEEE_FP"
396   "*
397 {
398   if (! STACK_TOP_P (operands[0]))
399     abort ();
400
401   output_asm_insn (\"ftst\", operands);
402
403   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
404     output_asm_insn (AS1 (fstp,%y0), operands);
405
406   return output_fp_cc0_set (insn);
407 }"
408   [(set_attr "type" "test")])
409
410 ;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode
411 ;; isn't IEEE compliant.
412
413 (define_expand "tstxf"
414   [(parallel [(set (cc0)
415                    (match_operand:XF 0 "register_operand" ""))
416               (clobber (match_scratch:HI 1 ""))])]
417   "TARGET_80387 && ! TARGET_IEEE_FP"
418   "
419 {
420   i386_compare_gen = gen_tstxf_cc;
421   i386_compare_op0 = operands[0];
422   i386_compare_op1 = const0_rtx;
423   DONE;
424 }")
425 \f
426 ;;- compare instructions.  See comments above tstM patterns about
427 ;;  expansion of these insns.
428
429 (define_insn "cmpsi_1"
430   [(set (cc0)
431         (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
432                  (match_operand:SI 1 "general_operand" "ri,mr")))]
433   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
434   "* return AS2 (cmp%L0,%1,%0);"
435   [(set_attr "type" "compare")])
436
437 (define_expand "cmpsi"
438   [(set (cc0)
439         (compare (match_operand:SI 0 "nonimmediate_operand" "")
440                  (match_operand:SI 1 "general_operand" "")))]
441   ""
442   "
443 {
444   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
445     operands[0] = force_reg (SImode, operands[0]);
446
447   i386_compare_gen = gen_cmpsi_1;
448   i386_compare_op0 = operands[0];
449   i386_compare_op1 = operands[1];
450   DONE;
451 }")
452
453 (define_insn "cmphi_1"
454   [(set (cc0)
455         (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
456                  (match_operand:HI 1 "general_operand" "ri,mr")))]
457   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
458   "* return AS2 (cmp%W0,%1,%0);"
459   [(set_attr "type" "compare")])
460
461 (define_expand "cmphi"
462   [(set (cc0)
463         (compare (match_operand:HI 0 "nonimmediate_operand" "")
464                  (match_operand:HI 1 "general_operand" "")))]
465   ""
466   "
467 {
468   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
469     operands[0] = force_reg (HImode, operands[0]);
470
471   i386_compare_gen = gen_cmphi_1;
472   i386_compare_op0 = operands[0];
473   i386_compare_op1 = operands[1];
474   DONE;
475 }")
476
477 (define_insn "cmpqi_1"
478   [(set (cc0)
479         (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
480                  (match_operand:QI 1 "general_operand" "qm,nq")))]
481   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
482   "* return AS2 (cmp%B0,%1,%0);"
483   [(set_attr "type" "compare")])
484
485 (define_expand "cmpqi"
486   [(set (cc0)
487         (compare (match_operand:QI 0 "nonimmediate_operand" "")
488                  (match_operand:QI 1 "general_operand" "")))]
489   ""
490   "
491 {
492   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
493     operands[0] = force_reg (QImode, operands[0]);
494
495   i386_compare_gen = gen_cmpqi_1;
496   i386_compare_op0 = operands[0];
497   i386_compare_op1 = operands[1];
498   DONE;
499 }")
500
501 ;; These implement float point compares.  For each of DFmode and
502 ;; SFmode, there is the normal insn, and an insn where the second operand
503 ;; is converted to the desired mode.
504
505 (define_insn ""
506   [(set (cc0)
507         (match_operator 2 "VOIDmode_compare_op"
508                         [(match_operand:XF 0 "register_operand" "f")
509                          (match_operand:XF 1 "register_operand" "f")]))
510    (clobber (match_scratch:HI 3 "=a"))]
511   "TARGET_80387"
512   "* return output_float_compare (insn, operands);"
513   [(set_attr "type" "fcompare")])
514
515 (define_insn ""
516   [(set (cc0)
517         (match_operator 2 "VOIDmode_compare_op"
518                         [(match_operand:XF 0 "register_operand" "f")
519                          (float_extend:XF
520                           (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
521    (clobber (match_scratch:HI 3 "=a"))]
522   "TARGET_80387"
523   "* return output_float_compare (insn, operands);"
524   [(set_attr "type" "fcompare")])
525
526 (define_insn ""
527   [(set (cc0)
528         (match_operator 2 "VOIDmode_compare_op"
529                         [(float_extend:XF
530                           (match_operand:DF 0 "nonimmediate_operand" "fm"))
531                          (match_operand:XF 1 "register_operand" "f")]))
532    (clobber (match_scratch:HI 3 "=a"))]
533   "TARGET_80387"
534   "* return output_float_compare (insn, operands);"
535   [(set_attr "type" "fcompare")])
536
537 (define_insn ""
538   [(set (cc0)
539         (match_operator 2 "VOIDmode_compare_op"
540                         [(match_operand:XF 0 "register_operand" "f")
541                          (float_extend:XF
542                           (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
543    (clobber (match_scratch:HI 3 "=a"))]
544   "TARGET_80387"
545   "* return output_float_compare (insn, operands);"
546   [(set_attr "type" "fcompare")])
547
548 (define_insn ""
549   [(set (cc0)
550         (match_operator 2 "VOIDmode_compare_op"
551                         [(float_extend:XF
552                           (match_operand:SF 0 "nonimmediate_operand" "fm"))
553                          (match_operand:XF 1 "register_operand" "f")]))
554    (clobber (match_scratch:HI 3 "=a"))]
555   "TARGET_80387"
556   "* return output_float_compare (insn, operands);"
557   [(set_attr "type" "fcompare")])
558
559 (define_insn ""
560   [(set (cc0)
561         (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
562                         (match_operand:XF 1 "register_operand" "f")))
563    (clobber (match_scratch:HI 2 "=a"))]
564   "TARGET_80387"
565   "* return output_float_compare (insn, operands);"
566   [(set_attr "type" "fcompare")])
567
568 (define_insn ""
569   [(set (cc0)
570         (match_operator 2 "VOIDmode_compare_op"
571                         [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
572                          (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
573    (clobber (match_scratch:HI 3 "=a,a"))]
574   "TARGET_80387
575    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
576   "* return output_float_compare (insn, operands);"
577   [(set_attr "type" "fcompare")])
578
579 (define_insn ""
580   [(set (cc0)
581         (match_operator 2 "VOIDmode_compare_op"
582                         [(match_operand:DF 0 "register_operand" "f")
583                          (float_extend:DF
584                           (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
585    (clobber (match_scratch:HI 3 "=a"))]
586   "TARGET_80387"
587   "* return output_float_compare (insn, operands);"
588   [(set_attr "type" "fcompare")])
589
590 (define_insn ""
591   [(set (cc0)
592         (match_operator 2 "VOIDmode_compare_op"
593                         [(float_extend:DF
594                           (match_operand:SF 0 "nonimmediate_operand" "fm"))
595                          (match_operand:DF 1 "register_operand" "f")]))
596    (clobber (match_scratch:HI 3 "=a"))]
597   "TARGET_80387"
598   "* return output_float_compare (insn, operands);"
599   [(set_attr "type" "fcompare")])
600
601 (define_insn ""
602   [(set (cc0)
603         (match_operator 2 "VOIDmode_compare_op"
604                         [(float_extend:DF
605                           (match_operand:SF 0 "register_operand" "f"))
606                          (match_operand:DF 1 "nonimmediate_operand" "fm")]))
607    (clobber (match_scratch:HI 3 "=a"))]
608   "TARGET_80387"
609   "* return output_float_compare (insn, operands);"
610   [(set_attr "type" "fcompare")])
611
612 (define_insn ""
613   [(set (cc0)
614         (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
615                         (match_operand:DF 1 "register_operand" "f")))
616    (clobber (match_scratch:HI 2 "=a"))]
617   "TARGET_80387"
618   "* return output_float_compare (insn, operands);"
619   [(set_attr "type" "fcompare")])
620
621 ;; These two insns will never be generated by combine due to the mode of
622 ;; the COMPARE.
623 ;(define_insn ""
624 ;  [(set (cc0)
625 ;       (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
626 ;                       (float_extend:DF
627 ;                        (match_operand:SF 1 "register_operand" "f"))))
628 ;   (clobber (match_scratch:HI 2 "=a"))]
629 ;  "TARGET_80387"
630 ;  "* return output_float_compare (insn, operands);")
631 ;
632 ;(define_insn ""
633 ;  [(set (cc0)
634 ;       (compare:CCFPEQ (float_extend:DF
635 ;                        (match_operand:SF 0 "register_operand" "f"))
636 ;                       (match_operand:DF 1 "register_operand" "f")))
637 ;   (clobber (match_scratch:HI 2 "=a"))]
638 ;  "TARGET_80387"
639 ;  "* return output_float_compare (insn, operands);")
640
641 (define_insn "*cmpsf_cc_1"
642   [(set (cc0)
643         (match_operator 2 "VOIDmode_compare_op"
644                         [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
645                          (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
646    (clobber (match_scratch:HI 3 "=a,a"))]
647   "TARGET_80387
648    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
649   "* return output_float_compare (insn, operands);"
650   [(set_attr "type" "fcompare")])
651
652 (define_insn ""
653   [(set (cc0)
654         (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
655                         (match_operand:SF 1 "register_operand" "f")))
656    (clobber (match_scratch:HI 2 "=a"))]
657   "TARGET_80387"
658   "* return output_float_compare (insn, operands);"
659   [(set_attr "type" "fcompare")])
660
661 (define_expand "cmpxf"
662   [(set (cc0)
663         (compare (match_operand:XF 0 "register_operand" "")
664                  (match_operand:XF 1 "register_operand" "")))]
665   "TARGET_80387"
666   "
667 {
668   i386_compare_gen = gen_cmpxf_cc;
669   i386_compare_gen_eq = gen_cmpxf_ccfpeq;
670   i386_compare_op0 = operands[0];
671   i386_compare_op1 = operands[1];
672   DONE;
673 }")
674
675 (define_expand "cmpdf"
676   [(set (cc0)
677         (compare (match_operand:DF 0 "register_operand" "")
678                  (match_operand:DF 1 "general_operand" "")))]
679   "TARGET_80387"
680   "
681 {
682   i386_compare_gen = gen_cmpdf_cc;
683   i386_compare_gen_eq = gen_cmpdf_ccfpeq;
684   i386_compare_op0 = operands[0];
685   i386_compare_op1 = (immediate_operand (operands[1], DFmode))
686                         ? copy_to_mode_reg (DFmode, operands[1]) : operands[1];
687   DONE;
688 }")
689
690 (define_expand "cmpsf"
691   [(set (cc0)
692         (compare (match_operand:SF 0 "register_operand" "")
693                  (match_operand:SF 1 "general_operand" "")))]
694   "TARGET_80387"
695   "
696 {
697   i386_compare_gen = gen_cmpsf_cc;
698   i386_compare_gen_eq = gen_cmpsf_ccfpeq;
699   i386_compare_op0 = operands[0];
700   i386_compare_op1 = (immediate_operand (operands[1], SFmode))
701                         ? copy_to_mode_reg (SFmode, operands[1]) : operands[1];
702   DONE;
703 }")
704
705 (define_expand "cmpxf_cc"
706   [(parallel [(set (cc0)
707                    (compare (match_operand:XF 0 "register_operand" "")
708                             (match_operand:XF 1 "register_operand" "")))
709               (clobber (match_scratch:HI 2 ""))])]
710   "TARGET_80387"
711   "")
712
713 (define_expand "cmpxf_ccfpeq"
714   [(parallel [(set (cc0)
715                    (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
716                                    (match_operand:XF 1 "register_operand" "")))
717               (clobber (match_scratch:HI 2 ""))])]
718   "TARGET_80387"
719   "")
720
721 (define_expand "cmpdf_cc"
722   [(parallel [(set (cc0)
723                    (compare (match_operand:DF 0 "register_operand" "")
724                             (match_operand:DF 1 "register_operand" "")))
725               (clobber (match_scratch:HI 2 ""))])]
726   "TARGET_80387"
727   "")
728
729 (define_expand "cmpdf_ccfpeq"
730   [(parallel [(set (cc0)
731                    (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
732                                    (match_operand:DF 1 "register_operand" "")))
733               (clobber (match_scratch:HI 2 ""))])]
734   "TARGET_80387"
735   "
736 {
737   if (! register_operand (operands[1], DFmode))
738     operands[1] = copy_to_mode_reg (DFmode, operands[1]);
739 }")
740
741 (define_expand "cmpsf_cc"
742   [(parallel [(set (cc0)
743                    (compare (match_operand:SF 0 "register_operand" "")
744                             (match_operand:SF 1 "register_operand" "")))
745               (clobber (match_scratch:HI 2 ""))])]
746   "TARGET_80387"
747   "")
748
749 (define_expand "cmpsf_ccfpeq"
750   [(parallel [(set (cc0)
751                    (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
752                                    (match_operand:SF 1 "register_operand" "")))
753               (clobber (match_scratch:HI 2 ""))])]
754   "TARGET_80387"
755   "
756 {
757   if (! register_operand (operands[1], SFmode))
758     operands[1] = copy_to_mode_reg (SFmode, operands[1]);
759 }")
760 \f
761 ;; logical compare
762
763 (define_insn ""
764   [(set (cc0)
765         (and:SI (match_operand:SI 0 "general_operand" "%ro")
766                 (match_operand:SI 1 "nonmemory_operand" "ri")))]
767   ""
768   "*
769 {
770   /* For small integers, we may actually use testb. */
771   if (GET_CODE (operands[1]) == CONST_INT
772       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
773       && (! REG_P (operands[0]) || QI_REG_P (operands[0]))
774       /* A Pentium test is pairable only with eax. Not with ah or al.  */
775       && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
776           || optimize_size))
777     {
778       /* We may set the sign bit spuriously.  */
779
780       if ((INTVAL (operands[1]) & ~0xff) == 0)
781         {
782           cc_status.flags |= CC_NOT_NEGATIVE;
783           return AS2 (test%B0,%1,%b0);
784         }
785
786       if ((INTVAL (operands[1]) & ~0xff00) == 0)
787         {
788           cc_status.flags |= CC_NOT_NEGATIVE;
789           operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
790
791           if (QI_REG_P (operands[0]))
792             return AS2 (test%B0,%1,%h0);
793           else
794             {
795               operands[0] = adj_offsettable_operand (operands[0], 1);
796               return AS2 (test%B0,%1,%b0);
797             }
798         }
799
800       if (GET_CODE (operands[0]) == MEM
801           && (INTVAL (operands[1]) & ~0xff0000) == 0)
802         {
803           cc_status.flags |= CC_NOT_NEGATIVE;
804           operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
805           operands[0] = adj_offsettable_operand (operands[0], 2);
806           return AS2 (test%B0,%1,%b0);
807         }
808
809       if (GET_CODE (operands[0]) == MEM
810           && (INTVAL (operands[1]) & ~0xff000000) == 0)
811         {
812           operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
813           operands[0] = adj_offsettable_operand (operands[0], 3);
814           return AS2 (test%B0,%1,%b0);
815         }
816     }
817
818   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
819     return AS2 (test%L0,%1,%0);
820
821   return AS2 (test%L1,%0,%1);
822 }"
823   [(set_attr "type" "compare")])
824
825 (define_insn ""
826   [(set (cc0)
827         (and:HI (match_operand:HI 0 "general_operand" "%ro")
828                 (match_operand:HI 1 "nonmemory_operand" "ri")))]
829   ""
830   "*
831 {
832   if (GET_CODE (operands[1]) == CONST_INT
833       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
834       && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
835     {
836       if ((INTVAL (operands[1]) & 0xff00) == 0)
837         {
838           /* ??? This might not be necessary. */
839           if (INTVAL (operands[1]) & 0xffff0000)
840             operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
841
842           /* We may set the sign bit spuriously.  */
843           cc_status.flags |= CC_NOT_NEGATIVE;
844           return AS2 (test%B0,%1,%b0);
845         }
846
847       if ((INTVAL (operands[1]) & 0xff) == 0)
848         {
849           operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
850
851           if (QI_REG_P (operands[0]))
852             return AS2 (test%B0,%1,%h0);
853           else
854             {
855               operands[0] = adj_offsettable_operand (operands[0], 1);
856               return AS2 (test%B0,%1,%b0);
857             }
858         }
859     }
860
861   /* use 32-bit test instruction if there are no sign issues */
862   if (GET_CODE (operands[1]) == CONST_INT
863       && !(INTVAL (operands[1]) & ~0x7fff)
864       && i386_aligned_p (operands[0]))
865     return AS2 (test%L0,%1,%k0);
866
867   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
868     return AS2 (test%W0,%1,%0);
869
870   return AS2 (test%W1,%0,%1);
871 }"
872   [(set_attr "type" "compare")])
873
874 (define_insn ""
875   [(set (cc0)
876         (and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm")
877                 (match_operand:QI 1 "nonmemory_operand" "qi")))]
878   ""
879   "*
880 {
881   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
882     return AS2 (test%B0,%1,%0);
883
884   return AS2 (test%B1,%0,%1);
885 }"
886   [(set_attr "type" "compare")])
887 \f
888 ;; move instructions.
889 ;; There is one for each machine mode,
890 ;; and each is preceded by a corresponding push-insn pattern
891 ;; (since pushes are not general_operands on the 386).
892
893 (define_insn ""
894   [(set (match_operand:SI 0 "push_operand" "=<")
895         (match_operand:SI 1 "nonmemory_operand" "rn"))]
896   "flag_pic"
897   "* return AS1 (push%L0,%1);"
898   [(set_attr "memory" "store")])
899
900 (define_insn ""
901   [(set (match_operand:SI 0 "push_operand" "=<")
902         (match_operand:SI 1 "nonmemory_operand" "ri"))]
903   "!flag_pic"
904   "* return AS1 (push%L0,%1);"
905   [(set_attr "memory" "store")])
906
907 ;; On a 386, it is faster to push MEM directly.
908
909 (define_insn ""
910   [(set (match_operand:SI 0 "push_operand" "=<")
911         (match_operand:SI 1 "memory_operand" "m"))]
912   "TARGET_PUSH_MEMORY"
913   "* return AS1 (push%L0,%1);"
914   [(set_attr "type" "memory")
915    (set_attr "memory" "load")])
916
917 ;; General case of fullword move.
918
919 ;; If generating PIC code and operands[1] is a symbolic CONST, emit a
920 ;; move to get the address of the symbolic object from the GOT.
921
922 (define_expand "movsi"
923   [(set (match_operand:SI 0 "general_operand" "")
924         (match_operand:SI 1 "general_operand" ""))]
925   ""
926   "
927 {
928   extern int flag_pic;
929
930   if (flag_pic && SYMBOLIC_CONST (operands[1]))
931     emit_pic_move (operands, SImode);
932
933   /* Don't generate memory->memory moves, go through a register */
934   else if (TARGET_MOVE
935            && no_new_pseudos == 0
936            && GET_CODE (operands[0]) == MEM
937            && GET_CODE (operands[1]) == MEM)
938     {
939       operands[1] = force_reg (SImode, operands[1]);
940     }
941 }")
942
943 ;; On i486, incl reg is faster than movl $1,reg.
944
945 (define_insn ""
946   [(set (match_operand:SI 0 "general_operand" "=g,r,r")
947         (match_operand:SI 1 "general_operand" "rn,i,m"))]
948   "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
949     || (GET_CODE (operands[1]) != MEM))
950    && flag_pic"
951   "*
952 {
953   rtx link;
954
955   /* K6: mov reg,0 is slightly faster than xor reg,reg but is 3 bytes
956      longer.  */
957   if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
958       && operands[1] == const0_rtx && REG_P (operands[0]))
959     return AS2 (xor%L0,%0,%0);
960
961   if (operands[1] == const1_rtx
962       /* PPRO and K6 prefer mov to inc to reduce dependencies.  */
963       && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
964       && (link = find_reg_note (insn, REG_WAS_0, 0))
965       /* Make sure the insn that stored the 0 is still present.  */
966       && ! INSN_DELETED_P (XEXP (link, 0))
967       && GET_CODE (XEXP (link, 0)) != NOTE
968       /* Make sure cross jumping didn't happen here.  */
969       && no_labels_between_p (XEXP (link, 0), insn)
970       /* Make sure the reg hasn't been clobbered.  */
971       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
972     /* Fastest way to change a 0 to a 1.  */
973     return AS1 (inc%L0,%0);
974
975   if (SYMBOLIC_CONST (operands[1]))
976     return AS2 (lea%L0,%a1,%0);
977
978   return AS2 (mov%L0,%1,%0);
979 }"
980   [(set_attr "type" "integer,integer,memory")
981    (set_attr "memory" "*,*,load")])
982
983 (define_insn ""
984   [(set (match_operand:SI 0 "general_operand" "=g,r")
985         (match_operand:SI 1 "general_operand" "ri,m"))]
986   "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
987     || (GET_CODE (operands[1]) != MEM))
988    && !flag_pic"
989   "*
990 {
991   rtx link;
992
993   /* Use of xor was disabled for AMD K6 as recommended by the Optimization
994      Manual.  My test shows, that this generally hurts the performance, because
995      mov is longer and takes longer to decode and decoding is the main
996      bottleneck of K6 when executing GCC code.  */
997
998   if (operands[1] == const0_rtx && REG_P (operands[0]))
999     return AS2 (xor%L0,%0,%0);
1000
1001   if (operands[1] == const1_rtx
1002       /* PPRO and K6 prefer mov to inc to reduce dependencies.  */
1003       && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1004       && (link = find_reg_note (insn, REG_WAS_0, 0))
1005       /* Make sure the insn that stored the 0 is still present.  */
1006       && ! INSN_DELETED_P (XEXP (link, 0))
1007       && GET_CODE (XEXP (link, 0)) != NOTE
1008       /* Make sure cross jumping didn't happen here.  */
1009       && no_labels_between_p (XEXP (link, 0), insn)
1010       /* Make sure the reg hasn't been clobbered.  */
1011       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1012     /* Fastest way to change a 0 to a 1.  */
1013     return AS1 (inc%L0,%0);
1014
1015   return AS2 (mov%L0,%1,%0);
1016 }"
1017   [(set_attr "type" "integer,memory")
1018    (set_attr "memory" "*,load")])
1019
1020 (define_insn ""
1021   [(set (match_operand:HI 0 "push_operand" "=<")
1022         (match_operand:HI 1 "nonmemory_operand" "ri"))]
1023   ""
1024   "* return AS1 (push%W0,%1);"
1025   [(set_attr "type" "memory")
1026    (set_attr "memory" "store")])
1027
1028 (define_insn ""
1029   [(set (match_operand:HI 0 "push_operand" "=<")
1030         (match_operand:HI 1 "memory_operand" "m"))]
1031   "TARGET_PUSH_MEMORY"
1032   "* return AS1 (push%W0,%1);"
1033   [(set_attr "type" "memory")
1034    (set_attr "memory" "load")])
1035
1036 ;; On i486, an incl and movl are both faster than incw and movw.
1037
1038 (define_expand "movhi"
1039   [(set (match_operand:HI 0 "general_operand" "")
1040         (match_operand:HI 1 "general_operand" ""))]
1041   ""
1042   "
1043 {
1044   /* Don't generate memory->memory moves, go through a register */
1045   if (TARGET_MOVE
1046       && no_new_pseudos == 0
1047       && GET_CODE (operands[0]) == MEM
1048       && GET_CODE (operands[1]) == MEM)
1049     {
1050       operands[1] = force_reg (HImode, operands[1]);
1051     }
1052 }")
1053
1054 (define_insn ""
1055   [(set (match_operand:HI 0 "general_operand" "=g,r")
1056         (match_operand:HI 1 "general_operand" "ri,m"))]
1057   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1058   "*
1059 {
1060   rtx link;
1061   if (REG_P (operands[0]) && operands[1] == const0_rtx)
1062     return AS2 (xor%L0,%k0,%k0);
1063
1064   if (REG_P (operands[0]) && operands[1] == const1_rtx 
1065       /* PPRO and K6 prefer mov to inc to reduce dependencies.  */
1066       && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1067       && (link = find_reg_note (insn, REG_WAS_0, 0))
1068       /* Make sure the insn that stored the 0 is still present.  */
1069       && ! INSN_DELETED_P (XEXP (link, 0))
1070       && GET_CODE (XEXP (link, 0)) != NOTE
1071       /* Make sure cross jumping didn't happen here.  */
1072       && no_labels_between_p (XEXP (link, 0), insn)
1073       /* Make sure the reg hasn't been clobbered.  */
1074       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1075     /* Fastest way to change a 0 to a 1.  */
1076     return AS1 (inc%L0,%k0);
1077
1078   if (REG_P (operands[0]))
1079     {
1080       if (i386_aligned_p (operands[1]))
1081         {
1082           operands[1] = i386_sext16_if_const (operands[1]);
1083           return AS2 (mov%L0,%k1,%k0);
1084         }
1085       if (! TARGET_ZERO_EXTEND_WITH_AND)
1086         {
1087           /* movzwl is faster than movw on the Pentium Pro,
1088            * although not as fast as an aligned movl. */
1089 #ifdef INTEL_SYNTAX
1090           return AS2 (movzx,%1,%k0);
1091 #else
1092           return AS2 (movz%W0%L0,%1,%k0);
1093 #endif
1094         }
1095     }
1096
1097   return AS2 (mov%W0,%1,%0);
1098 }"
1099   [(set_attr "type" "integer,memory")
1100    (set_attr "memory" "*,load")])
1101
1102 (define_expand "movstricthi"
1103   [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
1104         (match_operand:HI 1 "general_operand" ""))]
1105   ""
1106   "
1107 {
1108   /* Don't generate memory->memory moves, go through a register */
1109   if (TARGET_MOVE
1110       && no_new_pseudos == 0
1111       && GET_CODE (operands[0]) == MEM
1112       && GET_CODE (operands[1]) == MEM)
1113     {
1114       operands[1] = force_reg (HImode, operands[1]);
1115     }
1116 }")
1117
1118 (define_insn ""
1119   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
1120         (match_operand:HI 1 "general_operand" "ri,m"))]
1121   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1122   "*
1123 {
1124   rtx link;
1125
1126   /* Use of xor was disabled for AMD K6 as recommended by the Optimization
1127      Manual.  My test shows, that this generally hurts the performance, because
1128      mov is longer and takes longer to decode and decoding is the main
1129      bottleneck of K6 when executing GCC code.  */
1130
1131   if (operands[1] == const0_rtx && REG_P (operands[0]))
1132     return AS2 (xor%W0,%0,%0);
1133
1134   if (operands[1] == const1_rtx
1135       /* PPRO and K6 prefer mov to inc to reduce dependencies.  */
1136       && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO)
1137       && (link = find_reg_note (insn, REG_WAS_0, 0))
1138       /* Make sure the insn that stored the 0 is still present.  */
1139       && ! INSN_DELETED_P (XEXP (link, 0))
1140       && GET_CODE (XEXP (link, 0)) != NOTE
1141       /* Make sure cross jumping didn't happen here.  */
1142       && no_labels_between_p (XEXP (link, 0), insn)
1143       /* Make sure the reg hasn't been clobbered.  */
1144       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1145     /* Fastest way to change a 0 to a 1.  */
1146     return AS1 (inc%W0,%0);
1147
1148   return AS2 (mov%W0,%1,%0);
1149 }"
1150   [(set_attr "type" "integer,memory")])
1151
1152 ;; emit_push_insn when it calls move_by_pieces
1153 ;; requires an insn to "push a byte".
1154 ;; But actually we use pushw, which has the effect of rounding
1155 ;; the amount pushed up to a halfword.
1156 (define_insn ""
1157   [(set (match_operand:QI 0 "push_operand" "=<")
1158         (match_operand:QI 1 "const_int_operand" "n"))]
1159   ""
1160   "* return AS1(push%W0,%1);")
1161
1162 (define_insn ""
1163   [(set (match_operand:QI 0 "push_operand" "=<")
1164         (match_operand:QI 1 "register_operand" "q"))]
1165   ""
1166   "*
1167 {
1168   operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]));
1169   return AS1 (push%W0,%1);
1170 }")
1171
1172 ;; On i486, incb reg is faster than movb $1,reg.
1173
1174 ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
1175 ;; or writes %ah, %bh, %ch, %dh.
1176
1177 (define_expand "movqi"
1178   [(set (match_operand:QI 0 "general_operand" "")
1179         (match_operand:QI 1 "general_operand" ""))]
1180   ""
1181   "
1182 {
1183   /* Don't generate memory->memory moves, go through a register */
1184   if (TARGET_MOVE
1185       && no_new_pseudos == 0
1186       && GET_CODE (operands[0]) == MEM
1187       && GET_CODE (operands[1]) == MEM)
1188     {
1189       operands[1] = force_reg (QImode, operands[1]);
1190     }
1191 }")
1192
1193 (define_insn ""
1194   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,*r,qm")
1195         (match_operand:QI 1 "general_operand" "*g,*rn,qn"))]
1196   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1197   "*
1198 {
1199   rtx link;
1200
1201   /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8.
1202      It is at least as fast as xor on any processor except a Pentium. */
1203
1204   if (operands[1] == const1_rtx
1205       && TARGET_PENTIUM
1206       && (link = find_reg_note (insn, REG_WAS_0, 0))
1207       /* Make sure the insn that stored the 0 is still present.  */
1208       && ! INSN_DELETED_P (XEXP (link, 0))
1209       && GET_CODE (XEXP (link, 0)) != NOTE
1210       /* Make sure cross jumping didn't happen here.  */
1211       && no_labels_between_p (XEXP (link, 0), insn)
1212       /* Make sure the reg hasn't been clobbered.  */
1213       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1214     {
1215       /* Fastest way to change a 0 to a 1.
1216          If inc%B0 isn't allowed, use inc%L0.  */
1217       if (NON_QI_REG_P (operands[0]))
1218         return AS1 (inc%L0,%k0);
1219       else
1220         return AS1 (inc%B0,%0);
1221     }
1222
1223   /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
1224   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1225     return (AS2 (mov%L0,%k1,%k0));
1226
1227   return (AS2 (mov%B0,%1,%0));
1228 }")
1229
1230 ;; If it becomes necessary to support movstrictqi into %esi or %edi,
1231 ;; use the insn sequence:
1232 ;;
1233 ;;      shrdl $8,srcreg,dstreg
1234 ;;      rorl $24,dstreg
1235 ;;
1236 ;; If operands[1] is a constant, then an andl/orl sequence would be
1237 ;; faster.
1238
1239 (define_expand "movstrictqi"
1240   [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
1241         (match_operand:QI 1 "general_operand" ""))]
1242   ""
1243   "
1244 {
1245   /* Don't generate memory->memory moves, go through a register */
1246   if (TARGET_MOVE
1247       && no_new_pseudos == 0
1248       && GET_CODE (operands[0]) == MEM
1249       && GET_CODE (operands[1]) == MEM)
1250     {
1251       operands[1] = force_reg (QImode, operands[1]);
1252     }
1253 }")
1254
1255 (define_insn ""
1256   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1257         (match_operand:QI 1 "general_operand" "*qn,m"))]
1258   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1259   "*
1260 {
1261   rtx link;
1262
1263   /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8.  */
1264
1265   if (operands[1] == const1_rtx
1266       && TARGET_PENTIUM
1267       && ! NON_QI_REG_P (operands[0])
1268       && (link = find_reg_note (insn, REG_WAS_0, 0))
1269       /* Make sure the insn that stored the 0 is still present.  */
1270       && ! INSN_DELETED_P (XEXP (link, 0))
1271       && GET_CODE (XEXP (link, 0)) != NOTE
1272       /* Make sure cross jumping didn't happen here.  */
1273       && no_labels_between_p (XEXP (link, 0), insn)
1274       /* Make sure the reg hasn't been clobbered.  */
1275       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
1276     /* Fastest way to change a 0 to a 1.  */
1277     return AS1 (inc%B0,%0);
1278
1279   /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
1280   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1281     {
1282       abort ();
1283       return (AS2 (mov%L0,%k1,%k0));
1284     }
1285
1286   return AS2 (mov%B0,%1,%0);
1287 }")
1288
1289 (define_insn "movsf_push"
1290   [(set (match_operand:SF 0 "push_operand" "=<,<")
1291         (match_operand:SF 1 "general_operand" "*rfF,m"))]
1292   "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 
1293    || reload_in_progress || reload_completed"
1294   "*
1295 {
1296   if (STACK_REG_P (operands[1]))
1297     {
1298       rtx xops[3];
1299
1300       if (! STACK_TOP_P (operands[1]))
1301         abort ();
1302
1303       xops[0] = AT_SP (SFmode);
1304       xops[1] = GEN_INT (4);
1305       xops[2] = stack_pointer_rtx;
1306
1307       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1308
1309       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1310         output_asm_insn (AS1 (fstp%S0,%0), xops);
1311       else
1312         output_asm_insn (AS1 (fst%S0,%0), xops);
1313
1314       RET;
1315     }
1316
1317   return AS1 (push%L0,%1);
1318 }")
1319
1320 (define_split
1321   [(set (match_operand:SF 0 "push_operand" "")
1322         (match_operand:SF 1 "general_operand" ""))]
1323   "reload_completed && STACK_REG_P (operands[1])"
1324   [(set (reg:SI 7)
1325         (minus:SI (reg:SI 7) (const_int 4)))
1326    (set (mem:SF (reg:SI 7))
1327         (match_dup 1))]
1328   "")
1329
1330 (define_expand "movsf"
1331   [(set (match_operand:SF 0 "general_operand" "")
1332         (match_operand:SF 1 "general_operand" ""))]
1333   ""
1334   "
1335 {
1336   /* Don't generate memory->memory moves, go through a register */
1337   if (TARGET_MOVE
1338       && no_new_pseudos == 0
1339       && GET_CODE (operands[0]) == MEM
1340       && GET_CODE (operands[1]) == MEM)
1341     {
1342       operands[1] = force_reg (SFmode, operands[1]);
1343     }
1344
1345   /* If we are loading a floating point constant that isn't 0 or 1
1346      into a register, force the value to memory now, since we'll 
1347      get better code out the back end.  */
1348   else if ((reload_in_progress | reload_completed) == 0
1349            && GET_CODE (operands[0]) != MEM
1350            && GET_CODE (operands[1]) == CONST_DOUBLE
1351            && !standard_80387_constant_p (operands[1]))
1352     {
1353       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
1354     }
1355 }")
1356
1357 ;; For the purposes of regclass, prefer FLOAT_REGS.
1358 (define_insn ""
1359   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r,!m")
1360         (match_operand:SF 1 "general_operand" "fmG,f,*rmF,*rF"))]
1361   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
1362   "*
1363 {
1364   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1365
1366   /* First handle a `pop' insn or a `fld %st(0)' */
1367
1368   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1369     {
1370       if (stack_top_dies)
1371         return AS1 (fstp,%y0);
1372       else
1373         return AS1 (fld,%y0);
1374     }
1375
1376   /* Handle other kinds of writes from the 387 */
1377
1378   if (STACK_TOP_P (operands[1]))
1379     {
1380       if (stack_top_dies)
1381         return AS1 (fstp%z0,%y0);
1382       else
1383         return AS1 (fst%z0,%y0);
1384     }
1385
1386   /* Handle other kinds of reads to the 387 */
1387
1388   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1389     return output_move_const_single (operands);
1390
1391   if (STACK_TOP_P (operands[0]))
1392     return AS1 (fld%z1,%y1);
1393
1394   /* Handle all SFmode moves not involving the 387 */
1395
1396   return singlemove_string (operands);
1397 }"
1398   [(set_attr "type" "fld")])
1399
1400
1401 (define_insn "swapsf"
1402   [(set (match_operand:SF 0 "register_operand" "f")
1403         (match_operand:SF 1 "register_operand" "f"))
1404    (set (match_dup 1)
1405         (match_dup 0))]
1406   ""
1407   "*
1408 {
1409   if (STACK_TOP_P (operands[0]))
1410     return AS1 (fxch,%1);
1411   else
1412     return AS1 (fxch,%0);
1413 }")
1414
1415
1416 (define_insn "movdf_push"
1417   [(set (match_operand:DF 0 "push_operand" "=<,<")
1418         (match_operand:DF 1 "general_operand" "*rfF,o"))]
1419   "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 
1420    || reload_in_progress || reload_completed"
1421   "*
1422 {
1423   if (STACK_REG_P (operands[1]))
1424     {
1425       rtx xops[3];
1426
1427       xops[0] = AT_SP (DFmode);
1428       xops[1] = GEN_INT (8);
1429       xops[2] = stack_pointer_rtx;
1430
1431       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1432
1433       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1434         output_asm_insn (AS1 (fstp%Q0,%0), xops);
1435       else
1436         output_asm_insn (AS1 (fst%Q0,%0), xops);
1437
1438       RET;
1439     }
1440
1441   if (which_alternative == 1)
1442     return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 0, 0);
1443
1444   return output_move_double (operands);
1445 }")
1446
1447 (define_split
1448   [(set (match_operand:DF 0 "push_operand" "")
1449         (match_operand:DF 1 "register_operand" ""))]
1450   "reload_completed && STACK_REG_P (operands[1])"
1451   [(set (reg:SI 7)
1452         (minus:SI (reg:SI 7) (const_int 8)))
1453    (set (mem:DF (reg:SI 7))
1454         (match_dup 1))]
1455   "")
1456
1457 (define_expand "movdf"
1458   [(set (match_operand:DF 0 "general_operand" "")
1459         (match_operand:DF 1 "general_operand" ""))]
1460   ""
1461   "
1462 {
1463   /* Don't generate memory->memory moves, go through a register */
1464   if (TARGET_MOVE
1465       && no_new_pseudos == 0
1466       && GET_CODE (operands[0]) == MEM
1467       && GET_CODE (operands[1]) == MEM)
1468     {
1469       operands[1] = force_reg (DFmode, operands[1]);
1470     }
1471
1472   /* If we are loading a floating point constant that isn't 0 or 1 into a
1473      register, indicate we need the pic register loaded.  This could be
1474      optimized into stores of constants if the target eventually moves to
1475      memory, but better safe than sorry.  */
1476   else if ((reload_in_progress | reload_completed) == 0
1477            && GET_CODE (operands[0]) != MEM
1478            && GET_CODE (operands[1]) == CONST_DOUBLE
1479            && !standard_80387_constant_p (operands[1]))
1480     {
1481       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
1482     }
1483 }")
1484
1485 ;; For the purposes of regclass, prefer FLOAT_REGS.
1486 (define_insn ""
1487   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r,!o")
1488         (match_operand:DF 1 "general_operand" "fmG,f,*roF,*rF"))]
1489   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1490    || (GET_CODE (operands[1]) != MEM)"
1491   "*
1492 {
1493   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1494
1495   /* First handle a `pop' insn or a `fld %st(0)' */
1496
1497   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1498     {
1499       if (stack_top_dies)
1500         return AS1 (fstp,%y0);
1501       else
1502         return AS1 (fld,%y0);
1503     }
1504
1505   /* Handle other kinds of writes from the 387 */
1506
1507   if (STACK_TOP_P (operands[1]))
1508     {
1509       if (stack_top_dies)
1510         return AS1 (fstp%z0,%y0);
1511       else
1512         return AS1 (fst%z0,%y0);
1513     }
1514
1515   /* Handle other kinds of reads to the 387 */
1516
1517   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1518     return output_move_const_single (operands);
1519
1520   if (STACK_TOP_P (operands[0]))
1521     return AS1 (fld%z1,%y1);
1522
1523   /* Handle all DFmode moves not involving the 387 */
1524
1525   return output_move_double (operands);
1526 }"
1527   [(set_attr "type" "fld")])
1528
1529
1530
1531 (define_insn "swapdf"
1532   [(set (match_operand:DF 0 "register_operand" "f")
1533         (match_operand:DF 1 "register_operand" "f"))
1534    (set (match_dup 1)
1535         (match_dup 0))]
1536   ""
1537   "*
1538 {
1539   if (STACK_TOP_P (operands[0]))
1540     return AS1 (fxch,%1);
1541   else
1542     return AS1 (fxch,%0);
1543 }")
1544
1545 (define_insn "movxf_push"
1546   [(set (match_operand:XF 0 "push_operand" "=<,<")
1547         (match_operand:XF 1 "general_operand" "*rfF,o"))]
1548   "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 
1549    || reload_in_progress || reload_completed"
1550   "*
1551 {
1552   if (STACK_REG_P (operands[1]))
1553     {
1554       rtx xops[3];
1555
1556       xops[0] = AT_SP (XFmode);
1557       xops[1] = GEN_INT (12);
1558       xops[2] = stack_pointer_rtx;
1559
1560       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1561
1562       output_asm_insn (AS1 (fstp%T0,%0), xops);
1563       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1564         output_asm_insn (AS1 (fld%T0,%0), xops);
1565
1566       RET;
1567     }
1568
1569   if (which_alternative == 1)
1570     return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 0, 0);
1571
1572   return output_move_double (operands);
1573  }")
1574
1575 (define_split
1576   [(set (match_operand:XF 0 "push_operand" "")
1577         (match_operand:XF 1 "register_operand" ""))]
1578   "reload_completed && STACK_REG_P (operands[1])"
1579   [(set (reg:SI 7)
1580         (minus:SI (reg:SI 7) (const_int 12)))
1581    (set (mem:XF (reg:SI 7))
1582         (match_dup 1))]
1583   "")
1584
1585 (define_expand "movxf"
1586   [(set (match_operand:XF 0 "general_operand" "")
1587         (match_operand:XF 1 "general_operand" ""))]
1588   ""
1589   "
1590 {
1591   /* Don't generate memory->memory moves, go through a register */
1592   if (TARGET_MOVE
1593       && no_new_pseudos == 0
1594       && GET_CODE (operands[0]) == MEM
1595       && GET_CODE (operands[1]) == MEM)
1596     {
1597       operands[1] = force_reg (XFmode, operands[1]);
1598     }
1599
1600   /* If we are loading a floating point constant that isn't 0 or 1
1601      into a register, indicate we need the pic register loaded.  This could
1602      be optimized into stores of constants if the target eventually moves
1603      to memory, but better safe than sorry.  */
1604   else if ((reload_in_progress | reload_completed) == 0
1605            && GET_CODE (operands[0]) != MEM
1606            && GET_CODE (operands[1]) == CONST_DOUBLE
1607            && !standard_80387_constant_p (operands[1]))
1608     {
1609       operands[1] = validize_mem (force_const_mem (XFmode, operands[1]));
1610     }
1611 }")
1612
1613
1614 (define_insn ""
1615   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!*r,!o")
1616         (match_operand:XF 1 "general_operand" "fmG,f,*roF,*rF"))]
1617   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1618    || (GET_CODE (operands[1]) != MEM)"
1619   "*
1620 {
1621   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1622
1623   /* First handle a `pop' insn or a `fld %st(0)' */
1624
1625   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1626     {
1627       if (stack_top_dies)
1628         return AS1 (fstp,%y0);
1629       else
1630         return AS1 (fld,%y0);
1631     }
1632
1633   /* Handle other kinds of writes from the 387 */
1634
1635   if (STACK_TOP_P (operands[1]))
1636     {
1637       output_asm_insn (AS1 (fstp%z0,%y0), operands);
1638       if (! stack_top_dies)
1639         return AS1 (fld%z0,%y0);
1640
1641       RET;
1642     }
1643
1644   /* Handle other kinds of reads to the 387 */
1645
1646   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
1647     return output_move_const_single (operands);
1648
1649   if (STACK_TOP_P (operands[0]))
1650        return AS1 (fld%z1,%y1);
1651
1652   /* Handle all XFmode moves not involving the 387 */
1653
1654   return output_move_double (operands);
1655 }")
1656
1657 (define_insn "swapxf" 
1658   [(set (match_operand:XF 0 "register_operand" "f")
1659         (match_operand:XF 1 "register_operand" "f"))
1660    (set (match_dup 1)
1661         (match_dup 0))]
1662   ""
1663   "*
1664 {
1665   if (STACK_TOP_P (operands[0]))
1666     return AS1 (fxch,%1);
1667   else
1668     return AS1 (fxch,%0);
1669 }")
1670
1671 (define_insn ""
1672   [(set (match_operand:DI 0 "push_operand" "=<")
1673         (match_operand:DI 1 "general_operand" "riF"))]
1674   ""
1675   "* return output_move_double (operands);")
1676
1677 (define_insn ""
1678   [(set (match_operand:DI 0 "push_operand" "=<")
1679         (match_operand:DI 1 "memory_operand" "o"))]
1680   "TARGET_PUSH_MEMORY"
1681   "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode),0,0);")
1682
1683 (define_expand "movdi"
1684   [(set (match_operand:DI 0 "general_operand" "")
1685         (match_operand:DI 1 "general_operand" ""))]
1686   ""
1687   "
1688 {
1689   /* Don't generate memory->memory moves, go through a register */
1690   if (TARGET_MOVE
1691       && no_new_pseudos == 0
1692       && GET_CODE (operands[0]) == MEM
1693       && GET_CODE (operands[1]) == MEM)
1694     {
1695       operands[1] = force_reg (DImode, operands[1]);
1696     }
1697 }")
1698
1699 (define_insn ""
1700   [(set (match_operand:DI 0 "general_operand" "=g,r")
1701         (match_operand:DI 1 "general_operand" "riF,m"))]
1702   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1703    || (GET_CODE (operands[1]) != MEM)"
1704   "* return output_move_double (operands);"
1705   [(set_attr "type" "integer,memory")
1706    (set_attr "memory" "*,load")])
1707
1708 (define_split
1709   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1710         (match_operand:DI 1 "general_operand" ""))]
1711   "reload_completed
1712    && (offsettable_memref_p (operands[0])
1713        || nonmemory_operand (operands[0], DImode))
1714    && (offsettable_memref_p (operands[1])
1715        || nonmemory_operand (operands[1], DImode))
1716    && (! reg_overlap_mentioned_p (gen_lowpart (SImode, operands[0]),
1717                                   operands[1])
1718        || ! reg_overlap_mentioned_p (gen_highpart (SImode, operands[0]),
1719                                      operands[1]))"
1720   [(set (match_dup 2)
1721         (match_dup 4))
1722    (set (match_dup 3)
1723         (match_dup 5))]
1724   "
1725 {
1726   split_di (&operands[0], 1, &operands[2], &operands[3]);
1727   split_di (&operands[1], 1, &operands[4], &operands[5]);
1728
1729   if (reg_overlap_mentioned_p (operands[2], operands[1]))
1730     {
1731     rtx tmp;
1732
1733     tmp = operands[2];
1734     operands[2] = operands[3];
1735     operands[3] = tmp;
1736
1737     tmp = operands[4];
1738     operands[4] = operands[5];
1739     operands[5] = tmp;
1740     }
1741 }")
1742 \f
1743 ;;- conversion instructions
1744 ;;- NONE
1745
1746 ;;- zero extension instructions
1747 ;; See comments by `andsi' for when andl is faster than movzx.
1748
1749 (define_expand "zero_extendhisi2"
1750   [(set (match_operand:SI 0 "register_operand" "")
1751         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1752   ""
1753   "")
1754
1755 ;; When optimizing for the PPro/PII or code size, always use movzwl.
1756 ;; We want to use a different pattern so we can use different constraints
1757 ;; than the generic pattern.
1758 (define_insn ""
1759   [(set (match_operand:SI 0 "register_operand" "=r")
1760         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
1761   "(optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1762   "* return AS2 (movz%W0%L0,%1,%0);")
1763
1764 (define_insn ""
1765   [(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
1766         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
1767   "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1768   "*
1769   {
1770   rtx xops[2];
1771
1772   if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) 
1773       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1774     {
1775       xops[0] = operands[0];
1776       xops[1] = GEN_INT (0xffff);
1777       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1778       RET;
1779     }
1780   if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1]))
1781     {
1782       output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1783       output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1784       RET;
1785     }
1786
1787   if (TARGET_ZERO_EXTEND_WITH_AND)
1788     {
1789       xops[0] = operands[0];
1790       xops[1] = GEN_INT (0xffff);
1791       if (i386_aligned_p (operands[1]))
1792         output_asm_insn (AS2 (mov%L0,%k1,%k0),operands);
1793       else
1794         output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1795       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1796       RET;
1797     }
1798
1799 #ifdef INTEL_SYNTAX
1800   return AS2 (movzx,%1,%0);
1801 #else
1802   return AS2 (movz%W0%L0,%1,%0);
1803 #endif
1804 }")
1805
1806 (define_split
1807   [(set (match_operand:SI 0 "register_operand" "")
1808         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1809  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])"
1810  [(set (match_dup 0)
1811        (const_int 0))
1812   (set (strict_low_part (match_dup 2))
1813        (match_dup 1))]
1814  "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1815
1816
1817 (define_split
1818   [(set (match_operand:SI 0 "register_operand" "")
1819         (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))]
1820  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])"
1821  [(set (strict_low_part (match_dup 2))
1822        (match_dup 1))
1823   (set (match_dup 0)
1824        (and:SI (match_dup 0)
1825                (const_int 65535)))]
1826   "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
1827
1828 (define_expand "zero_extendqihi2"
1829   [(set (match_operand:HI 0 "register_operand" "")
1830         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1831   ""
1832   "")
1833
1834 (define_insn ""
1835   [(set (match_operand:HI 0 "register_operand" "=r")
1836         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1837   "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
1838
1839   "*  return AS2 (movz%B0%W0,%1,%0);")
1840
1841 (define_insn ""
1842   [(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
1843         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1844   "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1845   "*
1846   {
1847   rtx xops[2];
1848
1849   if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1850       && REG_P (operands[1]) 
1851       && REGNO (operands[0]) == REGNO (operands[1]))
1852     {
1853       xops[0] = operands[0];
1854       xops[1] = GEN_INT (0xff);
1855       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1856       RET;
1857     }
1858   if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1859     {
1860       if(!reg_overlap_mentioned_p(operands[0],operands[1]))
1861         {
1862           output_asm_insn (AS2 (xor%L0,%k0,%k0), operands);
1863           output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1864         }
1865       else
1866         {
1867           xops[0] = operands[0];
1868           xops[1] = GEN_INT (0xff);
1869           output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1870           output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1871         }
1872       RET;
1873     }
1874   
1875 #ifdef INTEL_SYNTAX
1876   return AS2 (movzx,%1,%0);
1877 #else
1878   return AS2 (movz%B0%W0,%1,%0);
1879 #endif
1880 }")
1881
1882 (define_split
1883   [(set (match_operand:HI 0 "register_operand" "")
1884         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1885  "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1886   && !reg_overlap_mentioned_p (operands[0], operands[1])"
1887  [(set (match_dup 0)
1888        (const_int 0))
1889   (set (strict_low_part (match_dup 2))
1890        (match_dup 1))]
1891  "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1892
1893
1894 (define_split
1895   [(set (match_operand:HI 0 "register_operand" "")
1896         (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))]
1897  "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1898   && reg_overlap_mentioned_p (operands[0], operands[1])"
1899  [(set (strict_low_part (match_dup 2))
1900        (match_dup 1))
1901   (set (match_dup 0)
1902        (and:HI (match_dup 0)
1903                (const_int 255)))]
1904  "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1905
1906 (define_split
1907   [(set (match_operand:HI 0 "register_operand" "")
1908         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1909  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND"
1910  [(set (match_dup 0)
1911        (match_dup 2))
1912   (set (match_dup 0)
1913        (and:HI (match_dup 0)
1914                (const_int 255)))]
1915  "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0)
1916     operands[1] = SUBREG_REG (operands[1]);
1917   if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG
1918       || REGNO (operands[0]) == REGNO (operands[1]))
1919     FAIL;
1920   operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
1921
1922 (define_expand "zero_extendqisi2"
1923   [(set (match_operand:SI 0 "register_operand" "")
1924         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1925   ""
1926   "")
1927
1928 (define_insn ""
1929   [(set (match_operand:SI 0 "register_operand" "=r")
1930         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1931   "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO"
1932   "* return AS2 (movz%B0%L0,%1,%0);")
1933
1934 (define_insn ""
1935   [(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
1936         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
1937   "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)"
1938   "*
1939   {
1940   rtx xops[2];
1941
1942   if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
1943       && REG_P (operands[1]) 
1944       && REGNO (operands[0]) == REGNO (operands[1]))
1945     {
1946       xops[0] = operands[0];
1947       xops[1] = GEN_INT (0xff);
1948       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1949       RET;
1950     }
1951   if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1952     {
1953       if(!reg_overlap_mentioned_p (operands[0], operands[1]))
1954         {
1955           output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1956           output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1957         }
1958       else
1959         {
1960           xops[0] = operands[0];
1961           xops[1] = GEN_INT (0xff);
1962           output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1963           output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1964         }
1965       RET;
1966     }
1967
1968   if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG)
1969     {
1970       xops[0] = operands[0];
1971       xops[1] = GEN_INT (0xff);
1972       operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1973       output_asm_insn (AS2 (mov%L0,%1,%0), operands);
1974       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1975       RET;
1976     }
1977
1978 #ifdef INTEL_SYNTAX
1979   return AS2 (movzx,%1,%0);
1980 #else
1981   return AS2 (movz%B0%L0,%1,%0);
1982 #endif
1983 }")
1984
1985 (define_split
1986   [(set (match_operand:SI 0 "register_operand" "")
1987         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1988  "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1989   && !reg_overlap_mentioned_p (operands[0], operands[1])"
1990  [(set (match_dup 0)
1991        (const_int 0))
1992   (set (strict_low_part (match_dup 2))
1993        (match_dup 1))]
1994  "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
1995
1996
1997 (define_split
1998   [(set (match_operand:SI 0 "register_operand" "")
1999         (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))]
2000  "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
2001   && reg_overlap_mentioned_p (operands[0], operands[1])"
2002  [(set (strict_low_part (match_dup 2))
2003        (match_dup 1))
2004   (set (match_dup 0)
2005        (and:SI (match_dup 0)
2006                (const_int 255)))]
2007  "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2008
2009 (define_split
2010   [(set (match_operand:SI 0 "register_operand" "")
2011         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2012  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
2013   && ! reg_overlap_mentioned_p (operands[0], operands[1])"
2014  [(set (match_dup 0)
2015        (match_dup 2))
2016   (set (match_dup 0)
2017        (and:SI (match_dup 0)
2018                (const_int 255)))]
2019  "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
2020
2021 (define_insn "zero_extendsidi2"
2022   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
2023         (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))]
2024   ""
2025   "#")
2026
2027 (define_split 
2028   [(set (match_operand:DI 0 "register_operand" "")
2029         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2030   "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
2031   [(set (match_dup 4) (const_int 0))]
2032   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2033
2034 (define_split 
2035   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2036         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
2037   "reload_completed"
2038   [(set (match_dup 3) (match_dup 1))
2039    (set (match_dup 4) (const_int 0))]
2040   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2041 \f
2042 ;;- sign extension instructions
2043
2044 (define_insn "extendsidi2"
2045   [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o")
2046         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r")))
2047    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
2048   ""
2049   "#")
2050
2051 ;; Extend to memory case when source register does die.
2052 (define_split 
2053   [(set (match_operand:DI 0 "memory_operand" "")
2054         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2055    (clobber (match_operand:SI 2 "register_operand" ""))]
2056   "(flow2_completed
2057     && dead_or_set_p (insn, operands[1])
2058     && !reg_mentioned_p (operands[1], operands[0]))"
2059   [(set (match_dup 3) (match_dup 1))
2060    (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
2061    (set (match_dup 4) (match_dup 1))]
2062   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
2063
2064 ;; Extend to memory case when source register does not die.
2065 (define_split 
2066   [(set (match_operand:DI 0 "memory_operand" "")
2067         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2068    (clobber (match_operand:SI 2 "register_operand" ""))]
2069   "flow2_completed"
2070   [(const_int 0)]
2071   "
2072 {
2073   split_di (&operands[0], 1, &operands[3], &operands[4]);
2074
2075   emit_move_insn (operands[3], operands[1]);
2076
2077   /* Generate a cltd if possible and doing so it profitable.  */
2078   if (true_regnum (operands[1]) == 0
2079       && true_regnum (operands[2]) == 1
2080       && (optimize_size || !TARGET_PENTIUM))
2081     {
2082       emit_insn (gen_ashrsi3_31 (operands[2], operands[1]));
2083     }
2084   else
2085     {
2086       emit_move_insn (operands[2], operands[1]);
2087       emit_insn (gen_ashrsi3_31 (operands[2], operands[2]));
2088     }
2089   emit_move_insn (operands[4], operands[2]);
2090   DONE;
2091 }")
2092
2093 ;; Extend to register case.  Optimize case where source and destination
2094 ;; registers match and cases where we can use cltd.
2095 (define_split 
2096   [(set (match_operand:DI 0 "register_operand" "")
2097         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
2098    (clobber (match_scratch:SI 2 ""))]
2099   "reload_completed"
2100   [(const_int 0)]
2101   "
2102 {
2103   split_di (&operands[0], 1, &operands[3], &operands[4]);
2104
2105   if (true_regnum (operands[3]) != true_regnum (operands[1]))
2106     emit_move_insn (operands[3], operands[1]);
2107
2108   /* Generate a cltd if possible and doing so it profitable.  */
2109   if (true_regnum (operands[3]) == 0
2110       && (optimize_size || !TARGET_PENTIUM))
2111     {
2112       emit_insn (gen_ashrsi3_31 (operands[4], operands[3]));
2113       DONE;
2114     }
2115
2116   if (true_regnum (operands[4]) != true_regnum (operands[1]))
2117     emit_move_insn (operands[4], operands[1]);
2118
2119   emit_insn (gen_ashrsi3_31 (operands[4], operands[4]));
2120   DONE;
2121 }")
2122
2123 ;; Note that the i386 programmers' manual says that the opcodes
2124 ;; are named movsx..., but the assembler on Unix does not accept that.
2125 ;; We use what the Unix assembler expects.
2126
2127 (define_insn "extendhisi2"
2128   [(set (match_operand:SI 0 "register_operand" "=r")
2129         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2130   ""
2131   "*
2132 {
2133   if (REGNO (operands[0]) == 0
2134       && REG_P (operands[1]) && REGNO (operands[1]) == 0
2135       && (optimize_size || ix86_cpu != PROCESSOR_K6))
2136 #ifdef INTEL_SYNTAX
2137     return \"cwde\";
2138 #else
2139     return \"cwtl\";
2140 #endif
2141
2142 #ifdef INTEL_SYNTAX
2143   return AS2 (movsx,%1,%0);
2144 #else
2145   return AS2 (movs%W0%L0,%1,%0);
2146 #endif
2147 }")
2148
2149 (define_insn "extendqihi2"
2150   [(set (match_operand:HI 0 "register_operand" "=r")
2151         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2152   ""
2153   "*
2154 {
2155   if (REGNO (operands[0]) == 0
2156       && REG_P (operands[1]) && REGNO (operands[1]) == 0
2157       && (optimize_size || ix86_cpu != PROCESSOR_K6))
2158     return \"cbtw\";
2159
2160 #ifdef INTEL_SYNTAX
2161   return AS2 (movsx,%1,%0);
2162 #else
2163   return AS2 (movs%B0%W0,%1,%0);
2164 #endif
2165 }")
2166
2167 (define_insn "extendqisi2"
2168   [(set (match_operand:SI 0 "register_operand" "=r")
2169         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2170   ""
2171   "*
2172 {
2173 #ifdef INTEL_SYNTAX
2174   return AS2 (movsx,%1,%0);
2175 #else
2176   return AS2 (movs%B0%L0,%1,%0);
2177 #endif
2178 }")
2179
2180 \f
2181 ;; Truncation of long long -> 32 bit
2182
2183 (define_expand "truncdisi2"
2184   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2185         (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2186   ""
2187   "
2188 {
2189   /* Don't generate memory->memory moves, go through a register */
2190   if (TARGET_MOVE
2191       && (reload_in_progress | reload_completed) == 0
2192       && GET_CODE (operands[0]) == MEM
2193       && GET_CODE (operands[1]) == MEM)
2194     {
2195       rtx target = gen_reg_rtx (SImode);
2196       emit_insn (gen_truncdisi2 (target, operands[1]));
2197       emit_move_insn (operands[0], target);
2198       DONE;
2199     }
2200 }")
2201
2202 (define_insn ""
2203   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2204         (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2205   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2206   "*
2207 {
2208   rtx low[2], high[2], xops[2];
2209
2210   split_di (&operands[1], 1, low, high);
2211   xops[0] = operands[0];
2212   xops[1] = low[0];
2213   if (!rtx_equal_p (xops[0], xops[1]))
2214     output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2215
2216   RET;
2217 }")
2218
2219 (define_insn ""
2220   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2221         (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
2222                                   (const_int 32))))]
2223   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2224   "*
2225 {
2226   rtx low[2], high[2], xops[2];
2227
2228   split_di (&operands[1], 1, low, high);
2229   xops[0] = operands[0];
2230   xops[1] = high[0];
2231   if (!rtx_equal_p (xops[0], xops[1]))
2232     output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2233
2234   RET;
2235 }")
2236
2237
2238 \f
2239 ;; Conversions between float and double.
2240
2241 (define_expand "extendsfdf2"
2242   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2243                    (float_extend:DF
2244                      (match_operand:SF 1 "nonimmediate_operand" "")))
2245      (clobber (match_dup 2))
2246      (clobber (match_dup 3))])]
2247   "TARGET_80387"
2248   "
2249 {
2250   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2251     operands[1] = force_reg (SFmode, operands[1]);
2252
2253   operands[2] = assign_386_stack_local (SFmode, 0);
2254   operands[3] = assign_386_stack_local (DFmode, 0);
2255 }")
2256
2257 (define_insn ""
2258   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2259         (float_extend:DF
2260           (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f")))
2261    (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m"))
2262    (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))]
2263   "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2264                     || GET_CODE (operands[1]) != MEM)"
2265   "*
2266 {
2267   output_float_extend (insn, operands);
2268   return \"\";
2269 }"
2270   [(set_attr "type" "fld,fpop,fld,fpop")])
2271
2272 (define_split
2273   [(set (match_operand:DF 0 "register_operand" "")
2274         (float_extend:DF (match_operand:SF 1 "register_operand" "")))
2275    (clobber (match_operand:SF 2 "memory_operand" ""))
2276    (clobber (match_operand:DF 3 "memory_operand" ""))]
2277   "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2278   [(set (match_dup 2)
2279         (match_dup 1))
2280    (set (match_dup 0)
2281         (float_extend:DF (match_dup 2)))]
2282   "")
2283
2284 (define_split
2285   [(set (match_operand:DF 0 "register_operand" "")
2286         (float_extend:DF (match_operand:SF 1 "register_operand" "")))
2287    (clobber (match_operand:SF 2 "memory_operand" ""))
2288    (clobber (match_operand:DF 3 "memory_operand" ""))]
2289   "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2290   [(set (match_dup 3)
2291         (float_extend:DF (match_dup 1)))
2292    (set (match_dup 0)
2293         (match_dup 3))]
2294   "")
2295
2296 (define_split
2297   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2298         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))
2299    (clobber (match_operand:SF 2 "memory_operand" ""))
2300    (clobber (match_operand:DF 3 "memory_operand" ""))]
2301   "TARGET_80387 && reload_completed"
2302   [(set (match_dup 0)
2303         (float_extend:DF (match_dup 1)))]
2304   "")
2305
2306 (define_insn ""
2307   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
2308         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2309   "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2310                     || GET_CODE (operands[1]) != MEM)"
2311   "*
2312 {
2313     output_float_extend (insn, operands);
2314     return \"\";
2315 }"
2316   [(set_attr "type" "fld,fpop")])
2317
2318 (define_expand "extenddfxf2"
2319   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2320                    (float_extend:XF
2321                      (match_operand:DF 1 "nonimmediate_operand" "")))
2322      (clobber (match_dup 2))
2323      (clobber (match_dup 3))])]
2324   "TARGET_80387"
2325   "
2326 {
2327   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2328     operands[1] = force_reg (DFmode, operands[1]);
2329
2330   operands[2] = assign_386_stack_local (DFmode, 0);
2331   operands[3] = assign_386_stack_local (XFmode, 0);
2332 }")
2333
2334 (define_insn ""
2335   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2336         (float_extend:XF
2337           (match_operand:DF 1 "nonimmediate_operand" "fm,f,*r,f")))
2338    (clobber (match_operand:DF 2 "memory_operand" "m,m,o,m"))
2339    (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
2340   "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2341                     || GET_CODE (operands[1]) != MEM)"
2342   "*
2343 {
2344     output_float_extend (insn, operands);
2345     return \"\";
2346 }"
2347   [(set_attr "type" "fld,fpop,fld,fpop")])
2348
2349 (define_split
2350   [(set (match_operand:XF 0 "register_operand" "")
2351         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
2352    (clobber (match_operand:DF 2 "memory_operand" ""))
2353    (clobber (match_operand:XF 3 "memory_operand" ""))]
2354   "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2355   [(set (match_dup 2)
2356         (match_dup 1))
2357    (set (match_dup 0)
2358         (float_extend:XF (match_dup 2)))]
2359   "")
2360
2361 (define_split
2362   [(set (match_operand:XF 0 "register_operand" "")
2363         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
2364    (clobber (match_operand:DF 2 "memory_operand" ""))
2365    (clobber (match_operand:XF 3 "memory_operand" ""))]
2366   "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2367   [(set (match_dup 3)
2368         (float_extend:XF (match_dup 1)))
2369    (set (match_dup 0)
2370         (match_dup 3))]
2371   "")
2372
2373 (define_split
2374   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2375         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))
2376    (clobber (match_operand:DF 2 "memory_operand" ""))
2377    (clobber (match_operand:XF 3 "memory_operand" ""))]
2378   "TARGET_80387 && reload_completed"
2379   [(set (match_dup 0)
2380         (float_extend:XF (match_dup 1)))]
2381   "")
2382
2383 (define_insn ""
2384   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2385         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
2386   "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2387                     || GET_CODE (operands[1]) != MEM)"
2388   "*
2389 {
2390     output_float_extend (insn, operands);
2391     return \"\";
2392 }"
2393   [(set_attr "type" "fld,fpop")])
2394
2395 (define_expand "extendsfxf2"
2396   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2397                    (float_extend:XF
2398                      (match_operand:SF 1 "nonimmediate_operand" "")))
2399      (clobber (match_dup 2))
2400      (clobber (match_dup 3))])]
2401   "TARGET_80387"
2402   "
2403 {
2404   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2405     operands[1] = force_reg (SFmode, operands[1]);
2406
2407   operands[2] = assign_386_stack_local (SFmode, 0);
2408   operands[3] = assign_386_stack_local (XFmode, 0);
2409 }")
2410
2411 (define_insn ""
2412   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r")
2413         (float_extend:XF
2414           (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f")))
2415    (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m"))
2416    (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
2417   "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2418                     || GET_CODE (operands[1]) != MEM)"
2419   "*
2420 {
2421     output_float_extend (insn, operands);
2422     return \"\";
2423 }"
2424   [(set_attr "type" "fld,fpop,fld,fpop")])
2425
2426 (define_split
2427   [(set (match_operand:XF 0 "register_operand" "")
2428         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
2429    (clobber (match_operand:SF 2 "memory_operand" ""))
2430    (clobber (match_operand:XF 3 "memory_operand" ""))]
2431   "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])"
2432   [(set (match_dup 2)
2433         (match_dup 1))
2434    (set (match_dup 0)
2435         (float_extend:XF (match_dup 2)))]
2436   "")
2437
2438 (define_split
2439   [(set (match_operand:XF 0 "register_operand" "")
2440         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
2441    (clobber (match_operand:SF 2 "memory_operand" ""))
2442    (clobber (match_operand:XF 3 "memory_operand" ""))]
2443   "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])"
2444   [(set (match_dup 3)
2445         (float_extend:XF (match_dup 1)))
2446    (set (match_dup 0)
2447         (match_dup 3))]
2448   "")
2449
2450 (define_split
2451   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2452         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))
2453    (clobber (match_operand:SF 2 "memory_operand" ""))
2454    (clobber (match_operand:XF 3 "memory_operand" ""))]
2455   "TARGET_80387 && reload_completed"
2456   [(set (match_dup 0)
2457         (float_extend:XF (match_dup 1)))]
2458   "")
2459
2460 (define_insn ""
2461   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
2462         (float_extend:XF
2463          (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
2464   "TARGET_80387 && (GET_CODE (operands[0]) != MEM
2465                     || GET_CODE (operands[1]) != MEM)"
2466   "*
2467 {
2468     output_float_extend (insn, operands);
2469     return \"\";
2470 }"
2471   [(set_attr "type" "fld,fpop")])
2472
2473 (define_expand "truncdfsf2"
2474   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2475                    (float_truncate:SF
2476                     (match_operand:DF 1 "register_operand" "")))
2477               (clobber (match_dup 2))])]
2478   "TARGET_80387"
2479   "
2480 {
2481   operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2482 }")
2483
2484 (define_insn ""
2485   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
2486         (float_truncate:SF
2487           (match_operand:DF 1 "register_operand" "0,f,f")))
2488    (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
2489   "TARGET_80387"
2490   "*
2491 {
2492   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2493   rtx xops[1];
2494
2495   xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2496
2497   if (stack_top_dies || STACK_REG_P (operands[0]))
2498     output_asm_insn (AS1 (fstp%z0,%0), xops);
2499   else
2500     output_asm_insn (AS1 (fst%z0,%0), xops);
2501
2502   if (STACK_REG_P (operands[0]))
2503     return AS1 (fld%z2,%2);
2504   else if (NON_STACK_REG_P (operands[0]))
2505     return AS2 (mov%L0,%2,%0);
2506
2507   return \"\";
2508 }"
2509   [(set_attr "type" "fpop")])
2510
2511 (define_split
2512   [(set (match_operand:SF 0 "register_operand" "")
2513         (float_truncate:SF (match_operand:DF 1 "register_operand" "")))
2514    (clobber (match_operand:SF 2 "memory_operand" ""))]
2515   "TARGET_80387 && reload_completed"
2516   [(set (match_dup 2)
2517         (float_truncate:SF (match_dup 1)))
2518    (set (match_dup 0)
2519         (match_dup 2))]
2520   "")
2521
2522 (define_split
2523   [(set (match_operand:SF 0 "memory_operand" "")
2524         (float_truncate:SF (match_operand:DF 1 "register_operand" "")))
2525    (clobber (match_operand:SF 2 "memory_operand" ""))]
2526   "TARGET_80387 && reload_completed"
2527   [(set (match_dup 0)
2528         (float_truncate:SF (match_dup 1)))]
2529   "")
2530
2531 ;; This cannot output into an f-reg because there is no way to be sure
2532 ;; of truncating in that case.
2533
2534 (define_insn ""
2535   [(set (match_operand:SF 0 "memory_operand" "=m")
2536         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
2537   "TARGET_80387"
2538   "*
2539 {
2540   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2541
2542   if (stack_top_dies)
2543     return AS1 (fstp%z0,%0);
2544   else
2545     return AS1 (fst%z0,%0);
2546 }"
2547   [(set_attr "type" "fpop")])
2548
2549 (define_expand "truncxfsf2"
2550   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2551                    (float_truncate:SF
2552                     (match_operand:XF 1 "register_operand" "")))
2553               (clobber (match_dup 2))])]
2554   "TARGET_80387"
2555   "
2556 {
2557   operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2558 }")
2559
2560 (define_insn ""
2561   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r")
2562         (float_truncate:SF
2563           (match_operand:XF 1 "register_operand" "0,f,f")))
2564    (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))]
2565   "TARGET_80387"
2566   "*
2567 {
2568   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2569   rtx xops[1];
2570
2571   xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2572
2573   if (stack_top_dies || STACK_REG_P (operands[0]))
2574     output_asm_insn (AS1 (fstp%z0,%0), xops);
2575   else
2576     output_asm_insn (AS1 (fst%z0,%0), xops);
2577
2578   if (STACK_REG_P (operands[0]))
2579     return AS1 (fld%z2,%2);
2580   else if (NON_STACK_REG_P (operands[0]))
2581     return AS2 (mov%L0,%2,%0);
2582
2583   return \"\";
2584 }"
2585   [(set_attr "type" "fpop")])
2586
2587 (define_split
2588   [(set (match_operand:SF 0 "register_operand" "")
2589         (float_truncate:SF (match_operand:XF 1 "register_operand" "")))
2590    (clobber (match_operand:SF 2 "memory_operand" ""))]
2591   "TARGET_80387 && reload_completed"
2592   [(set (match_dup 2)
2593         (float_truncate:SF (match_dup 1)))
2594    (set (match_dup 0)
2595         (match_dup 2))]
2596   "")
2597
2598 (define_split
2599   [(set (match_operand:SF 0 "memory_operand" "")
2600         (float_truncate:SF (match_operand:XF 1 "register_operand" "")))
2601    (clobber (match_operand:SF 2 "memory_operand" ""))]
2602   "TARGET_80387 && reload_completed"
2603   [(set (match_dup 0)
2604         (float_truncate:SF (match_dup 1)))]
2605   "")
2606
2607 (define_insn ""
2608   [(set (match_operand:SF 0 "memory_operand" "=m")
2609         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
2610   "TARGET_80387"
2611   "*
2612 {
2613   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2614
2615   if (stack_top_dies)
2616     return AS1 (fstp%z0,%0);
2617   else
2618     return AS1 (fst%z0,%0);
2619 }"
2620   [(set_attr "type" "fpop")])
2621
2622 (define_expand "truncxfdf2"
2623   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2624                    (float_truncate:DF
2625                     (match_operand:XF 1 "register_operand" "")))
2626               (clobber (match_dup 2))])]
2627   "TARGET_80387"
2628   "
2629 {
2630   operands[2] = (rtx) assign_386_stack_local (DFmode, 0);
2631 }")
2632
2633 (define_insn ""
2634   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r")
2635         (float_truncate:DF
2636           (match_operand:XF 1 "register_operand" "0,f,f")))
2637    (clobber (match_operand:DF 2 "memory_operand" "m,m,o"))]
2638   "TARGET_80387"
2639   "*
2640 {
2641   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2642   rtx xops[2];
2643
2644   xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2];
2645
2646   if (stack_top_dies || STACK_REG_P (operands[0]))
2647     output_asm_insn (AS1 (fstp%z0,%0), xops);
2648   else
2649     output_asm_insn (AS1 (fst%z0,%0), xops);
2650
2651   if (STACK_REG_P (operands[0]))
2652     return AS1 (fld%z2,%2);
2653   else if (NON_STACK_REG_P (operands[0]))
2654     {
2655     xops[0] = operands[0];
2656     xops[1] = operands[2];
2657     output_asm_insn (output_move_double (xops), xops);
2658     }
2659
2660   return \"\";
2661 }"
2662   [(set_attr "type" "fpop")])
2663
2664 (define_split
2665   [(set (match_operand:DF 0 "register_operand" "")
2666         (float_truncate:DF (match_operand:XF 1 "register_operand" "")))
2667    (clobber (match_operand:DF 2 "memory_operand" ""))]
2668   "TARGET_80387 && reload_completed"
2669   [(set (match_dup 2)
2670         (float_truncate:DF (match_dup 1)))
2671    (set (match_dup 0)
2672         (match_dup 2))]
2673   "")
2674
2675 (define_split
2676   [(set (match_operand:DF 0 "memory_operand" "")
2677         (float_truncate:DF (match_operand:XF 1 "register_operand" "")))
2678    (clobber (match_operand:DF 2 "memory_operand" ""))]
2679   "TARGET_80387 && reload_completed"
2680   [(set (match_dup 0)
2681         (float_truncate:DF (match_dup 1)))]
2682   "")
2683
2684 (define_insn ""
2685   [(set (match_operand:DF 0 "memory_operand" "=m")
2686         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
2687   "TARGET_80387"
2688   "*
2689 {
2690   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2691
2692   if (stack_top_dies)
2693     return AS1 (fstp%z0,%0);
2694   else
2695     return AS1 (fst%z0,%0);
2696 }"
2697   [(set_attr "type" "fpop")])
2698 \f
2699 ;; Conversions between floating point and fix point.
2700
2701 (define_expand "fix_truncsfsi2"
2702   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2703                    (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))
2704               (clobber (match_dup 2))
2705               (clobber (match_dup 3))
2706               (clobber (match_dup 4))
2707               (clobber (match_scratch:HI 5 ""))])]
2708   "TARGET_80387"
2709   "
2710 {
2711   operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2712   operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2713   operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2714 }")
2715
2716 (define_insn ""
2717   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
2718         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
2719    (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2720    (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2721    (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2722    (clobber (match_scratch:HI 5 "=&r,&r"))]
2723   "TARGET_80387"
2724   "* return output_fix_trunc (insn, operands);"
2725   [(set_attr "type" "fpop")])
2726
2727 (define_expand "fix_truncsfdi2"
2728   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2729                    (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
2730               (clobber (match_dup 1))
2731               (clobber (match_dup 2))
2732               (clobber (match_dup 3))
2733               (clobber (match_dup 4))
2734               (clobber (match_scratch:HI 5 ""))])]
2735   "TARGET_80387"
2736   "
2737 {
2738   operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2739   operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2740   operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2741   operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2742 }")
2743
2744 (define_insn ""
2745   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
2746         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
2747    (clobber (match_dup 1))
2748    (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2749    (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2750    (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2751    (clobber (match_scratch:HI 5 "=&r,&r"))]
2752   "TARGET_80387"
2753   "* return output_fix_trunc (insn, operands);"
2754   [(set_attr "type" "fpop")])
2755
2756 (define_expand "fix_truncdfsi2"
2757   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2758                    (fix:SI (fix:DF (match_operand:DF 1 "register_operand" ""))))
2759               (clobber (match_dup 2))
2760               (clobber (match_dup 3))
2761               (clobber (match_dup 4))
2762               (clobber (match_scratch:HI 5 ""))])]
2763   "TARGET_80387"
2764   "
2765 {
2766   operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2767   operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2768   operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2769 }")
2770
2771 (define_insn ""
2772   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
2773         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
2774    (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2775    (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2776    (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2777    (clobber (match_scratch:HI 5 "=&r,&r"))]
2778   "TARGET_80387"
2779   "* return output_fix_trunc (insn, operands);"
2780   [(set_attr "type" "fpop")])
2781
2782 (define_expand "fix_truncdfdi2"
2783   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2784                    (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
2785               (clobber (match_dup 1))
2786               (clobber (match_dup 2))
2787               (clobber (match_dup 3))
2788               (clobber (match_dup 4))
2789               (clobber (match_scratch:HI 5 ""))])]
2790   "TARGET_80387"
2791   "
2792 {
2793   operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2794   operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2795   operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2796   operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2797 }")
2798
2799 (define_insn ""
2800   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
2801         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
2802    (clobber (match_dup 1))
2803    (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2804    (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2805    (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2806    (clobber (match_scratch:HI 5 "=&r,&r"))]
2807   "TARGET_80387"
2808   "* return output_fix_trunc (insn, operands);"
2809   [(set_attr "type" "fpop")])
2810
2811 (define_expand "fix_truncxfsi2"
2812   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2813                    (fix:SI (fix:XF (match_operand:XF 1 "register_operand" ""))))
2814               (clobber (match_dup 2))
2815               (clobber (match_dup 3))
2816               (clobber (match_dup 4))
2817               (clobber (match_scratch:HI 5 ""))])]
2818   "TARGET_80387"
2819   "
2820 {
2821   operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2822   operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2823   operands[4] = (rtx) assign_386_stack_local (SImode, 0);
2824 }")
2825
2826 (define_insn ""
2827   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
2828         (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
2829    (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2830    (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2831    (clobber (match_operand:SI 4 "memory_operand" "m,m"))
2832    (clobber (match_scratch:HI 5 "=&r,&r"))]
2833   "TARGET_80387"
2834   "* return output_fix_trunc (insn, operands);"
2835   [(set_attr "type" "fpop")])
2836
2837 (define_expand "fix_truncxfdi2"
2838   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2839                    (fix:DI (fix:XF (match_operand:XF 1 "register_operand" ""))))
2840               (clobber (match_dup 1))
2841               (clobber (match_dup 2))
2842               (clobber (match_dup 3))
2843               (clobber (match_dup 4))
2844               (clobber (match_scratch:HI 5 ""))])]
2845   "TARGET_80387"
2846   "
2847 {
2848   operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2849   operands[2] = (rtx) assign_386_stack_local (HImode, 0);
2850   operands[3] = (rtx) assign_386_stack_local (HImode, 1);
2851   operands[4] = (rtx) assign_386_stack_local (DImode, 0);
2852 }")
2853
2854 (define_insn ""
2855   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
2856         (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
2857    (clobber (match_dup 1))
2858    (clobber (match_operand:HI 2 "memory_operand" "m,m"))
2859    (clobber (match_operand:HI 3 "memory_operand" "m,m"))
2860    (clobber (match_operand:DI 4 "memory_operand" "m,o"))
2861    (clobber (match_scratch:HI 5 "=&r,&r"))]
2862   "TARGET_80387"
2863   "* return output_fix_trunc (insn, operands);"
2864   [(set_attr "type" "fpop")])
2865 \f
2866 ;; Conversion between fixed point and floating point.
2867
2868 ;; ??? Possibly represent floatunssidf2 here in gcc2.
2869
2870 (define_expand "floatsisf2"
2871   [(parallel [(set (match_operand:SF 0 "register_operand" "")
2872                    (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))
2873               (clobber (match_dup 2))])]
2874   "TARGET_80387"
2875   "operands[2] = assign_386_stack_local (SImode, 0);")
2876
2877 (define_insn ""
2878   [(set (match_operand:SF 0 "register_operand" "=f,f")
2879         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
2880    (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
2881   "TARGET_80387"
2882   "#")
2883
2884 (define_split
2885   [(set (match_operand:SF 0 "register_operand" "")
2886         (float:SF (match_operand:SI 1 "memory_operand" "")))
2887    (clobber (match_operand:SI 2 "memory_operand" ""))]
2888   "TARGET_80387 && reload_completed"
2889   [(set (match_dup 0)
2890         (float:SF (match_dup 1)))]
2891   "")
2892
2893 (define_split
2894   [(set (match_operand:SF 0 "register_operand" "")
2895         (float:SF (match_operand:SI 1 "register_operand" "")))
2896    (clobber (match_operand:SI 2 "memory_operand" ""))]
2897   "TARGET_80387 && reload_completed"
2898   [(set (match_dup 2)
2899         (match_dup 1))
2900    (set (match_dup 0)
2901         (float:SF (match_dup 2)))]
2902   "")
2903
2904 (define_insn ""
2905   [(set (match_operand:SF 0 "register_operand" "=f")
2906         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
2907   "TARGET_80387"
2908   "* return AS1 (fild%z1,%1);"
2909   [(set_attr "type" "fpop")])
2910
2911 (define_expand "floathisf2"
2912   [(parallel [(set (match_operand:SF 0 "register_operand" "")
2913                    (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))
2914               (clobber (match_dup 2))])]
2915   "TARGET_80387"
2916   "operands[2] = assign_386_stack_local (HImode, 0);")
2917
2918 (define_insn ""
2919   [(set (match_operand:SF 0 "register_operand" "=f,f")
2920         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
2921    (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
2922   "TARGET_80387"
2923   "#")
2924
2925 (define_split
2926   [(set (match_operand:SF 0 "register_operand" "")
2927         (float:SF (match_operand:HI 1 "memory_operand" "")))
2928    (clobber (match_operand:HI 2 "memory_operand" ""))]
2929   "TARGET_80387 && reload_completed"
2930   [(set (match_dup 0)
2931         (float:SF (match_dup 1)))]
2932   "")
2933
2934 (define_split
2935   [(set (match_operand:SF 0 "register_operand" "")
2936         (float:SF (match_operand:HI 1 "register_operand" "")))
2937    (clobber (match_operand:HI 2 "memory_operand" ""))]
2938   "TARGET_80387 && reload_completed"
2939   [(set (match_dup 2)
2940         (match_dup 1))
2941    (set (match_dup 0)
2942         (float:SF (match_dup 2)))]
2943   "")
2944
2945 (define_insn ""
2946   [(set (match_operand:SF 0 "register_operand" "=f")
2947         (float:SF (match_operand:HI 1 "memory_operand" "m")))]
2948   "TARGET_80387"
2949   "* return AS1 (fild%z1,%1);"
2950   [(set_attr "type" "fpop")])
2951
2952 (define_expand "floatdisf2"
2953   [(parallel [(set (match_operand:SF 0 "register_operand" "")
2954                    (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))
2955               (clobber (match_dup 2))])]
2956   "TARGET_80387"
2957   "operands[2] = assign_386_stack_local (DImode, 0);")
2958
2959 (define_insn ""
2960   [(set (match_operand:SF 0 "register_operand" "=f,f")
2961         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
2962       (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
2963   "TARGET_80387"
2964   "#")
2965
2966 (define_split
2967   [(set (match_operand:SF 0 "register_operand" "")
2968         (float:SF (match_operand:DI 1 "memory_operand" "")))
2969    (clobber (match_operand:DI 2 "memory_operand" ""))]
2970   "TARGET_80387 && reload_completed"
2971   [(set (match_dup 0)
2972         (float:SF (match_dup 1)))]
2973   "")
2974
2975 (define_split
2976   [(set (match_operand:SF 0 "register_operand" "")
2977         (float:SF (match_operand:DI 1 "register_operand" "")))
2978    (clobber (match_operand:DI 2 "memory_operand" ""))]
2979   "TARGET_80387 && reload_completed"
2980   [(set (match_dup 2)
2981         (match_dup 1))
2982    (set (match_dup 0)
2983         (float:SF (match_dup 2)))]
2984   "")
2985
2986 (define_insn ""
2987   [(set (match_operand:SF 0 "register_operand" "=f")
2988         (float:SF (match_operand:DI 1 "memory_operand" "m")))]
2989   "TARGET_80387"
2990   "* return AS1 (fild%z1,%1);"
2991   [(set_attr "type" "fpop")])
2992
2993 (define_expand "floatsidf2"
2994   [(parallel [(set (match_operand:DF 0 "register_operand" "")
2995                    (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
2996               (clobber (match_dup 2))])]
2997   "TARGET_80387"
2998   "operands[2] = assign_386_stack_local (SImode, 0);")
2999
3000 (define_insn ""
3001   [(set (match_operand:DF 0 "register_operand" "=f,f")
3002         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
3003    (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
3004   "TARGET_80387"
3005   "#")
3006
3007 (define_split
3008   [(set (match_operand:DF 0 "register_operand" "")
3009         (float:DF (match_operand:SI 1 "memory_operand" "")))
3010    (clobber (match_operand:SI 2 "memory_operand" ""))]
3011   "TARGET_80387 && reload_completed"
3012   [(set (match_dup 0)
3013         (float:DF (match_dup 1)))]
3014   "")
3015
3016 (define_split
3017   [(set (match_operand:DF 0 "register_operand" "")
3018         (float:DF (match_operand:SI 1 "register_operand" "")))
3019    (clobber (match_operand:SI 2 "memory_operand" ""))]
3020   "TARGET_80387 && reload_completed"
3021   [(set (match_dup 2)
3022         (match_dup 1))
3023    (set (match_dup 0)
3024         (float:DF (match_dup 2)))]
3025   "")
3026
3027 (define_insn ""
3028   [(set (match_operand:DF 0 "register_operand" "=f")
3029         (float:DF (match_operand:SI 1 "memory_operand" "m")))]
3030   "TARGET_80387"
3031   "* return AS1 (fild%z1,%1);"
3032   [(set_attr "type" "fpop")])
3033
3034 (define_expand "floathidf2"
3035   [(parallel [(set (match_operand:DF 0 "register_operand" "")
3036                    (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))
3037               (clobber (match_dup 2))])]
3038   "TARGET_80387"
3039   "operands[2] = assign_386_stack_local (HImode, 0);")
3040
3041 (define_insn ""
3042   [(set (match_operand:DF 0 "register_operand" "=f,f")
3043         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
3044    (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
3045   "TARGET_80387"
3046   "#")
3047
3048 (define_split
3049   [(set (match_operand:DF 0 "register_operand" "")
3050         (float:DF (match_operand:HI 1 "memory_operand" "")))
3051    (clobber (match_operand:HI 2 "memory_operand" ""))]
3052   "TARGET_80387 && reload_completed"
3053   [(set (match_dup 0)
3054         (float:DF (match_dup 1)))]
3055   "")
3056
3057 (define_split
3058   [(set (match_operand:DF 0 "register_operand" "")
3059         (float:DF (match_operand:HI 1 "register_operand" "")))
3060    (clobber (match_operand:HI 2 "memory_operand" ""))]
3061   "TARGET_80387 && reload_completed"
3062   [(set (match_dup 2)
3063         (match_dup 1))
3064    (set (match_dup 0)
3065         (float:DF (match_dup 2)))]
3066   "")
3067
3068 (define_insn ""
3069   [(set (match_operand:DF 0 "register_operand" "=f")
3070         (float:DF (match_operand:HI 1 "memory_operand" "m")))]
3071   "TARGET_80387"
3072   "* return AS1 (fild%z1,%1);"
3073   [(set_attr "type" "fpop")])
3074
3075 (define_expand "floatdidf2"
3076   [(parallel [(set (match_operand:DF 0 "register_operand" "")
3077                    (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))
3078               (clobber (match_dup 2))])]
3079   "TARGET_80387"
3080   "operands[2] = assign_386_stack_local (DImode, 0);")
3081
3082 (define_insn ""
3083   [(set (match_operand:DF 0 "register_operand" "=f,f")
3084         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
3085    (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
3086   "TARGET_80387"
3087   "#")
3088
3089 (define_split
3090   [(set (match_operand:DF 0 "register_operand" "")
3091         (float:DF (match_operand:DI 1 "memory_operand" "")))
3092    (clobber (match_operand:DI 2 "memory_operand" ""))]
3093   "TARGET_80387 && reload_completed"
3094   [(set (match_dup 0)
3095         (float:DF (match_dup 1)))]
3096   "")
3097
3098 (define_split
3099   [(set (match_operand:DF 0 "register_operand" "")
3100         (float:DF (match_operand:DI 1 "register_operand" "")))
3101    (clobber (match_operand:DI 2 "memory_operand" ""))]
3102   "TARGET_80387 && reload_completed"
3103   [(set (match_dup 2)
3104         (match_dup 1))
3105    (set (match_dup 0)
3106         (float:DF (match_dup 2)))]
3107   "")
3108
3109 (define_insn ""
3110   [(set (match_operand:DF 0 "register_operand" "=f")
3111         (float:DF (match_operand:DI 1 "memory_operand" "m")))]
3112   "TARGET_80387"
3113   "* return AS1 (fild%z1,%1);"
3114   [(set_attr "type" "fpop")])
3115
3116 (define_expand "floatsixf2"
3117   [(parallel [(set (match_operand:XF 0 "register_operand" "")
3118                    (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))
3119               (clobber (match_dup 2))])]
3120   "TARGET_80387"
3121   "operands[2] = assign_386_stack_local (SImode, 0);")
3122
3123 (define_insn ""
3124   [(set (match_operand:XF 0 "register_operand" "=f,f")
3125         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!r")))
3126    (clobber (match_operand:SI 2 "memory_operand" "m,m"))]
3127   "TARGET_80387"
3128   "#")
3129
3130 (define_split
3131   [(set (match_operand:XF 0 "register_operand" "")
3132         (float:XF (match_operand:SI 1 "memory_operand" "")))
3133    (clobber (match_operand:SI 2 "memory_operand" ""))]
3134   "TARGET_80387 && reload_completed"
3135   [(set (match_dup 0)
3136         (float:XF (match_dup 1)))]
3137   "")
3138
3139 (define_split
3140   [(set (match_operand:XF 0 "register_operand" "")
3141         (float:XF (match_operand:SI 1 "register_operand" "")))
3142    (clobber (match_operand:SI 2 "memory_operand" ""))]
3143   "TARGET_80387 && reload_completed"
3144   [(set (match_dup 2)
3145         (match_dup 1))
3146    (set (match_dup 0)
3147         (float:XF (match_dup 2)))]
3148   "")
3149
3150 (define_insn ""
3151   [(set (match_operand:XF 0 "register_operand" "=f")
3152         (float:XF (match_operand:SI 1 "memory_operand" "m")))]
3153   "TARGET_80387"
3154   "* return AS1 (fild%z1,%1);"
3155   [(set_attr "type" "fpop")])
3156
3157 (define_expand "floathixf2"
3158   [(parallel [(set (match_operand:XF 0 "register_operand" "")
3159                    (float:XF (match_operand:HI 1 "nonimmediate_operand" "")))
3160               (clobber (match_dup 2))])]
3161   "TARGET_80387"
3162   "operands[2] = assign_386_stack_local (HImode, 0);")
3163
3164 (define_insn ""
3165   [(set (match_operand:XF 0 "register_operand" "=f,f")
3166         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,!r")))
3167    (clobber (match_operand:HI 2 "memory_operand" "m,m"))]
3168   "TARGET_80387"
3169   "#")
3170
3171 (define_split
3172   [(set (match_operand:XF 0 "register_operand" "")
3173         (float:XF (match_operand:HI 1 "memory_operand" "")))
3174    (clobber (match_operand:HI 2 "memory_operand" ""))]
3175   "TARGET_80387 && reload_completed"
3176   [(set (match_dup 0)
3177         (float:XF (match_dup 1)))]
3178   "")
3179
3180 (define_split
3181   [(set (match_operand:XF 0 "register_operand" "")
3182         (float:XF (match_operand:HI 1 "register_operand" "")))
3183    (clobber (match_operand:HI 2 "memory_operand" ""))]
3184   "TARGET_80387 && reload_completed"
3185   [(set (match_dup 2)
3186         (match_dup 1))
3187    (set (match_dup 0)
3188         (float:XF (match_dup 2)))]
3189   "")
3190
3191 (define_insn ""
3192   [(set (match_operand:XF 0 "register_operand" "=f")
3193         (float:XF (match_operand:HI 1 "memory_operand" "m")))]
3194   "TARGET_80387"
3195   "* return AS1 (fild%z1,%1);"
3196   [(set_attr "type" "fpop")])
3197
3198 (define_expand "floatdixf2"
3199   [(parallel [(set (match_operand:XF 0 "register_operand" "")
3200                    (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))
3201               (clobber (match_dup 2))])]
3202   "TARGET_80387"
3203   "operands[2] = assign_386_stack_local (DImode, 0);")
3204
3205 (define_insn ""
3206   [(set (match_operand:XF 0 "register_operand" "=f,f")
3207         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,!r")))
3208    (clobber (match_operand:DI 2 "memory_operand" "m,o"))]
3209   "TARGET_80387"
3210   "#")
3211
3212 (define_split
3213   [(set (match_operand:XF 0 "register_operand" "")
3214         (float:XF (match_operand:DI 1 "memory_operand" "")))
3215    (clobber (match_operand:DI 2 "memory_operand" ""))]
3216   "TARGET_80387 && reload_completed"
3217   [(set (match_dup 0)
3218         (float:XF (match_dup 1)))]
3219   "")
3220
3221 (define_split
3222   [(set (match_operand:XF 0 "register_operand" "")
3223         (float:XF (match_operand:DI 1 "register_operand" "")))
3224    (clobber (match_operand:DI 2 "memory_operand" ""))]
3225   "TARGET_80387 && reload_completed"
3226   [(set (match_dup 2)
3227         (match_dup 1))
3228    (set (match_dup 0)
3229         (float:XF (match_dup 2)))]
3230   "")
3231
3232 (define_insn ""
3233   [(set (match_operand:XF 0 "register_operand" "=f")
3234         (float:XF (match_operand:DI 1 "memory_operand" "m")))]
3235   "TARGET_80387"
3236   "* return AS1 (fild%z1,%1);"
3237   [(set_attr "type" "fpop")])
3238 \f
3239 ;;- add instructions
3240
3241 (define_insn "*addsidi3_1"
3242   [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
3243         (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
3244                  (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
3245    (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))]
3246   ""
3247   "*
3248 {
3249   rtx low[3], high[3], xops[7];
3250
3251   CC_STATUS_INIT;
3252
3253   split_di (operands, 2, low, high);
3254   high[2] = const0_rtx;
3255   low[2]  = operands[2];
3256
3257   if (!rtx_equal_p (operands[0], operands[1]))
3258     {
3259       xops[0] = high[0];
3260       xops[1] = low[0];
3261       xops[2] = high[1];
3262       xops[3] = low[1];
3263
3264       if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3265         {
3266           output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3267           output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3268         }
3269       else
3270         {
3271           xops[4] = high[2];
3272           xops[5] = low[2];
3273           xops[6] = operands[3];
3274           output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3275           output_asm_insn (AS2 (add%L6,%5,%6), xops);
3276           output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3277           output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3278           output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3279           output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3280           RET;
3281         }
3282     }
3283
3284   output_asm_insn (AS2 (add%L0,%2,%0), low);
3285   output_asm_insn (AS2 (adc%L0,%2,%0), high);
3286   cc_status.value1 = high[0];
3287   cc_status.flags = CC_NO_OVERFLOW;
3288   RET;
3289 }"
3290   [(set_attr "type" "binary")])
3291
3292 (define_insn "addsidi3_2"
3293   [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
3294         (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r"))
3295                  (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o")))
3296    (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))]
3297   ""
3298   "*
3299 {
3300   rtx low[3], high[3], xops[7];
3301
3302   CC_STATUS_INIT;
3303
3304   split_di (operands, 2, low, high);
3305   high[2] = const0_rtx;
3306   low[2]  = operands[2];
3307
3308   if (!rtx_equal_p (operands[0], operands[1]))
3309     {
3310       xops[0] = high[0];
3311       xops[1] = low[0];
3312       xops[2] = high[1];
3313       xops[3] = low[1];
3314
3315       if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3316         {
3317           if (rtx_equal_p (low[0], operands[2]))
3318             {
3319               output_asm_insn (AS2 (mov%L0,%2,%0), high);
3320               output_asm_insn (AS2 (add%L0,%1,%0), low);
3321               output_asm_insn (AS2 (adc%L0,%1,%0), high);
3322               RET;
3323             }
3324           if (rtx_equal_p (high[0], operands[2]))
3325             {
3326               if (GET_CODE (operands[0]) != MEM)
3327                 {
3328                   output_asm_insn (AS2 (mov%L0,%2,%0), low);
3329                   output_asm_insn (AS2 (mov%L0,%2,%0), high);
3330                   output_asm_insn (AS2 (add%L0,%1,%0), low);
3331                   output_asm_insn (AS2 (adc%L0,%1,%0), high);
3332                 }
3333               else
3334                 {
3335                   /* It's too late to ask for a scratch now - but this
3336                      will probably not happen too often.  */
3337                   output_asm_insn (AS2 (add%L1,%2,%1), low);
3338                   output_asm_insn (AS2 (mov%L0,%1,%0), low);
3339                   output_asm_insn (AS2 (mov%L1,%2,%1), low);
3340                   output_asm_insn (AS2 (mov%L0,%2,%0), high);
3341                   output_asm_insn (AS2 (adc%L0,%1,%0), high);
3342                   output_asm_insn (AS2 (sub%L1,%0,%1), low);
3343                   output_asm_insn (AS1 (neg%L1,%1), low);
3344                 }
3345               RET;
3346             }
3347           output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3348           output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3349         }
3350       else
3351         {
3352           xops[4] = high[2];
3353           xops[5] = low[2];
3354           xops[6] = operands[3];
3355           output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3356           output_asm_insn (AS2 (add%L6,%5,%6), xops);
3357           output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3358           output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3359           output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3360           output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3361           RET;
3362         }
3363     }
3364
3365   output_asm_insn (AS2 (add%L0,%2,%0), low);
3366   output_asm_insn (AS2 (adc%L0,%2,%0), high);
3367   cc_status.value1 = high[0];
3368   cc_status.flags = CC_NO_OVERFLOW;
3369   RET;
3370 }"
3371   [(set_attr "type" "binary")])
3372
3373 (define_insn "adddi3"
3374   [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
3375         (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
3376                  (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
3377    (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
3378   ""
3379   "*
3380 {
3381   rtx low[3], high[3], xops[7], temp;
3382
3383   CC_STATUS_INIT;
3384
3385   if (rtx_equal_p (operands[0], operands[2]))
3386     {
3387       temp = operands[1];
3388       operands[1] = operands[2];
3389       operands[2] = temp;
3390     }
3391
3392   split_di (operands, 3, low, high);
3393   if (!rtx_equal_p (operands[0], operands[1]))
3394     {
3395       xops[0] = high[0];
3396       xops[1] = low[0];
3397       xops[2] = high[1];
3398       xops[3] = low[1];
3399
3400       if (GET_CODE (operands[0]) != MEM)
3401         {
3402           output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3403           output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3404         }
3405       else
3406         {
3407           xops[4] = high[2];
3408           xops[5] = low[2];
3409           xops[6] = operands[3];
3410           output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3411           output_asm_insn (AS2 (add%L6,%5,%6), xops);
3412           output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3413           output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3414           output_asm_insn (AS2 (adc%L6,%4,%6), xops);
3415           output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3416           RET;
3417         }
3418     }
3419
3420   cc_status.value1 = high[0];
3421   cc_status.flags = CC_NO_OVERFLOW;
3422
3423   if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
3424     {
3425       xops[0] = high[0];
3426       xops[1] = low[0];
3427       xops[2] = high[2];
3428       xops[3] = low[2];
3429       xops[4] = operands[3];
3430
3431       output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3432       output_asm_insn (AS2 (add%L1,%4,%1), xops);
3433       output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3434       output_asm_insn (AS2 (adc%L0,%4,%0), xops);
3435     }
3436
3437   else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
3438     {
3439       output_asm_insn (AS2 (add%L0,%2,%0), low);
3440       output_asm_insn (AS2 (adc%L0,%2,%0), high);
3441     }
3442
3443   else
3444     output_asm_insn (AS2 (add%L0,%2,%0), high);
3445
3446   RET;
3447 }"
3448   [(set_attr "type" "binary")])
3449
3450 ;; On a 486, it is faster to do movl/addl than to do a single leal if
3451 ;; operands[1] and operands[2] are both registers.
3452
3453 (define_expand "addsi3"
3454   [(set (match_operand:SI 0 "nonimmediate_operand" "")
3455         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3456                  (match_operand:SI 2 "general_operand" "")))]
3457   ""
3458   "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);")
3459
3460 (define_insn ""
3461   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
3462         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
3463                  (match_operand:SI 2 "general_operand" "rmi,ri,ri")))]
3464   "ix86_binary_operator_ok (PLUS, SImode, operands)"
3465   "*
3466 {
3467   if (REG_P (operands[0]) && REG_P (operands[1])
3468       && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3469       && REGNO (operands[0]) != REGNO (operands[1]))
3470     {
3471       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3472         return AS2 (add%L0,%1,%0);
3473
3474       if (operands[2] == stack_pointer_rtx)
3475         {
3476           rtx temp;
3477
3478           temp = operands[1];
3479           operands[1] = operands[2];
3480           operands[2] = temp;
3481         }
3482
3483       if (operands[2] != stack_pointer_rtx)
3484         {
3485           CC_STATUS_INIT;
3486           operands[1] = SET_SRC (PATTERN (insn));
3487           return AS2 (lea%L0,%a1,%0);
3488         }
3489     }
3490
3491   if (!rtx_equal_p (operands[0], operands[1]))
3492     output_asm_insn (AS2 (mov%L0,%1,%0), operands);
3493
3494   if (operands[2] == const1_rtx)
3495     return AS1 (inc%L0,%0);
3496
3497   if (operands[2] == constm1_rtx)
3498     return AS1 (dec%L0,%0);
3499
3500   /* subl $-128,%ebx is smaller than addl $128,%ebx. */
3501   if (GET_CODE (operands[2]) == CONST_INT
3502       && INTVAL (operands[2]) == 128)
3503     {
3504       /* This doesn't compute the carry bit in the same way
3505        * as add%L0, but we use inc and dec above and they
3506        * don't set the carry bit at all.  If inc/dec don't need
3507        * a CC_STATUS_INIT, this doesn't either... */
3508       operands[2] = GEN_INT (-128);
3509       return AS2 (sub%L0,%2,%0);
3510     }
3511
3512   return AS2 (add%L0,%2,%0);
3513 }"
3514   [(set_attr "type" "binary")])
3515
3516 ;; addsi3 is faster, so put this after.
3517
3518 (define_insn "movsi_lea"
3519   [(set (match_operand:SI 0 "register_operand" "=r")
3520         (match_operand:QI 1 "address_operand" "p"))]
3521   ""
3522   "*
3523 {
3524   /* Adding a constant to a register is faster with an add.  */
3525   /* ??? can this ever happen? */
3526   if (GET_CODE (operands[1]) == PLUS
3527       && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
3528       && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
3529     {
3530       operands[1] = XEXP (operands[1], 1);
3531
3532       if (operands[1] == const1_rtx)
3533         return AS1 (inc%L0,%0);
3534
3535       if (operands[1] == constm1_rtx)
3536         return AS1 (dec%L0,%0);
3537
3538       return AS2 (add%L0,%1,%0);
3539     }
3540
3541   CC_STATUS_INIT;
3542   return AS2 (lea%L0,%a1,%0);
3543 }"
3544   [(set_attr "type" "lea")])
3545
3546 ;; ??? `lea' here, for three operand add?  If leaw is used, only %bx,
3547 ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
3548 ;; able to handle the operand.  But leal always works?
3549
3550 (define_expand "addhi3"
3551   [(set (match_operand:HI 0 "general_operand" "")
3552         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3553                  (match_operand:HI 2 "general_operand" "")))]
3554   ""
3555   "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
3556
3557 (define_insn ""
3558   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,?r")
3559         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
3560                  (match_operand:HI 2 "general_operand" "ri,rm,ri")))]
3561   "ix86_binary_operator_ok (PLUS, HImode, operands)"
3562   "*
3563 {
3564   if (REG_P (operands[0]) && REG_P (operands[1])
3565       && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3566       && REGNO (operands[0]) != REGNO (operands[1]))
3567     {
3568       if (operands[2] == stack_pointer_rtx) 
3569         abort ();
3570
3571       CC_STATUS_INIT;
3572       operands[1]
3573         = gen_rtx_PLUS (SImode,
3574                         gen_rtx_REG (SImode, REGNO (operands[1])),
3575                         (! REG_P (operands[2])
3576                          ? operands[2]
3577                          : gen_rtx_REG (SImode, REGNO (operands[2]))));
3578       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
3579       return AS2 (lea%L0,%a1,%0);
3580     }
3581
3582   /* ??? what about offsettable memory references? */
3583   if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
3584       && QI_REG_P (operands[0])
3585       && GET_CODE (operands[2]) == CONST_INT
3586       && (INTVAL (operands[2]) & 0xff) == 0
3587       && i386_cc_probably_useless_p (insn))
3588     {
3589       int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
3590       CC_STATUS_INIT;
3591
3592       if (byteval == 1)
3593         return AS1 (inc%B0,%h0);
3594       else if (byteval == 255)
3595         return AS1 (dec%B0,%h0);
3596
3597       operands[2] = GEN_INT (byteval);
3598       return AS2 (add%B0,%2,%h0);
3599     }
3600
3601   /* Use a 32-bit operation when possible, to avoid the prefix penalty. */
3602   if (REG_P (operands[0])
3603       && i386_aligned_p (operands[2])
3604       && i386_cc_probably_useless_p (insn))
3605     {
3606       CC_STATUS_INIT;
3607
3608       if (GET_CODE (operands[2]) == CONST_INT)
3609         {
3610           HOST_WIDE_INT intval = 0xffff & INTVAL (operands[2]);
3611
3612           if (intval == 1)
3613             return AS1 (inc%L0,%k0);
3614
3615           if (intval == 0xffff)
3616             return AS1 (dec%L0,%k0);
3617
3618           operands[2] = i386_sext16_if_const (operands[2]);
3619         }
3620       return AS2 (add%L0,%k2,%k0);
3621     }
3622
3623   if (operands[2] == const1_rtx)
3624     return AS1 (inc%W0,%0);
3625
3626   if (operands[2] == constm1_rtx
3627       || (GET_CODE (operands[2]) == CONST_INT
3628           && INTVAL (operands[2]) == 65535))
3629     return AS1 (dec%W0,%0);
3630
3631   return AS2 (add%W0,%2,%0);
3632 }"
3633   [(set_attr "type" "binary")])
3634
3635 (define_expand "addqi3"
3636   [(set (match_operand:QI 0 "general_operand" "")
3637         (plus:QI (match_operand:QI 1 "general_operand" "")
3638                  (match_operand:QI 2 "general_operand" "")))]
3639   ""
3640   "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
3641
3642 (define_insn ""
3643   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,?q")
3644         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q")
3645                  (match_operand:QI 2 "general_operand" "qn,qmn,qn")))]
3646   "ix86_binary_operator_ok (PLUS, QImode, operands)"
3647   "*
3648 {
3649   if (REG_P (operands[0]) && REG_P (operands[1])
3650       && (REG_P (operands[2]) || CONSTANT_P (operands[2]))
3651       && (REGNO (operands[0]) != REGNO (operands[1])
3652           || NON_QI_REG_P (operands[1])
3653           || (REG_P (operands[2]) && NON_QI_REG_P (operands[2]))))
3654     {
3655       if (operands[2] == stack_pointer_rtx) 
3656         abort ();
3657
3658       CC_STATUS_INIT;
3659       operands[1]
3660         = gen_rtx_PLUS (SImode,
3661                         gen_rtx_REG (SImode, REGNO (operands[1])),
3662                         (! REG_P (operands[2])
3663                          ? operands[2]
3664                          : gen_rtx_REG (SImode, REGNO (operands[2]))));
3665       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
3666       return AS2 (lea%L0,%a1,%0);
3667     }
3668   if (operands[2] == const1_rtx)
3669     return AS1 (inc%B0,%0);
3670
3671   if (operands[2] == constm1_rtx
3672       || (GET_CODE (operands[2]) == CONST_INT
3673           && INTVAL (operands[2]) == 255))
3674     return AS1 (dec%B0,%0);
3675
3676   return AS2 (add%B0,%2,%0);
3677 }"
3678   [(set_attr "type" "binary")])
3679
3680 ;Lennart Augustsson <augustss@cs.chalmers.se>
3681 ;says this pattern just makes slower code:
3682 ;       pushl   %ebp
3683 ;       addl    $-80,(%esp)
3684 ;instead of
3685 ;       leal    -80(%ebp),%eax
3686 ;       pushl   %eax
3687 ;
3688 ;(define_insn ""
3689 ;  [(set (match_operand:SI 0 "push_operand" "=<")
3690 ;       (plus:SI (match_operand:SI 1 "register_operand" "%r")
3691 ;                (match_operand:SI 2 "nonmemory_operand" "ri")))]
3692 ;  ""
3693 ;  "*
3694 ;{
3695 ;  rtx xops[4];
3696 ;  xops[0] = operands[0];
3697 ;  xops[1] = operands[1];
3698 ;  xops[2] = operands[2];
3699 ;  xops[3] = gen_rtx_MEM (SImode, stack_pointer_rtx);
3700 ;  output_asm_insn (\"push%z1 %1\", xops);
3701 ;  output_asm_insn (AS2 (add%z3,%2,%3), xops);
3702 ;  RET;
3703 ;}")
3704
3705 ;; The patterns that match these are at the end of this file.
3706
3707 (define_expand "addxf3"
3708   [(set (match_operand:XF 0 "register_operand" "")
3709         (plus:XF (match_operand:XF 1 "register_operand" "")
3710                  (match_operand:XF 2 "register_operand" "")))]
3711   "TARGET_80387"
3712   "")
3713
3714 (define_expand "adddf3"
3715   [(set (match_operand:DF 0 "register_operand" "")
3716         (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3717                  (match_operand:DF 2 "nonimmediate_operand" "")))]
3718   "TARGET_80387"
3719   "")
3720
3721 (define_expand "addsf3"
3722   [(set (match_operand:SF 0 "register_operand" "")
3723         (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3724                  (match_operand:SF 2 "nonimmediate_operand" "")))]
3725   "TARGET_80387"
3726   "")
3727 \f
3728 ;;- subtract instructions
3729
3730 (define_insn "subsidi3"
3731   [(set (match_operand:DI 0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o")
3732         (minus:DI (match_operand:DI 1 "general_operand" "0iF,0,roiF,roiF,riF,o,o")
3733                   (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,ri,i,r"))))
3734    (clobber (match_scratch:SI 3 "=X,X,X,X,X,&r,&r"))]
3735   ""
3736   "*
3737 {
3738   rtx low[3], high[3], xops[7];
3739
3740   CC_STATUS_INIT;
3741
3742   split_di (operands, 2, low, high);
3743   high[2] = const0_rtx;
3744   low[2]  = operands[2];
3745
3746   if (!rtx_equal_p (operands[0], operands[1]))
3747     {
3748       xops[0] = high[0];
3749       xops[1] = low[0];
3750       xops[2] = high[1];
3751       xops[3] = low[1];
3752
3753       if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3754         {
3755           output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3756           output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3757         }
3758       else
3759         {
3760           xops[4] = high[2];
3761           xops[5] = low[2];
3762           xops[6] = operands[3];
3763           output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3764           output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3765           output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3766           output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3767           output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3768           output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3769           RET;
3770         }
3771     }
3772
3773   output_asm_insn (AS2 (sub%L0,%2,%0), low);
3774   output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3775   cc_status.value1 = high[0];
3776   cc_status.flags = CC_NO_OVERFLOW;
3777
3778   RET;
3779 }"
3780   [(set_attr "type" "binary")])
3781
3782 (define_insn "subdi3"
3783   [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
3784         (minus:DI (match_operand:DI 1 "general_operand" "0,0,0iF,or,roiF,roiF")
3785                   (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
3786    (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
3787   ""
3788   "*
3789 {
3790   rtx low[3], high[3], xops[7];
3791
3792   CC_STATUS_INIT;
3793
3794   split_di (operands, 3, low, high);
3795
3796   if (!rtx_equal_p (operands[0], operands[1]))
3797     {
3798       xops[0] = high[0];
3799       xops[1] = low[0];
3800       xops[2] = high[1];
3801       xops[3] = low[1];
3802
3803       if (GET_CODE (operands[0]) != MEM)
3804         {
3805           output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3806           output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3807         }
3808       else
3809         {
3810           xops[4] = high[2];
3811           xops[5] = low[2];
3812           xops[6] = operands[3];
3813           output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3814           output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3815           output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3816           output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3817           output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3818           output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3819           RET;
3820         }
3821     }
3822
3823   cc_status.value1 = high[0];
3824   cc_status.flags = CC_NO_OVERFLOW;
3825
3826   if (GET_CODE (operands[3]) == REG)
3827     {
3828       xops[0] = high[0];
3829       xops[1] = low[0];
3830       xops[2] = high[2];
3831       xops[3] = low[2];
3832       xops[4] = operands[3];
3833
3834       output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3835       output_asm_insn (AS2 (sub%L1,%4,%1), xops);
3836       output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3837       output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
3838     }
3839
3840   else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
3841     {
3842       output_asm_insn (AS2 (sub%L0,%2,%0), low);
3843       output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3844     }
3845
3846   else
3847       output_asm_insn (AS2 (sub%L0,%2,%0), high);
3848
3849
3850   RET;
3851 }"
3852   [(set_attr "type" "binary")])
3853
3854 (define_expand "subsi3"
3855   [(set (match_operand:SI 0 "nonimmediate_operand" "")
3856         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3857                   (match_operand:SI 2 "general_operand" "")))]
3858   ""
3859   "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);")
3860
3861 (define_insn ""
3862   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3863         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3864                   (match_operand:SI 2 "general_operand" "ri,rm")))]
3865   "ix86_binary_operator_ok (MINUS, SImode, operands)"
3866   "* return AS2 (sub%L0,%2,%0);"
3867   [(set_attr "type" "binary")])
3868
3869 (define_expand "subhi3"
3870   [(set (match_operand:HI 0 "general_operand" "")
3871         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3872                   (match_operand:HI 2 "general_operand" "")))]
3873   ""
3874   "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);")
3875
3876 (define_insn ""
3877   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3878         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
3879                   (match_operand:HI 2 "general_operand" "ri,rm")))]
3880   "ix86_binary_operator_ok (MINUS, HImode, operands)"
3881   "*
3882 {
3883   if (REG_P (operands[0])
3884       && i386_aligned_p (operands[2])
3885       && i386_cc_probably_useless_p (insn))
3886     {
3887       CC_STATUS_INIT;
3888       operands[2] = i386_sext16_if_const (operands[2]);
3889       return AS2 (sub%L0,%k2,%k0);
3890     }
3891  return AS2 (sub%W0,%2,%0);
3892 }"
3893   [(set_attr "type" "binary")])
3894
3895 (define_expand "subqi3"
3896   [(set (match_operand:QI 0 "general_operand" "")
3897         (minus:QI (match_operand:QI 1 "general_operand" "")
3898                   (match_operand:QI 2 "general_operand" "")))]
3899   ""
3900   "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);")
3901
3902 (define_insn ""
3903   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3904         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
3905                   (match_operand:QI 2 "general_operand" "qn,qmn")))]
3906   "ix86_binary_operator_ok (MINUS, QImode, operands)"
3907   "* return AS2 (sub%B0,%2,%0);"
3908   [(set_attr "type" "binary")])
3909
3910 ;; The patterns that match these are at the end of this file.
3911
3912 (define_expand "subxf3"
3913   [(set (match_operand:XF 0 "register_operand" "")
3914         (minus:XF (match_operand:XF 1 "register_operand" "")
3915                   (match_operand:XF 2 "register_operand" "")))]
3916   "TARGET_80387"
3917   "")
3918
3919 (define_expand "subdf3"
3920   [(set (match_operand:DF 0 "register_operand" "")
3921         (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3922                   (match_operand:DF 2 "nonimmediate_operand" "")))]
3923   "TARGET_80387"
3924   "")
3925
3926 (define_expand "subsf3"
3927   [(set (match_operand:SF 0 "register_operand" "")
3928         (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3929                   (match_operand:SF 2 "nonimmediate_operand" "")))]
3930   "TARGET_80387"
3931   "")
3932 \f
3933 ;;- multiply instructions
3934
3935 ;(define_insn "mulqi3"
3936 ;  [(set (match_operand:QI 0 "register_operand" "=a")
3937 ;       (mult:QI (match_operand:QI 1 "register_operand" "%0")
3938 ;                (match_operand:QI 2 "nonimmediate_operand" "qm")))]
3939 ;  ""
3940 ;  "imul%B0 %2,%0")
3941
3942 (define_insn "mulhi3"
3943   [(set (match_operand:HI 0 "register_operand" "=r,r")
3944         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%0,rm")
3945                  (match_operand:HI 2 "general_operand" "g,i")))]
3946   ""
3947   "*
3948 {
3949   if (GET_CODE (operands[1]) == REG
3950       && REGNO (operands[1]) == REGNO (operands[0])
3951       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3952     /* Assembler has weird restrictions.  */
3953     return AS2 (imul%W0,%2,%0);
3954   return AS3 (imul%W0,%2,%1,%0);
3955 }"
3956   [(set_attr "type" "imul")])
3957
3958 (define_insn "mulsi3"
3959   [(set (match_operand:SI 0 "register_operand" "=r,r")
3960         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
3961                  (match_operand:SI 2 "general_operand" "g,i")))]
3962   ""
3963   "*
3964 {
3965   if (GET_CODE (operands[1]) == REG
3966       && REGNO (operands[1]) == REGNO (operands[0])
3967       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3968     /* Assembler has weird restrictions.  */
3969     return AS2 (imul%L0,%2,%0);
3970   return AS3 (imul%L0,%2,%1,%0);
3971 }"
3972   [(set_attr "type" "imul")])
3973
3974 (define_insn "umulqihi3"
3975   [(set (match_operand:HI 0 "register_operand" "=a")
3976         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3977                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3978   ""
3979   "mul%B0 %2"
3980   [(set_attr "type" "imul")])
3981
3982 (define_insn "mulqihi3"
3983   [(set (match_operand:HI 0 "register_operand" "=a")
3984         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
3985                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3986   ""
3987   "imul%B0 %2"
3988   [(set_attr "type" "imul")])
3989
3990 (define_insn "umulsidi3"
3991   [(set (match_operand:DI 0 "register_operand" "=A")
3992         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3993                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
3994   "TARGET_WIDE_MULTIPLY"
3995   "mul%L0 %2"
3996   [(set_attr "type" "imul")])
3997
3998 (define_insn "mulsidi3"
3999   [(set (match_operand:DI 0 "register_operand" "=A")
4000         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
4001                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
4002   "TARGET_WIDE_MULTIPLY"
4003   "imul%L0 %2"
4004   [(set_attr "type" "imul")])
4005
4006 (define_insn "umulsi3_highpart"
4007   [(set (match_operand:SI 0 "register_operand" "=d")
4008         (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
4009                                            (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
4010                                   (const_int 32))))
4011    (clobber (match_scratch:SI 3 "=a"))]
4012   "TARGET_WIDE_MULTIPLY"
4013   "mul%L0 %2"
4014   [(set_attr "type" "imul")])
4015
4016 (define_insn "smulsi3_highpart"
4017   [(set (match_operand:SI 0 "register_operand" "=d")
4018         (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
4019                                            (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
4020                                   (const_int 32))))
4021    (clobber (match_scratch:SI 3 "=a"))]
4022   "TARGET_WIDE_MULTIPLY"
4023   "imul%L0 %2"
4024   [(set_attr "type" "imul")])
4025
4026 ;; The patterns that match these are at the end of this file.
4027
4028 (define_expand "mulxf3"
4029   [(set (match_operand:XF 0 "register_operand" "")
4030         (mult:XF (match_operand:XF 1 "register_operand" "")
4031                  (match_operand:XF 2 "register_operand" "")))]
4032   "TARGET_80387"
4033   "")
4034
4035 (define_expand "muldf3"
4036   [(set (match_operand:DF 0 "register_operand" "")
4037         (mult:DF (match_operand:DF 1 "register_operand" "")
4038                  (match_operand:DF 2 "nonimmediate_operand" "")))]
4039   "TARGET_80387"
4040   "")
4041
4042 (define_expand "mulsf3"
4043   [(set (match_operand:SF 0 "register_operand" "")
4044         (mult:SF (match_operand:SF 1 "register_operand" "")
4045                  (match_operand:SF 2 "nonimmediate_operand" "")))]
4046   "TARGET_80387"
4047   "")
4048 \f
4049 ;;- divide instructions
4050
4051 (define_insn "divqi3"
4052   [(set (match_operand:QI 0 "register_operand" "=a")
4053         (div:QI (match_operand:HI 1 "register_operand" "0")
4054                 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
4055   ""
4056   "idiv%B0 %2")
4057
4058 (define_insn "udivqi3"
4059   [(set (match_operand:QI 0 "register_operand" "=a")
4060         (udiv:QI (match_operand:HI 1 "register_operand" "0")
4061                  (match_operand:QI 2 "nonimmediate_operand" "qm")))]
4062   ""
4063   "div%B0 %2"
4064   [(set_attr "type" "idiv")])
4065
4066 ;; The patterns that match these are at the end of this file.
4067
4068 (define_expand "divxf3"
4069   [(set (match_operand:XF 0 "register_operand" "")
4070         (div:XF (match_operand:XF 1 "register_operand" "")
4071                 (match_operand:XF 2 "register_operand" "")))]
4072   "TARGET_80387"
4073   "")
4074
4075 (define_expand "divdf3"
4076   [(set (match_operand:DF 0 "register_operand" "")
4077         (div:DF (match_operand:DF 1 "register_operand" "")
4078                 (match_operand:DF 2 "nonimmediate_operand" "")))]
4079    "TARGET_80387"
4080    "")
4081  
4082 (define_expand "divsf3"
4083   [(set (match_operand:SF 0 "register_operand" "")
4084         (div:SF (match_operand:SF 1 "register_operand" "")
4085                 (match_operand:SF 2 "nonimmediate_operand" "")))]
4086   "TARGET_80387"
4087   "")
4088 \f
4089 ;; Remainder instructions.
4090
4091 (define_insn "divmodsi4"
4092   [(set (match_operand:SI 0 "register_operand" "=a")
4093         (div:SI (match_operand:SI 1 "register_operand" "0")
4094                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
4095    (set (match_operand:SI 3 "register_operand" "=&d")
4096         (mod:SI (match_dup 1) (match_dup 2)))]
4097   ""
4098   "*
4099 {
4100 #ifdef INTEL_SYNTAX
4101   output_asm_insn (\"cdq\", operands);
4102 #else
4103   output_asm_insn (\"cltd\", operands);
4104 #endif
4105   return AS1 (idiv%L0,%2);
4106 }"
4107   [(set_attr "type" "idiv")])
4108
4109 (define_insn "divmodhi4"
4110   [(set (match_operand:HI 0 "register_operand" "=a")
4111         (div:HI (match_operand:HI 1 "register_operand" "0")
4112                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
4113    (set (match_operand:HI 3 "register_operand" "=&d")
4114         (mod:HI (match_dup 1) (match_dup 2)))]
4115   ""
4116   "cwtd\;idiv%W0 %2"
4117   [(set_attr "type" "idiv")])
4118
4119 ;; ??? Can we make gcc zero extend operand[0]?
4120 (define_insn "udivmodsi4"
4121   [(set (match_operand:SI 0 "register_operand" "=a")
4122         (udiv:SI (match_operand:SI 1 "register_operand" "0")
4123                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
4124    (set (match_operand:SI 3 "register_operand" "=&d")
4125         (umod:SI (match_dup 1) (match_dup 2)))]
4126   ""
4127   "*
4128 {
4129   output_asm_insn (AS2 (xor%L3,%3,%3), operands);
4130   return AS1 (div%L0,%2);
4131 }"
4132   [(set_attr "type" "idiv")])
4133
4134 ;; ??? Can we make gcc zero extend operand[0]?
4135 (define_insn "udivmodhi4"
4136   [(set (match_operand:HI 0 "register_operand" "=a")
4137         (udiv:HI (match_operand:HI 1 "register_operand" "0")
4138                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
4139    (set (match_operand:HI 3 "register_operand" "=&d")
4140         (umod:HI (match_dup 1) (match_dup 2)))]
4141   ""
4142   "*
4143 {
4144   output_asm_insn (AS2 (xor%W0,%3,%3), operands);
4145   return AS1 (div%W0,%2);
4146 }"
4147   [(set_attr "type" "idiv")])
4148
4149 /*
4150 ;;this should be a valid double division which we may want to add
4151
4152 (define_insn ""
4153   [(set (match_operand:SI 0 "register_operand" "=a")
4154         (udiv:DI (match_operand:DI 1 "register_operand" "a")
4155                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
4156    (set (match_operand:SI 3 "register_operand" "=d")
4157         (umod:SI (match_dup 1) (match_dup 2)))]
4158   ""
4159   "div%L0 %2,%0"
4160   [(set_attr "type" "idiv")])
4161 */
4162 \f
4163 ;;- and instructions
4164
4165 ;; On i386,
4166 ;;                      movzbl %bl,%ebx
4167 ;; is faster than
4168 ;;                      andl $255,%ebx
4169 ;;
4170 ;; but if the reg is %eax, then the "andl" is faster.
4171 ;;
4172 ;; On i486, the "andl" is always faster than the "movzbl".
4173 ;;
4174 ;; On both i386 and i486, a three operand AND is as fast with movzbl or
4175 ;; movzwl as with andl, if operands[0] != operands[1].
4176
4177 ;; The `r' in `rm' for operand 3 looks redundant, but it causes
4178 ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
4179
4180 (define_insn "andsi3"
4181   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4182         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4183                 (match_operand:SI 2 "general_operand" "ri,rm")))]
4184   ""
4185   "*
4186 {
4187   HOST_WIDE_INT intval;
4188   if (!rtx_equal_p (operands[0], operands[1])
4189       && rtx_equal_p (operands[0], operands[2]))
4190     {
4191       rtx tmp;
4192       tmp = operands[1];
4193       operands[1] = operands[2];
4194       operands[2] = tmp;
4195     }
4196   switch (GET_CODE (operands[2]))
4197     {
4198     case CONST_INT:
4199       if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4200         break;
4201       intval = INTVAL (operands[2]);
4202       /* zero-extend 16->32? */
4203       if (intval == 0xffff && REG_P (operands[0])
4204           && (! REG_P (operands[1])
4205               || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
4206           && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
4207         {
4208           /* ??? tege: Should forget CC_STATUS only if we clobber a
4209              remembered operand.  Fix that later.  */
4210           CC_STATUS_INIT;
4211 #ifdef INTEL_SYNTAX
4212           return AS2 (movzx,%w1,%0);
4213 #else
4214           return AS2 (movz%W0%L0,%w1,%0);
4215 #endif
4216         }
4217
4218       /* zero extend 8->32? */
4219       if (intval == 0xff && REG_P (operands[0])
4220           && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
4221           && (! REG_P (operands[1])
4222               || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
4223           && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
4224         {
4225           /* ??? tege: Should forget CC_STATUS only if we clobber a
4226              remembered operand.  Fix that later.  */
4227           CC_STATUS_INIT;
4228 #ifdef INTEL_SYNTAX
4229           return AS2 (movzx,%b1,%0);
4230 #else
4231           return AS2 (movz%B0%L0,%b1,%0);
4232 #endif
4233         }
4234
4235       /* Check partial bytes.. non-QI-regs are not available */
4236       if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4237         break;
4238
4239       /* only low byte has zero bits? */
4240       if (~(intval | 0xff) == 0)
4241         {
4242           intval &= 0xff;
4243           if (REG_P (operands[0]))
4244             {
4245               if (intval == 0)
4246                 {
4247                   CC_STATUS_INIT;
4248                   return AS2 (xor%B0,%b0,%b0);
4249                 }
4250
4251               /* we're better off with the 32-bit version if reg != EAX */
4252               /* the value is sign-extended in 8 bits */
4253               if (REGNO (operands[0]) != 0 && (intval & 0x80))
4254                 break;
4255             }
4256
4257           CC_STATUS_INIT;
4258
4259           operands[2] = GEN_INT (intval);
4260
4261           if (intval == 0)
4262             return AS2 (mov%B0,%2,%b0);
4263
4264           return AS2 (and%B0,%2,%b0);
4265         }
4266
4267       /* only second byte has zero? */
4268       if (~(intval | 0xff00) == 0)
4269         {
4270           CC_STATUS_INIT;
4271
4272           intval = (intval >> 8) & 0xff;
4273           operands[2] = GEN_INT (intval);
4274           if (intval == 0)
4275             {
4276               if (REG_P (operands[0]))
4277                 return AS2 (xor%B0,%h0,%h0);
4278               operands[0] = adj_offsettable_operand (operands[0], 1);
4279               return AS2 (mov%B0,%2,%b0);
4280             }
4281
4282           if (REG_P (operands[0]))
4283             return AS2 (and%B0,%2,%h0);
4284
4285           operands[0] = adj_offsettable_operand (operands[0], 1);
4286           return AS2 (and%B0,%2,%b0);
4287         }
4288
4289       if (REG_P (operands[0]))
4290         break;
4291
4292       /* third byte has zero bits? */
4293       if (~(intval | 0xff0000) == 0)
4294         {
4295           intval = (intval >> 16) & 0xff;
4296           operands[0] = adj_offsettable_operand (operands[0], 2);
4297 byte_and_operation:
4298           CC_STATUS_INIT;
4299           operands[2] = GEN_INT (intval);
4300           if (intval == 0)
4301             return AS2 (mov%B0,%2,%b0);
4302           return AS2 (and%B0,%2,%b0);
4303         }
4304
4305       /* fourth byte has zero bits? */
4306       if (~(intval | 0xff000000) == 0)
4307         {
4308           intval = (intval >> 24) & 0xff;
4309           operands[0] = adj_offsettable_operand (operands[0], 3);
4310           goto byte_and_operation;
4311         }
4312
4313       /* Low word is zero? */
4314       if (intval == 0xffff0000)
4315         {
4316 word_zero_and_operation:
4317           CC_STATUS_INIT;
4318           operands[2] = const0_rtx;
4319           return AS2 (mov%W0,%2,%w0);
4320         }
4321
4322       /* High word is zero? */
4323       if (intval == 0x0000ffff)
4324         {
4325           operands[0] = adj_offsettable_operand (operands[0], 2);
4326           goto word_zero_and_operation;
4327         }
4328
4329     default:
4330       break;
4331     }
4332
4333   return AS2 (and%L0,%2,%0);
4334 }"
4335   [(set_attr "type" "binary")])
4336
4337 (define_insn "andhi3"
4338   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4339         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4340                 (match_operand:HI 2 "general_operand" "ri,rm")))]
4341   ""
4342   "*
4343 {
4344   if (GET_CODE (operands[2]) == CONST_INT
4345       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4346     {
4347       /* Can we ignore the upper byte? */
4348       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
4349           && (INTVAL (operands[2]) & 0xff00) == 0xff00)
4350         {
4351           CC_STATUS_INIT;
4352
4353           if ((INTVAL (operands[2]) & 0xff) == 0)
4354             {
4355               operands[2] = const0_rtx;
4356               return AS2 (mov%B0,%2,%b0);
4357             }
4358
4359           operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
4360           return AS2 (and%B0,%2,%b0);
4361         }
4362
4363       /* Can we ignore the lower byte? */
4364       /* ??? what about offsettable memory references? */
4365       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
4366         {
4367           CC_STATUS_INIT;
4368
4369           if ((INTVAL (operands[2]) & 0xff00) == 0)
4370             {
4371               operands[2] = const0_rtx;
4372               return AS2 (mov%B0,%2,%h0);
4373             }
4374
4375           operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
4376           return AS2 (and%B0,%2,%h0);
4377         }
4378
4379       /* use 32-bit ops on registers when there are no sign issues.. */
4380       if (REG_P (operands[0]))
4381         {
4382           if (!(INTVAL (operands[2]) & ~0x7fff))
4383             return AS2 (and%L0,%2,%k0);
4384         }
4385     }
4386
4387   if (REG_P (operands[0])
4388       && i386_aligned_p (operands[2]))
4389     {
4390       CC_STATUS_INIT;
4391       /* If op[2] is constant, we should zero-extend it and */
4392       /* make a note that op[0] has been zero-extended, so  */
4393       /* that we could use 32-bit ops on it forthwith, but  */
4394       /* there is no such reg-note available. Instead we do */
4395       /* a sign extension as that can result in shorter asm */
4396       operands[2] = i386_sext16_if_const (operands[2]);
4397       return AS2 (and%L0,%k2,%k0);
4398     }
4399
4400   /* Use a 32-bit word with the upper bits set, invalidate CC */
4401   if (GET_CODE (operands[2]) == CONST_INT
4402       && i386_aligned_p (operands[0]))
4403     {
4404       HOST_WIDE_INT val = INTVAL (operands[2]);
4405       CC_STATUS_INIT;
4406       val |= ~0xffff;
4407       if (val != INTVAL (operands[2]))
4408         operands[2] = GEN_INT (val);
4409       return AS2 (and%L0,%k2,%k0);
4410     }
4411
4412   return AS2 (and%W0,%2,%0);
4413 }"
4414   [(set_attr "type" "binary")])
4415
4416 (define_insn "andqi3"
4417   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4418         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4419                 (match_operand:QI 2 "general_operand" "qn,qmn")))]
4420   ""
4421   "* return AS2 (and%B0,%2,%0);"
4422   [(set_attr "type" "binary")])
4423
4424 /* I am nervous about these two.. add them later..
4425 ;I presume this means that we have something in say op0= eax which is small
4426 ;and we want to and it with memory so we can do this by just an
4427 ;andb m,%al  and have success.
4428 (define_insn ""
4429   [(set (match_operand:SI 0 "general_operand" "=r")
4430         (and:SI (zero_extend:SI
4431                  (match_operand:HI 1 "nonimmediate_operand" "rm"))
4432                 (match_operand:SI 2 "general_operand" "0")))]
4433   "GET_CODE (operands[2]) == CONST_INT
4434    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
4435   "and%W0 %1,%0")
4436
4437 (define_insn ""
4438   [(set (match_operand:SI 0 "register_operand" "=q")
4439         (and:SI
4440          (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
4441                 (match_operand:SI 2 "register_operand" "0")))]
4442   "GET_CODE (operands[2]) == CONST_INT
4443    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
4444   "and%L0 %1,%0")
4445
4446 */
4447 \f
4448 ;;- Bit set (inclusive or) instructions
4449
4450 ;; This optimizes known byte-wide operations to memory, and in some cases
4451 ;; to QI registers.. Note that we don't want to use the QI registers too
4452 ;; aggressively, because often the 32-bit register instruction is the same
4453 ;; size, and likely to be faster on PentiumPro.
4454 (define_insn "iorsi3"
4455   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4456         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4457                 (match_operand:SI 2 "general_operand" "ri,rm")))]
4458   ""
4459   "*
4460 {
4461   HOST_WIDE_INT intval;
4462   switch (GET_CODE (operands[2]))
4463     {
4464     case CONST_INT:
4465
4466       if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4467         break;
4468
4469       /* don't try to optimize volatile accesses */
4470       if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4471         break;
4472
4473       intval = INTVAL (operands[2]);
4474       if ((intval & ~0xff) == 0)
4475         {
4476           if (REG_P (operands[0]))
4477             {
4478               /* Do low byte access only for %eax or when high bit is set */
4479               if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4480                 break;
4481             }
4482
4483 byte_or_operation:
4484             CC_STATUS_INIT;
4485
4486             if (intval != INTVAL (operands[2]))
4487               operands[2] = GEN_INT (intval);
4488
4489             if (intval == 0xff)
4490               return AS2 (mov%B0,%2,%b0);
4491
4492             return AS2 (or%B0,%2,%b0);
4493         }
4494
4495       /* second byte? */
4496       if ((intval & ~0xff00) == 0)
4497         {
4498           intval >>= 8;
4499
4500           if (REG_P (operands[0]))
4501             {
4502               CC_STATUS_INIT;
4503               operands[2] = GEN_INT (intval);
4504               if (intval == 0xff)
4505                 return AS2 (mov%B0,%2,%h0);
4506
4507               return AS2 (or%B0,%2,%h0);
4508             }
4509
4510           operands[0] = adj_offsettable_operand (operands[0], 1);
4511           goto byte_or_operation;
4512         }
4513
4514       if (REG_P (operands[0]))
4515         break;
4516
4517       /* third byte? */
4518       if ((intval & ~0xff0000) == 0)
4519         {
4520           intval >>= 16;
4521           operands[0] = adj_offsettable_operand (operands[0], 2);
4522           goto byte_or_operation;
4523         }
4524
4525       /* fourth byte? */
4526       if ((intval & ~0xff000000) == 0)
4527         {
4528           intval = (intval >> 24) & 0xff;
4529           operands[0] = adj_offsettable_operand (operands[0], 3);
4530           goto byte_or_operation;
4531         }
4532
4533     default:
4534       break;
4535     }
4536
4537   return AS2 (or%L0,%2,%0);
4538 }"
4539   [(set_attr "type" "binary")])
4540
4541 (define_insn "iorhi3"
4542   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4543         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4544                 (match_operand:HI 2 "general_operand" "ri,rm")))]
4545   ""
4546   "*
4547 {
4548   HOST_WIDE_INT intval;
4549   switch (GET_CODE (operands[2]))
4550     {
4551     case CONST_INT:
4552
4553       if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4554         break;
4555
4556       /* don't try to optimize volatile accesses */
4557       if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4558         break;
4559
4560       intval = 0xffff & INTVAL (operands[2]);
4561
4562       if ((intval & 0xff00) == 0)
4563         {
4564           if (REG_P (operands[0]))
4565             {
4566               /* Do low byte access only for %eax or when high bit is set */
4567               if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4568                 break;
4569             }
4570
4571 byte_or_operation:
4572             CC_STATUS_INIT;
4573
4574             if (intval == 0xff)
4575               return AS2 (mov%B0,%2,%b0);
4576
4577             return AS2 (or%B0,%2,%b0);
4578         }
4579
4580       /* high byte? */
4581       if ((intval & 0xff) == 0)
4582         {
4583           intval >>= 8;
4584           operands[2] = GEN_INT (intval);
4585
4586           if (REG_P (operands[0]))
4587             {
4588               CC_STATUS_INIT;
4589               if (intval == 0xff)
4590                 return AS2 (mov%B0,%2,%h0);
4591
4592               return AS2 (or%B0,%2,%h0);
4593             }
4594
4595           operands[0] = adj_offsettable_operand (operands[0], 1);
4596
4597           goto byte_or_operation;
4598         }
4599
4600     default:
4601       break;
4602     }
4603
4604   if (REG_P (operands[0])
4605       && i386_aligned_p (operands[2]))
4606     {
4607       CC_STATUS_INIT;
4608       operands[2] = i386_sext16_if_const (operands[2]);
4609       return AS2 (or%L0,%k2,%k0);
4610     }
4611
4612   if (GET_CODE (operands[2]) == CONST_INT
4613       && i386_aligned_p (operands[0]))
4614     {
4615       CC_STATUS_INIT;
4616       intval = 0xffff & INTVAL (operands[2]);
4617       if (intval != INTVAL (operands[2]))
4618         operands[2] = GEN_INT (intval);
4619       return AS2 (or%L0,%2,%k0);
4620     }
4621
4622   return AS2 (or%W0,%2,%0);
4623 }"
4624   [(set_attr "type" "binary")])
4625
4626 (define_insn "iorqi3"
4627   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4628         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4629                 (match_operand:QI 2 "general_operand" "qn,qmn")))]
4630   ""
4631   "* return AS2 (or%B0,%2,%0);"
4632   [(set_attr "type" "binary")])
4633 \f
4634 ;;- xor instructions
4635
4636 (define_insn "xorsi3"
4637   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4638         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4639                 (match_operand:SI 2 "general_operand" "ri,rm")))]
4640   ""
4641   "*
4642 {
4643   HOST_WIDE_INT intval;
4644   switch (GET_CODE (operands[2]))
4645     {
4646     case CONST_INT:
4647
4648       if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
4649         break;
4650
4651       /* don't try to optimize volatile accesses */
4652       if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
4653         break;
4654
4655       intval = INTVAL (operands[2]);
4656       if ((intval & ~0xff) == 0)
4657         {
4658           if (REG_P (operands[0]))
4659             {
4660               /* Do low byte access only for %eax or when high bit is set */
4661               if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4662                 break;
4663             }
4664
4665 byte_xor_operation:
4666             CC_STATUS_INIT;
4667               
4668             if (intval == 0xff
4669                 && (!TARGET_PENTIUM || optimize_size
4670                     || (GET_CODE (operands[0]) == MEM 
4671                         && memory_address_info (XEXP (operands[0], 0), 1))))
4672               return AS1 (not%B0,%b0);
4673
4674             if (intval != INTVAL (operands[2]))
4675               operands[2] = GEN_INT (intval);
4676             return AS2 (xor%B0,%2,%b0);
4677         }
4678
4679       /* second byte? */
4680       if ((intval & ~0xff00) == 0)
4681         {
4682           intval >>= 8;
4683
4684           if (REG_P (operands[0]))
4685             {
4686               CC_STATUS_INIT;
4687               if (intval == 0xff 
4688                   && (!TARGET_PENTIUM || optimize_size
4689                       || (GET_CODE (operands[0]) == MEM 
4690                           && memory_address_info (XEXP (operands[0], 0), 1))))
4691                 return AS1 (not%B0,%h0);
4692
4693               operands[2] = GEN_INT (intval);
4694               return AS2 (xor%B0,%2,%h0);
4695             }
4696
4697           operands[0] = adj_offsettable_operand (operands[0], 1);
4698
4699           goto byte_xor_operation;
4700         }
4701
4702       if (REG_P (operands[0]))
4703         break;
4704
4705       /* third byte? */
4706       if ((intval & ~0xff0000) == 0)
4707         {
4708           intval >>= 16;
4709           operands[0] = adj_offsettable_operand (operands[0], 2);
4710           goto byte_xor_operation;
4711         }
4712
4713       /* fourth byte? */
4714       if ((intval & ~0xff000000) == 0)
4715         {
4716           intval = (intval >> 24) & 0xff;
4717           operands[0] = adj_offsettable_operand (operands[0], 3);
4718           goto byte_xor_operation;
4719         }
4720
4721     default:
4722       break;
4723     }
4724
4725   return AS2 (xor%L0,%2,%0);
4726 }"
4727   [(set_attr "type" "binary")])
4728
4729 (define_insn "xorhi3"
4730   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4731         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4732                 (match_operand:HI 2 "general_operand" "ri,rm")))]
4733   ""
4734   "*
4735 {
4736   if (GET_CODE (operands[2]) == CONST_INT
4737       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4738     {
4739       /* Can we ignore the upper byte? */
4740       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
4741           && (INTVAL (operands[2]) & 0xff00) == 0)
4742         {
4743           CC_STATUS_INIT;
4744           if (INTVAL (operands[2]) & 0xffff0000)
4745             operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
4746
4747           if (INTVAL (operands[2]) == 0xff 
4748               && (!TARGET_PENTIUM || optimize_size
4749                   || (GET_CODE (operands[0]) == MEM 
4750                       && memory_address_info (XEXP (operands[0], 0), 1))))
4751             return AS1 (not%B0,%b0);
4752
4753           return AS2 (xor%B0,%2,%b0);
4754         }
4755
4756       /* Can we ignore the lower byte? */
4757       /* ??? what about offsettable memory references? */
4758       if (QI_REG_P (operands[0])
4759           && (INTVAL (operands[2]) & 0xff) == 0)
4760         {
4761           CC_STATUS_INIT;
4762           operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
4763
4764           if (INTVAL (operands[2]) == 0xff
4765               && (!TARGET_PENTIUM || optimize_size
4766                   || (GET_CODE (operands[0]) == MEM 
4767                       && memory_address_info (XEXP (operands[0], 0), 1))))
4768             return AS1 (not%B0,%h0);
4769
4770           return AS2 (xor%B0,%2,%h0);
4771         }
4772     }
4773
4774   if (REG_P (operands[0])
4775       && i386_aligned_p (operands[2]))
4776     {
4777       CC_STATUS_INIT;
4778       operands[2] = i386_sext16_if_const (operands[2]);
4779       return AS2 (xor%L0,%k2,%k0);
4780     }
4781
4782   if (GET_CODE (operands[2]) == CONST_INT
4783       && i386_aligned_p (operands[0]))
4784     {
4785       HOST_WIDE_INT intval;
4786       CC_STATUS_INIT;
4787       intval = 0xffff & INTVAL (operands[2]);
4788       if (intval != INTVAL (operands[2]))
4789         operands[2] = GEN_INT (intval);
4790       return AS2 (xor%L0,%2,%k0);
4791     }
4792
4793   return AS2 (xor%W0,%2,%0);
4794 }"
4795   [(set_attr "type" "binary")])
4796
4797 (define_insn "xorqi3"
4798   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4799         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
4800                 (match_operand:QI 2 "general_operand" "qn,qm")))]
4801   ""
4802   "* return AS2 (xor%B0,%2,%0);"
4803   [(set_attr "type" "binary")])
4804 \f
4805 ;; logical operations for DImode
4806
4807 (define_insn "anddi3"
4808   [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4809         (and:DI (match_operand:DI 1 "general_operand" "%0,0")
4810                 (match_operand:DI 2 "general_operand" "oriF,riF")))]
4811   ""
4812   "#"
4813   [(set_attr "type" "binary")])
4814
4815
4816 (define_insn "iordi3"
4817   [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4818         (ior:DI (match_operand:DI 1 "general_operand" "%0,0")
4819                 (match_operand:DI 2 "general_operand" "oriF,riF")))]
4820   ""
4821   "#"
4822   [(set_attr "type" "binary")])
4823
4824 (define_insn "xordi3"
4825   [(set (match_operand:DI 0 "general_operand" "=&r,&ro")
4826         (xor:DI (match_operand:DI 1 "general_operand" "%0,0")
4827                 (match_operand:DI 2 "general_operand" "oriF,riF")))]
4828   ""
4829   "#"
4830   [(set_attr "type" "binary")])
4831
4832 (define_split
4833   [(set (match_operand:DI 0 "general_operand" "")
4834         (match_operator:DI 3 "ix86_logical_operator"
4835           [(match_operand:DI 1 "general_operand" "")
4836            (match_operand:DI 2 "general_operand" "")]))]
4837   ""
4838   [(set (match_dup 4) (match_op_dup:SI 3 [(match_dup 6) (match_dup 8)]))
4839    (set (match_dup 5) (match_op_dup:SI 3 [(match_dup 7) (match_dup 9)]))]
4840   "split_di (&operands[0], 1, &operands[4], &operands[5]);
4841    split_di (&operands[1], 1, &operands[6], &operands[7]);
4842    split_di (&operands[2], 1, &operands[8], &operands[9]);")
4843
4844 ;;- negation instructions
4845
4846 (define_insn "negdi2"
4847   [(set (match_operand:DI 0 "general_operand" "=&ro")
4848         (neg:DI (match_operand:DI 1 "general_operand" "0")))]
4849   ""
4850   "*
4851 {
4852   rtx xops[2], low[1], high[1];
4853
4854   CC_STATUS_INIT;
4855
4856   split_di (operands, 1, low, high);
4857   xops[0] = const0_rtx;
4858   xops[1] = high[0];
4859
4860   output_asm_insn (AS1 (neg%L0,%0), low);
4861   output_asm_insn (AS2 (adc%L1,%0,%1), xops);
4862   output_asm_insn (AS1 (neg%L0,%0), high);
4863   RET;
4864 }")
4865
4866 (define_insn "negsi2"
4867   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4868         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
4869   ""
4870   "neg%L0 %0")
4871
4872 (define_insn "neghi2"
4873   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4874         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
4875   ""
4876   "*
4877     if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn))
4878       {
4879         CC_STATUS_INIT;
4880         return AS1(neg%L0,%k0);
4881       }
4882     return AS1(neg%W0,%0);")
4883
4884 (define_insn "negqi2"
4885   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
4886         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
4887   ""
4888   "neg%B0 %0")
4889
4890 (define_insn "negsf2"
4891   [(set (match_operand:SF 0 "register_operand" "=f")
4892         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
4893   "TARGET_80387"
4894   "fchs"
4895   [(set_attr "type" "fpop")])
4896
4897 (define_insn "negdf2"
4898   [(set (match_operand:DF 0 "register_operand" "=f")
4899         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
4900   "TARGET_80387"
4901   "fchs"
4902   [(set_attr "type" "fpop")])
4903
4904 (define_insn ""
4905   [(set (match_operand:DF 0 "register_operand" "=f")
4906         (neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4907   "TARGET_80387"
4908   "fchs"
4909   [(set_attr "type" "fpop")])
4910
4911 (define_insn "negxf2"
4912   [(set (match_operand:XF 0 "register_operand" "=f")
4913         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
4914   "TARGET_80387"
4915   "fchs"
4916   [(set_attr "type" "fpop")])
4917
4918 (define_insn ""
4919   [(set (match_operand:XF 0 "register_operand" "=f")
4920         (neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4921   "TARGET_80387"
4922   "fchs"
4923   [(set_attr "type" "fpop")])
4924 \f
4925 ;; Absolute value instructions
4926
4927 (define_insn "abssf2"
4928   [(set (match_operand:SF 0 "register_operand" "=f")
4929         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
4930   "TARGET_80387"
4931   "fabs"
4932   [(set_attr "type" "fpop")])
4933
4934 (define_insn "absdf2"
4935   [(set (match_operand:DF 0 "register_operand" "=f")
4936         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
4937   "TARGET_80387"
4938   "fabs"
4939   [(set_attr "type" "fpop")])
4940
4941 (define_insn ""
4942   [(set (match_operand:DF 0 "register_operand" "=f")
4943         (abs:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
4944   "TARGET_80387"
4945   "fabs"
4946   [(set_attr "type" "fpop")])
4947
4948 (define_insn "absxf2"
4949   [(set (match_operand:XF 0 "register_operand" "=f")
4950         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
4951   "TARGET_80387"
4952   "fabs"
4953   [(set_attr "type" "fpop")])
4954
4955 (define_insn ""
4956   [(set (match_operand:XF 0 "register_operand" "=f")
4957         (abs:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
4958   "TARGET_80387"
4959   "fabs"
4960   [(set_attr "type" "fpop")])
4961
4962 (define_insn "sqrtsf2"
4963   [(set (match_operand:SF 0 "register_operand" "=f")
4964         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
4965   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4966   "fsqrt")
4967
4968 (define_insn "sqrtdf2"
4969   [(set (match_operand:DF 0 "register_operand" "=f")
4970         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
4971   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
4972    && (TARGET_IEEE_FP || flag_fast_math) "
4973   "fsqrt")
4974
4975 (define_insn ""
4976   [(set (match_operand:DF 0 "register_operand" "=f")
4977         (sqrt:DF (float_extend:DF
4978                   (match_operand:SF 1 "register_operand" "0"))))]
4979   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4980   "fsqrt")
4981
4982 (define_insn "sqrtxf2"
4983   [(set (match_operand:XF 0 "register_operand" "=f")
4984         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
4985   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
4986    && (TARGET_IEEE_FP || flag_fast_math) "
4987   "fsqrt")
4988
4989 (define_insn ""
4990   [(set (match_operand:XF 0 "register_operand" "=f")
4991         (sqrt:XF (float_extend:XF
4992                   (match_operand:DF 1 "register_operand" "0"))))]
4993   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
4994   "fsqrt")
4995
4996 (define_insn ""
4997   [(set (match_operand:XF 0 "register_operand" "=f")
4998         (sqrt:XF (float_extend:XF
4999                   (match_operand:SF 1 "register_operand" "0"))))]
5000   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
5001   "fsqrt")
5002
5003 (define_insn "sindf2"
5004   [(set (match_operand:DF 0 "register_operand" "=f")
5005         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
5006   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5007   "fsin")
5008
5009 (define_insn "sinsf2"
5010   [(set (match_operand:SF 0 "register_operand" "=f")
5011         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
5012   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5013   "fsin")
5014
5015 (define_insn ""
5016   [(set (match_operand:DF 0 "register_operand" "=f")
5017         (unspec:DF [(float_extend:DF
5018                      (match_operand:SF 1 "register_operand" "0"))] 1))]
5019   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5020   "fsin")
5021
5022 (define_insn "sinxf2"
5023   [(set (match_operand:XF 0 "register_operand" "=f")
5024         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
5025   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5026   "fsin")
5027
5028 (define_insn "cosdf2"
5029   [(set (match_operand:DF 0 "register_operand" "=f")
5030         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
5031   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5032   "fcos")
5033
5034 (define_insn "cossf2"
5035   [(set (match_operand:SF 0 "register_operand" "=f")
5036         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
5037   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5038   "fcos")
5039
5040 (define_insn ""
5041   [(set (match_operand:DF 0 "register_operand" "=f")
5042         (unspec:DF [(float_extend:DF
5043                      (match_operand:SF 1 "register_operand" "0"))] 2))]
5044   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5045   "fcos")
5046
5047 (define_insn "cosxf2"
5048   [(set (match_operand:XF 0 "register_operand" "=f")
5049         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
5050   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
5051   "fcos")
5052 \f
5053 ;;- one complement instructions
5054
5055 (define_insn "one_cmplsi2"
5056   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5057         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
5058   ""
5059   "*
5060 {
5061   /* A Pentium NOT is not pariable.  Output it only in case of complex
5062      memory address, because XOR will be inpariable anyway because
5063      of immediate/displacement rule.  */
5064
5065   if (TARGET_PENTIUM && !optimize_size
5066       && (GET_CODE (operands[0]) != MEM 
5067           || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5068     {
5069       rtx xops[2];
5070       xops[0] = operands[0];
5071       xops[1] = GEN_INT (0xffffffff);
5072       output_asm_insn (AS2 (xor%L0,%1,%0), xops);
5073       RET;
5074     }
5075   else
5076     return AS1 (not%L0,%0);
5077 }")
5078
5079 (define_insn "one_cmplhi2"
5080   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5081         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
5082   ""
5083   "*
5084 {
5085   /* A Pentium NOT is not pariable.  Output it only in case of complex
5086      memory address, because XOR will be inpariable anyway because
5087      of immediate/displacement rule.  */
5088
5089   if (TARGET_PENTIUM && !optimize_size
5090       && (GET_CODE (operands[0]) != MEM 
5091           || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5092     {
5093       rtx xops[2];
5094       xops[0] = operands[0];
5095       xops[1] = GEN_INT (0xffff);
5096       if (REG_P (operands[0])
5097           && i386_cc_probably_useless_p (insn))
5098        {
5099           CC_STATUS_INIT;
5100           output_asm_insn (AS2 (xor%L0,%1,%k0), xops);
5101        }
5102       else
5103         output_asm_insn (AS2 (xor%W0,%1,%0), xops);
5104       RET;
5105     }
5106   else
5107     {
5108       if (REG_P (operands[0])
5109           && i386_cc_probably_useless_p (insn))
5110         {
5111           CC_STATUS_INIT;
5112           return AS1 (not%L0,%k0);
5113         }
5114       return AS1 (not%W0,%0);
5115     }
5116 }")
5117
5118 (define_insn "one_cmplqi2"
5119   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5120         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
5121   ""
5122   "*
5123 {
5124   /* A Pentium NOT is not pariable.  Output it only in case of complex
5125      memory address, because XOR will be inpariable anyway because
5126      of immediate/displacement rule.  */
5127
5128   if (TARGET_PENTIUM && !optimize_size
5129       && (GET_CODE (operands[0]) != MEM 
5130           || memory_address_info (XEXP (operands[0], 0), 1) == 0))
5131     {
5132       rtx xops[2];
5133       xops[0] = operands[0];
5134       xops[1] = GEN_INT (0xff);
5135       output_asm_insn (AS2 (xor%B0,%1,%0), xops);
5136       RET;
5137     }
5138   else
5139     return AS1 (not%B0,%0);
5140 }")
5141 \f
5142 ;;- arithmetic shift instructions
5143
5144 ;; DImode shifts are implemented using the i386 "shift double" opcode,
5145 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
5146 ;; is variable, then the count is in %cl and the "imm" operand is dropped
5147 ;; from the assembler input.
5148
5149 ;; This instruction shifts the target reg/mem as usual, but instead of
5150 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
5151 ;; is a left shift double, bits are taken from the high order bits of
5152 ;; reg, else if the insn is a shift right double, bits are taken from the
5153 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
5154 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
5155
5156 ;; Since sh[lr]d does not change the `reg' operand, that is done
5157 ;; separately, making all shifts emit pairs of shift double and normal
5158 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
5159 ;; support a 63 bit shift, each shift where the count is in a reg expands
5160 ;; to a pair of shifts, a branch, a shift by 32 and a label.
5161
5162 ;; If the shift count is a constant, we need never emit more than one
5163 ;; shift pair, instead using moves and sign extension for counts greater
5164 ;; than 31.
5165
5166 (define_expand "ashldi3"
5167   [(set (match_operand:DI 0 "register_operand" "")
5168         (ashift:DI (match_operand:DI 1 "register_operand" "")
5169                    (match_operand:QI 2 "nonmemory_operand" "")))]
5170   ""
5171   "
5172 {
5173   if (GET_CODE (operands[2]) != CONST_INT
5174       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5175     {
5176       operands[2] = copy_to_mode_reg (QImode, operands[2]);
5177       emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
5178                                             operands[2]));
5179     }
5180   else
5181     emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
5182
5183   DONE;
5184 }")
5185
5186 (define_insn "ashldi3_const_int"
5187   [(set (match_operand:DI 0 "register_operand" "=&r")
5188         (ashift:DI (match_operand:DI 1 "register_operand" "0")
5189                    (match_operand:QI 2 "const_int_operand" "J")))]
5190   "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5191   "*
5192 {
5193   rtx xops[4], low[1], high[1];
5194
5195   CC_STATUS_INIT;
5196
5197   split_di (operands, 1, low, high);
5198   xops[0] = operands[2];
5199   xops[1] = const1_rtx;
5200   xops[2] = low[0];
5201   xops[3] = high[0];
5202
5203   if (INTVAL (xops[0]) > 31)
5204     {
5205       output_asm_insn (AS2 (mov%L3,%2,%3), xops);       /* Fast shift by 32 */
5206       output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5207
5208       if (INTVAL (xops[0]) > 32)
5209         {
5210           xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5211           output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
5212         }
5213     }
5214   else
5215     {
5216       output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
5217       output_asm_insn (AS2 (sal%L2,%0,%2), xops);
5218     }
5219   RET;
5220 }")
5221
5222 (define_insn "ashldi3_non_const_int"
5223   [(set (match_operand:DI 0 "register_operand" "=&r")
5224         (ashift:DI (match_operand:DI 1 "register_operand" "0")
5225                    (match_operand:QI 2 "register_operand" "c")))]
5226   ""
5227   "*
5228 {
5229   rtx xops[5], low[1], high[1];
5230
5231   CC_STATUS_INIT;
5232
5233   split_di (operands, 1, low, high);
5234   xops[0] = operands[2];
5235   xops[1] = GEN_INT (32);
5236   xops[2] = low[0];
5237   xops[3] = high[0];
5238   xops[4] = gen_label_rtx ();
5239
5240   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
5241   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
5242   output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5243   output_asm_insn (AS1 (je,%X4), xops);
5244   output_asm_insn (AS2 (mov%L3,%2,%3), xops);   /* Fast shift by 32 */
5245   output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5246   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5247                              CODE_LABEL_NUMBER (xops[4]));
5248   RET;
5249 }")
5250
5251 (define_expand "ashlsi3"
5252   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5253         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
5254                    (match_operand:SI 2 "nonmemory_operand" "")))]
5255   ""
5256   "")
5257
5258 (define_expand "ashlhi3"
5259   [(set (match_operand:HI 0 "nonimmediate_operand" "")
5260         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
5261                    (match_operand:HI 2 "nonmemory_operand" "")))]
5262   ""
5263   "")
5264
5265 (define_expand "ashlqi3"
5266   [(set (match_operand:QI 0 "nonimmediate_operand" "")
5267         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
5268                    (match_operand:QI 2 "nonmemory_operand" "")))]
5269   ""
5270   "")
5271
5272 ;; Pattern for shifts which can be encoded into an lea instruction.
5273 ;; This is kept as a separate pattern so that regmove can optimize cases
5274 ;; where we know the source and destination must match.
5275 ;;
5276 ;; Do not expose this pattern when optimizing for size since we never want
5277 ;; to use lea when optimizing for size since mov+sal is smaller than lea.
5278
5279 (define_insn ""
5280   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
5281         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
5282                    (match_operand:SI 2 "small_shift_operand" "M,M")))]
5283   "! optimize_size"
5284   "* return output_ashl (insn, operands);")
5285
5286 ;; Generic left shift pattern to catch all cases not handled by the
5287 ;; shift pattern above.
5288 (define_insn ""
5289   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5290         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5291                    (match_operand:SI 2 "nonmemory_operand" "cI")))]
5292   ""
5293   "* return output_ashl (insn, operands);")
5294
5295 (define_insn ""
5296   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r")
5297         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
5298                    (match_operand:HI 2 "small_shift_operand" "M,M")))]
5299   "! optimize_size"
5300   "* return output_ashl (insn, operands);")
5301
5302 (define_insn ""
5303   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5304         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5305                    (match_operand:HI 2 "nonmemory_operand" "cI")))]
5306   ""
5307   "* return output_ashl (insn, operands);")
5308
5309 (define_insn ""
5310   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q")
5311         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,q")
5312                    (match_operand:QI 2 "small_shift_operand" "M,M")))]
5313   "! optimize_size"
5314   "* return output_ashl (insn, operands);")
5315
5316 ;; Generic left shift pattern to catch all cases not handled by the
5317 ;; shift pattern above.
5318 (define_insn ""
5319   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5320         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5321                    (match_operand:QI 2 "nonmemory_operand" "cI")))]
5322   ""
5323   "* return output_ashl (insn, operands);")
5324
5325 ;; See comment above `ashldi3' about how this works.
5326
5327 (define_expand "ashrdi3"
5328   [(set (match_operand:DI 0 "register_operand" "")
5329         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5330                      (match_operand:QI 2 "nonmemory_operand" "")))]
5331   ""
5332   "
5333 {
5334   if (GET_CODE (operands[2]) != CONST_INT
5335       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5336     {
5337       operands[2] = copy_to_mode_reg (QImode, operands[2]);
5338       emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
5339                                             operands[2]));
5340     }
5341   else
5342     emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
5343
5344   DONE;
5345 }")
5346
5347 (define_insn "ashldi3_32"
5348   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
5349         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
5350                    (const_int 32)))]
5351   ""
5352   "*
5353 {
5354   rtx low[2], high[2], xops[4];
5355
5356   split_di (operands, 2, low, high);
5357   xops[0] = high[0];
5358   xops[1] = low[1];
5359   xops[2] = low[0];
5360   xops[3] = const0_rtx;
5361   if (!rtx_equal_p (xops[0], xops[1]))
5362     output_asm_insn (AS2 (mov%L0,%1,%0), xops);
5363
5364   if (GET_CODE (low[0]) == MEM)
5365     output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5366   else
5367     output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5368
5369   RET;
5370 }")
5371
5372 (define_insn "ashrdi3_const_int"
5373   [(set (match_operand:DI 0 "register_operand" "=&r")
5374         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
5375                      (match_operand:QI 2 "const_int_operand" "J")))]
5376   "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5377   "*
5378 {
5379   rtx xops[4], low[1], high[1];
5380
5381   CC_STATUS_INIT;
5382
5383   split_di (operands, 1, low, high);
5384   xops[0] = operands[2];
5385   xops[1] = const1_rtx;
5386   xops[2] = low[0];
5387   xops[3] = high[0];
5388
5389   if (INTVAL (xops[0]) > 31)
5390     {
5391       xops[1] = GEN_INT (31);
5392       output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5393       output_asm_insn (AS2 (sar%L3,%1,%3), xops);       /* shift by 32 */
5394
5395       if (INTVAL (xops[0]) > 32)
5396         {
5397           xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5398           output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
5399         }
5400     }
5401   else
5402     {
5403       output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
5404       output_asm_insn (AS2 (sar%L3,%0,%3), xops);
5405     }
5406
5407   RET;
5408 }")
5409
5410 (define_insn "ashrdi3_non_const_int"
5411   [(set (match_operand:DI 0 "register_operand" "=&r")
5412         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
5413                      (match_operand:QI 2 "register_operand" "c")))]
5414   ""
5415   "*
5416 {
5417   rtx xops[5], low[1], high[1];
5418
5419   CC_STATUS_INIT;
5420
5421   split_di (operands, 1, low, high);
5422   xops[0] = operands[2];
5423   xops[1] = GEN_INT (32);
5424   xops[2] = low[0];
5425   xops[3] = high[0];
5426   xops[4] = gen_label_rtx ();
5427
5428   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
5429   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
5430   output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5431   output_asm_insn (AS1 (je,%X4), xops);
5432   xops[1] = GEN_INT (31);
5433   output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5434   output_asm_insn (AS2 (sar%L3,%1,%3), xops);   /* shift by 32 */
5435   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5436                              CODE_LABEL_NUMBER (xops[4]));
5437   RET;
5438 }")
5439
5440 (define_insn "ashrsi3_31"
5441   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d")
5442         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a")
5443                      (const_int 31)))]
5444   "!TARGET_PENTIUM || optimize_size"
5445   "@
5446     sar%L0 $31,%0
5447     cltd")
5448
5449 (define_insn "ashrsi3"
5450   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5451         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5452                      (match_operand:SI 2 "nonmemory_operand" "cI")))]
5453   ""
5454   "*
5455 {
5456   if (REG_P (operands[2]))
5457     return AS2 (sar%L0,%b2,%0);
5458   else
5459     return AS2 (sar%L0,%2,%0);
5460 }")
5461
5462 (define_insn "ashrhi3"
5463   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5464         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5465                      (match_operand:HI 2 "nonmemory_operand" "cI")))]
5466   ""
5467   "*
5468 {
5469   if (REG_P (operands[2]))
5470     return AS2 (sar%W0,%b2,%0);
5471   else
5472     return AS2 (sar%W0,%2,%0);
5473 }")
5474
5475 (define_insn "ashrqi3"
5476   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5477         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5478                      (match_operand:QI 2 "nonmemory_operand" "cI")))]
5479   ""
5480   "*
5481 {
5482   if (REG_P (operands[2]))
5483     return AS2 (sar%B0,%b2,%0);
5484   else
5485     return AS2 (sar%B0,%2,%0);
5486 }")
5487 \f
5488 ;;- logical shift instructions
5489
5490 ;; See comment above `ashldi3' about how this works.
5491
5492 (define_expand "lshrdi3"
5493   [(set (match_operand:DI 0 "register_operand" "")
5494         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5495                      (match_operand:QI 2 "nonmemory_operand" "")))]
5496   ""
5497   "
5498 {
5499   if (GET_CODE (operands[2]) != CONST_INT
5500       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
5501     {
5502       operands[2] = copy_to_mode_reg (QImode, operands[2]);
5503       emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
5504                                             operands[2]));
5505     }
5506   else
5507     emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
5508
5509   DONE;
5510 }")
5511
5512 (define_insn "lshrdi3_32"
5513   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
5514         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
5515                      (const_int 32)))]
5516   ""
5517   "*
5518 {
5519   rtx low[2], high[2], xops[4];
5520
5521   split_di (operands, 2, low, high);
5522   xops[0] = low[0];
5523   xops[1] = high[1];
5524   xops[2] = high[0];
5525   xops[3] = const0_rtx;
5526   if (!rtx_equal_p (xops[0], xops[1]))
5527     output_asm_insn (AS2 (mov%L0,%1,%0), xops);
5528
5529   if (GET_CODE (low[0]) == MEM)
5530     output_asm_insn (AS2 (mov%L2,%3,%2), xops);
5531   else
5532     output_asm_insn (AS2 (xor%L2,%2,%2), xops);
5533
5534   RET;
5535 }")
5536
5537 (define_insn "lshrdi3_const_int"
5538   [(set (match_operand:DI 0 "register_operand" "=&r")
5539         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5540                      (match_operand:QI 2 "const_int_operand" "J")))]
5541   "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')"
5542   "*
5543 {
5544   rtx xops[4], low[1], high[1];
5545
5546   CC_STATUS_INIT;
5547
5548   split_di (operands, 1, low, high);
5549   xops[0] = operands[2];
5550   xops[1] = const1_rtx;
5551   xops[2] = low[0];
5552   xops[3] = high[0];
5553
5554   if (INTVAL (xops[0]) > 31)
5555     {
5556       output_asm_insn (AS2 (mov%L2,%3,%2), xops);       /* Fast shift by 32 */
5557       output_asm_insn (AS2 (xor%L3,%3,%3), xops);
5558
5559       if (INTVAL (xops[0]) > 32)
5560         {
5561           xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
5562           output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
5563         }
5564     }
5565   else
5566     {
5567       output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
5568       output_asm_insn (AS2 (shr%L3,%0,%3), xops);
5569     }
5570
5571   RET;
5572 }")
5573
5574 (define_insn "lshrdi3_non_const_int"
5575   [(set (match_operand:DI 0 "register_operand" "=&r")
5576         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5577                      (match_operand:QI 2 "register_operand" "c")))]
5578   ""
5579   "*
5580 {
5581   rtx xops[5], low[1], high[1];
5582
5583   CC_STATUS_INIT;
5584
5585   split_di (operands, 1, low, high);
5586   xops[0] = operands[2];
5587   xops[1] = GEN_INT (32);
5588   xops[2] = low[0];
5589   xops[3] = high[0];
5590   xops[4] = gen_label_rtx ();
5591
5592   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
5593   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
5594   output_asm_insn (AS2 (test%B0,%1,%b0), xops);
5595   output_asm_insn (AS1 (je,%X4), xops);
5596   output_asm_insn (AS2 (mov%L2,%3,%2), xops);   /* Fast shift by 32 */
5597   output_asm_insn (AS2 (xor%L3,%3,%3), xops);
5598   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5599                              CODE_LABEL_NUMBER (xops[4]));
5600   RET;
5601 }")
5602
5603 (define_insn "lshrsi3"
5604   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5605         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5606                      (match_operand:SI 2 "nonmemory_operand" "cI")))]
5607   ""
5608   "*
5609 {
5610   if (REG_P (operands[2]))
5611     return AS2 (shr%L0,%b2,%0);
5612   else
5613     return AS2 (shr%L0,%2,%1);
5614 }")
5615
5616 (define_insn "lshrhi3"
5617   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5618         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5619                      (match_operand:HI 2 "nonmemory_operand" "cI")))]
5620   ""
5621   "*
5622 {
5623   if (REG_P (operands[2]))
5624     return AS2 (shr%W0,%b2,%0);
5625   else
5626     return AS2 (shr%W0,%2,%0);
5627 }")
5628
5629 (define_insn "lshrqi3"
5630   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5631         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5632                      (match_operand:QI 2 "nonmemory_operand" "cI")))]
5633   ""
5634   "*
5635 {
5636   if (REG_P (operands[2]))
5637     return AS2 (shr%B0,%b2,%0);
5638   else
5639     return AS2 (shr%B0,%2,%0);
5640 }")
5641 \f
5642 ;;- rotate instructions
5643
5644 (define_insn "rotlsi3"
5645   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5646         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5647                    (match_operand:SI 2 "nonmemory_operand" "cI")))]
5648   ""
5649   "*
5650 {
5651   if (REG_P (operands[2]))
5652     return AS2 (rol%L0,%b2,%0);
5653   else
5654     return AS2 (rol%L0,%2,%0);
5655 }")
5656
5657 (define_insn "rotlhi3"
5658   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5659         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5660                    (match_operand:HI 2 "nonmemory_operand" "cI")))]
5661   ""
5662   "*
5663 {
5664   if (REG_P (operands[2]))
5665     return AS2 (rol%W0,%b2,%0);
5666   else
5667     return AS2 (rol%W0,%2,%0);
5668 }")
5669
5670 (define_insn "rotlqi3"
5671   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5672         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5673                    (match_operand:QI 2 "nonmemory_operand" "cI")))]
5674   ""
5675   "*
5676 {
5677   if (REG_P (operands[2]))
5678     return AS2 (rol%B0,%b2,%0);
5679   else
5680     return AS2 (rol%B0,%2,%0);
5681 }")
5682
5683 (define_insn "rotrsi3"
5684   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5685         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5686                      (match_operand:SI 2 "nonmemory_operand" "cI")))]
5687   ""
5688   "*
5689 {
5690   if (REG_P (operands[2]))
5691     return AS2 (ror%L0,%b2,%0);
5692   else
5693     return AS2 (ror%L0,%2,%0);
5694 }")
5695
5696 (define_insn "rotrhi3"
5697   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5698         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
5699                      (match_operand:HI 2 "nonmemory_operand" "cI")))]
5700   ""
5701   "*
5702 {
5703   if (REG_P (operands[2]))
5704     return AS2 (ror%W0,%b2,%0);
5705   else
5706     return AS2 (ror%W0,%2,%0);
5707 }")
5708
5709 (define_insn "rotrqi3"
5710   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
5711         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
5712                      (match_operand:QI 2 "nonmemory_operand" "cI")))]
5713   ""
5714   "*
5715 {
5716   if (REG_P (operands[2]))
5717     return AS2 (ror%B0,%b2,%0);
5718   else
5719     return AS2 (ror%B0,%2,%0);
5720 }")
5721 \f
5722 /*
5723 ;; This usually looses.  But try a define_expand to recognize a few case
5724 ;; we can do efficiently, such as accessing the "high" QImode registers,
5725 ;; %ah, %bh, %ch, %dh.
5726 ;; ??? Note this has a botch on the mode of operand 0, which needs to be
5727 ;; fixed if this is ever enabled.
5728 (define_insn "insv"
5729   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
5730                          (match_operand:SI 1 "immediate_operand" "i")
5731                          (match_operand:SI 2 "immediate_operand" "i"))
5732         (match_operand:SI 3 "nonmemory_operand" "ri"))]
5733   ""
5734   "*
5735 {
5736   if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
5737     abort ();
5738   if (GET_CODE (operands[3]) == CONST_INT)
5739     {
5740       unsigned int mask = (1 << INTVAL (operands[1])) - 1; 
5741       operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
5742       output_asm_insn (AS2 (and%L0,%1,%0), operands);
5743       operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
5744       output_asm_insn (AS2 (or%L0,%3,%0), operands);
5745     }
5746   else
5747     {
5748       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
5749       if (INTVAL (operands[2]))
5750         output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5751       output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
5752       operands[2] = GEN_INT (BITS_PER_WORD
5753                              - INTVAL (operands[1]) - INTVAL (operands[2]));
5754       if (INTVAL (operands[2]))
5755         output_asm_insn (AS2 (ror%L0,%2,%0), operands);
5756     }
5757   RET;
5758 }")
5759 */
5760 /*
5761 ;; ??? There are problems with the mode of operand[3].  The point of this
5762 ;; is to represent an HImode move to a "high byte" register.
5763
5764 (define_expand "insv"
5765   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
5766                          (match_operand:SI 1 "immediate_operand" "")
5767                          (match_operand:SI 2 "immediate_operand" ""))
5768         (match_operand:QI 3 "nonmemory_operand" "ri"))]
5769   ""
5770   "
5771 {
5772   if (GET_CODE (operands[1]) != CONST_INT
5773       || GET_CODE (operands[2]) != CONST_INT)
5774     FAIL;
5775
5776   if (! (INTVAL (operands[1]) == 8
5777          && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
5778       && ! INTVAL (operands[1]) == 1)
5779     FAIL;
5780 }")
5781 */
5782
5783 ;; On i386, the register count for a bit operation is *not* truncated,
5784 ;; so SHIFT_COUNT_TRUNCATED must not be defined.
5785
5786 ;; On i486, the shift & or/and code is faster than bts or btr.  If
5787 ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
5788
5789 ;; On i386, bts is a little faster if operands[0] is a reg, and a
5790 ;; little slower if operands[0] is a MEM, than the shift & or/and code.
5791 ;; Use bts & btr, since they reload better.
5792
5793 ;; General bit set and clear.
5794 (define_insn ""
5795   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm")
5796                          (const_int 1)
5797                          (match_operand:SI 2 "register_operand" "r"))
5798         (match_operand:SI 3 "const_int_operand" "n"))]
5799   "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5800   "*
5801 {
5802   CC_STATUS_INIT;
5803
5804   if (INTVAL (operands[3]) == 1)
5805     return AS2 (bts%L0,%2,%0);
5806   else
5807     return AS2 (btr%L0,%2,%0);
5808 }")
5809
5810 ;; Bit complement.  See comments on previous pattern.
5811 ;; ??? Is this really worthwhile?
5812 (define_insn ""
5813   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5814         (xor:SI (ashift:SI (const_int 1)
5815                            (match_operand:SI 1 "register_operand" "r"))
5816                 (match_operand:SI 2 "nonimmediate_operand" "0")))]
5817   "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT"
5818   "*
5819 {
5820   CC_STATUS_INIT;
5821
5822   return AS2 (btc%L0,%1,%0);
5823 }")
5824
5825 (define_insn ""
5826   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5827         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5828                 (ashift:SI (const_int 1)
5829                            (match_operand:SI 2 "register_operand" "r"))))]
5830   "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT"
5831   "*
5832 {
5833   CC_STATUS_INIT;
5834
5835   return AS2 (btc%L0,%2,%0);
5836 }")
5837 \f
5838 ;; Recognizers for bit-test instructions.
5839
5840 ;; The bt opcode allows a MEM in operands[0].  But on both i386 and
5841 ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
5842 ;; bt on the MEM directly.
5843
5844 ;; ??? The first argument of a zero_extract must not be reloaded, so
5845 ;; don't allow a MEM in the operand predicate without allowing it in the
5846 ;; constraint.
5847
5848 (define_insn ""
5849   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5850                             (const_int 1)
5851                             (match_operand:SI 1 "register_operand" "r")))]
5852   "GET_CODE (operands[1]) != CONST_INT"
5853   "*
5854 {
5855   cc_status.flags |= CC_Z_IN_NOT_C;
5856   return AS2 (bt%L0,%1,%0);
5857 }")
5858
5859 (define_insn ""
5860   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
5861                             (match_operand:SI 1 "const_int_operand" "n")
5862                             (match_operand:SI 2 "const_int_operand" "n")))]
5863   ""
5864   "*
5865 {
5866   unsigned int mask;
5867
5868   mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5869   operands[1] = GEN_INT (mask);
5870
5871   if (QI_REG_P (operands[0])
5872       /* A Pentium test is pairable only with eax. Not with ah or al.  */
5873       && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
5874           || optimize_size))
5875     {
5876       if ((mask & ~0xff) == 0)
5877         {
5878           cc_status.flags |= CC_NOT_NEGATIVE;
5879           return AS2 (test%B0,%1,%b0);
5880         }
5881
5882       if ((mask & ~0xff00) == 0)
5883         {
5884           cc_status.flags |= CC_NOT_NEGATIVE;
5885           operands[1] = GEN_INT (mask >> 8);
5886           return AS2 (test%B0,%1,%h0);
5887         }
5888     }
5889
5890   return AS2 (test%L0,%1,%0);
5891 }")
5892
5893 ;; ??? All bets are off if operand 0 is a volatile MEM reference.
5894 ;; The CPU may access unspecified bytes around the actual target byte.
5895
5896 (define_insn ""
5897   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
5898                             (match_operand:SI 1 "const_int_operand" "n")
5899                             (match_operand:SI 2 "const_int_operand" "n")))]
5900   "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
5901   "*
5902 {
5903   unsigned int mask;
5904
5905   mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
5906   operands[1] = GEN_INT (mask);
5907
5908   if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
5909       /* A Pentium test is pairable only with eax. Not with ah or al.  */
5910       && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM
5911           || optimize_size))
5912     {
5913       if ((mask & ~0xff) == 0)
5914         {
5915           cc_status.flags |= CC_NOT_NEGATIVE;
5916           return AS2 (test%B0,%1,%b0);
5917         }
5918
5919       if ((mask & ~0xff00) == 0)
5920         {
5921           cc_status.flags |= CC_NOT_NEGATIVE;
5922           operands[1] = GEN_INT (mask >> 8);
5923
5924           if (QI_REG_P (operands[0]))
5925             return AS2 (test%B0,%1,%h0);
5926           else
5927             {
5928               operands[0] = adj_offsettable_operand (operands[0], 1);
5929               return AS2 (test%B0,%1,%b0);
5930             }
5931         }
5932
5933       if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
5934         {
5935           cc_status.flags |= CC_NOT_NEGATIVE;
5936           operands[1] = GEN_INT (mask >> 16);
5937           operands[0] = adj_offsettable_operand (operands[0], 2);
5938           return AS2 (test%B0,%1,%b0);
5939         }
5940
5941       if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
5942         {
5943           cc_status.flags |= CC_NOT_NEGATIVE;
5944           operands[1] = GEN_INT (mask >> 24);
5945           operands[0] = adj_offsettable_operand (operands[0], 3);
5946           return AS2 (test%B0,%1,%b0);
5947         }
5948     }
5949
5950   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
5951     return AS2 (test%L0,%1,%0);
5952
5953   return AS2 (test%L1,%0,%1);
5954 }")
5955 \f
5956 ;; Store-flag instructions.
5957
5958 ;; For all sCOND expanders, also expand the compare or test insn that
5959 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
5960
5961 (define_expand "seq"
5962   [(match_dup 1)
5963    (set (match_operand:QI 0 "register_operand" "")
5964         (eq:QI (cc0) (const_int 0)))]
5965   ""
5966   "
5967 {
5968   if (TARGET_IEEE_FP
5969       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5970     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5971   else
5972     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5973 }")
5974
5975 (define_expand "sne"
5976   [(match_dup 1)
5977    (set (match_operand:QI 0 "register_operand" "")
5978         (ne:QI (cc0) (const_int 0)))]
5979   ""
5980   "
5981 {
5982   if (TARGET_IEEE_FP
5983       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
5984     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
5985   else
5986     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
5987 }")
5988
5989 (define_expand "sgt"
5990   [(match_dup 1)
5991    (set (match_operand:QI 0 "register_operand" "")
5992         (gt:QI (cc0) (const_int 0)))]
5993   ""
5994   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
5995
5996 (define_expand "sgtu"
5997   [(match_dup 1)
5998    (set (match_operand:QI 0 "register_operand" "")
5999         (gtu:QI (cc0) (const_int 0)))]
6000   ""
6001   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6002
6003 (define_expand "slt"
6004   [(match_dup 1)
6005    (set (match_operand:QI 0 "register_operand" "")
6006         (lt:QI (cc0) (const_int 0)))]
6007   ""
6008   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6009
6010 (define_expand "sltu"
6011   [(match_dup 1)
6012    (set (match_operand:QI 0 "register_operand" "")
6013         (ltu:QI (cc0) (const_int 0)))]
6014   ""
6015   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6016
6017 (define_expand "sge"
6018   [(match_dup 1)
6019    (set (match_operand:QI 0 "register_operand" "")
6020         (ge:QI (cc0) (const_int 0)))]
6021   ""
6022   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6023
6024 (define_expand "sgeu"
6025   [(match_dup 1)
6026    (set (match_operand:QI 0 "register_operand" "")
6027         (geu:QI (cc0) (const_int 0)))]
6028   ""
6029   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6030
6031 (define_expand "sle"
6032   [(match_dup 1)
6033    (set (match_operand:QI 0 "register_operand" "")
6034         (le:QI (cc0) (const_int 0)))]
6035   ""
6036   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6037
6038 (define_expand "sleu"
6039   [(match_dup 1)
6040    (set (match_operand:QI 0 "register_operand" "")
6041         (leu:QI (cc0) (const_int 0)))]
6042   ""
6043   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6044
6045 ;; The 386 sCOND opcodes can write to memory.  But a gcc sCOND insn may
6046 ;; not have any input reloads.  A MEM write might need an input reload
6047 ;; for the address of the MEM.  So don't allow MEM as the SET_DEST.
6048
6049 (define_insn "*setcc"
6050   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
6051         (match_operator:QI 1 "comparison_operator" [(cc0) (const_int 0)]))]
6052   "reload_completed || register_operand (operands[0], QImode)"
6053   "*
6054 {
6055   enum rtx_code code = GET_CODE (operands[1]);
6056   if (cc_prev_status.flags & CC_TEST_AX)
6057     {
6058       int eq;
6059       HOST_WIDE_INT c;
6060       operands[2] = gen_rtx_REG (SImode, 0);
6061       switch (code)
6062         {
6063         case EQ:
6064           c = 0x4000;
6065           eq = 0;
6066           break;
6067         case NE:
6068           c = 0x4000;
6069           eq = 1;
6070           break;
6071         case GT:
6072           c = 0x4100;
6073           eq = 1;
6074           break;
6075         case LT:
6076           c = 0x100;
6077           eq = 0;
6078           break;
6079         case GE:
6080           c = 0x100;
6081           eq = 1;
6082           break;
6083         case LE:
6084           c = 0x4100;
6085           eq = 0;
6086           break;
6087         default:
6088           abort ();
6089         }
6090       if (!TARGET_PENTIUM || optimize_size)
6091         {
6092           operands[3] = GEN_INT (c >> 8);
6093           output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6094         }
6095       else
6096         {
6097           operands[3] = GEN_INT (c);
6098           output_asm_insn (AS2 (test%L0,%3,%2), operands);
6099         }
6100       return eq ? AS1 (sete,%0) : AS1 (setne, %0);
6101     }
6102
6103   if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6104     return (char *)0;
6105   return AS1(set%D1,%0);
6106 }")
6107
6108 \f
6109 ;; Basic conditional jump instructions.
6110 ;; We ignore the overflow flag for signed branch instructions.
6111
6112 ;; For all bCOND expanders, also expand the compare or test insn that
6113 ;; generates cc0.  Generate an equality comparison if `beq' or `bne'.
6114
6115 (define_expand "beq"
6116   [(match_dup 1)
6117    (set (pc)
6118         (if_then_else (eq (cc0)
6119                           (const_int 0))
6120                       (label_ref (match_operand 0 "" ""))
6121                       (pc)))]
6122   ""
6123   "
6124 {
6125   if (TARGET_IEEE_FP
6126       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
6127     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
6128   else
6129     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
6130 }")
6131
6132 (define_expand "bne"
6133   [(match_dup 1)
6134    (set (pc)
6135         (if_then_else (ne (cc0)
6136                           (const_int 0))
6137                       (label_ref (match_operand 0 "" ""))
6138                       (pc)))]
6139   ""
6140   "
6141 {
6142   if (TARGET_IEEE_FP
6143       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
6144     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
6145   else
6146     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
6147 }")
6148
6149
6150 (define_expand "bgt"
6151   [(match_dup 1)
6152    (set (pc)
6153         (if_then_else (gt (cc0)
6154                           (const_int 0))
6155                       (label_ref (match_operand 0 "" ""))
6156                       (pc)))]
6157   ""
6158   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6159
6160 (define_expand "bgtu"
6161   [(match_dup 1)
6162    (set (pc)
6163         (if_then_else (gtu (cc0)
6164                            (const_int 0))
6165                       (label_ref (match_operand 0 "" ""))
6166                       (pc)))]
6167   ""
6168   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6169
6170 (define_expand "blt"
6171   [(match_dup 1)
6172    (set (pc)
6173         (if_then_else (lt (cc0)
6174                           (const_int 0))
6175                       (label_ref (match_operand 0 "" ""))
6176                       (pc)))]
6177   ""
6178   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6179
6180
6181 (define_expand "bltu"
6182   [(match_dup 1)
6183    (set (pc)
6184         (if_then_else (ltu (cc0)
6185                            (const_int 0))
6186                       (label_ref (match_operand 0 "" ""))
6187                       (pc)))]
6188   ""
6189   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6190
6191 (define_expand "bge"
6192   [(match_dup 1)
6193    (set (pc)
6194         (if_then_else (ge (cc0)
6195                           (const_int 0))
6196                       (label_ref (match_operand 0 "" ""))
6197                       (pc)))]
6198   ""
6199   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6200
6201 (define_expand "bgeu"
6202   [(match_dup 1)
6203    (set (pc)
6204         (if_then_else (geu (cc0)
6205                            (const_int 0))
6206                       (label_ref (match_operand 0 "" ""))
6207                       (pc)))]
6208   ""
6209   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6210
6211 (define_expand "ble"
6212   [(match_dup 1)
6213    (set (pc)
6214         (if_then_else (le (cc0)
6215                           (const_int 0))
6216                       (label_ref (match_operand 0 "" ""))
6217                       (pc)))]
6218   ""
6219   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6220
6221 (define_expand "bleu"
6222   [(match_dup 1)
6223    (set (pc)
6224         (if_then_else (leu (cc0)
6225                            (const_int 0))
6226                       (label_ref (match_operand 0 "" ""))
6227                       (pc)))]
6228   ""
6229   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
6230
6231 (define_insn ""
6232   [(set (pc)
6233         (if_then_else (match_operator 0 "comparison_operator"
6234                                       [(cc0) (const_int 0)])
6235                       (label_ref (match_operand 1 "" ""))
6236                       (pc)))]
6237   ""
6238   "*
6239 {
6240   enum rtx_code code = GET_CODE (operands[0]);
6241   if (cc_prev_status.flags & CC_TEST_AX)
6242     {
6243       int eq;
6244       HOST_WIDE_INT c;
6245       operands[2] = gen_rtx_REG (SImode, 0);
6246       switch (code)
6247         {
6248         case EQ:
6249           c = 0x4000;
6250           eq = 0;
6251           break;
6252         case NE:
6253           c = 0x4000;
6254           eq = 1;
6255           break;
6256         case GT:
6257           c = 0x4100;
6258           eq = 1;
6259           break;
6260         case LT:
6261           c = 0x100;
6262           eq = 0;
6263           break;
6264         case GE:
6265           c = 0x100;
6266           eq = 1;
6267           break;
6268         case LE:
6269           c = 0x4100;
6270           eq = 0;
6271           break;
6272         default:
6273           abort ();
6274         }
6275       if (!TARGET_PENTIUM || optimize_size)
6276         {
6277           operands[3] = GEN_INT (c >> 8);
6278           output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6279         }
6280       else
6281         {
6282           operands[3] = GEN_INT (c);
6283           output_asm_insn (AS2 (test%L0,%3,%2), operands);
6284         }
6285       return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
6286     }
6287   if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6288     return (char *)0;
6289
6290   return AS1(j%D0,%l1);
6291 }")
6292
6293 (define_insn ""
6294   [(set (pc)
6295         (if_then_else (match_operator 0 "comparison_operator"
6296                                       [(cc0) (const_int 0)])
6297                       (pc)
6298                       (label_ref (match_operand 1 "" ""))))]
6299   ""
6300   "*
6301 {
6302   enum rtx_code code = GET_CODE (operands[0]);
6303   if (cc_prev_status.flags & CC_TEST_AX)
6304     {
6305       int eq;
6306       HOST_WIDE_INT c;
6307       operands[2] = gen_rtx_REG (SImode, 0);
6308       switch (code)
6309         {
6310         case EQ:
6311           c = 0x4000;
6312           eq = 1;
6313           break;
6314         case NE:
6315           c = 0x4000;
6316           eq = 0;
6317           break;
6318         case GT:
6319           c = 0x4100;
6320           eq = 0;
6321           break;
6322         case LT:
6323           c = 0x100;
6324           eq = 1;
6325           break;
6326         case GE:
6327           c = 0x100;
6328           eq = 0;
6329           break;
6330         case LE:
6331           c = 0x4100;
6332           eq = 1;
6333           break;
6334         default:
6335           abort ();
6336         }
6337       if (!TARGET_PENTIUM || optimize_size)
6338         {
6339           operands[3] = GEN_INT (c >> 8);
6340           output_asm_insn (AS2 (test%B0,%3,%h2), operands);
6341         }
6342       else
6343         {
6344           operands[3] = GEN_INT (c);
6345           output_asm_insn (AS2 (test%L0,%3,%2), operands);
6346         }
6347       return eq ? AS1 (je,%l1) : AS1 (jne, %l1);
6348     }
6349   if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
6350     return (char *)0;
6351
6352   return AS1(j%d0,%l1);
6353 }")
6354 \f
6355 ;; Unconditional and other jump instructions
6356
6357 (define_insn "jump"
6358   [(set (pc)
6359         (label_ref (match_operand 0 "" "")))]
6360   ""
6361   "jmp %l0"
6362   [(set_attr "memory" "none")])
6363
6364 (define_insn "indirect_jump"
6365   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
6366   ""
6367   "*
6368 {
6369   CC_STATUS_INIT;
6370
6371   return AS1 (jmp,%*%0);
6372 }"
6373   [(set_attr "memory" "none")])
6374
6375 ;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i);
6376 ;;     if S does not change i
6377
6378 (define_expand "decrement_and_branch_until_zero"
6379   [(parallel [(set (pc)
6380                    (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "")
6381                                               (const_int -1))
6382                                      (const_int 0))
6383                                  (label_ref (match_operand 1 "" ""))
6384                                  (pc)))
6385               (set (match_dup 0)
6386                    (plus:SI (match_dup 0)
6387                             (const_int -1)))])]
6388   ""
6389   "")
6390
6391 (define_insn ""
6392   [(set (pc)
6393         (if_then_else (match_operator 0 "arithmetic_comparison_operator"
6394                                       [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+c*r,m")
6395                                                 (match_operand:SI 2 "general_operand" "rmi,ri"))
6396                                        (const_int 0)])
6397                       (label_ref (match_operand 3 "" ""))
6398                       (pc)))
6399    (set (match_dup 1)
6400         (plus:SI (match_dup 1)
6401                  (match_dup 2)))]
6402   ""
6403   "*
6404 {
6405   CC_STATUS_INIT;
6406
6407   if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 &&
6408       operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6)
6409     return \"loop %l3\";
6410
6411   if (operands[2] == constm1_rtx)
6412     output_asm_insn (AS1 (dec%L1,%1), operands);
6413
6414   else if (operands[2] == const1_rtx)
6415     output_asm_insn (AS1 (inc%L1,%1), operands);
6416
6417   else
6418     output_asm_insn (AS2 (add%L1,%2,%1), operands);
6419
6420   return AS1 (%J0,%l3);
6421 }")
6422
6423 (define_insn ""
6424   [(set (pc)
6425         (if_then_else (match_operator 0 "arithmetic_comparison_operator"
6426                                       [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m")
6427                                                  (match_operand:SI 2 "general_operand" "rmi,ri"))
6428                                        (const_int 0)])
6429                       (label_ref (match_operand 3 "" ""))
6430                       (pc)))
6431    (set (match_dup 1)
6432         (minus:SI (match_dup 1)
6433                   (match_dup 2)))]
6434   ""
6435   "*
6436 {
6437   CC_STATUS_INIT;
6438   if (operands[2] == const1_rtx)
6439     output_asm_insn (AS1 (dec%L1,%1), operands);
6440
6441   else if (operands[1] == constm1_rtx)
6442     output_asm_insn (AS1 (inc%L1,%1), operands);
6443
6444   else
6445     output_asm_insn (AS2 (sub%L1,%2,%1), operands);
6446
6447   return AS1 (%J0,%l3);
6448 }")
6449
6450 (define_insn ""
6451   [(set (pc)
6452         (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6453                           (const_int 0))
6454                       (label_ref (match_operand 1 "" ""))
6455                       (pc)))
6456    (set (match_dup 0)
6457         (plus:SI (match_dup 0)
6458                  (const_int -1)))]
6459   ""
6460   "*
6461 {
6462   CC_STATUS_INIT;
6463   operands[2] = const1_rtx;
6464   output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6465   return \"jnc %l1\";
6466 }")
6467
6468 (define_insn ""
6469   [(set (pc)
6470         (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6471                           (const_int 0))
6472                       (label_ref (match_operand 1 "" ""))
6473                       (pc)))
6474    (set (match_dup 0)
6475         (plus:SI (match_dup 0)
6476                  (const_int -1)))]
6477   ""
6478   "*
6479 {
6480   CC_STATUS_INIT;
6481   operands[2] = const1_rtx;
6482   output_asm_insn (AS2 (sub%L0,%2,%0), operands);
6483   return \"jc %l1\";
6484 }")
6485
6486 (define_insn ""
6487   [(set (pc)
6488         (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6489                           (const_int 1))
6490                       (label_ref (match_operand 1 "" ""))
6491                       (pc)))
6492    (set (match_dup 0)
6493         (plus:SI (match_dup 0)
6494                  (const_int -1)))]
6495   ""
6496   "*
6497 {
6498   CC_STATUS_INIT;
6499   output_asm_insn (AS1 (dec%L0,%0), operands);
6500   return \"jnz %l1\";
6501 }")
6502
6503 (define_insn ""
6504   [(set (pc)
6505         (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6506                           (const_int 1))
6507                       (label_ref (match_operand 1 "" ""))
6508                       (pc)))
6509    (set (match_dup 0)
6510         (plus:SI (match_dup 0)
6511                  (const_int -1)))]
6512   ""
6513   "*
6514 {
6515   CC_STATUS_INIT;
6516   output_asm_insn (AS1 (dec%L0,%0), operands);
6517   return \"jz %l1\";
6518 }")
6519
6520 (define_insn ""
6521   [(set (pc)
6522         (if_then_else (ne (match_operand:SI 0 "general_operand" "+g")
6523                           (const_int -1))
6524                       (label_ref (match_operand 1 "" ""))
6525                       (pc)))
6526    (set (match_dup 0)
6527         (plus:SI (match_dup 0)
6528                  (const_int 1)))]
6529   ""
6530   "*
6531 {
6532   CC_STATUS_INIT;
6533   output_asm_insn (AS1 (inc%L0,%0), operands);
6534   return \"jnz %l1\";
6535 }")
6536
6537 (define_insn ""
6538   [(set (pc)
6539         (if_then_else (eq (match_operand:SI 0 "general_operand" "+g")
6540                           (const_int -1))
6541                       (label_ref (match_operand 1 "" ""))
6542                       (pc)))
6543    (set (match_dup 0)
6544         (plus:SI (match_dup 0)
6545                  (const_int 1)))]
6546   ""
6547   "*
6548 {
6549   CC_STATUS_INIT;
6550   output_asm_insn (AS1 (inc%L0,%0), operands);
6551   return \"jz %l1\";
6552 }")
6553
6554 ;; Implement switch statements when generating PIC code.  Switches are
6555 ;; implemented by `tablejump' when not using -fpic.
6556
6557 ;; Emit code here to do the range checking and make the index zero based.
6558
6559 (define_expand "casesi"
6560   [(set (match_dup 5)
6561         (match_operand:SI 0 "general_operand" ""))
6562    (set (match_dup 6)
6563         (minus:SI (match_dup 5)
6564                   (match_operand:SI 1 "general_operand" "")))
6565    (set (cc0)
6566         (compare:CC (match_dup 6)
6567                     (match_operand:SI 2 "general_operand" "")))
6568    (set (pc)
6569         (if_then_else (gtu (cc0)
6570                            (const_int 0))
6571                       (label_ref (match_operand 4 "" ""))
6572                       (pc)))
6573    (parallel
6574     [(set (pc)
6575           (minus:SI (reg:SI 3)
6576                     (mem:SI (plus:SI (mult:SI (match_dup 6)
6577                                               (const_int 4))
6578                                      (label_ref (match_operand 3 "" ""))))))
6579      (clobber (match_scratch:SI 7 ""))])]
6580   "flag_pic"
6581   "
6582 {
6583   operands[5] = gen_reg_rtx (SImode);
6584   operands[6] = gen_reg_rtx (SImode);
6585   current_function_uses_pic_offset_table = 1;
6586 }")
6587
6588 ;; Implement a casesi insn.
6589
6590 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
6591 ;; two rules below:
6592 ;; 
6593 ;;      .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
6594 ;; 
6595 ;; 1. An expression involving an external reference may only use the
6596 ;;    addition operator, and only with an assembly-time constant.
6597 ;;    The example above satisfies this because ".-.L2" is a constant.
6598 ;; 
6599 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
6600 ;;    given the value of "GOT - .", where GOT is the actual address of
6601 ;;    the Global Offset Table.  Therefore, the .long above actually
6602 ;;    stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2".  The
6603 ;;    expression "GOT - .L2" by itself would generate an error from as(1).
6604 ;; 
6605 ;; The pattern below emits code that looks like this:
6606 ;; 
6607 ;;      movl %ebx,reg
6608 ;;      subl TABLE@GOTOFF(%ebx,index,4),reg
6609 ;;      jmp reg
6610 ;; 
6611 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
6612 ;; the addr_diff_vec is known to be part of this module.
6613 ;; 
6614 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
6615 ;; evaluates to just ".L2".
6616
6617 (define_insn ""
6618   [(set (pc)
6619         (minus:SI (reg:SI 3)
6620                   (mem:SI (plus:SI
6621                            (mult:SI (match_operand:SI 0 "register_operand" "r")
6622                                     (const_int 4))
6623                            (label_ref (match_operand 1 "" ""))))))
6624    (clobber (match_scratch:SI 2 "=&r"))]
6625   ""
6626   "*
6627 {
6628   rtx xops[4];
6629
6630   xops[0] = operands[0];
6631   xops[1] = operands[1];
6632   xops[2] = operands[2];
6633   xops[3] = pic_offset_table_rtx;
6634
6635   output_asm_insn (AS2 (mov%L2,%3,%2), xops);
6636   output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
6637   output_asm_insn (AS1 (jmp,%*%2), xops);
6638   ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps);
6639   RET;
6640 }")
6641
6642 (define_insn "tablejump"
6643   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
6644    (use (label_ref (match_operand 1 "" "")))]
6645   ""
6646   "*
6647 {
6648   CC_STATUS_INIT;
6649
6650   return AS1 (jmp,%*%0);
6651 }")
6652
6653 ;; Call insns.
6654
6655 ;; If generating PIC code, the predicate indirect_operand will fail
6656 ;; for operands[0] containing symbolic references on all of the named
6657 ;; call* patterns.  Each named pattern is followed by an unnamed pattern
6658 ;; that matches any call to a symbolic CONST (ie, a symbol_ref).  The
6659 ;; unnamed patterns are only used while generating PIC code, because
6660 ;; otherwise the named patterns match.
6661
6662 ;; Call subroutine returning no value.
6663
6664 (define_expand "call_pop"
6665   [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
6666                     (match_operand:SI 1 "general_operand" ""))
6667               (set (reg:SI 7)
6668                    (plus:SI (reg:SI 7)
6669                             (match_operand:SI 3 "immediate_operand" "")))])]
6670   ""
6671   "
6672 {
6673   rtx addr;
6674
6675   if (operands[3] == const0_rtx)
6676     {
6677       emit_insn (gen_call (operands[0], operands[1]));
6678       DONE;
6679     }
6680
6681   if (flag_pic)
6682     current_function_uses_pic_offset_table = 1;
6683
6684   /* With half-pic, force the address into a register.  */
6685   addr = XEXP (operands[0], 0);
6686   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6687     XEXP (operands[0], 0) = force_reg (Pmode, addr);
6688
6689   if (! expander_call_insn_operand (operands[0], QImode))
6690     operands[0]
6691       = change_address (operands[0], VOIDmode,
6692                         copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6693 }")
6694
6695 (define_insn ""
6696   [(call (match_operand:QI 0 "call_insn_operand" "m")
6697          (match_operand:SI 1 "general_operand" "g"))
6698    (set (reg:SI 7) (plus:SI (reg:SI 7)
6699                             (match_operand:SI 3 "immediate_operand" "i")))]
6700   ""
6701   "*
6702 {
6703   if (GET_CODE (operands[0]) == MEM
6704       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6705     {
6706       operands[0] = XEXP (operands[0], 0);
6707       return AS1 (call,%*%0);
6708     }
6709   else
6710     return AS1 (call,%P0);
6711 }")
6712
6713 (define_insn ""
6714   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6715          (match_operand:SI 1 "general_operand" "g"))
6716    (set (reg:SI 7) (plus:SI (reg:SI 7)
6717                             (match_operand:SI 3 "immediate_operand" "i")))]
6718   "!HALF_PIC_P ()"
6719   "call %P0")
6720
6721 (define_expand "call"
6722   [(call (match_operand:QI 0 "indirect_operand" "")
6723          (match_operand:SI 1 "general_operand" ""))]
6724   ;; Operand 1 not used on the i386.
6725   ""
6726   "
6727 {
6728   rtx addr;
6729
6730   if (flag_pic)
6731     current_function_uses_pic_offset_table = 1;
6732
6733   /* With half-pic, force the address into a register.  */
6734   addr = XEXP (operands[0], 0);
6735   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6736     XEXP (operands[0], 0) = force_reg (Pmode, addr);
6737
6738   if (! expander_call_insn_operand (operands[0], QImode))
6739     operands[0]
6740       = change_address (operands[0], VOIDmode,
6741                         copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
6742 }")
6743
6744 (define_insn ""
6745   [(call (match_operand:QI 0 "call_insn_operand" "m")
6746          (match_operand:SI 1 "general_operand" "g"))]
6747   ;; Operand 1 not used on the i386.
6748   ""
6749   "*
6750 {
6751   if (GET_CODE (operands[0]) == MEM
6752       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
6753     {
6754       operands[0] = XEXP (operands[0], 0);
6755       return AS1 (call,%*%0);
6756     }
6757   else
6758     return AS1 (call,%P0);
6759 }")
6760
6761 (define_insn ""
6762   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
6763          (match_operand:SI 1 "general_operand" "g"))]
6764   ;; Operand 1 not used on the i386.
6765   "!HALF_PIC_P ()"
6766   "call %P0")
6767
6768 ;; Call subroutine, returning value in operand 0
6769 ;; (which must be a hard register).
6770
6771 (define_expand "call_value_pop"
6772   [(parallel [(set (match_operand 0 "" "")
6773                    (call (match_operand:QI 1 "indirect_operand" "")
6774                          (match_operand:SI 2 "general_operand" "")))
6775               (set (reg:SI 7)
6776                    (plus:SI (reg:SI 7)
6777                             (match_operand:SI 4 "immediate_operand" "")))])]
6778   ""
6779   "
6780 {
6781   rtx addr;
6782
6783   if (operands[4] == const0_rtx)
6784     {
6785       emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
6786       DONE;
6787     }
6788
6789   if (flag_pic)
6790     current_function_uses_pic_offset_table = 1;
6791
6792   /* With half-pic, force the address into a register.  */
6793   addr = XEXP (operands[1], 0);
6794   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6795     XEXP (operands[1], 0) = force_reg (Pmode, addr);
6796
6797   if (! expander_call_insn_operand (operands[1], QImode))
6798     operands[1]
6799       = change_address (operands[1], VOIDmode,
6800                         copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6801 }")
6802
6803 (define_insn ""
6804   [(set (match_operand 0 "" "=rf")
6805         (call (match_operand:QI 1 "call_insn_operand" "m")
6806               (match_operand:SI 2 "general_operand" "g")))
6807    (set (reg:SI 7) (plus:SI (reg:SI 7)
6808                             (match_operand:SI 4 "immediate_operand" "i")))]
6809   ""
6810   "*
6811 {
6812   if (GET_CODE (operands[1]) == MEM
6813       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6814     {
6815       operands[1] = XEXP (operands[1], 0);
6816       output_asm_insn (AS1 (call,%*%1), operands);
6817     }
6818   else
6819     output_asm_insn (AS1 (call,%P1), operands);
6820
6821   RET;
6822 }")
6823
6824 (define_insn ""
6825   [(set (match_operand 0 "" "=rf")
6826         (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6827               (match_operand:SI 2 "general_operand" "g")))
6828    (set (reg:SI 7) (plus:SI (reg:SI 7)
6829                             (match_operand:SI 4 "immediate_operand" "i")))]
6830   "!HALF_PIC_P ()"
6831   "call %P1")
6832
6833 (define_expand "call_value"
6834   [(set (match_operand 0 "" "")
6835         (call (match_operand:QI 1 "indirect_operand" "")
6836               (match_operand:SI 2 "general_operand" "")))]
6837   ;; Operand 2 not used on the i386.
6838   ""
6839   "
6840 {
6841   rtx addr;
6842
6843   if (flag_pic)
6844     current_function_uses_pic_offset_table = 1;
6845
6846   /* With half-pic, force the address into a register.  */
6847   addr = XEXP (operands[1], 0);
6848   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
6849     XEXP (operands[1], 0) = force_reg (Pmode, addr);
6850
6851   if (! expander_call_insn_operand (operands[1], QImode))
6852     operands[1]
6853       = change_address (operands[1], VOIDmode,
6854                         copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
6855 }")
6856
6857 (define_insn ""
6858   [(set (match_operand 0 "" "=rf")
6859         (call (match_operand:QI 1 "call_insn_operand" "m")
6860               (match_operand:SI 2 "general_operand" "g")))]
6861   ;; Operand 2 not used on the i386.
6862   ""
6863   "*
6864 {
6865   if (GET_CODE (operands[1]) == MEM
6866       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
6867     {
6868       operands[1] = XEXP (operands[1], 0);
6869       output_asm_insn (AS1 (call,%*%1), operands);
6870     }
6871   else
6872     output_asm_insn (AS1 (call,%P1), operands);
6873
6874   RET;
6875 }")
6876
6877 (define_insn ""
6878   [(set (match_operand 0 "" "=rf")
6879         (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
6880               (match_operand:SI 2 "general_operand" "g")))]
6881   ;; Operand 2 not used on the i386.
6882   "!HALF_PIC_P ()"
6883   "call %P1")
6884
6885 ;; Call subroutine returning any type.
6886
6887 (define_expand "untyped_call"
6888   [(parallel [(call (match_operand 0 "" "")
6889                     (const_int 0))
6890               (match_operand 1 "" "")
6891               (match_operand 2 "" "")])]
6892   ""
6893   "
6894 {
6895   int i;
6896
6897   /* In order to give reg-stack an easier job in validating two
6898      coprocessor registers as containing a possible return value,
6899      simply pretend the untyped call returns a complex long double
6900      value.  */
6901
6902   emit_call_insn (TARGET_80387
6903                   ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
6904                                     operands[0], const0_rtx)
6905                   : gen_call (operands[0], const0_rtx));
6906
6907   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6908     {
6909       rtx set = XVECEXP (operands[2], 0, i);
6910       emit_move_insn (SET_DEST (set), SET_SRC (set));
6911     }
6912
6913   /* The optimizer does not know that the call sets the function value
6914      registers we stored in the result block.  We avoid problems by
6915      claiming that all hard registers are used and clobbered at this
6916      point.  */
6917   emit_insn (gen_blockage ());
6918
6919   DONE;
6920 }")
6921
6922 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6923 ;; all of memory.  This blocks insns from being moved across this point.
6924
6925 (define_insn "blockage"
6926   [(unspec_volatile [(const_int 0)] 0)]
6927   ""
6928   ""
6929   [(set_attr "memory" "none")])
6930
6931 ;; Insn emitted into the body of a function to return from a function.
6932 ;; This is only done if the function's epilogue is known to be simple.
6933 ;; See comments for simple_386_epilogue in i386.c.
6934
6935 (define_expand "return"
6936   [(return)]
6937   "ix86_can_use_return_insn_p ()"
6938   "")
6939
6940 (define_insn "return_internal"
6941   [(return)]
6942   "reload_completed"
6943   "ret"
6944   [(set_attr "memory" "none")])
6945
6946 (define_insn "return_pop_internal"
6947   [(return)
6948    (use (match_operand:SI 0 "const_int_operand" ""))]
6949   "reload_completed"
6950   "ret %0"
6951   [(set_attr "memory" "none")])
6952
6953 (define_insn "nop"
6954   [(const_int 0)]
6955   ""
6956   "nop"
6957   [(set_attr "memory" "none")])
6958
6959 (define_expand "prologue"
6960   [(const_int 1)]
6961   ""
6962   "
6963 {
6964   ix86_expand_prologue ();
6965   DONE;
6966 }")
6967
6968 ;; The use of UNSPEC here is currently not necessary - a simple SET of ebp
6969 ;; to itself would be enough. But this way we are safe even if some optimizer
6970 ;; becomes too clever in the future.
6971 (define_insn "prologue_set_stack_ptr"
6972   [(set (reg:SI 7)
6973         (minus:SI (reg:SI 7) (match_operand:SI 0 "immediate_operand" "i")))
6974    (set (reg:SI 6) (unspec:SI [(reg:SI 6)] 4))]
6975   ""
6976   "*
6977 {
6978   rtx xops [2];
6979
6980   xops[0] = operands[0];
6981   xops[1] = stack_pointer_rtx;
6982   output_asm_insn (AS2 (sub%L1,%0,%1), xops);
6983   RET;
6984 }"
6985   [(set_attr "memory" "none")])
6986
6987 (define_insn "prologue_set_got"
6988   [(set (match_operand:SI 0 "" "")
6989         (unspec_volatile
6990          [(plus:SI (match_dup 0)
6991                    (plus:SI (match_operand:SI 1 "symbolic_operand" "")
6992                             (minus:SI (pc) (match_operand 2 "" ""))))] 1))]
6993   ""
6994   "*
6995 {
6996   char buffer[64];
6997
6998   if (TARGET_DEEP_BRANCH_PREDICTION) 
6999     {
7000       sprintf (buffer, \"addl %s,%%0\", XSTR (operands[1], 0));
7001       output_asm_insn (buffer, operands);
7002     }
7003   else  
7004     {
7005       sprintf (buffer, \"addl %s+[.-%%X2],%%0\", XSTR (operands[1], 0));
7006       output_asm_insn (buffer, operands);
7007     }    
7008   RET;
7009 }")
7010
7011 (define_insn "prologue_get_pc"
7012   [(set (match_operand:SI 0 "" "")
7013     (unspec_volatile [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
7014   ""
7015   "*
7016 {
7017   output_asm_insn (AS1 (call,%X1), operands);
7018   if (! TARGET_DEEP_BRANCH_PREDICTION) 
7019     {
7020       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1]));
7021     }    
7022   RET;
7023 }"
7024   [(set_attr "memory" "none")])
7025
7026 (define_insn "prologue_get_pc_and_set_got"
7027   [(unspec_volatile [(match_operand:SI 0 "" "")] 3)]
7028   ""
7029   "*
7030 {
7031   operands[1] = gen_label_rtx ();
7032   output_asm_insn (AS1 (call,%X1), operands);
7033   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
7034                              CODE_LABEL_NUMBER (operands[1]));
7035   output_asm_insn (AS1 (pop%L0,%0), operands);
7036   output_asm_insn (\"addl $%__GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands);
7037   RET;
7038 }"
7039   [(set_attr "memory" "none")])
7040
7041 (define_expand "epilogue"
7042   [(const_int 1)]
7043   ""
7044   "
7045 {
7046   ix86_expand_epilogue ();
7047   DONE;
7048 }")
7049
7050 (define_insn "epilogue_set_stack_ptr"
7051   [(set (reg:SI 7) (reg:SI 6))
7052         (clobber (reg:SI 6))]
7053   ""
7054   "*
7055 {
7056   rtx xops [2];
7057
7058     xops[0] = frame_pointer_rtx;
7059     xops[1] = stack_pointer_rtx;
7060     output_asm_insn (AS2 (mov%L0,%0,%1), xops);
7061     RET;
7062 }"
7063   [(set_attr "memory" "none")])
7064
7065 (define_insn "leave"
7066   [(const_int 2)
7067       (clobber (reg:SI 6))
7068       (clobber (reg:SI 7))]
7069   ""
7070   "leave"
7071   [(set_attr "memory" "none")])
7072
7073 (define_insn "pop"
7074   [(set (match_operand:SI 0 "register_operand" "r")
7075         (mem:SI (reg:SI 7)))
7076    (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))]
7077   ""
7078   "*
7079 {
7080     output_asm_insn (AS1 (pop%L0,%P0), operands);
7081     RET;
7082 }"
7083   [(set_attr "memory" "load")])
7084
7085 (define_expand "movstrsi"
7086   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
7087                    (match_operand:BLK 1 "memory_operand" ""))
7088               (use (match_operand:SI 2 "const_int_operand" ""))
7089               (use (match_operand:SI 3 "const_int_operand" ""))
7090               (clobber (match_scratch:SI 4 ""))
7091               (clobber (match_dup 5))
7092               (clobber (match_dup 6))])]
7093   ""
7094   "
7095 {
7096   rtx addr0, addr1;
7097
7098   if (GET_CODE (operands[2]) != CONST_INT)
7099     FAIL;
7100
7101   addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7102   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
7103
7104   operands[5] = addr0;
7105   operands[6] = addr1;
7106
7107   operands[0] = change_address (operands[0], VOIDmode, addr0);
7108   operands[1] = change_address (operands[1], VOIDmode, addr1);
7109 }")
7110
7111 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7112 ;; But strength reduction might offset the MEM expression.  So we let
7113 ;; reload put the address into %edi & %esi.
7114
7115 (define_insn ""
7116   [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
7117         (mem:BLK (match_operand:SI 1 "address_operand" "S")))
7118    (use (match_operand:SI 2 "const_int_operand" "n"))
7119    (use (match_operand:SI 3 "immediate_operand" "i"))
7120    (clobber (match_scratch:SI 4 "=&c"))
7121    (clobber (match_dup 0))
7122    (clobber (match_dup 1))]
7123   ""
7124   "*
7125 {
7126   rtx xops[2];
7127
7128   output_asm_insn (\"cld\", operands);
7129   if (GET_CODE (operands[2]) == CONST_INT)
7130     {
7131       if (INTVAL (operands[2]) & ~0x03)
7132         {
7133           xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
7134           xops[1] = operands[4];
7135
7136           output_asm_insn (AS2 (mov%L1,%0,%1), xops);
7137 #ifdef INTEL_SYNTAX
7138           output_asm_insn (\"rep movsd\", xops);
7139 #else
7140           output_asm_insn (\"rep\;movsl\", xops);
7141 #endif
7142         }
7143       if (INTVAL (operands[2]) & 0x02)
7144         output_asm_insn (\"movsw\", operands);
7145       if (INTVAL (operands[2]) & 0x01)
7146         output_asm_insn (\"movsb\", operands);
7147     }
7148   else
7149     abort ();
7150   RET;
7151 }")
7152
7153 (define_expand "clrstrsi"
7154   [(set (match_dup 3) (const_int 0))
7155    (parallel [(set (match_operand:BLK 0 "memory_operand" "")
7156                    (const_int 0))
7157               (use (match_operand:SI 1 "const_int_operand" ""))
7158               (use (match_operand:SI 2 "const_int_operand" ""))
7159               (use (match_dup 3))
7160               (clobber (match_scratch:SI 4 ""))
7161               (clobber (match_dup 5))])]
7162   ""
7163   "
7164 {
7165   rtx addr0;
7166
7167   if (GET_CODE (operands[1]) != CONST_INT)
7168     FAIL;
7169
7170   addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
7171
7172   operands[3] = gen_reg_rtx (SImode);
7173   operands[5] = addr0;
7174
7175   operands[0] = gen_rtx_MEM (BLKmode, addr0);
7176 }")
7177
7178 ;; It might seem that operand 0 could use predicate register_operand.
7179 ;; But strength reduction might offset the MEM expression.  So we let
7180 ;; reload put the address into %edi.
7181
7182 (define_insn "*bzero"
7183   [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
7184         (const_int 0))
7185    (use (match_operand:SI 1 "const_int_operand" "n"))
7186    (use (match_operand:SI 2 "immediate_operand" "i"))
7187    (use (match_operand:SI 3 "register_operand" "a"))
7188    (clobber (match_scratch:SI 4 "=&c"))
7189    (clobber (match_dup 0))]
7190   ""
7191   "*
7192 {
7193   rtx xops[2];
7194
7195   output_asm_insn (\"cld\", operands);
7196   if (GET_CODE (operands[1]) == CONST_INT)
7197     {
7198       unsigned int count = INTVAL (operands[1]) & 0xffffffff;
7199       if (count & ~0x03)
7200         {
7201           xops[0] = GEN_INT (count / 4);
7202           xops[1] = operands[4];
7203
7204           /* K6: stos takes 1 cycle, rep stos takes 8 + %ecx cycles.
7205              80386: 4/5+5n (+2 for set of ecx)
7206              80486: 5/7+5n (+1 for set of ecx)
7207              */
7208           if (count / 4 < ((int) ix86_cpu < (int)PROCESSOR_PENTIUM ? 4 : 6))
7209             {
7210               do
7211 #ifdef INTEL_SYNTAX
7212                 output_asm_insn (\"stosd\", xops);
7213 #else
7214                 output_asm_insn (\"stosl\", xops);
7215 #endif
7216               while ((count -= 4) > 3);
7217             }
7218           else
7219             {
7220               output_asm_insn (AS2 (mov%L1,%0,%1), xops);
7221 #ifdef INTEL_SYNTAX
7222               output_asm_insn (\"rep stosd\", xops);
7223 #else
7224               output_asm_insn (\"rep\;stosl\", xops);
7225 #endif
7226             }
7227         }
7228       if (INTVAL (operands[1]) & 0x02)
7229         output_asm_insn (\"stosw\", operands);
7230       if (INTVAL (operands[1]) & 0x01)
7231         output_asm_insn (\"stosb\", operands);
7232     }
7233   else
7234     abort ();
7235   RET;
7236 }")
7237
7238 (define_expand "cmpstrsi"
7239   [(parallel [(set (match_operand:SI 0 "general_operand" "")
7240                    (compare:SI (match_operand:BLK 1 "general_operand" "")
7241                                (match_operand:BLK 2 "general_operand" "")))
7242               (use (match_operand:SI 3 "general_operand" ""))
7243               (use (match_operand:SI 4 "immediate_operand" ""))
7244               (clobber (match_dup 5))
7245               (clobber (match_dup 6))
7246               (clobber (match_dup 3))])]
7247   ""
7248   "
7249 {
7250   rtx addr1, addr2;
7251
7252   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
7253   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
7254   operands[3] = copy_to_mode_reg (SImode, operands[3]);
7255
7256   operands[5] = addr1;
7257   operands[6] = addr2;
7258
7259   operands[1] = gen_rtx_MEM (BLKmode, addr1);
7260   operands[2] = gen_rtx_MEM (BLKmode, addr2);
7261
7262 }")
7263
7264 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
7265 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
7266
7267 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7268 ;; But strength reduction might offset the MEM expression.  So we let
7269 ;; reload put the address into %edi & %esi.
7270
7271 ;; ??? Most comparisons have a constant length, and it's therefore
7272 ;; possible to know that the length is non-zero, and to avoid the extra
7273 ;; code to handle zero-length compares.
7274
7275 (define_insn ""
7276   [(set (match_operand:SI 0 "register_operand" "=&r")
7277         (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
7278                     (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
7279    (use (match_operand:SI 3 "register_operand" "c"))
7280    (use (match_operand:SI 4 "immediate_operand" "i"))
7281    (clobber (match_dup 1))
7282    (clobber (match_dup 2))
7283    (clobber (match_dup 3))]
7284   ""
7285   "*
7286 {
7287   rtx xops[2], label;
7288
7289   label = gen_label_rtx ();
7290
7291   output_asm_insn (\"cld\", operands);
7292   output_asm_insn (AS2 (xor%L0,%0,%0), operands);
7293   output_asm_insn (\"repz\;cmps%B2\", operands);
7294   output_asm_insn (\"je %l0\", &label);
7295
7296   xops[0] = operands[0];
7297   xops[1] = const1_rtx;
7298   output_asm_insn (AS2 (sbb%L0,%0,%0), xops);
7299   if (QI_REG_P (xops[0]))
7300      output_asm_insn (AS2 (or%B0,%1,%b0), xops);
7301   else
7302      output_asm_insn (AS2 (or%L0,%1,%0), xops);
7303         
7304   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
7305   RET;
7306 }")
7307
7308 (define_insn ""
7309   [(set (cc0)
7310         (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
7311                     (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
7312    (use (match_operand:SI 2 "register_operand" "c"))
7313    (use (match_operand:SI 3 "immediate_operand" "i"))
7314    (clobber (match_dup 0))
7315    (clobber (match_dup 1))
7316    (clobber (match_dup 2))]
7317   ""
7318   "*
7319 {
7320   rtx xops[2];
7321
7322   cc_status.flags |= CC_NOT_SIGNED;
7323
7324   xops[0] = gen_rtx_REG (QImode, 0);
7325   xops[1] = CONST0_RTX (QImode);
7326
7327   output_asm_insn (\"cld\", operands);
7328   output_asm_insn (AS2 (test%B0,%1,%0), xops);
7329   return \"repz\;cmps%B2\";
7330 }")
7331
7332 \f
7333 ;; Note, you cannot optimize away the branch following the bsfl by assuming
7334 ;; that the destination is not modified if the input is 0, since not all
7335 ;; x86 implementations do this.
7336
7337 (define_expand "ffssi2"
7338   [(set (match_operand:SI 0 "general_operand" "") 
7339         (ffs:SI (match_operand:SI 1 "general_operand" "")))]
7340   ""
7341   "
7342 {
7343   rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode);
7344
7345   emit_insn (gen_ffssi_1 (temp, operands[1]));
7346   emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0);
7347   emit_jump_insn (gen_bne (label));
7348   emit_move_insn (temp, constm1_rtx);
7349   emit_label (label);
7350   temp = expand_binop (SImode, add_optab, temp, const1_rtx,
7351                        operands[0], 0, OPTAB_WIDEN);
7352
7353   if (temp != operands[0])
7354     emit_move_insn (operands[0], temp);
7355   DONE;  
7356 }")
7357
7358 (define_insn "ffssi_1"
7359   [(set (match_operand:SI 0 "register_operand" "=r")
7360         (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
7361   ""
7362   "* return AS2 (bsf%L0,%1,%0);")
7363
7364 (define_expand "ffshi2"
7365   [(set (match_operand:SI 0 "general_operand" "") 
7366         (ffs:HI (match_operand:HI 1 "general_operand" "")))]
7367   ""
7368   "
7369 {
7370   rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode);
7371
7372   emit_insn (gen_ffshi_1 (temp, operands[1]));
7373   emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0);
7374   emit_jump_insn (gen_bne (label));
7375   emit_move_insn (temp, constm1_rtx);
7376   emit_label (label);
7377   temp = expand_binop (HImode, add_optab, temp, const1_rtx,
7378                        operands[0], 0, OPTAB_WIDEN);
7379
7380   if (temp != operands[0])
7381     emit_move_insn (operands[0], temp);
7382   DONE;  
7383 }")
7384
7385 (define_insn "ffshi_1"
7386   [(set (match_operand:HI 0 "register_operand" "=r")
7387         (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
7388   ""
7389   "* return AS2 (bsf%W0,%1,%0);")
7390 \f
7391 ;; These patterns match the binary 387 instructions for addM3, subM3,
7392 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
7393 ;; SFmode.  The first is the normal insn, the second the same insn but
7394 ;; with one operand a conversion, and the third the same insn but with
7395 ;; the other operand a conversion.
7396
7397 (define_insn ""
7398   [(set (match_operand:DF 0 "register_operand" "=f,f")
7399         (match_operator:DF 3 "binary_387_op"
7400                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
7401                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
7402   "TARGET_80387"
7403   "* return output_387_binary_op (insn, operands);"
7404   [(set (attr "type") 
7405         (cond [(match_operand:DF 3 "is_mul" "") 
7406                  (const_string "fpmul")
7407                (match_operand:DF 3 "is_div" "") 
7408                  (const_string "fpdiv")
7409               ]
7410                (const_string "fpop")
7411         )
7412   )])
7413
7414 (define_insn ""
7415   [(set (match_operand:XF 0 "register_operand" "=f,f")
7416         (match_operator:XF 3 "binary_387_op"
7417                         [(match_operand:XF 1 "register_operand" "0,f")
7418                          (match_operand:XF 2 "register_operand" "f,0")]))]
7419   "TARGET_80387"
7420   "* return output_387_binary_op (insn, operands);"
7421   [(set (attr "type") 
7422         (cond [(match_operand:DF 3 "is_mul" "") 
7423                  (const_string "fpmul")
7424                (match_operand:DF 3 "is_div" "") 
7425                  (const_string "fpdiv")
7426               ]
7427                (const_string "fpop")
7428         )
7429   )])
7430
7431 (define_insn ""
7432   [(set (match_operand:XF 0 "register_operand" "=f,f")
7433         (match_operator:XF 3 "binary_387_op"
7434            [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7435             (match_operand:XF 2 "register_operand" "0,f")]))]
7436   "TARGET_80387"
7437   "* return output_387_binary_op (insn, operands);"
7438   [(set (attr "type") 
7439         (cond [(match_operand:DF 3 "is_mul" "") 
7440                  (const_string "fpmul")
7441                (match_operand:DF 3 "is_div" "") 
7442                  (const_string "fpdiv")
7443               ]
7444                (const_string "fpop")
7445         )
7446   )])
7447
7448 (define_insn ""
7449   [(set (match_operand:XF 0 "register_operand" "=f,f")
7450         (match_operator:XF 3 "binary_387_op"
7451           [(match_operand:XF 1 "register_operand" "0,f")
7452            (float_extend:XF
7453             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7454   "TARGET_80387"
7455   "* return output_387_binary_op (insn, operands);"
7456   [(set (attr "type") 
7457         (cond [(match_operand:DF 3 "is_mul" "") 
7458                  (const_string "fpmul")
7459                (match_operand:DF 3 "is_div" "") 
7460                  (const_string "fpdiv")
7461               ]
7462                (const_string "fpop")
7463         )
7464   )])
7465
7466 (define_insn ""
7467   [(set (match_operand:DF 0 "register_operand" "=f,f")
7468         (match_operator:DF 3 "binary_387_op"
7469            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7470             (match_operand:DF 2 "register_operand" "0,f")]))]
7471   "TARGET_80387"
7472   "* return output_387_binary_op (insn, operands);"
7473   [(set (attr "type") 
7474         (cond [(match_operand:DF 3 "is_mul" "") 
7475                  (const_string "fpmul")
7476                (match_operand:DF 3 "is_div" "") 
7477                  (const_string "fpdiv")
7478               ]
7479                (const_string "fpop")
7480         )
7481   )])
7482
7483 (define_insn ""
7484   [(set (match_operand:DF 0 "register_operand" "=f,f")
7485         (match_operator:DF 3 "binary_387_op"
7486           [(match_operand:DF 1 "register_operand" "0,f")
7487            (float_extend:DF
7488             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
7489   "TARGET_80387"
7490   "* return output_387_binary_op (insn, operands);"
7491   [(set (attr "type") 
7492         (cond [(match_operand:DF 3 "is_mul" "") 
7493                  (const_string "fpmul")
7494                (match_operand:DF 3 "is_div" "") 
7495                  (const_string "fpdiv")
7496               ]
7497                (const_string "fpop")
7498         )
7499   )])
7500
7501 (define_insn ""
7502   [(set (match_operand:SF 0 "register_operand" "=f,f")
7503         (match_operator:SF 3 "binary_387_op"
7504                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
7505                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
7506   "TARGET_80387"
7507   "* return output_387_binary_op (insn, operands);"
7508   [(set (attr "type") 
7509         (cond [(match_operand:DF 3 "is_mul" "") 
7510                  (const_string "fpmul")
7511                (match_operand:DF 3 "is_div" "") 
7512                  (const_string "fpdiv")
7513               ]
7514                (const_string "fpop")
7515         )
7516   )])
7517 \f
7518 (define_expand "strlensi"
7519   [(parallel [(set (match_dup 4)
7520                    (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
7521                                (match_operand:QI 2 "immediate_operand" "")
7522                                (match_operand:SI 3 "immediate_operand" "")] 0))
7523               (clobber (match_dup 1))])
7524    (set (match_dup 5)
7525         (not:SI (match_dup 4)))
7526    (set (match_operand:SI 0 "register_operand" "")
7527         (plus:SI (match_dup 5)
7528                  (const_int -1)))]
7529   ""
7530   "
7531 {
7532   if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1)
7533     {
7534       rtx address;
7535       rtx scratch;
7536
7537         /* well it seems that some optimizer does not combine a call like
7538              foo(strlen(bar), strlen(bar));
7539            when the move and the subtraction is done here.  It does calculate
7540            the length just once when these instructions are done inside of
7541            output_strlen_unroll().  But I think since &bar[strlen(bar)] is
7542            often used and I use one fewer register for the lifetime of
7543            output_strlen_unroll() this is better.  */
7544       scratch = gen_reg_rtx (SImode);
7545       address = force_reg (SImode, XEXP (operands[1], 0));
7546
7547         /* move address to scratch-register
7548            this is done here because the i586 can do the following and
7549            in the same cycle with the following move.  */
7550       if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4)
7551           emit_insn (gen_movsi (scratch, address));
7552
7553       emit_insn (gen_movsi (operands[0], address));
7554
7555       if(TARGET_USE_Q_REG)
7556         emit_insn (gen_strlensi_unroll5 (operands[0],
7557                                         operands[3],
7558                                         scratch,
7559                                         operands[0]));
7560       else
7561         emit_insn (gen_strlensi_unroll4 (operands[0],
7562                                         operands[3],
7563                                         scratch,
7564                                         operands[0]));
7565
7566         /* gen_strlensi_unroll[45] returns the address of the zero
7567            at the end of the string, like memchr(), so compute the
7568            length by subtracting the startaddress.  */
7569       emit_insn (gen_subsi3 (operands[0], operands[0], address));
7570       DONE;
7571     }
7572
7573   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7574   operands[4] = gen_reg_rtx (SImode);
7575   operands[5] = gen_reg_rtx (SImode);
7576 }")
7577
7578 ;; It might seem that operands 0 & 1 could use predicate register_operand.
7579 ;; But strength reduction might offset the MEM expression.  So we let
7580 ;; reload put the address into %edi.
7581
7582 (define_insn ""
7583   [(set (match_operand:SI 0 "register_operand" "=&c")
7584         (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
7585                     (match_operand:QI 2 "immediate_operand" "a")
7586                     (match_operand:SI 3 "immediate_operand" "i")] 0))
7587    (clobber (match_dup 1))]
7588   ""
7589   "*
7590 {
7591   rtx xops[2];
7592
7593   xops[0] = operands[0];
7594   xops[1] = constm1_rtx;
7595   output_asm_insn (\"cld\", operands);
7596   output_asm_insn (AS2 (mov%L0,%1,%0), xops);
7597   return \"repnz\;scas%B2\";
7598 }")
7599
7600 /* Conditional move define_insns.  */
7601
7602 (define_expand "movsicc"
7603   [(set (match_operand:SI 0 "register_operand" "")
7604         (if_then_else:SI (match_operand 1 "comparison_operator" "")
7605                          (match_operand:SI 2 "nonimmediate_operand" "")
7606                          (match_operand:SI 3 "nonimmediate_operand" "")))]
7607   "TARGET_CMOVE"
7608   "
7609 {
7610   if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7611     FAIL;
7612
7613   operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7614                         GET_MODE (i386_compare_op0),
7615                         i386_compare_op0, i386_compare_op1);
7616 }")
7617
7618 (define_insn ""
7619   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
7620         (if_then_else:SI (match_operator 1 "comparison_operator" 
7621               [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7622                 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7623               (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
7624               (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7625   "TARGET_CMOVE"
7626   "#")
7627
7628 (define_insn ""
7629   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
7630         (if_then_else:SI (match_operator 1 "comparison_operator" 
7631               [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7632                 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7633               (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0")
7634               (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7635   "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7636   "#")
7637
7638 (define_split
7639   [(set (match_operand:SI 0 "register_operand" "")
7640         (if_then_else:SI (match_operator 1 "comparison_operator" 
7641                                 [(match_operand 2 "nonimmediate_operand" "")
7642                                  (const_int 0)])
7643                       (match_operand:SI 3 "nonimmediate_operand" "")
7644                       (match_operand:SI 4 "nonimmediate_operand" "")))]
7645   "TARGET_CMOVE && reload_completed"
7646   [(set (cc0)
7647         (match_dup 2))
7648    (set (match_dup 0)
7649         (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7650                       (match_dup 3) (match_dup 4)))]
7651   "")
7652
7653 (define_split
7654   [(set (match_operand:SI 0 "register_operand" "")
7655         (if_then_else:SI (match_operator 1 "comparison_operator" 
7656                                 [(match_operand 2 "nonimmediate_operand" "")
7657                                  (match_operand 3 "general_operand" "")])
7658                       (match_operand:SI 4 "nonimmediate_operand" "")
7659                       (match_operand:SI 5 "nonimmediate_operand" "")))]
7660   "TARGET_CMOVE && reload_completed"
7661   [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7662    (set (match_dup 0)
7663         (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7664                       (match_dup 4) (match_dup 5)))]
7665   "")
7666
7667 (define_insn ""
7668   [(set (match_operand:SI 0 "register_operand" "=r,r")
7669         (if_then_else:SI (match_operator 1 "comparison_operator" 
7670                                 [(cc0) (const_int 0)])
7671                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
7672                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
7673   "TARGET_CMOVE && reload_completed"
7674   "* return output_int_conditional_move (which_alternative, operands);")
7675
7676 (define_expand "movhicc"
7677   [(set (match_operand:HI 0 "register_operand" "")
7678         (if_then_else:HI (match_operand 1 "comparison_operator" "")
7679                          (match_operand:HI 2 "nonimmediate_operand" "")
7680                          (match_operand:HI 3 "nonimmediate_operand" "")))]
7681   "TARGET_CMOVE"
7682   "
7683 {
7684   if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7685     FAIL;
7686
7687   operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7688                         GET_MODE (i386_compare_op0),
7689                         i386_compare_op0, i386_compare_op1);
7690 }")
7691
7692 (define_insn ""
7693   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
7694         (if_then_else:HI (match_operator 1 "comparison_operator" 
7695               [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7696                 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7697               (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
7698               (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7699   "TARGET_CMOVE"
7700   "#")
7701
7702 (define_insn ""
7703   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
7704         (if_then_else:HI (match_operator 1 "comparison_operator" 
7705               [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7706                 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7707               (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0")
7708               (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))]
7709   "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7710   "#")
7711
7712 (define_split
7713   [(set (match_operand:HI 0 "register_operand" "")
7714         (if_then_else:HI (match_operator 1 "comparison_operator" 
7715                                 [(match_operand 2 "nonimmediate_operand" "")
7716                                  (const_int 0)])
7717                       (match_operand:HI 3 "nonimmediate_operand" "")
7718                       (match_operand:HI 4 "nonimmediate_operand" "")))]
7719   "TARGET_CMOVE && reload_completed"
7720   [(set (cc0)
7721         (match_dup 2))
7722    (set (match_dup 0)
7723         (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7724                       (match_dup 3) (match_dup 4)))]
7725   "")
7726
7727 (define_split
7728   [(set (match_operand:HI 0 "register_operand" "")
7729         (if_then_else:HI (match_operator 1 "comparison_operator" 
7730                                 [(match_operand 2 "nonimmediate_operand" "")
7731                                  (match_operand 3 "general_operand" "")])
7732                       (match_operand:HI 4 "nonimmediate_operand" "")
7733                       (match_operand:HI 5 "nonimmediate_operand" "")))]
7734   "TARGET_CMOVE && reload_completed"
7735   [(set (cc0)
7736         (compare (match_dup 2) (match_dup 3)))
7737    (set (match_dup 0)
7738         (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7739                       (match_dup 4) (match_dup 5)))]
7740   "")
7741
7742 (define_insn ""
7743   [(set (match_operand:HI 0 "register_operand" "=r,r")
7744         (if_then_else:HI (match_operator 1 "comparison_operator" 
7745                                 [(cc0) (const_int 0)])
7746                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
7747                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
7748   "TARGET_CMOVE && reload_completed"
7749   "* return output_int_conditional_move (which_alternative, operands);")
7750
7751 (define_expand "movsfcc"
7752   [(set (match_operand:SF 0 "register_operand" "")
7753         (if_then_else:SF (match_operand 1 "comparison_operator" "")
7754                          (match_operand:SF 2 "register_operand" "")
7755                          (match_operand:SF 3 "register_operand" "")))]
7756   "TARGET_CMOVE"
7757   "
7758 {
7759   rtx temp;
7760
7761   if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7762     FAIL;
7763
7764   /* The floating point conditional move instructions don't directly
7765      support conditions resulting from a signed integer comparison. */
7766
7767   switch (GET_CODE (operands[1]))
7768     {
7769     case LT:
7770     case LE:
7771     case GE:
7772     case GT:
7773       temp = emit_store_flag (gen_reg_rtx (QImode),
7774                 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7775                 VOIDmode, 0, 0);
7776
7777       if (!temp)
7778         FAIL;
7779
7780       operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7781       break;
7782
7783     default:
7784       operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7785                         GET_MODE (i386_compare_op0),
7786                         i386_compare_op0, i386_compare_op1);
7787       break;
7788     }
7789 }")
7790
7791 (define_insn ""
7792   [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
7793         (if_then_else:SF (match_operator 1 "comparison_operator" 
7794               [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7795                 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7796               (match_operand:SF 4 "register_operand" "f,f,0,0")
7797               (match_operand:SF 5 "register_operand" "0,0,f,f")))]
7798   "TARGET_CMOVE
7799     && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7800     && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7801   "#")
7802
7803 (define_insn ""
7804   [(set (match_operand:SF 0 "register_operand" "=f,f,f,f")
7805         (if_then_else:SF (match_operator 1 "comparison_operator" 
7806                 [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7807                  (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7808               (match_operand:SF 4 "register_operand" "f,f,0,0")
7809               (match_operand:SF 5 "register_operand" "0,0,f,f")))]
7810   "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7811     && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7812     && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7813   "#")
7814
7815 (define_split
7816   [(set (match_operand:SF 0 "register_operand" "")
7817         (if_then_else:SF (match_operator 1 "comparison_operator" 
7818                                 [(match_operand 2 "nonimmediate_operand" "")
7819                                  (const_int 0)])
7820                       (match_operand:SF 3 "register_operand" "")
7821                       (match_operand:SF 4 "register_operand" "")))]
7822   "TARGET_CMOVE && reload_completed"
7823   [(set (cc0)
7824         (match_dup 2))
7825    (set (match_dup 0)
7826         (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7827                       (match_dup 3) (match_dup 4)))]
7828   "")
7829
7830 (define_split
7831   [(set (match_operand:SF 0 "register_operand" "")
7832         (if_then_else:SF (match_operator 1 "comparison_operator" 
7833                                 [(match_operand 2 "nonimmediate_operand" "")
7834                                  (match_operand 3 "general_operand" "")])
7835                       (match_operand:SF 4 "register_operand" "")
7836                       (match_operand:SF 5 "register_operand" "")))]
7837   "TARGET_CMOVE && reload_completed"
7838   [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7839    (set (match_dup 0)
7840         (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7841                       (match_dup 4) (match_dup 5)))]
7842   "")
7843
7844 (define_insn ""
7845   [(set (match_operand:SF 0 "register_operand" "=f,f")
7846         (if_then_else:SF (match_operator 1 "comparison_operator" 
7847                                 [(cc0) (const_int 0)])
7848                       (match_operand:SF 2 "register_operand" "f,0")
7849                       (match_operand:SF 3 "register_operand" "0,f")))]
7850   "TARGET_CMOVE && reload_completed"
7851   "* return output_fp_conditional_move (which_alternative, operands);")
7852
7853 (define_expand "movdfcc"
7854   [(set (match_operand:DF 0 "register_operand" "")
7855         (if_then_else:DF (match_operand 1 "comparison_operator" "")
7856                          (match_operand:DF 2 "register_operand" "")
7857                          (match_operand:DF 3 "register_operand" "")))]
7858   "TARGET_CMOVE"
7859   "
7860 {
7861   rtx temp;
7862
7863   if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7864     FAIL;
7865
7866   /* The floating point conditional move instructions don't directly
7867      support conditions resulting from a signed integer comparison. */
7868
7869   switch (GET_CODE (operands[1]))
7870     {
7871     case LT:
7872     case LE:
7873     case GE:
7874     case GT:
7875       temp = emit_store_flag (gen_reg_rtx (QImode),
7876                 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7877                 VOIDmode, 0, 0);
7878
7879       if (!temp)
7880         FAIL;
7881
7882       operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7883       break;
7884
7885     default:
7886       operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7887                         GET_MODE (i386_compare_op0),
7888                         i386_compare_op0, i386_compare_op1);
7889       break;
7890     }
7891 }")
7892
7893 (define_insn ""
7894   [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
7895         (if_then_else:DF (match_operator 1 "comparison_operator" 
7896               [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7897                 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
7898               (match_operand:DF 4 "register_operand" "f,f,0,0")
7899               (match_operand:DF 5 "register_operand" "0,0,f,f")))]
7900   "TARGET_CMOVE
7901     && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7902     && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7903   "#")
7904
7905 (define_insn ""
7906   [(set (match_operand:DF 0 "register_operand" "=f,f,f,f")
7907         (if_then_else:DF (match_operator 1 "comparison_operator" 
7908               [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
7909                 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
7910               (match_operand:DF 4 "register_operand" "f,f,0,0")
7911               (match_operand:DF 5 "register_operand" "0,0,f,f")))]
7912   "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7913     && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7914     && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
7915   "#")
7916
7917 (define_split
7918   [(set (match_operand:DF 0 "register_operand" "")
7919         (if_then_else:DF (match_operator 1 "comparison_operator" 
7920                                 [(match_operand 2 "nonimmediate_operand" "")
7921                                  (const_int 0)])
7922                       (match_operand:DF 3 "register_operand" "")
7923                       (match_operand:DF 4 "register_operand" "")))]
7924   "TARGET_CMOVE && reload_completed"
7925   [(set (cc0)
7926         (match_dup 2))
7927    (set (match_dup 0)
7928         (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7929                       (match_dup 3) (match_dup 4)))]
7930   "")
7931
7932 (define_split
7933   [(set (match_operand:DF 0 "register_operand" "")
7934         (if_then_else:DF (match_operator 1 "comparison_operator" 
7935                                 [(match_operand 2 "nonimmediate_operand" "")
7936                                  (match_operand 3 "general_operand" "")])
7937                       (match_operand:DF 4 "register_operand" "")
7938                       (match_operand:DF 5 "register_operand" "")))]
7939   "TARGET_CMOVE && reload_completed"
7940   [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7941    (set (match_dup 0)
7942         (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7943                       (match_dup 4) (match_dup 5)))]
7944   "")
7945
7946 (define_insn ""
7947   [(set (match_operand:DF 0 "register_operand" "=f,f")
7948         (if_then_else:DF (match_operator 1 "comparison_operator" 
7949                                 [(cc0) (const_int 0)])
7950                       (match_operand:DF 2 "register_operand" "f,0")
7951                       (match_operand:DF 3 "register_operand" "0,f")))]
7952   "TARGET_CMOVE && reload_completed"
7953   "* return output_fp_conditional_move (which_alternative, operands);")
7954
7955 (define_expand "movxfcc"
7956   [(set (match_operand:XF 0 "register_operand" "")
7957         (if_then_else:XF (match_operand 1 "comparison_operator" "")
7958                          (match_operand:XF 2 "register_operand" "")
7959                          (match_operand:XF 3 "register_operand" "")))]
7960   "TARGET_CMOVE"
7961   "
7962 {
7963   rtx temp;
7964
7965   if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7966     FAIL;
7967
7968   /* The floating point conditional move instructions don't directly
7969      support conditions resulting from a signed integer comparison. */
7970
7971   switch (GET_CODE (operands[1]))
7972     {
7973     case LT:
7974     case LE:
7975     case GE:
7976     case GT:
7977       temp = emit_store_flag (gen_reg_rtx (QImode),
7978                 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7979                 VOIDmode, 0, 0);
7980
7981       if (!temp)
7982         FAIL;
7983
7984       operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7985       break;
7986
7987     default:
7988       operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7989                         GET_MODE (i386_compare_op0),
7990                         i386_compare_op0, i386_compare_op1);
7991       break;
7992     }
7993 }")
7994
7995 (define_insn ""
7996   [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
7997         (if_then_else:XF (match_operator 1 "comparison_operator" 
7998               [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
7999                 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
8000               (match_operand:XF 4 "register_operand" "f,f,0,0")
8001               (match_operand:XF 5 "register_operand" "0,0,f,f")))]
8002   "TARGET_CMOVE
8003     && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
8004     && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
8005   "#")
8006
8007 (define_insn ""
8008   [(set (match_operand:XF 0 "register_operand" "=f,f,f,f")
8009         (if_then_else:XF (match_operator 1 "comparison_operator" 
8010               [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
8011                 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
8012               (match_operand:XF 4 "register_operand" "f,f,0,0")
8013               (match_operand:XF 5 "register_operand" "0,0,f,f")))]
8014   "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
8015     && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
8016     && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
8017   "#")
8018
8019 (define_split
8020   [(set (match_operand:XF 0 "register_operand" "")
8021         (if_then_else:XF (match_operator 1 "comparison_operator" 
8022                                 [(match_operand 2 "nonimmediate_operand" "")
8023                                  (const_int 0)])
8024                       (match_operand:XF 3 "register_operand" "")
8025                       (match_operand:XF 4 "register_operand" "")))]
8026   "TARGET_CMOVE && reload_completed"
8027   [(set (cc0)
8028         (match_dup 2))
8029    (set (match_dup 0)
8030         (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
8031                       (match_dup 3) (match_dup 4)))]
8032   "")
8033
8034 (define_split
8035   [(set (match_operand:XF 0 "register_operand" "")
8036         (if_then_else:XF (match_operator 1 "comparison_operator" 
8037                                 [(match_operand 2 "nonimmediate_operand" "")
8038                                  (match_operand 3 "general_operand" "")])
8039                       (match_operand:XF 4 "register_operand" "")
8040                       (match_operand:XF 5 "register_operand" "")))]
8041   "TARGET_CMOVE && reload_completed"
8042   [(set (cc0) (compare (match_dup 2) (match_dup 3)))
8043    (set (match_dup 0)
8044         (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
8045                       (match_dup 4) (match_dup 5)))]
8046   "")
8047
8048 (define_insn ""
8049   [(set (match_operand:XF 0 "register_operand" "=f,f")
8050         (if_then_else:XF (match_operator 1 "comparison_operator" 
8051                                 [(cc0) (const_int 0)])
8052                       (match_operand:XF 2 "register_operand" "f,0")
8053                       (match_operand:XF 3 "register_operand" "0,f")))]
8054   "TARGET_CMOVE && reload_completed"
8055   "* return output_fp_conditional_move (which_alternative, operands);")
8056
8057 (define_expand "movdicc"
8058   [(set (match_operand:DI 0 "register_operand" "")
8059         (if_then_else:DI (match_operand 1 "comparison_operator" "")
8060                          (match_operand:DI 2 "nonimmediate_operand" "")
8061                          (match_operand:DI 3 "nonimmediate_operand" "")))]
8062   "TARGET_CMOVE"
8063   "
8064 {
8065   if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
8066     FAIL;
8067
8068   operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
8069                         GET_MODE (i386_compare_op0),
8070                         i386_compare_op0, i386_compare_op1);
8071 }")
8072
8073 (define_insn ""
8074   [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
8075         (if_then_else:DI (match_operator 1 "comparison_operator" 
8076               [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m")
8077                 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")])
8078               (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
8079               (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
8080   "TARGET_CMOVE"
8081   "#")
8082
8083 (define_insn ""
8084   [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r")
8085         (if_then_else:DI (match_operator 1 "comparison_operator" 
8086               [(match_operand 2 "nonimmediate_operand" "r,m,r,m")
8087                 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")])
8088               (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0")
8089               (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))]
8090   "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
8091   "#")
8092
8093 (define_split
8094   [(set (match_operand:DI 0 "register_operand" "")
8095         (if_then_else:DI (match_operator 1 "comparison_operator" 
8096                                 [(match_operand 2 "nonimmediate_operand" "")
8097                                  (const_int 0)])
8098                       (match_operand:DI 3 "nonimmediate_operand" "")
8099                       (match_operand:DI 4 "nonimmediate_operand" "")))]
8100   "TARGET_CMOVE && reload_completed"
8101   [(set (cc0)
8102         (match_dup 2))
8103    (set (match_dup 5)
8104         (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8105                       (match_dup 7) (match_dup 9)))
8106    (set (match_dup 6)
8107         (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8108                       (match_dup 8) (match_dup 10)))]
8109   "split_di (&operands[0], 1, &operands[5], &operands[6]);
8110    split_di (&operands[3], 1, &operands[7], &operands[8]);
8111    split_di (&operands[4], 1, &operands[9], &operands[10]);")
8112
8113 (define_split
8114   [(set (match_operand:DI 0 "register_operand" "")
8115         (if_then_else:DI (match_operator 1 "comparison_operator" 
8116                                 [(match_operand 2 "nonimmediate_operand" "")
8117                                  (match_operand 3 "general_operand" "")])
8118                       (match_operand:DI 4 "nonimmediate_operand" "")
8119                       (match_operand:DI 5 "nonimmediate_operand" "")))]
8120   "TARGET_CMOVE && reload_completed"
8121   [(set (cc0) (compare (match_dup 2) (match_dup 3)))
8122    (set (match_dup 6)
8123         (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8124                       (match_dup 8) (match_dup 10)))
8125    (set (match_dup 7)
8126         (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
8127                       (match_dup 9) (match_dup 11)))]
8128   "split_di (&operands[0], 1, &operands[6], &operands[7]);
8129    split_di (&operands[4], 1, &operands[8], &operands[9]);
8130    split_di (&operands[5], 1, &operands[10], &operands[11]);")
8131
8132 (define_insn "strlensi_unroll"
8133   [(set (match_operand:SI 0 "register_operand" "=&r,&r")
8134         (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r"))
8135                     (match_operand:SI 2 "immediate_operand" "i,i")] 0))
8136    (clobber (match_scratch:SI 3 "=&q,&r"))]
8137   "optimize > 1"
8138   "* return output_strlen_unroll (operands);")
8139
8140 ;; the only difference between the following patterns is the register preference
8141 ;; on a pentium using a q-register saves one clock cycle per 4 characters
8142
8143 (define_insn "strlensi_unroll4"
8144   [(set (match_operand:SI 0 "register_operand" "=r,r")
8145                    (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0"))
8146                                (match_operand:SI 1 "immediate_operand" "i,i")
8147                                (match_operand:SI 2 "register_operand" "+q,!r")] 0))
8148    (clobber (match_dup 2))]
8149   "(TARGET_USE_ANY_REG && optimize > 1)"
8150   "* return output_strlen_unroll (operands);")
8151
8152 (define_insn "strlensi_unroll5"
8153   [(set (match_operand:SI 0 "register_operand" "=r")
8154                    (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0"))
8155                                (match_operand:SI 1 "immediate_operand" "i")
8156                                (match_operand:SI 2 "register_operand" "+q")] 0))
8157    (clobber (match_dup 2))]
8158   "(TARGET_USE_Q_REG && optimize > 1)"
8159   "* return output_strlen_unroll (operands);"
8160 )
8161
8162 (define_insn "allocate_stack_worker"
8163   [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
8164    (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
8165    (clobber (match_dup 0))]
8166   "TARGET_STACK_PROBE"
8167   "* return AS1(call,__alloca);"
8168   [(set_attr "memory" "none")])
8169
8170 (define_expand "allocate_stack"
8171   [(set (match_operand:SI 0 "register_operand" "=r")
8172         (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" "")))
8173    (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))]
8174    "TARGET_STACK_PROBE"
8175   "
8176 {
8177 #ifdef CHECK_STACK_LIMIT
8178   if (GET_CODE (operands[1]) == CONST_INT
8179       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
8180     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
8181                            operands[1]));
8182   else 
8183 #endif
8184     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
8185                                                             operands[1])));
8186
8187   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
8188   DONE;
8189 }")
8190
8191 (define_expand "exception_receiver"
8192   [(const_int 0)]
8193   "flag_pic"
8194   "
8195 {
8196   load_pic_register (1);
8197   DONE;
8198 }")
8199
8200 (define_expand "builtin_setjmp_receiver"
8201   [(label_ref (match_operand 0 "" ""))]
8202   "flag_pic"
8203   "
8204 {
8205   load_pic_register (1);
8206   DONE;
8207 }")