i860.c: Replace all occurrences of 'GNU CC' with 'GCC'.
[gcc.git] / gcc / config / i860 / i860.md
1 ;;- Machine description for Intel 860 chip for GNU C compiler
2 ;; Copyright (C) 1989, 1990, 1997, 1998, 1999, 2000, 2003
3 ;; Free Software Foundation, Inc.
4
5 ;; This file is part of GCC.
6
7 ;; GCC 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 ;; GCC 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 GCC; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
26 ;;- updates for most instructions.
27
28 ;;- Operand classes for the register allocator:
29 \f
30 /* Bit-test instructions. */
31
32 (define_insn ""
33 [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
34 (match_operand:SI 1 "logic_operand" "rL"))
35 (const_int 0)))]
36 ""
37 "*
38 {
39 CC_STATUS_PARTIAL_INIT;
40 return \"and %1,%0,%?r0\";
41 }")
42
43 (define_insn ""
44 [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")
45 (match_operand:SI 1 "logic_operand" "rL"))
46 (const_int 0)))]
47 ""
48 "*
49 {
50 CC_STATUS_PARTIAL_INIT;
51 cc_status.flags |= CC_NEGATED;
52 return \"and %1,%0,%?r0\";
53 }")
54
55 (define_insn ""
56 [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
57 (match_operand:SI 1 "immediate_operand" "i"))
58 (const_int 0)))]
59 "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"
60 "*
61 {
62 CC_STATUS_PARTIAL_INIT;
63 return \"andh %H1,%0,%?r0\";
64 }")
65
66 (define_insn ""
67 [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")
68 (match_operand:SI 1 "immediate_operand" "i"))
69 (const_int 0)))]
70 "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"
71 "*
72 {
73 CC_STATUS_PARTIAL_INIT;
74 cc_status.flags |= CC_NEGATED;
75 return \"andh %H1,%0,%?r0\";
76 }")
77
78 (define_insn ""
79 [(set (cc0) (eq (ashiftrt:SI
80 (sign_extend:SI
81 (ashift:QI (match_operand:QI 0 "register_operand" "r")
82 (match_operand:QI 1 "logic_int" "n")))
83 (match_operand:SI 2 "logic_int" "n"))
84 (const_int 0)))]
85 ""
86 "*
87 {
88 int width = 8 - INTVAL (operands[2]);
89 int pos = 8 - width - INTVAL (operands[1]);
90
91 CC_STATUS_PARTIAL_INIT;
92 operands[2] = GEN_INT (~((-1) << width) << pos);
93 return \"and %2,%0,%?r0\";
94 }")
95 \f
96 ;; -------------------------------------------------------------------------
97 ;; SImode signed integer comparisons
98 ;; -------------------------------------------------------------------------
99
100 (define_insn "cmpeqsi"
101 [(set (cc0) (eq (match_operand:SI 0 "logic_operand" "r,rL")
102 (match_operand:SI 1 "logic_operand" "L,r")))]
103 ""
104 "*
105 {
106 CC_STATUS_PARTIAL_INIT;
107 if (REG_P (operands[0]))
108 return \"xor %1,%0,%?r0\";
109 else
110 return \"xor %0,%1,%?r0\";
111 }")
112
113 (define_insn "cmpnesi"
114 [(set (cc0) (ne (match_operand:SI 0 "logic_operand" "r,rL")
115 (match_operand:SI 1 "logic_operand" "L,r")))]
116 ""
117 "*
118 {
119 CC_STATUS_PARTIAL_INIT;
120 cc_status.flags |= CC_NEGATED;
121 if (REG_P (operands[0]))
122 return \"xor %1,%0,%?r0\";
123 else
124 return \"xor %0,%1,%?r0\";
125 }")
126
127 (define_insn "cmpltsi"
128 [(set (cc0) (lt (match_operand:SI 0 "arith_operand" "r,rI")
129 (match_operand:SI 1 "arith_operand" "I,r")))]
130 ""
131 "*
132 {
133 CC_STATUS_PARTIAL_INIT;
134 if (REG_P (operands[1]))
135 return \"subs %0,%1,%?r0\";
136 else
137 {
138 cc_status.flags |= CC_REVERSED;
139 operands[1] = GEN_INT (- INTVAL (operands[1]));
140 return \"adds %1,%0,%?r0\";
141 }
142 }")
143
144 (define_insn "cmpgtsi"
145 [(set (cc0) (gt (match_operand:SI 0 "arith_operand" "r,rI")
146 (match_operand:SI 1 "arith_operand" "I,r")))]
147 ""
148 "*
149 {
150 CC_STATUS_PARTIAL_INIT;
151 if (REG_P (operands[0]))
152 return \"subs %1,%0,%?r0\";
153 else
154 {
155 cc_status.flags |= CC_REVERSED;
156 operands[0] = GEN_INT (- INTVAL (operands[0]));
157 return \"adds %0,%1,%?r0\";
158 }
159 }")
160
161 (define_insn "cmplesi"
162 [(set (cc0) (le (match_operand:SI 0 "arith_operand" "r,rI")
163 (match_operand:SI 1 "arith_operand" "I,r")))]
164 ""
165 "*
166 {
167 CC_STATUS_PARTIAL_INIT;
168 cc_status.flags |= CC_NEGATED;
169 if (REG_P (operands[0]))
170 return \"subs %1,%0,%?r0\";
171 else
172 {
173 cc_status.flags |= CC_REVERSED;
174 operands[0] = GEN_INT (- INTVAL (operands[0]));
175 return \"adds %0,%1,%?r0\";
176 }
177 }")
178
179 (define_insn "cmpgesi"
180 [(set (cc0) (ge (match_operand:SI 0 "arith_operand" "r,rI")
181 (match_operand:SI 1 "arith_operand" "I,r")))]
182 ""
183 "*
184 {
185 CC_STATUS_PARTIAL_INIT;
186 cc_status.flags |= CC_NEGATED;
187 if (REG_P (operands[1]))
188 return \"subs %0,%1,%?r0\";
189 else
190 {
191 cc_status.flags |= CC_REVERSED;
192 operands[1] = GEN_INT (- INTVAL (operands[1]));
193 return \"adds %1,%0,%?r0\";
194 }
195 }")
196
197 ;; -------------------------------------------------------------------------
198 ;; SImode unsigned integer comparisons
199 ;; -------------------------------------------------------------------------
200
201 ;; WARNING! There is a small i860 hardware limitation (bug?) which we
202 ;; may run up against (if we are not careful) when we are trying to do
203 ;; unsigned comparisons like (x >= 0), (x < 0), (0 <= x), and (0 > x).
204 ;; Specifically, we must avoid using an `addu' instruction to perform
205 ;; such comparisons because the result (in the CC bit register) will
206 ;; come out wrong. (This fact is documented in a footnote on page 7-10
207 ;; of the 1991 version of the i860 Microprocessor Family Programmer's
208 ;; Reference Manual). Note that unsigned comparisons of this sort are
209 ;; always redundant anyway, because an unsigned quantity can never be
210 ;; less than zero. When we see cases like this, we generate an
211 ;; `or K,%r0,%r0' instruction instead (where K is a constant 0 or -1)
212 ;; so as to get the CC bit register set properly for any subsequent
213 ;; conditional jump instruction.
214
215 (define_insn "cmpgeusi"
216 [(set (cc0) (geu (match_operand:SI 0 "arith_operand" "r,rI")
217 (match_operand:SI 1 "arith_operand" "I,r")))]
218 ""
219 "*
220 {
221 CC_STATUS_PARTIAL_INIT;
222 if (REG_P (operands[1]))
223 return \"subu %0,%1,%?r0\";
224 else
225 {
226 if (INTVAL (operands[1]) == 0)
227 return \"or 0,%?r0,%?r0\";
228 else
229 {
230 cc_status.flags |= CC_REVERSED;
231 operands[1] = GEN_INT (- INTVAL (operands[1]));
232 return \"addu %1,%0,%?r0\";
233 }
234 }
235 }")
236
237 (define_insn "cmpleusi"
238 [(set (cc0) (leu (match_operand:SI 0 "arith_operand" "r,rI")
239 (match_operand:SI 1 "arith_operand" "I,r")))]
240 ""
241 "*
242 {
243 CC_STATUS_PARTIAL_INIT;
244 if (REG_P (operands[0]))
245 return \"subu %1,%0,%?r0\";
246 else
247 {
248 if (INTVAL (operands[0]) == 0)
249 return \"or 0,%?r0,%?r0\";
250 else
251 {
252 cc_status.flags |= CC_REVERSED;
253 operands[0] = GEN_INT (- INTVAL (operands[0]));
254 return \"addu %0,%1,%?r0\";
255 }
256 }
257 }")
258
259 ;; -------------------------------------------------------------------------
260 ;; SFmode floating-point comparisons
261 ;; -------------------------------------------------------------------------
262
263 (define_insn "cmpeqsf"
264 [(set (cc0) (eq (match_operand:SF 0 "reg_or_0_operand" "fG")
265 (match_operand:SF 1 "reg_or_0_operand" "fG")))]
266 ""
267 "*
268 {
269 CC_STATUS_PARTIAL_INIT;
270 return \"pfeq.ss %r0,%r1,%?f0\";
271 }")
272
273 (define_insn "cmpnesf"
274 [(set (cc0) (ne (match_operand:SF 0 "reg_or_0_operand" "fG")
275 (match_operand:SF 1 "reg_or_0_operand" "fG")))]
276 ""
277 "*
278 {
279 CC_STATUS_PARTIAL_INIT;
280 cc_status.flags |= CC_NEGATED;
281 return \"pfeq.ss %r1,%r0,%?f0\";
282 }")
283
284 ;; NOTE: The i860 Programmer's Reference Manual says that when we are
285 ;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these
286 ;; in order to be IEEE compliant (in case a trap occurs during these
287 ;; operations). Conversely, for (A <= B) or (A >= B) comparisons, we
288 ;; must use pfle to be IEEE compliant.
289
290 (define_insn "cmpltsf"
291 [(set (cc0) (lt (match_operand:SF 0 "reg_or_0_operand" "fG")
292 (match_operand:SF 1 "reg_or_0_operand" "fG")))]
293 ""
294 "*
295 {
296 CC_STATUS_PARTIAL_INIT;
297 return \"pfgt.ss %r1,%r0,%?f0\";
298 }")
299
300 (define_insn "cmpgtsf"
301 [(set (cc0) (gt (match_operand:SF 0 "reg_or_0_operand" "fG")
302 (match_operand:SF 1 "reg_or_0_operand" "fG")))]
303 ""
304 "*
305 {
306 CC_STATUS_PARTIAL_INIT;
307 return \"pfgt.ss %r0,%r1,%?f0\";
308 }")
309
310 ;; NOTE: The pfle opcode doesn't do what you think it does. It is
311 ;; bass-ackwards. It *clears* the CC flag if the first operand is
312 ;; less than or equal to the second. Thus, we have to set CC_NEGATED
313 ;; for the following two patterns.
314
315 (define_insn "cmplesf"
316 [(set (cc0) (le (match_operand:SF 0 "reg_or_0_operand" "fG")
317 (match_operand:SF 1 "reg_or_0_operand" "fG")))]
318 ""
319 "*
320 {
321 CC_STATUS_PARTIAL_INIT;
322 cc_status.flags |= CC_NEGATED;
323 return \"pfle.ss %r0,%r1,%?f0\";
324 }")
325
326 (define_insn "cmpgesf"
327 [(set (cc0) (ge (match_operand:SF 0 "reg_or_0_operand" "fG")
328 (match_operand:SF 1 "reg_or_0_operand" "fG")))]
329 ""
330 "*
331 {
332 CC_STATUS_PARTIAL_INIT;
333 cc_status.flags |= CC_NEGATED;
334 return \"pfle.ss %r1,%r0,%?f0\";
335 }")
336
337 ;; -------------------------------------------------------------------------
338 ;; DFmode floating-point comparisons
339 ;; -------------------------------------------------------------------------
340
341 (define_insn "cmpeqdf"
342 [(set (cc0) (eq (match_operand:DF 0 "reg_or_0_operand" "fG")
343 (match_operand:DF 1 "reg_or_0_operand" "fG")))]
344 ""
345 "*
346 {
347 CC_STATUS_PARTIAL_INIT;
348 return \"pfeq.dd %r0,%r1,%?f0\";
349 }")
350
351 (define_insn "cmpnedf"
352 [(set (cc0) (ne (match_operand:DF 0 "reg_or_0_operand" "fG")
353 (match_operand:DF 1 "reg_or_0_operand" "fG")))]
354 ""
355 "*
356 {
357 CC_STATUS_PARTIAL_INIT;
358 cc_status.flags |= CC_NEGATED;
359 return \"pfeq.dd %r1,%r0,%?f0\";
360 }")
361
362 ;; NOTE: The i860 Programmer's Reference Manual says that when we are
363 ;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these
364 ;; in order to be IEEE compliant (in case a trap occurs during these
365 ;; operations). Conversely, for (A <= B) or (A >= B) comparisons, we
366 ;; must use pfle to be IEEE compliant.
367
368 (define_insn "cmpltdf"
369 [(set (cc0) (lt (match_operand:DF 0 "reg_or_0_operand" "fG")
370 (match_operand:DF 1 "reg_or_0_operand" "fG")))]
371 ""
372 "*
373 {
374 CC_STATUS_PARTIAL_INIT;
375 return \"pfgt.dd %r1,%r0,%?f0\";
376 }")
377
378 (define_insn "cmpgtdf"
379 [(set (cc0) (gt (match_operand:DF 0 "reg_or_0_operand" "fG")
380 (match_operand:DF 1 "reg_or_0_operand" "fG")))]
381 ""
382 "*
383 {
384 CC_STATUS_PARTIAL_INIT;
385 return \"pfgt.dd %r0,%r1,%?f0\";
386 }")
387
388 ;; NOTE: The pfle opcode doesn't do what you think it does. It is
389 ;; bass-ackwards. It *clears* the CC flag if the first operand is
390 ;; less than or equal to the second. Thus, we have to set CC_NEGATED
391 ;; for the following two patterns.
392
393 (define_insn "cmpledf"
394 [(set (cc0) (le (match_operand:DF 0 "reg_or_0_operand" "fG")
395 (match_operand:DF 1 "reg_or_0_operand" "fG")))]
396 ""
397 "*
398 {
399 CC_STATUS_PARTIAL_INIT;
400 cc_status.flags |= CC_NEGATED;
401 return \"pfle.dd %r0,%r1,%?f0\";
402 }")
403
404 (define_insn "cmpgedf"
405 [(set (cc0) (ge (match_operand:DF 0 "reg_or_0_operand" "fG")
406 (match_operand:DF 1 "reg_or_0_operand" "fG")))]
407 ""
408 "*
409 {
410 CC_STATUS_PARTIAL_INIT;
411 cc_status.flags |= CC_NEGATED;
412 return \"pfle.dd %r1,%r0,%?f0\";
413 }")
414
415 ;; ------------------------------------------------------------------------
416 ;; Integer EQ/NE comparisons against constant values which will fit in the
417 ;; 16-bit immediate field of an instruction. These are made by combining.
418 ;; ------------------------------------------------------------------------
419
420 (define_insn ""
421 [(set (cc0) (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m"))
422 (match_operand:SI 1 "small_int" "I")))]
423 "INTVAL (operands[1]) >= 0"
424 "*
425 {
426 CC_STATUS_PARTIAL_INIT;
427 return \"ld.s %0,%?r31\;xor %1,%?r31,%?r0\";
428 }")
429
430 (define_insn ""
431 [(set (cc0) (eq (match_operand:SI 0 "small_int" "I")
432 (zero_extend:SI (match_operand:HI 1 "load_operand" "m"))))]
433 "INTVAL (operands[0]) >= 0"
434 "*
435 {
436 CC_STATUS_PARTIAL_INIT;
437 return \"ld.s %1,%?r31\;xor %0,%?r31,%?r0\";
438 }")
439 \f
440 ;; ------------------------------------------------------------------------
441 ;; Define the real conditional branch instructions.
442 ;; ------------------------------------------------------------------------
443
444 (define_insn "cbranch"
445 [(set (pc) (if_then_else (eq (cc0) (const_int 0))
446 (label_ref (match_operand 0 "" ""))
447 (pc)))]
448 ""
449 "*
450 {
451 if ((cc_prev_status.flags & CC_NEGATED) == 0)
452 return \"bnc %l0\";
453 else
454 return \"bc %l0\";
455 }")
456
457 (define_insn "flipped_cbranch"
458 [(set (pc) (if_then_else (ne (cc0)
459 (const_int 0))
460 (pc)
461 (label_ref (match_operand 0 "" ""))))]
462 ""
463 "*
464 {
465 if ((cc_prev_status.flags & CC_NEGATED) == 0)
466 return \"bnc %l0\";
467 else
468 return \"bc %l0\";
469 }")
470
471 (define_insn "inverse_cbranch"
472 [(set (pc) (if_then_else (eq (cc0)
473 (const_int 0))
474 (pc)
475 (label_ref (match_operand 0 "" ""))))]
476 ""
477 "*
478 {
479 if ((cc_prev_status.flags & CC_NEGATED) == 0)
480 return \"bc %l0\";
481 else
482 return \"bnc %l0\";
483 }")
484
485
486 (define_insn "flipped_inverse_cbranch"
487 [(set (pc) (if_then_else (ne (cc0)
488 (const_int 0))
489 (label_ref (match_operand 0 "" ""))
490 (pc)))]
491 ""
492 "*
493 {
494 if ((cc_prev_status.flags & CC_NEGATED) == 0)
495 return \"bc %l0\";
496 else
497 return \"bnc %l0\";
498 }")
499
500 ;; Simple BTE/BTNE compare-and-branch insns made by combining.
501 ;; Note that it is wrong to add similar patterns for QI or HImode
502 ;; because bte/btne always compare the whole register.
503
504 (define_insn ""
505 [(set (pc)
506 (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
507 (match_operand:SI 1 "bte_operand" "rK"))
508 (label_ref (match_operand 2 "" ""))
509 (pc)))]
510 ""
511 "bte %1,%0,%2")
512
513 (define_insn ""
514 [(set (pc)
515 (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
516 (match_operand:SI 1 "bte_operand" "rK"))
517 (label_ref (match_operand 2 "" ""))
518 (pc)))]
519 ""
520 "btne %1,%0,%2")
521
522 (define_insn ""
523 [(set (pc)
524 (if_then_else (eq (match_operand:SI 0 "register_operand" "r")
525 (match_operand:SI 1 "bte_operand" "rK"))
526 (pc)
527 (label_ref (match_operand 2 "" ""))))]
528 ""
529 "btne %1,%0,%2")
530
531 (define_insn ""
532 [(set (pc)
533 (if_then_else (ne (match_operand:SI 0 "register_operand" "r")
534 (match_operand:SI 1 "bte_operand" "rK"))
535 (pc)
536 (label_ref (match_operand 2 "" ""))))]
537 ""
538 "bte %1,%0,%2")
539
540 ;; Load byte/halfword, zero-extend, & compare-and-branch insns.
541 ;; These are made by combining.
542
543 (define_insn ""
544 [(set (pc)
545 (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
546 (match_operand:SI 1 "bte_operand" "K"))
547 (label_ref (match_operand 2 "" ""))
548 (pc)))
549 (match_scratch:SI 3 "=r")]
550 ""
551 "ld.b %0,%3;bte %1,%3,%2")
552
553 (define_insn ""
554 [(set (pc)
555 (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
556 (match_operand:SI 1 "bte_operand" "K"))
557 (label_ref (match_operand 2 "" ""))
558 (pc)))
559 (match_scratch:SI 3 "=r")]
560 ""
561 "ld.b %0,%3;btne %1,%3,%2")
562
563 (define_insn ""
564 [(set (pc)
565 (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
566 (match_operand:SI 1 "bte_operand" "K"))
567 (pc)
568 (label_ref (match_operand 2 "" ""))))
569 (match_scratch:SI 3 "=r")]
570 ""
571 "ld.b %0,%3;btne %1,%3,%2")
572
573 (define_insn ""
574 [(set (pc)
575 (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m"))
576 (match_operand:SI 1 "bte_operand" "K"))
577 (pc)
578 (label_ref (match_operand 2 "" ""))))
579 (match_scratch:SI 3 "=r")]
580 ""
581 "ld.b %0,%3;bte %1,%3,%2")
582
583 (define_insn ""
584 [(set (pc)
585 (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
586 (match_operand:SI 1 "bte_operand" "K"))
587 (label_ref (match_operand 2 "" ""))
588 (pc)))
589 (match_scratch:SI 3 "=r")]
590 ""
591 "ld.s %0,%3;bte %1,%3,%2")
592
593 (define_insn ""
594 [(set (pc)
595 (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
596 (match_operand:SI 1 "bte_operand" "K"))
597 (label_ref (match_operand 2 "" ""))
598 (pc)))
599 (match_scratch:SI 3 "=r")]
600 ""
601 "ld.s %0,%3;btne %1,%3,%2")
602
603 (define_insn ""
604 [(set (pc)
605 (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
606 (match_operand:SI 1 "bte_operand" "K"))
607 (pc)
608 (label_ref (match_operand 2 "" ""))))
609 (match_scratch:SI 3 "=r")]
610 ""
611 "ld.s %0,%3;btne %1,%3,%2")
612
613 (define_insn ""
614 [(set (pc)
615 (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m"))
616 (match_operand:SI 1 "bte_operand" "K"))
617 (pc)
618 (label_ref (match_operand 2 "" ""))))
619 (match_scratch:SI 3 "=r")]
620 ""
621 "ld.s %0,%3;bte %1,%3,%2")
622
623 \f
624 ;; Generation of conditionals.
625
626 ;; We save the compare operands in the cmpxx patterns and use then when
627 ;; we generate the branch.
628
629 (define_expand "cmpsi"
630 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
631 (match_operand:SI 1 "compare_operand" "")))]
632 ""
633 "
634 { i860_compare_op0 = operands[0];
635 i860_compare_op1 = operands[1];
636 DONE;
637 }")
638
639 (define_expand "cmpsf"
640 [(set (cc0) (compare (match_operand:SF 0 "register_operand" "")
641 (match_operand:SF 1 "register_operand" "")))]
642 ""
643 "
644 { i860_compare_op0 = operands[0];
645 i860_compare_op1 = operands[1];
646 DONE;
647 }")
648
649 (define_expand "cmpdf"
650 [(set (cc0) (compare (match_operand:DF 0 "register_operand" "")
651 (match_operand:DF 1 "register_operand" "")))]
652 ""
653 "
654 { i860_compare_op0 = operands[0];
655 i860_compare_op1 = operands[1];
656 DONE;
657 }")
658
659 ;; These are the standard-named conditional branch patterns.
660 ;; Detailed comments are found in the first one only.
661
662 (define_expand "beq"
663 [(set (pc)
664 (if_then_else (eq (cc0)
665 (const_int 0))
666 (label_ref (match_operand 0 "" ""))
667 (pc)))]
668 ""
669 "
670 {
671 /* Emit a single-condition compare insn according to
672 the type of operands and the condition to be tested. */
673
674 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
675 emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1));
676 else if (GET_MODE (i860_compare_op0) == SFmode)
677 emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1));
678 else if (GET_MODE (i860_compare_op0) == DFmode)
679 emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1));
680 else
681 abort ();
682
683 /* Emit branch-if-true. */
684
685 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
686 DONE;
687 }")
688
689 (define_expand "bne"
690 [(set (pc)
691 (if_then_else (ne (cc0)
692 (const_int 0))
693 (label_ref (match_operand 0 "" ""))
694 (pc)))]
695 ""
696 "
697 {
698 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
699 emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1));
700 else if (GET_MODE (i860_compare_op0) == SFmode)
701 emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1));
702 else if (GET_MODE (i860_compare_op0) == DFmode)
703 emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1));
704 else
705 abort ();
706
707 emit_jump_insn (gen_flipped_cbranch (operands[0]));
708
709 DONE;
710 }")
711
712 (define_expand "bgt"
713 [(set (pc)
714 (if_then_else (gt (cc0)
715 (const_int 0))
716 (label_ref (match_operand 0 "" ""))
717 (pc)))]
718 ""
719 "
720 {
721 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
722 emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1));
723 else if (GET_MODE (i860_compare_op0) == SFmode)
724 emit_insn (gen_cmpgtsf (i860_compare_op0, i860_compare_op1));
725 else if (GET_MODE (i860_compare_op0) == DFmode)
726 emit_insn (gen_cmpgtdf (i860_compare_op0, i860_compare_op1));
727 else
728 abort ();
729
730 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
731 DONE;
732 }")
733
734 (define_expand "blt"
735 [(set (pc)
736 (if_then_else (lt (cc0)
737 (const_int 0))
738 (label_ref (match_operand 0 "" ""))
739 (pc)))]
740 ""
741 "
742 {
743 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
744 emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1));
745 else if (GET_MODE (i860_compare_op0) == SFmode)
746 emit_insn (gen_cmpltsf (i860_compare_op0, i860_compare_op1));
747 else if (GET_MODE (i860_compare_op0) == DFmode)
748 emit_insn (gen_cmpltdf (i860_compare_op0, i860_compare_op1));
749 else
750 abort ();
751
752 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
753 DONE;
754 }")
755
756 (define_expand "ble"
757 [(set (pc)
758 (if_then_else (le (cc0)
759 (const_int 0))
760 (label_ref (match_operand 0 "" ""))
761 (pc)))]
762 ""
763 "
764 {
765 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
766 {
767 emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1));
768 emit_jump_insn (gen_flipped_cbranch (operands[0]));
769 }
770 else
771 {
772 if (GET_MODE (i860_compare_op0) == SFmode)
773 emit_insn (gen_cmplesf (i860_compare_op0, i860_compare_op1));
774 else if (GET_MODE (i860_compare_op0) == DFmode)
775 emit_insn (gen_cmpledf (i860_compare_op0, i860_compare_op1));
776 else
777 abort ();
778 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
779 }
780 DONE;
781 }")
782
783 (define_expand "bge"
784 [(set (pc)
785 (if_then_else (ge (cc0)
786 (const_int 0))
787 (label_ref (match_operand 0 "" ""))
788 (pc)))]
789 ""
790 "
791 {
792 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT)
793 {
794 emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1));
795 emit_jump_insn (gen_flipped_cbranch (operands[0]));
796 }
797 else
798 {
799 if (GET_MODE (i860_compare_op0) == SFmode)
800 emit_insn (gen_cmpgesf (i860_compare_op0, i860_compare_op1));
801 else if (GET_MODE (i860_compare_op0) == DFmode)
802 emit_insn (gen_cmpgedf (i860_compare_op0, i860_compare_op1));
803 else
804 abort ();
805 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
806 }
807 DONE;
808 }")
809
810 (define_expand "bgtu"
811 [(set (pc)
812 (if_then_else (gtu (cc0)
813 (const_int 0))
814 (label_ref (match_operand 0 "" ""))
815 (pc)))]
816 ""
817 "
818 {
819 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
820 abort ();
821
822 emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1));
823 emit_jump_insn (gen_flipped_cbranch (operands[0]));
824 DONE;
825 }")
826
827 (define_expand "bltu"
828 [(set (pc)
829 (if_then_else (ltu (cc0)
830 (const_int 0))
831 (label_ref (match_operand 0 "" ""))
832 (pc)))]
833 ""
834 "
835 {
836 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
837 abort ();
838
839 emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1));
840 emit_jump_insn (gen_flipped_cbranch (operands[0]));
841 DONE;
842 }")
843
844 (define_expand "bgeu"
845 [(set (pc)
846 (if_then_else (geu (cc0)
847 (const_int 0))
848 (label_ref (match_operand 0 "" ""))
849 (pc)))]
850 ""
851 "
852 {
853 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
854 abort ();
855
856 emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1));
857 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
858 DONE;
859 }")
860
861 (define_expand "bleu"
862 [(set (pc)
863 (if_then_else (leu (cc0)
864 (const_int 0))
865 (label_ref (match_operand 0 "" ""))
866 (pc)))]
867 ""
868 "
869 {
870 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT)
871 abort ();
872
873 emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1));
874 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0]));
875 DONE;
876 }")
877 \f
878 ;; Move instructions
879
880 ;; Note that source operands for `mov' pseudo-instructions are no longer
881 ;; allowed (by the svr4 assembler) to be "big" things, i.e. constants that
882 ;; won't fit in 16-bits. (This includes any sort of a relocatable address
883 ;; also.) Thus, we must use an explicit orh/or pair of instructions if
884 ;; the source operand is something "big".
885
886 (define_insn "movsi"
887 [(set (match_operand:SI 0 "general_operand" "=r,m,f")
888 (match_operand:SI 1 "general_operand" "rmif,rfJ,rmfJ"))]
889 ""
890 "*
891 {
892 if (GET_CODE (operands[0]) == MEM)
893 {
894 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
895 return output_store (operands);
896 if (FP_REG_P (operands[1]))
897 return \"fst.l %1,%0\";
898 return \"st.l %r1,%0\";
899 }
900 if (GET_CODE (operands[1]) == MEM)
901 {
902 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
903 return output_load (operands);
904 if (FP_REG_P (operands[0]))
905 return \"fld.l %1,%0\";
906 return \"ld.l %1,%0\";
907 }
908 if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
909 return \"fmov.ss %1,%0\";
910 if (FP_REG_P (operands[1]))
911 return \"fxfr %1,%0\";
912 if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
913 return \"fmov.ss %?f0,%0\";
914 if (FP_REG_P (operands[0]))
915 return \"ixfr %1,%0\";
916
917 if (GET_CODE (operands[1]) == REG)
918 return \"shl %?r0,%1,%0\";
919
920 CC_STATUS_PARTIAL_INIT;
921
922 if (GET_CODE (operands[1]) == CONST_INT)
923 {
924 if((INTVAL (operands[1]) & 0xffff0000) == 0)
925 return \"or %L1,%?r0,%0\";
926 if((INTVAL (operands[1]) & 0x0000ffff) == 0)
927 return \"orh %H1,%?r0,%0\";
928 }
929 return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
930 }")
931
932 (define_insn "movhi"
933 [(set (match_operand:HI 0 "general_operand" "=r,m,!*f,!r")
934 (match_operand:HI 1 "general_operand" "rmi,rJ,rJ*f,*f"))]
935 ""
936 "*
937 {
938 if (GET_CODE (operands[0]) == MEM)
939 {
940 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
941 return output_store (operands);
942 return \"st.s %r1,%0\";
943 }
944 if (GET_CODE (operands[1]) == MEM)
945 {
946 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
947 return output_load (operands);
948 return \"ld.s %1,%0\";
949 }
950 if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
951 return \"fmov.ss %1,%0\";
952 if (FP_REG_P (operands[1]))
953 return \"fxfr %1,%0\";
954 if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
955 return \"fmov.ss %?f0,%0\";
956 if (FP_REG_P (operands[0]))
957 return \"ixfr %1,%0\";
958
959 if (GET_CODE (operands[1]) == REG)
960 return \"shl %?r0,%1,%0\";
961
962 CC_STATUS_PARTIAL_INIT;
963
964 return \"or %L1,%?r0,%0\";
965 }")
966
967 (define_insn "movqi"
968 [(set (match_operand:QI 0 "general_operand" "=r,m,!*f,!r")
969 (match_operand:QI 1 "general_operand" "rmi,rJ,rJ*f,*f"))]
970 ""
971 "*
972 {
973 if (GET_CODE (operands[0]) == MEM)
974 {
975 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
976 return output_store (operands);
977 return \"st.b %r1,%0\";
978 }
979 if (GET_CODE (operands[1]) == MEM)
980 {
981 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
982 return output_load (operands);
983 return \"ld.b %1,%0\";
984 }
985 if (FP_REG_P (operands[1]) && FP_REG_P (operands[0]))
986 return \"fmov.ss %1,%0\";
987 if (FP_REG_P (operands[1]))
988 return \"fxfr %1,%0\";
989 if (FP_REG_P (operands[0]) && operands[1] == const0_rtx)
990 return \"fmov.ss %?f0,%0\";
991 if (FP_REG_P (operands[0]))
992 return \"ixfr %1,%0\";
993
994 if (GET_CODE (operands[1]) == REG)
995 return \"shl %?r0,%1,%0\";
996
997 CC_STATUS_PARTIAL_INIT;
998
999 return \"or %L1,%?r0,%0\";
1000 }")
1001
1002 ;; The definition of this insn does not really explain what it does,
1003 ;; but it should suffice
1004 ;; that anything generated as this insn will be recognized as one
1005 ;; and that it won't successfully combine with anything.
1006 (define_expand "movstrsi"
1007 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
1008 (match_operand:BLK 1 "general_operand" ""))
1009 (use (match_operand:SI 2 "nonmemory_operand" ""))
1010 (use (match_operand:SI 3 "immediate_operand" ""))
1011 (clobber (match_dup 4))
1012 (clobber (match_dup 5))
1013 (clobber (match_dup 6))
1014 (clobber (match_dup 7))
1015 (clobber (match_dup 8))])]
1016 ""
1017 "
1018 {
1019 operands[4] = gen_reg_rtx (SImode);
1020 operands[5] = gen_reg_rtx (SImode);
1021 operands[6] = gen_reg_rtx (SImode);
1022 operands[7] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
1023 operands[8] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1024
1025 operands[0] = replace_equiv_address (operands[0], operands[7]);
1026 operands[1] = replace_equiv_address (operands[1], operands[8]);
1027 }")
1028
1029 (define_insn ""
1030 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
1031 (mem:BLK (match_operand:SI 1 "register_operand" "r")))
1032 (use (match_operand:SI 2 "general_operand" "rn"))
1033 (use (match_operand:SI 3 "immediate_operand" "i"))
1034 (clobber (match_operand:SI 4 "register_operand" "=r"))
1035 (clobber (match_operand:SI 5 "register_operand" "=r"))
1036 (clobber (match_operand:SI 6 "register_operand" "=r"))
1037 (clobber (match_dup 0))
1038 (clobber (match_dup 1))]
1039 ""
1040 "* return output_block_move (operands);")
1041 \f
1042 ;; Floating point move insns
1043
1044 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1045 ;; to be reloaded by putting the constant into memory.
1046 ;; It must come before the more general movdf pattern.
1047 (define_insn ""
1048 [(set (match_operand:DF 0 "general_operand" "=r,f,o")
1049 (match_operand:DF 1 "" "mG,m,G"))]
1050 "GET_CODE (operands[1]) == CONST_DOUBLE"
1051 "*
1052 {
1053 if (FP_REG_P (operands[0]) || operands[1] == CONST0_RTX (DFmode))
1054 return output_fp_move_double (operands);
1055 return output_move_double (operands);
1056 }")
1057
1058 (define_insn "movdf"
1059 [(set (match_operand:DF 0 "general_operand" "=*rm,*r,?f,?*rm")
1060 (match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))]
1061 ""
1062 "*
1063 {
1064 if (GET_CODE (operands[0]) == MEM
1065 && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1066 return output_store (operands);
1067 if (GET_CODE (operands[1]) == MEM
1068 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1069 return output_load (operands);
1070
1071 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1072 return output_fp_move_double (operands);
1073 return output_move_double (operands);
1074 }")
1075
1076 (define_insn "movdi"
1077 [(set (match_operand:DI 0 "general_operand" "=rm,r,?f,?rm")
1078 (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))]
1079 ""
1080 "*
1081 {
1082 if (GET_CODE (operands[0]) == MEM
1083 && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1084 return output_store (operands);
1085 if (GET_CODE (operands[1]) == MEM
1086 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1087 return output_load (operands);
1088
1089 /* ??? How can we have a DFmode arg here with DImode above? */
1090 if (FP_REG_P (operands[0]) && operands[1] == CONST0_RTX (DFmode))
1091 return \"fmov.dd %?f0,%0\";
1092
1093 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1094 return output_fp_move_double (operands);
1095 return output_move_double (operands);
1096 }")
1097
1098 ;; The alternative m/r is separate from m/f
1099 ;; The first alternative is separate from the second for the same reason.
1100 (define_insn "movsf"
1101 [(set (match_operand:SF 0 "general_operand" "=*rf,*rf,*r,m,m")
1102 (match_operand:SF 1 "general_operand" "*r,fmG,F,*r,f"))]
1103 ""
1104 "*
1105 {
1106 if (GET_CODE (operands[0]) == MEM
1107 && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1108 return output_store (operands);
1109 if (GET_CODE (operands[1]) == MEM
1110 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1111 return output_load (operands);
1112 if (FP_REG_P (operands[0]))
1113 {
1114 if (FP_REG_P (operands[1]))
1115 return \"fmov.ss %1,%0\";
1116 if (GET_CODE (operands[1]) == REG)
1117 return \"ixfr %1,%0\";
1118 if (operands[1] == CONST0_RTX (SFmode))
1119 return \"fmov.ss %?f0,%0\";
1120 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1121 {
1122 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1123 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1124 && cc_prev_status.mdep == XEXP(operands[1],0)))
1125 {
1126 CC_STATUS_INIT;
1127 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1128 cc_status.mdep = XEXP (operands[1], 0);
1129 return \"orh %h1,%?r0,%?r31\;fld.l %L1(%?r31),%0\";
1130 }
1131 return \"fld.l %L1(%?r31),%0\";
1132 }
1133 return \"fld.l %1,%0\";
1134 }
1135 if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
1136 {
1137 if (GET_CODE (operands[0]) == REG && FP_REG_P (operands[1]))
1138 return \"fxfr %1,%0\";
1139 if (GET_CODE (operands[0]) == REG)
1140 {
1141 CC_STATUS_PARTIAL_INIT;
1142 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1143 {
1144 register unsigned long ul;
1145
1146 ul = sfmode_constant_to_ulong (operands[1]);
1147 if ((ul & 0x0000ffff) == 0)
1148 return \"orh %H1,%?r0,%0\";
1149 if ((ul & 0xffff0000) == 0)
1150 return \"or %L1,%?r0,%0\";
1151 }
1152 return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
1153 }
1154 /* Now operand 0 must be memory.
1155 If operand 1 is CONST_DOUBLE, its value must be 0. */
1156 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1157 {
1158 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1159 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1160 && XEXP (operands[0], 0) == cc_prev_status.mdep))
1161 {
1162 CC_STATUS_INIT;
1163 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1164 cc_status.mdep = XEXP (operands[0], 0);
1165 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1166 }
1167 return \"fst.l %r1,%L0(%?r31)\";
1168 }
1169 return \"fst.l %r1,%0\";
1170 }
1171 if (GET_CODE (operands[0]) == MEM)
1172 return \"st.l %r1,%0\";
1173 if (GET_CODE (operands[1]) == MEM)
1174 return \"ld.l %1,%0\";
1175 if (operands[1] == CONST0_RTX (SFmode))
1176 return \"shl %?r0,%?r0,%0\";
1177 return \"mov %1,%0\";
1178 }")
1179 \f
1180 ;; Special load insns for REG+REG addresses.
1181 ;; Such addresses are not "legitimate" because st rejects them.
1182
1183 (define_insn ""
1184 [(set (match_operand:DF 0 "register_operand" "=rf")
1185 (match_operand:DF 1 "indexed_operand" "m"))]
1186 ""
1187 "*
1188 {
1189 if (FP_REG_P (operands[0]))
1190 return output_fp_move_double (operands);
1191 return output_move_double (operands);
1192 }")
1193
1194 (define_insn ""
1195 [(set (match_operand:SF 0 "register_operand" "=rf")
1196 (match_operand:SF 1 "indexed_operand" "m"))]
1197 ""
1198 "*
1199 {
1200 if (FP_REG_P (operands[0]))
1201 return \"fld.l %1,%0\";
1202 return \"ld.l %1,%0\";
1203 }")
1204
1205 (define_insn ""
1206 [(set (match_operand:SI 0 "register_operand" "=rf")
1207 (match_operand:SI 1 "indexed_operand" "m"))]
1208 ""
1209 "*
1210 {
1211 if (FP_REG_P (operands[0]))
1212 return \"fld.l %1,%0\";
1213 return \"ld.l %1,%0\";
1214 }")
1215
1216 (define_insn ""
1217 [(set (match_operand:HI 0 "register_operand" "=r")
1218 (match_operand:HI 1 "indexed_operand" "m"))]
1219 ""
1220 "ld.s %1,%0")
1221
1222 (define_insn ""
1223 [(set (match_operand:QI 0 "register_operand" "=r")
1224 (match_operand:QI 1 "indexed_operand" "m"))]
1225 ""
1226 "ld.b %1,%0")
1227
1228 ;; Likewise for floating-point store insns.
1229
1230 (define_insn ""
1231 [(set (match_operand:DF 0 "indexed_operand" "=m")
1232 (match_operand:DF 1 "register_operand" "f"))]
1233 ""
1234 "fst.d %1,%0")
1235
1236 (define_insn ""
1237 [(set (match_operand:SF 0 "indexed_operand" "=m")
1238 (match_operand:SF 1 "register_operand" "f"))]
1239 ""
1240 "fst.l %1,%0")
1241 \f
1242 ;;- truncation instructions
1243 (define_insn "truncsiqi2"
1244 [(set (match_operand:QI 0 "general_operand" "=g")
1245 (truncate:QI
1246 (match_operand:SI 1 "register_operand" "r")))]
1247 ""
1248 "*
1249 {
1250 if (GET_CODE (operands[0]) == MEM)
1251 {
1252 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1253 {
1254 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1255 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1256 && XEXP (operands[0], 0) == cc_prev_status.mdep))
1257 {
1258 CC_STATUS_INIT;
1259 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1260 cc_status.mdep = XEXP (operands[0], 0);
1261 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1262 }
1263 return \"st.b %1,%L0(%?r31)\";
1264 }
1265 else
1266 return \"st.b %1,%0\";
1267 }
1268 return \"shl %?r0,%1,%0\";
1269 }")
1270
1271 (define_insn "trunchiqi2"
1272 [(set (match_operand:QI 0 "general_operand" "=g")
1273 (truncate:QI
1274 (match_operand:HI 1 "register_operand" "r")))]
1275 ""
1276 "*
1277 {
1278 if (GET_CODE (operands[0]) == MEM)
1279 {
1280 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1281 {
1282 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1283 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1284 && XEXP (operands[0], 0) == cc_prev_status.mdep))
1285 {
1286 CC_STATUS_INIT;
1287 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1288 cc_status.mdep = XEXP (operands[0], 0);
1289 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1290 }
1291 return \"st.b %1,%L0(%?r31)\";
1292 }
1293 else
1294 return \"st.b %1,%0\";
1295 }
1296 return \"shl %?r0,%1,%0\";
1297 }")
1298
1299 (define_insn "truncsihi2"
1300 [(set (match_operand:HI 0 "general_operand" "=g")
1301 (truncate:HI
1302 (match_operand:SI 1 "register_operand" "r")))]
1303 ""
1304 "*
1305 {
1306 if (GET_CODE (operands[0]) == MEM)
1307 {
1308 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1309 {
1310 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1311 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1312 && XEXP (operands[0], 0) == cc_prev_status.mdep))
1313 {
1314 CC_STATUS_INIT;
1315 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1316 cc_status.mdep = XEXP (operands[0], 0);
1317 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1318 }
1319 return \"st.s %1,%L0(%?r31)\";
1320 }
1321 else
1322 return \"st.s %1,%0\";
1323 }
1324 return \"shl %?r0,%1,%0\";
1325 }")
1326 \f
1327 ;;- zero extension instructions
1328
1329 (define_insn "zero_extendhisi2"
1330 [(set (match_operand:SI 0 "register_operand" "=r")
1331 (zero_extend:SI
1332 (match_operand:HI 1 "register_operand" "r")))]
1333 ""
1334 "*
1335 {
1336 CC_STATUS_PARTIAL_INIT;
1337 return \"and 0xffff,%1,%0\";
1338 }")
1339
1340 (define_insn "zero_extendqihi2"
1341 [(set (match_operand:HI 0 "register_operand" "=r")
1342 (zero_extend:HI
1343 (match_operand:QI 1 "register_operand" "r")))]
1344 ""
1345 "*
1346 {
1347 CC_STATUS_PARTIAL_INIT;
1348 return \"and 0xff,%1,%0\";
1349 }")
1350
1351 (define_insn "zero_extendqisi2"
1352 [(set (match_operand:SI 0 "register_operand" "=r")
1353 (zero_extend:SI
1354 (match_operand:QI 1 "register_operand" "r")))]
1355 ""
1356 "*
1357 {
1358 CC_STATUS_PARTIAL_INIT;
1359 return \"and 0xff,%1,%0\";
1360 }")
1361 \f
1362 ;; Sign extension instructions.
1363
1364 (define_insn ""
1365 [(set (match_operand:SI 0 "register_operand" "=r")
1366 (sign_extend:SI
1367 (match_operand:HI 1 "indexed_operand" "m")))]
1368 ""
1369 "ld.s %1,%0")
1370
1371 (define_insn ""
1372 [(set (match_operand:HI 0 "register_operand" "=r")
1373 (sign_extend:HI
1374 (match_operand:QI 1 "indexed_operand" "m")))]
1375 ""
1376 "ld.b %1,%0")
1377
1378 (define_insn ""
1379 [(set (match_operand:SI 0 "register_operand" "=r")
1380 (sign_extend:SI
1381 (match_operand:QI 1 "indexed_operand" "m")))]
1382 ""
1383 "ld.b %1,%0")
1384
1385 (define_insn "extendhisi2"
1386 [(set (match_operand:SI 0 "register_operand" "=r")
1387 (sign_extend:SI
1388 (match_operand:HI 1 "nonimmediate_operand" "mr")))]
1389 ""
1390 "*
1391 {
1392 if (REG_P (operands[1]))
1393 return \"shl 16,%1,%0\;shra 16,%0,%0\";
1394 if (GET_CODE (operands[1]) == CONST_INT)
1395 abort ();
1396 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1397 {
1398 CC_STATUS_INIT;
1399 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1400 cc_status.mdep = XEXP (operands[1], 0);
1401 return \"orh %h1,%?r0,%?r31\;ld.s %L1(%?r31),%0\";
1402 }
1403 else
1404 return \"ld.s %1,%0\";
1405 }")
1406
1407 (define_insn "extendqihi2"
1408 [(set (match_operand:HI 0 "register_operand" "=r")
1409 (sign_extend:HI
1410 (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1411 ""
1412 "*
1413 {
1414 if (REG_P (operands[1]))
1415 return \"shl 24,%1,%0\;shra 24,%0,%0\";
1416 if (GET_CODE (operands[1]) == CONST_INT)
1417 abort ();
1418 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1419 {
1420 CC_STATUS_INIT;
1421 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1422 cc_status.mdep = XEXP (operands[1], 0);
1423 return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1424 }
1425 else
1426 return \"ld.b %1,%0\";
1427 }")
1428
1429 (define_insn "extendqisi2"
1430 [(set (match_operand:SI 0 "register_operand" "=r")
1431 (sign_extend:SI
1432 (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1433 ""
1434 "*
1435 {
1436 if (REG_P (operands[1]))
1437 return \"shl 24,%1,%0\;shra 24,%0,%0\";
1438 if (GET_CODE (operands[1]) == CONST_INT)
1439 abort ();
1440 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1441 {
1442 CC_STATUS_INIT;
1443 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1444 cc_status.mdep = XEXP (operands[1], 0);
1445 return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1446 }
1447 else
1448 return \"ld.b %1,%0\";
1449 }")
1450
1451 ;; Signed bitfield extractions come out looking like
1452 ;; (shiftrt (sign_extend (shift <Y> <C1>)) <C2>)
1453 ;; which we expand poorly as four shift insns.
1454 ;; These patterns yield two shifts:
1455 ;; (shiftrt (shift <Y> <C3>) <C4>)
1456 (define_insn ""
1457 [(set (match_operand:SI 0 "register_operand" "=r")
1458 (ashiftrt:SI
1459 (sign_extend:SI
1460 (match_operand:QI 1 "register_operand" "r"))
1461 (match_operand:SI 2 "logic_int" "n")))]
1462 "INTVAL (operands[2]) < 8"
1463 "*
1464 {
1465 return \"shl 24,%1,%0\;shra 24+%2,%0,%0\";
1466 }")
1467
1468 (define_insn ""
1469 [(set (match_operand:SI 0 "register_operand" "=r")
1470 (ashiftrt:SI
1471 (sign_extend:SI
1472 (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1473 (match_operand:SI 2 "logic_int" "n")) 0))
1474 (match_operand:SI 3 "logic_int" "n")))]
1475 "INTVAL (operands[3]) < 8"
1476 "*
1477 {
1478 return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1479 }")
1480
1481 (define_insn ""
1482 [(set (match_operand:SI 0 "register_operand" "=r")
1483 (ashiftrt:SI
1484 (sign_extend:SI
1485 (ashift:QI (match_operand:QI 1 "register_operand" "r")
1486 (match_operand:QI 2 "logic_int" "n")))
1487 (match_operand:SI 3 "logic_int" "n")))]
1488 "INTVAL (operands[3]) < 8"
1489 "*
1490 {
1491 return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1492 }")
1493 \f
1494 ;; Special patterns for optimizing bit-field instructions.
1495
1496 ;; First two patterns are for bitfields that came from memory
1497 ;; testing only the high bit. They work with old combiner.
1498
1499 (define_insn ""
1500 [(set (cc0)
1501 (eq (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1502 (const_int 7)) 0))
1503 (const_int 0)))]
1504 ""
1505 "*
1506 {
1507 CC_STATUS_PARTIAL_INIT;
1508 return \"and 128,%0,%?r0\";
1509 }")
1510
1511 (define_insn ""
1512 [(set (cc0)
1513 (eq (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1514 (const_int 7)) 0))
1515 (const_int 0)))]
1516 ""
1517 "*
1518 {
1519 CC_STATUS_PARTIAL_INIT;
1520 return \"and 128,%0,%?r0\";
1521 }")
1522
1523 ;; next two patterns are good for bitfields coming from memory
1524 ;; (via pseudo-register) or from a register, though this optimization
1525 ;; is only good for values contained wholly within the bottom 13 bits
1526 (define_insn ""
1527 [(set (cc0)
1528 (eq
1529 (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1530 (match_operand:SI 1 "logic_int" "n"))
1531 (match_operand:SI 2 "logic_int" "n"))
1532 (const_int 0)))]
1533 "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1534 "*
1535 {
1536 CC_STATUS_PARTIAL_INIT;
1537 operands[2] = GEN_INT (INTVAL (operands[2]) << INTVAL (operands[1]));
1538 return \"and %2,%0,%?r0\";
1539 }")
1540
1541 (define_insn ""
1542 [(set (cc0)
1543 (eq
1544 (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1545 (match_operand:SI 1 "logic_int" "n"))
1546 (match_operand:SI 2 "logic_int" "n"))
1547 (const_int 0)))]
1548 "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1549 "*
1550 {
1551 CC_STATUS_PARTIAL_INIT;
1552 operands[2] = GEN_INT (INTVAL (operands[2]) << INTVAL (operands[1]));
1553 return \"and %2,%0,%?r0\";
1554 }")
1555 \f
1556 ;; Conversions between float and double.
1557
1558 (define_insn "extendsfdf2"
1559 [(set (match_operand:DF 0 "register_operand" "=f")
1560 (float_extend:DF
1561 (match_operand:SF 1 "register_operand" "f")))]
1562 ""
1563 "fmov.sd %1,%0")
1564
1565 (define_insn "truncdfsf2"
1566 [(set (match_operand:SF 0 "register_operand" "=f")
1567 (float_truncate:SF
1568 (match_operand:DF 1 "register_operand" "f")))]
1569 ""
1570 "fmov.ds %1,%0")
1571 \f
1572 ;; Conversion between fixed point and floating point.
1573 ;; Note that among the fix-to-float insns
1574 ;; the ones that start with SImode come first.
1575 ;; That is so that an operand that is a CONST_INT
1576 ;; (and therefore lacks a specific machine mode).
1577 ;; will be recognized as SImode (which is always valid)
1578 ;; rather than as QImode or HImode.
1579
1580 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
1581 ;; to be reloaded by putting the constant into memory.
1582 ;; It must come before the more general floatsisf2 pattern.
1583 (define_expand "floatsidf2"
1584 [(set (match_dup 2) (match_dup 3))
1585 (set (match_dup 4) (xor:SI (match_operand:SI 1 "register_operand" "")
1586 (const_int -2147483648)))
1587 (set (match_dup 5) (match_dup 3))
1588 (set (subreg:SI (match_dup 5) 0) (match_dup 4))
1589 (set (match_operand:DF 0 "register_operand" "")
1590 (minus:DF (match_dup 5) (match_dup 2)))]
1591 ""
1592 "
1593 {
1594 REAL_VALUE_TYPE d;
1595 /* 4503601774854144 is (1 << 30) * ((1 << 22) + (1 << 1)). */
1596 d = REAL_VALUE_ATOF (\"4503601774854144\", DFmode);
1597 operands[2] = gen_reg_rtx (DFmode);
1598 operands[3] = CONST_DOUBLE_FROM_REAL_VALUE (d, DFmode);
1599 operands[4] = gen_reg_rtx (SImode);
1600 operands[5] = gen_reg_rtx (DFmode);
1601 }")
1602 \f
1603 ;; Floating to fixed conversion.
1604
1605 (define_expand "fix_truncdfsi2"
1606 ;; This first insn produces a double-word value
1607 ;; in which only the low word is valid.
1608 [(set (match_dup 2)
1609 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1610 (set (match_operand:SI 0 "register_operand" "=f")
1611 (subreg:SI (match_dup 2) 0))]
1612 ""
1613 "
1614 {
1615 operands[2] = gen_reg_rtx (DImode);
1616 }")
1617
1618 ;; Recognize the first insn generated above.
1619 ;; This RTL looks like a fix_truncdfdi2 insn,
1620 ;; but we don't call it that, because only 32 bits
1621 ;; of the result are valid.
1622 ;; This pattern will work for the intended purposes
1623 ;; as long as we do not have any fixdfdi2 or fix_truncdfdi2.
1624 (define_insn ""
1625 [(set (match_operand:DI 0 "register_operand" "=f")
1626 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1627 ""
1628 "ftrunc.dd %1,%0")
1629
1630 (define_expand "fix_truncsfsi2"
1631 ;; This first insn produces a double-word value
1632 ;; in which only the low word is valid.
1633 [(set (match_dup 2)
1634 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
1635 (set (match_operand:SI 0 "register_operand" "=f")
1636 (subreg:SI (match_dup 2) 0))]
1637 ""
1638 "
1639 {
1640 operands[2] = gen_reg_rtx (DImode);
1641 }")
1642
1643 ;; Recognize the first insn generated above.
1644 ;; This RTL looks like a fix_truncsfdi2 insn,
1645 ;; but we don't call it that, because only 32 bits
1646 ;; of the result are valid.
1647 ;; This pattern will work for the intended purposes
1648 ;; as long as we do not have any fixsfdi2 or fix_truncsfdi2.
1649 (define_insn ""
1650 [(set (match_operand:DI 0 "register_operand" "=f")
1651 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1652 ""
1653 "ftrunc.sd %1,%0")
1654 \f
1655 ;;- arithmetic instructions
1656
1657 (define_insn "addsi3"
1658 [(set (match_operand:SI 0 "register_operand" "=r,*f")
1659 (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,*f")
1660 (match_operand:SI 2 "arith_operand" "rI,*f")))]
1661 ""
1662 "*
1663 {
1664 if (which_alternative == 1)
1665 return \"fiadd.ss %2,%1,%0\";
1666 CC_STATUS_PARTIAL_INIT;
1667 return \"addu %2,%1,%0\";
1668 }")
1669
1670 (define_insn "adddi3"
1671 [(set (match_operand:DI 0 "register_operand" "=f")
1672 (plus:DI (match_operand:DI 1 "register_operand" "%f")
1673 (match_operand:DI 2 "register_operand" "f")))]
1674 ""
1675 "fiadd.dd %1,%2,%0")
1676
1677 (define_insn "subsi3"
1678 [(set (match_operand:SI 0 "register_operand" "=r,r,*f")
1679 (minus:SI (match_operand:SI 1 "register_operand" "r,I,*f")
1680 (match_operand:SI 2 "arith_operand" "rI,r,*f")))]
1681 ""
1682 "*
1683 {
1684 if (which_alternative == 2)
1685 return \"fisub.ss %1,%2,%0\";
1686 CC_STATUS_PARTIAL_INIT;
1687 if (REG_P (operands[2]))
1688 return \"subu %1,%2,%0\";
1689 operands[2] = GEN_INT (- INTVAL (operands[2]));
1690 return \"addu %2,%1,%0\";
1691 }")
1692
1693 (define_insn "subdi3"
1694 [(set (match_operand:DI 0 "register_operand" "=f")
1695 (minus:DI (match_operand:DI 1 "register_operand" "f")
1696 (match_operand:DI 2 "register_operand" "f")))]
1697 ""
1698 "fisub.dd %1,%2,%0")
1699
1700 (define_expand "mulsi3"
1701 [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1702 (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1703 (clobber (match_dup 3))
1704 (set (subreg:SI (match_dup 3) 0)
1705 (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1706 (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1707 ""
1708 "
1709 {
1710 if (WORDS_BIG_ENDIAN)
1711 emit_insn (gen_mulsi3_big (operands[0], operands[1], operands[2]));
1712 else
1713 emit_insn (gen_mulsi3_little (operands[0], operands[1], operands[2]));
1714 DONE;
1715 }")
1716
1717 (define_expand "mulsi3_little"
1718 [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1719 (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1720 (clobber (match_dup 3))
1721 (set (subreg:SI (match_dup 3) 0)
1722 (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1723 (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1724 "! WORDS_BIG_ENDIAN"
1725 "
1726 {
1727 operands[3] = gen_reg_rtx (DImode);
1728 operands[4] = gen_reg_rtx (DImode);
1729 operands[5] = gen_reg_rtx (DImode);
1730 }")
1731
1732 (define_expand "mulsi3_big"
1733 [(set (subreg:SI (match_dup 4) 4) (match_operand:SI 1 "general_operand" ""))
1734 (set (subreg:SI (match_dup 5) 4) (match_operand:SI 2 "general_operand" ""))
1735 (clobber (match_dup 3))
1736 (set (subreg:SI (match_dup 3) 4)
1737 (mult:SI (subreg:SI (match_dup 4) 4) (subreg:SI (match_dup 5) 4)))
1738 (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 4))]
1739 "WORDS_BIG_ENDIAN"
1740 "
1741 {
1742 operands[3] = gen_reg_rtx (DImode);
1743 operands[4] = gen_reg_rtx (DImode);
1744 operands[5] = gen_reg_rtx (DImode);
1745 }")
1746
1747 (define_insn ""
1748 [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0)
1749 (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0)
1750 (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))]
1751 "! WORDS_BIG_ENDIAN"
1752 "fmlow.dd %2,%1,%0")
1753
1754 (define_insn ""
1755 [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 4)
1756 (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 4)
1757 (subreg:SI (match_operand:DI 2 "register_operand" "f") 4)))]
1758 "WORDS_BIG_ENDIAN"
1759 "fmlow.dd %2,%1,%0")
1760 \f
1761 ;;- and instructions (with compliment also)
1762 (define_insn "andsi3"
1763 [(set (match_operand:SI 0 "register_operand" "=r")
1764 (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1765 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1766 ""
1767 "*
1768 {
1769 rtx xop[3];
1770
1771 CC_STATUS_PARTIAL_INIT;
1772 if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1773 return \"and %2,%1,%0\";
1774 if ((INTVAL (operands[2]) & 0xffff) == 0)
1775 {
1776 operands[2]
1777 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1778 return \"andh %2,%1,%0\";
1779 }
1780 xop[0] = operands[0];
1781 xop[1] = operands[1];
1782 xop[2] = GEN_INT (~INTVAL (operands[2]) & 0xffff);
1783 output_asm_insn (\"andnot %2,%1,%0\", xop);
1784 operands[2] = GEN_INT (~(unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1785 return \"andnoth %2,%0,%0\";
1786 }")
1787
1788 (define_insn ""
1789 [(set (match_operand:SI 0 "register_operand" "=r")
1790 (and:SI (not:SI (match_operand:SI 1 "register_operand" "rn"))
1791 (match_operand:SI 2 "register_operand" "r")))]
1792 ""
1793 "*
1794 {
1795 rtx xop[3];
1796
1797 CC_STATUS_PARTIAL_INIT;
1798 if (REG_P (operands[1]) || LOGIC_INT (operands[1]))
1799 return \"andnot %1,%2,%0\";
1800 if ((INTVAL (operands[1]) & 0xffff) == 0)
1801 {
1802 operands[1]
1803 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[1]) >> 16);
1804 return \"andnoth %1,%2,%0\";
1805 }
1806 xop[0] = operands[0];
1807 xop[1] = GEN_INT (INTVAL (operands[1]) & 0xffff);
1808 xop[2] = operands[2];
1809 output_asm_insn (\"andnot %1,%2,%0\", xop);
1810 operands[1] = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[1]) >> 16);
1811 return \"andnoth %1,%0,%0\";
1812 }")
1813
1814 (define_insn "iorsi3"
1815 [(set (match_operand:SI 0 "register_operand" "=r")
1816 (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1817 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1818 ""
1819 "*
1820 {
1821 rtx xop[3];
1822
1823 CC_STATUS_PARTIAL_INIT;
1824 if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1825 return \"or %2,%1,%0\";
1826 if ((INTVAL (operands[2]) & 0xffff) == 0)
1827 {
1828 operands[2]
1829 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1830 return \"orh %2,%1,%0\";
1831 }
1832 xop[0] = operands[0];
1833 xop[1] = operands[1];
1834 xop[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1835 output_asm_insn (\"or %2,%1,%0\", xop);
1836 operands[2] = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1837 return \"orh %2,%0,%0\";
1838 }")
1839
1840 (define_insn "xorsi3"
1841 [(set (match_operand:SI 0 "register_operand" "=r")
1842 (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1843 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1844 ""
1845 "*
1846 {
1847 rtx xop[3];
1848
1849 CC_STATUS_PARTIAL_INIT;
1850 if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1851 return \"xor %2,%1,%0\";
1852 if ((INTVAL (operands[2]) & 0xffff) == 0)
1853 {
1854 operands[2]
1855 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1856 return \"xorh %2,%1,%0\";
1857 }
1858 xop[0] = operands[0];
1859 xop[1] = operands[1];
1860 xop[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
1861 output_asm_insn (\"xor %2,%1,%0\", xop);
1862 operands[2] = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) >> 16);
1863 return \"xorh %2,%0,%0\";
1864 }")
1865
1866 ;(The i860 instruction set doesn't allow an immediate second operand in
1867 ; a subtraction.)
1868 (define_insn "negsi2"
1869 [(set (match_operand:SI 0 "general_operand" "=r")
1870 (neg:SI (match_operand:SI 1 "arith_operand" "r")))]
1871 ""
1872 "*
1873 {
1874 CC_STATUS_PARTIAL_INIT;
1875 return \"subu %?r0,%1,%0\";
1876 }")
1877
1878 (define_insn "one_cmplsi2"
1879 [(set (match_operand:SI 0 "general_operand" "=r")
1880 (not:SI (match_operand:SI 1 "arith_operand" "r")))]
1881 ""
1882 "*
1883 {
1884 CC_STATUS_PARTIAL_INIT;
1885 return \"subu -1,%1,%0\";
1886 }")
1887 \f
1888 ;; Floating point arithmetic instructions.
1889
1890 (define_insn "adddf3"
1891 [(set (match_operand:DF 0 "register_operand" "=f")
1892 (plus:DF (match_operand:DF 1 "register_operand" "f")
1893 (match_operand:DF 2 "register_operand" "f")))]
1894 ""
1895 "fadd.dd %1,%2,%0")
1896
1897 (define_insn "addsf3"
1898 [(set (match_operand:SF 0 "register_operand" "=f")
1899 (plus:SF (match_operand:SF 1 "register_operand" "f")
1900 (match_operand:SF 2 "register_operand" "f")))]
1901 ""
1902 "fadd.ss %1,%2,%0")
1903
1904 (define_insn "subdf3"
1905 [(set (match_operand:DF 0 "register_operand" "=f")
1906 (minus:DF (match_operand:DF 1 "register_operand" "f")
1907 (match_operand:DF 2 "register_operand" "f")))]
1908 ""
1909 "fsub.dd %1,%2,%0")
1910
1911 (define_insn "subsf3"
1912 [(set (match_operand:SF 0 "register_operand" "=f")
1913 (minus:SF (match_operand:SF 1 "register_operand" "f")
1914 (match_operand:SF 2 "register_operand" "f")))]
1915 ""
1916 "fsub.ss %1,%2,%0")
1917
1918 (define_insn "muldf3"
1919 [(set (match_operand:DF 0 "register_operand" "=f")
1920 (mult:DF (match_operand:DF 1 "register_operand" "f")
1921 (match_operand:DF 2 "register_operand" "f")))]
1922 ""
1923 "fmul.dd %1,%2,%0")
1924
1925 (define_insn "mulsf3"
1926 [(set (match_operand:SF 0 "register_operand" "=f")
1927 (mult:SF (match_operand:SF 1 "register_operand" "f")
1928 (match_operand:SF 2 "register_operand" "f")))]
1929 ""
1930 "fmul.ss %1,%2,%0")
1931
1932 (define_insn "negdf2"
1933 [(set (match_operand:DF 0 "register_operand" "=f")
1934 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1935 ""
1936 "fsub.dd %?f0,%1,%0")
1937
1938 (define_insn "negsf2"
1939 [(set (match_operand:SF 0 "register_operand" "=f")
1940 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1941 ""
1942 "fsub.ss %?f0,%1,%0")
1943 \f
1944 (define_insn "divdf3"
1945 [(set (match_operand:DF 0 "register_operand" "=&f")
1946 (div:DF (match_operand:DF 1 "register_operand" "f")
1947 (match_operand:DF 2 "register_operand" "f")))
1948 (clobber (match_scratch:DF 3 "=&f"))
1949 (clobber (match_scratch:DF 4 "=&f"))]
1950 ""
1951 "*
1952 {
1953 CC_STATUS_PARTIAL_INIT;
1954 if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1955 || (cc_prev_status.flags & CC_HI_R31_ADJ)
1956 || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1957 {
1958 cc_status.flags |= CC_KNOW_HI_R31;
1959 cc_status.flags &= ~CC_HI_R31_ADJ;
1960 cc_status.mdep = CONST2_RTX (SFmode);
1961 return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\
1962 orh 0x4000,%?r0,%?r31\;ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\
1963 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\
1964 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\
1965 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1966 }
1967 else
1968 return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\
1969 ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\
1970 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\
1971 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\
1972 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1973 }")
1974
1975 (define_insn "divsf3"
1976 [(set (match_operand:SF 0 "register_operand" "=&f")
1977 (div:SF (match_operand:SF 1 "register_operand" "f")
1978 (match_operand:SF 2 "register_operand" "f")))
1979 (clobber (match_scratch:SF 3 "=&f"))
1980 (clobber (match_scratch:SF 4 "=&f"))]
1981 ""
1982 "*
1983 {
1984 CC_STATUS_PARTIAL_INIT;
1985 if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1986 || (cc_prev_status.flags & CC_HI_R31_ADJ)
1987 || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1988 {
1989 cc_status.flags |= CC_KNOW_HI_R31;
1990 cc_status.flags &= ~CC_HI_R31_ADJ;
1991 cc_status.mdep = CONST2_RTX (SFmode);
1992 output_asm_insn (\"orh 0x4000,%?r0,%?r31\", operands);
1993 }
1994 return \"ixfr %?r31,%4\;frcp.ss %2,%0\;\\
1995 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;fmul.ss %0,%3,%0\;\\
1996 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;\\
1997 fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\";
1998 }")
1999 \f
2000 ;; Shift instructions
2001
2002 ;; Optimized special case of shifting.
2003 ;; Must precede the general case.
2004
2005 (define_insn ""
2006 [(set (match_operand:SI 0 "register_operand" "=r")
2007 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2008 (const_int 24)))]
2009 ""
2010 "*
2011 {
2012 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
2013 {
2014 CC_STATUS_INIT;
2015 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
2016 cc_status.mdep = XEXP (operands[1], 0);
2017 return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
2018 }
2019 return \"ld.b %1,%0\";
2020 }")
2021
2022 \f
2023 ;;- arithmetic shift instructions
2024 (define_insn "ashlsi3"
2025 [(set (match_operand:SI 0 "register_operand" "=r")
2026 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2027 (match_operand:SI 2 "shift_operand" "rn")))]
2028 ""
2029 "*
2030 {
2031 return \"shl %2,%1,%0\";
2032 }")
2033
2034 (define_insn "ashlhi3"
2035 [(set (match_operand:HI 0 "register_operand" "=r")
2036 (ashift:HI (match_operand:HI 1 "register_operand" "r")
2037 (match_operand:HI 2 "shift_operand" "rn")))]
2038 ""
2039 "*
2040 {
2041 return \"shl %2,%1,%0\";
2042 }")
2043
2044 (define_insn "ashlqi3"
2045 [(set (match_operand:QI 0 "register_operand" "=r")
2046 (ashift:QI (match_operand:QI 1 "register_operand" "r")
2047 (match_operand:QI 2 "shift_operand" "rn")))]
2048 ""
2049 "*
2050 {
2051 return \"shl %2,%1,%0\";
2052 }")
2053
2054 (define_insn "ashrsi3"
2055 [(set (match_operand:SI 0 "register_operand" "=r")
2056 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2057 (match_operand:SI 2 "shift_operand" "rn")))]
2058 ""
2059 "*
2060 {
2061 return \"shra %2,%1,%0\";
2062 }")
2063
2064 (define_insn "lshrsi3"
2065 [(set (match_operand:SI 0 "register_operand" "=r")
2066 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2067 (match_operand:SI 2 "shift_operand" "rn")))]
2068 ""
2069 "*
2070 {
2071 return \"shr %2,%1,%0\";
2072 }")
2073 \f
2074 ;; Unconditional and other jump instructions
2075
2076 (define_insn "jump"
2077 [(set (pc) (label_ref (match_operand 0 "" "")))]
2078 ""
2079 "*
2080 {
2081 return \"br %l0\;nop\";
2082 }")
2083
2084 ;; Here are two simple peepholes which fill the delay slot of
2085 ;; an unconditional branch.
2086 ;
2087 ;; ??? All disabled, because output_delayed_branch is a crock
2088 ;; that will reliably segfault. This should be using the dbr
2089 ;; pass in any case. Anyone who cares is welcome to fix it.
2090 ;
2091 ;(define_peephole
2092 ; [(set (match_operand:SI 0 "register_operand" "=rf")
2093 ; (match_operand:SI 1 "single_insn_src_p" "gfG"))
2094 ; (set (pc) (label_ref (match_operand 2 "" "")))]
2095 ; ""
2096 ; "* return output_delayed_branch (\"br %l2\", operands, insn);")
2097 ;
2098 ;(define_peephole
2099 ; [(set (match_operand:SI 0 "memory_operand" "=m")
2100 ; (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2101 ; (set (pc) (label_ref (match_operand 2 "" "")))]
2102 ; ""
2103 ; "* return output_delayed_branch (\"br %l2\", operands, insn);")
2104
2105 (define_insn "tablejump"
2106 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2107 (use (label_ref (match_operand 1 "" "")))]
2108 ""
2109 "bri %0\;nop")
2110
2111 ;(define_peephole
2112 ; [(set (match_operand:SI 0 "memory_operand" "=m")
2113 ; (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2114 ; (set (pc) (match_operand:SI 2 "register_operand" "r"))
2115 ; (use (label_ref (match_operand 3 "" "")))]
2116 ; ""
2117 ; "* return output_delayed_branch (\"bri %2\", operands, insn);")
2118
2119 ;;- jump to subroutine
2120 (define_expand "call"
2121 [(call (match_operand:SI 0 "memory_operand" "m")
2122 (match_operand 1 "" "i"))]
2123 ;; operand[2] is next_arg_register
2124 ""
2125 "
2126 {
2127 /* Make sure the address is just one reg and will stay that way. */
2128 if (! call_insn_operand (operands[0], QImode))
2129 operands[0]
2130 = replace_equiv_address (operands[0],
2131 copy_to_mode_reg (Pmode,
2132 XEXP (operands[0], 0)));
2133 if (INTVAL (operands[1]) > 0)
2134 {
2135 emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2136 emit_insn (gen_rtx_USE (VOIDmode, arg_pointer_rtx));
2137 }
2138 }")
2139
2140 ;;- jump to subroutine
2141 (define_insn ""
2142 [(call (match_operand:SI 0 "call_insn_operand" "m")
2143 (match_operand 1 "" "i"))]
2144 ;; operand[2] is next_arg_register
2145 ""
2146 "*
2147 {
2148 /* strip the MEM. */
2149 operands[0] = XEXP (operands[0], 0);
2150 CC_STATUS_INIT;
2151 if (GET_CODE (operands[0]) == REG)
2152 return \"calli %0\;nop\";
2153 return \"call %0\;nop\";
2154 }")
2155
2156 ;(define_peephole
2157 ; [(set (match_operand:SI 0 "register_operand" "=rf")
2158 ; (match_operand:SI 1 "single_insn_src_p" "gfG"))
2159 ; (call (match_operand:SI 2 "memory_operand" "m")
2160 ; (match_operand 3 "" "i"))]
2161 ; ;;- Don't use operand 1 for most machines.
2162 ; "! reg_mentioned_p (operands[0], operands[2])"
2163 ; "*
2164 ;{
2165 ; /* strip the MEM. */
2166 ; operands[2] = XEXP (operands[2], 0);
2167 ; if (GET_CODE (operands[2]) == REG)
2168 ; return output_delayed_branch (\"calli %2\", operands, insn);
2169 ; return output_delayed_branch (\"call %2\", operands, insn);
2170 ;}")
2171
2172 ;(define_peephole
2173 ; [(set (match_operand:SI 0 "memory_operand" "=m")
2174 ; (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2175 ; (call (match_operand:SI 2 "call_insn_operand" "m")
2176 ; (match_operand 3 "" "i"))]
2177 ; ;;- Don't use operand 1 for most machines.
2178 ; ""
2179 ; "*
2180 ;{
2181 ; /* strip the MEM. */
2182 ; operands[2] = XEXP (operands[2], 0);
2183 ; if (GET_CODE (operands[2]) == REG)
2184 ; return output_delayed_branch (\"calli %2\", operands, insn);
2185 ; return output_delayed_branch (\"call %2\", operands, insn);
2186 ;}")
2187
2188 (define_expand "call_value"
2189 [(set (match_operand 0 "register_operand" "=rf")
2190 (call (match_operand:SI 1 "memory_operand" "m")
2191 (match_operand 2 "" "i")))]
2192 ;; operand 3 is next_arg_register
2193 ""
2194 "
2195 {
2196 /* Make sure the address is just one reg and will stay that way. */
2197 if (! call_insn_operand (operands[1], QImode))
2198 operands[1]
2199 = replace_equiv_address (operands[1],
2200 copy_to_mode_reg (Pmode,
2201 XEXP (operands[1], 0)));
2202 if (INTVAL (operands[2]) > 0)
2203 {
2204 emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2205 emit_insn (gen_rtx_USE (VOIDmode, arg_pointer_rtx));
2206 }
2207 }")
2208
2209 (define_insn ""
2210 [(set (match_operand 0 "register_operand" "=rf")
2211 (call (match_operand:SI 1 "call_insn_operand" "m")
2212 (match_operand 2 "" "i")))]
2213 ;; operand 3 is next_arg_register
2214 ""
2215 "*
2216 {
2217 /* strip the MEM. */
2218 operands[1] = XEXP (operands[1], 0);
2219 CC_STATUS_INIT;
2220 if (GET_CODE (operands[1]) == REG)
2221 return \"calli %1\;nop\";
2222 return \"call %1\;nop\";
2223 }")
2224
2225 ;(define_peephole
2226 ; [(set (match_operand:SI 0 "register_operand" "=rf")
2227 ; (match_operand:SI 1 "single_insn_src_p" "gfG"))
2228 ; (set (match_operand 2 "" "=rf")
2229 ; (call (match_operand:SI 3 "call_insn_operand" "m")
2230 ; (match_operand 4 "" "i")))]
2231 ; ;;- Don't use operand 4 for most machines.
2232 ; "! reg_mentioned_p (operands[0], operands[3])"
2233 ; "*
2234 ;{
2235 ; /* strip the MEM. */
2236 ; operands[3] = XEXP (operands[3], 0);
2237 ; if (GET_CODE (operands[3]) == REG)
2238 ; return output_delayed_branch (\"calli %3\", operands, insn);
2239 ; return output_delayed_branch (\"call %3\", operands, insn);
2240 ;}")
2241
2242 ;(define_peephole
2243 ; [(set (match_operand:SI 0 "memory_operand" "=m")
2244 ; (match_operand:SI 1 "reg_or_0_operand" "rJf"))
2245 ; (set (match_operand 2 "" "=rf")
2246 ; (call (match_operand:SI 3 "call_insn_operand" "m")
2247 ; (match_operand 4 "" "i")))]
2248 ; ;;- Don't use operand 4 for most machines.
2249 ; ""
2250 ; "*
2251 ;{
2252 ; /* strip the MEM. */
2253 ; operands[3] = XEXP (operands[3], 0);
2254 ; if (GET_CODE (operands[3]) == REG)
2255 ; return output_delayed_branch (\"calli %3\", operands, insn);
2256 ; return output_delayed_branch (\"call %3\", operands, insn);
2257 ;}")
2258
2259 ;; Call subroutine returning any type.
2260
2261 (define_expand "untyped_call"
2262 [(parallel [(call (match_operand 0 "" "")
2263 (const_int 0))
2264 (match_operand 1 "" "")
2265 (match_operand 2 "" "")])]
2266 ""
2267 "
2268 {
2269 int i;
2270
2271 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
2272
2273 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2274 {
2275 rtx set = XVECEXP (operands[2], 0, i);
2276 emit_move_insn (SET_DEST (set), SET_SRC (set));
2277 }
2278
2279 /* The optimizer does not know that the call sets the function value
2280 registers we stored in the result block. We avoid problems by
2281 claiming that all hard registers are used and clobbered at this
2282 point. */
2283 emit_insn (gen_blockage ());
2284
2285 DONE;
2286 }")
2287
2288 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2289 ;; all of memory. This blocks insns from being moved across this point.
2290
2291 (define_insn "blockage"
2292 [(unspec_volatile [(const_int 0)] 0)]
2293 ""
2294 "")
2295 \f
2296 (define_insn "nop"
2297 [(const_int 0)]
2298 ""
2299 "nop")
2300
2301 (define_insn "indirect_jump"
2302 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2303 ""
2304 "bri %0")
2305 \f
2306 ;;
2307 ;; A special insn that does the work to get setup just
2308 ;; before a table jump.
2309 ;;
2310 (define_insn ""
2311 [(set (match_operand:SI 0 "register_operand" "=r")
2312 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2313 (label_ref (match_operand 2 "" "")))))]
2314 ""
2315 "*
2316 {
2317 CC_STATUS_INIT;
2318 return \"orh %H2,%?r0,%?r31\;or %L2,%?r31,%?r31\;ld.l %?r31(%1),%0\";
2319 }")
2320
2321 ;(define_peephole
2322 ; [(set (match_operand:SI 0 "register_operand" "=rf")
2323 ; (match_operand:SI 1 "single_insn_src_p" "gfG"))
2324 ; (set (pc) (match_operand:SI 2 "register_operand" "r"))
2325 ; (use (label_ref (match_operand 3 "" "")))]
2326 ; "REGNO (operands[0]) != REGNO (operands[2])"
2327 ; "* return output_delayed_branch (\"bri %2\", operands, insn);")