;; GCC machine description for NEC V850
-;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-
-;; Contributed by Jeff Law (law@cygnus.com).
+;; Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+;; Contributed by Jeff Law (law@cygnus.com).
;; This file is part of GNU CC.
(define_attr "length" ""
(const_int 200))
+(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,mult,other"
|| CONST_OK_FOR_K (INTVAL (operands[1]))
|| CONST_OK_FOR_L (INTVAL (operands[1])))))
{
- rtx high;
rtx temp;
if (reload_in_progress || reload_completed)
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)));
+ 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;
}
}")
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[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 \"\";
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[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 \"\";
else
{
rtx xoperands[2];
- xoperands[0] = gen_rtx (MEM, QImode,
- plus_constant (XEXP (operands[0], 0), log2 / 8));
+ 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);
}
else
{
rtx xoperands[2];
- xoperands[0] = gen_rtx (MEM, QImode,
- plus_constant (XEXP (operands[0], 0), log2 / 8));
+ 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);
}
else
{
rtx xoperands[2];
- xoperands[0] = gen_rtx (MEM, QImode,
- plus_constant (XEXP (operands[0], 0), log2 / 8));
+ 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);
}
else
{
rtx xoperands[2];
- xoperands[0] = gen_rtx (MEM, QImode,
- plus_constant (XEXP (operands[0], 0), log2 / 8));
+ 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);
}
if (get_attr_length (insn) == 2)
return \"b%b1 %l0\";
else
- return \"b%B1 .+6\;jr %l0\";
+ return \"b%B1 .+6 ; jr %l0\";
}"
[(set (attr "length")
(if_then_else (lt (abs (minus (match_dup 0) (pc)))
if (get_attr_length (insn) == 2)
return \"b%B1 %l0\";
else
- return \"b%b1 .+6\;jr %l0\";
+ return \"b%b1 .+6 ; jr %l0\";
}"
[(set (attr "length")
(if_then_else (lt (abs (minus (match_dup 0) (pc)))
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, VOIDmode, operands[3])));
+ 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_rtx (MEM, CASE_VECTOR_MODE, reg);
- RTX_UNCHANGING_P (mem);
+ mem = gen_rtx_MEM (CASE_VECTOR_MODE, reg);
+ RTX_UNCHANGING_P (mem) = 1;
if (! TARGET_BIG_SWITCH)
{
rtx reg2 = gen_reg_rtx (HImode);
""
"
{
- if (! call_address_operand (XEXP (operands[0], 0))
+ if (! call_address_operand (XEXP (operands[0], 0), QImode)
|| 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]));
+ if (TARGET_LONG_CALLS)
+ emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1]));
+ else
+ emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1]));
+
DONE;
}")
-(define_insn "call_internal"
+(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,r31
- jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %0"
- [(set_attr "length" "4,8")])
+ jarl .+4,r31 ; add 4,r31 ; jmp %0"
+ [(set_attr "length" "4,8")]
+)
+
+(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\";
+ else
+ return \"movhi hi(%0), r0, r11 ; movea lo(%0), r11, r11 ; jarl .+4,r31 ; add 4, r31 ; jmp r11\";
+ }
+ else
+ return \"jarl .+4,r31 ; add 4,r31 ; jmp %0\";
+ }"
+ [(set_attr "length" "16,8")]
+)
;; Call subroutine, returning value in operand 0
;; (which must be a hard register).
""
"
{
- if (! call_address_operand (XEXP (operands[1], 0))
+ if (! call_address_operand (XEXP (operands[1], 0), QImode)
|| 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]));
+ if (TARGET_LONG_CALLS)
+ emit_call_insn (gen_call_value_internal_long (operands[0],
+ XEXP (operands[1], 0),
+ operands[2]));
+ else
+ emit_call_insn (gen_call_value_internal_short (operands[0],
+ XEXP (operands[1], 0),
+ operands[2]));
DONE;
}")
-(define_insn "call_value_internal"
+(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,r31
- jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %1"
- [(set_attr "length" "4,8")])
+ jarl .+4,r31 ; add 4,r31 ; jmp %1"
+ [(set_attr "length" "4,8")]
+)
+
+(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\";
+ }
+ else
+ return \"jarl .+4, r31 ; add 4, r31 ; jmp %1\";
+ }"
+ [(set_attr "length" "16,8")]
+)
(define_insn "nop"
[(const_int 0)]
"TARGET_PROLOG_FUNCTION"
"* return construct_save_jarl (operands[0]);
"
- [(set_attr "length" "4")
+ [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes")
+ (const_string "16")
+ (const_string "4")))
(set_attr "cc" "clobber")])
;; This pattern will match a return RTX followed by any number of pop RTXs
[(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")
+ (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_V850"
"* return construct_restore_jr (operands[0]);
"
- [(set_attr "length" "4")
+ [(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.
(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 4))
(set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
- "TARGET_V850"
- "add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10"
+ "TARGET_V850 && ! TARGET_LONG_CALLS"
+ "add -16, sp ; st.w r10, 12[sp] ; jarl __save_interrupt, r10"
[(set_attr "length" "12")
(set_attr "cc" "clobber")])
(define_insn "save_all_interrupt"
[(unspec_volatile [(const_int 0)] 0)]
- "TARGET_V850"
+ "TARGET_V850 && ! TARGET_LONG_CALLS"
"jarl __save_all_interrupt,r10"
[(set_attr "length" "4")
(set_attr "cc" "clobber")])
(define_insn "restore_all_interrupt"
[(unspec_volatile [(const_int 0)] 1)]
- "TARGET_V850"
+ "TARGET_V850 && ! TARGET_LONG_CALLS"
"jarl __restore_all_interrupt,r10"
[(set_attr "length" "4")
(set_attr "cc" "clobber")])
(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"
+ "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS"
"jarl __save_r6_r9,r10"
[(set_attr "length" "4")
(set_attr "cc" "clobber")])