diff options
Diffstat (limited to 'gcc/config/v850/v850.md')
-rw-r--r-- | gcc/config/v850/v850.md | 1852 |
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 |