From f726ea7dd51046d6d6587d99cfa8b0619a0494db Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Thu, 2 Jun 1994 21:06:45 -0600 Subject: [PATCH] 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 --- gcc/config/pa/pa.c | 16 +++++++++-- gcc/config/pa/pa.h | 8 ++++-- gcc/config/pa/pa.md | 69 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 77 insertions(+), 16 deletions(-) diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 3d122516220..7c33fc2a544 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 c82f37d741e..4be2b0d308e 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 f9d0d8fb0e8..4c7a1afc1e0 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. -- 2.30.2