OSDN Git Service

* pa.h (TARGET_SWITCHES): Enable TARGET_LONG_CALLS when
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 3 Jun 1994 03:06:45 +0000 (03:06 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 3 Jun 1994 03:06:45 +0000 (03:06 +0000)
TARGET_PORTABLE_RUNTIME is enabled.
* pa.c (output_call): If TARGET_LONG_CALLS is enabled, then emit
an inline long-call sequence.
* pa.md (millicode define_delay): Disable delay slots if
TARGET_LONG_CALLS.
(call_internal_reg, call_value_internal_reg): If TARGET_LONG_CALLS
is enabled, then emit an inline long-call sequence.  Fix length
computation for TARGET_LONG_CALLS.
(millicode calls): Fix length computation for TARGET_LONG_CALLS.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@7434 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/pa.md

index 3d12251..7c33fc2 100644 (file)
@@ -3706,7 +3706,12 @@ output_movb (operands, insn, which_alternative, reverse_comparison)
    CALL_DEST is the routine we are calling.
 
    RETURN_POINTER is the register which will hold the return address.
-   %r2 for most calls, %r31 for millicode calls.  */
+   %r2 for most calls, %r31 for millicode calls. 
+
+   When TARGET_LONG_CALLS is true, output_call is only called for
+   millicode calls.  In addition, no delay slots are available when
+   TARGET_LONG_CALLS is true.  */
+
 char *
 output_call (insn, call_dest, return_pointer)
   rtx insn;
@@ -3725,7 +3730,14 @@ output_call (insn, call_dest, return_pointer)
     {
       xoperands[0] = call_dest;
       xoperands[1] = return_pointer;
-      output_asm_insn ("bl %0,%r1%#", xoperands);
+      if (TARGET_LONG_CALLS)
+       {
+         output_asm_insn ("ldil L%%%0,%%r29", xoperands);
+         output_asm_insn ("ldo R%%%0(%%r29),%%r29", xoperands);
+         output_asm_insn ("blr 0,%r1\n\tbv,n 0(%%r29)\n\tnop", xoperands);
+       }
+      else
+       output_asm_insn ("bl %0,%r1%#", xoperands);
       return "";
     }
 
index c82f37d..4be2b0d 100644 (file)
@@ -64,7 +64,9 @@ extern int target_flags;
 
 /* Emit code which follows the new portable runtime calling conventions
    HP wants everyone to use for ELF objects.  If at all possible you want
-   to avoid this since it's a performance loss for non-prototyped code.  */
+   to avoid this since it's a performance loss for non-prototyped code.
+
+   Note TARGET_PORTABLE_RUNTIME also implies TARGET_LONG_CALLS.  */
 
 #define TARGET_PORTABLE_RUNTIME (target_flags & 64)
 
@@ -93,8 +95,8 @@ extern int target_flags;
    {"no-long-calls", -16},     \
    {"disable-indexing", 32},   \
    {"no-disable-indexing", -32},\
-   {"portable-runtime", 64},   \
-   {"no-portable-runtime", -64},\
+   {"portable-runtime", 64+16},\
+   {"no-portable-runtime", -(64+16)},\
    {"gas", 128},               \
    {"no-gas", -128},           \
    { "", TARGET_DEFAULT}}
index f9d0d8f..4c7a1af 100644 (file)
        (const_string "false")))
 
 
-;; Unconditional branch, call, and millicode call delay slot description.
-(define_delay (eq_attr "type" "uncond_branch,branch,call,milli")
+;; Unconditional branch and call delay slot description.
+(define_delay (eq_attr "type" "uncond_branch,branch,call")
   [(eq_attr "in_call_delay" "true") (nil) (nil)])
 
+;; millicode call delay slot description.  Note it disallows delay slot
+;; when TARGET_LONG_CALLS is true.
+(define_delay (eq_attr "type" "milli")
+  [(and (eq_attr "in_call_delay" "true")
+       (eq (symbol_ref "TARGET_LONG_CALLS") (const_int 0)))
+   (nil) (nil)])
+
 ;; Unconditional branch, return and other similar instructions.
 (define_delay (eq_attr "type" "uncond_branch,branch")
   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
    (clobber (reg:SI 31))]
   ""
   "* return output_mul_insn (0, insn);"
-  [(set_attr "type" "milli")])
+  [(set_attr "type" "milli")
+   (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS")
+                                         (const_int 0))
+                                     (const_int 4)
+                                     (const_int 24)))])
 
 ;;; Division and mod.
 (define_expand "divsi3"
   ""
   "*
    return output_div_insn (operands, 0, insn);"
-  [(set_attr "type" "milli")])
+  [(set_attr "type" "milli")
+   (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS")
+                                         (const_int 0))
+                                     (const_int 4)
+                                     (const_int 24)))])
 
 (define_expand "udivsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
   ""
   "*
    return output_div_insn (operands, 1, insn);"
-  [(set_attr "type" "milli")])
+  [(set_attr "type" "milli")
+   (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS")
+                                         (const_int 0))
+                                     (const_int 4)
+                                     (const_int 24)))])
 
 (define_expand "modsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
   ""
   "*
   return output_mod_insn (0, insn);"
-  [(set_attr "type" "milli")])
+  [(set_attr "type" "milli")
+   (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS")
+                                         (const_int 0))
+                                     (const_int 4)
+                                     (const_int 24)))])
 
 (define_expand "umodsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
   ""
   "*
   return output_mod_insn (1, insn);"
-  [(set_attr "type" "milli")])
+  [(set_attr "type" "milli")
+   (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS")
+                                         (const_int 0))
+                                     (const_int 4)
+                                     (const_int 24)))])
 
 ;;- and instructions
 ;; We define DImode `and` so with DImode `not` we can get
    (clobber (reg:SI 2))
    (use (const_int 1))]
   ""
-  "copy %r0,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2"
+  "*
+{
+  /* Yuk!  bl may not be able to reach $$dyncall.  */
+  if (TARGET_LONG_CALLS)
+    return \"copy %r0,%%r22\;ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\";
+  else
+    return \"copy %r0,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\";
+}"
   [(set_attr "type" "dyncall")
-   (set_attr "length" "12")])
+   (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS")
+                                         (const_int 0))
+                                     (const_int 12)
+                                     (const_int 24)))])
 
 (define_expand "call_value"
   [(parallel [(set (match_operand 0 "" "")
    (use (const_int 1))]
   ;;- Don't use operand 1 for most machines.
   ""
-  "copy %r1,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2"
+  "*
+{
+  /* Yuk!  bl may not be able to reach $$dyncall.  */
+  if (TARGET_LONG_CALLS)
+    return \"copy %r1,%%r22\;ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\";
+  else
+    return \"copy %r1,%%r22\;.CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\";
+}"
   [(set_attr "type" "dyncall")
-   (set_attr "length" "12")])
+   (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS")
+                                         (const_int 0))
+                                     (const_int 12)
+                                     (const_int 24)))])
 
 ;; Call subroutine returning any type.