OSDN Git Service

Fix for PR 18535 - enforce -mlong-calls option
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Feb 1999 12:23:33 +0000 (12:23 +0000)
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Feb 1999 12:23:33 +0000 (12:23 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25084 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/v850/v850.c
gcc/config/v850/v850.md

index 78f04ed..1b044b4 100644 (file)
@@ -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.
index b27f12c..15867ac 100644 (file)
@@ -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;
 }
index 42a95db..daea8b7 100644 (file)
@@ -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).
 
 (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"
   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).
   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)]
  "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
  "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"
+  "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")])