aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog12
-rw-r--r--gdb/s390-tdep.c27
2 files changed, 29 insertions, 10 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 49687c9..0fb0d36 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,15 @@
+2011-09-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * s390-tdep.c (s390_function_arg_pass_by_reference): Handle
+ complex and vector types.
+ (s390_return_value_convention): Likewise.
+
+ (s390_value_from_register): Call check_typedef.
+ (extend_simple_arg): Likewise.
+ (alignment_of): Likewise.
+ (s390_push_dummy_call): Likewise.
+ (s390_return_value): Likewise.
+
2011-09-21 Joseph Myers <joseph@codesourcery.com>
* event-top.c (async_disconnect): If an exception is thrown from
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index ca7ecc7..788f8c1 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -336,7 +336,7 @@ s390_value_from_register (struct type *type, int regnum,
struct frame_info *frame)
{
struct value *value = default_value_from_register (type, regnum, frame);
- int len = TYPE_LENGTH (type);
+ int len = TYPE_LENGTH (check_typedef (type));
if (regnum >= S390_F0_REGNUM && regnum <= S390_F15_REGNUM && len < 8)
set_value_offset (value, 0);
@@ -2254,8 +2254,9 @@ s390_function_arg_pass_by_reference (struct type *type)
if (length > 8)
return 1;
- /* FIXME: All complex and vector types are also returned by reference. */
- return is_struct_like (type) && !is_power_of_two (length);
+ return (is_struct_like (type) && !is_power_of_two (TYPE_LENGTH (type)))
+ || TYPE_CODE (type) == TYPE_CODE_COMPLEX
+ || (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type));
}
/* Return non-zero if TYPE should be passed in a float register
@@ -2290,7 +2291,7 @@ static LONGEST
extend_simple_arg (struct gdbarch *gdbarch, struct value *arg)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct type *type = value_type (arg);
+ struct type *type = check_typedef (value_type (arg));
/* Even structs get passed in the least significant bits of the
register / memory word. It's not really right to extract them as
@@ -2323,7 +2324,8 @@ alignment_of (struct type *type)
alignment = 1;
for (i = 0; i < TYPE_NFIELDS (type); i++)
{
- int field_alignment = alignment_of (TYPE_FIELD_TYPE (type, i));
+ int field_alignment
+ = alignment_of (check_typedef (TYPE_FIELD_TYPE (type, i)));
if (field_alignment > alignment)
alignment = field_alignment;
@@ -2374,7 +2376,7 @@ s390_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
for (i = 0; i < nargs; i++)
{
struct value *arg = args[i];
- struct type *type = value_type (arg);
+ struct type *type = check_typedef (value_type (arg));
unsigned length = TYPE_LENGTH (type);
if (s390_function_arg_pass_by_reference (type))
@@ -2427,7 +2429,7 @@ s390_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
for (i = 0; i < nargs; i++)
{
struct value *arg = args[i];
- struct type *type = value_type (arg);
+ struct type *type = check_typedef (value_type (arg));
unsigned length = TYPE_LENGTH (type);
if (s390_function_arg_pass_by_reference (type))
@@ -2561,6 +2563,7 @@ s390_return_value_convention (struct gdbarch *gdbarch, struct type *type)
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
case TYPE_CODE_ARRAY:
+ case TYPE_CODE_COMPLEX:
return RETURN_VALUE_STRUCT_CONVENTION;
default:
@@ -2575,9 +2578,13 @@ s390_return_value (struct gdbarch *gdbarch, struct type *func_type,
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int word_size = gdbarch_ptr_bit (gdbarch) / 8;
- int length = TYPE_LENGTH (type);
- enum return_value_convention rvc =
- s390_return_value_convention (gdbarch, type);
+ enum return_value_convention rvc;
+ int length;
+
+ type = check_typedef (type);
+ rvc = s390_return_value_convention (gdbarch, type);
+ length = TYPE_LENGTH (type);
+
if (in)
{
switch (rvc)