aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJohn David Anglin <danglin@gcc.gnu.org>2023-04-15 17:02:44 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2023-04-15 17:02:44 +0000
commit4f1c5e54d782b26304b0095ffb3ceb4c92c3c78d (patch)
treea5d2b649420288edcfbac31b2837c7fea921b939 /gcc
parent13669741e673fa6a7b7c8d68f992e58ecd393160 (diff)
downloadgcc-4f1c5e54d782b26304b0095ffb3ceb4c92c3c78d.zip
gcc-4f1c5e54d782b26304b0095ffb3ceb4c92c3c78d.tar.gz
gcc-4f1c5e54d782b26304b0095ffb3ceb4c92c3c78d.tar.bz2
Fix handling of large arguments passed by value.
2023-04-15 John David Anglin <danglin@gcc.gnu.org> gcc/ChangeLog: PR target/104989 * config/pa/pa-protos.h (pa_function_arg_size): Update prototype. * config/pa/pa.cc (pa_function_arg): Return NULL_RTX if argument size is zero. (pa_arg_partial_bytes): Don't call pa_function_arg_size twice. (pa_function_arg_size): Change return type to int. Return zero for arguments larger than 1 GB. Update comments.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/pa/pa-protos.h2
-rw-r--r--gcc/config/pa/pa.cc27
2 files changed, 20 insertions, 9 deletions
diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h
index c0a61ea..b4b1310 100644
--- a/gcc/config/pa/pa-protos.h
+++ b/gcc/config/pa/pa-protos.h
@@ -106,7 +106,7 @@ extern void pa_asm_output_aligned_local (FILE *, const char *,
unsigned int);
extern void pa_hpux_asm_output_external (FILE *, tree, const char *);
extern HOST_WIDE_INT pa_initial_elimination_offset (int, int);
-extern HOST_WIDE_INT pa_function_arg_size (machine_mode, const_tree);
+extern int pa_function_arg_size (machine_mode, const_tree);
extern void pa_output_function_label (FILE *);
extern void hppa_profile_hook (int);
diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc
index 3f91ebc..db633b2 100644
--- a/gcc/config/pa/pa.cc
+++ b/gcc/config/pa/pa.cc
@@ -9784,6 +9784,8 @@ pa_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
return NULL_RTX;
arg_size = pa_function_arg_size (mode, type);
+ if (!arg_size)
+ return NULL_RTX;
/* If this arg would be passed partially or totally on the stack, then
this routine should return zero. pa_arg_partial_bytes will
@@ -9985,15 +9987,16 @@ pa_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
unsigned int max_arg_words = 8;
unsigned int offset = 0;
+ int arg_size;
if (!TARGET_64BIT)
return 0;
- if (pa_function_arg_size (arg.mode, arg.type) > 1 && (cum->words & 1))
+ arg_size = pa_function_arg_size (arg.mode, arg.type);
+ if (arg_size > 1 && (cum->words & 1))
offset = 1;
- if (cum->words + offset + pa_function_arg_size (arg.mode, arg.type)
- <= max_arg_words)
+ if (cum->words + offset + arg_size <= max_arg_words)
/* Arg fits fully into registers. */
return 0;
else if (cum->words + offset >= max_arg_words)
@@ -11067,17 +11070,25 @@ pa_starting_frame_offset (void)
return 8;
}
-/* Figure out the size in words of the function argument. The size
- returned by this function should always be greater than zero because
- we pass variable and zero sized objects by reference. */
+/* Figure out the size in words of the function argument. */
-HOST_WIDE_INT
+int
pa_function_arg_size (machine_mode mode, const_tree type)
{
HOST_WIDE_INT size;
size = mode != BLKmode ? GET_MODE_SIZE (mode) : int_size_in_bytes (type);
- return CEIL (size, UNITS_PER_WORD);
+
+ /* The 64-bit runtime does not restrict the size of stack frames,
+ but the gcc calling conventions limit argument sizes to 1G. Our
+ prologue/epilogue code limits frame sizes to just under 32 bits.
+ 1G is also the maximum frame size that can be handled by the HPUX
+ unwind descriptor. Since very large TYPE_SIZE_UNIT values can
+ occur for (parallel:BLK []), we need to ignore large arguments
+ passed by value. */
+ if (size >= (1 << (HOST_BITS_PER_INT - 2)))
+ size = 0;
+ return (int) CEIL (size, UNITS_PER_WORD);
}
#include "gt-pa.h"