aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/v850/v850.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/v850/v850.md')
-rw-r--r--gcc/config/v850/v850.md1852
1 files changed, 1852 insertions, 0 deletions
diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md
new file mode 100644
index 00000000000..30ebf8709c0
--- /dev/null
+++ b/gcc/config/v850/v850.md
@@ -0,0 +1,1852 @@
+;; CYGNUS LOCAL entire file/law
+;; GCC machine description for NEC V850
+;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+
+;; Contributed by Jeff Law (law@cygnus.com).
+
+;; This file is part of GNU CC.
+
+;; GNU CC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU CC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU CC; see the file COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; The original PO technology requires these to be ordered by speed,
+;; so that assigner will pick the fastest.
+
+;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
+
+;; The V851 manual states that the instruction address space is 16M;
+;; the various branch/call instructions only have a 22bit offset (4M range).
+;;
+;; One day we'll probably need to handle calls to targets more than 4M
+;; away.
+
+;; The size of instructions in bytes.
+
+(define_attr "length" ""
+ (const_int 200))
+
+;; Types of instructions (for scheduling purposes).
+
+(define_attr "type" "load,mult,other"
+ (const_string "other"))
+
+;; Condition code settings.
+;; none - insn does not affect cc
+;; none_0hit - insn does not affect cc but it does modify operand 0
+;; This attribute is used to keep track of when operand 0 changes.
+;; See the description of NOTICE_UPDATE_CC for more info.
+;; set_znv - sets z,n,v to useable values; c is unknown.
+;; set_zn - sets z,n to usable values; v,c is unknown.
+;; compare - compare instruction
+;; clobber - value of cc is unknown
+(define_attr "cc" "none,none_0hit,set_zn,set_znv,compare,clobber"
+ (const_string "clobber"))
+
+;; Function units for the V850. As best as I can tell, there's
+;; a traditional memory load/use stall as well as a stall if
+;; the result of a multiply is used too early.
+;;
+(define_function_unit "memory" 1 0 (eq_attr "type" "load") 2 0)
+(define_function_unit "mult" 1 0 (eq_attr "type" "mult") 2 0)
+
+
+;; ----------------------------------------------------------------------
+;; MOVE INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+;; movqi
+
+(define_expand "movqi"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, QImode)
+ && !reg_or_0_operand (operand1, QImode))
+ operands[1] = copy_to_mode_reg (QImode, operand1);
+}")
+
+(define_insn "*movqi_internal"
+ [(set (match_operand:QI 0 "general_operand" "=r,r,r,Q,r,m,m")
+ (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
+ "register_operand (operands[0], QImode)
+ || reg_or_0_operand (operands[1], QImode)"
+ "* return output_move_single (operands);"
+ [(set_attr "length" "2,4,2,2,4,4,4")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,load,other,load,other,other")])
+
+;; movhi
+
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "general_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, HImode)
+ && !reg_or_0_operand (operand1, HImode))
+ operands[1] = copy_to_mode_reg (HImode, operand1);
+}")
+
+(define_insn "*movhi_internal"
+ [(set (match_operand:HI 0 "general_operand" "=r,r,r,Q,r,m,m")
+ (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
+ "register_operand (operands[0], HImode)
+ || reg_or_0_operand (operands[1], HImode)"
+ "* return output_move_single (operands);"
+ [(set_attr "length" "2,4,2,2,4,4,4")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,load,other,load,other,other")])
+
+;; movsi and helpers
+
+(define_insn "*movsi_high"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (match_operand 1 "" "")))]
+ ""
+ "movhi hi(%1),%.,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")
+ (set_attr "type" "other")])
+
+(define_insn "*movsi_lo"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "immediate_operand" "i")))]
+ ""
+ "movea lo(%2),%1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")
+ (set_attr "type" "other")])
+
+(define_expand "movsi"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, SImode)
+ && !reg_or_0_operand (operand1, SImode))
+ operands[1] = copy_to_mode_reg (SImode, operand1);
+
+ /* Some constants, as well as symbolic operands
+ must be done with HIGH & LO_SUM patterns. */
+ if (CONSTANT_P (operands[1])
+ && GET_CODE (operands[1]) != HIGH
+ && !special_symbolref_operand (operands[1], VOIDmode)
+ && !(GET_CODE (operands[1]) == CONST_INT
+ && (CONST_OK_FOR_J (INTVAL (operands[1]))
+ || CONST_OK_FOR_K (INTVAL (operands[1]))
+ || CONST_OK_FOR_L (INTVAL (operands[1])))))
+ {
+ rtx high;
+ rtx temp;
+
+ if (reload_in_progress || reload_completed)
+ temp = operands[0];
+ else
+ temp = gen_reg_rtx (SImode);
+
+ emit_insn (gen_rtx (SET, SImode, temp,
+ gen_rtx (HIGH, SImode, operand1)));
+ emit_insn (gen_rtx (SET, SImode, operand0,
+ gen_rtx (LO_SUM, SImode, temp, operand1)));
+ DONE;
+ }
+}")
+
+(define_insn "*movsi_internal"
+ [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
+ (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
+ "register_operand (operands[0], SImode)
+ || reg_or_0_operand (operands[1], SImode)"
+ "* return output_move_single (operands);"
+ [(set_attr "length" "2,4,4,2,2,4,4,4,4")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,other,load,other,load,other,other,other")])
+
+(define_expand "movdi"
+ [(set (match_operand:DI 0 "general_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, DImode)
+ && !reg_or_0_operand (operand1, DImode))
+ operands[1] = copy_to_mode_reg (DImode, operand1);
+}")
+
+(define_insn "*movdi_internal"
+ [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,m,r")
+ (match_operand:DI 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
+ "register_operand (operands[0], DImode)
+ || reg_or_0_operand (operands[1], DImode)"
+ "* return output_move_double (operands);"
+ [(set_attr "length" "4,8,8,16,8,8,8,16")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,other,other,load,other,other,other")])
+
+(define_expand "movsf"
+ [(set (match_operand:SF 0 "general_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, SFmode)
+ && !reg_or_0_operand (operand1, SFmode))
+ operands[1] = copy_to_mode_reg (SFmode, operand1);
+}")
+
+(define_insn "*movsf_internal"
+ [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
+ (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
+ "register_operand (operands[0], SFmode)
+ || reg_or_0_operand (operands[1], SFmode)"
+ "* return output_move_single (operands);"
+ [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,other,other,load,other,load,other,other,other")])
+
+(define_expand "movdf"
+ [(set (match_operand:DF 0 "general_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* One of the ops has to be in a register or 0 */
+ if (!register_operand (operand0, DFmode)
+ && !reg_or_0_operand (operand1, DFmode))
+ operands[1] = copy_to_mode_reg (DFmode, operand1);
+}")
+
+(define_insn "*movdf_internal"
+ [(set (match_operand:DF 0 "general_operand" "=r,r,r,r,r,m,m,r")
+ (match_operand:DF 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
+ "register_operand (operands[0], DFmode)
+ || reg_or_0_operand (operands[1], DFmode)"
+ "* return output_move_double (operands);"
+ [(set_attr "length" "4,8,8,16,8,8,8,16")
+ (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
+ (set_attr "type" "other,other,other,other,load,other,other,other")])
+
+
+;; ----------------------------------------------------------------------
+;; TEST INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "*v850_tst1"
+ [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
+ (const_int 1)
+ (match_operand:QI 1 "const_int_operand" "n")))]
+ ""
+ "tst1 %1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "tstsi"
+ [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
+ ""
+ "cmp %.,%0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "set_znv")])
+
+(define_insn "cmpsi"
+ [(set (cc0)
+ (compare:SI (match_operand:SI 0 "register_operand" "r,r")
+ (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
+ ""
+ "@
+ cmp %1,%0
+ cmp %1,%0"
+ [(set_attr "length" "2,2")
+ (set_attr "cc" "compare")])
+
+;; ----------------------------------------------------------------------
+;; ADD INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,&r")
+ (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
+ (match_operand:SI 2 "nonmemory_operand" "rJ,K,r")))]
+ ""
+ "@
+ add %2,%0
+ addi %2,%1,%0
+ mov %1,%0\;add %2,%0"
+ [(set_attr "length" "2,4,6")
+ (set_attr "cc" "set_zn")])
+
+;; ----------------------------------------------------------------------
+;; SUBTRACT INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "subsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (minus:SI (match_operand:SI 1 "register_operand" "0,r")
+ (match_operand:SI 2 "register_operand" "r,0")))]
+ ""
+ "@
+ sub %2,%0
+ subr %1,%0"
+ [(set_attr "length" "2,2")
+ (set_attr "cc" "set_zn")])
+
+(define_insn "negsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_operand:SI 1 "register_operand" "0")))]
+ ""
+ "subr %.,%0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "set_zn")])
+
+;; ----------------------------------------------------------------------
+;; MULTIPLY INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_expand "mulhisi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
+ (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
+ ""
+ "")
+
+(define_insn "*mulhisi3_internal1"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
+ (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
+ ""
+ "mulh %2,%0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none_0hit")
+ (set_attr "type" "mult")])
+
+(define_insn "*mulhisi3_internal2"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (mult:SI
+ (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
+ (sign_extend:SI (match_operand 2 "const_int_operand" "J,K"))))]
+ ""
+ "@
+ mulh %2,%0
+ mulhi %2,%1,%0"
+ [(set_attr "length" "2,4")
+ (set_attr "cc" "none_0hit,none_0hit")
+ (set_attr "type" "mult")])
+
+
+;; ----------------------------------------------------------------------
+;; AND INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "*v850_clr1_1"
+ [(set (match_operand:QI 0 "memory_operand" "=m")
+ (subreg:QI
+ (and:SI (subreg:SI (match_dup 0) 0)
+ (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
+ ""
+ "*
+{
+ rtx xoperands[2];
+ xoperands[0] = operands[0];
+ xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
+ output_asm_insn (\"clr1 %M1,%0\", xoperands);
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_clr1_2"
+ [(set (match_operand:HI 0 "memory_operand" "=m")
+ (subreg:HI
+ (and:SI (subreg:SI (match_dup 0) 0)
+ (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
+
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"clr1 %1,%0\", xoperands);
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_clr1_3"
+ [(set (match_operand:SI 0 "memory_operand" "=m")
+ (and:SI (match_dup 0)
+ (match_operand:SI 1 "not_power_of_two_operand" "")))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
+
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"clr1 %1,%0\", xoperands);
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "andsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
+ ""
+ "@
+ and %2,%0
+ and %.,%0
+ andi %2,%1,%0"
+ [(set_attr "length" "2,2,4")
+ (set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; OR INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "*v850_set1_1"
+ [(set (match_operand:QI 0 "memory_operand" "=m")
+ (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
+ (match_operand 1 "power_of_two_operand" "")) 0))]
+ ""
+ "set1 %M1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_set1_2"
+ [(set (match_operand:HI 0 "memory_operand" "=m")
+ (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
+ (match_operand 1 "power_of_two_operand" "")) 0))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (INTVAL (operands[1]));
+
+ if (log2 < 8)
+ return \"set1 %M1,%0\";
+ else
+ {
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"set1 %1,%0\", xoperands);
+ }
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_set1_3"
+ [(set (match_operand:SI 0 "memory_operand" "=m")
+ (ior:SI (match_dup 0)
+ (match_operand 1 "power_of_two_operand" "")))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (INTVAL (operands[1]));
+
+ if (log2 < 8)
+ return \"set1 %M1,%0\";
+ else
+ {
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"set1 %1,%0\", xoperands);
+ }
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "iorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
+ ""
+ "@
+ or %2,%0
+ or %.,%0
+ ori %2,%1,%0"
+ [(set_attr "length" "2,2,4")
+ (set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; XOR INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "*v850_not1_1"
+ [(set (match_operand:QI 0 "memory_operand" "=m")
+ (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
+ (match_operand 1 "power_of_two_operand" "")) 0))]
+ ""
+ "not1 %M1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_not1_2"
+ [(set (match_operand:HI 0 "memory_operand" "=m")
+ (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
+ (match_operand 1 "power_of_two_operand" "")) 0))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (INTVAL (operands[1]));
+
+ if (log2 < 8)
+ return \"not1 %M1,%0\";
+ else
+ {
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"not1 %1,%0\", xoperands);
+ }
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "*v850_not1_3"
+ [(set (match_operand:SI 0 "memory_operand" "=m")
+ (xor:SI (match_dup 0)
+ (match_operand 1 "power_of_two_operand" "")))]
+ ""
+ "*
+{
+ int log2 = exact_log2 (INTVAL (operands[1]));
+
+ if (log2 < 8)
+ return \"not1 %M1,%0\";
+ else
+ {
+ rtx xoperands[2];
+ xoperands[0] = gen_rtx (MEM, QImode,
+ plus_constant (XEXP (operands[0], 0), log2 / 8));
+ xoperands[1] = GEN_INT (log2 % 8);
+ output_asm_insn (\"not1 %1,%0\", xoperands);
+ }
+ return \"\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+(define_insn "xorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
+ (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
+ ""
+ "@
+ xor %2,%0
+ xor %.,%0
+ xori %2,%1,%0"
+ [(set_attr "length" "2,2,4")
+ (set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; NOT INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+(define_insn "one_cmplsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (not:SI (match_operand:SI 1 "register_operand" "r")))]
+ ""
+ "not %1,%0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "set_znv")])
+
+;; -----------------------------------------------------------------
+;; BIT FIELDS
+;; -----------------------------------------------------------------
+;; Is it worth defining insv and extv for the V850 series?!?
+
+;; -----------------------------------------------------------------
+;; Scc INSTRUCTIONS
+;; -----------------------------------------------------------------
+
+(define_insn "sle"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (le:SI (cc0) (const_int 0)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+ return 0;
+
+ return \"setf le,%0\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sleu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (leu:SI (cc0) (const_int 0)))]
+ ""
+ "setf nh,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sge"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ge:SI (cc0) (const_int 0)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+ return 0;
+
+ return \"setf ge,%0\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sgeu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (geu:SI (cc0) (const_int 0)))]
+ ""
+ "setf nl,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "slt"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lt:SI (cc0) (const_int 0)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+ return 0;
+
+ return \"setf lt,%0\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sltu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ltu:SI (cc0) (const_int 0)))]
+ ""
+ "setf l,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sgt"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (gt:SI (cc0) (const_int 0)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+ return 0;
+
+ return \"setf gt,%0\";
+}"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sgtu"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (gtu:SI (cc0) (const_int 0)))]
+ ""
+ "setf h,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "seq"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (eq:SI (cc0) (const_int 0)))]
+ ""
+ "setf z,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+(define_insn "sne"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ne:SI (cc0) (const_int 0)))]
+ ""
+ "setf nz,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "none_0hit")])
+
+
+;; ----------------------------------------------------------------------
+;; JUMP INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+;; Conditional jump instructions
+
+(define_expand "ble"
+ [(set (pc)
+ (if_then_else (le (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bleu"
+ [(set (pc)
+ (if_then_else (leu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bge"
+ [(set (pc)
+ (if_then_else (ge (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgeu"
+ [(set (pc)
+ (if_then_else (geu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "blt"
+ [(set (pc)
+ (if_then_else (lt (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bltu"
+ [(set (pc)
+ (if_then_else (ltu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgt"
+ [(set (pc)
+ (if_then_else (gt (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bgtu"
+ [(set (pc)
+ (if_then_else (gtu (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "beq"
+ [(set (pc)
+ (if_then_else (eq (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "bne"
+ [(set (pc)
+ (if_then_else (ne (cc0)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_insn "*branch_normal"
+ [(set (pc)
+ (if_then_else (match_operator 1 "comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
+ && (GET_CODE (operands[1]) == GT
+ || GET_CODE (operands[1]) == GE
+ || GET_CODE (operands[1]) == LE
+ || GET_CODE (operands[1]) == LT))
+ return 0;
+
+ if (get_attr_length (insn) == 2)
+ return \"%b1 %l0\";
+ else
+ return \"%B1 .+6\;jr %l0\";
+}"
+ [(set (attr "length")
+ (if_then_else (lt (abs (minus (match_dup 0) (pc)))
+ (const_int 256))
+ (const_int 2)
+ (const_int 6)))
+ (set_attr "cc" "none")])
+
+(define_insn "*branch_invert"
+ [(set (pc)
+ (if_then_else (match_operator 1 "comparison_operator"
+ [(cc0) (const_int 0)])
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
+ && (GET_CODE (operands[1]) == GT
+ || GET_CODE (operands[1]) == GE
+ || GET_CODE (operands[1]) == LE
+ || GET_CODE (operands[1]) == LT))
+ return 0;
+ if (get_attr_length (insn) == 2)
+ return \"%B1 %l0\";
+ else
+ return \"%b1 .+6\;jr %l0\";
+}"
+ [(set (attr "length")
+ (if_then_else (lt (abs (minus (match_dup 0) (pc)))
+ (const_int 256))
+ (const_int 2)
+ (const_int 6)))
+ (set_attr "cc" "none")])
+
+;; Unconditional and other jump instructions.
+
+(define_insn "jump"
+ [(set (pc)
+ (label_ref (match_operand 0 "" "")))]
+ ""
+ "*
+{
+ if (get_attr_length (insn) == 2)
+ return \"br %0\";
+ else
+ return \"jr %0\";
+}"
+ [(set (attr "length")
+ (if_then_else (lt (abs (minus (match_dup 0) (pc)))
+ (const_int 256))
+ (const_int 2)
+ (const_int 4)))
+ (set_attr "cc" "none")])
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
+ ""
+ "jmp %0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+(define_insn "tablejump"
+ [(set (pc) (match_operand:SI 0 "register_operand" "r"))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
+ "jmp %0"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+;; Call subroutine with no return value.
+
+(define_expand "call"
+ [(call (match_operand:QI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" ""))]
+ ""
+ "
+{
+ if (! call_address_operand (XEXP (operands[0], 0))
+ || TARGET_LONG_CALLS)
+ XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
+ emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
+ DONE;
+}")
+
+(define_insn "call_internal"
+ [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
+ (match_operand:SI 1 "general_operand" "g,g"))
+ (clobber (reg:SI 31))]
+ ""
+ "@
+ jarl %0,r31
+ jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %0"
+ [(set_attr "length" "4,8")])
+
+;; Call subroutine, returning value in operand 0
+;; (which must be a hard register).
+
+(define_expand "call_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ ""
+ "
+{
+ if (! call_address_operand (XEXP (operands[1], 0))
+ || TARGET_LONG_CALLS)
+ XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
+ emit_call_insn (gen_call_value_internal (operands[0],
+ XEXP (operands[1], 0),
+ operands[2]));
+ DONE;
+}")
+
+(define_insn "call_value_internal"
+ [(set (match_operand 0 "" "=r,r")
+ (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
+ (match_operand:SI 2 "general_operand" "g,g")))
+ (clobber (reg:SI 31))]
+ ""
+ "@
+ jarl %1,r31
+ jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %1"
+ [(set_attr "length" "4,8")])
+
+(define_insn "nop"
+ [(const_int 0)]
+ ""
+ "nop"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+;; ----------------------------------------------------------------------
+;; EXTEND INSTRUCTIONS
+;; ----------------------------------------------------------------------
+
+
+(define_insn "zero_extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI
+ (match_operand:HI 1 "register_operand" "r")))]
+ ""
+ "andi 65535,%1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "set_znv")])
+
+(define_insn "zero_extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI
+ (match_operand:QI 1 "register_operand" "r")))]
+ ""
+ "andi 255,%1,%0"
+ [(set_attr "length" "4")
+ (set_attr "cc" "set_znv")])
+
+;;- sign extension instructions
+
+(define_expand "extendhisi2"
+ [(set (match_dup 2)
+ (ashift:SI (match_operand:HI 1 "register_operand" "")
+ (const_int 16)))
+ (set (match_operand:SI 0 "register_operand" "")
+ (ashiftrt:SI (match_dup 2)
+ (const_int 16)))]
+ ""
+ "
+{
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_reg_rtx (SImode);
+}")
+
+(define_expand "extendqisi2"
+ [(set (match_dup 2)
+ (ashift:SI (match_operand:QI 1 "register_operand" "")
+ (const_int 24)))
+ (set (match_operand:SI 0 "register_operand" "")
+ (ashiftrt:SI (match_dup 2)
+ (const_int 24)))]
+ ""
+ "
+{
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_reg_rtx (SImode);
+}")
+
+;; ----------------------------------------------------------------------
+;; SHIFTS
+;; ----------------------------------------------------------------------
+
+(define_insn "ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ashift:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "r,N")))]
+ ""
+ "@
+ shl %2,%0
+ shl %2,%0"
+ [(set_attr "length" "4,2")
+ (set_attr "cc" "set_znv")])
+
+(define_insn "lshrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (lshiftrt:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "r,J")))]
+ ""
+ "@
+ shr %2,%0
+ shr %2,%0"
+ [(set_attr "length" "4,2")
+ (set_attr "cc" "set_znv")])
+
+(define_insn "ashrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (ashiftrt:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "r,N")))]
+ ""
+ "@
+ sar %2,%0
+ sar %2,%0"
+ [(set_attr "length" "4,2")
+ (set_attr "cc" "set_znv")])
+
+;; ----------------------------------------------------------------------
+;; PROLOGUE/EPILOGUE
+;; ----------------------------------------------------------------------
+(define_expand "prologue"
+ [(const_int 0)]
+ ""
+ "expand_prologue (); DONE;")
+
+(define_expand "epilogue"
+ [(return)]
+ ""
+ "
+{
+ /* Try to use the trivial return first. Else use the
+ full epilogue. */
+ if (0)
+ emit_jump_insn (gen_return ());
+ else
+ expand_epilogue ();
+ DONE;
+}")
+
+(define_insn "return"
+ [(return)]
+ "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
+ "jmp [r31]"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+(define_insn "return_internal"
+ [(return)
+ (use (reg:SI 31))]
+ ""
+ "jmp [r31]"
+ [(set_attr "length" "2")
+ (set_attr "cc" "none")])
+
+
+
+;; ----------------------------------------------------------------------
+;; HELPER INSTRUCTIONS for saving the prologue and epilog registers
+;; ----------------------------------------------------------------------
+
+;; Save r2, r20-r29, r31, and create 16 byte register call area
+(define_insn "save_r2_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -64)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 2))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 20))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 21))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 22))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -32))) (reg:SI 23))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -36))) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -40))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -44))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -48))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -52))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -56))) (reg:SI 29))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -60))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r2_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r20-r29, r31, and create 16 byte register call area
+(define_insn "save_r20_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -60)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 20))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 21))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 22))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 23))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -32))) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -36))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -40))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -44))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -48))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -52))) (reg:SI 29))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -56))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r20_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r21-r29, r31, and create 16 byte register call area
+(define_insn "save_r21_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -56)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 21))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 22))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 23))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -32))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -36))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -40))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -44))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -48))) (reg:SI 29))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -52))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r21_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r22-r29, r31, and create 16 byte register call area
+(define_insn "save_r22_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -52)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 22))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 23))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -32))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -36))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -40))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -44))) (reg:SI 29))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -48))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r22_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r23-r29, r31, and create 16 byte register call area
+(define_insn "save_r23_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -48)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 23))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -32))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -36))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -40))) (reg:SI 29))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -44))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r23_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r24-r29, r31, and create 16 byte register call area
+(define_insn "save_r24_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -44)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -32))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -36))) (reg:SI 29))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -40))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r24_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r25-r29, r31, and create 16 byte register call area
+(define_insn "save_r25_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -40)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -32))) (reg:SI 29))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -36))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r25_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r26-r29, r31, and create 16 byte register call area
+(define_insn "save_r26_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -36)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 29))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -32))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r26_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r27-r29, r31, and create 16 byte register call area
+(define_insn "save_r27_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -32)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 29))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r27_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r28-r29, r31, and create 16 byte register call area
+(define_insn "save_r28_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -28)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 29))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r28_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r29, r31, and create 16 byte register call area
+(define_insn "save_r29_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -24)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 29))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r29_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r31, and create 16 byte register call area
+(define_insn "save_r31"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20)))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 31))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r31,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r2, r20-r29
+(define_insn "save_r2_r29"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -44)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 2))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 20))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 21))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 22))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 23))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -32))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -36))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -40))) (reg:SI 29))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r2_r29,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r20-r29
+(define_insn "save_r20_r29"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -40)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 20))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 21))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 22))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 23))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -32))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -36))) (reg:SI 29))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r20_r29,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r21-r29
+(define_insn "save_r21_r29"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -36)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 21))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 22))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 23))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -32))) (reg:SI 29))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r21_r29,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r22-r29
+(define_insn "save_r22_r29"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -32)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 22))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 23))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -28))) (reg:SI 29))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r22_r29,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r23-r29
+(define_insn "save_r23_r29"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -28)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 23))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -24))) (reg:SI 29))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r23_r29,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r24-r29
+(define_insn "save_r24_r29"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -24)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 24))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 29))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r24_r29,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r25-r29
+(define_insn "save_r25_r29"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 25))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 29))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r25_r29,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r26-r29
+(define_insn "save_r26_r29"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 26))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 29))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r26_r29,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r27-r29
+(define_insn "save_r27_r29"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -12)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 27))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 29))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r27_r29,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r28-r29
+(define_insn "save_r28_r29"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -8)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 28))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 29))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r28_r29,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r29
+(define_insn "save_r29"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -4)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 29))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r29,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
+(define_insn "save_interrupt"
+ [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
+ (set (mem:SI (reg:SI 3)) (reg:SI 30))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 5))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
+ ""
+ "add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10"
+ [(set_attr "length" "12")
+ (set_attr "cc" "clobber")])
+
+;; Save all registers except for the registers saved in save_interrupt when
+;; an interrupt function makes a call.
+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
+;; all of memory. This blocks insns from being moved across this point.
+;; This is needed because the rest of the compiler is not reading to handle
+;; insns this compilcated
+
+(define_insn "save_all_interrupt"
+ [(unspec_volatile [(const_int 0)] 0)]
+ ""
+ "jarl __save_all_interrupt,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r2, r20-r29, r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r2_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 64)))
+ (set (reg:SI 2) (mem:SI (plus:SI (reg:SI 3) (const_int 60))))
+ (set (reg:SI 20) (mem:SI (plus:SI (reg:SI 3) (const_int 56))))
+ (set (reg:SI 21) (mem:SI (plus:SI (reg:SI 3) (const_int 52))))
+ (set (reg:SI 22) (mem:SI (plus:SI (reg:SI 3) (const_int 48))))
+ (set (reg:SI 23) (mem:SI (plus:SI (reg:SI 3) (const_int 44))))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 40))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 36))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r2_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r20-r29, r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r20_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 60)))
+ (set (reg:SI 20) (mem:SI (plus:SI (reg:SI 3) (const_int 56))))
+ (set (reg:SI 21) (mem:SI (plus:SI (reg:SI 3) (const_int 52))))
+ (set (reg:SI 22) (mem:SI (plus:SI (reg:SI 3) (const_int 48))))
+ (set (reg:SI 23) (mem:SI (plus:SI (reg:SI 3) (const_int 44))))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 40))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 36))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r20_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r21-r29, r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r21_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 56)))
+ (set (reg:SI 21) (mem:SI (plus:SI (reg:SI 3) (const_int 52))))
+ (set (reg:SI 22) (mem:SI (plus:SI (reg:SI 3) (const_int 48))))
+ (set (reg:SI 23) (mem:SI (plus:SI (reg:SI 3) (const_int 44))))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 40))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 36))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r21_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r22-r29, r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r22_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 52)))
+ (set (reg:SI 22) (mem:SI (plus:SI (reg:SI 3) (const_int 48))))
+ (set (reg:SI 23) (mem:SI (plus:SI (reg:SI 3) (const_int 44))))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 40))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 36))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r22_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r23-r29, r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r23_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 48)))
+ (set (reg:SI 23) (mem:SI (plus:SI (reg:SI 3) (const_int 44))))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 40))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 36))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r23_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r24-r29, r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r24_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 44)))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 40))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 36))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r24_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r25-r29, r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r25_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 40)))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 36))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r25_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r26-r29, r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r26_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 36)))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r26_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r27-r29, r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r27_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 32)))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r27_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r28-r29, r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r28_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 28)))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r28_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r29, r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r29_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 24)))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r29_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r31, eliminate 16 byte register call area, and return to user
+(define_insn "restore_r31"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 20)))
+ (set (reg:SI 31) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r31"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r2, r20-r29, and return to user
+(define_insn "restore_r2_r29"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 48)))
+ (set (reg:SI 2) (mem:SI (plus:SI (reg:SI 3) (const_int 44))))
+ (set (reg:SI 20) (mem:SI (plus:SI (reg:SI 3) (const_int 40))))
+ (set (reg:SI 21) (mem:SI (plus:SI (reg:SI 3) (const_int 36))))
+ (set (reg:SI 22) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 23) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r2_r29"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r20-r29, and return to user
+(define_insn "restore_r20_r29"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 44)))
+ (set (reg:SI 20) (mem:SI (plus:SI (reg:SI 3) (const_int 40))))
+ (set (reg:SI 21) (mem:SI (plus:SI (reg:SI 3) (const_int 36))))
+ (set (reg:SI 22) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 23) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r20_r29"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r21-r29, and return to user
+(define_insn "restore_r21_r29"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 40)))
+ (set (reg:SI 21) (mem:SI (plus:SI (reg:SI 3) (const_int 36))))
+ (set (reg:SI 22) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 23) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r21_r29"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r22-r29, and return to user
+(define_insn "restore_r22_r29"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 36)))
+ (set (reg:SI 22) (mem:SI (plus:SI (reg:SI 3) (const_int 32))))
+ (set (reg:SI 23) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r22_r29"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r23-r29, and return to user
+(define_insn "restore_r23_r29"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 32)))
+ (set (reg:SI 23) (mem:SI (plus:SI (reg:SI 3) (const_int 28))))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r23_r29"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r24-r29, and return to user
+(define_insn "restore_r24_r29"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 28)))
+ (set (reg:SI 24) (mem:SI (plus:SI (reg:SI 3) (const_int 24))))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r24_r29"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r25-r29, and return to user
+(define_insn "restore_r25_r29"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 24)))
+ (set (reg:SI 25) (mem:SI (plus:SI (reg:SI 3) (const_int 20))))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r25_r29"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r26-r29, and return to user
+(define_insn "restore_r26_r29"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 20)))
+ (set (reg:SI 26) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r26_r29"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r27-r29, and return to user
+(define_insn "restore_r27_r29"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16)))
+ (set (reg:SI 27) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r27_r29"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r28-r29, and return to user
+(define_insn "restore_r28_r29"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 12)))
+ (set (reg:SI 28) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r28_r29"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r29, and return to user
+(define_insn "restore_r29"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 8)))
+ (set (reg:SI 29) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))]
+ "TARGET_PROLOG_FUNCTION"
+ "jr __return_r29"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore r1, r5, r10, and return from the interrupt
+(define_insn "restore_interrupt"
+ [(return)
+ (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16)))
+ (set (reg:SI 30) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
+ (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
+ (set (reg:SI 5) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
+ (set (reg:SI 1) (mem:SI (reg:SI 3)))]
+ ""
+ "jr __return_interrupt"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Restore all registers saved when an interrupt function makes a call.
+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
+;; all of memory. This blocks insns from being moved across this point.
+;; This is needed because the rest of the compiler is not reading to handle
+;; insns this compilcated
+
+(define_insn "restore_all_interrupt"
+ [(unspec_volatile [(const_int 0)] 1)]
+ ""
+ "jarl __restore_all_interrupt,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+
+;; Save r6-r9 for a variable argument function
+(define_insn "save_r6_r9"
+ [(set (mem:SI (reg:SI 3)) (reg:SI 6))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
+ (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
+ (clobber (reg:SI 10))]
+ "TARGET_PROLOG_FUNCTION"
+ "jarl __save_r6_r9,r10"
+ [(set_attr "length" "4")
+ (set_attr "cc" "clobber")])
+;; END CYGNUS LOCAL