]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.md
i386.c (output_fp_conditional_move): Don't bother handling (cc_prev_status.flags...
[gcc.git] / gcc / config / i386 / i386.md
CommitLineData
f25aca7a 1; GCC machine description for Intel X86.
e5e809f4 2;; Copyright (C) 1988, 94, 95, 96, 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.
ce193852 66;; 5 This is a `bsf' operation.
2ae0f82c
SC
67\f
68;; This shadows the processor_type enumeration, so changes must be made
69;; to i386.h at the same time.
70
36cf4bcf 71(define_attr "type" "integer,idiv,imul,fld,fpop,fpdiv,fpmul"
2ae0f82c
SC
72 (const_string "integer"))
73
74;; Functional units
75
36cf4bcf
SC
76; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
77; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
78
79; pentiumpro has a reservation station with 5 ports
80; port 0 has integer, float add, integer divide, float divide, float
81; multiply, and shifter units.
82; port 1 has integer, and jump units.
83; port 2 has the load address generation unit
84; ports 3 and 4 have the store address generation units
85
86; pentium has two integer pipelines, the main u pipe and the secondary v pipe.
87; and a float pipeline
88
2ae0f82c
SC
89;; Floating point
90
91(define_function_unit "fp" 1 0
36cf4bcf 92 (and (eq_attr "type" "fpop") (eq_attr "cpu" "i386,i486"))
2ae0f82c
SC
93 5 5)
94
95(define_function_unit "fp" 1 0
36cf4bcf 96 (and (eq_attr "type" "fpop") (eq_attr "cpu" "pentium,pentiumpro"))
2ae0f82c
SC
97 3 0)
98
36cf4bcf
SC
99(define_function_unit "fp" 1 0
100 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium"))
101 7 0)
102
103(define_function_unit "fp" 1 0
104 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro"))
105 5 0)
106
107(define_function_unit "fp" 1 0
108 (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro"))
109 10 10)
110
111(define_function_unit "fp" 1 0
112 (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro"))
113 6 0)
114
2ae0f82c
SC
115(define_function_unit "fp" 1 0
116 (eq_attr "type" "fpdiv")
117 10 10)
118
119(define_function_unit "fp" 1 0
120 (eq_attr "type" "fld")
121 1 0)
122
123(define_function_unit "integer" 1 0
124 (and (eq_attr "type" "integer") (eq_attr "cpu" "!i386"))
125 2 0)
126
886c62d1 127\f
886c62d1
JVA
128;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
129;; But restricting MEM here would mean that gcc could not remove a redundant
130;; test in cases like "incl MEM / je TARGET".
131;;
132;; We don't want to allow a constant operand for test insns because
133;; (set (cc0) (const_int foo)) has no mode information. Such insns will
134;; be folded while optimizing anyway.
135
c572e5ba
JVA
136;; All test insns have expanders that save the operands away without
137;; actually generating RTL. The bCOND or sCOND (emitted immediately
138;; after the tstM or cmp) will actually emit the tstM or cmpM.
139
268bfa44 140;; Processor type -- this attribute must exactly match the processor_type
926b3fae 141;; enumeration in i386.h.
268bfa44 142
926b3fae 143(define_attr "cpu" "i386,i486,pentium,pentiumpro"
2ae0f82c 144 (const (symbol_ref "ix86_cpu")))
268bfa44 145
fe4435d9 146(define_insn "tstsi_1"
886c62d1
JVA
147 [(set (cc0)
148 (match_operand:SI 0 "nonimmediate_operand" "rm"))]
149 ""
150 "*
151{
152 if (REG_P (operands[0]))
153 return AS2 (test%L0,%0,%0);
154
155 operands[1] = const0_rtx;
156 return AS2 (cmp%L0,%1,%0);
157}")
158
c572e5ba
JVA
159(define_expand "tstsi"
160 [(set (cc0)
161 (match_operand:SI 0 "nonimmediate_operand" ""))]
162 ""
163 "
164{
fe4435d9 165 i386_compare_gen = gen_tstsi_1;
c572e5ba 166 i386_compare_op0 = operands[0];
726e2d54 167 i386_compare_op1 = const0_rtx;
c572e5ba
JVA
168 DONE;
169}")
170
fe4435d9 171(define_insn "tsthi_1"
886c62d1
JVA
172 [(set (cc0)
173 (match_operand:HI 0 "nonimmediate_operand" "rm"))]
174 ""
175 "*
176{
177 if (REG_P (operands[0]))
178 return AS2 (test%W0,%0,%0);
179
180 operands[1] = const0_rtx;
181 return AS2 (cmp%W0,%1,%0);
182}")
183
c572e5ba
JVA
184(define_expand "tsthi"
185 [(set (cc0)
186 (match_operand:HI 0 "nonimmediate_operand" ""))]
187 ""
188 "
189{
fe4435d9 190 i386_compare_gen = gen_tsthi_1;
c572e5ba 191 i386_compare_op0 = operands[0];
726e2d54 192 i386_compare_op1 = const0_rtx;
c572e5ba
JVA
193 DONE;
194}")
195
fe4435d9 196(define_insn "tstqi_1"
886c62d1
JVA
197 [(set (cc0)
198 (match_operand:QI 0 "nonimmediate_operand" "qm"))]
199 ""
200 "*
201{
202 if (REG_P (operands[0]))
203 return AS2 (test%B0,%0,%0);
204
205 operands[1] = const0_rtx;
206 return AS2 (cmp%B0,%1,%0);
207}")
208
c572e5ba
JVA
209(define_expand "tstqi"
210 [(set (cc0)
211 (match_operand:QI 0 "nonimmediate_operand" ""))]
212 ""
213 "
214{
fe4435d9 215 i386_compare_gen = gen_tstqi_1;
c572e5ba 216 i386_compare_op0 = operands[0];
726e2d54 217 i386_compare_op1 = const0_rtx;
c572e5ba
JVA
218 DONE;
219}")
220
221(define_insn "tstsf_cc"
886c62d1
JVA
222 [(set (cc0)
223 (match_operand:SF 0 "register_operand" "f"))
224 (clobber (match_scratch:HI 1 "=a"))]
c572e5ba 225 "TARGET_80387 && ! TARGET_IEEE_FP"
886c62d1
JVA
226 "*
227{
228 if (! STACK_TOP_P (operands[0]))
229 abort ();
230
231 output_asm_insn (\"ftst\", operands);
886c62d1
JVA
232
233 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
234 output_asm_insn (AS1 (fstp,%y0), operands);
235
2f2a49e8 236 return output_fp_cc0_set (insn);
c572e5ba
JVA
237}")
238
239;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
240;; isn't IEEE compliant.
886c62d1 241
c572e5ba
JVA
242(define_expand "tstsf"
243 [(parallel [(set (cc0)
244 (match_operand:SF 0 "register_operand" ""))
245 (clobber (match_scratch:HI 1 ""))])]
246 "TARGET_80387 && ! TARGET_IEEE_FP"
247 "
248{
249 i386_compare_gen = gen_tstsf_cc;
250 i386_compare_op0 = operands[0];
726e2d54 251 i386_compare_op1 = const0_rtx;
c572e5ba 252 DONE;
886c62d1
JVA
253}")
254
c572e5ba 255(define_insn "tstdf_cc"
886c62d1
JVA
256 [(set (cc0)
257 (match_operand:DF 0 "register_operand" "f"))
258 (clobber (match_scratch:HI 1 "=a"))]
c572e5ba 259 "TARGET_80387 && ! TARGET_IEEE_FP"
886c62d1
JVA
260 "*
261{
262 if (! STACK_TOP_P (operands[0]))
263 abort ();
264
265 output_asm_insn (\"ftst\", operands);
886c62d1
JVA
266
267 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
268 output_asm_insn (AS1 (fstp,%y0), operands);
269
2f2a49e8 270 return output_fp_cc0_set (insn);
c572e5ba 271}")
886c62d1 272
c572e5ba
JVA
273;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
274;; isn't IEEE compliant.
275
276(define_expand "tstdf"
277 [(parallel [(set (cc0)
278 (match_operand:DF 0 "register_operand" ""))
279 (clobber (match_scratch:HI 1 ""))])]
280 "TARGET_80387 && ! TARGET_IEEE_FP"
281 "
282{
283 i386_compare_gen = gen_tstdf_cc;
284 i386_compare_op0 = operands[0];
726e2d54 285 i386_compare_op1 = const0_rtx;
c572e5ba 286 DONE;
886c62d1 287}")
4fb21e90
JVA
288
289(define_insn "tstxf_cc"
290 [(set (cc0)
291 (match_operand:XF 0 "register_operand" "f"))
292 (clobber (match_scratch:HI 1 "=a"))]
293 "TARGET_80387 && ! TARGET_IEEE_FP"
294 "*
295{
296 if (! STACK_TOP_P (operands[0]))
297 abort ();
298
299 output_asm_insn (\"ftst\", operands);
300
301 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
302 output_asm_insn (AS1 (fstp,%y0), operands);
303
2f2a49e8 304 return output_fp_cc0_set (insn);
4fb21e90
JVA
305}")
306
2ae0f82c 307;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode
4fb21e90
JVA
308;; isn't IEEE compliant.
309
310(define_expand "tstxf"
311 [(parallel [(set (cc0)
312 (match_operand:XF 0 "register_operand" ""))
313 (clobber (match_scratch:HI 1 ""))])]
314 "TARGET_80387 && ! TARGET_IEEE_FP"
315 "
316{
317 i386_compare_gen = gen_tstxf_cc;
318 i386_compare_op0 = operands[0];
726e2d54 319 i386_compare_op1 = const0_rtx;
4fb21e90
JVA
320 DONE;
321}")
886c62d1 322\f
c572e5ba
JVA
323;;- compare instructions. See comments above tstM patterns about
324;; expansion of these insns.
886c62d1 325
fe4435d9 326(define_insn "cmpsi_1"
886c62d1 327 [(set (cc0)
fe4435d9
JVA
328 (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
329 (match_operand:SI 1 "general_operand" "ri,mr")))]
330 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
9bc6d2c2 331 "* return AS2 (cmp%L0,%1,%0);")
886c62d1 332
c572e5ba 333(define_expand "cmpsi"
886c62d1 334 [(set (cc0)
fe4435d9
JVA
335 (compare (match_operand:SI 0 "nonimmediate_operand" "")
336 (match_operand:SI 1 "general_operand" "")))]
c572e5ba
JVA
337 ""
338 "
339{
fe4435d9
JVA
340 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
341 operands[0] = force_reg (SImode, operands[0]);
342
343 i386_compare_gen = gen_cmpsi_1;
c572e5ba
JVA
344 i386_compare_op0 = operands[0];
345 i386_compare_op1 = operands[1];
346 DONE;
347}")
348
fe4435d9 349(define_insn "cmphi_1"
c572e5ba 350 [(set (cc0)
fe4435d9
JVA
351 (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
352 (match_operand:HI 1 "general_operand" "ri,mr")))]
353 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
9bc6d2c2 354 "* return AS2 (cmp%W0,%1,%0);")
886c62d1 355
c572e5ba 356(define_expand "cmphi"
886c62d1 357 [(set (cc0)
fe4435d9
JVA
358 (compare (match_operand:HI 0 "nonimmediate_operand" "")
359 (match_operand:HI 1 "general_operand" "")))]
c572e5ba
JVA
360 ""
361 "
362{
fe4435d9
JVA
363 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
364 operands[0] = force_reg (HImode, operands[0]);
365
366 i386_compare_gen = gen_cmphi_1;
c572e5ba
JVA
367 i386_compare_op0 = operands[0];
368 i386_compare_op1 = operands[1];
369 DONE;
370}")
371
fe4435d9 372(define_insn "cmpqi_1"
c572e5ba 373 [(set (cc0)
fe4435d9
JVA
374 (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
375 (match_operand:QI 1 "general_operand" "qm,nq")))]
376 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
9bc6d2c2 377 "* return AS2 (cmp%B0,%1,%0);")
886c62d1 378
c572e5ba
JVA
379(define_expand "cmpqi"
380 [(set (cc0)
fe4435d9
JVA
381 (compare (match_operand:QI 0 "nonimmediate_operand" "")
382 (match_operand:QI 1 "general_operand" "")))]
c572e5ba
JVA
383 ""
384 "
385{
fe4435d9
JVA
386 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
387 operands[0] = force_reg (QImode, operands[0]);
388
389 i386_compare_gen = gen_cmpqi_1;
c572e5ba
JVA
390 i386_compare_op0 = operands[0];
391 i386_compare_op1 = operands[1];
392 DONE;
393}")
394
886c62d1
JVA
395;; These implement float point compares. For each of DFmode and
396;; SFmode, there is the normal insn, and an insn where the second operand
397;; is converted to the desired mode.
398
4fb21e90
JVA
399(define_insn ""
400 [(set (cc0)
401 (match_operator 2 "VOIDmode_compare_op"
cac58785
SC
402 [(match_operand:XF 0 "register_operand" "f")
403 (match_operand:XF 1 "register_operand" "f")]))
404 (clobber (match_scratch:HI 3 "=a"))]
405 "TARGET_80387"
2f2a49e8 406 "* return output_float_compare (insn, operands);")
4fb21e90
JVA
407
408(define_insn ""
409 [(set (cc0)
410 (match_operator 2 "VOIDmode_compare_op"
411 [(match_operand:XF 0 "register_operand" "f")
412 (float:XF
413 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
414 (clobber (match_scratch:HI 3 "=a"))]
415 "TARGET_80387"
2f2a49e8 416 "* return output_float_compare (insn, operands);")
4fb21e90
JVA
417
418(define_insn ""
419 [(set (cc0)
420 (match_operator 2 "VOIDmode_compare_op"
421 [(float:XF
422 (match_operand:SI 0 "nonimmediate_operand" "rm"))
423 (match_operand:XF 1 "register_operand" "f")]))
424 (clobber (match_scratch:HI 3 "=a"))]
425 "TARGET_80387"
2f2a49e8 426 "* return output_float_compare (insn, operands);")
4fb21e90
JVA
427
428(define_insn ""
429 [(set (cc0)
430 (match_operator 2 "VOIDmode_compare_op"
431 [(match_operand:XF 0 "register_operand" "f")
432 (float_extend:XF
433 (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
434 (clobber (match_scratch:HI 3 "=a"))]
435 "TARGET_80387"
2f2a49e8 436 "* return output_float_compare (insn, operands);")
4fb21e90 437
926b3fae
SC
438(define_insn ""
439 [(set (cc0)
440 (match_operator 2 "VOIDmode_compare_op"
441 [(float_extend:XF
442 (match_operand:DF 1 "nonimmediate_operand" "fm"))
443 (match_operand:XF 0 "register_operand" "f")]))
444 (clobber (match_scratch:HI 3 "=a"))]
445 "TARGET_80387"
446 "* return output_float_compare (insn, operands);")
447
4fb21e90
JVA
448(define_insn ""
449 [(set (cc0)
450 (match_operator 2 "VOIDmode_compare_op"
451 [(match_operand:XF 0 "register_operand" "f")
452 (float_extend:XF
453 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
454 (clobber (match_scratch:HI 3 "=a"))]
455 "TARGET_80387"
2f2a49e8 456 "* return output_float_compare (insn, operands);")
4fb21e90
JVA
457
458(define_insn ""
459 [(set (cc0)
460 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
461 (match_operand:XF 1 "register_operand" "f")))
462 (clobber (match_scratch:HI 2 "=a"))]
463 "TARGET_80387"
2f2a49e8 464 "* return output_float_compare (insn, operands);")
4fb21e90 465
fe4435d9 466(define_insn ""
08a7baac 467 [(set (cc0)
fe4435d9
JVA
468 (match_operator 2 "VOIDmode_compare_op"
469 [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
470 (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
471 (clobber (match_scratch:HI 3 "=a,a"))]
08a7baac
JVA
472 "TARGET_80387
473 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f2a49e8 474 "* return output_float_compare (insn, operands);")
08a7baac
JVA
475
476(define_insn ""
c572e5ba 477 [(set (cc0)
fe4435d9
JVA
478 (match_operator 2 "VOIDmode_compare_op"
479 [(match_operand:DF 0 "register_operand" "f")
480 (float:DF
481 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
482 (clobber (match_scratch:HI 3 "=a"))]
886c62d1 483 "TARGET_80387"
2f2a49e8 484 "* return output_float_compare (insn, operands);")
886c62d1 485
c572e5ba
JVA
486(define_insn ""
487 [(set (cc0)
fe4435d9
JVA
488 (match_operator 2 "VOIDmode_compare_op"
489 [(float:DF
490 (match_operand:SI 0 "nonimmediate_operand" "rm"))
491 (match_operand:DF 1 "register_operand" "f")]))
492 (clobber (match_scratch:HI 3 "=a"))]
886c62d1 493 "TARGET_80387"
2f2a49e8 494 "* return output_float_compare (insn, operands);")
886c62d1 495
c572e5ba
JVA
496(define_insn ""
497 [(set (cc0)
fe4435d9
JVA
498 (match_operator 2 "VOIDmode_compare_op"
499 [(match_operand:DF 0 "register_operand" "f")
500 (float_extend:DF
501 (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
502 (clobber (match_scratch:HI 3 "=a"))]
08a7baac 503 "TARGET_80387"
2f2a49e8 504 "* return output_float_compare (insn, operands);")
08a7baac
JVA
505
506(define_insn ""
507 [(set (cc0)
fe4435d9
JVA
508 (match_operator 2 "VOIDmode_compare_op"
509 [(float_extend:DF
510 (match_operand:SF 0 "nonimmediate_operand" "fm"))
511 (match_operand:DF 1 "register_operand" "f")]))
512 (clobber (match_scratch:HI 3 "=a"))]
c572e5ba 513 "TARGET_80387"
2f2a49e8 514 "* return output_float_compare (insn, operands);")
2bb7a0f5 515
2ae0f82c
SC
516(define_insn ""
517 [(set (cc0)
518 (match_operator 2 "VOIDmode_compare_op"
519 [(float_extend:DF
520 (match_operand:SF 0 "register_operand" "f"))
521 (match_operand:DF 1 "nonimmediate_operand" "fm")]))
522 (clobber (match_scratch:HI 3 "=a"))]
523 "TARGET_80387"
524 "* return output_float_compare (insn, operands);")
525
886c62d1
JVA
526(define_insn ""
527 [(set (cc0)
c572e5ba
JVA
528 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
529 (match_operand:DF 1 "register_operand" "f")))
886c62d1
JVA
530 (clobber (match_scratch:HI 2 "=a"))]
531 "TARGET_80387"
2f2a49e8 532 "* return output_float_compare (insn, operands);")
886c62d1 533
fe4435d9
JVA
534;; These two insns will never be generated by combine due to the mode of
535;; the COMPARE.
536;(define_insn ""
537; [(set (cc0)
538; (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
539; (float_extend:DF
540; (match_operand:SF 1 "register_operand" "f"))))
541; (clobber (match_scratch:HI 2 "=a"))]
542; "TARGET_80387"
2f2a49e8 543; "* return output_float_compare (insn, operands);")
fe4435d9
JVA
544;
545;(define_insn ""
546; [(set (cc0)
547; (compare:CCFPEQ (float_extend:DF
548; (match_operand:SF 0 "register_operand" "f"))
549; (match_operand:DF 1 "register_operand" "f")))
550; (clobber (match_scratch:HI 2 "=a"))]
551; "TARGET_80387"
2f2a49e8 552; "* return output_float_compare (insn, operands);")
fe4435d9
JVA
553
554(define_insn "cmpsf_cc_1"
08a7baac 555 [(set (cc0)
fe4435d9
JVA
556 (match_operator 2 "VOIDmode_compare_op"
557 [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
558 (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
559 (clobber (match_scratch:HI 3 "=a,a"))]
08a7baac
JVA
560 "TARGET_80387
561 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2f2a49e8 562 "* return output_float_compare (insn, operands);")
08a7baac
JVA
563
564(define_insn ""
c572e5ba 565 [(set (cc0)
fe4435d9
JVA
566 (match_operator 2 "VOIDmode_compare_op"
567 [(match_operand:SF 0 "register_operand" "f")
568 (float:SF
569 (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
570 (clobber (match_scratch:HI 3 "=a"))]
886c62d1 571 "TARGET_80387"
2f2a49e8 572 "* return output_float_compare (insn, operands);")
886c62d1
JVA
573
574(define_insn ""
575 [(set (cc0)
fe4435d9
JVA
576 (match_operator 2 "VOIDmode_compare_op"
577 [(float:SF
578 (match_operand:SI 0 "nonimmediate_operand" "rm"))
579 (match_operand:SF 1 "register_operand" "f")]))
580 (clobber (match_scratch:HI 3 "=a"))]
886c62d1 581 "TARGET_80387"
2f2a49e8 582 "* return output_float_compare (insn, operands);")
886c62d1
JVA
583
584(define_insn ""
585 [(set (cc0)
c572e5ba
JVA
586 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
587 (match_operand:SF 1 "register_operand" "f")))
886c62d1
JVA
588 (clobber (match_scratch:HI 2 "=a"))]
589 "TARGET_80387"
2f2a49e8 590 "* return output_float_compare (insn, operands);")
886c62d1 591
4fb21e90
JVA
592(define_expand "cmpxf"
593 [(set (cc0)
594 (compare (match_operand:XF 0 "register_operand" "")
cac58785 595 (match_operand:XF 1 "register_operand" "")))]
4fb21e90
JVA
596 "TARGET_80387"
597 "
598{
599 i386_compare_gen = gen_cmpxf_cc;
600 i386_compare_gen_eq = gen_cmpxf_ccfpeq;
601 i386_compare_op0 = operands[0];
cac58785 602 i386_compare_op1 = operands[1];
4fb21e90
JVA
603 DONE;
604}")
605
c572e5ba 606(define_expand "cmpdf"
886c62d1 607 [(set (cc0)
fe4435d9 608 (compare (match_operand:DF 0 "register_operand" "")
2ae0f82c 609 (match_operand:DF 1 "general_operand" "")))]
886c62d1 610 "TARGET_80387"
c572e5ba
JVA
611 "
612{
613 i386_compare_gen = gen_cmpdf_cc;
614 i386_compare_gen_eq = gen_cmpdf_ccfpeq;
615 i386_compare_op0 = operands[0];
2ae0f82c
SC
616 i386_compare_op1 = (immediate_operand (operands[1], DFmode))
617 ? copy_to_mode_reg (DFmode, operands[1]) : operands[1];
c572e5ba
JVA
618 DONE;
619}")
620
621(define_expand "cmpsf"
622 [(set (cc0)
fe4435d9 623 (compare (match_operand:SF 0 "register_operand" "")
2ae0f82c 624 (match_operand:SF 1 "general_operand" "")))]
c572e5ba
JVA
625 "TARGET_80387"
626 "
627{
628 i386_compare_gen = gen_cmpsf_cc;
629 i386_compare_gen_eq = gen_cmpsf_ccfpeq;
630 i386_compare_op0 = operands[0];
2ae0f82c
SC
631 i386_compare_op1 = (immediate_operand (operands[1], SFmode))
632 ? copy_to_mode_reg (SFmode, operands[1]) : operands[1];
c572e5ba
JVA
633 DONE;
634}")
635
4fb21e90
JVA
636(define_expand "cmpxf_cc"
637 [(parallel [(set (cc0)
638 (compare (match_operand:XF 0 "register_operand" "")
639 (match_operand:XF 1 "register_operand" "")))
640 (clobber (match_scratch:HI 2 ""))])]
641 "TARGET_80387"
642 "")
643
644(define_expand "cmpxf_ccfpeq"
645 [(parallel [(set (cc0)
646 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
647 (match_operand:XF 1 "register_operand" "")))
648 (clobber (match_scratch:HI 2 ""))])]
649 "TARGET_80387"
cac58785 650 "")
4fb21e90 651
fe4435d9
JVA
652(define_expand "cmpdf_cc"
653 [(parallel [(set (cc0)
654 (compare (match_operand:DF 0 "register_operand" "")
655 (match_operand:DF 1 "register_operand" "")))
656 (clobber (match_scratch:HI 2 ""))])]
657 "TARGET_80387"
658 "")
659
c572e5ba
JVA
660(define_expand "cmpdf_ccfpeq"
661 [(parallel [(set (cc0)
662 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
663 (match_operand:DF 1 "register_operand" "")))
664 (clobber (match_scratch:HI 2 ""))])]
665 "TARGET_80387"
666 "
667{
668 if (! register_operand (operands[1], DFmode))
669 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
670}")
671
fe4435d9
JVA
672(define_expand "cmpsf_cc"
673 [(parallel [(set (cc0)
674 (compare (match_operand:SF 0 "register_operand" "")
675 (match_operand:SF 1 "register_operand" "")))
676 (clobber (match_scratch:HI 2 ""))])]
677 "TARGET_80387"
678 "")
679
c572e5ba
JVA
680(define_expand "cmpsf_ccfpeq"
681 [(parallel [(set (cc0)
682 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
683 (match_operand:SF 1 "register_operand" "")))
684 (clobber (match_scratch:HI 2 ""))])]
685 "TARGET_80387"
686 "
687{
688 if (! register_operand (operands[1], SFmode))
689 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
690}")
886c62d1
JVA
691\f
692;; logical compare
693
886c62d1
JVA
694(define_insn ""
695 [(set (cc0)
b4ac57ab 696 (and:SI (match_operand:SI 0 "general_operand" "%ro")
2ae0f82c 697 (match_operand:SI 1 "nonmemory_operand" "ri")))]
886c62d1
JVA
698 ""
699 "*
700{
701 /* For small integers, we may actually use testb. */
702 if (GET_CODE (operands[1]) == CONST_INT
b4ac57ab 703 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
a199fdd6 704 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
886c62d1
JVA
705 {
706 /* We may set the sign bit spuriously. */
886c62d1 707
b4ac57ab
RS
708 if ((INTVAL (operands[1]) & ~0xff) == 0)
709 {
710 cc_status.flags |= CC_NOT_NEGATIVE;
711 return AS2 (test%B0,%1,%b0);
712 }
886c62d1 713
b4ac57ab 714 if ((INTVAL (operands[1]) & ~0xff00) == 0)
886c62d1 715 {
b4ac57ab 716 cc_status.flags |= CC_NOT_NEGATIVE;
a199fdd6 717 operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
b4ac57ab
RS
718
719 if (QI_REG_P (operands[0]))
720 return AS2 (test%B0,%1,%h0);
721 else
722 {
723 operands[0] = adj_offsettable_operand (operands[0], 1);
724 return AS2 (test%B0,%1,%b0);
725 }
726 }
727
728 if (GET_CODE (operands[0]) == MEM
729 && (INTVAL (operands[1]) & ~0xff0000) == 0)
730 {
731 cc_status.flags |= CC_NOT_NEGATIVE;
a199fdd6 732 operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
b4ac57ab
RS
733 operands[0] = adj_offsettable_operand (operands[0], 2);
734 return AS2 (test%B0,%1,%b0);
735 }
736
737 if (GET_CODE (operands[0]) == MEM
738 && (INTVAL (operands[1]) & ~0xff000000) == 0)
739 {
a199fdd6 740 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
b4ac57ab
RS
741 operands[0] = adj_offsettable_operand (operands[0], 3);
742 return AS2 (test%B0,%1,%b0);
886c62d1
JVA
743 }
744 }
745
746 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
747 return AS2 (test%L0,%1,%0);
748
749 return AS2 (test%L1,%0,%1);
750}")
751
752(define_insn ""
753 [(set (cc0)
b4ac57ab 754 (and:HI (match_operand:HI 0 "general_operand" "%ro")
2ae0f82c 755 (match_operand:HI 1 "nonmemory_operand" "ri")))]
886c62d1
JVA
756 ""
757 "*
758{
759 if (GET_CODE (operands[1]) == CONST_INT
b4ac57ab 760 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
a199fdd6 761 && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
886c62d1 762 {
b4ac57ab 763 if ((INTVAL (operands[1]) & 0xff00) == 0)
886c62d1 764 {
b4ac57ab 765 /* ??? This might not be necessary. */
886c62d1 766 if (INTVAL (operands[1]) & 0xffff0000)
a199fdd6 767 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
886c62d1
JVA
768
769 /* We may set the sign bit spuriously. */
770 cc_status.flags |= CC_NOT_NEGATIVE;
771 return AS2 (test%B0,%1,%b0);
772 }
773
b4ac57ab 774 if ((INTVAL (operands[1]) & 0xff) == 0)
886c62d1 775 {
a199fdd6 776 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
b4ac57ab
RS
777
778 if (QI_REG_P (operands[0]))
779 return AS2 (test%B0,%1,%h0);
780 else
781 {
782 operands[0] = adj_offsettable_operand (operands[0], 1);
783 return AS2 (test%B0,%1,%b0);
784 }
886c62d1
JVA
785 }
786 }
787
5bc7cd8e
SC
788 /* use 32-bit test instruction if there are no sign issues */
789 if (GET_CODE (operands[1]) == CONST_INT
790 && !(INTVAL (operands[1]) & ~0x7fff)
791 && i386_aligned_p (operands[0]))
792 return AS2 (test%L0,%1,%k0);
793
886c62d1
JVA
794 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
795 return AS2 (test%W0,%1,%0);
796
797 return AS2 (test%W1,%0,%1);
798}")
799
800(define_insn ""
801 [(set (cc0)
2ae0f82c
SC
802 (and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm")
803 (match_operand:QI 1 "nonmemory_operand" "qi")))]
886c62d1
JVA
804 ""
805 "*
806{
807 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
808 return AS2 (test%B0,%1,%0);
809
810 return AS2 (test%B1,%0,%1);
811}")
812\f
813;; move instructions.
814;; There is one for each machine mode,
815;; and each is preceded by a corresponding push-insn pattern
816;; (since pushes are not general_operands on the 386).
817
685885b7
RH
818(define_insn ""
819 [(set (match_operand:SI 0 "push_operand" "=<")
820 (match_operand:SI 1 "nonmemory_operand" "rn"))]
821 "flag_pic"
822 "* return AS1 (push%L0,%1);")
823
2f2a49e8
MM
824(define_insn ""
825 [(set (match_operand:SI 0 "push_operand" "=<")
826 (match_operand:SI 1 "nonmemory_operand" "ri"))]
685885b7 827 "!flag_pic"
ae0d310d 828 "* return AS1 (push%L0,%1);")
2f2a49e8 829
ca097615
JW
830;; On a 386, it is faster to push MEM directly.
831
886c62d1
JVA
832(define_insn ""
833 [(set (match_operand:SI 0 "push_operand" "=<")
ca097615
JW
834 (match_operand:SI 1 "memory_operand" "m"))]
835 "TARGET_PUSH_MEMORY"
ae0d310d 836 "* return AS1 (push%L0,%1);")
886c62d1
JVA
837
838;; General case of fullword move.
839
2bb7a0f5
RS
840;; If generating PIC code and operands[1] is a symbolic CONST, emit a
841;; move to get the address of the symbolic object from the GOT.
842
843(define_expand "movsi"
844 [(set (match_operand:SI 0 "general_operand" "")
845 (match_operand:SI 1 "general_operand" ""))]
846 ""
847 "
848{
849 extern int flag_pic;
850
851 if (flag_pic && SYMBOLIC_CONST (operands[1]))
852 emit_pic_move (operands, SImode);
2f2a49e8
MM
853
854 /* Don't generate memory->memory moves, go through a register */
855 else if (TARGET_MOVE
856 && (reload_in_progress | reload_completed) == 0
857 && GET_CODE (operands[0]) == MEM
91f0226f 858 && GET_CODE (operands[1]) == MEM)
2f2a49e8
MM
859 {
860 operands[1] = force_reg (SImode, operands[1]);
861 }
2bb7a0f5
RS
862}")
863
886c62d1
JVA
864;; On i486, incl reg is faster than movl $1,reg.
865
2bb7a0f5 866(define_insn ""
886c62d1 867 [(set (match_operand:SI 0 "general_operand" "=g,r")
685885b7
RH
868 (match_operand:SI 1 "general_operand" "rn,im"))]
869 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
870 || (GET_CODE (operands[1]) != MEM))
871 && flag_pic"
886c62d1
JVA
872 "*
873{
874 rtx link;
875 if (operands[1] == const0_rtx && REG_P (operands[0]))
876 return AS2 (xor%L0,%0,%0);
877
878 if (operands[1] == const1_rtx
879 && (link = find_reg_note (insn, REG_WAS_0, 0))
880 /* Make sure the insn that stored the 0 is still present. */
fe4435d9 881 && ! INSN_DELETED_P (XEXP (link, 0))
886c62d1
JVA
882 && GET_CODE (XEXP (link, 0)) != NOTE
883 /* Make sure cross jumping didn't happen here. */
fe4435d9
JVA
884 && no_labels_between_p (XEXP (link, 0), insn)
885 /* Make sure the reg hasn't been clobbered. */
886 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
886c62d1
JVA
887 /* Fastest way to change a 0 to a 1. */
888 return AS1 (inc%L0,%0);
889
685885b7 890 if (SYMBOLIC_CONST (operands[1]))
b840bfb0
MM
891 return AS2 (lea%L0,%a1,%0);
892
886c62d1
JVA
893 return AS2 (mov%L0,%1,%0);
894}")
895
685885b7
RH
896(define_insn ""
897 [(set (match_operand:SI 0 "general_operand" "=g,r")
898 (match_operand:SI 1 "general_operand" "ri,m"))]
899 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
900 || (GET_CODE (operands[1]) != MEM))
901 && !flag_pic"
902 "*
903{
904 rtx link;
905 if (operands[1] == const0_rtx && REG_P (operands[0]))
906 return AS2 (xor%L0,%0,%0);
907
908 if (operands[1] == const1_rtx
909 && (link = find_reg_note (insn, REG_WAS_0, 0))
910 /* Make sure the insn that stored the 0 is still present. */
911 && ! INSN_DELETED_P (XEXP (link, 0))
912 && GET_CODE (XEXP (link, 0)) != NOTE
913 /* Make sure cross jumping didn't happen here. */
914 && no_labels_between_p (XEXP (link, 0), insn)
915 /* Make sure the reg hasn't been clobbered. */
916 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
917 /* Fastest way to change a 0 to a 1. */
918 return AS1 (inc%L0,%0);
919
920 return AS2 (mov%L0,%1,%0);
921}")
922
2f2a49e8
MM
923(define_insn ""
924 [(set (match_operand:HI 0 "push_operand" "=<")
925 (match_operand:HI 1 "nonmemory_operand" "ri"))]
ca097615 926 ""
ae0d310d 927 "* return AS1 (push%W0,%1);")
2f2a49e8
MM
928
929(define_insn ""
930 [(set (match_operand:HI 0 "push_operand" "=<")
ca097615
JW
931 (match_operand:HI 1 "memory_operand" "m"))]
932 "TARGET_PUSH_MEMORY"
ae0d310d 933 "* return AS1 (push%W0,%1);")
886c62d1
JVA
934
935;; On i486, an incl and movl are both faster than incw and movw.
936
2f2a49e8
MM
937(define_expand "movhi"
938 [(set (match_operand:HI 0 "general_operand" "")
939 (match_operand:HI 1 "general_operand" ""))]
940 ""
941 "
942{
943 /* Don't generate memory->memory moves, go through a register */
944 if (TARGET_MOVE
945 && (reload_in_progress | reload_completed) == 0
946 && GET_CODE (operands[0]) == MEM
91f0226f 947 && GET_CODE (operands[1]) == MEM)
2f2a49e8
MM
948 {
949 operands[1] = force_reg (HImode, operands[1]);
950 }
951}")
952
953(define_insn ""
886c62d1
JVA
954 [(set (match_operand:HI 0 "general_operand" "=g,r")
955 (match_operand:HI 1 "general_operand" "ri,m"))]
2f2a49e8 956 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
957 "*
958{
959 rtx link;
960 if (REG_P (operands[0]) && operands[1] == const0_rtx)
961 return AS2 (xor%L0,%k0,%k0);
962
963 if (REG_P (operands[0]) && operands[1] == const1_rtx
964 && (link = find_reg_note (insn, REG_WAS_0, 0))
965 /* Make sure the insn that stored the 0 is still present. */
fe4435d9 966 && ! INSN_DELETED_P (XEXP (link, 0))
886c62d1
JVA
967 && GET_CODE (XEXP (link, 0)) != NOTE
968 /* Make sure cross jumping didn't happen here. */
fe4435d9
JVA
969 && no_labels_between_p (XEXP (link, 0), insn)
970 /* Make sure the reg hasn't been clobbered. */
971 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
886c62d1
JVA
972 /* Fastest way to change a 0 to a 1. */
973 return AS1 (inc%L0,%k0);
974
975 if (REG_P (operands[0]))
976 {
5bc7cd8e
SC
977 if (i386_aligned_p (operands[1]))
978 {
979 operands[1] = i386_sext16_if_const (operands[1]);
980 return AS2 (mov%L0,%k1,%k0);
981 }
982 if (TARGET_PENTIUMPRO)
983 {
984 /* movzwl is faster than movw on the Pentium Pro,
985 * although not as fast as an aligned movl. */
986#ifdef INTEL_SYNTAX
987 return AS2 (movzx,%1,%k0);
988#else
989 return AS2 (movz%W0%L0,%1,%k0);
990#endif
991 }
886c62d1
JVA
992 }
993
994 return AS2 (mov%W0,%1,%0);
995}")
996
2f2a49e8
MM
997(define_expand "movstricthi"
998 [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
999 (match_operand:HI 1 "general_operand" ""))]
1000 ""
1001 "
1002{
1003 /* Don't generate memory->memory moves, go through a register */
1004 if (TARGET_MOVE
1005 && (reload_in_progress | reload_completed) == 0
1006 && GET_CODE (operands[0]) == MEM
91f0226f 1007 && GET_CODE (operands[1]) == MEM)
2f2a49e8
MM
1008 {
1009 operands[1] = force_reg (HImode, operands[1]);
1010 }
1011}")
1012
1013(define_insn ""
886c62d1
JVA
1014 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
1015 (match_operand:HI 1 "general_operand" "ri,m"))]
2f2a49e8 1016 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
1017 "*
1018{
1019 rtx link;
1020 if (operands[1] == const0_rtx && REG_P (operands[0]))
1021 return AS2 (xor%W0,%0,%0);
1022
1023 if (operands[1] == const1_rtx
1024 && (link = find_reg_note (insn, REG_WAS_0, 0))
1025 /* Make sure the insn that stored the 0 is still present. */
fe4435d9 1026 && ! INSN_DELETED_P (XEXP (link, 0))
886c62d1
JVA
1027 && GET_CODE (XEXP (link, 0)) != NOTE
1028 /* Make sure cross jumping didn't happen here. */
fe4435d9
JVA
1029 && no_labels_between_p (XEXP (link, 0), insn)
1030 /* Make sure the reg hasn't been clobbered. */
1031 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
886c62d1
JVA
1032 /* Fastest way to change a 0 to a 1. */
1033 return AS1 (inc%W0,%0);
1034
1035 return AS2 (mov%W0,%1,%0);
1036}")
1037
1038;; emit_push_insn when it calls move_by_pieces
1039;; requires an insn to "push a byte".
1040;; But actually we use pushw, which has the effect of rounding
1041;; the amount pushed up to a halfword.
1042(define_insn ""
1043 [(set (match_operand:QI 0 "push_operand" "=<")
2ae0f82c 1044 (match_operand:QI 1 "const_int_operand" "n"))]
886c62d1 1045 ""
ae0d310d 1046 "* return AS1(push%W0,%1);")
2f2a49e8
MM
1047
1048(define_insn ""
1049 [(set (match_operand:QI 0 "push_operand" "=<")
1050 (match_operand:QI 1 "register_operand" "q"))]
ca097615 1051 ""
886c62d1
JVA
1052 "*
1053{
f64cecad 1054 operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]));
886c62d1
JVA
1055 return AS1 (push%W0,%1);
1056}")
1057
1058;; On i486, incb reg is faster than movb $1,reg.
1059
1060;; ??? Do a recognizer for zero_extract that looks just like this, but reads
1061;; or writes %ah, %bh, %ch, %dh.
1062
2f2a49e8
MM
1063(define_expand "movqi"
1064 [(set (match_operand:QI 0 "general_operand" "")
1065 (match_operand:QI 1 "general_operand" ""))]
1066 ""
1067 "
1068{
1069 /* Don't generate memory->memory moves, go through a register */
1070 if (TARGET_MOVE
1071 && (reload_in_progress | reload_completed) == 0
1072 && GET_CODE (operands[0]) == MEM
91f0226f 1073 && GET_CODE (operands[1]) == MEM)
2f2a49e8
MM
1074 {
1075 operands[1] = force_reg (QImode, operands[1]);
1076 }
1077}")
1078
1079(define_insn ""
2ae0f82c 1080 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,*r,qm")
52c18286 1081 (match_operand:QI 1 "general_operand" "*g,*rn,qn"))]
2f2a49e8 1082 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
1083 "*
1084{
1085 rtx link;
1086 if (operands[1] == const0_rtx && REG_P (operands[0]))
5bc7cd8e 1087 return AS2 (xor%L0,%k0,%k0);
886c62d1
JVA
1088
1089 if (operands[1] == const1_rtx
1090 && (link = find_reg_note (insn, REG_WAS_0, 0))
1091 /* Make sure the insn that stored the 0 is still present. */
fe4435d9 1092 && ! INSN_DELETED_P (XEXP (link, 0))
886c62d1
JVA
1093 && GET_CODE (XEXP (link, 0)) != NOTE
1094 /* Make sure cross jumping didn't happen here. */
fe4435d9
JVA
1095 && no_labels_between_p (XEXP (link, 0), insn)
1096 /* Make sure the reg hasn't been clobbered. */
1097 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
b76c90cf
L
1098 {
1099 /* Fastest way to change a 0 to a 1.
1100 If inc%B0 isn't allowed, use inc%L0. */
1101 if (NON_QI_REG_P (operands[0]))
1102 return AS1 (inc%L0,%0);
1103 else
1104 return AS1 (inc%B0,%0);
1105 }
886c62d1
JVA
1106
1107 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
1108 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1109 return (AS2 (mov%L0,%k1,%k0));
1110
1111 return (AS2 (mov%B0,%1,%0));
1112}")
1113
1114;; If it becomes necessary to support movstrictqi into %esi or %edi,
1115;; use the insn sequence:
1116;;
1117;; shrdl $8,srcreg,dstreg
1118;; rorl $24,dstreg
1119;;
1120;; If operands[1] is a constant, then an andl/orl sequence would be
1121;; faster.
1122
2f2a49e8
MM
1123(define_expand "movstrictqi"
1124 [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
1125 (match_operand:QI 1 "general_operand" ""))]
1126 ""
1127 "
1128{
1129 /* Don't generate memory->memory moves, go through a register */
1130 if (TARGET_MOVE
1131 && (reload_in_progress | reload_completed) == 0
1132 && GET_CODE (operands[0]) == MEM
91f0226f 1133 && GET_CODE (operands[1]) == MEM)
2f2a49e8
MM
1134 {
1135 operands[1] = force_reg (QImode, operands[1]);
1136 }
1137}")
1138
1139(define_insn ""
2ae0f82c 1140 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
c0f06344 1141 (match_operand:QI 1 "general_operand" "*qn,m"))]
2f2a49e8 1142 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
1143 "*
1144{
1145 rtx link;
1146 if (operands[1] == const0_rtx && REG_P (operands[0]))
1147 return AS2 (xor%B0,%0,%0);
1148
1149 if (operands[1] == const1_rtx
b76c90cf 1150 && ! NON_QI_REG_P (operands[0])
886c62d1
JVA
1151 && (link = find_reg_note (insn, REG_WAS_0, 0))
1152 /* Make sure the insn that stored the 0 is still present. */
fe4435d9 1153 && ! INSN_DELETED_P (XEXP (link, 0))
886c62d1
JVA
1154 && GET_CODE (XEXP (link, 0)) != NOTE
1155 /* Make sure cross jumping didn't happen here. */
fe4435d9
JVA
1156 && no_labels_between_p (XEXP (link, 0), insn)
1157 /* Make sure the reg hasn't been clobbered. */
1158 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
886c62d1
JVA
1159 /* Fastest way to change a 0 to a 1. */
1160 return AS1 (inc%B0,%0);
1161
c0f06344 1162 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */
886c62d1
JVA
1163 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
1164 {
1165 abort ();
1166 return (AS2 (mov%L0,%k1,%k0));
1167 }
1168
1169 return AS2 (mov%B0,%1,%0);
1170}")
1171
f31fce3f
JW
1172(define_insn "movsf_push"
1173 [(set (match_operand:SF 0 "push_operand" "=<,<")
dc0f0eb8
JW
1174 (match_operand:SF 1 "general_operand" "*rfF,m"))]
1175 "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed"
f31fce3f
JW
1176 "*
1177{
1178 if (STACK_REG_P (operands[1]))
1179 {
1180 rtx xops[3];
1181
1182 if (! STACK_TOP_P (operands[1]))
1183 abort ();
1184
1185 xops[0] = AT_SP (SFmode);
1186 xops[1] = GEN_INT (4);
1187 xops[2] = stack_pointer_rtx;
1188
1189 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1190
1191 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1192 output_asm_insn (AS1 (fstp%S0,%0), xops);
1193 else
1194 output_asm_insn (AS1 (fst%S0,%0), xops);
1195
1196 RET;
1197 }
dc0f0eb8 1198
f31fce3f
JW
1199 return AS1 (push%L0,%1);
1200}")
1201
1202(define_insn "movsf_push_memory"
1203 [(set (match_operand:SF 0 "push_operand" "=<")
1204 (match_operand:SF 1 "memory_operand" "m"))]
1205 "TARGET_PUSH_MEMORY"
1206 "* return AS1 (push%L0,%1);")
1207
0be5d99f
MM
1208(define_expand "movsf"
1209 [(set (match_operand:SF 0 "general_operand" "")
1210 (match_operand:SF 1 "general_operand" ""))]
1211 ""
1212 "
1213{
f31fce3f 1214 /* Don't generate memory->memory moves, go through a register */
0be5d99f
MM
1215 if (TARGET_MOVE
1216 && (reload_in_progress | reload_completed) == 0
1217 && GET_CODE (operands[0]) == MEM
f31fce3f 1218 && GET_CODE (operands[1]) == MEM)
0be5d99f 1219 {
f31fce3f 1220 operands[1] = force_reg (SFmode, operands[1]);
0be5d99f 1221 }
0bb6c81b 1222
2ae0f82c 1223 /* If we are loading a floating point constant that isn't 0 or 1
83199882
RK
1224 into a register, indicate we need the pic register loaded. This could
1225 be optimized into stores of constants if the target eventually moves
1226 to memory, but better safe than sorry. */
f31fce3f 1227 else if ((reload_in_progress | reload_completed) == 0
0bb6c81b
RK
1228 && GET_CODE (operands[0]) != MEM
1229 && GET_CODE (operands[1]) == CONST_DOUBLE
1230 && !standard_80387_constant_p (operands[1]))
1231 {
2ae0f82c
SC
1232 rtx insn, note, fp_const;
1233
1234 fp_const = force_const_mem (SFmode, operands[1]);
1235 if (flag_pic)
1236 current_function_uses_pic_offset_table = 1;
1237
f64cecad 1238 insn = emit_insn (gen_rtx_SET (SFmode, operands[0], fp_const));
2ae0f82c
SC
1239 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1240
1241 if (note)
1242 XEXP (note, 0) = operands[1];
1243 else
f64cecad 1244 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn));
0bb6c81b 1245 }
0be5d99f
MM
1246}")
1247
0be5d99f 1248;; For the purposes of regclass, prefer FLOAT_REGS.
f31fce3f 1249(define_insn ""
2ae0f82c 1250 [(set (match_operand:SF 0 "nonimmediate_operand" "=*rfm,*rf,f,!*rm")
0fcad513 1251 (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
f58acb67 1252 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
1253 "*
1254{
1255 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1256
1257 /* First handle a `pop' insn or a `fld %st(0)' */
1258
1259 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1260 {
1261 if (stack_top_dies)
1262 return AS1 (fstp,%y0);
1263 else
1264 return AS1 (fld,%y0);
1265 }
1266
1267 /* Handle a transfer between the 387 and a 386 register */
1268
1269 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1270 {
1271 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1272 RET;
1273 }
1274
1275 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1276 {
f25aca7a 1277 output_to_reg (operands[0], stack_top_dies, 0);
886c62d1
JVA
1278 RET;
1279 }
1280
1281 /* Handle other kinds of writes from the 387 */
1282
1283 if (STACK_TOP_P (operands[1]))
1284 {
1285 if (stack_top_dies)
1286 return AS1 (fstp%z0,%y0);
1287 else
1288 return AS1 (fst%z0,%y0);
1289 }
1290
1291 /* Handle other kinds of reads to the 387 */
1292
1293 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
2f2a49e8 1294 return output_move_const_single (operands);
886c62d1
JVA
1295
1296 if (STACK_TOP_P (operands[0]))
1297 return AS1 (fld%z1,%y1);
1298
1299 /* Handle all SFmode moves not involving the 387 */
1300
2f2a49e8 1301 return singlemove_string (operands);
2ae0f82c
SC
1302}"
1303 [(set_attr "type" "fld")])
1304
886c62d1 1305
0be5d99f
MM
1306(define_insn "swapsf"
1307 [(set (match_operand:SF 0 "register_operand" "f")
1308 (match_operand:SF 1 "register_operand" "f"))
1309 (set (match_dup 1)
1310 (match_dup 0))]
1311 ""
1312 "*
1313{
1314 if (STACK_TOP_P (operands[0]))
1315 return AS1 (fxch,%1);
1316 else
1317 return AS1 (fxch,%0);
1318}")
1319
f31fce3f
JW
1320(define_insn "movdf_push"
1321 [(set (match_operand:DF 0 "push_operand" "=<,<")
dc0f0eb8
JW
1322 (match_operand:DF 1 "general_operand" "*rfF,o"))]
1323 "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed"
f31fce3f
JW
1324 "*
1325{
1326 if (STACK_REG_P (operands[1]))
1327 {
1328 rtx xops[3];
1329
1330 xops[0] = AT_SP (DFmode);
1331 xops[1] = GEN_INT (8);
1332 xops[2] = stack_pointer_rtx;
1333
1334 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1335
1336 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1337 output_asm_insn (AS1 (fstp%Q0,%0), xops);
1338 else
1339 output_asm_insn (AS1 (fst%Q0,%0), xops);
1340
1341 RET;
1342 }
dc0f0eb8
JW
1343
1344 if (which_alternative == 1)
1345 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 0, 0);
1346
f31fce3f
JW
1347 return output_move_double (operands);
1348}")
1349
1350(define_insn "movdf_push_memory"
1351 [(set (match_operand:DF 0 "push_operand" "=<")
1352 (match_operand:DF 1 "memory_operand" "o"))]
1353 "TARGET_PUSH_MEMORY"
1354 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode),0,0);")
1355
0be5d99f
MM
1356(define_expand "movdf"
1357 [(set (match_operand:DF 0 "general_operand" "")
1358 (match_operand:DF 1 "general_operand" ""))]
1359 ""
1360 "
1361{
f31fce3f 1362 /* Don't generate memory->memory moves, go through a register */
0be5d99f
MM
1363 if (TARGET_MOVE
1364 && (reload_in_progress | reload_completed) == 0
1365 && GET_CODE (operands[0]) == MEM
f31fce3f 1366 && GET_CODE (operands[1]) == MEM)
0be5d99f 1367 {
f31fce3f 1368 operands[1] = force_reg (DFmode, operands[1]);
0be5d99f 1369 }
0bb6c81b 1370
83199882
RK
1371 /* If we are loading a floating point constant that isn't 0 or 1 into a
1372 register, indicate we need the pic register loaded. This could be
1373 optimized into stores of constants if the target eventually moves to
1374 memory, but better safe than sorry. */
f31fce3f 1375 else if ((reload_in_progress | reload_completed) == 0
0bb6c81b
RK
1376 && GET_CODE (operands[0]) != MEM
1377 && GET_CODE (operands[1]) == CONST_DOUBLE
1378 && !standard_80387_constant_p (operands[1]))
1379 {
2ae0f82c
SC
1380 rtx insn, note, fp_const;
1381
1382 fp_const = force_const_mem (DFmode, operands[1]);
1383 if (flag_pic)
1384 current_function_uses_pic_offset_table = 1;
1385
f64cecad 1386 insn = emit_insn (gen_rtx_SET (DFmode, operands[0], fp_const));
2ae0f82c
SC
1387 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1388
1389 if (note)
1390 XEXP (note, 0) = operands[1];
1391 else
f64cecad 1392 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn));
0bb6c81b 1393 }
0be5d99f
MM
1394}")
1395
0be5d99f 1396;; For the purposes of regclass, prefer FLOAT_REGS.
83199882 1397(define_insn ""
2ae0f82c 1398 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
640667cb 1399 (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
f58acb67
SC
1400 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1401 || (GET_CODE (operands[1]) != MEM)"
886c62d1
JVA
1402 "*
1403{
1404 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1405
1406 /* First handle a `pop' insn or a `fld %st(0)' */
1407
1408 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1409 {
1410 if (stack_top_dies)
1411 return AS1 (fstp,%y0);
1412 else
1413 return AS1 (fld,%y0);
1414 }
1415
1416 /* Handle a transfer between the 387 and a 386 register */
1417
1418 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1419 {
1420 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1421 RET;
1422 }
1423
1424 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1425 {
f25aca7a 1426 output_to_reg (operands[0], stack_top_dies, 0);
886c62d1
JVA
1427 RET;
1428 }
1429
1430 /* Handle other kinds of writes from the 387 */
1431
1432 if (STACK_TOP_P (operands[1]))
1433 {
1434 if (stack_top_dies)
1435 return AS1 (fstp%z0,%y0);
1436 else
1437 return AS1 (fst%z0,%y0);
1438 }
1439
1440 /* Handle other kinds of reads to the 387 */
1441
1442 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
2f2a49e8 1443 return output_move_const_single (operands);
886c62d1
JVA
1444
1445 if (STACK_TOP_P (operands[0]))
1446 return AS1 (fld%z1,%y1);
1447
1448 /* Handle all DFmode moves not involving the 387 */
1449
2f2a49e8 1450 return output_move_double (operands);
2ae0f82c 1451}"
36cf4bcf 1452 [(set_attr "type" "fld")])
2ae0f82c
SC
1453
1454
886c62d1 1455
0be5d99f
MM
1456(define_insn "swapdf"
1457 [(set (match_operand:DF 0 "register_operand" "f")
1458 (match_operand:DF 1 "register_operand" "f"))
1459 (set (match_dup 1)
1460 (match_dup 0))]
1461 ""
1462 "*
1463{
1464 if (STACK_TOP_P (operands[0]))
1465 return AS1 (fxch,%1);
1466 else
1467 return AS1 (fxch,%0);
1468}")
1469
f31fce3f
JW
1470(define_insn "movxf_push"
1471 [(set (match_operand:XF 0 "push_operand" "=<,<")
dc0f0eb8
JW
1472 (match_operand:XF 1 "general_operand" "*rfF,o"))]
1473 "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed"
f31fce3f
JW
1474 "*
1475{
1476 if (STACK_REG_P (operands[1]))
1477 {
1478 rtx xops[3];
1479
1480 xops[0] = AT_SP (XFmode);
1481 xops[1] = GEN_INT (12);
1482 xops[2] = stack_pointer_rtx;
1483
1484 output_asm_insn (AS2 (sub%L2,%1,%2), xops);
1485
1486 output_asm_insn (AS1 (fstp%T0,%0), xops);
1487 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
1488 output_asm_insn (AS1 (fld%T0,%0), xops);
1489
1490 RET;
1491 }
dc0f0eb8
JW
1492
1493 if (which_alternative == 1)
1494 return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 0, 0);
1495
f31fce3f
JW
1496 return output_move_double (operands);
1497 }")
1498
1499(define_insn "movxf_push_memory"
1500 [(set (match_operand:XF 0 "push_operand" "=<")
1501 (match_operand:XF 1 "memory_operand" "o"))]
1502 "TARGET_PUSH_MEMORY"
1503 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode),0,0);")
1504
0be5d99f
MM
1505(define_expand "movxf"
1506 [(set (match_operand:XF 0 "general_operand" "")
1507 (match_operand:XF 1 "general_operand" ""))]
1508 ""
1509 "
1510{
f31fce3f 1511 /* Don't generate memory->memory moves, go through a register */
0be5d99f
MM
1512 if (TARGET_MOVE
1513 && (reload_in_progress | reload_completed) == 0
1514 && GET_CODE (operands[0]) == MEM
f31fce3f 1515 && GET_CODE (operands[1]) == MEM)
0be5d99f 1516 {
f31fce3f 1517 operands[1] = force_reg (XFmode, operands[1]);
0be5d99f 1518 }
0bb6c81b 1519
2ae0f82c 1520 /* If we are loading a floating point constant that isn't 0 or 1
83199882
RK
1521 into a register, indicate we need the pic register loaded. This could
1522 be optimized into stores of constants if the target eventually moves
1523 to memory, but better safe than sorry. */
f31fce3f 1524 else if ((reload_in_progress | reload_completed) == 0
0bb6c81b
RK
1525 && GET_CODE (operands[0]) != MEM
1526 && GET_CODE (operands[1]) == CONST_DOUBLE
1527 && !standard_80387_constant_p (operands[1]))
1528 {
2ae0f82c
SC
1529 rtx insn, note, fp_const;
1530
1531 fp_const = force_const_mem (XFmode, operands[1]);
1532 if (flag_pic)
1533 current_function_uses_pic_offset_table = 1;
1534
f64cecad 1535 insn = emit_insn (gen_rtx_SET (XFmode, operands[0], fp_const));
2ae0f82c
SC
1536 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
1537
1538 if (note)
1539 XEXP (note, 0) = operands[1];
1540 else
f64cecad 1541 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn));
0bb6c81b 1542 }
0be5d99f
MM
1543}")
1544
c1450f19 1545
83199882 1546(define_insn ""
2ae0f82c 1547 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm")
4fb21e90 1548 (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
f58acb67
SC
1549 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1550 || (GET_CODE (operands[1]) != MEM)"
4fb21e90
JVA
1551 "*
1552{
1553 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1554
1555 /* First handle a `pop' insn or a `fld %st(0)' */
1556
1557 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
1558 {
1559 if (stack_top_dies)
1560 return AS1 (fstp,%y0);
1561 else
1562 return AS1 (fld,%y0);
1563 }
1564
1565 /* Handle a transfer between the 387 and a 386 register */
1566
1567 if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
1568 {
1569 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
1570 RET;
1571 }
1572
1573 if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
1574 {
f25aca7a 1575 output_to_reg (operands[0], stack_top_dies, 0);
4fb21e90
JVA
1576 RET;
1577 }
1578
1579 /* Handle other kinds of writes from the 387 */
1580
1581 if (STACK_TOP_P (operands[1]))
1582 {
2f17722a
JVA
1583 output_asm_insn (AS1 (fstp%z0,%y0), operands);
1584 if (! stack_top_dies)
1585 return AS1 (fld%z0,%y0);
1586
1587 RET;
4fb21e90
JVA
1588 }
1589
1590 /* Handle other kinds of reads to the 387 */
1591
1592 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
2f2a49e8 1593 return output_move_const_single (operands);
4fb21e90
JVA
1594
1595 if (STACK_TOP_P (operands[0]))
1596 return AS1 (fld%z1,%y1);
1597
1598 /* Handle all XFmode moves not involving the 387 */
1599
2f2a49e8 1600 return output_move_double (operands);
4fb21e90
JVA
1601}")
1602
2ae0f82c 1603(define_insn "swapxf"
0be5d99f
MM
1604 [(set (match_operand:XF 0 "register_operand" "f")
1605 (match_operand:XF 1 "register_operand" "f"))
1606 (set (match_dup 1)
1607 (match_dup 0))]
1608 ""
1609 "*
1610{
1611 if (STACK_TOP_P (operands[0]))
1612 return AS1 (fxch,%1);
1613 else
1614 return AS1 (fxch,%0);
1615}")
1616
b840bfb0 1617(define_insn ""
d2f2cb19
JW
1618 [(set (match_operand:DI 0 "push_operand" "=<")
1619 (match_operand:DI 1 "general_operand" "riF"))]
c1450f19 1620 ""
d2f2cb19 1621 "* return output_move_double (operands);")
2f2a49e8 1622
d2f2cb19
JW
1623(define_insn ""
1624 [(set (match_operand:DI 0 "push_operand" "=<")
1625 (match_operand:DI 1 "memory_operand" "o"))]
1626 "TARGET_PUSH_MEMORY"
1627 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode),0,0);")
886c62d1 1628
d2f2cb19
JW
1629(define_expand "movdi"
1630 [(set (match_operand:DI 0 "general_operand" "")
1631 (match_operand:DI 1 "general_operand" ""))]
2f2a49e8 1632 ""
d2f2cb19 1633 "
2f2a49e8 1634{
d2f2cb19
JW
1635 /* Don't generate memory->memory moves, go through a register */
1636 if (TARGET_MOVE
1637 && (reload_in_progress | reload_completed) == 0
1638 && GET_CODE (operands[0]) == MEM
1639 && GET_CODE (operands[1]) == MEM)
1640 {
1641 operands[1] = force_reg (DImode, operands[1]);
1642 }
886c62d1 1643}")
0be5d99f 1644
d2f2cb19
JW
1645(define_insn ""
1646 [(set (match_operand:DI 0 "general_operand" "=g,r")
1647 (match_operand:DI 1 "general_operand" "riF,m"))]
1648 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
1649 || (GET_CODE (operands[1]) != MEM)"
1650 "* return output_move_double (operands);")
1651
886c62d1
JVA
1652\f
1653;;- conversion instructions
1654;;- NONE
1655
886c62d1
JVA
1656;;- zero extension instructions
1657;; See comments by `andsi' for when andl is faster than movzx.
1658
1659(define_insn "zero_extendhisi2"
2ae0f82c
SC
1660 [(set (match_operand:SI 0 "register_operand" "=r,&r,?r")
1661 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))]
886c62d1
JVA
1662 ""
1663 "*
2ae0f82c
SC
1664 {
1665 rtx xops[2];
1666
1667 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
886c62d1
JVA
1668 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
1669 {
886c62d1 1670 xops[0] = operands[0];
a199fdd6 1671 xops[1] = GEN_INT (0xffff);
886c62d1
JVA
1672 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1673 RET;
1674 }
2ae0f82c
SC
1675 if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1]))
1676 {
1677 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1678 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
1679 RET;
1680 }
1681
1682 if (TARGET_ZERO_EXTEND_WITH_AND)
1683 {
1684 xops[0] = operands[0];
f64cecad 1685 xops[1] = GEN_INT (0xffff);
5bc7cd8e
SC
1686 if (i386_aligned_p (operands[1]))
1687 output_asm_insn (AS2 (mov%L0,%k1,%k0),operands);
1688 else
1689 output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
2ae0f82c
SC
1690 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1691 RET;
1692 }
886c62d1
JVA
1693
1694#ifdef INTEL_SYNTAX
1695 return AS2 (movzx,%1,%0);
1696#else
1697 return AS2 (movz%W0%L0,%1,%0);
1698#endif
1699}")
1700
2ae0f82c
SC
1701(define_split
1702 [(set (match_operand:SI 0 "register_operand" "")
1703 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1704 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])"
1705 [(set (match_dup 0)
1706 (const_int 0))
1707 (set (strict_low_part (match_dup 2))
1708 (match_dup 1))]
f64cecad 1709 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
2ae0f82c
SC
1710
1711
1712(define_split
1713 [(set (match_operand:SI 0 "register_operand" "")
1714 (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))]
1715 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])"
1716 [(set (strict_low_part (match_dup 2))
1717 (match_dup 1))
1718 (set (match_dup 0)
1719 (and:SI (match_dup 0)
1720 (const_int 65535)))]
f64cecad 1721 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));")
2ae0f82c 1722
886c62d1 1723(define_insn "zero_extendqihi2"
2ae0f82c
SC
1724 [(set (match_operand:HI 0 "register_operand" "=q,&q,?r")
1725 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
886c62d1
JVA
1726 ""
1727 "*
2ae0f82c
SC
1728 {
1729 rtx xops[2];
1730
268bfa44 1731 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
2ae0f82c
SC
1732 && REG_P (operands[1])
1733 && REGNO (operands[0]) == REGNO (operands[1]))
886c62d1 1734 {
886c62d1 1735 xops[0] = operands[0];
a199fdd6 1736 xops[1] = GEN_INT (0xff);
886c62d1
JVA
1737 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1738 RET;
1739 }
2ae0f82c
SC
1740 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1741 {
1742 if(!reg_overlap_mentioned_p(operands[0],operands[1]))
1743 {
1744 output_asm_insn (AS2 (xor%L0,%k0,%k0), operands);
1745 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1746 }
1747 else
1748 {
1749 xops[0] = operands[0];
f64cecad 1750 xops[1] = GEN_INT (0xff);
2ae0f82c
SC
1751 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1752 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1753 }
1754 RET;
1755 }
1756
886c62d1
JVA
1757#ifdef INTEL_SYNTAX
1758 return AS2 (movzx,%1,%0);
1759#else
1760 return AS2 (movz%B0%W0,%1,%0);
1761#endif
1762}")
1763
2ae0f82c
SC
1764(define_split
1765 [(set (match_operand:HI 0 "register_operand" "")
1766 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1767 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1768 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1769 [(set (match_dup 0)
1770 (const_int 0))
1771 (set (strict_low_part (match_dup 2))
1772 (match_dup 1))]
f64cecad 1773 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2ae0f82c
SC
1774
1775
1776(define_split
1777 [(set (match_operand:HI 0 "register_operand" "")
1778 (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))]
1779 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1780 && reg_overlap_mentioned_p (operands[0], operands[1])"
1781 [(set (strict_low_part (match_dup 2))
1782 (match_dup 1))
1783 (set (match_dup 0)
1784 (and:HI (match_dup 0)
1785 (const_int 255)))]
f64cecad 1786 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2ae0f82c
SC
1787
1788(define_split
1789 [(set (match_operand:HI 0 "register_operand" "")
1790 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2d204901 1791 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND"
2ae0f82c
SC
1792 [(set (match_dup 0)
1793 (match_dup 2))
1794 (set (match_dup 0)
1795 (and:HI (match_dup 0)
1796 (const_int 255)))]
2d204901
RK
1797 "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0)
1798 operands[1] = SUBREG_REG (operands[1]);
1799 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG
1800 || REGNO (operands[0]) == REGNO (operands[1]))
1801 FAIL;
f64cecad 1802 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));")
2ae0f82c 1803
886c62d1 1804(define_insn "zero_extendqisi2"
2ae0f82c
SC
1805 [(set (match_operand:SI 0 "register_operand" "=q,&q,?r")
1806 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))]
886c62d1
JVA
1807 ""
1808 "*
2ae0f82c
SC
1809 {
1810 rtx xops[2];
1811
268bfa44 1812 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0)
2ae0f82c
SC
1813 && REG_P (operands[1])
1814 && REGNO (operands[0]) == REGNO (operands[1]))
886c62d1 1815 {
886c62d1 1816 xops[0] = operands[0];
a199fdd6 1817 xops[1] = GEN_INT (0xff);
886c62d1
JVA
1818 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1819 RET;
1820 }
2ae0f82c
SC
1821 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]))
1822 {
1823 if(!reg_overlap_mentioned_p (operands[0], operands[1]))
1824 {
1825 output_asm_insn (AS2 (xor%L0,%0,%0),operands);
1826 output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
1827 }
1828 else
1829 {
1830 xops[0] = operands[0];
f64cecad 1831 xops[1] = GEN_INT (0xff);
2ae0f82c
SC
1832 output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
1833 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1834 }
1835 RET;
1836 }
1837
1838 if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG)
1839 {
1840 xops[0] = operands[0];
f64cecad
JC
1841 xops[1] = GEN_INT (0xff);
1842 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
2ae0f82c
SC
1843 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
1844 output_asm_insn (AS2 (and%L0,%1,%k0), xops);
1845 RET;
1846 }
886c62d1
JVA
1847
1848#ifdef INTEL_SYNTAX
1849 return AS2 (movzx,%1,%0);
1850#else
1851 return AS2 (movz%B0%L0,%1,%0);
1852#endif
1853}")
9c530261 1854
2ae0f82c
SC
1855(define_split
1856 [(set (match_operand:SI 0 "register_operand" "")
1857 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1858 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1859 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1860 [(set (match_dup 0)
1861 (const_int 0))
1862 (set (strict_low_part (match_dup 2))
1863 (match_dup 1))]
f64cecad 1864 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2ae0f82c
SC
1865
1866
1867(define_split
1868 [(set (match_operand:SI 0 "register_operand" "")
1869 (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))]
1870 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
1871 && reg_overlap_mentioned_p (operands[0], operands[1])"
1872 [(set (strict_low_part (match_dup 2))
1873 (match_dup 1))
1874 (set (match_dup 0)
1875 (and:SI (match_dup 0)
1876 (const_int 255)))]
f64cecad 1877 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2ae0f82c
SC
1878
1879(define_split
1880 [(set (match_operand:SI 0 "register_operand" "")
1881 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3bc97c56
SC
1882 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
1883 && ! reg_overlap_mentioned_p (operands[0], operands[1])"
2ae0f82c
SC
1884 [(set (match_dup 0)
1885 (match_dup 2))
1886 (set (match_dup 0)
1887 (and:SI (match_dup 0)
1888 (const_int 255)))]
f64cecad 1889 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
2ae0f82c 1890
9c530261 1891(define_insn "zero_extendsidi2"
2ae0f82c
SC
1892 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m")
1893 (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))]
9c530261
JVA
1894 ""
1895 "*
2ae0f82c
SC
1896 {
1897 rtx high[2], low[2], xops[4];
1898
1899 if (REG_P (operands[0]) && REG_P (operands[1])
1900 && REGNO (operands[0]) == REGNO (operands[1]))
1901 {
f64cecad 1902 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2ae0f82c
SC
1903 return AS2 (xor%L0,%0,%0);
1904 }
1905
1906 split_di (operands, 1, low, high);
1907 xops[0] = low[0];
1908 xops[1] = operands[1];
1909 xops[2] = high[0];
1910 xops[3] = const0_rtx;
1911
1912 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
1913 if (GET_CODE (low[0]) == MEM)
1914 output_asm_insn (AS2 (mov%L2,%3,%2), xops);
1915 else
1916 output_asm_insn (AS2 (xor%L2,%2,%2), xops);
1917
1918 RET;
9c530261 1919}")
886c62d1
JVA
1920\f
1921;;- sign extension instructions
1922
886c62d1 1923(define_insn "extendsidi2"
9c530261 1924 [(set (match_operand:DI 0 "register_operand" "=r")
2ae0f82c 1925 (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))]
886c62d1 1926 ""
9c530261
JVA
1927 "*
1928{
1929 if (REGNO (operands[0]) == 0)
71a247f0
RS
1930 {
1931 /* This used to be cwtl, but that extends HI to SI somehow. */
1932#ifdef INTEL_SYNTAX
1933 return \"cdq\";
1934#else
1935 return \"cltd\";
1936#endif
1937 }
9c530261 1938
f64cecad 1939 operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
9c530261
JVA
1940 output_asm_insn (AS2 (mov%L0,%0,%1), operands);
1941
1942 operands[0] = GEN_INT (31);
1943 return AS2 (sar%L1,%0,%1);
1944}")
886c62d1
JVA
1945
1946;; Note that the i386 programmers' manual says that the opcodes
1947;; are named movsx..., but the assembler on Unix does not accept that.
1948;; We use what the Unix assembler expects.
1949
1950(define_insn "extendhisi2"
2ae0f82c
SC
1951 [(set (match_operand:SI 0 "register_operand" "=r")
1952 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
886c62d1
JVA
1953 ""
1954 "*
1955{
1956 if (REGNO (operands[0]) == 0
1957 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
1958#ifdef INTEL_SYNTAX
1959 return \"cwde\";
1960#else
1961 return \"cwtl\";
1962#endif
1963
1964#ifdef INTEL_SYNTAX
1965 return AS2 (movsx,%1,%0);
1966#else
1967 return AS2 (movs%W0%L0,%1,%0);
1968#endif
1969}")
1970
1971(define_insn "extendqihi2"
2ae0f82c
SC
1972 [(set (match_operand:HI 0 "register_operand" "=r")
1973 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
886c62d1
JVA
1974 ""
1975 "*
1976{
1977 if (REGNO (operands[0]) == 0
1978 && REG_P (operands[1]) && REGNO (operands[1]) == 0)
1979 return \"cbtw\";
1980
1981#ifdef INTEL_SYNTAX
1982 return AS2 (movsx,%1,%0);
1983#else
1984 return AS2 (movs%B0%W0,%1,%0);
1985#endif
1986}")
1987
1988(define_insn "extendqisi2"
2ae0f82c
SC
1989 [(set (match_operand:SI 0 "register_operand" "=r")
1990 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
886c62d1
JVA
1991 ""
1992 "*
1993{
1994#ifdef INTEL_SYNTAX
1995 return AS2 (movsx,%1,%0);
1996#else
1997 return AS2 (movs%B0%L0,%1,%0);
1998#endif
1999}")
2ae0f82c
SC
2000
2001\f
2002;; Truncation of long long -> 32 bit
2003
2004(define_expand "truncdisi2"
2005 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2006 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2007 ""
2008 "
2009{
2010 /* Don't generate memory->memory moves, go through a register */
2011 if (TARGET_MOVE
2012 && (reload_in_progress | reload_completed) == 0
2013 && GET_CODE (operands[0]) == MEM
2014 && GET_CODE (operands[1]) == MEM)
2015 {
2016 rtx target = gen_reg_rtx (SImode);
2017 emit_insn (gen_truncdisi2 (target, operands[1]));
2018 emit_move_insn (operands[0], target);
2019 DONE;
2020 }
2021}")
2022
2023(define_insn ""
2024 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2025 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))]
2026 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2027 "*
2028{
2029 rtx low[2], high[2], xops[2];
2030
2031 split_di (&operands[1], 1, low, high);
2032 xops[0] = operands[0];
2033 xops[1] = low[0];
2034 if (!rtx_equal_p (xops[0], xops[1]))
2035 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2036
2037 RET;
2038}")
2039
2040(define_insn ""
2041 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
2042 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r")
2043 (const_int 32))))]
2044 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
2045 "*
2046{
2047 rtx low[2], high[2], xops[2];
2048
2049 split_di (&operands[1], 1, low, high);
2050 xops[0] = operands[0];
2051 xops[1] = high[0];
2052 if (!rtx_equal_p (xops[0], xops[1]))
2053 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2054
2055 RET;
2056}")
2057
2058
886c62d1
JVA
2059\f
2060;; Conversions between float and double.
2061
2062(define_insn "extendsfdf2"
2ae0f82c 2063 [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f")
886c62d1 2064 (float_extend:DF
2ae0f82c 2065 (match_operand:SF 1 "nonimmediate_operand" "f,fm")))]
886c62d1
JVA
2066 "TARGET_80387"
2067 "*
2068{
2069 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2070
2071 if (NON_STACK_REG_P (operands[1]))
2072 {
2073 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2074 RET;
2075 }
2076
2077 if (NON_STACK_REG_P (operands[0]))
2078 {
f25aca7a 2079 output_to_reg (operands[0], stack_top_dies, 0);
886c62d1
JVA
2080 RET;
2081 }
2082
2083 if (STACK_TOP_P (operands[0]))
2084 return AS1 (fld%z1,%y1);
2085
2086 if (GET_CODE (operands[0]) == MEM)
2087 {
2088 if (stack_top_dies)
2089 return AS1 (fstp%z0,%y0);
2090 else
2091 return AS1 (fst%z0,%y0);
2092 }
2093
2094 abort ();
2095}")
2096
4fb21e90 2097(define_insn "extenddfxf2"
2ae0f82c 2098 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
4fb21e90 2099 (float_extend:XF
2ae0f82c 2100 (match_operand:DF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
4fb21e90
JVA
2101 "TARGET_80387"
2102 "*
2103{
2104 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2105
2106 if (NON_STACK_REG_P (operands[1]))
2107 {
2108 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2109 RET;
2110 }
2111
2112 if (NON_STACK_REG_P (operands[0]))
2113 {
f25aca7a 2114 output_to_reg (operands[0], stack_top_dies, 0);
4fb21e90
JVA
2115 RET;
2116 }
2117
2118 if (STACK_TOP_P (operands[0]))
2119 return AS1 (fld%z1,%y1);
2120
2121 if (GET_CODE (operands[0]) == MEM)
2122 {
2f17722a
JVA
2123 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2124 if (! stack_top_dies)
2125 return AS1 (fld%z0,%y0);
2126 RET;
4fb21e90
JVA
2127 }
2128
2129 abort ();
2130}")
2131
2132(define_insn "extendsfxf2"
2ae0f82c 2133 [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r")
4fb21e90 2134 (float_extend:XF
2ae0f82c 2135 (match_operand:SF 1 "nonimmediate_operand" "f,fm,!*r,f")))]
4fb21e90
JVA
2136 "TARGET_80387"
2137 "*
2138{
2139 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2140
2141 if (NON_STACK_REG_P (operands[1]))
2142 {
2143 output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
2144 RET;
2145 }
2146
2147 if (NON_STACK_REG_P (operands[0]))
2148 {
f25aca7a 2149 output_to_reg (operands[0], stack_top_dies, 0);
4fb21e90
JVA
2150 RET;
2151 }
2152
2153 if (STACK_TOP_P (operands[0]))
2154 return AS1 (fld%z1,%y1);
2155
2156 if (GET_CODE (operands[0]) == MEM)
2157 {
2f17722a
JVA
2158 output_asm_insn (AS1 (fstp%z0,%y0), operands);
2159 if (! stack_top_dies)
2160 return AS1 (fld%z0,%y0);
2161 RET;
4fb21e90
JVA
2162 }
2163
2164 abort ();
2165}")
2166
0fcad513
JVA
2167(define_expand "truncdfsf2"
2168 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2169 (float_truncate:SF
2170 (match_operand:DF 1 "register_operand" "")))
2171 (clobber (match_dup 2))])]
2172 "TARGET_80387"
2173 "
2174{
2175 operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
2176}")
2177
886c62d1
JVA
2178;; This cannot output into an f-reg because there is no way to be sure
2179;; of truncating in that case. Otherwise this is just like a simple move
0fcad513
JVA
2180;; insn. So we pretend we can output to a reg in order to get better
2181;; register preferencing, but we really use a stack slot.
886c62d1 2182
0fcad513 2183(define_insn ""
fe4435d9 2184 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
886c62d1 2185 (float_truncate:SF
0fcad513
JVA
2186 (match_operand:DF 1 "register_operand" "0,f")))
2187 (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
886c62d1
JVA
2188 "TARGET_80387"
2189 "*
2190{
2191 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2192
fe4435d9 2193 if (GET_CODE (operands[0]) == MEM)
886c62d1
JVA
2194 {
2195 if (stack_top_dies)
2196 return AS1 (fstp%z0,%0);
2197 else
2198 return AS1 (fst%z0,%0);
2199 }
fe4435d9
JVA
2200 else if (STACK_TOP_P (operands[0]))
2201 {
0fcad513
JVA
2202 output_asm_insn (AS1 (fstp%z2,%y2), operands);
2203 return AS1 (fld%z2,%y2);
fe4435d9 2204 }
886c62d1
JVA
2205 else
2206 abort ();
2207}")
4fb21e90
JVA
2208
2209(define_insn "truncxfsf2"
2ae0f82c 2210 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r")
4fb21e90
JVA
2211 (float_truncate:SF
2212 (match_operand:XF 1 "register_operand" "f,f")))]
2213 "TARGET_80387"
2214 "*
2215{
2216 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2217
2218 if (NON_STACK_REG_P (operands[0]))
2219 {
2220 if (stack_top_dies == 0)
2221 {
2222 output_asm_insn (AS1 (fld,%y1), operands);
2223 stack_top_dies = 1;
2224 }
f25aca7a 2225 output_to_reg (operands[0], stack_top_dies, 0);
4fb21e90
JVA
2226 RET;
2227 }
2228 else if (GET_CODE (operands[0]) == MEM)
2229 {
2230 if (stack_top_dies)
2231 return AS1 (fstp%z0,%0);
2232 else
2233 {
2234 output_asm_insn (AS1 (fld,%y1), operands);
2235 return AS1 (fstp%z0,%0);
2236 }
2237 }
2238 else
2239 abort ();
2240}")
2241
2242(define_insn "truncxfdf2"
2ae0f82c 2243 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r")
4fb21e90
JVA
2244 (float_truncate:DF
2245 (match_operand:XF 1 "register_operand" "f,f")))]
2246 "TARGET_80387"
2247 "*
2248{
2249 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2250
2251 if (NON_STACK_REG_P (operands[0]))
2252 {
2253 if (stack_top_dies == 0)
2254 {
2255 output_asm_insn (AS1 (fld,%y1), operands);
2256 stack_top_dies = 1;
2257 }
f25aca7a 2258 output_to_reg (operands[0], stack_top_dies, 0);
4fb21e90
JVA
2259 RET;
2260 }
2261 else if (GET_CODE (operands[0]) == MEM)
2262 {
2263 if (stack_top_dies)
2264 return AS1 (fstp%z0,%0);
2265 else
2266 {
2267 output_asm_insn (AS1 (fld,%y1), operands);
2268 return AS1 (fstp%z0,%0);
2269 }
2270 }
2271 else
2272 abort ();
2273}")
2274
886c62d1
JVA
2275\f
2276;; The 387 requires that the stack top dies after converting to DImode.
2277
2278;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
2279;; doing a signed conversion to DImode, and then taking just the low
2280;; part.
2281
4fb21e90
JVA
2282(define_expand "fixuns_truncxfsi2"
2283 [(set (match_dup 4)
2284 (match_operand:XF 1 "register_operand" ""))
2285 (parallel [(set (match_dup 2)
2286 (fix:DI (fix:XF (match_dup 4))))
2287 (clobber (match_dup 4))
2288 (clobber (match_dup 5))
2289 (clobber (match_dup 6))
2290 (clobber (match_scratch:SI 7 ""))])
2291 (set (match_operand:SI 0 "general_operand" "")
2292 (match_dup 3))]
2293 "TARGET_80387"
2294 "
2295{
2296 operands[2] = gen_reg_rtx (DImode);
2297 operands[3] = gen_lowpart (SImode, operands[2]);
2298 operands[4] = gen_reg_rtx (XFmode);
2299 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2300 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
4fb21e90
JVA
2301}")
2302
886c62d1 2303(define_expand "fixuns_truncdfsi2"
0fcad513 2304 [(set (match_dup 4)
eb085d72 2305 (match_operand:DF 1 "register_operand" ""))
0fcad513
JVA
2306 (parallel [(set (match_dup 2)
2307 (fix:DI (fix:DF (match_dup 4))))
2308 (clobber (match_dup 4))
2309 (clobber (match_dup 5))
2310 (clobber (match_dup 6))
2311 (clobber (match_scratch:SI 7 ""))])
886c62d1 2312 (set (match_operand:SI 0 "general_operand" "")
0fcad513 2313 (match_dup 3))]
886c62d1
JVA
2314 "TARGET_80387"
2315 "
2316{
0fcad513
JVA
2317 operands[2] = gen_reg_rtx (DImode);
2318 operands[3] = gen_lowpart (SImode, operands[2]);
2319 operands[4] = gen_reg_rtx (DFmode);
2320 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2321 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
886c62d1
JVA
2322}")
2323
2324(define_expand "fixuns_truncsfsi2"
0fcad513 2325 [(set (match_dup 4)
eb085d72 2326 (match_operand:SF 1 "register_operand" ""))
0fcad513
JVA
2327 (parallel [(set (match_dup 2)
2328 (fix:DI (fix:SF (match_dup 4))))
2329 (clobber (match_dup 4))
2330 (clobber (match_dup 5))
2331 (clobber (match_dup 6))
2332 (clobber (match_scratch:SI 7 ""))])
886c62d1 2333 (set (match_operand:SI 0 "general_operand" "")
0fcad513 2334 (match_dup 3))]
886c62d1
JVA
2335 "TARGET_80387"
2336 "
2337{
0fcad513
JVA
2338 operands[2] = gen_reg_rtx (DImode);
2339 operands[3] = gen_lowpart (SImode, operands[2]);
2340 operands[4] = gen_reg_rtx (SFmode);
2341 operands[5] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2342 operands[6] = (rtx) assign_386_stack_local (DImode, 1);
886c62d1
JVA
2343}")
2344
2345;; Signed conversion to DImode.
2346
4fb21e90 2347(define_expand "fix_truncxfdi2"
eb085d72
MM
2348 [(set (match_dup 2)
2349 (match_operand:XF 1 "register_operand" ""))
2350 (parallel [(set (match_operand:DI 0 "general_operand" "")
2351 (fix:DI (fix:XF (match_dup 2))))
2352 (clobber (match_dup 2))
2353 (clobber (match_dup 3))
2354 (clobber (match_dup 4))
2355 (clobber (match_scratch:SI 5 ""))])]
4fb21e90
JVA
2356 "TARGET_80387"
2357 "
2358{
eb085d72
MM
2359 operands[1] = copy_to_mode_reg (XFmode, operands[1]);
2360 operands[2] = gen_reg_rtx (XFmode);
2361 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2362 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
4fb21e90
JVA
2363}")
2364
886c62d1 2365(define_expand "fix_truncdfdi2"
eb085d72
MM
2366 [(set (match_dup 2)
2367 (match_operand:DF 1 "register_operand" ""))
2368 (parallel [(set (match_operand:DI 0 "general_operand" "")
2369 (fix:DI (fix:DF (match_dup 2))))
2370 (clobber (match_dup 2))
2371 (clobber (match_dup 3))
2372 (clobber (match_dup 4))
2373 (clobber (match_scratch:SI 5 ""))])]
886c62d1
JVA
2374 "TARGET_80387"
2375 "
2376{
eb085d72
MM
2377 operands[1] = copy_to_mode_reg (DFmode, operands[1]);
2378 operands[2] = gen_reg_rtx (DFmode);
2379 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2380 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
886c62d1
JVA
2381}")
2382
2383(define_expand "fix_truncsfdi2"
eb085d72
MM
2384 [(set (match_dup 2)
2385 (match_operand:SF 1 "register_operand" ""))
2386 (parallel [(set (match_operand:DI 0 "general_operand" "")
2387 (fix:DI (fix:SF (match_dup 2))))
2388 (clobber (match_dup 2))
2389 (clobber (match_dup 3))
2390 (clobber (match_dup 4))
2391 (clobber (match_scratch:SI 5 ""))])]
886c62d1
JVA
2392 "TARGET_80387"
2393 "
2394{
eb085d72
MM
2395 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
2396 operands[2] = gen_reg_rtx (SFmode);
2397 operands[3] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2398 operands[4] = (rtx) assign_386_stack_local (DImode, 1);
886c62d1
JVA
2399}")
2400
b4ac57ab 2401;; These match a signed conversion of either DFmode or SFmode to DImode.
886c62d1 2402
eb085d72 2403(define_insn ""
2ae0f82c 2404 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
7beb6381 2405 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "+f"))))
4fb21e90
JVA
2406 (clobber (match_dup 1))
2407 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2408 (clobber (match_operand:DI 3 "memory_operand" "m"))
4fb21e90
JVA
2409 (clobber (match_scratch:SI 4 "=&q"))]
2410 "TARGET_80387"
2f2a49e8 2411 "* return output_fix_trunc (insn, operands);")
4fb21e90 2412
eb085d72 2413(define_insn ""
2ae0f82c 2414 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
7beb6381 2415 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "+f"))))
0fcad513
JVA
2416 (clobber (match_dup 1))
2417 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2418 (clobber (match_operand:DI 3 "memory_operand" "m"))
0fcad513 2419 (clobber (match_scratch:SI 4 "=&q"))]
886c62d1 2420 "TARGET_80387"
2f2a49e8 2421 "* return output_fix_trunc (insn, operands);")
886c62d1 2422
eb085d72 2423(define_insn ""
2ae0f82c 2424 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
7beb6381 2425 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "+f"))))
0fcad513
JVA
2426 (clobber (match_dup 1))
2427 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2428 (clobber (match_operand:DI 3 "memory_operand" "m"))
0fcad513 2429 (clobber (match_scratch:SI 4 "=&q"))]
886c62d1 2430 "TARGET_80387"
2f2a49e8 2431 "* return output_fix_trunc (insn, operands);")
886c62d1
JVA
2432
2433;; Signed MODE_FLOAT conversion to SImode.
2434
4fb21e90
JVA
2435(define_expand "fix_truncxfsi2"
2436 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2437 (fix:SI
2438 (fix:XF (match_operand:XF 1 "register_operand" ""))))
2439 (clobber (match_dup 2))
2440 (clobber (match_dup 3))
2441 (clobber (match_scratch:SI 4 ""))])]
2442 "TARGET_80387"
2443 "
2444{
2445 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2446 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
4fb21e90
JVA
2447}")
2448
886c62d1
JVA
2449(define_expand "fix_truncdfsi2"
2450 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2451 (fix:SI
2452 (fix:DF (match_operand:DF 1 "register_operand" ""))))
0fcad513
JVA
2453 (clobber (match_dup 2))
2454 (clobber (match_dup 3))
2455 (clobber (match_scratch:SI 4 ""))])]
886c62d1 2456 "TARGET_80387"
0fcad513
JVA
2457 "
2458{
2459 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2460 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
0fcad513 2461}")
886c62d1
JVA
2462
2463(define_expand "fix_truncsfsi2"
2464 [(parallel [(set (match_operand:SI 0 "general_operand" "")
2465 (fix:SI
2466 (fix:SF (match_operand:SF 1 "register_operand" ""))))
0fcad513
JVA
2467 (clobber (match_dup 2))
2468 (clobber (match_dup 3))
2469 (clobber (match_scratch:SI 4 ""))])]
886c62d1 2470 "TARGET_80387"
0fcad513
JVA
2471 "
2472{
2473 operands[2] = (rtx) assign_386_stack_local (SImode, 0);
f25aca7a 2474 operands[3] = (rtx) assign_386_stack_local (DImode, 1);
0fcad513 2475}")
886c62d1 2476
4fb21e90 2477(define_insn ""
2ae0f82c 2478 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4fb21e90
JVA
2479 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
2480 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2481 (clobber (match_operand:DI 3 "memory_operand" "m"))
4fb21e90
JVA
2482 (clobber (match_scratch:SI 4 "=&q"))]
2483 "TARGET_80387"
2f2a49e8 2484 "* return output_fix_trunc (insn, operands);")
4fb21e90 2485
886c62d1 2486(define_insn ""
2ae0f82c 2487 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
08a7baac 2488 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
0fcad513 2489 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2490 (clobber (match_operand:DI 3 "memory_operand" "m"))
0fcad513 2491 (clobber (match_scratch:SI 4 "=&q"))]
886c62d1 2492 "TARGET_80387"
2f2a49e8 2493 "* return output_fix_trunc (insn, operands);")
886c62d1
JVA
2494
2495(define_insn ""
2ae0f82c 2496 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
08a7baac 2497 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
0fcad513 2498 (clobber (match_operand:SI 2 "memory_operand" "m"))
f25aca7a 2499 (clobber (match_operand:DI 3 "memory_operand" "m"))
0fcad513 2500 (clobber (match_scratch:SI 4 "=&q"))]
886c62d1 2501 "TARGET_80387"
2f2a49e8 2502 "* return output_fix_trunc (insn, operands);")
886c62d1
JVA
2503\f
2504;; Conversion between fixed point and floating point.
2505;; The actual pattern that matches these is at the end of this file.
2506
b4ac57ab 2507;; ??? Possibly represent floatunssidf2 here in gcc2.
886c62d1
JVA
2508
2509(define_expand "floatsisf2"
2510 [(set (match_operand:SF 0 "register_operand" "")
08a7baac 2511 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
886c62d1
JVA
2512 "TARGET_80387"
2513 "")
2514
2515(define_expand "floatdisf2"
2516 [(set (match_operand:SF 0 "register_operand" "")
08a7baac 2517 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
886c62d1
JVA
2518 "TARGET_80387"
2519 "")
2520
2521(define_expand "floatsidf2"
2522 [(set (match_operand:DF 0 "register_operand" "")
08a7baac 2523 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
886c62d1
JVA
2524 "TARGET_80387"
2525 "")
2526
2527(define_expand "floatdidf2"
2528 [(set (match_operand:DF 0 "register_operand" "")
08a7baac 2529 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
886c62d1
JVA
2530 "TARGET_80387"
2531 "")
2532
4fb21e90
JVA
2533(define_expand "floatsixf2"
2534 [(set (match_operand:XF 0 "register_operand" "")
2535 (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
2536 "TARGET_80387"
2537 "")
2538
2539(define_expand "floatdixf2"
2540 [(set (match_operand:XF 0 "register_operand" "")
2541 (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
f58acb67 2542 "TARGET_80387 && LONG_DOUBLE_TYPE_SIZE == 96"
4fb21e90
JVA
2543 "")
2544
886c62d1
JVA
2545;; This will convert from SImode or DImode to MODE_FLOAT.
2546
4fb21e90
JVA
2547(define_insn ""
2548 [(set (match_operand:XF 0 "register_operand" "=f")
2ae0f82c 2549 (float:XF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
4fb21e90
JVA
2550 "TARGET_80387"
2551 "*
2552{
2553 if (NON_STACK_REG_P (operands[1]))
2554 {
2555 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2556 RET;
2557 }
2558 else if (GET_CODE (operands[1]) == MEM)
2559 return AS1 (fild%z1,%1);
2560 else
2561 abort ();
2562}")
2563
886c62d1 2564(define_insn ""
08a7baac
JVA
2565 [(set (match_operand:DF 0 "register_operand" "=f")
2566 (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
e1f998ad 2567 "TARGET_80387"
886c62d1
JVA
2568 "*
2569{
2570 if (NON_STACK_REG_P (operands[1]))
2571 {
2572 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2573 RET;
2574 }
2575 else if (GET_CODE (operands[1]) == MEM)
2576 return AS1 (fild%z1,%1);
2577 else
2578 abort ();
2579}")
2580
2581(define_insn ""
08a7baac
JVA
2582 [(set (match_operand:SF 0 "register_operand" "=f")
2583 (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
e1f998ad
JVA
2584 "TARGET_80387"
2585 "*
2586{
2587 if (NON_STACK_REG_P (operands[1]))
2588 {
2589 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2590 RET;
2591 }
2592 else if (GET_CODE (operands[1]) == MEM)
2593 return AS1 (fild%z1,%1);
2594 else
2595 abort ();
2596}")
2597
2598(define_insn ""
08a7baac
JVA
2599 [(set (match_operand:DF 0 "register_operand" "=f")
2600 (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
e1f998ad
JVA
2601 "TARGET_80387"
2602 "*
2603{
2604 if (NON_STACK_REG_P (operands[1]))
2605 {
2606 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2607 RET;
2608 }
2609 else if (GET_CODE (operands[1]) == MEM)
2610 return AS1 (fild%z1,%1);
2611 else
2612 abort ();
2613}")
2614
4fb21e90
JVA
2615(define_insn ""
2616 [(set (match_operand:XF 0 "register_operand" "=f,f")
2ae0f82c 2617 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!*r")))]
4fb21e90
JVA
2618 "TARGET_80387"
2619 "*
2620{
2621 if (NON_STACK_REG_P (operands[1]))
2622 {
2623 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2624 RET;
2625 }
2626 else if (GET_CODE (operands[1]) == MEM)
2627 return AS1 (fild%z1,%1);
2628 else
2629 abort ();
2630}")
2631
e1f998ad 2632(define_insn ""
08a7baac
JVA
2633 [(set (match_operand:SF 0 "register_operand" "=f")
2634 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
e1f998ad 2635 "TARGET_80387"
886c62d1
JVA
2636 "*
2637{
2638 if (NON_STACK_REG_P (operands[1]))
2639 {
2640 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
2641 RET;
2642 }
2643 else if (GET_CODE (operands[1]) == MEM)
2644 return AS1 (fild%z1,%1);
2645 else
2646 abort ();
2647}")
2648\f
2649;;- add instructions
2650
f58acb67
SC
2651(define_insn "addsidi3_1"
2652 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o")
2ae0f82c
SC
2653 (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o")
2654 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri"))))
2655 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))]
f58acb67 2656 ""
2ae0f82c
SC
2657 "*
2658{
2659 rtx low[3], high[3], xops[7], temp;
2660
2661 CC_STATUS_INIT;
2662
2663 split_di (operands, 2, low, high);
2664 high[2] = const0_rtx;
2665 low[2] = operands[2];
2666
2667 if (!rtx_equal_p (operands[0], operands[1]))
2668 {
2669 xops[0] = high[0];
2670 xops[1] = low[0];
2671 xops[2] = high[1];
2672 xops[3] = low[1];
2673
2674 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2675 {
2676 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2677 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2678 }
2679 else
2680 {
2681 xops[4] = high[2];
2682 xops[5] = low[2];
2683 xops[6] = operands[3];
2684 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2685 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2686 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2687 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2688 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2689 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2690 RET;
2691 }
2692 }
2693
2694 output_asm_insn (AS2 (add%L0,%2,%0), low);
2695 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2696 RET;
2697}")
2698
f58acb67 2699(define_insn "addsidi3_2"
5bc7cd8e 2700 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o")
f58acb67
SC
2701 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r"))
2702 (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o")))
2703 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))]
2704 ""
2ae0f82c
SC
2705 "*
2706{
2707 rtx low[3], high[3], xops[7], temp;
2708
2709 CC_STATUS_INIT;
2710
2711 split_di (operands, 2, low, high);
2712 high[2] = const0_rtx;
2713 low[2] = operands[2];
2714
2715 if (!rtx_equal_p (operands[0], operands[1]))
2716 {
2717 xops[0] = high[0];
2718 xops[1] = low[0];
2719 xops[2] = high[1];
2720 xops[3] = low[1];
2721
2722 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2723 {
70cff8f5
RK
2724 if (rtx_equal_p (low[0], operands[2]))
2725 {
2726 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2727 output_asm_insn (AS2 (add%L0,%1,%0), low);
2728 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2729 RET;
2730 }
2731 if (rtx_equal_p (high[0], operands[2]))
2732 {
2733 if (GET_CODE (operands[0]) != MEM)
2734 {
2735 output_asm_insn (AS2 (mov%L0,%2,%0), low);
2736 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2737 output_asm_insn (AS2 (add%L0,%1,%0), low);
2738 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2739 }
2740 else
2741 {
2742 /* It's too late to ask for a scratch now - but this
2743 will probably not happen too often. */
2744 output_asm_insn (AS2 (add%L1,%2,%1), low);
2745 output_asm_insn (AS2 (mov%L0,%1,%0), low);
2746 output_asm_insn (AS2 (mov%L1,%2,%1), low);
2747 output_asm_insn (AS2 (mov%L0,%2,%0), high);
2748 output_asm_insn (AS2 (adc%L0,%1,%0), high);
2749 output_asm_insn (AS2 (sub%L1,%0,%1), low);
2750 output_asm_insn (AS1 (neg%L1,%1), low);
2751 }
2752 RET;
2753 }
2ae0f82c
SC
2754 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2755 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2756 }
2757 else
2758 {
2759 xops[4] = high[2];
2760 xops[5] = low[2];
2761 xops[6] = operands[3];
2762 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2763 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2764 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2765 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2766 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2767 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2768 RET;
2769 }
2770 }
2771
2772 output_asm_insn (AS2 (add%L0,%2,%0), low);
2773 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2774 RET;
2775}")
2776
f58acb67 2777(define_insn "adddi3"
93f83bd5
R
2778 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
2779 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
2780 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
2781 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
886c62d1
JVA
2782 ""
2783 "*
2784{
f94bdcb6 2785 rtx low[3], high[3], xops[7], temp;
886c62d1
JVA
2786
2787 CC_STATUS_INIT;
2788
f94bdcb6
MM
2789 if (rtx_equal_p (operands[0], operands[2]))
2790 {
2791 temp = operands[1];
2792 operands[1] = operands[2];
2793 operands[2] = temp;
2794 }
886c62d1 2795
f94bdcb6 2796 split_di (operands, 3, low, high);
96f218bb
MM
2797 if (!rtx_equal_p (operands[0], operands[1]))
2798 {
2799 xops[0] = high[0];
2800 xops[1] = low[0];
2801 xops[2] = high[1];
2802 xops[3] = low[1];
2803
8ff9a9d1 2804 if (GET_CODE (operands[0]) != MEM)
96f218bb
MM
2805 {
2806 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
2807 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
2808 }
2809 else
2810 {
2811 xops[4] = high[2];
2812 xops[5] = low[2];
2813 xops[6] = operands[3];
2814 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
2815 output_asm_insn (AS2 (add%L6,%5,%6), xops);
2816 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
2817 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
2818 output_asm_insn (AS2 (adc%L6,%4,%6), xops);
2819 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
2820 RET;
2821 }
2822 }
2823
f94bdcb6 2824 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
96f218bb
MM
2825 {
2826 xops[0] = high[0];
2827 xops[1] = low[0];
2828 xops[2] = high[2];
2829 xops[3] = low[2];
2830 xops[4] = operands[3];
2831
2832 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
2833 output_asm_insn (AS2 (add%L1,%4,%1), xops);
2834 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
2835 output_asm_insn (AS2 (adc%L0,%4,%0), xops);
2836 }
2837
2838 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
9c530261
JVA
2839 {
2840 output_asm_insn (AS2 (add%L0,%2,%0), low);
2841 output_asm_insn (AS2 (adc%L0,%2,%0), high);
2842 }
96f218bb 2843
9c530261
JVA
2844 else
2845 output_asm_insn (AS2 (add%L0,%2,%0), high);
96f218bb 2846
886c62d1
JVA
2847 RET;
2848}")
2849
2850;; On a 486, it is faster to do movl/addl than to do a single leal if
2851;; operands[1] and operands[2] are both registers.
2852
2ae0f82c
SC
2853(define_expand "addsi3"
2854 [(set (match_operand:SI 0 "nonimmediate_operand" "")
2855 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
2856 (match_operand:SI 2 "general_operand" "")))]
886c62d1 2857 ""
2ae0f82c
SC
2858 "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);")
2859
2860(define_insn ""
2861 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
2862 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
2863 (match_operand:SI 2 "general_operand" "rmi,ri,ri")))]
2864 "ix86_binary_operator_ok (PLUS, SImode, operands)"
886c62d1
JVA
2865 "*
2866{
2ae0f82c
SC
2867 if (REG_P (operands[0]) && REG_P (operands[1])
2868 && (REG_P (operands[2]) || GET_CODE (operands[2]) == CONST_INT)
2869 && REGNO (operands[0]) != REGNO (operands[1]))
886c62d1
JVA
2870 {
2871 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
2872 return AS2 (add%L0,%1,%0);
2873
c1450f19
MM
2874 if (operands[2] == stack_pointer_rtx)
2875 {
2876 rtx temp;
44242645 2877
c1450f19
MM
2878 temp = operands[1];
2879 operands[1] = operands[2];
2880 operands[2] = temp;
2881 }
44242645 2882
c1450f19
MM
2883 if (operands[2] != stack_pointer_rtx)
2884 {
2885 CC_STATUS_INIT;
2886 operands[1] = SET_SRC (PATTERN (insn));
2887 return AS2 (lea%L0,%a1,%0);
886c62d1 2888 }
886c62d1
JVA
2889 }
2890
2ae0f82c
SC
2891 if (!rtx_equal_p (operands[0], operands[1]))
2892 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
2893
886c62d1
JVA
2894 if (operands[2] == const1_rtx)
2895 return AS1 (inc%L0,%0);
2896
2897 if (operands[2] == constm1_rtx)
2898 return AS1 (dec%L0,%0);
2899
5bc7cd8e
SC
2900 /* subl $-128,%ebx is smaller than addl $128,%ebx. */
2901 if (GET_CODE (operands[2]) == CONST_INT
2902 && INTVAL (operands[2]) == 128)
2903 {
2904 /* This doesn't compute the carry bit in the same way
2905 * as add%L0, but we use inc and dec above and they
2906 * don't set the carry bit at all. If inc/dec don't need
2907 * a CC_STATUS_INIT, this doesn't either... */
2908 operands[2] = GEN_INT (-128);
2909 return AS2 (sub%L0,%2,%0);
2910 }
2911
886c62d1
JVA
2912 return AS2 (add%L0,%2,%0);
2913}")
2914
2ae0f82c
SC
2915;; addsi3 is faster, so put this after.
2916
2917(define_insn "movsi_lea"
2918 [(set (match_operand:SI 0 "register_operand" "=r")
2919 (match_operand:QI 1 "address_operand" "p"))]
2920 ""
2921 "*
2922{
2923 /* Adding a constant to a register is faster with an add. */
2924 /* ??? can this ever happen? */
2925 if (GET_CODE (operands[1]) == PLUS
2926 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
2927 && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
2928 {
2929 operands[1] = XEXP (operands[1], 1);
2930
2931 if (operands[1] == const1_rtx)
2932 return AS1 (inc%L0,%0);
2933
2934 if (operands[1] == constm1_rtx)
2935 return AS1 (dec%L0,%0);
2936
2937 return AS2 (add%L0,%1,%0);
2938 }
2939
2940 CC_STATUS_INIT;
2941 return AS2 (lea%L0,%a1,%0);
2942}")
2943
886c62d1
JVA
2944;; ??? `lea' here, for three operand add? If leaw is used, only %bx,
2945;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
2946;; able to handle the operand. But leal always works?
2947
2ae0f82c
SC
2948(define_expand "addhi3"
2949 [(set (match_operand:HI 0 "general_operand" "")
2950 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
2951 (match_operand:HI 2 "general_operand" "")))]
886c62d1 2952 ""
2ae0f82c
SC
2953 "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);")
2954
2955(define_insn ""
2956 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
2957 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
2958 (match_operand:HI 2 "general_operand" "ri,rm")))]
2959 "ix86_binary_operator_ok (PLUS, HImode, operands)"
886c62d1
JVA
2960 "*
2961{
b980bec0 2962 /* ??? what about offsettable memory references? */
5bc7cd8e
SC
2963 if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */
2964 && QI_REG_P (operands[0])
b980bec0 2965 && GET_CODE (operands[2]) == CONST_INT
5bc7cd8e
SC
2966 && (INTVAL (operands[2]) & 0xff) == 0
2967 && i386_cc_probably_useless_p (insn))
b980bec0 2968 {
c64ca3e9 2969 int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
b980bec0
JVA
2970 CC_STATUS_INIT;
2971
c64ca3e9 2972 if (byteval == 1)
b980bec0 2973 return AS1 (inc%B0,%h0);
c64ca3e9 2974 else if (byteval == 255)
b980bec0
JVA
2975 return AS1 (dec%B0,%h0);
2976
c64ca3e9 2977 operands[2] = GEN_INT (byteval);
b980bec0
JVA
2978 return AS2 (add%B0,%2,%h0);
2979 }
2980
5bc7cd8e
SC
2981 /* Use a 32-bit operation when possible, to avoid the prefix penalty. */
2982 if (REG_P (operands[0])
2983 && i386_aligned_p (operands[2])
2984 && i386_cc_probably_useless_p (insn))
2985 {
2986 CC_STATUS_INIT;
2987
2988 if (GET_CODE (operands[2]) == CONST_INT)
2989 {
2990 HOST_WIDE_INT intval = 0xffff & INTVAL (operands[2]);
2991
2992 if (intval == 1)
2993 return AS1 (inc%L0,%k0);
2994
2995 if (intval == 0xffff)
2996 return AS1 (dec%L0,%k0);
2997
2998 operands[2] = i386_sext16_if_const (operands[2]);
2999 }
3000 return AS2 (add%L0,%k2,%k0);
3001 }
3002
886c62d1
JVA
3003 if (operands[2] == const1_rtx)
3004 return AS1 (inc%W0,%0);
3005
c64ca3e9
RK
3006 if (operands[2] == constm1_rtx
3007 || (GET_CODE (operands[2]) == CONST_INT
3008 && INTVAL (operands[2]) == 65535))
886c62d1
JVA
3009 return AS1 (dec%W0,%0);
3010
3011 return AS2 (add%W0,%2,%0);
3012}")
3013
2ae0f82c
SC
3014(define_expand "addqi3"
3015 [(set (match_operand:QI 0 "general_operand" "")
3016 (plus:QI (match_operand:QI 1 "general_operand" "")
3017 (match_operand:QI 2 "general_operand" "")))]
886c62d1 3018 ""
2ae0f82c
SC
3019 "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);")
3020
3021(define_insn ""
3022 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3023 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
3024 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3025 "ix86_binary_operator_ok (PLUS, QImode, operands)"
886c62d1
JVA
3026 "*
3027{
3028 if (operands[2] == const1_rtx)
3029 return AS1 (inc%B0,%0);
3030
c64ca3e9
RK
3031 if (operands[2] == constm1_rtx
3032 || (GET_CODE (operands[2]) == CONST_INT
3033 && INTVAL (operands[2]) == 255))
886c62d1
JVA
3034 return AS1 (dec%B0,%0);
3035
3036 return AS2 (add%B0,%2,%0);
3037}")
3038
3039;Lennart Augustsson <augustss@cs.chalmers.se>
3040;says this pattern just makes slower code:
3041; pushl %ebp
3042; addl $-80,(%esp)
3043;instead of
3044; leal -80(%ebp),%eax
3045; pushl %eax
3046;
3047;(define_insn ""
3048; [(set (match_operand:SI 0 "push_operand" "=<")
2ae0f82c
SC
3049; (plus:SI (match_operand:SI 1 "register_operand" "%r")
3050; (match_operand:SI 2 "nonmemory_operand" "ri")))]
886c62d1
JVA
3051; ""
3052; "*
3053;{
3054; rtx xops[4];
3055; xops[0] = operands[0];
3056; xops[1] = operands[1];
3057; xops[2] = operands[2];
f64cecad 3058; xops[3] = gen_rtx_MEM (SImode, stack_pointer_rtx);
886c62d1
JVA
3059; output_asm_insn (\"push%z1 %1\", xops);
3060; output_asm_insn (AS2 (add%z3,%2,%3), xops);
3061; RET;
3062;}")
3063
886c62d1
JVA
3064;; The patterns that match these are at the end of this file.
3065
4fb21e90
JVA
3066(define_expand "addxf3"
3067 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
3068 (plus:XF (match_operand:XF 1 "register_operand" "")
3069 (match_operand:XF 2 "register_operand" "")))]
4fb21e90
JVA
3070 "TARGET_80387"
3071 "")
3072
886c62d1
JVA
3073(define_expand "adddf3"
3074 [(set (match_operand:DF 0 "register_operand" "")
3075 (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3076 (match_operand:DF 2 "nonimmediate_operand" "")))]
3077 "TARGET_80387"
3078 "")
3079
3080(define_expand "addsf3"
3081 [(set (match_operand:SF 0 "register_operand" "")
3082 (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3083 (match_operand:SF 2 "nonimmediate_operand" "")))]
3084 "TARGET_80387"
3085 "")
3086\f
3087;;- subtract instructions
3088
f58acb67
SC
3089(define_insn "subsidi3"
3090 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o")
3091 (minus:DI (match_operand:DI 1 "general_operand" "0iF,0,roiF,roiF,riF,o,o")
3092 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,ri,i,r"))))
3093 (clobber (match_scratch:SI 3 "=X,X,X,X,X,&r,&r"))]
3094 ""
2ae0f82c
SC
3095 "*
3096{
3097 rtx low[3], high[3], xops[7];
3098
3099 CC_STATUS_INIT;
3100
3101 split_di (operands, 2, low, high);
3102 high[2] = const0_rtx;
3103 low[2] = operands[2];
3104
3105 if (!rtx_equal_p (operands[0], operands[1]))
3106 {
3107 xops[0] = high[0];
3108 xops[1] = low[0];
3109 xops[2] = high[1];
3110 xops[3] = low[1];
3111
3112 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3113 {
3114 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3115 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3116 }
3117 else
3118 {
3119 xops[4] = high[2];
3120 xops[5] = low[2];
3121 xops[6] = operands[3];
3122 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3123 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3124 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3125 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3126 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3127 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3128 RET;
3129 }
3130 }
3131
3132 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3133 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3134 RET;
3135}")
3136
f58acb67
SC
3137(define_insn "subdi3"
3138 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
3139 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0iF,or,roiF,roiF")
3140 (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
3141 (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
acb94fa1 3142 ""
886c62d1
JVA
3143 "*
3144{
96f218bb 3145 rtx low[3], high[3], xops[7];
886c62d1
JVA
3146
3147 CC_STATUS_INIT;
3148
3149 split_di (operands, 3, low, high);
3150
96f218bb
MM
3151 if (!rtx_equal_p (operands[0], operands[1]))
3152 {
3153 xops[0] = high[0];
3154 xops[1] = low[0];
3155 xops[2] = high[1];
3156 xops[3] = low[1];
3157
dee6d39e 3158 if (GET_CODE (operands[0]) != MEM)
96f218bb
MM
3159 {
3160 output_asm_insn (AS2 (mov%L1,%3,%1), xops);
3161 output_asm_insn (AS2 (mov%L0,%2,%0), xops);
3162 }
3163 else
3164 {
3165 xops[4] = high[2];
3166 xops[5] = low[2];
3167 xops[6] = operands[3];
3168 output_asm_insn (AS2 (mov%L6,%3,%6), xops);
3169 output_asm_insn (AS2 (sub%L6,%5,%6), xops);
3170 output_asm_insn (AS2 (mov%L1,%6,%1), xops);
3171 output_asm_insn (AS2 (mov%L6,%2,%6), xops);
3172 output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
3173 output_asm_insn (AS2 (mov%L0,%6,%0), xops);
3174 RET;
3175 }
3176 }
3177
3178 if (GET_CODE (operands[3]) == REG)
3179 {
3180 xops[0] = high[0];
3181 xops[1] = low[0];
3182 xops[2] = high[2];
3183 xops[3] = low[2];
3184 xops[4] = operands[3];
3185
3186 output_asm_insn (AS2 (mov%L4,%3,%4), xops);
3187 output_asm_insn (AS2 (sub%L1,%4,%1), xops);
3188 output_asm_insn (AS2 (mov%L4,%2,%4), xops);
3189 output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
3190 }
3191
3192 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
9c530261
JVA
3193 {
3194 output_asm_insn (AS2 (sub%L0,%2,%0), low);
3195 output_asm_insn (AS2 (sbb%L0,%2,%0), high);
3196 }
96f218bb 3197
9c530261
JVA
3198 else
3199 output_asm_insn (AS2 (sub%L0,%2,%0), high);
3200
886c62d1
JVA
3201 RET;
3202}")
3203
2ae0f82c
SC
3204(define_expand "subsi3"
3205 [(set (match_operand:SI 0 "nonimmediate_operand" "")
3206 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3207 (match_operand:SI 2 "general_operand" "")))]
886c62d1 3208 ""
2ae0f82c
SC
3209 "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);")
3210
3211(define_insn ""
3212 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3213 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
3214 (match_operand:SI 2 "general_operand" "ri,rm")))]
3215 "ix86_binary_operator_ok (MINUS, SImode, operands)"
886c62d1
JVA
3216 "* return AS2 (sub%L0,%2,%0);")
3217
2ae0f82c
SC
3218(define_expand "subhi3"
3219 [(set (match_operand:HI 0 "general_operand" "")
3220 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
3221 (match_operand:HI 2 "general_operand" "")))]
886c62d1 3222 ""
2ae0f82c
SC
3223 "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);")
3224
3225(define_insn ""
3226 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
87fd1847 3227 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
2ae0f82c
SC
3228 (match_operand:HI 2 "general_operand" "ri,rm")))]
3229 "ix86_binary_operator_ok (MINUS, HImode, operands)"
5bc7cd8e
SC
3230 "*
3231{
3232 if (REG_P (operands[0])
3233 && i386_aligned_p (operands[2])
3234 && i386_cc_probably_useless_p (insn))
3235 {
3236 CC_STATUS_INIT;
3237 operands[2] = i386_sext16_if_const (operands[2]);
3238 return AS2 (sub%L0,%k2,%k0);
3239 }
3240 return AS2 (sub%W0,%2,%0);
3241}")
886c62d1 3242
2ae0f82c
SC
3243(define_expand "subqi3"
3244 [(set (match_operand:QI 0 "general_operand" "")
3245 (minus:QI (match_operand:QI 1 "general_operand" "")
3246 (match_operand:QI 2 "general_operand" "")))]
886c62d1 3247 ""
2ae0f82c
SC
3248 "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);")
3249
3250(define_insn ""
3251 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3252 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
3253 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3254 "ix86_binary_operator_ok (MINUS, QImode, operands)"
3255 "* return AS2 (sub%B0,%2,%0);")
3256
886c62d1
JVA
3257;; The patterns that match these are at the end of this file.
3258
4fb21e90
JVA
3259(define_expand "subxf3"
3260 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
3261 (minus:XF (match_operand:XF 1 "register_operand" "")
3262 (match_operand:XF 2 "register_operand" "")))]
4fb21e90
JVA
3263 "TARGET_80387"
3264 "")
3265
886c62d1
JVA
3266(define_expand "subdf3"
3267 [(set (match_operand:DF 0 "register_operand" "")
3268 (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
3269 (match_operand:DF 2 "nonimmediate_operand" "")))]
3270 "TARGET_80387"
3271 "")
3272
3273(define_expand "subsf3"
3274 [(set (match_operand:SF 0 "register_operand" "")
3275 (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
3276 (match_operand:SF 2 "nonimmediate_operand" "")))]
3277 "TARGET_80387"
3278 "")
3279\f
3280;;- multiply instructions
3281
3282;(define_insn "mulqi3"
2ae0f82c
SC
3283; [(set (match_operand:QI 0 "register_operand" "=a")
3284; (mult:QI (match_operand:QI 1 "register_operand" "%0")
3285; (match_operand:QI 2 "nonimmediate_operand" "qm")))]
886c62d1
JVA
3286; ""
3287; "imul%B0 %2,%0")
3288
886c62d1 3289(define_insn "mulhi3"
2ae0f82c
SC
3290 [(set (match_operand:HI 0 "register_operand" "=r,r")
3291 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%0,rm")
886c62d1
JVA
3292 (match_operand:HI 2 "general_operand" "g,i")))]
3293 ""
3294 "*
3295{
3296 if (GET_CODE (operands[1]) == REG
3297 && REGNO (operands[1]) == REGNO (operands[0])
3298 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3299 /* Assembler has weird restrictions. */
3300 return AS2 (imul%W0,%2,%0);
3301 return AS3 (imul%W0,%2,%1,%0);
36cf4bcf
SC
3302}"
3303 [(set_attr "type" "imul")])
886c62d1 3304
886c62d1 3305(define_insn "mulsi3"
2ae0f82c
SC
3306 [(set (match_operand:SI 0 "register_operand" "=r,r")
3307 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
886c62d1
JVA
3308 (match_operand:SI 2 "general_operand" "g,i")))]
3309 ""
3310 "*
3311{
3312 if (GET_CODE (operands[1]) == REG
3313 && REGNO (operands[1]) == REGNO (operands[0])
3314 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
3315 /* Assembler has weird restrictions. */
3316 return AS2 (imul%L0,%2,%0);
3317 return AS3 (imul%L0,%2,%1,%0);
36cf4bcf
SC
3318}"
3319 [(set_attr "type" "imul")])
886c62d1 3320
4b71cd6e 3321(define_insn "umulqihi3"
2ae0f82c
SC
3322 [(set (match_operand:HI 0 "register_operand" "=a")
3323 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
4b71cd6e 3324 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
886c62d1 3325 ""
36cf4bcf
SC
3326 "mul%B0 %2"
3327 [(set_attr "type" "imul")])
886c62d1 3328
4b71cd6e 3329(define_insn "mulqihi3"
2ae0f82c
SC
3330 [(set (match_operand:HI 0 "register_operand" "=a")
3331 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
4b71cd6e
MM
3332 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
3333 ""
36cf4bcf
SC
3334 "imul%B0 %2"
3335 [(set_attr "type" "imul")])
4b71cd6e
MM
3336
3337(define_insn "umulsidi3"
3338 [(set (match_operand:DI 0 "register_operand" "=A")
3339 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3340 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
2f2a49e8 3341 "TARGET_WIDE_MULTIPLY"
36cf4bcf
SC
3342 "mul%L0 %2"
3343 [(set_attr "type" "imul")])
4b71cd6e
MM
3344
3345(define_insn "mulsidi3"
3346 [(set (match_operand:DI 0 "register_operand" "=A")
3347 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
3348 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
2f2a49e8 3349 "TARGET_WIDE_MULTIPLY"
36cf4bcf
SC
3350 "imul%L0 %2"
3351 [(set_attr "type" "imul")])
2f2a49e8
MM
3352
3353(define_insn "umulsi3_highpart"
3354 [(set (match_operand:SI 0 "register_operand" "=d")
3355 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
3356 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
3357 (const_int 32))))
3358 (clobber (match_scratch:SI 3 "=a"))]
3359 "TARGET_WIDE_MULTIPLY"
36cf4bcf
SC
3360 "mul%L0 %2"
3361 [(set_attr "type" "imul")])
2f2a49e8
MM
3362
3363(define_insn "smulsi3_highpart"
3364 [(set (match_operand:SI 0 "register_operand" "=d")
3365 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
3366 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
3367 (const_int 32))))
3368 (clobber (match_scratch:SI 3 "=a"))]
3369 "TARGET_WIDE_MULTIPLY"
36cf4bcf
SC
3370 "imul%L0 %2"
3371 [(set_attr "type" "imul")])
4b71cd6e 3372
886c62d1
JVA
3373;; The patterns that match these are at the end of this file.
3374
4fb21e90
JVA
3375(define_expand "mulxf3"
3376 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
3377 (mult:XF (match_operand:XF 1 "register_operand" "")
3378 (match_operand:XF 2 "register_operand" "")))]
4fb21e90
JVA
3379 "TARGET_80387"
3380 "")
3381
886c62d1
JVA
3382(define_expand "muldf3"
3383 [(set (match_operand:DF 0 "register_operand" "")
2ae0f82c 3384 (mult:DF (match_operand:DF 1 "register_operand" "")
886c62d1
JVA
3385 (match_operand:DF 2 "nonimmediate_operand" "")))]
3386 "TARGET_80387"
3387 "")
3388
3389(define_expand "mulsf3"
3390 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 3391 (mult:SF (match_operand:SF 1 "register_operand" "")
886c62d1
JVA
3392 (match_operand:SF 2 "nonimmediate_operand" "")))]
3393 "TARGET_80387"
3394 "")
3395\f
3396;;- divide instructions
3397
3398(define_insn "divqi3"
2ae0f82c
SC
3399 [(set (match_operand:QI 0 "register_operand" "=a")
3400 (div:QI (match_operand:HI 1 "register_operand" "0")
3401 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
886c62d1
JVA
3402 ""
3403 "idiv%B0 %2")
3404
3405(define_insn "udivqi3"
2ae0f82c
SC
3406 [(set (match_operand:QI 0 "register_operand" "=a")
3407 (udiv:QI (match_operand:HI 1 "register_operand" "0")
3408 (match_operand:QI 2 "nonimmediate_operand" "qm")))]
886c62d1 3409 ""
36cf4bcf
SC
3410 "div%B0 %2"
3411 [(set_attr "type" "idiv")])
886c62d1
JVA
3412
3413;; The patterns that match these are at the end of this file.
3414
4fb21e90
JVA
3415(define_expand "divxf3"
3416 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
3417 (div:XF (match_operand:XF 1 "register_operand" "")
3418 (match_operand:XF 2 "register_operand" "")))]
886c62d1
JVA
3419 "TARGET_80387"
3420 "")
3421
a78cb986
SC
3422(define_expand "divdf3"
3423 [(set (match_operand:DF 0 "register_operand" "")
3424 (div:DF (match_operand:DF 1 "register_operand" "")
3425 (match_operand:DF 2 "nonimmediate_operand" "")))]
3426 "TARGET_80387"
3427 "")
3428
886c62d1
JVA
3429(define_expand "divsf3"
3430 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 3431 (div:SF (match_operand:SF 1 "register_operand" "")
886c62d1
JVA
3432 (match_operand:SF 2 "nonimmediate_operand" "")))]
3433 "TARGET_80387"
3434 "")
3435\f
3436;; Remainder instructions.
3437
3438(define_insn "divmodsi4"
2bb7a0f5
RS
3439 [(set (match_operand:SI 0 "register_operand" "=a")
3440 (div:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 3441 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 3442 (set (match_operand:SI 3 "register_operand" "=&d")
886c62d1
JVA
3443 (mod:SI (match_dup 1) (match_dup 2)))]
3444 ""
3445 "*
3446{
3447#ifdef INTEL_SYNTAX
3448 output_asm_insn (\"cdq\", operands);
3449#else
3450 output_asm_insn (\"cltd\", operands);
3451#endif
3452 return AS1 (idiv%L0,%2);
36cf4bcf
SC
3453}"
3454 [(set_attr "type" "idiv")])
886c62d1
JVA
3455
3456(define_insn "divmodhi4"
2bb7a0f5
RS
3457 [(set (match_operand:HI 0 "register_operand" "=a")
3458 (div:HI (match_operand:HI 1 "register_operand" "0")
2ae0f82c 3459 (match_operand:HI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 3460 (set (match_operand:HI 3 "register_operand" "=&d")
886c62d1
JVA
3461 (mod:HI (match_dup 1) (match_dup 2)))]
3462 ""
36cf4bcf
SC
3463 "cwtd\;idiv%W0 %2"
3464 [(set_attr "type" "idiv")])
886c62d1
JVA
3465
3466;; ??? Can we make gcc zero extend operand[0]?
3467(define_insn "udivmodsi4"
2bb7a0f5
RS
3468 [(set (match_operand:SI 0 "register_operand" "=a")
3469 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 3470 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 3471 (set (match_operand:SI 3 "register_operand" "=&d")
886c62d1
JVA
3472 (umod:SI (match_dup 1) (match_dup 2)))]
3473 ""
3474 "*
3475{
3476 output_asm_insn (AS2 (xor%L3,%3,%3), operands);
3477 return AS1 (div%L0,%2);
36cf4bcf
SC
3478}"
3479 [(set_attr "type" "idiv")])
886c62d1
JVA
3480
3481;; ??? Can we make gcc zero extend operand[0]?
3482(define_insn "udivmodhi4"
2bb7a0f5
RS
3483 [(set (match_operand:HI 0 "register_operand" "=a")
3484 (udiv:HI (match_operand:HI 1 "register_operand" "0")
2ae0f82c 3485 (match_operand:HI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 3486 (set (match_operand:HI 3 "register_operand" "=&d")
886c62d1
JVA
3487 (umod:HI (match_dup 1) (match_dup 2)))]
3488 ""
3489 "*
3490{
3491 output_asm_insn (AS2 (xor%W0,%3,%3), operands);
3492 return AS1 (div%W0,%2);
36cf4bcf
SC
3493}"
3494 [(set_attr "type" "idiv")])
886c62d1
JVA
3495
3496/*
3497;;this should be a valid double division which we may want to add
3498
3499(define_insn ""
2bb7a0f5
RS
3500 [(set (match_operand:SI 0 "register_operand" "=a")
3501 (udiv:DI (match_operand:DI 1 "register_operand" "a")
2ae0f82c 3502 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 3503 (set (match_operand:SI 3 "register_operand" "=d")
886c62d1
JVA
3504 (umod:SI (match_dup 1) (match_dup 2)))]
3505 ""
36cf4bcf
SC
3506 "div%L0 %2,%0"
3507 [(set_attr "type" "idiv")])
886c62d1
JVA
3508*/
3509\f
3510;;- and instructions
3511
3512;; On i386,
3513;; movzbl %bl,%ebx
3514;; is faster than
3515;; andl $255,%ebx
3516;;
3517;; but if the reg is %eax, then the "andl" is faster.
3518;;
3519;; On i486, the "andl" is always faster than the "movzbl".
3520;;
3521;; On both i386 and i486, a three operand AND is as fast with movzbl or
3522;; movzwl as with andl, if operands[0] != operands[1].
3523
3524;; The `r' in `rm' for operand 3 looks redundant, but it causes
3525;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
3526
886c62d1 3527(define_insn "andsi3"
2ae0f82c
SC
3528 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3529 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
3530 (match_operand:SI 2 "general_operand" "ri,rm")))]
886c62d1
JVA
3531 ""
3532 "*
3533{
5bc7cd8e 3534 HOST_WIDE_INT intval;
2ae0f82c
SC
3535 if (!rtx_equal_p (operands[0], operands[1])
3536 && rtx_equal_p (operands[0], operands[2]))
3537 {
3538 rtx tmp;
3539 tmp = operands[1];
3540 operands[1] = operands[2];
3541 operands[2] = tmp;
3542 }
5bc7cd8e 3543 switch (GET_CODE (operands[2]))
886c62d1 3544 {
5bc7cd8e
SC
3545 case CONST_INT:
3546 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
3547 break;
3548 intval = INTVAL (operands[2]);
3549 /* zero-extend 16->32? */
3550 if (intval == 0xffff && REG_P (operands[0])
886c62d1
JVA
3551 && (! REG_P (operands[1])
3552 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
268bfa44 3553 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
886c62d1
JVA
3554 {
3555 /* ??? tege: Should forget CC_STATUS only if we clobber a
3556 remembered operand. Fix that later. */
3557 CC_STATUS_INIT;
3558#ifdef INTEL_SYNTAX
3559 return AS2 (movzx,%w1,%0);
3560#else
3561 return AS2 (movz%W0%L0,%w1,%0);
3562#endif
3563 }
3564
5bc7cd8e
SC
3565 /* zero extend 8->32? */
3566 if (intval == 0xff && REG_P (operands[0])
886c62d1
JVA
3567 && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
3568 && (! REG_P (operands[1])
3569 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
268bfa44 3570 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1])))
886c62d1
JVA
3571 {
3572 /* ??? tege: Should forget CC_STATUS only if we clobber a
3573 remembered operand. Fix that later. */
3574 CC_STATUS_INIT;
3575#ifdef INTEL_SYNTAX
3576 return AS2 (movzx,%b1,%0);
3577#else
3578 return AS2 (movz%B0%L0,%b1,%0);
3579#endif
3580 }
3581
5bc7cd8e
SC
3582 /* Check partial bytes.. non-QI-regs are not available */
3583 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
3584 break;
886c62d1 3585
5bc7cd8e
SC
3586 /* only low byte has zero bits? */
3587 if (~(intval | 0xff) == 0)
3588 {
3589 intval &= 0xff;
3590 if (REG_P (operands[0]))
886c62d1 3591 {
5bc7cd8e
SC
3592 if (intval == 0)
3593 {
3594 CC_STATUS_INIT;
3595 return AS2 (xor%B0,%b0,%b0);
3596 }
3597
3598 /* we're better off with the 32-bit version if reg != EAX */
3599 /* the value is sign-extended in 8 bits */
3600 if (REGNO (operands[0]) != 0 && (intval & 0x80))
3601 break;
886c62d1
JVA
3602 }
3603
5bc7cd8e
SC
3604 CC_STATUS_INIT;
3605
3606 operands[2] = GEN_INT (intval);
3607
3608 if (intval == 0)
3609 return AS2 (mov%B0,%2,%b0);
3610
886c62d1
JVA
3611 return AS2 (and%B0,%2,%b0);
3612 }
3613
5bc7cd8e
SC
3614 /* only second byte has zero? */
3615 if (~(intval | 0xff00) == 0)
886c62d1
JVA
3616 {
3617 CC_STATUS_INIT;
3618
5bc7cd8e
SC
3619 intval = (intval >> 8) & 0xff;
3620 operands[2] = GEN_INT (intval);
3621 if (intval == 0)
886c62d1 3622 {
5bc7cd8e
SC
3623 if (REG_P (operands[0]))
3624 return AS2 (xor%B0,%h0,%h0);
3625 operands[0] = adj_offsettable_operand (operands[0], 1);
3626 return AS2 (mov%B0,%2,%b0);
886c62d1
JVA
3627 }
3628
5bc7cd8e
SC
3629 if (REG_P (operands[0]))
3630 return AS2 (and%B0,%2,%h0);
3631
3632 operands[0] = adj_offsettable_operand (operands[0], 1);
3633 return AS2 (and%B0,%2,%b0);
886c62d1
JVA
3634 }
3635
5bc7cd8e
SC
3636 if (REG_P (operands[0]))
3637 break;
3638
3639 /* third byte has zero bits? */
3640 if (~(intval | 0xff0000) == 0)
3641 {
3642 intval = (intval >> 16) & 0xff;
3643 operands[0] = adj_offsettable_operand (operands[0], 2);
3644byte_and_operation:
3645 CC_STATUS_INIT;
3646 operands[2] = GEN_INT (intval);
3647 if (intval == 0)
3648 return AS2 (mov%B0,%2,%b0);
3649 return AS2 (and%B0,%2,%b0);
3650 }
3651
3652 /* fourth byte has zero bits? */
3653 if (~(intval | 0xff000000) == 0)
3654 {
3655 intval = (intval >> 24) & 0xff;
3656 operands[0] = adj_offsettable_operand (operands[0], 3);
3657 goto byte_and_operation;
3658 }
3659
3660 /* Low word is zero? */
3661 if (intval == 0xffff0000)
886c62d1 3662 {
5bc7cd8e
SC
3663word_zero_and_operation:
3664 CC_STATUS_INIT;
886c62d1
JVA
3665 operands[2] = const0_rtx;
3666 return AS2 (mov%W0,%2,%w0);
3667 }
5bc7cd8e
SC
3668
3669 /* High word is zero? */
3670 if (intval == 0x0000ffff)
3671 {
3672 operands[0] = adj_offsettable_operand (operands[0], 2);
3673 goto word_zero_and_operation;
3674 }
4fce8e83
MH
3675
3676 default:
3677 break;
886c62d1
JVA
3678 }
3679
3680 return AS2 (and%L0,%2,%0);
3681}")
3682
3683(define_insn "andhi3"
2ae0f82c
SC
3684 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3685 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
3686 (match_operand:HI 2 "general_operand" "ri,rm")))]
3687 ""
3688 "*
3689{
3690 if (GET_CODE (operands[2]) == CONST_INT
3691 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
3692 {
3693 /* Can we ignore the upper byte? */
a199fdd6 3694 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
886c62d1
JVA
3695 && (INTVAL (operands[2]) & 0xff00) == 0xff00)
3696 {
3697 CC_STATUS_INIT;
3698
3699 if ((INTVAL (operands[2]) & 0xff) == 0)
3700 {
3701 operands[2] = const0_rtx;
3702 return AS2 (mov%B0,%2,%b0);
3703 }
3704
a199fdd6 3705 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
886c62d1
JVA
3706 return AS2 (and%B0,%2,%b0);
3707 }
3708
3709 /* Can we ignore the lower byte? */
3710 /* ??? what about offsettable memory references? */
3711 if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
3712 {
3713 CC_STATUS_INIT;
3714
3715 if ((INTVAL (operands[2]) & 0xff00) == 0)
3716 {
3717 operands[2] = const0_rtx;
3718 return AS2 (mov%B0,%2,%h0);
3719 }
3720
a199fdd6 3721 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
886c62d1
JVA
3722 return AS2 (and%B0,%2,%h0);
3723 }
5bc7cd8e
SC
3724
3725 /* use 32-bit ops on registers when there are no sign issues.. */
3726 if (REG_P (operands[0]))
3727 {
3728 if (!(INTVAL (operands[2]) & ~0x7fff))
3729 return AS2 (and%L0,%2,%k0);
3730 }
3731 }
3732
3733 if (REG_P (operands[0])
3734 && i386_aligned_p (operands[2]))
3735 {
3736 CC_STATUS_INIT;
3737 /* If op[2] is constant, we should zero-extend it and */
3738 /* make a note that op[0] has been zero-extended, so */
3739 /* that we could use 32-bit ops on it forthwith, but */
3740 /* there is no such reg-note available. Instead we do */
3741 /* a sign extension as that can result in shorter asm */
3742 operands[2] = i386_sext16_if_const (operands[2]);
3743 return AS2 (and%L0,%k2,%k0);
3744 }
3745
3746 /* Use a 32-bit word with the upper bits set, invalidate CC */
3747 if (GET_CODE (operands[2]) == CONST_INT
3748 && i386_aligned_p (operands[0]))
3749 {
3750 HOST_WIDE_INT val = INTVAL (operands[2]);
3751 CC_STATUS_INIT;
3752 val |= ~0xffff;
3753 if (val != INTVAL (operands[2]))
3754 operands[2] = GEN_INT (val);
3755 return AS2 (and%L0,%k2,%k0);
886c62d1
JVA
3756 }
3757
3758 return AS2 (and%W0,%2,%0);
3759}")
3760
3761(define_insn "andqi3"
2ae0f82c
SC
3762 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3763 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
3764 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3765 ""
3766 "* return AS2 (and%B0,%2,%0);")
3767
3768/* I am nervous about these two.. add them later..
3769;I presume this means that we have something in say op0= eax which is small
3770;and we want to and it with memory so we can do this by just an
3771;andb m,%al and have success.
3772(define_insn ""
3773 [(set (match_operand:SI 0 "general_operand" "=r")
3774 (and:SI (zero_extend:SI
3775 (match_operand:HI 1 "nonimmediate_operand" "rm"))
3776 (match_operand:SI 2 "general_operand" "0")))]
3777 "GET_CODE (operands[2]) == CONST_INT
3778 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
3779 "and%W0 %1,%0")
3780
3781(define_insn ""
2ae0f82c 3782 [(set (match_operand:SI 0 "register_operand" "=q")
886c62d1
JVA
3783 (and:SI
3784 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
2ae0f82c 3785 (match_operand:SI 2 "register_operand" "0")))]
886c62d1
JVA
3786 "GET_CODE (operands[2]) == CONST_INT
3787 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
3788 "and%L0 %1,%0")
3789
3790*/
3791\f
3792;;- Bit set (inclusive or) instructions
3793
5bc7cd8e
SC
3794;; This optimizes known byte-wide operations to memory, and in some cases
3795;; to QI registers.. Note that we don't want to use the QI registers too
3796;; aggressively, because often the 32-bit register instruction is the same
3797;; size, and likely to be faster on PentiumPro.
886c62d1 3798(define_insn "iorsi3"
2ae0f82c
SC
3799 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3800 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
3801 (match_operand:SI 2 "general_operand" "ri,rm")))]
3802 ""
3803 "*
3804{
5bc7cd8e
SC
3805 HOST_WIDE_INT intval;
3806 switch (GET_CODE (operands[2]))
886c62d1 3807 {
5bc7cd8e 3808 case CONST_INT:
886c62d1 3809
5bc7cd8e
SC
3810 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
3811 break;
3812
3813 /* don't try to optimize volatile accesses */
3814 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
3815 break;
3816
3817 intval = INTVAL (operands[2]);
3818 if ((intval & ~0xff) == 0)
3819 {
3820 if (REG_P (operands[0]))
3821 {
3822 /* Do low byte access only for %eax or when high bit is set */
3823 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
3824 break;
3825 }
886c62d1 3826
5bc7cd8e
SC
3827byte_or_operation:
3828 CC_STATUS_INIT;
3829
3830 if (intval != INTVAL (operands[2]))
3831 operands[2] = GEN_INT (intval);
3832
3833 if (intval == 0xff)
3834 return AS2 (mov%B0,%2,%b0);
3835
3836 return AS2 (or%B0,%2,%b0);
886c62d1
JVA
3837 }
3838
5bc7cd8e
SC
3839 /* second byte? */
3840 if ((intval & ~0xff00) == 0)
886c62d1 3841 {
5bc7cd8e 3842 intval >>= 8;
886c62d1 3843
5bc7cd8e
SC
3844 if (REG_P (operands[0]))
3845 {
3846 CC_STATUS_INIT;
3847 operands[2] = GEN_INT (intval);
3848 if (intval == 0xff)
3849 return AS2 (mov%B0,%2,%h0);
886c62d1 3850
5bc7cd8e
SC
3851 return AS2 (or%B0,%2,%h0);
3852 }
3853
3854 operands[0] = adj_offsettable_operand (operands[0], 1);
3855 goto byte_or_operation;
3856 }
3857
3858 if (REG_P (operands[0]))
3859 break;
3860
3861 /* third byte? */
3862 if ((intval & ~0xff0000) == 0)
3863 {
3864 intval >>= 16;
3865 operands[0] = adj_offsettable_operand (operands[0], 2);
3866 goto byte_or_operation;
3867 }
3868
3869 /* fourth byte? */
3870 if ((intval & ~0xff000000) == 0)
3871 {
3872 intval = (intval >> 24) & 0xff;
3873 operands[0] = adj_offsettable_operand (operands[0], 3);
3874 goto byte_or_operation;
886c62d1 3875 }
4fce8e83
MH
3876
3877 default:
3878 break;
886c62d1
JVA
3879 }
3880
3881 return AS2 (or%L0,%2,%0);
3882}")
3883
3884(define_insn "iorhi3"
2ae0f82c
SC
3885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
3886 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
3887 (match_operand:HI 2 "general_operand" "ri,rm")))]
3888 ""
3889 "*
3890{
5bc7cd8e
SC
3891 HOST_WIDE_INT intval;
3892 switch (GET_CODE (operands[2]))
886c62d1 3893 {
5bc7cd8e 3894 case CONST_INT:
886c62d1 3895
5bc7cd8e
SC
3896 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
3897 break;
3898
3899 /* don't try to optimize volatile accesses */
3900 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
3901 break;
3902
3903 intval = 0xffff & INTVAL (operands[2]);
3904
3905 if ((intval & 0xff00) == 0)
3906 {
3907 if (REG_P (operands[0]))
3908 {
3909 /* Do low byte access only for %eax or when high bit is set */
3910 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
3911 break;
3912 }
3913
3914byte_or_operation:
3915 CC_STATUS_INIT;
3916
3917 if (intval == 0xff)
3918 return AS2 (mov%B0,%2,%b0);
886c62d1 3919
5bc7cd8e 3920 return AS2 (or%B0,%2,%b0);
886c62d1
JVA
3921 }
3922
5bc7cd8e
SC
3923 /* high byte? */
3924 if ((intval & 0xff) == 0)
886c62d1 3925 {
5bc7cd8e
SC
3926 intval >>= 8;
3927 operands[2] = GEN_INT (intval);
886c62d1 3928
5bc7cd8e
SC
3929 if (REG_P (operands[0]))
3930 {
3931 CC_STATUS_INIT;
3932 if (intval == 0xff)
3933 return AS2 (mov%B0,%2,%h0);
3934
3935 return AS2 (or%B0,%2,%h0);
3936 }
3937
3938 operands[0] = adj_offsettable_operand (operands[0], 1);
886c62d1 3939
5bc7cd8e 3940 goto byte_or_operation;
886c62d1 3941 }
4fce8e83
MH
3942
3943 default:
3944 break;
886c62d1
JVA
3945 }
3946
5bc7cd8e
SC
3947 if (REG_P (operands[0])
3948 && i386_aligned_p (operands[2]))
3949 {
3950 CC_STATUS_INIT;
3951 operands[2] = i386_sext16_if_const (operands[2]);
3952 return AS2 (or%L0,%k2,%k0);
3953 }
3954
3955 if (GET_CODE (operands[2]) == CONST_INT
3956 && i386_aligned_p (operands[0]))
3957 {
3958 CC_STATUS_INIT;
3959 intval = 0xffff & INTVAL (operands[2]);
3960 if (intval != INTVAL (operands[2]))
3961 operands[2] = GEN_INT (intval);
3962 return AS2 (or%L0,%2,%k0);
3963 }
3964
886c62d1
JVA
3965 return AS2 (or%W0,%2,%0);
3966}")
3967
3968(define_insn "iorqi3"
2ae0f82c
SC
3969 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
3970 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
3971 (match_operand:QI 2 "general_operand" "qn,qmn")))]
3972 ""
3973 "* return AS2 (or%B0,%2,%0);")
3974\f
3975;;- xor instructions
3976
886c62d1 3977(define_insn "xorsi3"
2ae0f82c
SC
3978 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
3979 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
3980 (match_operand:SI 2 "general_operand" "ri,rm")))]
3981 ""
3982 "*
3983{
5bc7cd8e
SC
3984 HOST_WIDE_INT intval;
3985 switch (GET_CODE (operands[2]))
886c62d1 3986 {
5bc7cd8e 3987 case CONST_INT:
886c62d1 3988
5bc7cd8e
SC
3989 if (REG_P (operands[0]) && ! QI_REG_P (operands[0]))
3990 break;
886c62d1 3991
5bc7cd8e
SC
3992 /* don't try to optimize volatile accesses */
3993 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
3994 break;
3995
3996 intval = INTVAL (operands[2]);
3997 if ((intval & ~0xff) == 0)
3998 {
3999 if (REG_P (operands[0]))
4000 {
4001 /* Do low byte access only for %eax or when high bit is set */
4002 if (REGNO (operands[0]) != 0 && !(intval & 0x80))
4003 break;
4004 }
4005
4006byte_xor_operation:
4007 CC_STATUS_INIT;
4008
4009 if (intval == 0xff)
4010 return AS1 (not%B0,%b0);
4011
4012 if (intval != INTVAL (operands[2]))
4013 operands[2] = GEN_INT (intval);
4014 return AS2 (xor%B0,%2,%b0);
886c62d1
JVA
4015 }
4016
5bc7cd8e
SC
4017 /* second byte? */
4018 if ((intval & ~0xff00) == 0)
886c62d1 4019 {
5bc7cd8e 4020 intval >>= 8;
886c62d1 4021
5bc7cd8e
SC
4022 if (REG_P (operands[0]))
4023 {
4024 CC_STATUS_INIT;
4025 if (intval == 0xff)
4026 return AS1 (not%B0,%h0);
886c62d1 4027
5bc7cd8e
SC
4028 operands[2] = GEN_INT (intval);
4029 return AS2 (xor%B0,%2,%h0);
4030 }
4031
4032 operands[0] = adj_offsettable_operand (operands[0], 1);
4033
4034 goto byte_xor_operation;
4035 }
4036
4037 if (REG_P (operands[0]))
4038 break;
4039
4040 /* third byte? */
4041 if ((intval & ~0xff0000) == 0)
4042 {
4043 intval >>= 16;
4044 operands[0] = adj_offsettable_operand (operands[0], 2);
4045 goto byte_xor_operation;
4046 }
4047
4048 /* fourth byte? */
4049 if ((intval & ~0xff000000) == 0)
4050 {
4051 intval = (intval >> 24) & 0xff;
4052 operands[0] = adj_offsettable_operand (operands[0], 3);
4053 goto byte_xor_operation;
886c62d1 4054 }
4fce8e83
MH
4055
4056 default:
4057 break;
886c62d1
JVA
4058 }
4059
4060 return AS2 (xor%L0,%2,%0);
4061}")
4062
4063(define_insn "xorhi3"
2ae0f82c
SC
4064 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4065 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
4066 (match_operand:HI 2 "general_operand" "ri,rm")))]
4067 ""
4068 "*
4069{
4070 if (GET_CODE (operands[2]) == CONST_INT
4071 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
4072 {
4073 /* Can we ignore the upper byte? */
a199fdd6 4074 if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
886c62d1
JVA
4075 && (INTVAL (operands[2]) & 0xff00) == 0)
4076 {
4077 CC_STATUS_INIT;
4078 if (INTVAL (operands[2]) & 0xffff0000)
a199fdd6 4079 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
886c62d1
JVA
4080
4081 if (INTVAL (operands[2]) == 0xff)
b4ac57ab 4082 return AS1 (not%B0,%b0);
886c62d1
JVA
4083
4084 return AS2 (xor%B0,%2,%b0);
4085 }
4086
4087 /* Can we ignore the lower byte? */
4088 /* ??? what about offsettable memory references? */
4089 if (QI_REG_P (operands[0])
4090 && (INTVAL (operands[2]) & 0xff) == 0)
4091 {
4092 CC_STATUS_INIT;
a199fdd6 4093 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
886c62d1
JVA
4094
4095 if (INTVAL (operands[2]) == 0xff)
4096 return AS1 (not%B0,%h0);
4097
4098 return AS2 (xor%B0,%2,%h0);
4099 }
4100 }
4101
5bc7cd8e
SC
4102 if (REG_P (operands[0])
4103 && i386_aligned_p (operands[2]))
4104 {
4105 CC_STATUS_INIT;
4106 operands[2] = i386_sext16_if_const (operands[2]);
4107 return AS2 (xor%L0,%k2,%k0);
4108 }
4109
4110 if (GET_CODE (operands[2]) == CONST_INT
4111 && i386_aligned_p (operands[0]))
4112 {
4113 HOST_WIDE_INT intval;
4114 CC_STATUS_INIT;
4115 intval = 0xffff & INTVAL (operands[2]);
4116 if (intval != INTVAL (operands[2]))
4117 operands[2] = GEN_INT (intval);
4118 return AS2 (xor%L0,%2,%k0);
4119 }
4120
886c62d1
JVA
4121 return AS2 (xor%W0,%2,%0);
4122}")
4123
4124(define_insn "xorqi3"
2ae0f82c
SC
4125 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4126 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
886c62d1
JVA
4127 (match_operand:QI 2 "general_operand" "qn,qm")))]
4128 ""
4129 "* return AS2 (xor%B0,%2,%0);")
4130\f
57dbca5e
BS
4131;; logical operations for DImode
4132
4133
4134(define_insn "anddi3"
4135 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4136 (and:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
4137 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
4138 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
4139 ""
4140 "#")
4141
4142(define_insn "iordi3"
4143 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4144 (ior:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
4145 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
4146 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
4147 ""
4148 "#")
4149
4150(define_insn "xordi3"
4151 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4152 (xor:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
4153 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")))
4154 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
4155 ""
4156 "#")
4157
4158(define_split
4159 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o")
4160 (match_operator:DI 4 "ix86_logical_operator"
4161 [(match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o")
4162 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")]))
4163 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))]
4164 "reload_completed"
4165 [(const_int 0)]
4166 "
4167{
4168 rtx low[3], high[3], xops[7], temp;
4169 rtx (*genfunc)() = (GET_CODE (operands[4]) == AND ? gen_andsi3
4170 : GET_CODE (operands[4]) == IOR ? gen_iorsi3
4171 : GET_CODE (operands[4]) == XOR ? gen_xorsi3
4172 : 0);
4173
4174 if (rtx_equal_p (operands[0], operands[2]))
4175 {
4176 temp = operands[1];
4177 operands[1] = operands[2];
4178 operands[2] = temp;
4179 }
4180
4181 split_di (operands, 3, low, high);
4182 if (!rtx_equal_p (operands[0], operands[1]))
4183 {
4184 xops[0] = high[0];
4185 xops[1] = low[0];
4186 xops[2] = high[1];
4187 xops[3] = low[1];
4188
4189 if (GET_CODE (operands[0]) != MEM)
4190 {
4191 emit_insn (gen_movsi (xops[1], xops[3]));
4192 emit_insn (gen_movsi (xops[0], xops[2]));
4193 }
4194 else
4195 {
4196 xops[4] = high[2];
4197 xops[5] = low[2];
4198 xops[6] = operands[3];
4199 emit_insn (gen_movsi (xops[6], xops[3]));
4200 emit_insn ((*genfunc) (xops[6], xops[6], xops[5]));
4201 emit_insn (gen_movsi (xops[1], xops[6]));
4202 emit_insn (gen_movsi (xops[6], xops[2]));
4203 emit_insn ((*genfunc) (xops[6], xops[6], xops[4]));
4204 emit_insn (gen_movsi (xops[0], xops[6]));
4205 DONE;
4206 }
4207 }
4208
4209 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
4210 {
4211 xops[0] = high[0];
4212 xops[1] = low[0];
4213 xops[2] = high[2];
4214 xops[3] = low[2];
4215 xops[4] = operands[3];
4216
4217 emit_insn (gen_movsi (xops[4], xops[3]));
4218 emit_insn ((*genfunc) (xops[1], xops[1], xops[4]));
4219 emit_insn (gen_movsi (xops[4], xops[2]));
4220 emit_insn ((*genfunc) (xops[0], xops[0], xops[4]));
4221 }
4222
4223 else
4224 {
4225 emit_insn ((*genfunc) (low[0], low[0], low[2]));
4226 emit_insn ((*genfunc) (high[0], high[0], high[2]));
4227 }
4228
4229 DONE;
4230}")
4231
886c62d1
JVA
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 }
f64cecad
JC
4586 operands[1] = gen_rtx_MULT (SImode, operands[1],
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 {
f64cecad 5047 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
886c62d1
JVA
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 {
f64cecad 5480 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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 {
f64cecad 5520 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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 {
f64cecad 5554 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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 {
f64cecad 5606 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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 {
f64cecad 5657 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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 {
f64cecad 5708 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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 {
f64cecad 5752 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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 {
f64cecad 5774 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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 {
f64cecad 5796 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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 {
f64cecad 5827 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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 {
f64cecad 5859 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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 {
f64cecad 5891 operands[1] = gen_rtx_REG (SImode, 0);
2ae0f82c
SC
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);
fc470718 6184 ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps);
2bb7a0f5
RS
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 6436 emit_call_insn (TARGET_80387
f64cecad
JC
6437 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
6438 operands[0], const0_rtx)
d8b679b9 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 {
5cb6195d 6534 sprintf (buffer, \"addl %s+[.-%%X2],%%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
5cb6195d 6548 output_asm_insn (AS1 (call,%X1), 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 ();
5cb6195d 6562 output_asm_insn (AS1 (call,%X1), operands);
4f9ca067
JW
6563 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
6564 CODE_LABEL_NUMBER (operands[1]));
6565 output_asm_insn (AS1 (pop%L0,%0), operands);
5cb6195d 6566 output_asm_insn (\"addl $_GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands);
4f9ca067
JW
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
f64cecad 6701 operands[0] = gen_rtx_MEM (BLKmode, addr0);
0ae40045
RK
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
f64cecad
JC
6767 operands[1] = gen_rtx_MEM (BLKmode, addr1);
6768 operands[2] = gen_rtx_MEM (BLKmode, addr2);
783cdf65 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
f64cecad 6832 xops[0] = gen_rtx_REG (QImode, 0);
f76e3b05
JVA
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
ad626759
MM
6841;; Note, you cannot optimize away the branch following the bsfl by assuming
6842;; that the destination is not modified if the input is 0, since not all
6843;; x86 implementations do this.
6844
ce193852
RH
6845(define_expand "ffssi2"
6846 [(set (match_operand:SI 0 "general_operand" "")
6847 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
886c62d1 6848 ""
ce193852 6849 "
886c62d1 6850{
ce193852 6851 rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode);
886c62d1 6852
ce193852
RH
6853 emit_insn (gen_ffssi_1 (temp, operands[1]));
6854 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0);
6855 emit_jump_insn (gen_bne (label));
6856 emit_move_insn (temp, constm1_rtx);
6857 emit_label (label);
6858 temp = expand_binop (SImode, add_optab, temp, const1_rtx,
6859 operands[0], 0, OPTAB_WIDEN);
6d7512e4 6860
ce193852
RH
6861 if (temp != operands[0])
6862 emit_move_insn (operands[0], temp);
6863 DONE;
886c62d1
JVA
6864}")
6865
ce193852
RH
6866(define_insn "ffssi_1"
6867 [(set (match_operand:SI 0 "register_operand" "=r")
6868 (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
886c62d1 6869 ""
ce193852 6870 "* return AS2 (bsf%L0,%1,%0);")
886c62d1 6871
ce193852
RH
6872(define_expand "ffshi2"
6873 [(set (match_operand:SI 0 "general_operand" "")
6874 (ffs:HI (match_operand:HI 1 "general_operand" "")))]
886c62d1 6875 ""
ce193852 6876 "
886c62d1 6877{
ce193852 6878 rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode);
886c62d1 6879
ce193852
RH
6880 emit_insn (gen_ffshi_1 (temp, operands[1]));
6881 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0);
6882 emit_jump_insn (gen_bne (label));
6883 emit_move_insn (temp, constm1_rtx);
6884 emit_label (label);
6885 temp = expand_binop (HImode, add_optab, temp, const1_rtx,
6886 operands[0], 0, OPTAB_WIDEN);
6d7512e4 6887
ce193852
RH
6888 if (temp != operands[0])
6889 emit_move_insn (operands[0], temp);
6890 DONE;
886c62d1 6891}")
ce193852
RH
6892
6893(define_insn "ffshi_1"
6894 [(set (match_operand:HI 0 "register_operand" "=r")
6895 (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
6896 ""
6897 "* return AS2 (bsf%W0,%1,%0);")
886c62d1
JVA
6898\f
6899;; These patterns match the binary 387 instructions for addM3, subM3,
6900;; mulM3 and divM3. There are three patterns for each of DFmode and
6901;; SFmode. The first is the normal insn, the second the same insn but
6902;; with one operand a conversion, and the third the same insn but with
6903;; the other operand a conversion. The conversion may be SFmode or
6904;; SImode if the target mode DFmode, but only SImode if the target mode
6905;; is SFmode.
6906
6907(define_insn ""
6908 [(set (match_operand:DF 0 "register_operand" "=f,f")
6909 (match_operator:DF 3 "binary_387_op"
08a7baac
JVA
6910 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
6911 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
886c62d1 6912 "TARGET_80387"
2ae0f82c
SC
6913 "* return output_387_binary_op (insn, operands);"
6914 [(set (attr "type")
6915 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6916 (const_string "fpmul")
2ae0f82c
SC
6917 (match_operand:DF 3 "is_div" "")
6918 (const_string "fpdiv")
6919 ]
6920 (const_string "fpop")
6921 )
6922 )])
886c62d1
JVA
6923
6924(define_insn ""
08a7baac 6925 [(set (match_operand:DF 0 "register_operand" "=f")
886c62d1 6926 (match_operator:DF 3 "binary_387_op"
2ae0f82c
SC
6927 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "rm"))
6928 (match_operand:DF 2 "register_operand" "0")]))]
886c62d1 6929 "TARGET_80387"
2ae0f82c
SC
6930 "* return output_387_binary_op (insn, operands);"
6931 [(set (attr "type")
6932 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6933 (const_string "fpmul")
2ae0f82c
SC
6934 (match_operand:DF 3 "is_div" "")
6935 (const_string "fpdiv")
6936 ]
6937 (const_string "fpop")
6938 )
6939 )])
4fb21e90
JVA
6940
6941(define_insn ""
6942 [(set (match_operand:XF 0 "register_operand" "=f,f")
6943 (match_operator:XF 3 "binary_387_op"
2ae0f82c
SC
6944 [(match_operand:XF 1 "register_operand" "0,f")
6945 (match_operand:XF 2 "register_operand" "f,0")]))]
4fb21e90 6946 "TARGET_80387"
2ae0f82c
SC
6947 "* return output_387_binary_op (insn, operands);"
6948 [(set (attr "type")
6949 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6950 (const_string "fpmul")
2ae0f82c
SC
6951 (match_operand:DF 3 "is_div" "")
6952 (const_string "fpdiv")
6953 ]
6954 (const_string "fpop")
6955 )
6956 )])
4fb21e90
JVA
6957
6958(define_insn ""
6959 [(set (match_operand:XF 0 "register_operand" "=f")
6960 (match_operator:XF 3 "binary_387_op"
2ae0f82c
SC
6961 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "rm"))
6962 (match_operand:XF 2 "register_operand" "0")]))]
4fb21e90 6963 "TARGET_80387"
2ae0f82c
SC
6964 "* return output_387_binary_op (insn, operands);"
6965 [(set (attr "type")
6966 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6967 (const_string "fpmul")
2ae0f82c
SC
6968 (match_operand:DF 3 "is_div" "")
6969 (const_string "fpdiv")
6970 ]
6971 (const_string "fpop")
6972 )
6973 )])
4fb21e90
JVA
6974
6975(define_insn ""
6976 [(set (match_operand:XF 0 "register_operand" "=f,f")
6977 (match_operator:XF 3 "binary_387_op"
2ae0f82c
SC
6978 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
6979 (match_operand:XF 2 "register_operand" "0,f")]))]
4fb21e90 6980 "TARGET_80387"
2ae0f82c
SC
6981 "* return output_387_binary_op (insn, operands);"
6982 [(set (attr "type")
6983 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 6984 (const_string "fpmul")
2ae0f82c
SC
6985 (match_operand:DF 3 "is_div" "")
6986 (const_string "fpdiv")
6987 ]
6988 (const_string "fpop")
6989 )
6990 )])
4fb21e90
JVA
6991
6992(define_insn ""
6993 [(set (match_operand:XF 0 "register_operand" "=f")
6994 (match_operator:XF 3 "binary_387_op"
2ae0f82c
SC
6995 [(match_operand:XF 1 "register_operand" "0")
6996 (float:XF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
4fb21e90 6997 "TARGET_80387"
2ae0f82c
SC
6998 "* return output_387_binary_op (insn, operands);"
6999 [(set (attr "type")
7000 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 7001 (const_string "fpmul")
2ae0f82c
SC
7002 (match_operand:DF 3 "is_div" "")
7003 (const_string "fpdiv")
7004 ]
7005 (const_string "fpop")
7006 )
7007 )])
4fb21e90
JVA
7008
7009(define_insn ""
7010 [(set (match_operand:XF 0 "register_operand" "=f,f")
7011 (match_operator:XF 3 "binary_387_op"
2ae0f82c 7012 [(match_operand:XF 1 "register_operand" "0,f")
4fb21e90 7013 (float_extend:XF
2ae0f82c 7014 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
4fb21e90 7015 "TARGET_80387"
2ae0f82c
SC
7016 "* return output_387_binary_op (insn, operands);"
7017 [(set (attr "type")
7018 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 7019 (const_string "fpmul")
2ae0f82c
SC
7020 (match_operand:DF 3 "is_div" "")
7021 (const_string "fpdiv")
7022 ]
7023 (const_string "fpop")
7024 )
7025 )])
886c62d1
JVA
7026
7027(define_insn ""
08a7baac 7028 [(set (match_operand:DF 0 "register_operand" "=f,f")
886c62d1 7029 (match_operator:DF 3 "binary_387_op"
2ae0f82c
SC
7030 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
7031 (match_operand:DF 2 "register_operand" "0,f")]))]
886c62d1 7032 "TARGET_80387"
2ae0f82c
SC
7033 "* return output_387_binary_op (insn, operands);"
7034 [(set (attr "type")
7035 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 7036 (const_string "fpmul")
2ae0f82c
SC
7037 (match_operand:DF 3 "is_div" "")
7038 (const_string "fpdiv")
7039 ]
7040 (const_string "fpop")
7041 )
7042 )])
886c62d1
JVA
7043
7044(define_insn ""
08a7baac 7045 [(set (match_operand:DF 0 "register_operand" "=f")
886c62d1 7046 (match_operator:DF 3 "binary_387_op"
2ae0f82c
SC
7047 [(match_operand:DF 1 "register_operand" "0")
7048 (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
886c62d1 7049 "TARGET_80387"
2ae0f82c
SC
7050 "* return output_387_binary_op (insn, operands);"
7051 [(set (attr "type")
7052 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 7053 (const_string "fpmul")
2ae0f82c
SC
7054 (match_operand:DF 3 "is_div" "")
7055 (const_string "fpdiv")
7056 ]
7057 (const_string "fpop")
7058 )
7059 )])
886c62d1
JVA
7060
7061(define_insn ""
08a7baac 7062 [(set (match_operand:DF 0 "register_operand" "=f,f")
886c62d1 7063 (match_operator:DF 3 "binary_387_op"
2ae0f82c 7064 [(match_operand:DF 1 "register_operand" "0,f")
886c62d1 7065 (float_extend:DF
2ae0f82c 7066 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
886c62d1 7067 "TARGET_80387"
2ae0f82c
SC
7068 "* return output_387_binary_op (insn, operands);"
7069 [(set (attr "type")
7070 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 7071 (const_string "fpmul")
2ae0f82c
SC
7072 (match_operand:DF 3 "is_div" "")
7073 (const_string "fpdiv")
7074 ]
7075 (const_string "fpop")
7076 )
7077 )])
886c62d1
JVA
7078
7079(define_insn ""
7080 [(set (match_operand:SF 0 "register_operand" "=f,f")
7081 (match_operator:SF 3 "binary_387_op"
08a7baac
JVA
7082 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
7083 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
886c62d1 7084 "TARGET_80387"
2ae0f82c
SC
7085 "* return output_387_binary_op (insn, operands);"
7086 [(set (attr "type")
7087 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 7088 (const_string "fpmul")
2ae0f82c
SC
7089 (match_operand:DF 3 "is_div" "")
7090 (const_string "fpdiv")
7091 ]
7092 (const_string "fpop")
7093 )
7094 )])
886c62d1
JVA
7095
7096(define_insn ""
08a7baac 7097 [(set (match_operand:SF 0 "register_operand" "=f")
886c62d1 7098 (match_operator:SF 3 "binary_387_op"
2ae0f82c
SC
7099 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "rm"))
7100 (match_operand:SF 2 "register_operand" "0")]))]
886c62d1 7101 "TARGET_80387"
2ae0f82c
SC
7102 "* return output_387_binary_op (insn, operands);"
7103 [(set (attr "type")
7104 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 7105 (const_string "fpmul")
2ae0f82c
SC
7106 (match_operand:DF 3 "is_div" "")
7107 (const_string "fpdiv")
7108 ]
7109 (const_string "fpop")
7110 )
7111 )])
886c62d1
JVA
7112
7113(define_insn ""
08a7baac 7114 [(set (match_operand:SF 0 "register_operand" "=f")
886c62d1 7115 (match_operator:SF 3 "binary_387_op"
2ae0f82c
SC
7116 [(match_operand:SF 1 "register_operand" "0")
7117 (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))]
886c62d1 7118 "TARGET_80387"
2ae0f82c
SC
7119 "* return output_387_binary_op (insn, operands);"
7120 [(set (attr "type")
7121 (cond [(match_operand:DF 3 "is_mul" "")
36cf4bcf 7122 (const_string "fpmul")
2ae0f82c
SC
7123 (match_operand:DF 3 "is_div" "")
7124 (const_string "fpdiv")
7125 ]
7126 (const_string "fpop")
7127 )
7128 )])
886c62d1 7129\f
19c3fc24
RS
7130(define_expand "strlensi"
7131 [(parallel [(set (match_dup 4)
7132 (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
628448b3 7133 (match_operand:QI 2 "immediate_operand" "")
19c3fc24
RS
7134 (match_operand:SI 3 "immediate_operand" "")] 0))
7135 (clobber (match_dup 1))])
7136 (set (match_dup 5)
7137 (not:SI (match_dup 4)))
7138 (set (match_operand:SI 0 "register_operand" "")
628448b3
SC
7139 (plus:SI (match_dup 5)
7140 (const_int -1)))]
19c3fc24
RS
7141 ""
7142 "
7143{
628448b3
SC
7144 if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1)
7145 {
7146 rtx address;
7147 rtx scratch;
7148
7149 /* well it seems that some optimizer does not combine a call like
7150 foo(strlen(bar), strlen(bar));
7151 when the move and the subtraction is done here. It does calculate
7152 the length just once when these instructions are done inside of
7153 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
7154 often used and I use one fewer register for the lifetime of
7155 output_strlen_unroll() this is better. */
7156 scratch = gen_reg_rtx (SImode);
7157 address = force_reg (SImode, XEXP (operands[1], 0));
7158
7159 /* move address to scratch-register
7160 this is done here because the i586 can do the following and
7161 in the same cycle with the following move. */
7162 if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4)
7163 emit_insn (gen_movsi (scratch, address));
7164
7165 emit_insn (gen_movsi (operands[0], address));
7166
7167 if(TARGET_USE_Q_REG)
7168 emit_insn (gen_strlensi_unroll5 (operands[0],
7169 operands[3],
7170 scratch,
7171 operands[0]));
7172 else
7173 emit_insn (gen_strlensi_unroll4 (operands[0],
7174 operands[3],
7175 scratch,
7176 operands[0]));
7177
7178 /* gen_strlensi_unroll[45] returns the address of the zero
7179 at the end of the string, like memchr(), so compute the
7180 length by subtracting the startaddress. */
7181 emit_insn (gen_subsi3 (operands[0], operands[0], address));
7182 DONE;
7183 }
7184
19c3fc24
RS
7185 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
7186 operands[4] = gen_reg_rtx (SImode);
7187 operands[5] = gen_reg_rtx (SImode);
7188}")
7189
56c0e8fa
JVA
7190;; It might seem that operands 0 & 1 could use predicate register_operand.
7191;; But strength reduction might offset the MEM expression. So we let
08a7baac 7192;; reload put the address into %edi.
56c0e8fa 7193
19c3fc24
RS
7194(define_insn ""
7195 [(set (match_operand:SI 0 "register_operand" "=&c")
56c0e8fa 7196 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
628448b3 7197 (match_operand:QI 2 "immediate_operand" "a")
19c3fc24
RS
7198 (match_operand:SI 3 "immediate_operand" "i")] 0))
7199 (clobber (match_dup 1))]
7200 ""
7201 "*
7202{
7203 rtx xops[2];
7204
7205 xops[0] = operands[0];
7206 xops[1] = constm1_rtx;
e8375399 7207 output_asm_insn (\"cld\", operands);
19c3fc24
RS
7208 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
7209 return \"repnz\;scas%B2\";
7210}")
628448b3 7211
926b3fae
SC
7212/* Conditional move define_insns. */
7213
7214(define_expand "movsicc"
726e2d54 7215 [(set (match_operand:SI 0 "register_operand" "")
926b3fae 7216 (if_then_else:SI (match_operand 1 "comparison_operator" "")
726e2d54
JW
7217 (match_operand:SI 2 "nonimmediate_operand" "")
7218 (match_operand:SI 3 "nonimmediate_operand" "")))]
7219 "TARGET_CMOVE"
926b3fae
SC
7220 "
7221{
726e2d54
JW
7222 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7223 FAIL;
926b3fae 7224
726e2d54
JW
7225 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7226 GET_MODE (i386_compare_op0),
7227 i386_compare_op0, i386_compare_op1);
926b3fae
SC
7228}")
7229
726e2d54
JW
7230(define_insn ""
7231 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
7232 (if_then_else:SI (match_operator 1 "comparison_operator"
7233 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7234 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7235 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
7236 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
7237 "TARGET_CMOVE"
7238 "#")
7239
7240(define_insn ""
7241 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
7242 (if_then_else:SI (match_operator 1 "comparison_operator"
7243 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7244 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7245 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
7246 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
7247 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7248 "#")
7249
7250(define_split
7251 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7252 (if_then_else:SI (match_operator 1 "comparison_operator"
7253 [(match_operand 2 "nonimmediate_operand" "")
7254 (const_int 0)])
7255 (match_operand:SI 3 "nonimmediate_operand" "rm,0,rm")
7256 (match_operand:SI 4 "nonimmediate_operand" "0,rm,rm")))]
7257 "TARGET_CMOVE && reload_completed"
7258 [(set (cc0)
7259 (match_dup 2))
7260 (set (match_dup 0)
7261 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7262 (match_dup 3) (match_dup 4)))]
7263 "")
7264
7265(define_split
7266 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7267 (if_then_else:SI (match_operator 1 "comparison_operator"
7268 [(match_operand 2 "nonimmediate_operand" "")
7269 (match_operand 3 "general_operand" "")])
7270 (match_operand:SI 4 "nonimmediate_operand" "rm,0,rm")
7271 (match_operand:SI 5 "nonimmediate_operand" "0,rm,rm")))]
7272 "TARGET_CMOVE && reload_completed"
7273 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7274 (set (match_dup 0)
7275 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
7276 (match_dup 4) (match_dup 5)))]
7277 "")
7278
7279(define_insn ""
7280 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
926b3fae 7281 (if_then_else:SI (match_operator 1 "comparison_operator"
b76c90cf 7282 [(cc0) (const_int 0)])
726e2d54
JW
7283 (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm")
7284 (match_operand:SI 3 "nonimmediate_operand" "0,rm,rm")))]
7285 "TARGET_CMOVE && reload_completed"
b657fc39 7286 "* return output_int_conditional_move (which_alternative, operands);")
926b3fae 7287
726e2d54
JW
7288(define_expand "movhicc"
7289 [(set (match_operand:HI 0 "register_operand" "")
7290 (if_then_else:HI (match_operand 1 "comparison_operator" "")
7291 (match_operand:HI 2 "nonimmediate_operand" "")
7292 (match_operand:HI 3 "nonimmediate_operand" "")))]
7293 "TARGET_CMOVE"
7294 "
7295{
7296 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7297 FAIL;
7298
7299 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7300 GET_MODE (i386_compare_op0),
7301 i386_compare_op0, i386_compare_op1);
7302}")
7303
7304(define_insn ""
7305 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
7306 (if_then_else:HI (match_operator 1 "comparison_operator"
7307 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7308 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7309 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
7310 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
7311 "TARGET_CMOVE"
7312 "#")
7313
7314(define_insn ""
7315 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
7316 (if_then_else:HI (match_operator 1 "comparison_operator"
7317 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7318 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7319 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
7320 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
7321 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7322 "#")
7323
7324(define_split
7325 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7326 (if_then_else:HI (match_operator 1 "comparison_operator"
7327 [(match_operand 2 "nonimmediate_operand" "")
7328 (const_int 0)])
7329 (match_operand:HI 3 "nonimmediate_operand" "rm,0,rm")
7330 (match_operand:HI 4 "nonimmediate_operand" "0,rm,rm")))]
7331 "TARGET_CMOVE && reload_completed"
7332 [(set (cc0)
7333 (match_dup 2))
7334 (set (match_dup 0)
7335 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7336 (match_dup 3) (match_dup 4)))]
7337 "")
7338
7339(define_split
7340 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7341 (if_then_else:HI (match_operator 1 "comparison_operator"
7342 [(match_operand 2 "nonimmediate_operand" "")
7343 (match_operand 3 "general_operand" "")])
7344 (match_operand:HI 4 "nonimmediate_operand" "rm,0,rm")
7345 (match_operand:HI 5 "nonimmediate_operand" "0,rm,rm")))]
7346 "TARGET_CMOVE && reload_completed"
7347 [(set (cc0)
7348 (compare (match_dup 2) (match_dup 3)))
7349 (set (match_dup 0)
7350 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
7351 (match_dup 4) (match_dup 5)))]
7352 "")
7353
7354(define_insn ""
7355 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
926b3fae 7356 (if_then_else:HI (match_operator 1 "comparison_operator"
b76c90cf 7357 [(cc0) (const_int 0)])
726e2d54
JW
7358 (match_operand:HI 2 "nonimmediate_operand" "rm,0,rm")
7359 (match_operand:HI 3 "nonimmediate_operand" "0,rm,rm")))]
7360 "TARGET_CMOVE && reload_completed"
b657fc39 7361 "* return output_int_conditional_move (which_alternative, operands);")
e5e809f4 7362
56710e42 7363(define_expand "movsfcc"
726e2d54 7364 [(set (match_operand:SF 0 "register_operand" "")
56710e42 7365 (if_then_else:SF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
7366 (match_operand:SF 2 "register_operand" "")
7367 (match_operand:SF 3 "register_operand" "")))]
726e2d54 7368 "TARGET_CMOVE"
56710e42
SC
7369 "
7370{
bbe8497f
JW
7371 rtx temp;
7372
726e2d54
JW
7373 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7374 FAIL;
7375
bbe8497f
JW
7376 /* The floating point conditional move instructions don't directly
7377 support conditions resulting from a signed integer comparison. */
7378
7379 switch (GET_CODE (operands[1]))
7380 {
7381 case LT:
7382 case LE:
7383 case GE:
7384 case GT:
7385 temp = emit_store_flag (gen_reg_rtx (QImode),
7386 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7387 VOIDmode, 0, 0);
7388
7389 if (!temp)
7390 FAIL;
7391
7392 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
7393 break;
7394
7395 default:
7396 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
726e2d54
JW
7397 GET_MODE (i386_compare_op0),
7398 i386_compare_op0, i386_compare_op1);
bbe8497f
JW
7399 break;
7400 }
726e2d54
JW
7401}")
7402
7403(define_insn ""
7404 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
7405 (if_then_else:SF (match_operator 1 "comparison_operator"
7406 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7407 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7408 (match_operand:SF 4 "register_operand" "f,f,0,0,f,f")
7409 (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))]
bbe8497f
JW
7410 "TARGET_CMOVE
7411 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7412 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7413 "#")
7414
7415(define_insn ""
7416 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
7417 (if_then_else:SF (match_operator 1 "comparison_operator"
7418 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7419 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7420 (match_operand:SF 4 "register_operand" "f,f,0,0,f,f")
7421 (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))]
bbe8497f
JW
7422 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7423 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7424 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7425 "#")
7426
7427(define_split
7428 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
7429 (if_then_else:SF (match_operator 1 "comparison_operator"
7430 [(match_operand 2 "nonimmediate_operand" "")
7431 (const_int 0)])
7432 (match_operand:SF 3 "register_operand" "f,0,f")
7433 (match_operand:SF 4 "register_operand" "0,f,f")))]
7434 "TARGET_CMOVE && reload_completed"
7435 [(set (cc0)
7436 (match_dup 2))
7437 (set (match_dup 0)
7438 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7439 (match_dup 3) (match_dup 4)))]
7440 "")
7441
7442(define_split
7443 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
7444 (if_then_else:SF (match_operator 1 "comparison_operator"
7445 [(match_operand 2 "nonimmediate_operand" "")
7446 (match_operand 3 "general_operand" "")])
7447 (match_operand:SF 4 "register_operand" "f,0,f")
7448 (match_operand:SF 5 "register_operand" "0,f,f")))]
7449 "TARGET_CMOVE && reload_completed"
7450 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7451 (set (match_dup 0)
7452 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
7453 (match_dup 4) (match_dup 5)))]
7454 "")
7455
7456(define_insn ""
7457 [(set (match_operand:SF 0 "register_operand" "=f,f,f")
7458 (if_then_else:SF (match_operator 1 "comparison_operator"
7459 [(cc0) (const_int 0)])
7460 (match_operand:SF 2 "register_operand" "f,0,f")
7461 (match_operand:SF 3 "register_operand" "0,f,f")))]
7462 "TARGET_CMOVE && reload_completed"
b657fc39 7463 "* return output_fp_conditional_move (which_alternative, operands);")
56710e42
SC
7464
7465(define_expand "movdfcc"
726e2d54 7466 [(set (match_operand:DF 0 "register_operand" "")
56710e42 7467 (if_then_else:DF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
7468 (match_operand:DF 2 "register_operand" "")
7469 (match_operand:DF 3 "register_operand" "")))]
726e2d54 7470 "TARGET_CMOVE"
56710e42
SC
7471 "
7472{
bbe8497f
JW
7473 rtx temp;
7474
726e2d54
JW
7475 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7476 FAIL;
7477
bbe8497f
JW
7478 /* The floating point conditional move instructions don't directly
7479 support conditions resulting from a signed integer comparison. */
1c5d60f5
JW
7480
7481 switch (GET_CODE (operands[1]))
7482 {
7483 case LT:
7484 case LE:
7485 case GE:
7486 case GT:
bbe8497f
JW
7487 temp = emit_store_flag (gen_reg_rtx (QImode),
7488 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7489 VOIDmode, 0, 0);
1c5d60f5 7490
bbe8497f
JW
7491 if (!temp)
7492 FAIL;
7493
7494 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
1c5d60f5 7495 break;
1c5d60f5 7496
bbe8497f
JW
7497 default:
7498 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
726e2d54
JW
7499 GET_MODE (i386_compare_op0),
7500 i386_compare_op0, i386_compare_op1);
bbe8497f
JW
7501 break;
7502 }
726e2d54
JW
7503}")
7504
7505(define_insn ""
7506 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
7507 (if_then_else:DF (match_operator 1 "comparison_operator"
7508 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7509 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7510 (match_operand:DF 4 "register_operand" "f,f,0,0,f,f")
7511 (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))]
bbe8497f
JW
7512 "TARGET_CMOVE
7513 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7514 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7515 "#")
7516
7517(define_insn ""
7518 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
7519 (if_then_else:DF (match_operator 1 "comparison_operator"
7520 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7521 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7522 (match_operand:DF 4 "register_operand" "f,f,0,0,f,f")
7523 (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))]
bbe8497f
JW
7524 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7525 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7526 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7527 "#")
7528
7529(define_split
7530 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
7531 (if_then_else:DF (match_operator 1 "comparison_operator"
7532 [(match_operand 2 "nonimmediate_operand" "")
7533 (const_int 0)])
7534 (match_operand:DF 3 "register_operand" "f,0,f")
7535 (match_operand:DF 4 "register_operand" "0,f,f")))]
7536 "TARGET_CMOVE && reload_completed"
7537 [(set (cc0)
7538 (match_dup 2))
7539 (set (match_dup 0)
7540 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7541 (match_dup 3) (match_dup 4)))]
7542 "")
7543
7544(define_split
7545 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
7546 (if_then_else:DF (match_operator 1 "comparison_operator"
7547 [(match_operand 2 "nonimmediate_operand" "")
7548 (match_operand 3 "general_operand" "")])
7549 (match_operand:DF 4 "register_operand" "f,0,f")
7550 (match_operand:DF 5 "register_operand" "0,f,f")))]
7551 "TARGET_CMOVE && reload_completed"
7552 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7553 (set (match_dup 0)
7554 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
7555 (match_dup 4) (match_dup 5)))]
7556 "")
7557
7558(define_insn ""
7559 [(set (match_operand:DF 0 "register_operand" "=f,f,f")
7560 (if_then_else:DF (match_operator 1 "comparison_operator"
7561 [(cc0) (const_int 0)])
7562 (match_operand:DF 2 "register_operand" "f,0,f")
7563 (match_operand:DF 3 "register_operand" "0,f,f")))]
7564 "TARGET_CMOVE && reload_completed"
b657fc39 7565 "* return output_fp_conditional_move (which_alternative, operands);")
56710e42
SC
7566
7567(define_expand "movxfcc"
726e2d54 7568 [(set (match_operand:XF 0 "register_operand" "")
56710e42 7569 (if_then_else:XF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
7570 (match_operand:XF 2 "register_operand" "")
7571 (match_operand:XF 3 "register_operand" "")))]
726e2d54 7572 "TARGET_CMOVE"
56710e42
SC
7573 "
7574{
bbe8497f
JW
7575 rtx temp;
7576
726e2d54
JW
7577 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7578 FAIL;
7579
bbe8497f
JW
7580 /* The floating point conditional move instructions don't directly
7581 support conditions resulting from a signed integer comparison. */
1c5d60f5
JW
7582
7583 switch (GET_CODE (operands[1]))
7584 {
7585 case LT:
7586 case LE:
7587 case GE:
7588 case GT:
bbe8497f
JW
7589 temp = emit_store_flag (gen_reg_rtx (QImode),
7590 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1,
7591 VOIDmode, 0, 0);
1c5d60f5 7592
bbe8497f
JW
7593 if (!temp)
7594 FAIL;
7595
7596 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx);
1c5d60f5 7597 break;
1c5d60f5 7598
bbe8497f
JW
7599 default:
7600 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
726e2d54
JW
7601 GET_MODE (i386_compare_op0),
7602 i386_compare_op0, i386_compare_op1);
bbe8497f
JW
7603 break;
7604 }
56710e42
SC
7605}")
7606
726e2d54
JW
7607(define_insn ""
7608 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
7609 (if_then_else:XF (match_operator 1 "comparison_operator"
7610 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7611 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7612 (match_operand:XF 4 "register_operand" "f,f,0,0,f,f")
7613 (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))]
bbe8497f
JW
7614 "TARGET_CMOVE
7615 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7616 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7617 "#")
7618
7619(define_insn ""
7620 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
7621 (if_then_else:XF (match_operator 1 "comparison_operator"
7622 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7623 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7624 (match_operand:XF 4 "register_operand" "f,f,0,0,f,f")
7625 (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))]
bbe8497f
JW
7626 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT
7627 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE
7628 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT"
726e2d54
JW
7629 "#")
7630
7631(define_split
7632 [(set (match_operand:XF 0 "register_operand" "=f,f,f")
7633 (if_then_else:XF (match_operator 1 "comparison_operator"
7634 [(match_operand 2 "nonimmediate_operand" "")
7635 (const_int 0)])
7636 (match_operand:XF 3 "register_operand" "f,0,f")
7637 (match_operand:XF 4 "register_operand" "0,f,f")))]
7638 "TARGET_CMOVE && reload_completed"
7639 [(set (cc0)
7640 (match_dup 2))
7641 (set (match_dup 0)
7642 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
7643 (match_dup 3) (match_dup 4)))]
7644 "")
7645
7646(define_split
7647 [(set (match_operand:XF 0 "register_operand" "=f,f,f")
7648 (if_then_else:XF (match_operator 1 "comparison_operator"
7649 [(match_operand 2 "nonimmediate_operand" "")
7650 (match_operand 3 "general_operand" "")])
7651 (match_operand:XF 4 "register_operand" "f,0,f")
7652 (match_operand:XF 5 "register_operand" "0,f,f")))]
7653 "TARGET_CMOVE && reload_completed"
7654 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7655 (set (match_dup 0)
7656 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
7657 (match_dup 4) (match_dup 5)))]
7658 "")
7659
7660(define_insn ""
7661 [(set (match_operand:XF 0 "register_operand" "=f,f,f")
7662 (if_then_else:XF (match_operator 1 "comparison_operator"
7663 [(cc0) (const_int 0)])
7664 (match_operand:XF 2 "register_operand" "f,0,f")
7665 (match_operand:XF 3 "register_operand" "0,f,f")))]
7666 "TARGET_CMOVE && reload_completed"
b657fc39 7667 "* return output_fp_conditional_move (which_alternative, operands);")
56710e42 7668
726e2d54
JW
7669(define_expand "movdicc"
7670 [(set (match_operand:DI 0 "register_operand" "")
7671 (if_then_else:DI (match_operand 1 "comparison_operator" "")
7672 (match_operand:DI 2 "nonimmediate_operand" "")
7673 (match_operand:DI 3 "nonimmediate_operand" "")))]
7674 "TARGET_CMOVE"
7675 "
7676{
7677 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
7678 FAIL;
7679
7680 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
7681 GET_MODE (i386_compare_op0),
7682 i386_compare_op0, i386_compare_op1);
7683}")
7684
7685(define_insn ""
7686 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r,&r,&r")
7687 (if_then_else:DI (match_operator 1 "comparison_operator"
7688 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
7689 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
7690 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0,ro,ro")
7691 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro,ro,ro")))]
7692 "TARGET_CMOVE"
7693 "#")
7694
7695(define_insn ""
7696 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r,&r,&r")
7697 (if_then_else:DI (match_operator 1 "comparison_operator"
7698 [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
7699 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
7700 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0,ro,ro")
7701 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro,ro,ro")))]
7702 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
7703 "#")
7704
7705(define_split
7706 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
7707 (if_then_else:DI (match_operator 1 "comparison_operator"
7708 [(match_operand 2 "nonimmediate_operand" "")
7709 (const_int 0)])
7710 (match_operand:DI 3 "nonimmediate_operand" "ro,0,ro")
7711 (match_operand:DI 4 "nonimmediate_operand" "0,ro,ro")))]
7712 "TARGET_CMOVE && reload_completed"
7713 [(set (cc0)
7714 (match_dup 2))
7715 (set (match_dup 0)
7716 (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)])
7717 (match_dup 3) (match_dup 4)))]
7718 "")
7719
7720(define_split
7721 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
7722 (if_then_else:DI (match_operator 1 "comparison_operator"
7723 [(match_operand 2 "nonimmediate_operand" "")
7724 (match_operand 3 "general_operand" "")])
7725 (match_operand:DI 4 "nonimmediate_operand" "ro,0,ro")
7726 (match_operand:DI 5 "nonimmediate_operand" "0,ro,ro")))]
7727 "TARGET_CMOVE && reload_completed"
7728 [(set (cc0) (compare (match_dup 2) (match_dup 3)))
7729 (set (match_dup 0)
7730 (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)])
7731 (match_dup 4) (match_dup 5)))]
7732 "")
7733
7734(define_insn ""
7735 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
7736 (if_then_else:DI (match_operator 1 "comparison_operator"
7737 [(cc0) (const_int 0)])
7738 (match_operand:DI 2 "nonimmediate_operand" "ro,0,ro")
7739 (match_operand:DI 3 "nonimmediate_operand" "0,ro,ro")))]
7740 "TARGET_CMOVE && reload_completed"
b657fc39 7741 "* return output_int_conditional_move (which_alternative, operands);")
926b3fae 7742
2ae0f82c
SC
7743(define_insn "strlensi_unroll"
7744 [(set (match_operand:SI 0 "register_operand" "=&r,&r")
7745 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r"))
7746 (match_operand:SI 2 "immediate_operand" "i,i")] 0))
7747 (clobber (match_scratch:SI 3 "=&q,&r"))]
7748 "optimize > 1"
7749 "* return output_strlen_unroll (operands);")
7750
628448b3
SC
7751;; the only difference between the following patterns is the register preference
7752;; on a pentium using a q-register saves one clock cycle per 4 characters
7753
7754(define_insn "strlensi_unroll4"
7755 [(set (match_operand:SI 0 "register_operand" "=r,r")
7756 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0"))
7757 (match_operand:SI 1 "immediate_operand" "i,i")
d9118e7b 7758 (match_operand:SI 2 "register_operand" "+q,!r")] 0))
628448b3
SC
7759 (clobber (match_dup 2))]
7760 "(TARGET_USE_ANY_REG && optimize > 1)"
7761 "* return output_strlen_unroll (operands);")
7762
7763(define_insn "strlensi_unroll5"
7764 [(set (match_operand:SI 0 "register_operand" "=r")
7765 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0"))
7766 (match_operand:SI 1 "immediate_operand" "i")
d9118e7b 7767 (match_operand:SI 2 "register_operand" "+q")] 0))
628448b3
SC
7768 (clobber (match_dup 2))]
7769 "(TARGET_USE_Q_REG && optimize > 1)"
5f3d14e3
SC
7770 "* return output_strlen_unroll (operands);"
7771)
578b58f5
RK
7772
7773(define_insn "allocate_stack_worker"
7774 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
7775 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
7776 (clobber (match_dup 0))]
7777 "TARGET_STACK_PROBE"
7778 "* return AS1(call,__alloca);")
7779
7780(define_expand "allocate_stack"
e9a25f70
JL
7781 [(set (match_operand:SI 0 "register_operand" "=r")
7782 (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" "")))
7783 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))]
7784 "TARGET_STACK_PROBE"
578b58f5
RK
7785 "
7786{
7787#ifdef CHECK_STACK_LIMIT
e9a25f70
JL
7788 if (GET_CODE (operands[1]) == CONST_INT
7789 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
578b58f5 7790 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
e9a25f70 7791 operands[1]));
578b58f5
RK
7792 else
7793#endif
7794 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
e9a25f70 7795 operands[1])));
578b58f5 7796
e9a25f70
JL
7797 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
7798 DONE;
7799}")
This page took 1.477523 seconds and 5 git commands to generate.