Change FSF address.
[gcc.git] / gcc / config / i860 / i860.md
1 ;;- Machine description for Intel 860 chip for GNU C compiler
2 ;; Copyright (C) 1989, 1990 Free Software Foundation, Inc.
3
4 ;; This file is part of GNU CC.
5
6 ;; GNU CC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 2, or (at your option)
9 ;; any later version.
10
11 ;; GNU CC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
15
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GNU CC; see the file COPYING. If not, write to
18 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
19 ;; Boston, MA 02111-1307, USA.
20
21
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23
24 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
25 ;;- updates for most instructions.
26
27 ;;- Operand classes for the register allocator:
28 \f
29 /* Bit-test instructions. */
30
31 (define_insn ""
32 [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
33 (match_operand:SI 1 "logic_operand" "rL"))
34 (const_int 0)))]
35 ""
36 "*
37 {
38 CC_STATUS_PARTIAL_INIT;
39 return \"and %1,%0,%?r0\";
40 }")
41
42 (define_insn ""
43 [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")
44 (match_operand:SI 1 "logic_operand" "rL"))
45 (const_int 0)))]
46 ""
47 "*
48 {
49 CC_STATUS_PARTIAL_INIT;
50 cc_status.flags |= CC_NEGATED;
51 return \"and %1,%0,%?r0\";
52 }")
53
54 (define_insn ""
55 [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r")
56 (match_operand:SI 1 "immediate_operand" "i"))
57 (const_int 0)))]
58 "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"
59 "*
60 {
61 CC_STATUS_PARTIAL_INIT;
62 return \"andh %H1,%0,%?r0\";
63 }")
64
65 (define_insn ""
66 [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r")
67 (match_operand:SI 1 "immediate_operand" "i"))
68 (const_int 0)))]
69 "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0"
70 "*
71 {
72 CC_STATUS_PARTIAL_INIT;
73 cc_status.flags |= CC_NEGATED;
74 return \"andh %H1,%0,%?r0\";
75 }")
76
77 (define_insn ""
78 [(set (cc0) (eq (ashiftrt:SI
79 (sign_extend:SI
80 (ashift:QI (match_operand:QI 0 "register_operand" "r")
81 (match_operand:QI 1 "logic_int" "n")))
82 (match_operand:SI 2 "logic_int" "n"))
83 (const_int 0)))]
84 ""
85 "*
86 {
87 int width = 8 - INTVAL (operands[2]);
88 int pos = 8 - width - INTVAL (operands[1]);
89
90 CC_STATUS_PARTIAL_INIT;
91 operands[2] = gen_rtx (CONST_INT, VOIDmode,
92 ~((-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_rtx (CONST_INT, VOIDmode, - 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_rtx (CONST_INT, VOIDmode, - 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_rtx (CONST_INT, VOIDmode, - 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_rtx (CONST_INT, VOIDmode, - 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_rtx (CONST_INT, VOIDmode, - 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_rtx (CONST_INT, VOIDmode, - 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 (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1008 (mem:BLK (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 0))
1015 (clobber (match_dup 1))])]
1016 ""
1017 "
1018 {
1019 operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
1020 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1021 operands[4] = gen_reg_rtx (SImode);
1022 operands[5] = gen_reg_rtx (SImode);
1023 operands[6] = gen_reg_rtx (SImode);
1024 }")
1025
1026 (define_insn ""
1027 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
1028 (mem:BLK (match_operand:SI 1 "register_operand" "r")))
1029 (use (match_operand:SI 2 "general_operand" "rn"))
1030 (use (match_operand:SI 3 "immediate_operand" "i"))
1031 (clobber (match_operand:SI 4 "register_operand" "=r"))
1032 (clobber (match_operand:SI 5 "register_operand" "=r"))
1033 (clobber (match_operand:SI 6 "register_operand" "=r"))
1034 (clobber (match_dup 0))
1035 (clobber (match_dup 1))]
1036 ""
1037 "* return output_block_move (operands);")
1038 \f
1039 ;; Floating point move insns
1040
1041 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1042 ;; to be reloaded by putting the constant into memory.
1043 ;; It must come before the more general movdf pattern.
1044 (define_insn ""
1045 [(set (match_operand:DF 0 "general_operand" "=r,f,o")
1046 (match_operand:DF 1 "" "mG,m,G"))]
1047 "GET_CODE (operands[1]) == CONST_DOUBLE"
1048 "*
1049 {
1050 if (FP_REG_P (operands[0]) || operands[1] == CONST0_RTX (DFmode))
1051 return output_fp_move_double (operands);
1052 return output_move_double (operands);
1053 }")
1054
1055 (define_insn "movdf"
1056 [(set (match_operand:DF 0 "general_operand" "=*rm,*r,?f,?*rm")
1057 (match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))]
1058 ""
1059 "*
1060 {
1061 if (GET_CODE (operands[0]) == MEM
1062 && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1063 return output_store (operands);
1064 if (GET_CODE (operands[1]) == MEM
1065 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1066 return output_load (operands);
1067
1068 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1069 return output_fp_move_double (operands);
1070 return output_move_double (operands);
1071 }")
1072
1073 (define_insn "movdi"
1074 [(set (match_operand:DI 0 "general_operand" "=rm,r,?f,?rm")
1075 (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))]
1076 ""
1077 "*
1078 {
1079 if (GET_CODE (operands[0]) == MEM
1080 && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1081 return output_store (operands);
1082 if (GET_CODE (operands[1]) == MEM
1083 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1084 return output_load (operands);
1085
1086 /* ??? How can we have a DFmode arg here with DImode above? */
1087 if (FP_REG_P (operands[0]) && operands[1] == CONST0_RTX (DFmode))
1088 return \"fmov.dd %?f0,%0\";
1089
1090 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1091 return output_fp_move_double (operands);
1092 return output_move_double (operands);
1093 }")
1094
1095 ;; The alternative m/r is separate from m/f
1096 ;; The first alternative is separate from the second for the same reason.
1097 (define_insn "movsf"
1098 [(set (match_operand:SF 0 "general_operand" "=*rf,*rf,*r,m,m")
1099 (match_operand:SF 1 "general_operand" "*r,fmG,F,*r,f"))]
1100 ""
1101 "*
1102 {
1103 if (GET_CODE (operands[0]) == MEM
1104 && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1105 return output_store (operands);
1106 if (GET_CODE (operands[1]) == MEM
1107 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1108 return output_load (operands);
1109 if (FP_REG_P (operands[0]))
1110 {
1111 if (FP_REG_P (operands[1]))
1112 return \"fmov.ss %1,%0\";
1113 if (GET_CODE (operands[1]) == REG)
1114 return \"ixfr %1,%0\";
1115 if (operands[1] == CONST0_RTX (SFmode))
1116 return \"fmov.ss %?f0,%0\";
1117 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1118 {
1119 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1120 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1121 && cc_prev_status.mdep == XEXP(operands[1],0)))
1122 {
1123 CC_STATUS_INIT;
1124 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1125 cc_status.mdep = XEXP (operands[1], 0);
1126 return \"orh %h1,%?r0,%?r31\;fld.l %L1(%?r31),%0\";
1127 }
1128 return \"fld.l %L1(%?r31),%0\";
1129 }
1130 return \"fld.l %1,%0\";
1131 }
1132 if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE)
1133 {
1134 if (GET_CODE (operands[0]) == REG && FP_REG_P (operands[1]))
1135 return \"fxfr %1,%0\";
1136 if (GET_CODE (operands[0]) == REG)
1137 {
1138 CC_STATUS_PARTIAL_INIT;
1139 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1140 {
1141 register unsigned long ul;
1142
1143 ul = sfmode_constant_to_ulong (operands[1]);
1144 if ((ul & 0x0000ffff) == 0)
1145 return \"orh %H1,%?r0,%0\";
1146 if ((ul & 0xffff0000) == 0)
1147 return \"or %L1,%?r0,%0\";
1148 }
1149 return \"orh %H1,%?r0,%0\;or %L1,%0,%0\";
1150 }
1151 /* Now operand 0 must be memory.
1152 If operand 1 is CONST_DOUBLE, its value must be 0. */
1153 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1154 {
1155 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1156 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1157 && XEXP (operands[0], 0) == cc_prev_status.mdep))
1158 {
1159 CC_STATUS_INIT;
1160 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1161 cc_status.mdep = XEXP (operands[0], 0);
1162 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1163 }
1164 return \"fst.l %r1,%L0(%?r31)\";
1165 }
1166 return \"fst.l %r1,%0\";
1167 }
1168 if (GET_CODE (operands[0]) == MEM)
1169 return \"st.l %r1,%0\";
1170 if (GET_CODE (operands[1]) == MEM)
1171 return \"ld.l %1,%0\";
1172 if (operands[1] == CONST0_RTX (SFmode))
1173 return \"shl %?r0,%?r0,%0\";
1174 return \"mov %1,%0\";
1175 }")
1176 \f
1177 ;; Special load insns for REG+REG addresses.
1178 ;; Such addresses are not "legitimate" because st rejects them.
1179
1180 (define_insn ""
1181 [(set (match_operand:DF 0 "register_operand" "=rf")
1182 (match_operand:DF 1 "indexed_operand" "m"))]
1183 ""
1184 "*
1185 {
1186 if (FP_REG_P (operands[0]))
1187 return output_fp_move_double (operands);
1188 return output_move_double (operands);
1189 }")
1190
1191 (define_insn ""
1192 [(set (match_operand:SF 0 "register_operand" "=rf")
1193 (match_operand:SF 1 "indexed_operand" "m"))]
1194 ""
1195 "*
1196 {
1197 if (FP_REG_P (operands[0]))
1198 return \"fld.l %1,%0\";
1199 return \"ld.l %1,%0\";
1200 }")
1201
1202 (define_insn ""
1203 [(set (match_operand:SI 0 "register_operand" "=rf")
1204 (match_operand:SI 1 "indexed_operand" "m"))]
1205 ""
1206 "*
1207 {
1208 if (FP_REG_P (operands[0]))
1209 return \"fld.l %1,%0\";
1210 return \"ld.l %1,%0\";
1211 }")
1212
1213 (define_insn ""
1214 [(set (match_operand:HI 0 "register_operand" "=r")
1215 (match_operand:HI 1 "indexed_operand" "m"))]
1216 ""
1217 "ld.s %1,%0")
1218
1219 (define_insn ""
1220 [(set (match_operand:QI 0 "register_operand" "=r")
1221 (match_operand:QI 1 "indexed_operand" "m"))]
1222 ""
1223 "ld.b %1,%0")
1224
1225 ;; Likewise for floating-point store insns.
1226
1227 (define_insn ""
1228 [(set (match_operand:DF 0 "indexed_operand" "=m")
1229 (match_operand:DF 1 "register_operand" "f"))]
1230 ""
1231 "fst.d %1,%0")
1232
1233 (define_insn ""
1234 [(set (match_operand:SF 0 "indexed_operand" "=m")
1235 (match_operand:SF 1 "register_operand" "f"))]
1236 ""
1237 "fst.l %1,%0")
1238 \f
1239 ;;- truncation instructions
1240 (define_insn "truncsiqi2"
1241 [(set (match_operand:QI 0 "general_operand" "=g")
1242 (truncate:QI
1243 (match_operand:SI 1 "register_operand" "r")))]
1244 ""
1245 "*
1246 {
1247 if (GET_CODE (operands[0]) == MEM)
1248 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1249 {
1250 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1251 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1252 && XEXP (operands[0], 0) == cc_prev_status.mdep))
1253 {
1254 CC_STATUS_INIT;
1255 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1256 cc_status.mdep = XEXP (operands[0], 0);
1257 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1258 }
1259 return \"st.b %1,%L0(%?r31)\";
1260 }
1261 else
1262 return \"st.b %1,%0\";
1263 return \"shl %?r0,%1,%0\";
1264 }")
1265
1266 (define_insn "trunchiqi2"
1267 [(set (match_operand:QI 0 "general_operand" "=g")
1268 (truncate:QI
1269 (match_operand:HI 1 "register_operand" "r")))]
1270 ""
1271 "*
1272 {
1273 if (GET_CODE (operands[0]) == MEM)
1274 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1275 {
1276 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1277 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1278 && XEXP (operands[0], 0) == cc_prev_status.mdep))
1279 {
1280 CC_STATUS_INIT;
1281 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1282 cc_status.mdep = XEXP (operands[0], 0);
1283 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1284 }
1285 return \"st.b %1,%L0(%?r31)\";
1286 }
1287 else
1288 return \"st.b %1,%0\";
1289 return \"shl %?r0,%1,%0\";
1290 }")
1291
1292 (define_insn "truncsihi2"
1293 [(set (match_operand:HI 0 "general_operand" "=g")
1294 (truncate:HI
1295 (match_operand:SI 1 "register_operand" "r")))]
1296 ""
1297 "*
1298 {
1299 if (GET_CODE (operands[0]) == MEM)
1300 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
1301 {
1302 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1303 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1304 && XEXP (operands[0], 0) == cc_prev_status.mdep))
1305 {
1306 CC_STATUS_INIT;
1307 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1308 cc_status.mdep = XEXP (operands[0], 0);
1309 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands);
1310 }
1311 return \"st.s %1,%L0(%?r31)\";
1312 }
1313 else
1314 return \"st.s %1,%0\";
1315 return \"shl %?r0,%1,%0\";
1316 }")
1317 \f
1318 ;;- zero extension instructions
1319
1320 (define_insn "zero_extendhisi2"
1321 [(set (match_operand:SI 0 "register_operand" "=r")
1322 (zero_extend:SI
1323 (match_operand:HI 1 "register_operand" "r")))]
1324 ""
1325 "*
1326 {
1327 CC_STATUS_PARTIAL_INIT;
1328 return \"and 0xffff,%1,%0\";
1329 }")
1330
1331 (define_insn "zero_extendqihi2"
1332 [(set (match_operand:HI 0 "register_operand" "=r")
1333 (zero_extend:HI
1334 (match_operand:QI 1 "register_operand" "r")))]
1335 ""
1336 "*
1337 {
1338 CC_STATUS_PARTIAL_INIT;
1339 return \"and 0xff,%1,%0\";
1340 }")
1341
1342 (define_insn "zero_extendqisi2"
1343 [(set (match_operand:SI 0 "register_operand" "=r")
1344 (zero_extend:SI
1345 (match_operand:QI 1 "register_operand" "r")))]
1346 ""
1347 "*
1348 {
1349 CC_STATUS_PARTIAL_INIT;
1350 return \"and 0xff,%1,%0\";
1351 }")
1352 \f
1353 ;; Sign extension instructions.
1354
1355 (define_insn ""
1356 [(set (match_operand:SI 0 "register_operand" "=r")
1357 (sign_extend:SI
1358 (match_operand:HI 1 "indexed_operand" "m")))]
1359 ""
1360 "ld.s %1,%0")
1361
1362 (define_insn ""
1363 [(set (match_operand:HI 0 "register_operand" "=r")
1364 (sign_extend:HI
1365 (match_operand:QI 1 "indexed_operand" "m")))]
1366 ""
1367 "ld.b %1,%0")
1368
1369 (define_insn ""
1370 [(set (match_operand:SI 0 "register_operand" "=r")
1371 (sign_extend:SI
1372 (match_operand:QI 1 "indexed_operand" "m")))]
1373 ""
1374 "ld.b %1,%0")
1375
1376 (define_insn "extendhisi2"
1377 [(set (match_operand:SI 0 "register_operand" "=r")
1378 (sign_extend:SI
1379 (match_operand:HI 1 "nonimmediate_operand" "mr")))]
1380 ""
1381 "*
1382 {
1383 if (REG_P (operands[1]))
1384 return \"shl 16,%1,%0\;shra 16,%0,%0\";
1385 if (GET_CODE (operands[1]) == CONST_INT)
1386 abort ();
1387 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1388 {
1389 CC_STATUS_INIT;
1390 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1391 cc_status.mdep = XEXP (operands[1], 0);
1392 return \"orh %h1,%?r0,%?r31\;ld.s %L1(%?r31),%0\";
1393 }
1394 else
1395 return \"ld.s %1,%0\";
1396 }")
1397
1398 (define_insn "extendqihi2"
1399 [(set (match_operand:HI 0 "register_operand" "=r")
1400 (sign_extend:HI
1401 (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1402 ""
1403 "*
1404 {
1405 if (REG_P (operands[1]))
1406 return \"shl 24,%1,%0\;shra 24,%0,%0\";
1407 if (GET_CODE (operands[1]) == CONST_INT)
1408 abort ();
1409 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1410 {
1411 CC_STATUS_INIT;
1412 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1413 cc_status.mdep = XEXP (operands[1], 0);
1414 return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1415 }
1416 else
1417 return \"ld.b %1,%0\";
1418 }")
1419
1420 (define_insn "extendqisi2"
1421 [(set (match_operand:SI 0 "register_operand" "=r")
1422 (sign_extend:SI
1423 (match_operand:QI 1 "nonimmediate_operand" "mr")))]
1424 ""
1425 "*
1426 {
1427 if (REG_P (operands[1]))
1428 return \"shl 24,%1,%0\;shra 24,%0,%0\";
1429 if (GET_CODE (operands[1]) == CONST_INT)
1430 abort ();
1431 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
1432 {
1433 CC_STATUS_INIT;
1434 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
1435 cc_status.mdep = XEXP (operands[1], 0);
1436 return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
1437 }
1438 else
1439 return \"ld.b %1,%0\";
1440 }")
1441
1442 ;; Signed bitfield extractions come out looking like
1443 ;; (shiftrt (sign_extend (shift <Y> <C1>)) <C2>)
1444 ;; which we expand poorly as four shift insns.
1445 ;; These patterns yield two shifts:
1446 ;; (shiftrt (shift <Y> <C3>) <C4>)
1447 (define_insn ""
1448 [(set (match_operand:SI 0 "register_operand" "=r")
1449 (ashiftrt:SI
1450 (sign_extend:SI
1451 (match_operand:QI 1 "register_operand" "r"))
1452 (match_operand:SI 2 "logic_int" "n")))]
1453 "INTVAL (operands[2]) < 8"
1454 "*
1455 {
1456 return \"shl 24,%1,%0\;shra 24+%2,%0,%0\";
1457 }")
1458
1459 (define_insn ""
1460 [(set (match_operand:SI 0 "register_operand" "=r")
1461 (ashiftrt:SI
1462 (sign_extend:SI
1463 (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1464 (match_operand:SI 2 "logic_int" "n")) 0))
1465 (match_operand:SI 3 "logic_int" "n")))]
1466 "INTVAL (operands[3]) < 8"
1467 "*
1468 {
1469 return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1470 }")
1471
1472 (define_insn ""
1473 [(set (match_operand:SI 0 "register_operand" "=r")
1474 (ashiftrt:SI
1475 (sign_extend:SI
1476 (ashift:QI (match_operand:QI 1 "register_operand" "r")
1477 (match_operand:QI 2 "logic_int" "n")))
1478 (match_operand:SI 3 "logic_int" "n")))]
1479 "INTVAL (operands[3]) < 8"
1480 "*
1481 {
1482 return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\";
1483 }")
1484 \f
1485 ;; Special patterns for optimizing bit-field instructions.
1486
1487 ;; First two patterns are for bitfields that came from memory
1488 ;; testing only the high bit. They work with old combiner.
1489
1490 (define_insn ""
1491 [(set (cc0)
1492 (eq (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1493 (const_int 7)) 0))
1494 (const_int 0)))]
1495 ""
1496 "*
1497 {
1498 CC_STATUS_PARTIAL_INIT;
1499 return \"and 128,%0,%?r0\";
1500 }")
1501
1502 (define_insn ""
1503 [(set (cc0)
1504 (eq (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1505 (const_int 7)) 0))
1506 (const_int 0)))]
1507 ""
1508 "*
1509 {
1510 CC_STATUS_PARTIAL_INIT;
1511 return \"and 128,%0,%?r0\";
1512 }")
1513
1514 ;; next two patterns are good for bitfields coming from memory
1515 ;; (via pseudo-register) or from a register, though this optimization
1516 ;; is only good for values contained wholly within the bottom 13 bits
1517 (define_insn ""
1518 [(set (cc0)
1519 (eq
1520 (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
1521 (match_operand:SI 1 "logic_int" "n"))
1522 (match_operand:SI 2 "logic_int" "n"))
1523 (const_int 0)))]
1524 "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1525 "*
1526 {
1527 CC_STATUS_PARTIAL_INIT;
1528 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1529 (INTVAL (operands[2]) << INTVAL (operands[1])));
1530 return \"and %2,%0,%?r0\";
1531 }")
1532
1533 (define_insn ""
1534 [(set (cc0)
1535 (eq
1536 (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
1537 (match_operand:SI 1 "logic_int" "n"))
1538 (match_operand:SI 2 "logic_int" "n"))
1539 (const_int 0)))]
1540 "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))"
1541 "*
1542 {
1543 CC_STATUS_PARTIAL_INIT;
1544 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1545 (INTVAL (operands[2]) << INTVAL (operands[1])));
1546 return \"and %2,%0,%?r0\";
1547 }")
1548 \f
1549 ;; Conversions between float and double.
1550
1551 (define_insn "extendsfdf2"
1552 [(set (match_operand:DF 0 "register_operand" "=f")
1553 (float_extend:DF
1554 (match_operand:SF 1 "register_operand" "f")))]
1555 ""
1556 "fmov.sd %1,%0")
1557
1558 (define_insn "truncdfsf2"
1559 [(set (match_operand:SF 0 "register_operand" "=f")
1560 (float_truncate:SF
1561 (match_operand:DF 1 "register_operand" "f")))]
1562 ""
1563 "fmov.ds %1,%0")
1564 \f
1565 ;; Conversion between fixed point and floating point.
1566 ;; Note that among the fix-to-float insns
1567 ;; the ones that start with SImode come first.
1568 ;; That is so that an operand that is a CONST_INT
1569 ;; (and therefore lacks a specific machine mode).
1570 ;; will be recognized as SImode (which is always valid)
1571 ;; rather than as QImode or HImode.
1572
1573 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
1574 ;; to be reloaded by putting the constant into memory.
1575 ;; It must come before the more general floatsisf2 pattern.
1576 (define_expand "floatsidf2"
1577 [(set (match_dup 2) (match_dup 3))
1578 (set (match_dup 4) (xor:SI (match_operand:SI 1 "register_operand" "")
1579 (const_int -2147483648)))
1580 (set (match_dup 5) (match_dup 3))
1581 (set (subreg:SI (match_dup 5) 0) (match_dup 4))
1582 (set (match_operand:DF 0 "register_operand" "")
1583 (minus:DF (match_dup 5) (match_dup 2)))]
1584 ""
1585 "
1586 {
1587 REAL_VALUE_TYPE d;
1588 /* 4503601774854144 is (1 << 30) * ((1 << 22) + (1 << 1)). */
1589 d = REAL_VALUE_ATOF (\"4503601774854144\", DFmode);
1590 operands[2] = gen_reg_rtx (DFmode);
1591 operands[3] = CONST_DOUBLE_FROM_REAL_VALUE (d, DFmode);
1592 operands[4] = gen_reg_rtx (SImode);
1593 operands[5] = gen_reg_rtx (DFmode);
1594 }")
1595 \f
1596 ;; Floating to fixed conversion.
1597
1598 (define_expand "fix_truncdfsi2"
1599 ;; This first insn produces a double-word value
1600 ;; in which only the low word is valid.
1601 [(set (match_dup 2)
1602 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
1603 (set (match_operand:SI 0 "register_operand" "=f")
1604 (subreg:SI (match_dup 2) 0))]
1605 ""
1606 "
1607 {
1608 operands[2] = gen_reg_rtx (DImode);
1609 }")
1610
1611 ;; Recognize the first insn generated above.
1612 ;; This RTL looks like a fix_truncdfdi2 insn,
1613 ;; but we dont call it that, because only 32 bits
1614 ;; of the result are valid.
1615 ;; This pattern will work for the intended purposes
1616 ;; as long as we do not have any fixdfdi2 or fix_truncdfdi2.
1617 (define_insn ""
1618 [(set (match_operand:DI 0 "register_operand" "=f")
1619 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1620 ""
1621 "ftrunc.dd %1,%0")
1622
1623 (define_expand "fix_truncsfsi2"
1624 ;; This first insn produces a double-word value
1625 ;; in which only the low word is valid.
1626 [(set (match_dup 2)
1627 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
1628 (set (match_operand:SI 0 "register_operand" "=f")
1629 (subreg:SI (match_dup 2) 0))]
1630 ""
1631 "
1632 {
1633 operands[2] = gen_reg_rtx (DImode);
1634 }")
1635
1636 ;; Recognize the first insn generated above.
1637 ;; This RTL looks like a fix_truncsfdi2 insn,
1638 ;; but we dont call it that, because only 32 bits
1639 ;; of the result are valid.
1640 ;; This pattern will work for the intended purposes
1641 ;; as long as we do not have any fixsfdi2 or fix_truncsfdi2.
1642 (define_insn ""
1643 [(set (match_operand:DI 0 "register_operand" "=f")
1644 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1645 ""
1646 "ftrunc.sd %1,%0")
1647 \f
1648 ;;- arithmetic instructions
1649
1650 (define_insn "addsi3"
1651 [(set (match_operand:SI 0 "register_operand" "=r,*f")
1652 (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,*f")
1653 (match_operand:SI 2 "arith_operand" "rI,*f")))]
1654 ""
1655 "*
1656 {
1657 if (which_alternative == 1)
1658 return \"fiadd.ss %2,%1,%0\";
1659 CC_STATUS_PARTIAL_INIT;
1660 return \"addu %2,%1,%0\";
1661 }")
1662
1663 (define_insn "adddi3"
1664 [(set (match_operand:DI 0 "register_operand" "=f")
1665 (plus:DI (match_operand:DI 1 "register_operand" "%f")
1666 (match_operand:DI 2 "register_operand" "f")))]
1667 ""
1668 "fiadd.dd %1,%2,%0")
1669
1670 (define_insn "subsi3"
1671 [(set (match_operand:SI 0 "register_operand" "=r,r,*f")
1672 (minus:SI (match_operand:SI 1 "register_operand" "r,I,*f")
1673 (match_operand:SI 2 "arith_operand" "rI,r,*f")))]
1674 ""
1675 "*
1676 {
1677 if (which_alternative == 2)
1678 return \"fisub.ss %1,%2,%0\";
1679 CC_STATUS_PARTIAL_INIT;
1680 if (REG_P (operands[2]))
1681 return \"subu %1,%2,%0\";
1682 operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]));
1683 return \"addu %2,%1,%0\";
1684 }")
1685
1686 (define_insn "subdi3"
1687 [(set (match_operand:DI 0 "register_operand" "=f")
1688 (minus:DI (match_operand:DI 1 "register_operand" "f")
1689 (match_operand:DI 2 "register_operand" "f")))]
1690 ""
1691 "fisub.dd %1,%2,%0")
1692
1693 (define_expand "mulsi3"
1694 [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1695 (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1696 (clobber (match_dup 3))
1697 (set (subreg:SI (match_dup 3) 0)
1698 (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1699 (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1700 ""
1701 "
1702 {
1703 if (WORDS_BIG_ENDIAN)
1704 emit_insn (gen_mulsi3_big (operands[0], operands[1], operands[2]));
1705 else
1706 emit_insn (gen_mulsi3_little (operands[0], operands[1], operands[2]));
1707 DONE;
1708 }")
1709
1710 (define_expand "mulsi3_little"
1711 [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" ""))
1712 (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" ""))
1713 (clobber (match_dup 3))
1714 (set (subreg:SI (match_dup 3) 0)
1715 (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0)))
1716 (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))]
1717 "! WORDS_BIG_ENDIAN"
1718 "
1719 {
1720 operands[3] = gen_reg_rtx (DImode);
1721 operands[4] = gen_reg_rtx (DImode);
1722 operands[5] = gen_reg_rtx (DImode);
1723 }")
1724
1725 (define_expand "mulsi3_big"
1726 [(set (subreg:SI (match_dup 4) 1) (match_operand:SI 1 "general_operand" ""))
1727 (set (subreg:SI (match_dup 5) 1) (match_operand:SI 2 "general_operand" ""))
1728 (clobber (match_dup 3))
1729 (set (subreg:SI (match_dup 3) 1)
1730 (mult:SI (subreg:SI (match_dup 4) 1) (subreg:SI (match_dup 5) 1)))
1731 (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 1))]
1732 "WORDS_BIG_ENDIAN"
1733 "
1734 {
1735 operands[3] = gen_reg_rtx (DImode);
1736 operands[4] = gen_reg_rtx (DImode);
1737 operands[5] = gen_reg_rtx (DImode);
1738 }")
1739
1740 (define_insn ""
1741 [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0)
1742 (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0)
1743 (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))]
1744 "! WORDS_BIG_ENDIAN"
1745 "fmlow.dd %2,%1,%0")
1746
1747 (define_insn ""
1748 [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 1)
1749 (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 1)
1750 (subreg:SI (match_operand:DI 2 "register_operand" "f") 1)))]
1751 "WORDS_BIG_ENDIAN"
1752 "fmlow.dd %2,%1,%0")
1753 \f
1754 ;;- and instructions (with compliment also)
1755 (define_insn "andsi3"
1756 [(set (match_operand:SI 0 "register_operand" "=r")
1757 (and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1758 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1759 ""
1760 "*
1761 {
1762 rtx xop[3];
1763
1764 CC_STATUS_PARTIAL_INIT;
1765 if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1766 return \"and %2,%1,%0\";
1767 if ((INTVAL (operands[2]) & 0xffff) == 0)
1768 {
1769 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1770 (unsigned) INTVAL (operands[2]) >> 16);
1771 return \"andh %2,%1,%0\";
1772 }
1773 xop[0] = operands[0];
1774 xop[1] = operands[1];
1775 xop[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]) & 0xffff);
1776 output_asm_insn (\"andnot %2,%1,%0\", xop);
1777 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1778 ~(unsigned) INTVAL (operands[2]) >> 16);
1779 return \"andnoth %2,%0,%0\";
1780 }")
1781
1782 (define_insn ""
1783 [(set (match_operand:SI 0 "register_operand" "=r")
1784 (and:SI (not:SI (match_operand:SI 1 "register_operand" "rn"))
1785 (match_operand:SI 2 "register_operand" "r")))]
1786 ""
1787 "*
1788 {
1789 rtx xop[3];
1790
1791 CC_STATUS_PARTIAL_INIT;
1792 if (REG_P (operands[1]) || LOGIC_INT (operands[1]))
1793 return \"andnot %1,%2,%0\";
1794 if ((INTVAL (operands[1]) & 0xffff) == 0)
1795 {
1796 operands[1] = gen_rtx (CONST_INT, VOIDmode,
1797 (unsigned) INTVAL (operands[1]) >> 16);
1798 return \"andnoth %1,%2,%0\";
1799 }
1800 xop[0] = operands[0];
1801 xop[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) & 0xffff));
1802 xop[2] = operands[2];
1803 output_asm_insn (\"andnot %1,%2,%0\", xop);
1804 operands[1] = gen_rtx (CONST_INT, VOIDmode,
1805 (unsigned) INTVAL (operands[1]) >> 16);
1806 return \"andnoth %1,%0,%0\";
1807 }")
1808
1809 (define_insn "iorsi3"
1810 [(set (match_operand:SI 0 "register_operand" "=r")
1811 (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1812 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1813 ""
1814 "*
1815 {
1816 rtx xop[3];
1817
1818 CC_STATUS_PARTIAL_INIT;
1819 if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1820 return \"or %2,%1,%0\";
1821 if ((INTVAL (operands[2]) & 0xffff) == 0)
1822 {
1823 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1824 (unsigned) INTVAL (operands[2]) >> 16);
1825 return \"orh %2,%1,%0\";
1826 }
1827 xop[0] = operands[0];
1828 xop[1] = operands[1];
1829 xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1830 output_asm_insn (\"or %2,%1,%0\", xop);
1831 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1832 (unsigned) INTVAL (operands[2]) >> 16);
1833 return \"orh %2,%0,%0\";
1834 }")
1835
1836 (define_insn "xorsi3"
1837 [(set (match_operand:SI 0 "register_operand" "=r")
1838 (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
1839 (match_operand:SI 2 "nonmemory_operand" "rL")))]
1840 ""
1841 "*
1842 {
1843 rtx xop[3];
1844
1845 CC_STATUS_PARTIAL_INIT;
1846 if (REG_P (operands[2]) || LOGIC_INT (operands[2]))
1847 return \"xor %2,%1,%0\";
1848 if ((INTVAL (operands[2]) & 0xffff) == 0)
1849 {
1850 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1851 (unsigned) INTVAL (operands[2]) >> 16);
1852 return \"xorh %2,%1,%0\";
1853 }
1854 xop[0] = operands[0];
1855 xop[1] = operands[1];
1856 xop[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) & 0xffff));
1857 output_asm_insn (\"xor %2,%1,%0\", xop);
1858 operands[2] = gen_rtx (CONST_INT, VOIDmode,
1859 (unsigned) INTVAL (operands[2]) >> 16);
1860 return \"xorh %2,%0,%0\";
1861 }")
1862
1863 ;(The i860 instruction set doesn't allow an immediate second operand in
1864 ; a subtraction.)
1865 (define_insn "negsi2"
1866 [(set (match_operand:SI 0 "general_operand" "=r")
1867 (neg:SI (match_operand:SI 1 "arith_operand" "r")))]
1868 ""
1869 "*
1870 {
1871 CC_STATUS_PARTIAL_INIT;
1872 return \"subu %?r0,%1,%0\";
1873 }")
1874
1875 (define_insn "one_cmplsi2"
1876 [(set (match_operand:SI 0 "general_operand" "=r")
1877 (not:SI (match_operand:SI 1 "arith_operand" "r")))]
1878 ""
1879 "*
1880 {
1881 CC_STATUS_PARTIAL_INIT;
1882 return \"subu -1,%1,%0\";
1883 }")
1884 \f
1885 ;; Floating point arithmetic instructions.
1886
1887 (define_insn "adddf3"
1888 [(set (match_operand:DF 0 "register_operand" "=f")
1889 (plus:DF (match_operand:DF 1 "register_operand" "f")
1890 (match_operand:DF 2 "register_operand" "f")))]
1891 ""
1892 "fadd.dd %1,%2,%0")
1893
1894 (define_insn "addsf3"
1895 [(set (match_operand:SF 0 "register_operand" "=f")
1896 (plus:SF (match_operand:SF 1 "register_operand" "f")
1897 (match_operand:SF 2 "register_operand" "f")))]
1898 ""
1899 "fadd.ss %1,%2,%0")
1900
1901 (define_insn "subdf3"
1902 [(set (match_operand:DF 0 "register_operand" "=f")
1903 (minus:DF (match_operand:DF 1 "register_operand" "f")
1904 (match_operand:DF 2 "register_operand" "f")))]
1905 ""
1906 "fsub.dd %1,%2,%0")
1907
1908 (define_insn "subsf3"
1909 [(set (match_operand:SF 0 "register_operand" "=f")
1910 (minus:SF (match_operand:SF 1 "register_operand" "f")
1911 (match_operand:SF 2 "register_operand" "f")))]
1912 ""
1913 "fsub.ss %1,%2,%0")
1914
1915 (define_insn "muldf3"
1916 [(set (match_operand:DF 0 "register_operand" "=f")
1917 (mult:DF (match_operand:DF 1 "register_operand" "f")
1918 (match_operand:DF 2 "register_operand" "f")))]
1919 ""
1920 "fmul.dd %1,%2,%0")
1921
1922 (define_insn "mulsf3"
1923 [(set (match_operand:SF 0 "register_operand" "=f")
1924 (mult:SF (match_operand:SF 1 "register_operand" "f")
1925 (match_operand:SF 2 "register_operand" "f")))]
1926 ""
1927 "fmul.ss %1,%2,%0")
1928
1929 (define_insn "negdf2"
1930 [(set (match_operand:DF 0 "register_operand" "=f")
1931 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
1932 ""
1933 "fsub.dd %?f0,%1,%0")
1934
1935 (define_insn "negsf2"
1936 [(set (match_operand:SF 0 "register_operand" "=f")
1937 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
1938 ""
1939 "fsub.ss %?f0,%1,%0")
1940 \f
1941 (define_insn "divdf3"
1942 [(set (match_operand:DF 0 "register_operand" "=&f")
1943 (div:DF (match_operand:DF 1 "register_operand" "f")
1944 (match_operand:DF 2 "register_operand" "f")))
1945 (clobber (match_scratch:DF 3 "=&f"))
1946 (clobber (match_scratch:DF 4 "=&f"))]
1947 ""
1948 "*
1949 {
1950 CC_STATUS_PARTIAL_INIT;
1951 if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1952 || (cc_prev_status.flags & CC_HI_R31_ADJ)
1953 || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1954 {
1955 cc_status.flags |= CC_KNOW_HI_R31;
1956 cc_status.flags &= ~CC_HI_R31_ADJ;
1957 cc_status.mdep = CONST2_RTX (SFmode);
1958 return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1959 orh 0x4000,%?r0,%?r31\;ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1960 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1961 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1962 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1963 }
1964 else
1965 return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\
1966 ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\
1967 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1968 fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\
1969 fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\";
1970 }")
1971
1972 (define_insn "divsf3"
1973 [(set (match_operand:SF 0 "register_operand" "=&f")
1974 (div:SF (match_operand:SF 1 "register_operand" "f")
1975 (match_operand:SF 2 "register_operand" "f")))
1976 (clobber (match_scratch:SF 3 "=&f"))
1977 (clobber (match_scratch:SF 4 "=&f"))]
1978 ""
1979 "*
1980 {
1981 CC_STATUS_PARTIAL_INIT;
1982 if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0)
1983 || (cc_prev_status.flags & CC_HI_R31_ADJ)
1984 || (cc_prev_status.mdep != CONST2_RTX (SFmode)))
1985 {
1986 cc_status.flags |= CC_KNOW_HI_R31;
1987 cc_status.flags &= ~CC_HI_R31_ADJ;
1988 cc_status.mdep = CONST2_RTX (SFmode);
1989 output_asm_insn (\"orh 0x4000,%?r0,%?r31\", operands);
1990 }
1991 return \"ixfr %?r31,%4\;frcp.ss %2,%0\;\\\
1992 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;fmul.ss %0,%3,%0\;\\\
1993 fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;\\\
1994 fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\";
1995 }")
1996 \f
1997 ;; Shift instructions
1998
1999 ;; Optimized special case of shifting.
2000 ;; Must precede the general case.
2001
2002 (define_insn ""
2003 [(set (match_operand:SI 0 "register_operand" "=r")
2004 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
2005 (const_int 24)))]
2006 ""
2007 "*
2008 {
2009 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
2010 {
2011 CC_STATUS_INIT;
2012 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
2013 cc_status.mdep = XEXP (operands[1], 0);
2014 return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\";
2015 }
2016 return \"ld.b %1,%0\";
2017 }")
2018
2019 \f
2020 ;;- arithmetic shift instructions
2021 (define_insn "ashlsi3"
2022 [(set (match_operand:SI 0 "register_operand" "=r")
2023 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2024 (match_operand:SI 2 "shift_operand" "rn")))]
2025 ""
2026 "*
2027 {
2028 return \"shl %2,%1,%0\";
2029 }")
2030
2031 (define_insn "ashlhi3"
2032 [(set (match_operand:HI 0 "register_operand" "=r")
2033 (ashift:HI (match_operand:HI 1 "register_operand" "r")
2034 (match_operand:HI 2 "shift_operand" "rn")))]
2035 ""
2036 "*
2037 {
2038 return \"shl %2,%1,%0\";
2039 }")
2040
2041 (define_insn "ashlqi3"
2042 [(set (match_operand:QI 0 "register_operand" "=r")
2043 (ashift:QI (match_operand:QI 1 "register_operand" "r")
2044 (match_operand:QI 2 "shift_operand" "rn")))]
2045 ""
2046 "*
2047 {
2048 return \"shl %2,%1,%0\";
2049 }")
2050
2051 (define_insn "ashrsi3"
2052 [(set (match_operand:SI 0 "register_operand" "=r")
2053 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2054 (match_operand:SI 2 "shift_operand" "rn")))]
2055 ""
2056 "*
2057 {
2058 return \"shra %2,%1,%0\";
2059 }")
2060
2061 (define_insn "lshrsi3"
2062 [(set (match_operand:SI 0 "register_operand" "=r")
2063 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2064 (match_operand:SI 2 "shift_operand" "rn")))]
2065 ""
2066 "*
2067 {
2068 return \"shr %2,%1,%0\";
2069 }")
2070 \f
2071 ;; Unconditional and other jump instructions
2072
2073 (define_insn "jump"
2074 [(set (pc) (label_ref (match_operand 0 "" "")))]
2075 ""
2076 "*
2077 {
2078 return \"br %l0\;nop\";
2079 }")
2080
2081 ;; Here are two simple peepholes which fill the delay slot of
2082 ;; an unconditional branch.
2083
2084 (define_peephole
2085 [(set (match_operand:SI 0 "register_operand" "=rf")
2086 (match_operand:SI 1 "single_insn_src_p" "gfG"))
2087 (set (pc) (label_ref (match_operand 2 "" "")))]
2088 ""
2089 "* return output_delayed_branch (\"br %l2\", operands, insn);")
2090
2091 (define_peephole
2092 [(set (match_operand:SI 0 "memory_operand" "=m")
2093 (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2094 (set (pc) (label_ref (match_operand 2 "" "")))]
2095 ""
2096 "* return output_delayed_branch (\"br %l2\", operands, insn);")
2097
2098 (define_insn "tablejump"
2099 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2100 (use (label_ref (match_operand 1 "" "")))]
2101 ""
2102 "bri %0\;nop")
2103
2104 (define_peephole
2105 [(set (match_operand:SI 0 "memory_operand" "=m")
2106 (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2107 (set (pc) (match_operand:SI 2 "register_operand" "r"))
2108 (use (label_ref (match_operand 3 "" "")))]
2109 ""
2110 "* return output_delayed_branch (\"bri %2\", operands, insn);")
2111
2112 ;;- jump to subroutine
2113 (define_expand "call"
2114 [(call (match_operand:SI 0 "memory_operand" "m")
2115 (match_operand 1 "" "i"))]
2116 ;; operand[2] is next_arg_register
2117 ""
2118 "
2119 {
2120 /* Make sure the address is just one reg and will stay that way. */
2121 if (! call_insn_operand (operands[0], QImode))
2122 operands[0]
2123 = change_address (operands[0], VOIDmode,
2124 copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2125 if (INTVAL (operands[1]) > 0)
2126 {
2127 emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2128 emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2129 }
2130 }")
2131
2132 ;;- jump to subroutine
2133 (define_insn ""
2134 [(call (match_operand:SI 0 "call_insn_operand" "m")
2135 (match_operand 1 "" "i"))]
2136 ;; operand[2] is next_arg_register
2137 ""
2138 "*
2139 {
2140 /* strip the MEM. */
2141 operands[0] = XEXP (operands[0], 0);
2142 CC_STATUS_INIT;
2143 if (GET_CODE (operands[0]) == REG)
2144 return \"calli %0\;nop\";
2145 return \"call %0\;nop\";
2146 }")
2147
2148 (define_peephole
2149 [(set (match_operand:SI 0 "register_operand" "=rf")
2150 (match_operand:SI 1 "single_insn_src_p" "gfG"))
2151 (call (match_operand:SI 2 "memory_operand" "m")
2152 (match_operand 3 "" "i"))]
2153 ;;- Don't use operand 1 for most machines.
2154 "! reg_mentioned_p (operands[0], operands[2])"
2155 "*
2156 {
2157 /* strip the MEM. */
2158 operands[2] = XEXP (operands[2], 0);
2159 if (GET_CODE (operands[2]) == REG)
2160 return output_delayed_branch (\"calli %2\", operands, insn);
2161 return output_delayed_branch (\"call %2\", operands, insn);
2162 }")
2163
2164 (define_peephole
2165 [(set (match_operand:SI 0 "memory_operand" "=m")
2166 (match_operand:SI 1 "reg_or_0_operand" "rfJ"))
2167 (call (match_operand:SI 2 "call_insn_operand" "m")
2168 (match_operand 3 "" "i"))]
2169 ;;- Don't use operand 1 for most machines.
2170 ""
2171 "*
2172 {
2173 /* strip the MEM. */
2174 operands[2] = XEXP (operands[2], 0);
2175 if (GET_CODE (operands[2]) == REG)
2176 return output_delayed_branch (\"calli %2\", operands, insn);
2177 return output_delayed_branch (\"call %2\", operands, insn);
2178 }")
2179
2180 (define_expand "call_value"
2181 [(set (match_operand 0 "register_operand" "=rf")
2182 (call (match_operand:SI 1 "memory_operand" "m")
2183 (match_operand 2 "" "i")))]
2184 ;; operand 3 is next_arg_register
2185 ""
2186 "
2187 {
2188 /* Make sure the address is just one reg and will stay that way. */
2189 if (! call_insn_operand (operands[1], QImode))
2190 operands[1]
2191 = change_address (operands[1], VOIDmode,
2192 copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2193 if (INTVAL (operands[2]) > 0)
2194 {
2195 emit_move_insn (arg_pointer_rtx, stack_pointer_rtx);
2196 emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx));
2197 }
2198 }")
2199
2200 (define_insn ""
2201 [(set (match_operand 0 "register_operand" "=rf")
2202 (call (match_operand:SI 1 "call_insn_operand" "m")
2203 (match_operand 2 "" "i")))]
2204 ;; operand 3 is next_arg_register
2205 ""
2206 "*
2207 {
2208 /* strip the MEM. */
2209 operands[1] = XEXP (operands[1], 0);
2210 CC_STATUS_INIT;
2211 if (GET_CODE (operands[1]) == REG)
2212 return \"calli %1\;nop\";
2213 return \"call %1\;nop\";
2214 }")
2215
2216 (define_peephole
2217 [(set (match_operand:SI 0 "register_operand" "=rf")
2218 (match_operand:SI 1 "single_insn_src_p" "gfG"))
2219 (set (match_operand 2 "" "=rf")
2220 (call (match_operand:SI 3 "call_insn_operand" "m")
2221 (match_operand 4 "" "i")))]
2222 ;;- Don't use operand 4 for most machines.
2223 "! reg_mentioned_p (operands[0], operands[3])"
2224 "*
2225 {
2226 /* strip the MEM. */
2227 operands[3] = XEXP (operands[3], 0);
2228 if (GET_CODE (operands[3]) == REG)
2229 return output_delayed_branch (\"calli %3\", operands, insn);
2230 return output_delayed_branch (\"call %3\", operands, insn);
2231 }")
2232
2233 (define_peephole
2234 [(set (match_operand:SI 0 "memory_operand" "=m")
2235 (match_operand:SI 1 "reg_or_0_operand" "rJf"))
2236 (set (match_operand 2 "" "=rf")
2237 (call (match_operand:SI 3 "call_insn_operand" "m")
2238 (match_operand 4 "" "i")))]
2239 ;;- Don't use operand 4 for most machines.
2240 ""
2241 "*
2242 {
2243 /* strip the MEM. */
2244 operands[3] = XEXP (operands[3], 0);
2245 if (GET_CODE (operands[3]) == REG)
2246 return output_delayed_branch (\"calli %3\", operands, insn);
2247 return output_delayed_branch (\"call %3\", operands, insn);
2248 }")
2249
2250 ;; Call subroutine returning any type.
2251
2252 (define_expand "untyped_call"
2253 [(parallel [(call (match_operand 0 "" "")
2254 (const_int 0))
2255 (match_operand 1 "" "")
2256 (match_operand 2 "" "")])]
2257 ""
2258 "
2259 {
2260 int i;
2261
2262 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2263
2264 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2265 {
2266 rtx set = XVECEXP (operands[2], 0, i);
2267 emit_move_insn (SET_DEST (set), SET_SRC (set));
2268 }
2269
2270 /* The optimizer does not know that the call sets the function value
2271 registers we stored in the result block. We avoid problems by
2272 claiming that all hard registers are used and clobbered at this
2273 point. */
2274 emit_insn (gen_blockage ());
2275
2276 DONE;
2277 }")
2278
2279 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2280 ;; all of memory. This blocks insns from being moved across this point.
2281
2282 (define_insn "blockage"
2283 [(unspec_volatile [(const_int 0)] 0)]
2284 ""
2285 "")
2286 \f
2287 (define_insn "nop"
2288 [(const_int 0)]
2289 ""
2290 "nop")
2291
2292 (define_insn "indirect_jump"
2293 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2294 ""
2295 "bri %0")
2296 \f
2297 ;;
2298 ;; A special insn that does the work to get setup just
2299 ;; before a table jump.
2300 ;;
2301 (define_insn ""
2302 [(set (match_operand:SI 0 "register_operand" "=r")
2303 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2304 (label_ref (match_operand 2 "" "")))))]
2305 ""
2306 "*
2307 {
2308 CC_STATUS_INIT;
2309 return \"orh %H2,%?r0,%?r31\;or %L2,%?r31,%?r31\;ld.l %?r31(%1),%0\";
2310 }")
2311
2312 (define_peephole
2313 [(set (match_operand:SI 0 "register_operand" "=rf")
2314 (match_operand:SI 1 "single_insn_src_p" "gfG"))
2315 (set (pc) (match_operand:SI 2 "register_operand" "r"))
2316 (use (label_ref (match_operand 3 "" "")))]
2317 "REGNO (operands[0]) != REGNO (operands[2])"
2318 "* return output_delayed_branch (\"bri %2\", operands, insn);")