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