1 ;; iq2000.md Machine Description for Vitesse IQ2000 processors
2 ;; Copyright (C) 2003-2024 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
6 ;; GCC 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 3, or (at your option)
11 ;; GCC 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.
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING3. If not see
18 ;; <http://www.gnu.org/licenses/>.
69 ;; UNSPEC values used in iq2000.md
72 ;; 1 movsi_us, get_fnaddr
74 ;; 20 builtin_setjmp_setup
76 ;; UNSPEC_VOLATILE values
80 ;; 4 exception_receiver
92 ;; ....................
96 ;; ....................
98 ;; Classification of each insn.
99 ;; branch conditional branch
100 ;; jump unconditional jump
101 ;; call unconditional call
102 ;; load load instruction(s)
103 ;; store store instruction(s)
104 ;; move data movement within same register set
105 ;; xfer transfer to/from coprocessor
106 ;; arith integer arithmetic instruction
107 ;; darith double precision integer arithmetic instructions
108 ;; imul integer multiply
109 ;; idiv integer divide
110 ;; icmp integer compare
111 ;; fadd floating point add/subtract
112 ;; fmul floating point multiply
113 ;; fmadd floating point multiply-add
114 ;; fdiv floating point divide
115 ;; fabs floating point absolute value
116 ;; fneg floating point negation
117 ;; fcmp floating point compare
118 ;; fcvt floating point convert
119 ;; fsqrt floating point square root
120 ;; multi multiword sequence (or user asm statements)
124 "unknown,branch,jump,call,load,store,move,xfer,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop"
125 (const_string "unknown"))
127 ;; Main data type used by the insn
128 (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
130 ;; Length (in # of bytes). A conditional branch is allowed only to a
131 ;; location within a signed 18-bit offset of the delay slot. If that
132 ;; provides too small a range, we use the `j' instruction. This
133 ;; instruction takes a 28-bit value, but that value is not an offset.
134 ;; Instead, it's bitwise-ored with the high-order four bits of the
135 ;; instruction in the delay slot, which means it cannot be used to
136 ;; cross a 256MB boundary. We could fall back on the jr
137 ;; instruction which allows full access to the entire address space,
138 ;; but we do not do so at present.
140 (define_attr "length" ""
141 (cond [(eq_attr "type" "branch")
142 (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
150 (const (symbol_ref "iq2000_cpu_attr")))
152 ;; Does the instruction have a mandatory delay slot? has_dslot
153 ;; Can the instruction be in a delay slot? ok_in_dslot
154 ;; Can the instruction not be in a delay slot? not_in_dslot
155 (define_attr "dslot" "has_dslot,ok_in_dslot,not_in_dslot"
156 (if_then_else (eq_attr "type" "branch,jump,call,xfer,fcmp")
157 (const_string "has_dslot")
158 (const_string "ok_in_dslot")))
160 ;; Attribute defining whether or not we can use the branch-likely instructions
162 (define_attr "branch_likely" "no,yes"
164 (if_then_else (match_test "GENERATE_BRANCHLIKELY")
166 (const_string "no"))))
168 ;; Is this a bbi instruction or not
169 (define_attr "bbi" "no,yes" (const_string "no"))
171 ;; Describe a user's asm statement.
172 (define_asm_attributes
173 [(set_attr "type" "multi")])
177 ;; .........................
179 ;; Delay slots, can't describe load/fcmp/xfer delay slots here
181 ;; .........................
183 (define_delay (eq_attr "type" "jump")
184 [(and (eq_attr "dslot" "ok_in_dslot") (eq_attr "length" "4"))
188 ;; GAS refuses to assemble bbi[n]l. So for bbi instructions, do not
189 ;; allow them to annul-false.
190 (define_delay (and (eq_attr "type" "branch") (eq_attr "bbi" "no"))
191 [(and (eq_attr "dslot" "ok_in_dslot") (eq_attr "length" "4"))
193 (and (eq_attr "branch_likely" "yes") (and (eq_attr "dslot" "ok_in_dslot") (eq_attr "length" "4")))])
195 (define_delay (and (eq_attr "type" "branch") (eq_attr "bbi" "yes"))
196 [(and (eq_attr "dslot" "ok_in_dslot") (eq_attr "length" "4"))
200 (define_delay (eq_attr "type" "call")
201 [(and (eq_attr "dslot" "ok_in_dslot") (eq_attr "length" "4"))
205 (include "predicates.md")
206 (include "constraints.md")
209 ;; .........................
213 ;; .........................
215 (define_automaton "iq2000")
216 (define_cpu_unit "core,memory" "iq2000")
218 (define_insn_reservation "nonmemory" 1
219 (eq_attr "type" "!load,move,store,xfer")
222 (define_insn_reservation "iq2000_load_move" 3
223 (and (eq_attr "type" "load,move")
224 (eq_attr "cpu" "iq2000"))
227 (define_insn_reservation "other_load_move" 1
228 (and (eq_attr "type" "load,move")
229 (eq_attr "cpu" "!iq2000"))
232 (define_insn_reservation "store" 1
233 (eq_attr "type" "store")
236 (define_insn_reservation "xfer" 2
237 (eq_attr "type" "xfer")
241 ;; ....................
245 ;; ....................
249 [(trap_if (const_int 1) (const_int 0))]
257 ;; ....................
261 ;; ....................
264 (define_expand "addsi3"
265 [(set (match_operand:SI 0 "register_operand" "=d")
266 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
267 (match_operand:SI 2 "arith_operand" "dI")))]
271 (define_insn "addsi3_internal"
272 [(set (match_operand:SI 0 "register_operand" "=d,d")
273 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
274 (match_operand:SI 2 "arith_operand" "d,I")))]
279 [(set_attr "type" "arith")
280 (set_attr "mode" "SI")])
283 ;; ....................
287 ;; ....................
290 (define_expand "subsi3"
291 [(set (match_operand:SI 0 "register_operand" "=d")
292 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
293 (match_operand:SI 2 "arith_operand" "dI")))]
297 (define_insn "subsi3_internal"
298 [(set (match_operand:SI 0 "register_operand" "=d,d")
299 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")
300 (match_operand:SI 2 "arith_operand" "d,I")))]
305 [(set_attr "type" "arith")
306 (set_attr "mode" "SI")])
309 ;; ....................
311 ;; NEGATION and ONE'S COMPLEMENT
313 ;; ....................
315 (define_insn "negsi2"
316 [(set (match_operand:SI 0 "register_operand" "=d")
317 (neg:SI (match_operand:SI 1 "register_operand" "d")))]
321 operands[2] = const0_rtx;
322 return \"subu\\t%0,%z2,%1\";
324 [(set_attr "type" "arith")
325 (set_attr "mode" "SI")])
327 (define_insn "one_cmplsi2"
328 [(set (match_operand:SI 0 "register_operand" "=d")
329 (not:SI (match_operand:SI 1 "register_operand" "d")))]
333 operands[2] = const0_rtx;
334 return \"nor\\t%0,%z2,%1\";
336 [(set_attr "type" "arith")
337 (set_attr "mode" "SI")])
340 ;; ....................
344 ;; ....................
347 (define_expand "andsi3"
348 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
349 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d,d")
350 (match_operand:SI 2 "nonmemory_operand" "d,K,N")))]
355 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
356 (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d,d")
357 (match_operand:SI 2 "nonmemory_operand" "d,K,N")))]
361 if (which_alternative == 0)
362 return \"and\\t%0,%1,%2\";
363 else if (which_alternative == 1)
364 return \"andi\\t%0,%1,%x2\";
365 else if (which_alternative == 2)
367 if ((INTVAL (operands[2]) & 0xffff) == 0xffff)
369 operands[2] = GEN_INT (INTVAL (operands[2]) >> 16);
370 return \"andoui\\t%0,%1,%x2\";
374 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
375 return \"andoi\\t%0,%1,%x2\";
381 [(set_attr "type" "arith")
382 (set_attr "mode" "SI")])
384 (define_expand "iorsi3"
385 [(set (match_operand:SI 0 "register_operand" "=d,d")
386 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
387 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
392 [(set (match_operand:SI 0 "register_operand" "=d,d")
393 (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
394 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
399 [(set_attr "type" "arith")
400 (set_attr "mode" "SI")])
402 (define_expand "xorsi3"
403 [(set (match_operand:SI 0 "register_operand" "=d,d")
404 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
405 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
410 [(set (match_operand:SI 0 "register_operand" "=d,d")
411 (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
412 (match_operand:SI 2 "uns_arith_operand" "d,K")))]
417 [(set_attr "type" "arith")
418 (set_attr "mode" "SI")])
420 (define_insn "*norsi3"
421 [(set (match_operand:SI 0 "register_operand" "=d")
422 (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
423 (not:SI (match_operand:SI 2 "register_operand" "d"))))]
426 [(set_attr "type" "arith")
427 (set_attr "mode" "SI")])
430 ;; ....................
434 ;; ....................
437 ;; Those for integer source operand are ordered widest source type first.
439 (define_expand "zero_extendhisi2"
440 [(set (match_operand:SI 0 "register_operand" "")
441 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
446 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
447 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
451 if (which_alternative == 0)
452 return \"andi\\t%0,%1,0xffff\";
454 return iq2000_move_1word (operands, insn, TRUE);
456 [(set_attr "type" "arith,load,load")
457 (set_attr "mode" "SI")
458 (set_attr "length" "4,4,8")])
460 (define_expand "zero_extendqihi2"
461 [(set (match_operand:HI 0 "register_operand" "")
462 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
467 [(set (match_operand:HI 0 "register_operand" "=d,d,d")
468 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
472 if (which_alternative == 0)
473 return \"andi\\t%0,%1,0x00ff\";
475 return iq2000_move_1word (operands, insn, TRUE);
477 [(set_attr "type" "arith,load,load")
478 (set_attr "mode" "HI")
479 (set_attr "length" "4,4,8")])
481 (define_expand "zero_extendqisi2"
482 [(set (match_operand:SI 0 "register_operand" "")
483 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
488 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
489 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
493 if (which_alternative == 0)
494 return \"andi\\t%0,%1,0x00ff\";
496 return iq2000_move_1word (operands, insn, TRUE);
498 [(set_attr "type" "arith,load,load")
499 (set_attr "mode" "SI")
500 (set_attr "length" "4,4,8")])
503 ;; ....................
507 ;; ....................
510 ;; Those for integer source operand are ordered widest source type first.
512 ;; These patterns originally accepted general_operands, however, slightly
513 ;; better code is generated by only accepting register_operands, and then
514 ;; letting combine generate the lh and lb insns.
516 (define_expand "extendhisi2"
517 [(set (match_operand:SI 0 "register_operand" "")
518 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
522 if (optimize && GET_CODE (operands[1]) == MEM)
523 operands[1] = force_not_mem (operands[1]);
525 if (GET_CODE (operands[1]) != MEM)
527 rtx op1 = gen_lowpart (SImode, operands[1]);
528 rtx temp = gen_reg_rtx (SImode);
529 rtx shift = GEN_INT (16);
531 emit_insn (gen_ashlsi3 (temp, op1, shift));
532 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
537 (define_insn "extendhisi2_internal"
538 [(set (match_operand:SI 0 "register_operand" "=d,d")
539 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
541 "* return iq2000_move_1word (operands, insn, FALSE);"
542 [(set_attr "type" "load")
543 (set_attr "mode" "SI")
544 (set_attr "length" "4,8")])
546 (define_expand "extendqihi2"
547 [(set (match_operand:HI 0 "register_operand" "")
548 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
552 if (optimize && GET_CODE (operands[1]) == MEM)
553 operands[1] = force_not_mem (operands[1]);
555 if (GET_CODE (operands[1]) != MEM)
557 rtx op0 = gen_lowpart (SImode, operands[0]);
558 rtx op1 = gen_lowpart (SImode, operands[1]);
559 rtx temp = gen_reg_rtx (SImode);
560 rtx shift = GEN_INT (24);
562 emit_insn (gen_ashlsi3 (temp, op1, shift));
563 emit_insn (gen_ashrsi3 (op0, temp, shift));
568 (define_insn "extendqihi2_internal"
569 [(set (match_operand:HI 0 "register_operand" "=d,d")
570 (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
572 "* return iq2000_move_1word (operands, insn, FALSE);"
573 [(set_attr "type" "load")
574 (set_attr "mode" "SI")
575 (set_attr "length" "4,8")])
578 (define_expand "extendqisi2"
579 [(set (match_operand:SI 0 "register_operand" "")
580 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
584 if (optimize && GET_CODE (operands[1]) == MEM)
585 operands[1] = force_not_mem (operands[1]);
587 if (GET_CODE (operands[1]) != MEM)
589 rtx op1 = gen_lowpart (SImode, operands[1]);
590 rtx temp = gen_reg_rtx (SImode);
591 rtx shift = GEN_INT (24);
593 emit_insn (gen_ashlsi3 (temp, op1, shift));
594 emit_insn (gen_ashrsi3 (operands[0], temp, shift));
599 (define_insn "extendqisi2_insn"
600 [(set (match_operand:SI 0 "register_operand" "=d,d")
601 (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
603 "* return iq2000_move_1word (operands, insn, FALSE);"
604 [(set_attr "type" "load")
605 (set_attr "mode" "SI")
606 (set_attr "length" "4,8")])
609 ;; ........................
611 ;; BIT FIELD EXTRACTION
613 ;; ........................
616 [(set (match_operand:SI 0 "register_operand" "=r")
617 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
618 (match_operand:SI 2 "const_int_operand" "O")
619 (match_operand:SI 3 "const_int_operand" "O")))]
624 value[2] = INTVAL (operands[2]);
625 value[3] = INTVAL (operands[3]);
626 operands[2] = GEN_INT ((value[3]));
627 operands[3] = GEN_INT ((32 - value[2]));
628 return \"ram\\t%0,%1,%2,%3,0x0\";
630 [(set_attr "type" "arith")])
633 ;; ....................
637 ;; ....................
639 /* Take care of constants that don't fit in single instruction */
641 [(set (match_operand:SI 0 "register_operand" "")
642 (match_operand:SI 1 "general_operand" ""))]
643 "(reload_in_progress || reload_completed)
644 && large_int (operands[1], SImode)"
647 (high:SI (match_dup 1)))
649 (lo_sum:SI (match_dup 0)
653 ;; ??? iq2000_move_1word has support for HIGH, so this pattern may be
657 [(set (match_operand:SI 0 "register_operand" "=r")
658 (high:SI (match_operand:SI 1 "immediate_operand" "")))]
660 "lui\\t%0,%%hi(%1) # high"
661 [(set_attr "type" "move")])
664 [(set (match_operand:SI 0 "register_operand" "=r")
665 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
666 (match_operand:SI 2 "immediate_operand" "")))]
668 "addiu\\t%0,%1,%%lo(%2) # low"
669 [(set_attr "type" "arith")
670 (set_attr "mode" "SI")])
672 ;; 32-bit Integer moves
675 [(set (match_operand:SI 0 "register_operand" "")
676 (match_operand:SI 1 "large_int" ""))]
677 "reload_in_progress | reload_completed"
681 (ior:SI (match_dup 0)
685 operands[2] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
688 operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16);
691 ;; Unlike most other insns, the move insns can't be split with
692 ;; different predicates, because register spilling and other parts of
693 ;; the compiler, have memoized the insn number already.
695 (define_expand "movsi"
696 [(set (match_operand:SI 0 "nonimmediate_operand" "")
697 (match_operand:SI 1 "general_operand" ""))]
701 if (iq2000_check_split (operands[1], SImode))
703 machine_mode mode = GET_MODE (operands[0]);
704 rtx tem = ((reload_in_progress | reload_completed)
705 ? operands[0] : gen_reg_rtx (mode));
707 emit_insn (gen_rtx_SET (tem, gen_rtx_HIGH (mode, operands[1])));
709 operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
712 if ((reload_in_progress | reload_completed) == 0
713 && !register_operand (operands[0], SImode)
714 && !register_operand (operands[1], SImode)
715 && (GET_CODE (operands[1]) != CONST_INT
716 || INTVAL (operands[1]) != 0))
718 rtx temp = force_reg (SImode, operands[1]);
719 emit_move_insn (operands[0], temp);
723 /* Take care of constants that don't fit in single instruction */
724 if ((reload_in_progress || reload_completed)
725 && CONSTANT_P (operands[1])
726 && GET_CODE (operands[1]) != HIGH
727 && GET_CODE (operands[1]) != LO_SUM
728 && ! SMALL_INT_UNSIGNED (operands[1]))
730 rtx tem = ((reload_in_progress | reload_completed)
731 ? operands[0] : gen_reg_rtx (SImode));
733 emit_insn (gen_rtx_SET (tem, gen_rtx_HIGH (SImode, operands[1])));
734 operands[1] = gen_rtx_LO_SUM (SImode, tem, operands[1]);
738 ;; The difference between these two is whether or not ints are allowed
739 ;; in FP registers (off by default, use -mdebugh to enable).
741 (define_insn "movsi_internal2"
742 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m")
743 (match_operand:SI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ"))]
744 "(register_operand (operands[0], SImode)
745 || register_operand (operands[1], SImode)
746 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
747 "* return iq2000_move_1word (operands, insn, FALSE);"
748 [(set_attr "type" "move,arith,arith,load,load,store,store")
749 (set_attr "mode" "SI")
750 (set_attr "length" "4,4,8,8,8,4,8")])
752 ;; 16-bit Integer moves
754 ;; Unlike most other insns, the move insns can't be split with
755 ;; different predicates, because register spilling and other parts of
756 ;; the compiler, have memoized the insn number already.
757 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
759 (define_expand "movhi"
760 [(set (match_operand:HI 0 "nonimmediate_operand" "")
761 (match_operand:HI 1 "general_operand" ""))]
765 if ((reload_in_progress | reload_completed) == 0
766 && !register_operand (operands[0], HImode)
767 && !register_operand (operands[1], HImode)
768 && ((GET_CODE (operands[1]) != CONST_INT
769 || INTVAL (operands[1]) != 0)))
771 rtx temp = force_reg (HImode, operands[1]);
772 emit_move_insn (operands[0], temp);
777 ;; The difference between these two is whether or not ints are allowed
778 ;; in FP registers (off by default, use -mdebugh to enable).
780 (define_insn "movhi_internal2"
781 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m")
782 (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ"))]
783 "(register_operand (operands[0], HImode)
784 || register_operand (operands[1], HImode)
785 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
786 "* return iq2000_move_1word (operands, insn, TRUE);"
787 [(set_attr "type" "move,arith,load,load,store,store")
788 (set_attr "mode" "HI")
789 (set_attr "length" "4,4,4,8,4,8")])
791 ;; 8-bit Integer moves
793 ;; Unlike most other insns, the move insns can't be split with
794 ;; different predicates, because register spilling and other parts of
795 ;; the compiler, have memoized the insn number already.
796 ;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined
798 (define_expand "movqi"
799 [(set (match_operand:QI 0 "nonimmediate_operand" "")
800 (match_operand:QI 1 "general_operand" ""))]
804 if ((reload_in_progress | reload_completed) == 0
805 && !register_operand (operands[0], QImode)
806 && !register_operand (operands[1], QImode)
807 && (GET_CODE (operands[1]) != CONST_INT
808 || INTVAL (operands[1]) != 0))
810 rtx temp = force_reg (QImode, operands[1]);
811 emit_move_insn (operands[0], temp);
816 ;; The difference between these two is whether or not ints are allowed
817 ;; in FP registers (off by default, use -mdebugh to enable).
819 (define_insn "movqi_internal2"
820 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m")
821 (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ"))]
822 "(register_operand (operands[0], QImode)
823 || register_operand (operands[1], QImode)
824 || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
825 "* return iq2000_move_1word (operands, insn, TRUE);"
826 [(set_attr "type" "move,arith,load,load,store,store")
827 (set_attr "mode" "QI")
828 (set_attr "length" "4,4,4,8,4,8")])
830 ;; 32-bit floating point moves
832 (define_expand "movsf"
833 [(set (match_operand:SF 0 "general_operand" "")
834 (match_operand:SF 1 "general_operand" ""))]
838 if (!reload_in_progress
840 && GET_CODE (operands[0]) == MEM
841 && (GET_CODE (operands[1]) == MEM
842 || GET_CODE (operands[1]) == CONST_DOUBLE))
843 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
845 /* Take care of reg <- SF constant */
846 if ( const_double_operand (operands[1], GET_MODE (operands[1]) ) )
848 emit_insn (gen_movsf_high (operands[0], operands[1]));
849 emit_insn (gen_movsf_lo_sum (operands[0], operands[0], operands[1]));
854 (define_insn "movsf_lo_sum"
855 [(set (match_operand:SF 0 "register_operand" "=r")
856 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
857 (match_operand:SF 2 "const_double_operand" "")))]
863 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[2]), i);
864 operands[2] = GEN_INT (i);
865 return \"addiu\\t%0,%1,%%lo(%2) # low\";
867 [(set_attr "length" "4")
868 (set_attr "type" "arith")])
870 (define_insn "movsf_high"
871 [(set (match_operand:SF 0 "register_operand" "=r")
872 (high:SF (match_operand:SF 1 "const_double_operand" "")))]
878 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), i);
879 operands[1] = GEN_INT (i);
880 return \"lui\\t%0,%%hi(%1) # high\";
882 [(set_attr "length" "4")
883 (set_attr "type" "arith")])
885 (define_insn "*movsf_internal"
886 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
887 (match_operand:SF 1 "nonimmediate_operand" "r,m,r"))]
888 "!memory_operand (operands[0], SFmode) || !memory_operand (operands[1], SFmode)"
891 iq2000_fill_delay_slot (\"\", DELAY_LOAD, operands, insn);
892 if (which_alternative == 0)
893 return \"or\\t%0,%1,%1\";
894 else if (which_alternative == 1)
895 return \"lw\\t%0,%1\";
896 else if (which_alternative == 2)
897 return \"sw\\t%1,%0\";
901 [(set_attr "length" "4,4,4")
902 (set_attr "type" "arith,load,store")]
906 ;; ....................
910 ;; ....................
912 (define_expand "ashlsi3"
913 [(set (match_operand:SI 0 "register_operand" "=d")
914 (ashift:SI (match_operand:SI 1 "register_operand" "d")
915 (match_operand:SI 2 "arith_operand" "dI")))]
919 (define_insn "ashlsi3_internal1"
920 [(set (match_operand:SI 0 "register_operand" "=d")
921 (ashift:SI (match_operand:SI 1 "register_operand" "d")
922 (match_operand:SI 2 "arith_operand" "dI")))]
926 if (GET_CODE (operands[2]) == CONST_INT)
928 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
929 return \"sll\\t%0,%1,%2\";
932 return \"sllv\\t%0,%1,%2\";
934 [(set_attr "type" "arith")
935 (set_attr "mode" "SI")])
937 (define_expand "ashrsi3"
938 [(set (match_operand:SI 0 "register_operand" "=d")
939 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
940 (match_operand:SI 2 "arith_operand" "dI")))]
944 (define_insn "ashrsi3_internal1"
945 [(set (match_operand:SI 0 "register_operand" "=d")
946 (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
947 (match_operand:SI 2 "arith_operand" "dI")))]
951 if (GET_CODE (operands[2]) == CONST_INT)
953 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
954 return \"sra\\t%0,%1,%2\";
957 return \"srav\\t%0,%1,%2\";
959 [(set_attr "type" "arith")
960 (set_attr "mode" "SI")])
962 (define_expand "lshrsi3"
963 [(set (match_operand:SI 0 "register_operand" "=d")
964 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
965 (match_operand:SI 2 "arith_operand" "dI")))]
969 (define_insn "lshrsi3_internal1"
970 [(set (match_operand:SI 0 "register_operand" "=d")
971 (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
972 (match_operand:SI 2 "arith_operand" "dI")))]
976 if (GET_CODE (operands[2]) == CONST_INT)
978 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
979 return \"srl\\t%0,%1,%2\";
982 return \"srlv\\t%0,%1,%2\";
984 [(set_attr "type" "arith")
985 (set_attr "mode" "SI")])
988 (define_insn "rotrsi3"
989 [(set (match_operand:SI 0 "register_operand" "=r")
990 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
991 (match_operand:SI 2 "uns_arith_constant" "O")))]
993 "ram %0,%1,%2,0x0,0x0"
994 [(set_attr "type" "arith")])
998 ;; ....................
1000 ;; CONDITIONAL BRANCHES
1002 ;; ....................
1004 (define_expand "cbranchsi4"
1007 (match_operator 0 "ordered_comparison_operator"
1008 [(match_operand:SI 1 "register_operand")
1009 (match_operand:SI 2 "reg_or_const_operand")])
1010 (label_ref (match_operand 3 ""))
1015 gen_conditional_branch (operands, SImode);
1020 ;; Conditional branches on comparisons with zero.
1022 (define_insn "branch_zero"
1025 (match_operator 0 "cmp_op"
1026 [(match_operand:SI 2 "register_operand" "d")
1028 (label_ref (match_operand 1 "" ""))
1033 return iq2000_output_conditional_branch (insn,
1035 /*two_operands_p=*/0,
1038 get_attr_length (insn));
1040 [(set_attr "type" "branch")
1041 (set_attr "mode" "none")])
1043 (define_insn "branch_zero_inverted"
1046 (match_operator 0 "cmp_op"
1047 [(match_operand:SI 2 "register_operand" "d")
1050 (label_ref (match_operand 1 "" ""))))]
1054 return iq2000_output_conditional_branch (insn,
1056 /*two_operands_p=*/0,
1059 get_attr_length (insn));
1061 [(set_attr "type" "branch")
1062 (set_attr "mode" "none")])
1064 ;; Conditional branch on equality comparison.
1066 (define_insn "branch_equality"
1069 (match_operator 0 "equality_op"
1070 [(match_operand:SI 2 "register_operand" "d")
1071 (match_operand:SI 3 "register_operand" "d")])
1072 (label_ref (match_operand 1 "" ""))
1077 return iq2000_output_conditional_branch (insn,
1079 /*two_operands_p=*/1,
1082 get_attr_length (insn));
1084 [(set_attr "type" "branch")
1085 (set_attr "mode" "none")])
1087 (define_insn "branch_equality_inverted"
1090 (match_operator 0 "equality_op"
1091 [(match_operand:SI 2 "register_operand" "d")
1092 (match_operand:SI 3 "register_operand" "d")])
1094 (label_ref (match_operand 1 "" ""))))]
1098 return iq2000_output_conditional_branch (insn,
1100 /*two_operands_p=*/1,
1103 get_attr_length (insn));
1105 [(set_attr "type" "branch")
1106 (set_attr "mode" "none")])
1109 ;; Recognize bbi and bbin instructions. These use two unusual template
1110 ;; patterns, %Ax and %Px. %Ax outputs an 'i' if operand `x' is a LABEL_REF
1111 ;; otherwise it outputs an 'in'. %Px does nothing if `x' is PC
1112 ;; and outputs the operand if `x' is a LABEL_REF.
1117 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1119 (match_operand:SI 1 "arith_operand" "I"))
1121 (match_operand 2 "pc_or_label_operand" "")
1122 (match_operand 3 "pc_or_label_operand" "")))]
1124 "bb%A2\\t%0(31-%1),%P2%P3"
1125 [(set_attr "length" "4")
1126 (set_attr "type" "branch")
1127 (set_attr "bbi" "yes")])
1132 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1134 (match_operand:SI 1 "arith_operand" "I"))
1136 (match_operand 2 "pc_or_label_operand" "")
1137 (match_operand 3 "pc_or_label_operand" "")))]
1139 "bb%A3\\t%0(31-%1),%P2%P3"
1140 [(set_attr "length" "4")
1141 (set_attr "type" "branch")
1142 (set_attr "bbi" "yes")])
1147 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1149 (match_operand:SI 1 "arith_operand" "I"))
1151 (match_operand 2 "pc_or_label_operand" "")
1152 (match_operand 3 "pc_or_label_operand" "")))]
1154 "bb%A2\\t%0(31-%1),%P2%P3"
1155 [(set_attr "length" "4")
1156 (set_attr "type" "branch")
1157 (set_attr "bbi" "yes")])
1162 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1164 (match_operand:SI 1 "arith_operand" "I"))
1166 (match_operand 2 "pc_or_label_operand" "")
1167 (match_operand 3 "pc_or_label_operand" "")))]
1169 "bb%A3\\t%0(31-%1),%P2%P3"
1170 [(set_attr "length" "4")
1171 (set_attr "type" "branch")
1172 (set_attr "bbi" "yes")])
1177 (eq (and:SI (match_operand:SI 0 "register_operand" "r")
1178 (match_operand:SI 1 "power_of_2_operand" "I"))
1180 (match_operand 2 "pc_or_label_operand" "")
1181 (match_operand 3 "pc_or_label_operand" "")))]
1183 "bb%A3\\t%0(%p1),%P2%P3"
1184 [(set_attr "length" "4")
1185 (set_attr "type" "branch")
1186 (set_attr "bbi" "yes")])
1191 (ne (and:SI (match_operand:SI 0 "register_operand" "r")
1192 (match_operand:SI 1 "power_of_2_operand" "I"))
1194 (match_operand 2 "pc_or_label_operand" "")
1195 (match_operand 3 "pc_or_label_operand" "")))]
1197 "bb%A2\\t%0(%p1),%P2%P3"
1198 [(set_attr "length" "4")
1199 (set_attr "type" "branch")
1200 (set_attr "bbi" "yes")])
1203 ;; ....................
1205 ;; SETTING A REGISTER FROM A COMPARISON
1207 ;; ....................
1209 (define_expand "cstoresi4"
1210 [(set (match_operand:SI 0 "register_operand" "=d")
1211 (match_operator:SI 1 "ordered_comparison_operator"
1212 [(match_operand:SI 2 "register_operand")
1213 (match_operand:SI 3 "reg_or_const_operand")]))]
1217 gen_int_relational (GET_CODE (operands[1]), operands[0],
1218 operands[2], operands[3], (int *)0);
1222 (define_insn "seq_si_zero"
1223 [(set (match_operand:SI 0 "register_operand" "=d")
1224 (eq:SI (match_operand:SI 1 "register_operand" "d")
1228 [(set_attr "type" "arith")
1229 (set_attr "mode" "SI")])
1231 (define_insn "sne_si_zero"
1232 [(set (match_operand:SI 0 "register_operand" "=d")
1233 (ne:SI (match_operand:SI 1 "register_operand" "d")
1237 [(set_attr "type" "arith")
1238 (set_attr "mode" "SI")])
1240 (define_insn "sgt_si"
1241 [(set (match_operand:SI 0 "register_operand" "=d,d")
1242 (gt:SI (match_operand:SI 1 "register_operand" "d,d")
1243 (match_operand:SI 2 "reg_or_0_operand" "d,J")))]
1248 [(set_attr "type" "arith,arith")
1249 (set_attr "mode" "SI,SI")])
1251 (define_insn "slt_si"
1252 [(set (match_operand:SI 0 "register_operand" "=d,d")
1253 (lt:SI (match_operand:SI 1 "register_operand" "d,d")
1254 (match_operand:SI 2 "arith_operand" "d,I")))]
1259 [(set_attr "type" "arith,arith")
1260 (set_attr "mode" "SI,SI")])
1262 (define_insn "sle_si_const"
1263 [(set (match_operand:SI 0 "register_operand" "=d")
1264 (le:SI (match_operand:SI 1 "register_operand" "d")
1265 (match_operand:SI 2 "small_int" "I")))]
1266 "INTVAL (operands[2]) < 32767"
1269 operands[2] = GEN_INT (INTVAL (operands[2])+1);
1270 return \"slti\\t%0,%1,%2\";
1272 [(set_attr "type" "arith")
1273 (set_attr "mode" "SI")])
1275 (define_insn "sgtu_si"
1276 [(set (match_operand:SI 0 "register_operand" "=d")
1277 (gtu:SI (match_operand:SI 1 "register_operand" "d")
1278 (match_operand:SI 2 "reg_or_0_operand" "dJ")))]
1281 [(set_attr "type" "arith")
1282 (set_attr "mode" "SI")])
1284 (define_insn "sltu_si"
1285 [(set (match_operand:SI 0 "register_operand" "=d,d")
1286 (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
1287 (match_operand:SI 2 "arith_operand" "d,I")))]
1292 [(set_attr "type" "arith,arith")
1293 (set_attr "mode" "SI,SI")])
1295 (define_insn "sleu_si_const"
1296 [(set (match_operand:SI 0 "register_operand" "=d")
1297 (leu:SI (match_operand:SI 1 "register_operand" "d")
1298 (match_operand:SI 2 "small_int" "I")))]
1299 "INTVAL (operands[2]) < 32767"
1302 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
1303 return \"sltiu\\t%0,%1,%2\";
1305 [(set_attr "type" "arith")
1306 (set_attr "mode" "SI")])
1310 ;; ....................
1312 ;; UNCONDITIONAL BRANCHES
1314 ;; ....................
1316 ;; Unconditional branches.
1320 (label_ref (match_operand 0 "" "")))]
1324 if (GET_CODE (operands[0]) == REG)
1327 /* return \"b\\t%l0\";*/
1329 [(set_attr "type" "jump")
1330 (set_attr "mode" "none")])
1332 (define_expand "indirect_jump"
1333 [(set (pc) (match_operand 0 "register_operand" "d"))]
1339 if (operands[0]) /* eliminate unused code warnings */
1342 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
1343 operands[0] = copy_to_mode_reg (Pmode, dest);
1345 if (!(Pmode == DImode))
1346 emit_jump_insn (gen_indirect_jump_internal1 (operands[0]));
1348 internal_error (\"unimplemented functionality\");
1354 (define_insn "indirect_jump_internal1"
1355 [(set (pc) (match_operand:SI 0 "register_operand" "d"))]
1356 "!(Pmode == DImode)"
1358 [(set_attr "type" "jump")
1359 (set_attr "mode" "none")])
1361 (define_expand "tablejump"
1363 (match_operand 0 "register_operand" "d"))
1364 (use (label_ref (match_operand 1 "" "")))]
1368 if (operands[0]) /* eliminate unused code warnings */
1370 gcc_assert (GET_MODE (operands[0]) == Pmode);
1372 if (!(Pmode == DImode))
1373 emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
1375 internal_error (\"unimplemented functionality\");
1381 (define_insn "tablejump_internal1"
1383 (match_operand:SI 0 "register_operand" "d"))
1384 (use (label_ref (match_operand 1 "" "")))]
1385 "!(Pmode == DImode)"
1387 [(set_attr "type" "jump")
1388 (set_attr "mode" "none")])
1390 (define_expand "tablejump_internal3"
1391 [(parallel [(set (pc)
1392 (plus:SI (match_operand:SI 0 "register_operand" "d")
1393 (label_ref:SI (match_operand 1 "" ""))))
1394 (use (label_ref:SI (match_dup 1)))])]
1398 ;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
1399 ;;; it is not valid. ??? With the USE, the condition tests may not be required
1402 ;;; ??? The length depends on the ABI. It is two for o32, and one for n32.
1403 ;;; We just use the conservative number here.
1407 (plus:SI (match_operand:SI 0 "register_operand" "d")
1408 (label_ref:SI (match_operand 1 "" ""))))
1409 (use (label_ref:SI (match_dup 1)))]
1410 "!(Pmode == DImode) && NEXT_INSN (as_a <rtx_insn *> (operands[1])) != 0
1411 && GET_CODE (PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[1])))) == ADDR_DIFF_VEC"
1416 [(set_attr "type" "jump")
1417 (set_attr "mode" "none")
1418 (set_attr "length" "8")])
1421 ;; ....................
1423 ;; Function prologue/epilogue
1425 ;; ....................
1428 (define_expand "prologue"
1433 if (iq2000_isa >= 0) /* avoid unused code warnings */
1435 iq2000_expand_prologue ();
1440 ;; Block any insns from being moved before this point, since the
1441 ;; profiling call to mcount can use various registers that aren't
1442 ;; saved or used to pass arguments.
1444 (define_insn "blockage"
1445 [(unspec_volatile [(const_int 0)] 0)]
1448 [(set_attr "type" "unknown")
1449 (set_attr "mode" "none")
1450 (set_attr "length" "0")])
1452 (define_expand "epilogue"
1457 if (iq2000_isa >= 0) /* avoid unused code warnings */
1459 iq2000_expand_epilogue ();
1464 ;; Trivial return. Make it look like a normal return insn as that
1465 ;; allows jump optimizations to work better .
1466 (define_insn "return"
1468 "iq2000_can_use_return_insn ()"
1470 [(set_attr "type" "jump")
1471 (set_attr "mode" "none")])
1475 (define_insn "return_internal"
1476 [(use (match_operand 0 "pmode_register_operand" ""))
1483 [(set_attr "type" "jump")
1484 (set_attr "mode" "none")])
1486 (define_insn "eh_return_internal"
1493 [(set_attr "type" "jump")
1494 (set_attr "mode" "none")])
1496 (define_expand "eh_return"
1497 [(use (match_operand:SI 0 "register_operand" "r"))]
1501 iq2000_expand_eh_return (operands[0]);
1507 ;; ....................
1511 ;; ....................
1513 ;; calls.cc now passes a third argument, make saber happy
1515 (define_expand "call"
1516 [(parallel [(call (match_operand 0 "memory_operand" "m")
1517 (match_operand 1 "" "i"))
1518 (clobber (reg:SI 31))
1519 (use (match_operand 2 "" "")) ;; next_arg_reg
1520 (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
1526 if (operands[0]) /* eliminate unused code warnings */
1528 addr = XEXP (operands[0], 0);
1529 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr)))
1530 || ! call_insn_operand (addr, VOIDmode))
1531 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
1533 /* In order to pass small structures by value in registers
1534 compatibly with the IQ2000 compiler, we need to shift the value
1535 into the high part of the register. Function_arg has encoded
1536 a PARALLEL rtx, holding a vector of adjustments to be made
1537 as the next_arg_reg variable, so we split up the insns,
1538 and emit them separately. */
1540 if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
1542 rtvec adjust = XVEC (operands[2], 0);
1543 int num = GET_NUM_ELEM (adjust);
1546 for (i = 0; i < num; i++)
1547 emit_insn (RTVEC_ELT (adjust, i));
1550 emit_call_insn (gen_call_internal0 (operands[0], operands[1],
1551 gen_rtx_REG (SImode,
1552 GP_REG_FIRST + 31)));
1557 (define_expand "call_internal0"
1558 [(parallel [(call (match_operand 0 "" "")
1559 (match_operand 1 "" ""))
1560 (clobber (match_operand:SI 2 "" ""))])]
1564 (define_insn "call_internal1"
1565 [(call (mem (match_operand 0 "call_insn_operand" "ri"))
1566 (match_operand 1 "" "i"))
1567 (clobber (match_operand:SI 2 "register_operand" "=d"))]
1571 rtx target = operands[0];
1573 if (GET_CODE (target) == CONST_INT)
1574 return \"li\\t%@,%0\\n\\tjalr\\t%2,%@\";
1575 else if (CONSTANT_ADDRESS_P (target))
1576 return \"jal\\t%0\";
1578 return \"jalr\\t%2,%0\";
1580 [(set_attr "type" "call")
1581 (set_attr "mode" "none")])
1583 ;; calls.cc now passes a fourth argument, make saber happy
1585 (define_expand "call_value"
1586 [(parallel [(set (match_operand 0 "register_operand" "=d")
1587 (call (match_operand 1 "memory_operand" "m")
1588 (match_operand 2 "" "i")))
1589 (clobber (reg:SI 31))
1590 (use (match_operand 3 "" ""))])] ;; next_arg_reg
1596 if (operands[0]) /* eliminate unused code warning */
1598 addr = XEXP (operands[1], 0);
1599 if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr)))
1600 || ! call_insn_operand (addr, VOIDmode))
1601 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
1603 /* In order to pass small structures by value in registers
1604 compatibly with the IQ2000 compiler, we need to shift the value
1605 into the high part of the register. Function_arg has encoded
1606 a PARALLEL rtx, holding a vector of adjustments to be made
1607 as the next_arg_reg variable, so we split up the insns,
1608 and emit them separately. */
1610 if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
1612 rtvec adjust = XVEC (operands[3], 0);
1613 int num = GET_NUM_ELEM (adjust);
1616 for (i = 0; i < num; i++)
1617 emit_insn (RTVEC_ELT (adjust, i));
1620 if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
1622 emit_call_insn (gen_call_value_multiple_internal0
1623 (XEXP (XVECEXP (operands[0], 0, 0), 0),
1624 operands[1], operands[2],
1625 XEXP (XVECEXP (operands[0], 0, 1), 0),
1626 gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
1630 /* We have a call returning a DImode structure in an FP reg.
1631 Strip off the now unnecessary PARALLEL. */
1632 if (GET_CODE (operands[0]) == PARALLEL)
1633 operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
1635 emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
1636 gen_rtx_REG (SImode,
1637 GP_REG_FIRST + 31)));
1643 (define_expand "call_value_internal0"
1644 [(parallel [(set (match_operand 0 "" "")
1645 (call (match_operand 1 "" "")
1646 (match_operand 2 "" "")))
1647 (clobber (match_operand:SI 3 "" ""))])]
1651 (define_insn "call_value_internal1"
1652 [(set (match_operand 0 "register_operand" "=d")
1653 (call (mem (match_operand 1 "call_insn_operand" "r"))
1654 (match_operand 2 "" "i")))
1655 (clobber (match_operand:SI 3 "register_operand" "=d"))]
1659 rtx target = operands[1];
1661 if (GET_CODE (target) == CONST_INT)
1662 return \"li\\t%@,%1\\n\\tjalr\\t%3,%@\";
1663 else if (CONSTANT_ADDRESS_P (target))
1664 return \"jal\\t%1\";
1666 return \"jalr\\t%3,%1\";
1668 [(set_attr "type" "call")
1669 (set_attr "mode" "none")])
1671 (define_expand "call_value_multiple_internal0"
1672 [(parallel [(set (match_operand 0 "" "")
1673 (call (match_operand 1 "" "")
1674 (match_operand 2 "" "")))
1675 (set (match_operand 3 "" "")
1678 (clobber (match_operand:SI 4 "" ""))])]
1682 ;; ??? May eventually need all 6 versions of the call patterns with multiple
1685 (define_insn "call_value_multiple_internal1"
1686 [(set (match_operand 0 "register_operand" "=d")
1687 (call (mem (match_operand 1 "call_insn_operand" "r"))
1688 (match_operand 2 "" "i")))
1689 (set (match_operand 3 "register_operand" "=d")
1690 (call (mem (match_dup 1))
1692 (clobber (match_operand:SI 4 "register_operand" "=d"))]
1696 rtx target = operands[1];
1698 if (GET_CODE (target) == CONST_INT)
1699 return \"li\\t%@,%1\\n\\tjalr\\t%4,%@\";
1700 else if (CONSTANT_ADDRESS_P (target))
1701 return \"jal\\t%1\";
1703 return \"jalr\\t%4,%1\";
1705 [(set_attr "type" "call")
1706 (set_attr "mode" "none")])
1708 ;; Call subroutine returning any type.
1710 (define_expand "untyped_call"
1711 [(parallel [(call (match_operand 0 "" "")
1713 (match_operand 1 "" "")
1714 (match_operand 2 "" "")])]
1718 if (operands[0]) /* silence statement not reached warnings */
1722 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
1724 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1726 rtx set = XVECEXP (operands[2], 0, i);
1727 emit_move_insn (SET_DEST (set), SET_SRC (set));
1730 emit_insn (gen_blockage ());
1736 ;; ....................
1740 ;; ....................
1747 [(set_attr "type" "nop")
1748 (set_attr "mode" "none")])
1751 ;; For the rare case where we need to load an address into a register
1752 ;; that cannot be recognized by the normal movsi/addsi instructions.
1753 ;; I have no idea how many insns this can actually generate. It should
1754 ;; be rare, so over-estimating as 10 instructions should not have any
1755 ;; real performance impact.
1756 (define_insn "leasi"
1757 [(set (match_operand:SI 0 "register_operand" "=d")
1758 (match_operand:SI 1 "address_operand" "p"))]
1764 xoperands[0] = operands[0];
1765 xoperands[1] = XEXP (operands[1], 0);
1766 xoperands[2] = XEXP (operands[1], 1);
1767 output_asm_insn (\"addiu\\t%0,%1,%2\", xoperands);
1770 [(set_attr "type" "arith")
1771 (set_attr "mode" "SI")
1772 (set_attr "length" "40")])
1774 (define_insn "ado16"
1775 [(set (match_operand:SI 0 "register_operand" "=r")
1776 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1777 (match_operand:SI 2 "register_operand" "r")]
1780 "ado16\\t%0, %1, %2"
1784 [(set (match_operand:SI 0 "register_operand" "=r")
1785 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1786 (match_operand:SI 2 "const_int_operand" "I")
1787 (match_operand:SI 3 "const_int_operand" "I")
1788 (match_operand:SI 4 "const_int_operand" "I")]
1791 "ram\\t%0, %1, %2, %3, %4"
1794 (define_insn "chkhdr"
1795 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "=r")
1796 (match_operand:SI 1 "register_operand" "r")]
1799 "* return iq2000_fill_delay_slot (\"chkhdr\\t%0, %1\", DELAY_LOAD, operands, insn);"
1800 [(set_attr "dslot" "not_in_dslot")]
1804 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1805 (match_operand:SI 1 "register_operand" "r")]
1808 "* return iq2000_fill_delay_slot (\"pkrl\\t%0, %1\", DELAY_NONE, operands, insn);"
1809 [(set_attr "dslot" "not_in_dslot")]
1813 [(set (match_operand:SI 0 "register_operand" "=r")
1814 (unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "I")]
1817 "* return iq2000_fill_delay_slot (\"cfc0\\t%0, %%%1\", DELAY_LOAD, operands, insn);"
1818 [(set_attr "dslot" "ok_in_dslot")]
1822 [(set (match_operand:SI 0 "register_operand" "=r")
1823 (unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "I")]
1826 "* return iq2000_fill_delay_slot (\"cfc1\\t%0, %%%1\", DELAY_LOAD, operands, insn);"
1827 [(set_attr "dslot" "ok_in_dslot")]
1831 [(set (match_operand:SI 0 "register_operand" "=r")
1832 (unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "I")]
1835 "* return iq2000_fill_delay_slot (\"cfc2\\t%0, %%%1\", DELAY_LOAD, operands, insn);"
1836 [(set_attr "dslot" "not_in_dslot")]
1840 [(set (match_operand:SI 0 "register_operand" "=r")
1841 (unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "I")]
1844 "* return iq2000_fill_delay_slot (\"cfc3\\t%0, %%%1\", DELAY_LOAD, operands, insn);"
1845 [(set_attr "dslot" "not_in_dslot")]
1849 [(unspec_volatile:SI [(match_operand:SI 0 "reg_or_0_operand" "rJ")
1850 (match_operand:SI 1 "const_int_operand" "I")]
1853 "* return iq2000_fill_delay_slot (\"ctc0\\t%z0, %%%1\", DELAY_NONE, operands, insn);"
1854 [(set_attr "dslot" "ok_in_dslot")]
1858 [(unspec_volatile:SI [(match_operand:SI 0 "reg_or_0_operand" "rJ")
1859 (match_operand:SI 1 "const_int_operand" "I")]
1862 "* return iq2000_fill_delay_slot (\"ctc1\\t%z0, %%%1\", DELAY_NONE, operands, insn);"
1863 [(set_attr "dslot" "ok_in_dslot")]
1867 [(unspec_volatile:SI [(match_operand:SI 0 "reg_or_0_operand" "rJ")
1868 (match_operand:SI 1 "const_int_operand" "I")]
1871 "* return iq2000_fill_delay_slot (\"ctc2\\t%z0, %%%1\", DELAY_NONE, operands, insn);"
1872 [(set_attr "dslot" "ok_in_dslot")]
1876 [(unspec_volatile:SI [(match_operand:SI 0 "reg_or_0_operand" "rJ")
1877 (match_operand:SI 1 "const_int_operand" "I")]
1880 "* return iq2000_fill_delay_slot (\"ctc3\\t%z0, %%%1\", DELAY_NONE, operands, insn);"
1881 [(set_attr "dslot" "ok_in_dslot")]
1885 [(set (match_operand:SI 0 "register_operand" "=r")
1886 (unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "I")]
1889 "* return iq2000_fill_delay_slot (\"mfc0\\t%0, %%%1\", DELAY_LOAD, operands, insn);"
1890 [(set_attr "dslot" "ok_in_dslot")]
1894 [(set (match_operand:SI 0 "register_operand" "=r")
1895 (unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "I")]
1898 "* return iq2000_fill_delay_slot (\"mfc1\\t%0, %%%1\", DELAY_LOAD, operands, insn);"
1899 [(set_attr "dslot" "ok_in_dslot")]
1903 [(set (match_operand:SI 0 "register_operand" "=r")
1904 (unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "I")]
1907 "* return iq2000_fill_delay_slot (\"mfc2\\t%0, %%%1\", DELAY_LOAD, operands, insn);"
1908 [(set_attr "dslot" "not_in_dslot")]
1912 [(set (match_operand:SI 0 "register_operand" "=r")
1913 (unspec_volatile:SI [(match_operand:SI 1 "const_int_operand" "I")]
1916 "* return iq2000_fill_delay_slot (\"mfc3\\t%0, %%%1\", DELAY_LOAD, operands, insn);"
1917 [(set_attr "dslot" "not_in_dslot")]
1921 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1922 (match_operand:SI 1 "const_int_operand" "I")]
1925 "* return iq2000_fill_delay_slot (\"mtc0\\t%0, %%%1\", DELAY_NONE, operands, insn);"
1926 [(set_attr "dslot" "ok_in_dslot")]
1930 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1931 (match_operand:SI 1 "const_int_operand" "I")]
1934 "* return iq2000_fill_delay_slot (\"mtc1\\t%0, %%%1\", DELAY_NONE, operands, insn);"
1935 [(set_attr "dslot" "ok_in_dslot")]
1939 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1940 (match_operand:SI 1 "const_int_operand" "I")]
1943 "* return iq2000_fill_delay_slot (\"mtc2\\t%0, %%%1\", DELAY_NONE, operands, insn);"
1944 [(set_attr "dslot" "ok_in_dslot")]
1948 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1949 (match_operand:SI 1 "const_int_operand" "I")]
1952 "* return iq2000_fill_delay_slot (\"mtc3\\t%0, %%%1\", DELAY_NONE, operands, insn);"
1953 [(set_attr "dslot" "ok_in_dslot")]
1957 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1958 (match_operand:SI 1 "register_operand" "r")]
1961 "* return iq2000_fill_delay_slot (\"lur\\t%0, %1\", DELAY_NONE, operands, insn);"
1962 [(set_attr "dslot" "not_in_dslot")]
1966 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1967 (match_operand:SI 1 "register_operand" "r")]
1970 "* return iq2000_fill_delay_slot (\"rb\\t%0, %1\", DELAY_NONE, operands, insn);"
1971 [(set_attr "dslot" "not_in_dslot")]
1975 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1976 (match_operand:SI 1 "register_operand" "r")]
1979 "* return iq2000_fill_delay_slot (\"rx\\t%0, %1\", DELAY_NONE, operands, insn);"
1980 [(set_attr "dslot" "not_in_dslot")]
1984 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
1987 "* return iq2000_fill_delay_slot (\"srrd\\t%0\", DELAY_NONE, operands, insn);"
1988 [(set_attr "dslot" "not_in_dslot")]
1992 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
1993 (match_operand:SI 1 "register_operand" "r")]
1996 "* return iq2000_fill_delay_slot (\"srwr\\t%0, %1\", DELAY_NONE, operands, insn);"
1997 [(set_attr "dslot" "not_in_dslot")]
2001 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2002 (match_operand:SI 1 "register_operand" "r")]
2005 "* return iq2000_fill_delay_slot (\"wb\\t%0, %1\", DELAY_NONE, operands, insn);"
2006 [(set_attr "dslot" "not_in_dslot")]
2010 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2011 (match_operand:SI 1 "register_operand" "r")]
2014 "* return iq2000_fill_delay_slot (\"wx\\t%0, %1\", DELAY_NONE, operands, insn);"
2015 [(set_attr "dslot" "not_in_dslot")]
2018 (define_insn "luc32"
2019 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2020 (match_operand:SI 1 "register_operand" "r")]
2023 "* return iq2000_fill_delay_slot (\"luc32\\t%0, %1\", DELAY_NONE, operands, insn);"
2024 [(set_attr "dslot" "not_in_dslot")]
2027 (define_insn "luc32l"
2028 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2029 (match_operand:SI 1 "register_operand" "r")]
2032 "* return iq2000_fill_delay_slot (\"luc32l\\t%0, %1\", DELAY_NONE, operands, insn);"
2033 [(set_attr "dslot" "not_in_dslot")]
2036 (define_insn "luc64"
2037 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2038 (match_operand:SI 1 "register_operand" "r")]
2041 "* return iq2000_fill_delay_slot (\"luc64\\t%0, %1\", DELAY_NONE, operands, insn);"
2042 [(set_attr "dslot" "not_in_dslot")]
2045 (define_insn "luc64l"
2046 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2047 (match_operand:SI 1 "register_operand" "r")]
2050 "* return iq2000_fill_delay_slot (\"luc64l\\t%0, %1\", DELAY_NONE, operands, insn);"
2051 [(set_attr "dslot" "not_in_dslot")]
2055 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2056 (match_operand:SI 1 "register_operand" "r")]
2059 "* return iq2000_fill_delay_slot (\"luk\\t%0, %1\", DELAY_NONE, operands, insn);"
2060 [(set_attr "dslot" "ok_in_dslot")]
2063 (define_insn "lulck"
2064 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
2067 "* return iq2000_fill_delay_slot (\"lulck\\t%0\", DELAY_NONE, operands, insn);"
2068 [(set_attr "dslot" "not_in_dslot")]
2071 (define_insn "lum32"
2072 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2073 (match_operand:SI 1 "register_operand" "r")]
2076 "* return iq2000_fill_delay_slot (\"lum32\\t%0, %1\", DELAY_NONE, operands, insn);"
2077 [(set_attr "dslot" "not_in_dslot")]
2080 (define_insn "lum32l"
2081 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2082 (match_operand:SI 1 "register_operand" "r")]
2085 "* return iq2000_fill_delay_slot (\"lum32l\\t%0, %1\", DELAY_NONE, operands, insn);"
2086 [(set_attr "dslot" "not_in_dslot")]
2089 (define_insn "lum64"
2090 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2091 (match_operand:SI 1 "register_operand" "r")]
2094 "* return iq2000_fill_delay_slot (\"lum64\\t%0, %1\", DELAY_NONE, operands, insn);"
2095 [(set_attr "dslot" "not_in_dslot")]
2098 (define_insn "lum64l"
2099 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2100 (match_operand:SI 1 "register_operand" "r")]
2103 "* return iq2000_fill_delay_slot (\"lum64l\\t%0, %1\", DELAY_NONE, operands, insn);"
2104 [(set_attr "dslot" "not_in_dslot")]
2108 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2109 (match_operand:SI 1 "register_operand" "r")]
2112 "* return iq2000_fill_delay_slot (\"lurl\\t%0, %1\", DELAY_NONE, operands, insn);"
2113 [(set_attr "dslot" "not_in_dslot")]
2117 [(set (match_operand:SI 0 "register_operand" "=r")
2118 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")
2119 (match_operand:SI 2 "register_operand" "r")
2120 (match_operand:SI 3 "const_int_operand" "I")]
2123 "* return iq2000_fill_delay_slot (\"mrgb\\t%0, %1, %2, %3\", DELAY_LOAD, operands, insn);"
2124 [(set_attr "dslot" "ok_in_dslot")]
2127 (define_insn "srrdl"
2128 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
2131 "* return iq2000_fill_delay_slot (\"srrdl\\t%0\", DELAY_NONE, operands, insn);"
2132 [(set_attr "dslot" "not_in_dslot")]
2135 (define_insn "srulck"
2136 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
2139 "* return iq2000_fill_delay_slot (\"srulck\\t%0\", DELAY_NONE, operands, insn);"
2140 [(set_attr "dslot" "not_in_dslot")]
2143 (define_insn "srwru"
2144 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2145 (match_operand:SI 1 "register_operand" "r")]
2148 "* return iq2000_fill_delay_slot (\"srwru\\t%0, %1\", DELAY_NONE, operands, insn);"
2149 [(set_attr "dslot" "not_in_dslot")]
2152 (define_insn "trapqfl"
2153 [(unspec_volatile:SI [(const_int 1)] UNSPEC_TRAPQFL)]
2155 "* return iq2000_fill_delay_slot (\"trapqfl\", DELAY_NONE, operands, insn);"
2156 [(set_attr "dslot" "not_in_dslot")]
2159 (define_insn "trapqne"
2160 [(unspec_volatile:SI [(const_int 2)] UNSPEC_TRAPQNE)]
2162 "* return iq2000_fill_delay_slot (\"trapqne\", DELAY_NONE, operands, insn);"
2163 [(set_attr "dslot" "not_in_dslot")]
2166 (define_insn "traprel"
2167 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
2170 "* return iq2000_fill_delay_slot (\"traprel %0\", DELAY_NONE, operands, insn);"
2171 [(set_attr "dslot" "not_in_dslot")]
2175 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")
2176 (match_operand:SI 1 "register_operand" "r")]
2179 "* return iq2000_fill_delay_slot (\"wbu\\t%0, %1\", DELAY_NONE, operands, insn);"
2180 [(set_attr "dslot" "not_in_dslot")]
2183 (define_insn "syscall"
2184 [(unspec_volatile:SI [(const_int 2)] UNSPEC_SYSCALL)]
2187 [(set_attr "dslot" "not_in_dslot")]