From 5d5c854105ab9b3ad4600e280eab5499cb560831 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Sat, 3 Jul 1993 16:55:32 -0600 Subject: [PATCH] pa.md (call expanders): Emit different patterns for named calls and indirect calls. * pa.md (call expanders): Emit different patterns for named calls and indirect calls. (call_internal_symref, call_internal_reg): New patterns. (call_internal): Deleted. Now handled by call_interal_{symref,reg}. (call_value_internal_symref, call_value_internal_reg): New patterns. (call_value_internal): Deleted. Now handled by call_value_internal_{symref,reg). From-SVN: r4837 --- gcc/config/pa/pa.md | 93 +++++++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 29 deletions(-) diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 05138097104..5461f257881 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -2754,7 +2754,17 @@ op = force_reg (SImode, XEXP (operands[0], 0)); else op = XEXP (operands[0], 0); - emit_call_insn (gen_call_internal (op, operands[1])); + + /* Use two different patterns for calls to explicitly named functions + and calls through function pointers. This is necessary as these two + types of calls use different calling conventions, and CSE might try + to change the named call into an indirect call in some cases (using + two patterns keeps CSE from performing this optimization). */ + if (GET_CODE (op) == SYMBOL_REF) + emit_call_insn (gen_call_internal_symref (op, operands[1])); + else + emit_call_insn (gen_call_internal_reg (op, operands[1])); + if (flag_pic) { if (!hppa_save_pic_table_rtx) @@ -2765,23 +2775,29 @@ DONE; }") -(define_insn "call_internal" - [(call (mem:SI (match_operand:SI 0 "call_operand_address" "r,S")) - (match_operand 1 "" "i,i")) - (clobber (reg:SI 2))] +(define_insn "call_internal_symref" + [(call (mem:SI (match_operand:SI 0 "call_operand_address" "")) + (match_operand 1 "" "i")) + (clobber (reg:SI 2)) + (use (const_int 0))] "" "* { - if (which_alternative == 0) - return \"copy %0,22\;.CALL\\tARGW0=GR\;bl $$dyncall,31\;copy 31,2\"; - else - { - output_arg_descriptor (insn); - return \"bl %0,2%#\"; - } + output_arg_descriptor (insn); + return \"bl %0,2%#\"; }" - [(set_attr "type" "dyncall,call") - (set_attr "length" "3,1")]) + [(set_attr "type" "call") + (set_attr "length" "1")]) + +(define_insn "call_internal_reg" + [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) + (match_operand 1 "" "i")) + (clobber (reg:SI 2)) + (use (const_int 1))] + "" + "copy %0,22\;.CALL\\tARGW0=GR\;bl $$dyncall,31\;copy 31,2" + [(set_attr "type" "dyncall") + (set_attr "length" "3")]) (define_expand "call_value" [(parallel [(set (match_operand 0 "" "") @@ -2798,7 +2814,18 @@ op = force_reg (SImode, XEXP (operands[1], 0)); else op = XEXP (operands[1], 0); - emit_call_insn (gen_call_value_internal (operands[0], op, operands[2])); + + /* Use two different patterns for calls to explicitly named functions + and calls through function pointers. This is necessary as these two + types of calls use different calling conventions, and CSE might try + to change the named call into an indirect call in some cases (using + two patterns keeps CSE from performing this optimization). */ + if (GET_CODE (op) == SYMBOL_REF) + emit_call_insn (gen_call_value_internal_symref (operands[0], op, + operands[2])); + else + emit_call_insn (gen_call_value_internal_reg (operands[0], op, operands[2])); + if (flag_pic) { if (!hppa_save_pic_table_rtx) @@ -2809,25 +2836,33 @@ DONE; }") -(define_insn "call_value_internal" - [(set (match_operand 0 "" "=rfx,rfx") - (call (mem:SI (match_operand:SI 1 "call_operand_address" "r,S")) - (match_operand 2 "" "i,i"))) - (clobber (reg:SI 2))] +(define_insn "call_value_internal_symref" + [(set (match_operand 0 "" "=rfx") + (call (mem:SI (match_operand:SI 1 "call_operand_address" "")) + (match_operand 2 "" "i"))) + (clobber (reg:SI 2)) + (use (const_int 0))] ;;- Don't use operand 1 for most machines. "" "* { - if (which_alternative == 0) - return \"copy %1,22\;.CALL\\tARGW0=GR\;bl $$dyncall,31\;copy 31,2\"; - else - { - output_arg_descriptor (insn); - return \"bl %1,2%#\"; - } + output_arg_descriptor (insn); + return \"bl %1,2%#\"; }" - [(set_attr "type" "dyncall,call") - (set_attr "length" "3,1")]) + [(set_attr "type" "call") + (set_attr "length" "1")]) + +(define_insn "call_value_internal_reg" + [(set (match_operand 0 "" "=rfx") + (call (mem:SI (match_operand:SI 1 "register_operand" "r")) + (match_operand 2 "" "i"))) + (clobber (reg:SI 2)) + (use (const_int 1))] + ;;- Don't use operand 1 for most machines. + "" + "copy %1,22\;.CALL\\tARGW0=GR\;bl $$dyncall,31\;copy 31,2" + [(set_attr "type" "dyncall") + (set_attr "length" "3")]) (define_insn "nop" [(const_int 0)] -- 2.30.2