URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [v850/] [v850.md] - Rev 750
Go to most recent revision | Compare with Previous | Blame | View Log
;; GCC machine description for NEC V850;; Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005, 2007, 2008, 2010;; Free Software Foundation, Inc.;; Contributed by Jeff Law (law@cygnus.com).;; This file is part of GCC.;; GCC 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 3, or (at your option);; any later version.;; GCC 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 GCC; see the file COPYING3. If not see;; <http://www.gnu.org/licenses/>.;; 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.;;---------------------------------------------------------------------------;; Constants;;(define_constants[(ZERO_REGNUM 0) ; constant zero(SP_REGNUM 3) ; Stack Pointer(GP_REGNUM 4) ; GP Pointer(EP_REGNUM 30) ; EP pointer(LP_REGNUM 31) ; Return address register(CC_REGNUM 32) ; Condition code pseudo register(FCC_REGNUM 33) ; Floating Condition code pseudo register])(define_attr "length" ""(const_int 4))(define_attr "long_calls" "yes,no"(const (if_then_else (symbol_ref "TARGET_LONG_CALLS")(const_string "yes")(const_string "no"))));; Types of instructions (for scheduling purposes).(define_attr "type" "load,store,bit1,mult,macc,div,fpu,single,other"(const_string "other"))(define_attr "cpu" "none,v850,v850e,v850e1,v850e2,v850e2v3"(cond [(match_test "TARGET_V850")(const_string "v850")(match_test "TARGET_V850E")(const_string "v850e")(match_test "TARGET_V850E1")(const_string "v850e1")(match_test "TARGET_V850E2")(const_string "v850e2")(match_test "TARGET_V850E2")(const_string "v850e2v3")](const_string "none")));; 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 usable 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_z,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_insn_reservation "v850_other" 1(eq_attr "type" "other")"nothing")(define_insn_reservation "v850_mult" 2(eq_attr "type" "mult")"nothing")(define_insn_reservation "v850_memory" 2(eq_attr "type" "load")"nothing")(include "predicates.md")(include "constraints.md");; ----------------------------------------------------------------------;; MOVE INSTRUCTIONS;; ----------------------------------------------------------------------(define_insn "sign23byte_load"[(set (match_operand:SI 0 "register_operand" "=r")(sign_extend:SI(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")(match_operand 2 "disp23_operand" "W")))))]"TARGET_V850E2V3""ld.b %2[%1],%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")])(define_insn "unsign23byte_load"[(set (match_operand:SI 0 "register_operand" "=r")(zero_extend:SI(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")(match_operand 2 "disp23_operand" "W")))))]"TARGET_V850E2V3""ld.bu %2[%1],%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")])(define_insn "sign23hword_load"[(set (match_operand:SI 0 "register_operand" "=r")(sign_extend:SI(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")(match_operand 2 "disp23_operand" "W")))))]"TARGET_V850E2V3""ld.h %2[%1],%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")])(define_insn "unsign23hword_load"[(set (match_operand:SI 0 "register_operand" "=r")(zero_extend:SI(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")(match_operand 2 "disp23_operand" "W")))))]"TARGET_V850E2V3""ld.hu %2[%1],%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")])(define_insn "23word_load"[(set (match_operand:SI 0 "register_operand" "=r")(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")(match_operand 2 "disp23_operand" "W"))))]"TARGET_V850E2V3""ld.w %2[%1],%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")])(define_insn "23byte_store"[(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "r")(match_operand 1 "disp23_operand" "W")))(match_operand:QI 2 "register_operand" "r"))]"TARGET_V850E2V3""st.b %2,%1[%0]"[(set_attr "length" "4")(set_attr "cc" "none_0hit")])(define_insn "23hword_store"[(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "r")(match_operand 1 "disp23_operand" "W")))(match_operand:HI 2 "register_operand" "r"))]"TARGET_V850E2V3""st.h %2,%1[%0]"[(set_attr "length" "4")(set_attr "cc" "none_0hit")])(define_insn "23word_store"[(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")(match_operand 1 "disp23_operand" "W")))(match_operand:SI 2 "register_operand" "r"))]"TARGET_V850E2V3""st.w %2,%1[%0]"[(set_attr "length" "4")(set_attr "cc" "none_0hit")]);; 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,store,store")]);; 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,store,store")]);; movsi and helpers(define_insn "*movsi_high"[(set (match_operand:SI 0 "register_operand" "=r")(high:SI (match_operand 1 "immediate_operand" "i")))]"""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 operandsmust be done with HIGH & LO_SUM patterns. */if (CONSTANT_P (operands[1])&& GET_CODE (operands[1]) != HIGH&& ! (TARGET_V850E || TARGET_V850E2_ALL)&& !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 temp;if (reload_in_progress || reload_completed)temp = operands[0];elsetemp = 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;}}");; This is the same as the following pattern, except that it includes;; support for arbitrary 32-bit immediates.;; ??? This always loads addresses using hilo. If the only use of this address;; was in a load/store, then we would get smaller code if we only loaded the;; upper part with hi, and then put the lower part in the load/store insn.(define_insn "*movsi_internal_v850e"[(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m,r")(match_operand:SI 1 "general_operand" "Jr,K,L,Q,Ir,m,R,r,I,i"))]"(TARGET_V850E || TARGET_V850E2_ALL)&& (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,6")(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,load,other,load,other,store,store,other")])(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,store,store,other")])(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,store,store,other")]);; ----------------------------------------------------------------------;; TEST INSTRUCTIONS;; ----------------------------------------------------------------------(define_insn "*v850_tst1"[(set (cc0)(compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")(const_int 1)(match_operand:QI 1 "const_int_operand" "n"))(const_int 0)))]"""tst1 %1,%0"[(set_attr "length" "4")(set_attr "cc" "clobber")]);; This replaces ld.b;sar;andi with tst1;setf nz.(define_split[(set (match_operand:SI 0 "register_operand" "")(compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")(const_int 1)(match_operand 2 "const_int_operand" ""))(const_int 0)))]""[(set (cc0) (compare (zero_extract:SI (match_dup 1)(const_int 1)(match_dup 2))(const_int 0)))(set (match_dup 0) (ne:SI (cc0) (const_int 0)))])(define_expand "cbranchsi4"[(set (cc0)(compare (match_operand:SI 1 "register_operand" "")(match_operand:SI 2 "reg_or_int5_operand" "")))(set (pc)(if_then_else(match_operator 0 "ordered_comparison_operator" [(cc0)(const_int 0)])(label_ref (match_operand 3 "" ""))(pc)))]"")(define_expand "cstoresi4"[(set (cc0)(compare (match_operand:SI 2 "register_operand" "")(match_operand:SI 3 "reg_or_int5_operand" "")))(set (match_operand:SI 0 "register_operand")(match_operator:SI 1 "ordered_comparison_operator" [(cc0)(const_int 0)]))]"")(define_expand "cmpsi"[(set (cc0)(compare (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "reg_or_int5_operand" "r,J")))]"""{v850_compare_op0 = operands[0];v850_compare_op1 = operands[1];DONE;}")(define_insn "cmpsi_insn"[(set (cc0)(compare (match_operand:SI 0 "register_operand" "r,r")(match_operand:SI 1 "reg_or_int5_operand" "r,J")))]"""@cmp %1,%0cmp %1,%0"[(set_attr "length" "2,2")(set_attr "cc" "compare")])(define_expand "cmpsf"[(set (reg:CC CC_REGNUM)(compare (match_operand:SF 0 "register_operand" "r")(match_operand:SF 1 "register_operand" "r")))]"TARGET_V850E2V3""{v850_compare_op0 = operands[0];v850_compare_op1 = operands[1];DONE;}")(define_expand "cmpdf"[(set (reg:CC CC_REGNUM)(compare (match_operand:DF 0 "even_reg_operand" "r")(match_operand:DF 1 "even_reg_operand" "r")))]"TARGET_V850E2V3""{v850_compare_op0 = operands[0];v850_compare_op1 = operands[1];DONE;}");; ----------------------------------------------------------------------;; 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,U")))(clobber (reg:CC CC_REGNUM))]"""@add %2,%0addi %2,%1,%0addi %O2(%P2),%1,%0"[(set_attr "length" "2,4,4")(set_attr "cc" "set_zn,set_zn,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")))(clobber (reg:CC CC_REGNUM))]"""@sub %2,%0subr %1,%0"[(set_attr "length" "2,2")(set_attr "cc" "set_zn,set_zn")])(define_insn "negsi2"[(set (match_operand:SI 0 "register_operand" "=r")(neg:SI (match_operand:SI 1 "register_operand" "0")))(clobber (reg:CC CC_REGNUM))]"""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" ""))))]"""if (GET_CODE (operands[2]) == CONST_INT){emit_insn (gen_mulhisi3_internal2 (operands[0], operands[1], operands[2]));DONE;}")(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"))(match_operand:HI 2 "const_int_operand" "J,K")))]"""@mulh %2,%0mulhi %2,%1,%0"[(set_attr "length" "2,4")(set_attr "cc" "none_0hit,none_0hit")(set_attr "type" "mult")]);; ??? The scheduling info is probably wrong.;; ??? This instruction can also generate the 32-bit highpart, but using it;; may increase code size counter to the desired result.;; ??? This instructions can also give a DImode result.;; ??? There is unsigned version, but it matters only for the DImode/highpart;; results.(define_insn "mulsi3"[(set (match_operand:SI 0 "register_operand" "=r")(mult:SI (match_operand:SI 1 "register_operand" "%0")(match_operand:SI 2 "reg_or_int9_operand" "rO")))]"(TARGET_V850E || TARGET_V850E2_ALL)""mul %2,%1,%."[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "mult")]);; ----------------------------------------------------------------------;; DIVIDE INSTRUCTIONS;; ----------------------------------------------------------------------;; ??? These insns do set the Z/N condition codes, except that they are based;; on only one of the two results, so it doesn't seem to make sense to use;; them.;; ??? The scheduling info is probably wrong.(define_insn "divmodsi4"[(set (match_operand:SI 0 "register_operand" "=r")(div:SI (match_operand:SI 1 "register_operand" "0")(match_operand:SI 2 "register_operand" "r")))(set (match_operand:SI 3 "register_operand" "=r")(mod:SI (match_dup 1)(match_dup 2)))(clobber (reg:CC CC_REGNUM))]"TARGET_V850E || TARGET_V850E2_ALL"{if (TARGET_V850E2_ALL)return "divq %2,%0,%3";elsereturn "div %2,%0,%3";}[(set_attr "length" "4")(set_attr "cc" "clobber")(set_attr "type" "div")])(define_insn "udivmodsi4"[(set (match_operand:SI 0 "register_operand" "=r")(udiv:SI (match_operand:SI 1 "register_operand" "0")(match_operand:SI 2 "register_operand" "r")))(set (match_operand:SI 3 "register_operand" "=r")(umod:SI (match_dup 1)(match_dup 2)))(clobber (reg:CC CC_REGNUM))]"TARGET_V850E || TARGET_V850E2_ALL"{if (TARGET_V850E2_ALL)return "divqu %2,%0,%3";elsereturn "divu %2,%0,%3";}[(set_attr "length" "4")(set_attr "cc" "clobber")(set_attr "type" "div")]);; ??? There is a 2 byte instruction for generating only the quotient.;; However, it isn't clear how to compute the length field correctly.(define_insn "divmodhi4"[(set (match_operand:HI 0 "register_operand" "=r")(div:HI (match_operand:HI 1 "register_operand" "0")(match_operand:HI 2 "register_operand" "r")))(set (match_operand:HI 3 "register_operand" "=r")(mod:HI (match_dup 1)(match_dup 2)))(clobber (reg:CC CC_REGNUM))]"TARGET_V850E || TARGET_V850E2_ALL""divh %2,%0,%3"[(set_attr "length" "4")(set_attr "cc" "clobber")(set_attr "type" "div")]);; Half-words are sign-extended by default, so we must zero extend to a word;; here before doing the divide.(define_insn "udivmodhi4"[(set (match_operand:HI 0 "register_operand" "=r")(udiv:HI (match_operand:HI 1 "register_operand" "0")(match_operand:HI 2 "register_operand" "r")))(set (match_operand:HI 3 "register_operand" "=r")(umod:HI (match_dup 1)(match_dup 2)))(clobber (reg:CC CC_REGNUM))]"TARGET_V850E || TARGET_V850E2_ALL""zxh %0 ; divhu %2,%0,%3"[(set_attr "length" "4")(set_attr "cc" "clobber")(set_attr "type" "div")]);; ----------------------------------------------------------------------;; 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))(clobber (reg:CC CC_REGNUM))]"""*{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")(set_attr "type" "bit1")])(define_insn "*v850_clr1_2"[(set (match_operand:HI 0 "indirect_operand" "=m")(subreg:HI(and:SI (subreg:SI (match_dup 0) 0)(match_operand:HI 1 "not_power_of_two_operand" "")) 0))(clobber (reg:CC CC_REGNUM))]"""*{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")(set_attr "type" "bit1")])(define_insn "*v850_clr1_3"[(set (match_operand:SI 0 "indirect_operand" "=m")(and:SI (match_dup 0)(match_operand:SI 1 "not_power_of_two_operand" "")))(clobber (reg:CC CC_REGNUM))]"""*{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")(set_attr "type" "bit1")])(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")))(clobber (reg:CC CC_REGNUM))]"""@and %2,%0and %.,%0andi %2,%1,%0"[(set_attr "length" "2,2,4")(set_attr "cc" "set_zn")]);; ----------------------------------------------------------------------;; 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))(clobber (reg:CC CC_REGNUM))]"""set1 %M1,%0"[(set_attr "length" "4")(set_attr "cc" "clobber")(set_attr "type" "bit1")])(define_insn "*v850_set1_2"[(set (match_operand:HI 0 "indirect_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")(set_attr "type" "bit1")])(define_insn "*v850_set1_3"[(set (match_operand:SI 0 "indirect_operand" "=m")(ior:SI (match_dup 0)(match_operand 1 "power_of_two_operand" "")))(clobber (reg:CC CC_REGNUM))]"""*{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")(set_attr "type" "bit1")])(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")))(clobber (reg:CC CC_REGNUM))]"""@or %2,%0or %.,%0ori %2,%1,%0"[(set_attr "length" "2,2,4")(set_attr "cc" "set_zn")]);; ----------------------------------------------------------------------;; 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))(clobber (reg:CC CC_REGNUM))]"""not1 %M1,%0"[(set_attr "length" "4")(set_attr "cc" "clobber")(set_attr "type" "bit1")])(define_insn "*v850_not1_2"[(set (match_operand:HI 0 "indirect_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")(set_attr "type" "bit1")])(define_insn "*v850_not1_3"[(set (match_operand:SI 0 "indirect_operand" "=m")(xor:SI (match_dup 0)(match_operand 1 "power_of_two_operand" "")))(clobber (reg:CC CC_REGNUM))]"""*{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")(set_attr "type" "bit1")])(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")))(clobber (reg:CC CC_REGNUM))]"""@xor %2,%0xor %.,%0xori %2,%1,%0"[(set_attr "length" "2,2,4")(set_attr "cc" "set_zn")]);; ----------------------------------------------------------------------;; NOT INSTRUCTIONS;; ----------------------------------------------------------------------(define_insn "one_cmplsi2"[(set (match_operand:SI 0 "register_operand" "=r")(not:SI (match_operand:SI 1 "register_operand" "r")))(clobber (reg:CC CC_REGNUM))]"""not %1,%0"[(set_attr "length" "2")(set_attr "cc" "set_zn")]);; -----------------------------------------------------------------;; BIT FIELDS;; -----------------------------------------------------------------;; ??? Is it worth defining insv and extv for the V850 series?!?;; An insv pattern would be useful, but does not get used because;; store_bit_field never calls insv when storing a constant value into a;; single-bit bitfield.;; extv/extzv patterns would be useful, but do not get used because;; optimize_bitfield_compare in fold-const usually converts single;; bit extracts into an AND with a mask.;; -----------------------------------------------------------------;; Scc INSTRUCTIONS;; -----------------------------------------------------------------(define_insn "*setcc"[(set (match_operand:SI 0 "register_operand" "=r")(match_operator:SI 1 "comparison_operator"[(cc0) (const_int 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;return \"setf %c1,%0\";}"[(set_attr "length" "4")(set_attr "cc" "none_0hit")])(define_insn "setf_insn"[(set (match_operand:SI 0 "register_operand" "=r")(match_operator:SI 1 "comparison_operator"[(reg:CC CC_REGNUM) (const_int 0)]))]"""setf %b1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")])(define_insn "set_z_insn"[(set (match_operand:SI 0 "register_operand" "=r")(match_operand 1 "v850_float_z_comparison_operator" ""))]"TARGET_V850E2V3""setf z,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")])(define_insn "set_nz_insn"[(set (match_operand:SI 0 "register_operand" "=r")(match_operand 1 "v850_float_nz_comparison_operator" ""))]"TARGET_V850E2V3""setf nz,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")]);; ----------------------------------------------------------------------;; CONDITIONAL MOVE INSTRUCTIONS;; ----------------------------------------------------------------------;; Instructions using cc0 aren't allowed to have input reloads, so we must;; hide the fact that this instruction uses cc0. We do so by including the;; compare instruction inside it.(define_expand "movsicc"[(set (match_operand:SI 0 "register_operand" "=r")(if_then_else:SI(match_operand 1 "comparison_operator")(match_operand:SI 2 "reg_or_const_operand" "rJ")(match_operand:SI 3 "reg_or_const_operand" "rI")))]"(TARGET_V850E || TARGET_V850E2_ALL)""{if ( (GET_CODE (operands[2]) == CONST_INT&& GET_CODE (operands[3]) == CONST_INT)){int o2 = INTVAL (operands[2]);int o3 = INTVAL (operands[3]);if (o2 == 1 && o3 == 0)FAIL; /* setf */if (o3 == 1 && o2 == 0)FAIL; /* setf */if (o2 == 0 && (o3 < -16 || o3 > 15) && exact_log2 (o3) >= 0)FAIL; /* setf + shift */if (o3 == 0 && (o2 < -16 || o2 > 15) && exact_log2 (o2) >=0)FAIL; /* setf + shift */if (o2 != 0)operands[2] = copy_to_mode_reg (SImode, operands[2]);if (o3 !=0 )operands[3] = copy_to_mode_reg (SImode, operands[3]);}else{if (GET_CODE (operands[2]) != REG)operands[2] = copy_to_mode_reg (SImode,operands[2]);if (GET_CODE (operands[3]) != REG)operands[3] = copy_to_mode_reg (SImode, operands[3]);}}");; ??? Clobbering the condition codes is overkill.;; ??? We sometimes emit an unnecessary compare instruction because the;; condition codes may have already been set by an earlier instruction,;; but we have no code here to avoid the compare if it is unnecessary.(define_insn "movsicc_normal_cc"[(set (match_operand:SI 0 "register_operand" "=r")(if_then_else:SI(match_operator 1 "comparison_operator"[(reg:CC CC_REGNUM) (const_int 0)])(match_operand:SI 2 "reg_or_int5_operand" "rJ")(match_operand:SI 3 "reg_or_0_operand" "rI")))]"(TARGET_V850E || TARGET_V850E2_ALL)""cmov %c1,%2,%z3,%0";[(set_attr "length" "6")(set_attr "cc" "compare")])(define_insn "movsicc_reversed_cc"[(set (match_operand:SI 0 "register_operand" "=r")(if_then_else:SI(match_operator 1 "comparison_operator"[(reg:CC CC_REGNUM) (const_int 0)])(match_operand:SI 2 "reg_or_0_operand" "rI")(match_operand:SI 3 "reg_or_int5_operand" "rJ")))]"(TARGET_V850E || TARGET_V850E2_ALL)""cmov %C1,%3,%z2,%0"[(set_attr "length" "6")(set_attr "cc" "compare")])(define_insn "*movsicc_normal"[(set (match_operand:SI 0 "register_operand" "=r")(if_then_else:SI(match_operator 1 "comparison_operator"[(match_operand:SI 4 "register_operand" "r")(match_operand:SI 5 "reg_or_int5_operand" "rJ")])(match_operand:SI 2 "reg_or_int5_operand" "rJ")(match_operand:SI 3 "reg_or_0_operand" "rI")))]"(TARGET_V850E || TARGET_V850E2_ALL)""cmp %5,%4 ; cmov %c1,%2,%z3,%0"[(set_attr "length" "6")(set_attr "cc" "clobber")])(define_insn "*movsicc_reversed"[(set (match_operand:SI 0 "register_operand" "=r")(if_then_else:SI(match_operator 1 "comparison_operator"[(match_operand:SI 4 "register_operand" "r")(match_operand:SI 5 "reg_or_int5_operand" "rJ")])(match_operand:SI 2 "reg_or_0_operand" "rI")(match_operand:SI 3 "reg_or_int5_operand" "rJ")))]"(TARGET_V850E || TARGET_V850E2_ALL)""cmp %5,%4 ; cmov %C1,%3,%z2,%0"[(set_attr "length" "6")(set_attr "cc" "clobber")])(define_insn "*movsicc_tst1"[(set (match_operand:SI 0 "register_operand" "=r")(if_then_else:SI(match_operator 1 "comparison_operator"[(zero_extract:SI(match_operand:QI 2 "memory_operand" "m")(const_int 1)(match_operand 3 "const_int_operand" "n"))(const_int 0)])(match_operand:SI 4 "reg_or_int5_operand" "rJ")(match_operand:SI 5 "reg_or_0_operand" "rI")))]"(TARGET_V850E || TARGET_V850E2_ALL)""tst1 %3,%2 ; cmov %c1,%4,%z5,%0"[(set_attr "length" "8")(set_attr "cc" "clobber")])(define_insn "*movsicc_tst1_reversed"[(set (match_operand:SI 0 "register_operand" "=r")(if_then_else:SI(match_operator 1 "comparison_operator"[(zero_extract:SI(match_operand:QI 2 "memory_operand" "m")(const_int 1)(match_operand 3 "const_int_operand" "n"))(const_int 0)])(match_operand:SI 4 "reg_or_0_operand" "rI")(match_operand:SI 5 "reg_or_int5_operand" "rJ")))]"(TARGET_V850E || TARGET_V850E2_ALL)""tst1 %3,%2 ; cmov %C1,%5,%z4,%0"[(set_attr "length" "8")(set_attr "cc" "clobber")]);; Matching for sasf requires combining 4 instructions, so we provide a;; dummy pattern to match the first 3, which will always be turned into the;; second pattern by subsequent combining. As above, we must include the;; comparison to avoid input reloads in an insn using cc0.(define_insn "*sasf"[(set (match_operand:SI 0 "register_operand" "=r")(ior:SI(match_operator 1 "comparison_operator"[(match_operand:SI 3 "register_operand" "r")(match_operand:SI 4 "reg_or_int5_operand" "rJ")])(ashift:SI (match_operand:SI 2 "register_operand" "0")(const_int 1))))(clobber (reg:CC CC_REGNUM))]"(TARGET_V850E || TARGET_V850E2_ALL)""cmp %4,%3 ; sasf %c1,%0"[(set_attr "length" "6")(set_attr "cc" "clobber")])(define_split[(set (match_operand:SI 0 "register_operand" "")(if_then_else:SI(match_operator 1 "comparison_operator"[(match_operand:SI 4 "register_operand" "")(match_operand:SI 5 "reg_or_int5_operand" "")])(match_operand:SI 2 "const_int_operand" "")(match_operand:SI 3 "const_int_operand" "")))(clobber (reg:CC CC_REGNUM))]"(TARGET_V850E || TARGET_V850E2_ALL)&& ((INTVAL (operands[2]) ^ INTVAL (operands[3])) == 1)&& ((INTVAL (operands[2]) + INTVAL (operands[3])) != 1)&& (GET_CODE (operands[5]) == CONST_INT|| REGNO (operands[0]) != REGNO (operands[5]))&& REGNO (operands[0]) != REGNO (operands[4])"[(set (match_dup 0) (match_dup 6))(parallel [(set (match_dup 0)(ior:SI (match_op_dup 7 [(match_dup 4) (match_dup 5)])(ashift:SI (match_dup 0) (const_int 1))))(clobber (reg:CC CC_REGNUM))])]"{operands[6] = GEN_INT (INTVAL (operands[2]) >> 1);if (INTVAL (operands[2]) & 0x1)operands[7] = operands[1];elseoperands[7] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),GET_MODE (operands[1]),XEXP (operands[1], 0), XEXP (operands[1], 1));}");; ---------------------------------------------------------------------;; BYTE SWAP INSTRUCTIONS;; ---------------------------------------------------------------------(define_expand "rotlhi3"[(parallel [(set (match_operand:HI 0 "register_operand" "")(rotate:HI (match_operand:HI 1 "register_operand" "")(match_operand:HI 2 "const_int_operand" "")))(clobber (reg:CC CC_REGNUM))])]"(TARGET_V850E || TARGET_V850E2_ALL)""{if (INTVAL (operands[2]) != 8)FAIL;}")(define_insn "*rotlhi3_8"[(set (match_operand:HI 0 "register_operand" "=r")(rotate:HI (match_operand:HI 1 "register_operand" "r")(const_int 8)))(clobber (reg:CC CC_REGNUM))]"(TARGET_V850E || TARGET_V850E2_ALL)""bsh %1,%0"[(set_attr "length" "4")(set_attr "cc" "clobber")])(define_expand "rotlsi3"[(parallel [(set (match_operand:SI 0 "register_operand" "")(rotate:SI (match_operand:SI 1 "register_operand" "")(match_operand:SI 2 "const_int_operand" "")))(clobber (reg:CC CC_REGNUM))])]"(TARGET_V850E || TARGET_V850E2_ALL)""{if (INTVAL (operands[2]) != 16)FAIL;}")(define_insn "*rotlsi3_16"[(set (match_operand:SI 0 "register_operand" "=r")(rotate:SI (match_operand:SI 1 "register_operand" "r")(const_int 16)))(clobber (reg:CC CC_REGNUM))]"(TARGET_V850E || TARGET_V850E2_ALL)""hsw %1,%0"[(set_attr "length" "4")(set_attr "cc" "clobber")]);; ----------------------------------------------------------------------;; JUMP INSTRUCTIONS;; ----------------------------------------------------------------------;; Conditional jump instructions(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 \"b%b1 %l0\";elsereturn \"b%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 \"b%B1 %l0\";elsereturn \"b%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_z_normal"[(set (pc)(if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")(label_ref (match_operand 0 "" ""))(pc)))]"TARGET_V850E2V3""*{if (get_attr_length (insn) == 2)return \"bz %l0\";elsereturn \"bnz 1f ; jr %l0 ; 1:\";}"[(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_z_invert"[(set (pc)(if_then_else (match_operand 1 "v850_float_z_comparison_operator" "")(pc)(label_ref (match_operand 0 "" ""))))]"TARGET_V850E2V3""*{if (get_attr_length (insn) == 2)return \"bnz %l0\";elsereturn \"bz 1f ; jr %l0 ; 1:\";}"[(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_nz_normal"[(set (pc)(if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")(label_ref (match_operand 0 "" ""))(pc)))]"TARGET_V850E2V3""*{if (get_attr_length (insn) == 2)return \"bnz %l0\";elsereturn \"bz 1f ; jr %l0 ; 1:\";}"[(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_nz_invert"[(set (pc)(if_then_else (match_operand 1 "v850_float_nz_comparison_operator" "")(pc)(label_ref (match_operand 0 "" ""))))]"TARGET_V850E2V3""*{if (get_attr_length (insn) == 2)return \"bz %l0\";elsereturn \"bnz 1f ; jr %l0 ; 1:\";}"[(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\";elsereturn \"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")])(define_insn "switch"[(set (pc)(plus:SI(sign_extend:SI(mem:HI(plus:SI (ashift:SI (match_operand:SI 0 "register_operand" "r")(const_int 1))(label_ref (match_operand 1 "" "")))))(label_ref (match_dup 1))))]"(TARGET_V850E || TARGET_V850E2_ALL)""switch %0"[(set_attr "length" "2")(set_attr "cc" "none")])(define_expand "casesi"[(match_operand:SI 0 "register_operand" "")(match_operand:SI 1 "register_operand" "")(match_operand:SI 2 "register_operand" "")(match_operand 3 "" "") (match_operand 4 "" "")]"""{rtx reg = gen_reg_rtx (SImode);rtx tableaddress = gen_reg_rtx (SImode);rtx test;rtx mem;/* Subtract the lower bound from the index. */emit_insn (gen_subsi3 (reg, operands[0], operands[1]));/* Compare the result against the number of table entries;branch to the default label if out of range of the table. */test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]);emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4]));/* Shift index for the table array access. */emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));/* Load the table address into a pseudo. */emit_insn (gen_movsi (tableaddress,gen_rtx_LABEL_REF (Pmode, operands[3])));/* Add the table address to the index. */emit_insn (gen_addsi3 (reg, reg, tableaddress));/* Load the table entry. */mem = gen_const_mem (CASE_VECTOR_MODE, reg);if (! TARGET_BIG_SWITCH){rtx reg2 = gen_reg_rtx (HImode);emit_insn (gen_movhi (reg2, mem));emit_insn (gen_extendhisi2 (reg, reg2));}elseemit_insn (gen_movsi (reg, mem));/* Add the table address. */emit_insn (gen_addsi3 (reg, reg, tableaddress));/* Branch to the switch label. */emit_jump_insn (gen_tablejump (reg, operands[3]));DONE;}");; 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), QImode)|| TARGET_LONG_CALLS)XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));if (TARGET_LONG_CALLS)emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));elseemit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));DONE;}")(define_insn "call_internal_short"[(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))(match_operand:SI 1 "general_operand" "g,g"))(clobber (reg:SI 31))]"! TARGET_LONG_CALLS""@jarl %0,r31jarl .+4,r31 ; add 4,r31 ; jmp %0"[(set_attr "length" "4,8")(set_attr "cc" "clobber,clobber")])(define_insn "call_internal_long"[(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))(match_operand:SI 1 "general_operand" "g,g"))(clobber (reg:SI 31))]"TARGET_LONG_CALLS""*{if (which_alternative == 0){if (GET_CODE (operands[0]) == REG)return \"jarl %0,r31\";elsereturn \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\";}elsereturn \"jarl .+4,r31 ; add 4,r31 ; jmp %0\";}"[(set_attr "length" "16,8")(set_attr "cc" "clobber,clobber")]);; 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), QImode)|| TARGET_LONG_CALLS)XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));if (TARGET_LONG_CALLS)emit_call_insn (gen_call_value_internal_long (operands[0],XEXP (operands[1], 0),operands[2]));elseemit_call_insn (gen_call_value_internal_short (operands[0],XEXP (operands[1], 0),operands[2]));DONE;}")(define_insn "call_value_internal_short"[(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))]"! TARGET_LONG_CALLS""@jarl %1,r31jarl .+4,r31 ; add 4,r31 ; jmp %1"[(set_attr "length" "4,8")(set_attr "cc" "clobber,clobber")])(define_insn "call_value_internal_long"[(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))]"TARGET_LONG_CALLS""*{if (which_alternative == 0){if (GET_CODE (operands[1]) == REG)return \"jarl %1, r31\";else/* Reload can generate this pattern.... */return \"movhi hi(%1), r0, r11 ; movea lo(%1), r11, r11 ; jarl .+4, r31 ; add 4, r31 ; jmp r11\";}elsereturn \"jarl .+4, r31 ; add 4, r31 ; jmp %1\";}"[(set_attr "length" "16,8")(set_attr "cc" "clobber,clobber")])(define_insn "nop"[(const_int 0)]"""nop"[(set_attr "length" "2")(set_attr "cc" "none")]);; ----------------------------------------------------------------------;; EXTEND INSTRUCTIONS;; ----------------------------------------------------------------------(define_insn "*zero_extendhisi2_v850e"[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")(zero_extend:SI(match_operand:HI 1 "nonimmediate_operand" "0,r,T,m")))(clobber (reg:CC CC_REGNUM))]"(TARGET_V850E || TARGET_V850E2_ALL)""@zxh %0andi 65535,%1,%0sld.hu %1,%0ld.hu %1,%0"[(set_attr "length" "2,4,2,4")(set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])(define_insn "*zero_extendhisi2_v850"[(set (match_operand:SI 0 "register_operand" "=r")(zero_extend:SI(match_operand:HI 1 "register_operand" "r")))(clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander"""andi 65535,%1,%0"[(set_attr "length" "4")(set_attr "cc" "set_zn")])(define_expand "zero_extendhisi2"[(parallel [(set (match_operand:SI 0 "register_operand")(zero_extend:SI(match_operand:HI 1 "nonimmediate_operand")))(clobber (reg:CC CC_REGNUM))])]""{if (! (TARGET_V850E || TARGET_V850E2_ALL))operands[1] = force_reg (HImode, operands[1]);})(define_insn "*zero_extendqisi2_v850e"[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")(zero_extend:SI(match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))(clobber (reg:CC CC_REGNUM))]"(TARGET_V850E || TARGET_V850E2_ALL)""@zxb %0andi 255,%1,%0sld.bu %1,%0ld.bu %1,%0"[(set_attr "length" "2,4,2,4")(set_attr "cc" "none_0hit,set_zn,none_0hit,none_0hit")])(define_insn "*zero_extendqisi2_v850"[(set (match_operand:SI 0 "register_operand" "=r")(zero_extend:SI(match_operand:QI 1 "register_operand" "r")))(clobber (reg:CC CC_REGNUM))] ;; A lie, but we have to match the expander"""andi 255,%1,%0"[(set_attr "length" "4")(set_attr "cc" "set_zn")])(define_expand "zero_extendqisi2"[(parallel [(set (match_operand:SI 0 "register_operand")(zero_extend:SI(match_operand:QI 1 "nonimmediate_operand")))(clobber (reg:CC CC_REGNUM))])]""{if (! (TARGET_V850E || TARGET_V850E2_ALL))operands[1] = force_reg (QImode, operands[1]);});;- sign extension instructions;; ??? The extendhisi2 pattern should not emit shifts for v850e?(define_insn "*extendhisi_insn"[(set (match_operand:SI 0 "register_operand" "=r,r,r")(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))(clobber (reg:CC CC_REGNUM))]"(TARGET_V850E || TARGET_V850E2_ALL)""@sxh %0sld.h %1,%0ld.h %1,%0"[(set_attr "length" "2,2,4")(set_attr "cc" "none_0hit,none_0hit,none_0hit")]);; ??? This is missing a sign extend from memory pattern to match the ld.h;; instruction.(define_expand "extendhisi2"[(parallel [(set (match_dup 2)(ashift:SI (match_operand:HI 1 "register_operand" "")(const_int 16)))(clobber (reg:CC CC_REGNUM))])(parallel [(set (match_operand:SI 0 "register_operand" "")(ashiftrt:SI (match_dup 2)(const_int 16)))(clobber (reg:CC CC_REGNUM))])]"""{operands[1] = gen_lowpart (SImode, operands[1]);operands[2] = gen_reg_rtx (SImode);}");; ??? The extendqisi2 pattern should not emit shifts for v850e?(define_insn "*extendqisi_insn"[(set (match_operand:SI 0 "register_operand" "=r,r,r")(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))(clobber (reg:CC CC_REGNUM))]"(TARGET_V850E || TARGET_V850E2_ALL)""@sxb %0sld.b %1,%0ld.b %1,%0"[(set_attr "length" "2,2,4")(set_attr "cc" "none_0hit,none_0hit,none_0hit")]);; ??? This is missing a sign extend from memory pattern to match the ld.b;; instruction.(define_expand "extendqisi2"[(parallel [(set (match_dup 2)(ashift:SI (match_operand:QI 1 "register_operand" "")(const_int 24)))(clobber (reg:CC CC_REGNUM))])(parallel [(set (match_operand:SI 0 "register_operand" "")(ashiftrt:SI (match_dup 2)(const_int 24)))(clobber (reg:CC CC_REGNUM))])]"""{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:SI 2 "nonmemory_operand" "r,N")))(clobber (reg:CC CC_REGNUM))]"""@shl %2,%0shl %2,%0"[(set_attr "length" "4,2")(set_attr "cc" "set_zn")])(define_insn "ashlsi3_v850e2"[(set (match_operand:SI 0 "register_operand" "=r")(ashift:SI(match_operand:SI 1 "register_operand" "r")(match_operand:SI 2 "nonmemory_operand" "r")))(clobber (reg:CC CC_REGNUM))]"TARGET_V850E2_ALL""shl %2,%1,%0"[(set_attr "length" "4")(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:SI 2 "nonmemory_operand" "r,N")))(clobber (reg:CC CC_REGNUM))]"""@shr %2,%0shr %2,%0"[(set_attr "length" "4,2")(set_attr "cc" "set_zn")])(define_insn "lshrsi3_v850e2"[(set (match_operand:SI 0 "register_operand" "=r")(lshiftrt:SI(match_operand:SI 1 "register_operand" "r")(match_operand:SI 2 "nonmemory_operand" "r")))(clobber (reg:CC CC_REGNUM))]"TARGET_V850E2_ALL""shr %2,%1,%0"[(set_attr "length" "4")(set_attr "cc" "set_zn")])(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")))(clobber (reg:CC CC_REGNUM))]"""@sar %2,%0sar %2,%0"[(set_attr "length" "4,2")(set_attr "cc" "set_zn, set_zn")])(define_insn "ashrsi3_v850e2"[(set (match_operand:SI 0 "register_operand" "=r")(ashiftrt:SI(match_operand:SI 1 "register_operand" "r")(match_operand:SI 2 "nonmemory_operand" "r")))(clobber (reg:CC CC_REGNUM))]"TARGET_V850E2_ALL""sar %2,%1,%0"[(set_attr "length" "4")(set_attr "cc" "set_zn")]);; ----------------------------------------------------------------------;; FIND FIRST BIT INSTRUCTION;; ----------------------------------------------------------------------(define_insn "ffssi2"[(set (match_operand:SI 0 "register_operand" "=r")(ffs:SI (match_operand:SI 1 "register_operand" "r")))(clobber (reg:CC CC_REGNUM))]"TARGET_V850E2_ALL""sch1r %1,%0"[(set_attr "length" "4")(set_attr "cc" "clobber")]);; ----------------------------------------------------------------------;; PROLOGUE/EPILOGUE;; ----------------------------------------------------------------------(define_expand "prologue"[(const_int 0)]"""expand_prologue (); DONE;")(define_expand "epilogue"[(return)]"""{expand_epilogue ();DONE;}")(define_insn "return_simple"[(return)]"reload_completed""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")]);; ----------------------------------------------------------------------;; v850e2V3 floating-point hardware support;; ----------------------------------------------------------------------(define_insn "addsf3"[(set (match_operand:SF 0 "register_operand" "=r")(plus:SF (match_operand:SF 1 "register_operand" "r")(match_operand:SF 2 "register_operand" "r")))]"TARGET_V850E2V3""addf.s %1,%2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "adddf3"[(set (match_operand:DF 0 "even_reg_operand" "=r")(plus:DF (match_operand:DF 1 "even_reg_operand" "r")(match_operand:DF 2 "even_reg_operand" "r")))]"TARGET_V850E2V3""addf.d %1,%2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "subsf3"[(set (match_operand:SF 0 "register_operand" "=r")(minus:SF (match_operand:SF 1 "register_operand" "r")(match_operand:SF 2 "register_operand" "r")))]"TARGET_V850E2V3""subf.s %2,%1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "subdf3"[(set (match_operand:DF 0 "even_reg_operand" "=r")(minus:DF (match_operand:DF 1 "even_reg_operand" "r")(match_operand:DF 2 "even_reg_operand" "r")))]"TARGET_V850E2V3""subf.d %2,%1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "mulsf3"[(set (match_operand:SF 0 "register_operand" "=r")(mult:SF (match_operand:SF 1 "register_operand" "r")(match_operand:SF 2 "register_operand" "r")))]"TARGET_V850E2V3""mulf.s %1,%2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "muldf3"[(set (match_operand:DF 0 "even_reg_operand" "=r")(mult:DF (match_operand:DF 1 "even_reg_operand" "r")(match_operand:DF 2 "even_reg_operand" "r")))]"TARGET_V850E2V3""mulf.d %1,%2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "divsf3"[(set (match_operand:SF 0 "register_operand" "=r")(div:SF (match_operand:SF 1 "register_operand" "r")(match_operand:SF 2 "register_operand" "r")))]"TARGET_V850E2V3""divf.s %2,%1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "divdf3"[(set (match_operand:DF 0 "register_operand" "=r")(div:DF (match_operand:DF 1 "even_reg_operand" "r")(match_operand:DF 2 "even_reg_operand" "r")))]"TARGET_V850E2V3""divf.d %2,%1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "minsf3"[(set (match_operand:SF 0 "register_operand" "=r")(smin:SF (match_operand:SF 1 "reg_or_0_operand" "r")(match_operand:SF 2 "reg_or_0_operand" "r")))]"TARGET_V850E2V3""minf.s %z1,%z2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "mindf3"[(set (match_operand:DF 0 "even_reg_operand" "=r")(smin:DF (match_operand:DF 1 "even_reg_operand" "r")(match_operand:DF 2 "even_reg_operand" "r")))]"TARGET_V850E2V3""minf.d %1,%2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "maxsf3"[(set (match_operand:SF 0 "register_operand" "=r")(smax:SF (match_operand:SF 1 "reg_or_0_operand" "r")(match_operand:SF 2 "reg_or_0_operand" "r")))]"TARGET_V850E2V3""maxf.s %z1,%z2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "maxdf3"[(set (match_operand:DF 0 "even_reg_operand" "=r")(smax:DF (match_operand:DF 1 "even_reg_operand" "r")(match_operand:DF 2 "even_reg_operand" "r")))]"TARGET_V850E2V3""maxf.d %1,%2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "abssf2"[(set (match_operand:SF 0 "register_operand" "=r")(abs:SF (match_operand:SF 1 "register_operand" "r")))]"TARGET_V850E2V3""absf.s %1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "absdf2"[(set (match_operand:DF 0 "even_reg_operand" "=r")(abs:DF (match_operand:DF 1 "even_reg_operand" "r")))]"TARGET_V850E2V3""absf.d %1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "negsf2"[(set (match_operand:SF 0 "register_operand" "=r")(neg:SF (match_operand:SF 1 "register_operand" "r")))]"TARGET_V850E2V3""negf.s %1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "negdf2"[(set (match_operand:DF 0 "even_reg_operand" "=r")(neg:DF (match_operand:DF 1 "even_reg_operand" "r")))]"TARGET_V850E2V3""negf.d %1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);; square-root(define_insn "sqrtsf2"[(set (match_operand:SF 0 "register_operand" "=r")(sqrt:SF (match_operand:SF 1 "register_operand" "r")))]"TARGET_V850E2V3""sqrtf.s %1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "sqrtdf2"[(set (match_operand:DF 0 "even_reg_operand" "=r")(sqrt:DF (match_operand:DF 1 "even_reg_operand" "r")))]"TARGET_V850E2V3""sqrtf.d %1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);; float -> int(define_insn "fix_truncsfsi2"[(set (match_operand:SI 0 "register_operand" "=r")(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "r"))))]"TARGET_V850E2V3""trncf.sw %1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "fix_truncdfsi2"[(set (match_operand:SI 0 "register_operand" "=r")(fix:SI (fix:DF (match_operand:DF 1 "even_reg_operand" "r"))))]"TARGET_V850E2V3""trncf.dw %1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);; int -> float(define_insn "floatsisf2"[(set (match_operand:SF 0 "register_operand" "=r")(float:SF (match_operand:SI 1 "reg_or_0_operand" "rI")))]"TARGET_V850E2V3""cvtf.ws %z1, %0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "floatsidf2"[(set (match_operand:DF 0 "even_reg_operand" "=r")(float:DF (match_operand:SI 1 "reg_or_0_operand" "rI")))]"TARGET_V850E2V3""cvtf.wd %z1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);; single-float -> double-float(define_insn "extendsfdf2"[(set (match_operand:DF 0 "even_reg_operand" "=r")(float_extend:DF(match_operand:SF 1 "reg_or_0_operand" "rI")))]"TARGET_V850E2V3""cvtf.sd %z1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);; double-float -> single-float(define_insn "truncdfsf2"[(set (match_operand:SF 0 "register_operand" "=r")(float_truncate:SF(match_operand:DF 1 "even_reg_operand" "r")))]"TARGET_V850E2V3""cvtf.ds %1,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);;;; ---------------- special insns;;;;; reciprocal(define_insn "recipsf2"[(set (match_operand:SF 0 "register_operand" "=r")(div:SF (match_operand:SF 1 "const_float_1_operand" "")(match_operand:SF 2 "register_operand" "r")))]"TARGET_V850E2V3""recipf.s %2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "recipdf2"[(set (match_operand:DF 0 "even_reg_operand" "=r")(div:DF (match_operand:DF 1 "const_float_1_operand" "")(match_operand:DF 2 "even_reg_operand" "r")))]"TARGET_V850E2V3""recipf.d %2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);;; reciprocal of square-root(define_insn "rsqrtsf2"[(set (match_operand:SF 0 "register_operand" "=r")(div:SF (match_operand:SF 1 "const_float_1_operand" "")(sqrt:SF (match_operand:SF 2 "register_operand" "r"))))]"TARGET_V850E2V3""rsqrtf.s %2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "rsqrtdf2"[(set (match_operand:DF 0 "even_reg_operand" "=r")(div:DF (match_operand:DF 1 "const_float_1_operand" "")(sqrt:DF (match_operand:DF 2 "even_reg_operand" "r"))))]"TARGET_V850E2V3""rsqrtf.d %2,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);;; multiply-add(define_insn "fmasf4"[(set (match_operand:SF 0 "register_operand" "=r")(fma:SF (match_operand:SF 1 "register_operand" "r")(match_operand:SF 2 "register_operand" "r")(match_operand:SF 3 "register_operand" "r")))]"TARGET_V850E2V3""maddf.s %2,%1,%3,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);;; multiply-subtract(define_insn "fmssf4"[(set (match_operand:SF 0 "register_operand" "=r")(fma:SF (match_operand:SF 1 "register_operand" "r")(match_operand:SF 2 "register_operand" "r")(neg:SF (match_operand:SF 3 "register_operand" "r"))))]"TARGET_V850E2V3""msubf.s %2,%1,%3,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);;; negative-multiply-add(define_insn "fnmasf4"[(set (match_operand:SF 0 "register_operand" "=r")(fma:SF (neg:SF (match_operand:SF 1 "register_operand" "r"))(match_operand:SF 2 "register_operand" "r")(match_operand:SF 3 "register_operand" "r")))]"TARGET_V850E2V3""nmaddf.s %2,%1,%3,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);; negative-multiply-subtract(define_insn "fnmssf4"[(set (match_operand:SF 0 "register_operand" "=r")(fma:SF (neg:SF (match_operand:SF 1 "register_operand" "r"))(match_operand:SF 2 "register_operand" "r")(neg:SF (match_operand:SF 3 "register_operand" "r"))))]"TARGET_V850E2V3""nmsubf.s %2,%1,%3,%0"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);; ---------------- comparison/conditionals;; SF(define_insn "cmpsf_le_insn"[(set (reg:CC_FPU_LE FCC_REGNUM)(compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r")(match_operand:SF 1 "register_operand" "r")))]"TARGET_V850E2V3""cmpf.s le,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "cmpsf_lt_insn"[(set (reg:CC_FPU_LT FCC_REGNUM)(compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r")(match_operand:SF 1 "register_operand" "r")))]"TARGET_V850E2V3""cmpf.s lt,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "cmpsf_ge_insn"[(set (reg:CC_FPU_GE FCC_REGNUM)(compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r")(match_operand:SF 1 "register_operand" "r")))]"TARGET_V850E2V3""cmpf.s ge,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "cmpsf_gt_insn"[(set (reg:CC_FPU_GT FCC_REGNUM)(compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r")(match_operand:SF 1 "register_operand" "r")))]"TARGET_V850E2V3""cmpf.s gt,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "cmpsf_eq_insn"[(set (reg:CC_FPU_EQ FCC_REGNUM)(compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r")(match_operand:SF 1 "register_operand" "r")))]"TARGET_V850E2V3""cmpf.s eq,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "cmpsf_ne_insn"[(set (reg:CC_FPU_NE FCC_REGNUM)(compare:CC_FPU_NE (match_operand:SF 0 "register_operand" "r")(match_operand:SF 1 "register_operand" "r")))]"TARGET_V850E2V3""cmpf.s neq,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]); DF(define_insn "cmpdf_le_insn"[(set (reg:CC_FPU_LE FCC_REGNUM)(compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r")(match_operand:DF 1 "even_reg_operand" "r")))]"TARGET_V850E2V3""cmpf.d le,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "cmpdf_lt_insn"[(set (reg:CC_FPU_LT FCC_REGNUM)(compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r")(match_operand:DF 1 "even_reg_operand" "r")))]"TARGET_V850E2V3""cmpf.d lt,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "cmpdf_ge_insn"[(set (reg:CC_FPU_GE FCC_REGNUM)(compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r")(match_operand:DF 1 "even_reg_operand" "r")))]"TARGET_V850E2V3""cmpf.d ge,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "cmpdf_gt_insn"[(set (reg:CC_FPU_GT FCC_REGNUM)(compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r")(match_operand:DF 1 "even_reg_operand" "r")))]"TARGET_V850E2V3""cmpf.d gt,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "cmpdf_eq_insn"[(set (reg:CC_FPU_EQ FCC_REGNUM)(compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r")(match_operand:DF 1 "even_reg_operand" "r")))]"TARGET_V850E2V3""cmpf.d eq,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")])(define_insn "cmpdf_ne_insn"[(set (reg:CC_FPU_NE FCC_REGNUM)(compare:CC_FPU_NE (match_operand:DF 0 "even_reg_operand" "r")(match_operand:DF 1 "even_reg_operand" "r")))]"TARGET_V850E2V3""cmpf.d neq,%z0,%z1"[(set_attr "length" "4")(set_attr "cc" "none_0hit")(set_attr "type" "fpu")]);;;; Transfer a v850e2v3 fcc to the Z bit of CC0 (this is necessary to do a;; conditional branch based on a floating-point compare);;(define_insn "trfsr"[(set (match_operand 0 "" "") (match_operand 1 "" ""))]"TARGET_V850E2V3&& GET_MODE(operands[0]) == GET_MODE(operands[1])&& GET_CODE(operands[0]) == REG && REGNO (operands[0]) == CC_REGNUM&& GET_CODE(operands[1]) == REG && REGNO (operands[1]) == FCC_REGNUM&& (GET_MODE(operands[0]) == CC_FPU_LEmode|| GET_MODE(operands[0]) == CC_FPU_GEmode|| GET_MODE(operands[0]) == CC_FPU_LTmode|| GET_MODE(operands[0]) == CC_FPU_GTmode|| GET_MODE(operands[0]) == CC_FPU_EQmode|| GET_MODE(operands[0]) == CC_FPU_NEmode)""trfsr"[(set_attr "length" "4")(set_attr "cc" "set_z")(set_attr "type" "fpu")]);;;; Floating-point conditional moves for the v850e2v3.;;;; The actual v850e2v3 conditional move instructions;;(define_insn "movsfcc_z_insn"[(set (match_operand:SF 0 "register_operand" "=r")(if_then_else:SF(match_operand 3 "v850_float_z_comparison_operator" "")(match_operand:SF 1 "reg_or_0_operand" "rIG")(match_operand:SF 2 "reg_or_0_operand" "rIG")))]"TARGET_V850E2V3""cmovf.s 0,%z1,%z2,%0"[(set_attr "cc" "clobber")]) ;; ??? or none_0hit(define_insn "movsfcc_nz_insn"[(set (match_operand:SF 0 "register_operand" "=r")(if_then_else:SF(match_operand 3 "v850_float_nz_comparison_operator" "")(match_operand:SF 1 "reg_or_0_operand" "rIG")(match_operand:SF 2 "reg_or_0_operand" "rIG")))]"TARGET_V850E2V3""cmovf.s 0,%z2,%z1,%0"[(set_attr "cc" "clobber")]) ;; ??? or none_0hit(define_insn "movdfcc_z_insn"[(set (match_operand:DF 0 "even_reg_operand" "=r")(if_then_else:DF(match_operand 3 "v850_float_z_comparison_operator" "")(match_operand:DF 1 "even_reg_operand" "r")(match_operand:DF 2 "even_reg_operand" "r")))]"TARGET_V850E2V3""cmovf.d 0,%z1,%z2,%0"[(set_attr "cc" "clobber")]) ;; ??? or none_0hit(define_insn "movdfcc_nz_insn"[(set (match_operand:DF 0 "even_reg_operand" "=r")(if_then_else:DF(match_operand 3 "v850_float_nz_comparison_operator" "")(match_operand:DF 1 "even_reg_operand" "r")(match_operand:DF 2 "even_reg_operand" "r")))]"TARGET_V850E2V3""cmovf.d 0,%z2,%z1,%0"[(set_attr "cc" "clobber")]) ;; ??? or none_0hit(define_insn "movedfcc_z_zero"[(set (match_operand:DF 0 "register_operand" "=r")(if_then_else:DF(match_operand 3 "v850_float_z_comparison_operator" "")(match_operand:DF 1 "reg_or_0_operand" "rIG")(match_operand:DF 2 "reg_or_0_operand" "rIG")))]"TARGET_V850E2V3""cmovf.s 0,%z1,%z2,%0 ; cmovf.s 0,%Z1,%Z2,%R0"[(set_attr "length" "8")(set_attr "cc" "clobber")]) ;; ??? or none_0hit(define_insn "movedfcc_nz_zero"[(set (match_operand:DF 0 "register_operand" "=r")(if_then_else:DF(match_operand 3 "v850_float_nz_comparison_operator" "")(match_operand:DF 1 "reg_or_0_operand" "rIG")(match_operand:DF 2 "reg_or_0_operand" "rIG")))]"TARGET_V850E2V3""cmovf.s 0,%z2,%z1,%0 ; cmovf.s 0,%Z2,%Z1,%R0"[(set_attr "length" "8")(set_attr "cc" "clobber")]) ;; ??? or none_0hit;; ----------------------------------------------------------------------;; HELPER INSTRUCTIONS for saving the prologue and epilogue registers;; ----------------------------------------------------------------------;; This pattern will match a stack adjust RTX followed by any number of push;; RTXs. These RTXs will then be turned into a suitable call to a worker;; function.;;;; Actually, convert the RTXs into a PREPARE instruction.;;(define_insn ""[(match_parallel 0 "pattern_is_ok_for_prepare"[(set (reg:SI 3)(plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))(set (mem:SI (plus:SI (reg:SI 3)(match_operand:SI 2 "immediate_operand" "i")))(match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]"TARGET_PROLOG_FUNCTION && (TARGET_V850E || TARGET_V850E2_ALL)""* return construct_prepare_instruction (operands[0]);"[(set_attr "length" "4")(set_attr "cc" "clobber")])(define_insn ""[(match_parallel 0 "pattern_is_ok_for_prologue"[(set (reg:SI 3)(plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))(set (mem:SI (plus:SI (reg:SI 3)(match_operand:SI 2 "immediate_operand" "i")))(match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]"TARGET_PROLOG_FUNCTION""* return construct_save_jarl (operands[0]);"[(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")(const_string "16")(const_string "4")))(set_attr "cc" "clobber")]);;;; Actually, turn the RTXs into a DISPOSE instruction.;;(define_insn ""[(match_parallel 0 "pattern_is_ok_for_dispose"[(return)(set (reg:SI 3)(plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))(set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")(mem:SI (plus:SI (reg:SI 3)(match_operand:SI 3 "immediate_operand" "i"))))])]"TARGET_PROLOG_FUNCTION && (TARGET_V850E || TARGET_V850E2_ALL)""* return construct_dispose_instruction (operands[0]);"[(set_attr "length" "4")(set_attr "cc" "clobber")]);; This pattern will match a return RTX followed by any number of pop RTXs;; and possible a stack adjustment as well. These RTXs will be turned into;; a suitable call to a worker function.(define_insn ""[(match_parallel 0 "pattern_is_ok_for_epilogue"[(return)(set (reg:SI 3)(plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))(set (match_operand:SI 2 "register_is_ok_for_epilogue" "=r")(mem:SI (plus:SI (reg:SI 3)(match_operand:SI 3 "immediate_operand" "i"))))])]"TARGET_PROLOG_FUNCTION""* return construct_restore_jr (operands[0]);"[(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")(const_string "12")(const_string "4")))(set_attr "cc" "clobber")]);; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.(define_insn "callt_save_interrupt"[(unspec_volatile [(const_int 0)] 2)]"(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT";; The CALLT instruction stores the next address of CALLT to CTPC register;; without saving its previous value. So if the interrupt handler;; or its caller could possibly execute the CALLT insn, save_interrupt;; MUST NOT be called via CALLT."*{output_asm_insn (\"addi -28, sp, sp\", operands);output_asm_insn (\"st.w r1, 24[sp]\", operands);output_asm_insn (\"st.w r10, 12[sp]\", operands);output_asm_insn (\"st.w r11, 16[sp]\", operands);output_asm_insn (\"stsr ctpc, r10\", operands);output_asm_insn (\"st.w r10, 20[sp]\", operands);output_asm_insn (\"stsr ctpsw, r10\", operands);output_asm_insn (\"st.w r10, 24[sp]\", operands);output_asm_insn (\"callt ctoff(__callt_save_interrupt)\", operands);return \"\";}"[(set_attr "length" "26")(set_attr "cc" "clobber")])(define_insn "callt_return_interrupt"[(unspec_volatile [(const_int 0)] 3)]"(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT""callt ctoff(__callt_return_interrupt)"[(set_attr "length" "2")(set_attr "cc" "clobber")])(define_insn "save_interrupt"[(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -20)))(set (mem:SI (plus:SI (reg:SI 3) (const_int -20))) (reg:SI 30))(set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 4))(set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))(set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 10))(set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 11))]"""*{if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)return \"addi -20,sp,sp \; st.w r11,16[sp] \; st.w r10,12[sp] \; jarl __save_interrupt,r10\";else{output_asm_insn (\"addi -20, sp, sp\", operands);output_asm_insn (\"st.w r11, 16[sp]\", operands);output_asm_insn (\"st.w r10, 12[sp]\", operands);output_asm_insn (\"st.w ep, 0[sp]\", operands);output_asm_insn (\"st.w gp, 4[sp]\", operands);output_asm_insn (\"st.w r1, 8[sp]\", operands);output_asm_insn (\"movhi hi(__ep), r0, ep\", operands);output_asm_insn (\"movea lo(__ep), ep, ep\", operands);output_asm_insn (\"movhi hi(__gp), r0, gp\", operands);output_asm_insn (\"movea lo(__gp), gp, gp\", operands);return \"\";}}"[(set (attr "length")(if_then_else (match_test "TARGET_LONG_CALLS")(const_int 10)(const_int 34)))(set_attr "cc" "clobber")]);; Restore r1, r4, r10, and return from the interrupt(define_insn "return_interrupt"[(return)(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 20)))(set (reg:SI 11) (mem:SI (plus:SI (reg:SI 3) (const_int 16))))(set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))(set (reg:SI 1) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))(set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))(set (reg:SI 30) (mem:SI (reg:SI 3)))]"""*{if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)return \"jr __return_interrupt\";else{output_asm_insn (\"ld.w 0[sp], ep\", operands);output_asm_insn (\"ld.w 4[sp], gp\", operands);output_asm_insn (\"ld.w 8[sp], r1\", operands);output_asm_insn (\"ld.w 12[sp], r10\", operands);output_asm_insn (\"ld.w 16[sp], r11\", operands);output_asm_insn (\"addi 20, sp, sp\", operands);output_asm_insn (\"reti\", operands);return \"\";}}"[(set (attr "length")(if_then_else (match_test "TARGET_LONG_CALLS")(const_int 4)(const_int 24)))(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 ready to handle;; insns this complicated.(define_insn "callt_save_all_interrupt"[(unspec_volatile [(const_int 0)] 0)]"(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT""callt ctoff(__callt_save_all_interrupt)"[(set_attr "length" "2")(set_attr "cc" "none")])(define_insn "save_all_interrupt"[(unspec_volatile [(const_int 0)] 0)]"""*{if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)return \"jarl __save_all_interrupt,r10\";output_asm_insn (\"addi -120, sp, sp\", operands);if (TARGET_EP){output_asm_insn (\"mov ep, r1\", operands);output_asm_insn (\"mov sp, ep\", operands);output_asm_insn (\"sst.w r31, 116[ep]\", operands);output_asm_insn (\"sst.w r2, 112[ep]\", operands);output_asm_insn (\"sst.w gp, 108[ep]\", operands);output_asm_insn (\"sst.w r6, 104[ep]\", operands);output_asm_insn (\"sst.w r7, 100[ep]\", operands);output_asm_insn (\"sst.w r8, 96[ep]\", operands);output_asm_insn (\"sst.w r9, 92[ep]\", operands);output_asm_insn (\"sst.w r11, 88[ep]\", operands);output_asm_insn (\"sst.w r12, 84[ep]\", operands);output_asm_insn (\"sst.w r13, 80[ep]\", operands);output_asm_insn (\"sst.w r14, 76[ep]\", operands);output_asm_insn (\"sst.w r15, 72[ep]\", operands);output_asm_insn (\"sst.w r16, 68[ep]\", operands);output_asm_insn (\"sst.w r17, 64[ep]\", operands);output_asm_insn (\"sst.w r18, 60[ep]\", operands);output_asm_insn (\"sst.w r19, 56[ep]\", operands);output_asm_insn (\"sst.w r20, 52[ep]\", operands);output_asm_insn (\"sst.w r21, 48[ep]\", operands);output_asm_insn (\"sst.w r22, 44[ep]\", operands);output_asm_insn (\"sst.w r23, 40[ep]\", operands);output_asm_insn (\"sst.w r24, 36[ep]\", operands);output_asm_insn (\"sst.w r25, 32[ep]\", operands);output_asm_insn (\"sst.w r26, 28[ep]\", operands);output_asm_insn (\"sst.w r27, 24[ep]\", operands);output_asm_insn (\"sst.w r28, 20[ep]\", operands);output_asm_insn (\"sst.w r29, 16[ep]\", operands);output_asm_insn (\"mov r1, ep\", operands);}else{output_asm_insn (\"st.w r31, 116[sp]\", operands);output_asm_insn (\"st.w r2, 112[sp]\", operands);output_asm_insn (\"st.w gp, 108[sp]\", operands);output_asm_insn (\"st.w r6, 104[sp]\", operands);output_asm_insn (\"st.w r7, 100[sp]\", operands);output_asm_insn (\"st.w r8, 96[sp]\", operands);output_asm_insn (\"st.w r9, 92[sp]\", operands);output_asm_insn (\"st.w r11, 88[sp]\", operands);output_asm_insn (\"st.w r12, 84[sp]\", operands);output_asm_insn (\"st.w r13, 80[sp]\", operands);output_asm_insn (\"st.w r14, 76[sp]\", operands);output_asm_insn (\"st.w r15, 72[sp]\", operands);output_asm_insn (\"st.w r16, 68[sp]\", operands);output_asm_insn (\"st.w r17, 64[sp]\", operands);output_asm_insn (\"st.w r18, 60[sp]\", operands);output_asm_insn (\"st.w r19, 56[sp]\", operands);output_asm_insn (\"st.w r20, 52[sp]\", operands);output_asm_insn (\"st.w r21, 48[sp]\", operands);output_asm_insn (\"st.w r22, 44[sp]\", operands);output_asm_insn (\"st.w r23, 40[sp]\", operands);output_asm_insn (\"st.w r24, 36[sp]\", operands);output_asm_insn (\"st.w r25, 32[sp]\", operands);output_asm_insn (\"st.w r26, 28[sp]\", operands);output_asm_insn (\"st.w r27, 24[sp]\", operands);output_asm_insn (\"st.w r28, 20[sp]\", operands);output_asm_insn (\"st.w r29, 16[sp]\", operands);}return \"\";}"[(set (attr "length")(if_then_else (match_test "TARGET_LONG_CALLS")(const_int 4)(const_int 62)))(set_attr "cc" "clobber")])(define_insn "_save_all_interrupt"[(unspec_volatile [(const_int 0)] 0)]"TARGET_V850 && ! TARGET_LONG_CALLS""jarl __save_all_interrupt,r10"[(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 ready to handle;; insns this complicated.(define_insn "callt_restore_all_interrupt"[(unspec_volatile [(const_int 0)] 1)]"(TARGET_V850E || TARGET_V850E2_ALL) && !TARGET_DISABLE_CALLT""callt ctoff(__callt_restore_all_interrupt)"[(set_attr "length" "2")(set_attr "cc" "none")])(define_insn "restore_all_interrupt"[(unspec_volatile [(const_int 0)] 1)]"""*{if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS)return \"jarl __restore_all_interrupt,r10\";if (TARGET_EP){output_asm_insn (\"mov ep, r1\", operands);output_asm_insn (\"mov sp, ep\", operands);output_asm_insn (\"sld.w 116[ep], r31\", operands);output_asm_insn (\"sld.w 112[ep], r2\", operands);output_asm_insn (\"sld.w 108[ep], gp\", operands);output_asm_insn (\"sld.w 104[ep], r6\", operands);output_asm_insn (\"sld.w 100[ep], r7\", operands);output_asm_insn (\"sld.w 96[ep], r8\", operands);output_asm_insn (\"sld.w 92[ep], r9\", operands);output_asm_insn (\"sld.w 88[ep], r11\", operands);output_asm_insn (\"sld.w 84[ep], r12\", operands);output_asm_insn (\"sld.w 80[ep], r13\", operands);output_asm_insn (\"sld.w 76[ep], r14\", operands);output_asm_insn (\"sld.w 72[ep], r15\", operands);output_asm_insn (\"sld.w 68[ep], r16\", operands);output_asm_insn (\"sld.w 64[ep], r17\", operands);output_asm_insn (\"sld.w 60[ep], r18\", operands);output_asm_insn (\"sld.w 56[ep], r19\", operands);output_asm_insn (\"sld.w 52[ep], r20\", operands);output_asm_insn (\"sld.w 48[ep], r21\", operands);output_asm_insn (\"sld.w 44[ep], r22\", operands);output_asm_insn (\"sld.w 40[ep], r23\", operands);output_asm_insn (\"sld.w 36[ep], r24\", operands);output_asm_insn (\"sld.w 32[ep], r25\", operands);output_asm_insn (\"sld.w 28[ep], r26\", operands);output_asm_insn (\"sld.w 24[ep], r27\", operands);output_asm_insn (\"sld.w 20[ep], r28\", operands);output_asm_insn (\"sld.w 16[ep], r29\", operands);output_asm_insn (\"mov r1, ep\", operands);}else{output_asm_insn (\"ld.w 116[sp], r31\", operands);output_asm_insn (\"ld.w 112[sp], r2\", operands);output_asm_insn (\"ld.w 108[sp], gp\", operands);output_asm_insn (\"ld.w 104[sp], r6\", operands);output_asm_insn (\"ld.w 100[sp], r7\", operands);output_asm_insn (\"ld.w 96[sp], r8\", operands);output_asm_insn (\"ld.w 92[sp], r9\", operands);output_asm_insn (\"ld.w 88[sp], r11\", operands);output_asm_insn (\"ld.w 84[sp], r12\", operands);output_asm_insn (\"ld.w 80[sp], r13\", operands);output_asm_insn (\"ld.w 76[sp], r14\", operands);output_asm_insn (\"ld.w 72[sp], r15\", operands);output_asm_insn (\"ld.w 68[sp], r16\", operands);output_asm_insn (\"ld.w 64[sp], r17\", operands);output_asm_insn (\"ld.w 60[sp], r18\", operands);output_asm_insn (\"ld.w 56[sp], r19\", operands);output_asm_insn (\"ld.w 52[sp], r20\", operands);output_asm_insn (\"ld.w 48[sp], r21\", operands);output_asm_insn (\"ld.w 44[sp], r22\", operands);output_asm_insn (\"ld.w 40[sp], r23\", operands);output_asm_insn (\"ld.w 36[sp], r24\", operands);output_asm_insn (\"ld.w 32[sp], r25\", operands);output_asm_insn (\"ld.w 28[sp], r26\", operands);output_asm_insn (\"ld.w 24[sp], r27\", operands);output_asm_insn (\"ld.w 20[sp], r28\", operands);output_asm_insn (\"ld.w 16[sp], r29\", operands);}output_asm_insn (\"addi 120, sp, sp\", operands);return \"\";}"[(set (attr "length")(if_then_else (match_test "TARGET_LONG_CALLS")(const_int 4)(const_int 62)))(set_attr "cc" "clobber")])(define_insn "_restore_all_interrupt"[(unspec_volatile [(const_int 0)] 1)]"TARGET_V850 && ! TARGET_LONG_CALLS""jarl __restore_all_interrupt,r10"[(set_attr "length" "4")(set_attr "cc" "clobber")])
Go to most recent revision | Compare with Previous | Blame | View Log
