diff options
author | Nick Clifton <nickc@cygnus.com> | 1999-02-08 12:23:33 +0000 |
---|---|---|
committer | Nick Clifton <nickc@gcc.gnu.org> | 1999-02-08 12:23:33 +0000 |
commit | be1d3f9370fef7950058801d924fd6e0b1f860e7 (patch) | |
tree | 3a66bf546f4480aecd3a3efe721bc2042dbd42b3 | |
parent | 7ff140c597657d58af2d0b41ddab6fd7886a24b1 (diff) | |
download | gcc-be1d3f9370fef7950058801d924fd6e0b1f860e7.zip gcc-be1d3f9370fef7950058801d924fd6e0b1f860e7.tar.gz gcc-be1d3f9370fef7950058801d924fd6e0b1f860e7.tar.bz2 |
Fix for PR 18535 - enforce -mlong-calls option
From-SVN: r25084
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/v850/v850.c | 48 | ||||
-rw-r--r-- | gcc/config/v850/v850.md | 96 |
3 files changed, 124 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 78f04ed..1b044b4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +1999-02-08 Nick Clifton <nickc@cygnus.com> + + * config/v850/v850.md: Enforce TARGET_LONG_CALLS option. + * config/v850/v850.c (construct_restore_jr, construct_save_jarl): + Enforce TARGET_LONG_CALLS option. + Mon Feb 8 11:43:07 1999 Donn Terry <donn@interix.com> * real.c (PUT_REAL) [XFmode]: Zero the balance of the structure. diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index b27f12c..15867ac 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -1,5 +1,5 @@ /* Subroutines for insn-output.c for NEC V850 series - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. Contributed by Jeff Law (law@cygnus.com). This file is part of GNU CC. @@ -2350,11 +2350,26 @@ construct_restore_jr (op) be popping more registers than is strictly necessary, but it does save code space. */ - if (first == last) - sprintf (buff, "jr __return_%s", reg_names [first]); + if (TARGET_LONG_CALLS) + { + char name[40]; + + if (first == last) + sprintf (name, "__return_%s", reg_names [first]); + else + sprintf (name, "__return_%s_%s", reg_names [first], reg_names [last]); + + sprintf (buff, "movhi hi(%s), r0, r6\n\tmovea lo(%s), r6, r6\n\tjmp r6", + name, name); + } else - sprintf (buff, "jr __return_%s_%s", reg_names [first], reg_names [last]); - + { + if (first == last) + sprintf (buff, "jr __return_%s", reg_names [first]); + else + sprintf (buff, "jr __return_%s_%s", reg_names [first], reg_names [last]); + } + return buff; } @@ -2536,11 +2551,26 @@ construct_save_jarl (op) be pushing more registers than is strictly necessary, but it does save code space. */ - if (first == last) - sprintf (buff, "jarl __save_%s, r10", reg_names [first]); + if (TARGET_LONG_CALLS) + { + char name[40]; + + if (first == last) + sprintf (name, "__save_%s", reg_names [first]); + else + sprintf (name, "__save_%s_%s", reg_names [first], reg_names [last]); + + sprintf (buff, "movhi hi(%s), r0, r11\n\tmovea lo(%s), r11, r11\n\tjarl .+4, r10\n\tadd 4, r10\n\tjmp r11", + name, name); + } else - sprintf (buff, "jarl __save_%s_%s, r10", reg_names [first], - reg_names [last]); + { + if (first == last) + sprintf (buff, "jarl __save_%s, r10", reg_names [first]); + else + sprintf (buff, "jarl __save_%s_%s, r10", reg_names [first], + reg_names [last]); + } return buff; } diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md index 42a95db..daea8b7 100644 --- a/gcc/config/v850/v850.md +++ b/gcc/config/v850/v850.md @@ -1,5 +1,5 @@ ;; GCC machine description for NEC V850 -;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. +;; Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. ;; Contributed by Jeff Law (law@cygnus.com). @@ -36,6 +36,11 @@ (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" @@ -969,19 +974,44 @@ 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])); + 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")]) + [(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\\n\\tmovea lo(%0), r11, r11\\n\\tjarl .+4,r31\\n\\tadd 4, r31\\n\\tjmp r11\"; + } + else + return \"jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %0\"; + }" + [(set_attr "length" "16,8")] +) ;; Call subroutine, returning value in operand 0 ;; (which must be a hard register). @@ -996,22 +1026,50 @@ 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])); + 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")]) + [(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\\n\\tmovea lo(%1), r11, r11\\n\\tjarl .+4, r31\\n\\tadd 4, r31\\n\\tjmp r11\"; + } + else + return \"jarl .+4, r31\\n\\tadd 4, r31\\n\\tjmp %1\"; + }" + [(set_attr "length" "16,8")] +) (define_insn "nop" [(const_int 0)] @@ -1180,7 +1238,9 @@ "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 @@ -1198,7 +1258,9 @@ "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. @@ -1208,7 +1270,7 @@ (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" + "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")]) @@ -1236,7 +1298,7 @@ (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")]) @@ -1250,7 +1312,7 @@ (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")]) @@ -1262,7 +1324,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" + "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS" "jarl __save_r6_r9,r10" [(set_attr "length" "4") (set_attr "cc" "clobber")]) |