aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1994-06-02 21:06:45 -0600
committerJeff Law <law@gcc.gnu.org>1994-06-02 21:06:45 -0600
commitf726ea7dd51046d6d6587d99cfa8b0619a0494db (patch)
tree6041878a5a6236044fb20fdc122ec3bc4b02b738
parentb99e1ee9e93f97d187e96c98cf456c86fbe7a23a (diff)
downloadgcc-f726ea7dd51046d6d6587d99cfa8b0619a0494db.zip
gcc-f726ea7dd51046d6d6587d99cfa8b0619a0494db.tar.gz
gcc-f726ea7dd51046d6d6587d99cfa8b0619a0494db.tar.bz2
pa.h (TARGET_SWITCHES): Enable TARGET_LONG_CALLS when TARGET_PORTABLE_RUNTIME is enabled.
* pa.h (TARGET_SWITCHES): Enable TARGET_LONG_CALLS when 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. From-SVN: r7434
-rw-r--r--gcc/config/pa/pa.c16
-rw-r--r--gcc/config/pa/pa.h8
-rw-r--r--gcc/config/pa/pa.md69
3 files changed, 77 insertions, 16 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 3d12251..7c33fc2 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -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 "";
}
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index c82f37d..4be2b0d 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -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}}
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index f9d0d8f..4c7a1af 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -88,10 +88,17 @@
(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)])
@@ -2155,7 +2162,11 @@
(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"
@@ -2201,7 +2212,11 @@
""
"*
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" ""))
@@ -2246,7 +2261,11 @@
""
"*
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" ""))
@@ -2287,7 +2306,11 @@
""
"*
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" ""))
@@ -2328,7 +2351,11 @@
""
"*
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
@@ -3061,9 +3088,19 @@
(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 "" "")
@@ -3133,9 +3170,19 @@
(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.