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