From bfb23806b83c3bc24f9ed6232974d783c00a2ebd Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 7 May 2004 13:40:42 +0200 Subject: [PATCH] sparc-protos.h (sparc_skip_caller_unimp): New declaration. * config/sparc/sparc-protos.h (sparc_skip_caller_unimp): New declaration. * config/sparc/sparc.c (SKIP_CALLERS_UNIMP_P): Delete. (sparc_skip_caller_unimp): New global variable. (sparc_function_epilogue): Set 'sparc_skip_caller_unimp'. Use it instead of SKIP_CALLERS_UNIMP_P. * config/sparc/sparc.md (call expander): Add sanity check. (call_address_struct_value_sp32): Re-sync with expander. (call_symbolic_struct_value_sp32): Likewise. (return peepholes): Use 'sparc_skip_caller_unimp' instead of custom predicate. From-SVN: r81617 --- gcc/ChangeLog | 14 ++++++++++++++ gcc/config/sparc/sparc-protos.h | 1 + gcc/config/sparc/sparc.c | 33 +++++++++++++++++---------------- gcc/config/sparc/sparc.md | 26 ++++++++++++++++---------- 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index edad48cad9d..a4e98639538 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2004-05-07 Eric Botcazou + + * config/sparc/sparc-protos.h (sparc_skip_caller_unimp): New + declaration. + * config/sparc/sparc.c (SKIP_CALLERS_UNIMP_P): Delete. + (sparc_skip_caller_unimp): New global variable. + (sparc_function_epilogue): Set 'sparc_skip_caller_unimp'. + Use it instead of SKIP_CALLERS_UNIMP_P. + * config/sparc/sparc.md (call expander): Add sanity check. + (call_address_struct_value_sp32): Re-sync with expander. + (call_symbolic_struct_value_sp32): Likewise. + (return peepholes): Use 'sparc_skip_caller_unimp' instead + of custom predicate. + 2004-05-07 Eric Botcazou PR c++/14962 diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 0908aaa5ea5..4b1f9f0d3be 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA. */ #define __SPARC_PROTOS_H__ extern bool sparc_emitting_epilogue; +extern bool sparc_skip_caller_unimp; #ifdef TREE_CODE extern struct rtx_def *function_value (tree, enum machine_mode, int); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 76ccb34eade..2192d967224 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -48,17 +48,6 @@ Boston, MA 02111-1307, USA. */ #include "target-def.h" #include "cfglayout.h" -/* 1 if the caller has placed an "unimp" insn immediately after the call. - This is used in v8 code when calling a function that returns a structure. - v9 doesn't have this. Be careful to have this test be the same as that - used on the call. */ - -#define SKIP_CALLERS_UNIMP_P \ -(!TARGET_ARCH64 && current_function_returns_struct \ - && ! integer_zerop (DECL_SIZE (DECL_RESULT (current_function_decl))) \ - && (TREE_CODE (DECL_SIZE (DECL_RESULT (current_function_decl))) \ - == INTEGER_CST)) - /* Global variables for machine-dependent things. */ /* Size of frame. Need to know this to emit return insns from leaf procedures. @@ -81,6 +70,7 @@ rtx sparc_compare_op0, sparc_compare_op1; /* Coordinate with the md file wrt special insns created by sparc_function_epilogue. */ bool sparc_emitting_epilogue; +bool sparc_skip_caller_unimp; /* Vector to say how input registers are mapped to output registers. HARD_FRAME_POINTER_REGNUM cannot be remapped by this function to @@ -4498,6 +4488,17 @@ sparc_function_epilogue (FILE *file, { const char *ret; + /* True if the caller has placed an "unimp" insn immediately after the call. + This insn is used in the 32-bit ABI when calling a function that returns + a non zero-sized structure. The 64-bit ABI doesn't have it. Be careful + to have this test be the same as that used on the call. */ + sparc_skip_caller_unimp = + ! TARGET_ARCH64 + && current_function_returns_struct + && (TREE_CODE (DECL_SIZE (DECL_RESULT (current_function_decl))) + == INTEGER_CST) + && ! integer_zerop (DECL_SIZE (DECL_RESULT (current_function_decl))); + if (current_function_epilogue_delay_list == 0) { /* If code does not drop into the epilogue, we need @@ -4532,9 +4533,9 @@ sparc_function_epilogue (FILE *file, /* Work out how to skip the caller's unimp instruction if required. */ if (leaf_function) - ret = (SKIP_CALLERS_UNIMP_P ? "jmp\t%o7+12" : "retl"); + ret = (sparc_skip_caller_unimp ? "jmp\t%o7+12" : "retl"); else - ret = (SKIP_CALLERS_UNIMP_P ? "jmp\t%i7+12" : "ret"); + ret = (sparc_skip_caller_unimp ? "jmp\t%i7+12" : "ret"); if (! leaf_function) { @@ -4542,7 +4543,7 @@ sparc_function_epilogue (FILE *file, { if (current_function_epilogue_delay_list) abort (); - if (SKIP_CALLERS_UNIMP_P) + if (sparc_skip_caller_unimp) abort (); fputs ("\trestore\n\tretl\n\tadd\t%sp, %g1, %sp\n", file); @@ -4555,7 +4556,7 @@ sparc_function_epilogue (FILE *file, if (TARGET_V9 && ! epilogue_renumber (&delay, 1)) { epilogue_renumber (&delay, 0); - fputs (SKIP_CALLERS_UNIMP_P + fputs (sparc_skip_caller_unimp ? "\treturn\t%i7+12\n" : "\treturn\t%i7+8\n", file); final_scan_insn (XEXP (current_function_epilogue_delay_list, 0), @@ -4588,7 +4589,7 @@ sparc_function_epilogue (FILE *file, sparc_emitting_epilogue = false; } } - else if (TARGET_V9 && ! SKIP_CALLERS_UNIMP_P) + else if (TARGET_V9 && ! sparc_skip_caller_unimp) fputs ("\treturn\t%i7+8\n\tnop\n", file); else fprintf (file, "\t%s\n\trestore\n", ret); diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 2c388f99c8a..130d58c84f8 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -7321,9 +7321,12 @@ { rtx fn_rtx; - if (GET_MODE (operands[0]) != FUNCTION_MODE) + if (GET_MODE (operands[0]) != FUNCTION_MODE) abort (); + if (GET_CODE (operands[3]) != CONST_INT) + abort(); + if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF) { /* This is really a PIC sequence. We want to represent @@ -7333,6 +7336,7 @@ call-clobbered registers? We lose this if it is a JUMP_INSN. Why cannot we have delay slots filled if it were a CALL? */ + /* We accept negative sizes for untyped calls. */ if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0) emit_jump_insn (gen_rtx_PARALLEL @@ -7353,6 +7357,7 @@ fn_rtx = operands[0]; + /* We accept negative sizes for untyped calls. */ if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0) emit_call_insn (gen_rtx_PARALLEL @@ -7419,7 +7424,7 @@ (match_operand 2 "immediate_operand" "") (clobber (reg:SI 15))] ;;- Do not use operand 1 for most machines. - "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0" + "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" "call\t%a0, %1\n\tnop\n\tunimp\t%2" [(set_attr "type" "call_no_delay_slot") (set_attr "length" "3")]) @@ -7432,7 +7437,7 @@ (match_operand 2 "immediate_operand" "") (clobber (reg:SI 15))] ;;- Do not use operand 1 for most machines. - "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0" + "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" "call\t%a0, %1\n\tnop\n\tunimp\t%2" [(set_attr "type" "call_no_delay_slot") (set_attr "length" "3")]) @@ -7450,7 +7455,8 @@ [(set_attr "type" "call_no_delay_slot") (set_attr "length" "3")]) -;; This is a call that wants a structure value. +;; This is a call that may want a structure value. This is used for +;; untyped_calls. (define_insn "*call_symbolic_untyped_struct_value_sp32" [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) (match_operand 1 "" "")) @@ -8083,7 +8089,7 @@ (return)] "sparc_emitting_epilogue" { - if (! TARGET_ARCH64 && current_function_returns_struct) + if (sparc_skip_caller_unimp) return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0"; else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT || IN_OR_GLOBAL_P (operands[1]))) @@ -8100,7 +8106,7 @@ (return)] "sparc_emitting_epilogue" { - if (! TARGET_ARCH64 && current_function_returns_struct) + if (sparc_skip_caller_unimp) return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0"; else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT || IN_OR_GLOBAL_P (operands[1]))) @@ -8117,7 +8123,7 @@ (return)] "sparc_emitting_epilogue" { - if (! TARGET_ARCH64 && current_function_returns_struct) + if (sparc_skip_caller_unimp) return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0"; else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT || IN_OR_GLOBAL_P (operands[1]))) @@ -8134,7 +8140,7 @@ (return)] "sparc_emitting_epilogue" { - if (! TARGET_ARCH64 && current_function_returns_struct) + if (sparc_skip_caller_unimp) return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0"; else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])) return "return\t%%i7+8\n\tmov\t%Y1, %Y0"; @@ -8165,7 +8171,7 @@ (return)] "sparc_emitting_epilogue" { - if (! TARGET_ARCH64 && current_function_returns_struct) + if (sparc_skip_caller_unimp) return "jmp\t%%i7+12\n\trestore %r1, %2, %Y0"; /* If operands are global or in registers, can use return */ else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]) @@ -8185,7 +8191,7 @@ (return)] "sparc_emitting_epilogue && ! TARGET_CM_MEDMID" { - if (! TARGET_ARCH64 && current_function_returns_struct) + if (sparc_skip_caller_unimp) return "jmp\t%%i7+12\n\trestore %r1, %%lo(%a2), %Y0"; /* If operands are global or in registers, can use return */ else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])) -- 2.30.2