X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fppc-sysv-tdep.c;h=3d5a7dbb8e498bd6229d224d0b9ec421a7bbce83;hb=904001b085513a5d6b7734275f6fb90c860cf3be;hp=9d54227a97a77e3ce53eaaa2d3f3b25dc64ad9a2;hpb=36815e57a6bfc52ac1231d78f52bbf656b3f8886;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c index 9d54227a97..3d5a7dbb8e 100644 --- a/gdb/ppc-sysv-tdep.c +++ b/gdb/ppc-sysv-tdep.c @@ -1,7 +1,7 @@ /* Target-dependent code for PowerPC systems using the SVR4 ABI for GDB, the GNU debugger. - Copyright (C) 2000, 2001, 2002, 2003, 2005, 2007 + Copyright (C) 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GDB. @@ -48,15 +48,14 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ULONGEST saved_sp; int argspace = 0; /* 0 is an initial wrong guess. */ int write_pass; gdb_assert (tdep->wordsize == 4); - regcache_cooked_read_unsigned (regcache, - gdbarch_sp_regnum (current_gdbarch), + regcache_cooked_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch), &saved_sp); /* Go through the argument list twice. @@ -130,23 +129,27 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, } else { - /* SysV ABI converts floats to doubles before - writing them to an 8 byte aligned stack location. */ - argoffset = align_up (argoffset, 8); + /* The SysV ABI tells us to convert floats to + doubles before writing them to an 8 byte aligned + stack location. Unfortunately GCC does not do + that, and stores floats into 4 byte aligned + locations without converting them to doubles. + Since there is no know compiler that actually + follows the ABI here, we implement the GCC + convention. */ + + /* Align to 4 bytes or 8 bytes depending on the type of + the argument (float or double). */ + argoffset = align_up (argoffset, len); if (write_pass) - { - char memval[8]; - convert_typed_floating (val, type, memval, - builtin_type_ieee_double); write_memory (sp + argoffset, val, len); - } - argoffset += 8; + argoffset += len; } } else if (TYPE_CODE (type) == TYPE_CODE_FLT && len == 16 && !tdep->soft_float - && (gdbarch_long_double_format (current_gdbarch) + && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double)) { /* IBM long double passed in two FP registers if @@ -174,13 +177,16 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, } else if (len == 8 && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */ - || TYPE_CODE (type) == TYPE_CODE_FLT)) /* double */ + || TYPE_CODE (type) == TYPE_CODE_FLT /* double */ + || (TYPE_CODE (type) == TYPE_CODE_DECFLOAT + && tdep->soft_float))) { - /* "long long" or soft-float "double" passed in an odd/even - register pair with the low addressed word in the odd - register and the high addressed word in the even - register, or when the registers run out an 8 byte - aligned stack location. */ + /* "long long" or soft-float "double" or "_Decimal64" + passed in an odd/even register pair with the low + addressed word in the odd register and the high + addressed word in the even register, or when the + registers run out an 8 byte aligned stack + location. */ if (greg > 9) { /* Just in case GREG was 10. */ @@ -207,13 +213,16 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, greg += 2; } } - else if (len == 16 && TYPE_CODE (type) == TYPE_CODE_FLT - && (gdbarch_long_double_format (current_gdbarch) - == floatformats_ibm_long_double)) + else if (len == 16 + && ((TYPE_CODE (type) == TYPE_CODE_FLT + && (gdbarch_long_double_format (gdbarch) + == floatformats_ibm_long_double)) + || (TYPE_CODE (type) == TYPE_CODE_DECFLOAT + && tdep->soft_float))) { - /* Soft-float IBM long double passed in four consecutive - registers, or on the stack. The registers are not - necessarily odd/even pairs. */ + /* Soft-float IBM long double or _Decimal128 passed in + four consecutive registers, or on the stack. The + registers are not necessarily odd/even pairs. */ if (greg > 7) { greg = 11; @@ -242,6 +251,81 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, greg += 4; } } + else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && len <= 8 + && !tdep->soft_float) + { + /* 32-bit and 64-bit decimal floats go in f1 .. f8. They can + end up in memory. */ + + if (freg <= 8) + { + if (write_pass) + { + gdb_byte regval[MAX_REGISTER_SIZE]; + const gdb_byte *p; + + /* 32-bit decimal floats are right aligned in the + doubleword. */ + if (TYPE_LENGTH (type) == 4) + { + memcpy (regval + 4, val, 4); + p = regval; + } + else + p = val; + + regcache_cooked_write (regcache, + tdep->ppc_fp0_regnum + freg, p); + } + + freg++; + } + else + { + argoffset = align_up (argoffset, len); + + if (write_pass) + /* Write value in the stack's parameter save area. */ + write_memory (sp + argoffset, val, len); + + argoffset += len; + } + } + else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && len == 16 + && !tdep->soft_float) + { + /* 128-bit decimal floats go in f2 .. f7, always in even/odd + pairs. They can end up in memory, using two doublewords. */ + + if (freg <= 6) + { + /* Make sure freg is even. */ + freg += freg & 1; + + if (write_pass) + { + regcache_cooked_write (regcache, + tdep->ppc_fp0_regnum + freg, val); + regcache_cooked_write (regcache, + tdep->ppc_fp0_regnum + freg + 1, val + 8); + } + } + else + { + argoffset = align_up (argoffset, 8); + + if (write_pass) + write_memory (sp + argoffset, val, 16); + + argoffset += 16; + } + + /* If a 128-bit decimal float goes to the stack because only f7 + and f8 are free (thus there's no even/odd register pair + available), these registers should be marked as occupied. + Hence we increase freg even when writing to memory. */ + freg += 2; + } else if (len == 16 && TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type) @@ -375,8 +459,7 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, } /* Update %sp. */ - regcache_cooked_write_signed (regcache, - gdbarch_sp_regnum (current_gdbarch), sp); + regcache_cooked_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp); /* Write the backchain (it occupies WORDSIZED bytes). */ write_memory_signed_integer (sp, tdep->wordsize, saved_sp); @@ -388,6 +471,70 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, return sp; } +/* Handle the return-value conventions for Decimal Floating Point values + in both ppc32 and ppc64, which are the same. */ +static int +get_decimal_float_return_value (struct gdbarch *gdbarch, struct type *valtype, + struct regcache *regcache, gdb_byte *readbuf, + const gdb_byte *writebuf) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + gdb_assert (TYPE_CODE (valtype) == TYPE_CODE_DECFLOAT); + + /* 32-bit and 64-bit decimal floats in f1. */ + if (TYPE_LENGTH (valtype) <= 8) + { + if (writebuf != NULL) + { + gdb_byte regval[MAX_REGISTER_SIZE]; + const gdb_byte *p; + + /* 32-bit decimal float is right aligned in the doubleword. */ + if (TYPE_LENGTH (valtype) == 4) + { + memcpy (regval + 4, writebuf, 4); + p = regval; + } + else + p = writebuf; + + regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, p); + } + if (readbuf != NULL) + { + regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, readbuf); + + /* Left align 32-bit decimal float. */ + if (TYPE_LENGTH (valtype) == 4) + memcpy (readbuf, readbuf + 4, 4); + } + } + /* 128-bit decimal floats in f2,f3. */ + else if (TYPE_LENGTH (valtype) == 16) + { + if (writebuf != NULL || readbuf != NULL) + { + int i; + + for (i = 0; i < 2; i++) + { + if (writebuf != NULL) + regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 2 + i, + writebuf + i * 8); + if (readbuf != NULL) + regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 2 + i, + readbuf + i * 8); + } + } + } + else + /* Can't happen. */ + internal_error (__FILE__, __LINE__, "Unknown decimal float size."); + + return RETURN_VALUE_REGISTER_CONVENTION; +} + /* Handle the return-value conventions specified by the SysV 32-bit PowerPC ABI (including all the supplements): @@ -438,8 +585,7 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type, if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 16 && !tdep->soft_float - && (gdbarch_long_double_format (current_gdbarch) - == floatformats_ibm_long_double)) + && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double)) { /* IBM long double stored in f1 and f2. */ if (readbuf) @@ -456,12 +602,13 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type, } return RETURN_VALUE_REGISTER_CONVENTION; } - if (TYPE_CODE (type) == TYPE_CODE_FLT - && TYPE_LENGTH (type) == 16 - && (gdbarch_long_double_format (current_gdbarch) - == floatformats_ibm_long_double)) + if (TYPE_LENGTH (type) == 16 + && ((TYPE_CODE (type) == TYPE_CODE_FLT + && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double)) + || (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && tdep->soft_float))) { - /* Soft-float IBM long double stored in r3, r4, r5, r6. */ + /* Soft-float IBM long double or _Decimal128 stored in r3, r4, + r5, r6. */ if (readbuf) { regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, readbuf); @@ -485,11 +632,14 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type, return RETURN_VALUE_REGISTER_CONVENTION; } if ((TYPE_CODE (type) == TYPE_CODE_INT && TYPE_LENGTH (type) == 8) - || (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8)) + || (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8) + || (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && TYPE_LENGTH (type) == 8 + && tdep->soft_float)) { if (readbuf) { - /* A long long, or a double stored in the 32 bit r3/r4. */ + /* A long long, double or _Decimal64 stored in the 32 bit + r3/r4. */ regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, readbuf + 0); regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, @@ -497,7 +647,8 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type, } if (writebuf) { - /* A long long, or a double stored in the 32 bit r3/r4. */ + /* A long long, double or _Decimal64 stored in the 32 bit + r3/r4. */ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, writebuf + 0); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, @@ -505,6 +656,9 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type, } return RETURN_VALUE_REGISTER_CONVENTION; } + if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && !tdep->soft_float) + return get_decimal_float_return_value (gdbarch, type, regcache, readbuf, + writebuf); else if ((TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_CHAR || TYPE_CODE (type) == TYPE_CODE_BOOL @@ -663,9 +817,9 @@ do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type, } enum return_value_convention -ppc_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype, - struct regcache *regcache, gdb_byte *readbuf, - const gdb_byte *writebuf) +ppc_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *func_type, + struct type *valtype, struct regcache *regcache, + gdb_byte *readbuf, const gdb_byte *writebuf) { return do_ppc_sysv_return_value (gdbarch, valtype, regcache, readbuf, writebuf, 0); @@ -673,6 +827,7 @@ ppc_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype, enum return_value_convention ppc_sysv_abi_broken_return_value (struct gdbarch *gdbarch, + struct type *func_type, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) @@ -736,7 +891,7 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int struct_return, CORE_ADDR struct_addr) { CORE_ADDR func_addr = find_function_addr (function, NULL); - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ULONGEST back_chain; /* See for-loop comment below. */ int write_pass; @@ -763,8 +918,7 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* By this stage in the proceedings, SP has been decremented by "red zone size" + "struct return size". Fetch the stack-pointer from before this and use that as the BACK_CHAIN. */ - regcache_cooked_read_unsigned (regcache, - gdbarch_sp_regnum (current_gdbarch), + regcache_cooked_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch), &back_chain); /* Go through the argument list twice. @@ -797,7 +951,7 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, { /* During the first pass, GPARAM and VPARAM are more like offsets (start address zero) than addresses. That way - the accumulate the total stack space each region + they accumulate the total stack space each region requires. */ gparam = 0; vparam = 0; @@ -834,6 +988,7 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct value *arg = args[argno]; struct type *type = check_typedef (value_type (arg)); const bfd_byte *val = value_contents (arg); + if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8) { /* Floats and Doubles go in f1 .. f13. They also @@ -841,44 +996,57 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, memory. */ if (write_pass) { + gdb_byte regval[MAX_REGISTER_SIZE]; + const gdb_byte *p; + + /* Version 1.7 of the 64-bit PowerPC ELF ABI says: + + "Single precision floating point values are mapped to + the first word in a single doubleword." + + And version 1.9 says: + + "Single precision floating point values are mapped to + the second word in a single doubleword." + + GDB then writes single precision floating point values + at both words in a doubleword, to support both ABIs. */ + if (TYPE_LENGTH (type) == 4) + { + memcpy (regval, val, 4); + memcpy (regval + 4, val, 4); + p = regval; + } + else + p = val; + + /* Write value in the stack's parameter save area. */ + write_memory (gparam, p, 8); + if (freg <= 13) { - gdb_byte regval[MAX_REGISTER_SIZE]; struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum); + convert_typed_floating (val, type, regval, regtype); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, regval); } if (greg <= 10) - { - /* The ABI states "Single precision floating - point values are mapped to the first word in - a single doubleword" and "... floating point - values mapped to the first eight doublewords - of the parameter save area are also passed in - general registers"). - - This code interprets that to mean: store it, - left aligned, in the general register. */ - gdb_byte regval[MAX_REGISTER_SIZE]; - memset (regval, 0, sizeof regval); - memcpy (regval, val, TYPE_LENGTH (type)); - regcache_cooked_write (regcache, - tdep->ppc_gp0_regnum + greg, - regval); - } - write_memory (gparam, val, TYPE_LENGTH (type)); + regcache_cooked_write (regcache, + tdep->ppc_gp0_regnum + greg, + regval); } - /* Always consume parameter stack space. */ + freg++; greg++; - gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); + /* Always consume parameter stack space. */ + gparam = align_up (gparam + 8, tdep->wordsize); } else if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 16 - && (gdbarch_long_double_format (current_gdbarch) + && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double)) { /* IBM long double stored in two doublewords of the @@ -911,6 +1079,63 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, greg += 2; gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); } + else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT + && TYPE_LENGTH (type) <= 8) + { + /* 32-bit and 64-bit decimal floats go in f1 .. f13. They can + end up in memory. */ + if (write_pass) + { + gdb_byte regval[MAX_REGISTER_SIZE]; + const gdb_byte *p; + + /* 32-bit decimal floats are right aligned in the + doubleword. */ + if (TYPE_LENGTH (type) == 4) + { + memcpy (regval + 4, val, 4); + p = regval; + } + else + p = val; + + /* Write value in the stack's parameter save area. */ + write_memory (gparam, p, 8); + + if (freg <= 13) + regcache_cooked_write (regcache, + tdep->ppc_fp0_regnum + freg, p); + } + + freg++; + greg++; + /* Always consume parameter stack space. */ + gparam = align_up (gparam + 8, tdep->wordsize); + } + else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && + TYPE_LENGTH (type) == 16) + { + /* 128-bit decimal floats go in f2 .. f12, always in even/odd + pairs. They can end up in memory, using two doublewords. */ + if (write_pass) + { + if (freg <= 12) + { + /* Make sure freg is even. */ + freg += freg & 1; + regcache_cooked_write (regcache, + tdep->ppc_fp0_regnum + freg, val); + regcache_cooked_write (regcache, + tdep->ppc_fp0_regnum + freg + 1, val + 8); + } + + write_memory (gparam, val, TYPE_LENGTH (type)); + } + + freg += 2; + greg += 2; + gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); + } else if (TYPE_LENGTH (type) == 16 && TYPE_VECTOR (type) && TYPE_CODE (type) == TYPE_CODE_ARRAY && tdep->ppc_vr0_regnum >= 0) @@ -936,7 +1161,10 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, } else if ((TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_ENUM - || TYPE_CODE (type) == TYPE_CODE_PTR) + || TYPE_CODE (type) == TYPE_CODE_BOOL + || TYPE_CODE (type) == TYPE_CODE_CHAR + || TYPE_CODE (type) == TYPE_CODE_PTR + || TYPE_CODE (type) == TYPE_CODE_REF) && TYPE_LENGTH (type) <= 8) { /* Scalars and Pointers get sign[un]extended and go in @@ -948,11 +1176,18 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Convert any function code addresses into descriptors. */ if (TYPE_CODE (type) == TYPE_CODE_PTR - && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC) + || TYPE_CODE (type) == TYPE_CODE_REF) { - CORE_ADDR desc = word; - convert_code_addr_to_desc_addr (word, &desc); - word = desc; + struct type *target_type; + target_type = check_typedef (TYPE_TARGET_TYPE (type)); + + if (TYPE_CODE (target_type) == TYPE_CODE_FUNC + || TYPE_CODE (target_type) == TYPE_CODE_METHOD) + { + CORE_ADDR desc = word; + convert_code_addr_to_desc_addr (word, &desc); + word = desc; + } } if (greg <= 10) regcache_cooked_write_unsigned (regcache, @@ -993,14 +1228,20 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, greg++; } if (write_pass) - /* WARNING: cagney/2003-09-21: Strictly speaking, this - isn't necessary, unfortunately, GCC appears to get - "struct convention" parameter passing wrong putting - odd sized structures in memory instead of in a - register. Work around this by always writing the - value to memory. Fortunately, doing this - simplifies the code. */ - write_memory (gparam, val, TYPE_LENGTH (type)); + { + /* WARNING: cagney/2003-09-21: Strictly speaking, this + isn't necessary, unfortunately, GCC appears to get + "struct convention" parameter passing wrong putting + odd sized structures in memory instead of in a + register. Work around this by always writing the + value to memory. Fortunately, doing this + simplifies the code. */ + int len = TYPE_LENGTH (type); + if (len < tdep->wordsize) + write_memory (gparam + tdep->wordsize - len, val, len); + else + write_memory (gparam, val, len); + } if (freg <= 13 && TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1 @@ -1033,7 +1274,7 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, freg++; } else if (TYPE_LENGTH (type) == 16 - && (gdbarch_long_double_format (current_gdbarch) + && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double)) { if (write_pass) @@ -1071,8 +1312,7 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, } /* Update %sp. */ - regcache_cooked_write_signed (regcache, - gdbarch_sp_regnum (current_gdbarch), sp); + regcache_cooked_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp); /* Write the backchain (it occupies WORDSIZED bytes). */ write_memory_signed_integer (sp, tdep->wordsize, back_chain); @@ -1111,9 +1351,9 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, location; when READBUF is non-NULL, fill the buffer from the corresponding register return-value location. */ enum return_value_convention -ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype, - struct regcache *regcache, gdb_byte *readbuf, - const gdb_byte *writebuf) +ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *func_type, + struct type *valtype, struct regcache *regcache, + gdb_byte *readbuf, const gdb_byte *writebuf) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); @@ -1139,9 +1379,14 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype, } return RETURN_VALUE_REGISTER_CONVENTION; } + if (TYPE_CODE (valtype) == TYPE_CODE_DECFLOAT) + return get_decimal_float_return_value (gdbarch, valtype, regcache, readbuf, + writebuf); /* Integers in r3. */ if ((TYPE_CODE (valtype) == TYPE_CODE_INT - || TYPE_CODE (valtype) == TYPE_CODE_ENUM) + || TYPE_CODE (valtype) == TYPE_CODE_ENUM + || TYPE_CODE (valtype) == TYPE_CODE_CHAR + || TYPE_CODE (valtype) == TYPE_CODE_BOOL) && TYPE_LENGTH (valtype) <= 8) { if (writebuf != NULL) @@ -1162,7 +1407,8 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype, return RETURN_VALUE_REGISTER_CONVENTION; } /* All pointers live in r3. */ - if (TYPE_CODE (valtype) == TYPE_CODE_PTR) + if (TYPE_CODE (valtype) == TYPE_CODE_PTR + || TYPE_CODE (valtype) == TYPE_CODE_REF) { /* All pointers live in r3. */ if (writebuf != NULL) @@ -1231,7 +1477,7 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype, { gdb_byte regval[MAX_REGISTER_SIZE]; struct type *regtype = - register_type (current_gdbarch, tdep->ppc_fp0_regnum); + register_type (gdbarch, tdep->ppc_fp0_regnum); if (writebuf != NULL) { convert_typed_floating ((const bfd_byte *) writebuf + @@ -1276,20 +1522,3 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype, return RETURN_VALUE_STRUCT_CONVENTION; } -CORE_ADDR -ppc64_sysv_abi_adjust_breakpoint_address (struct gdbarch *gdbarch, - CORE_ADDR bpaddr) -{ - /* PPC64 SYSV specifies that the minimal-symbol "FN" should point at - a function-descriptor while the corresponding minimal-symbol - ".FN" should point at the entry point. Consequently, a command - like "break FN" applied to an object file with only minimal - symbols, will insert the breakpoint into the descriptor at "FN" - and not the function at ".FN". Avoid this confusion by adjusting - any attempt to set a descriptor breakpoint into a corresponding - function breakpoint. Note that GDB warns the user when this - adjustment is applied - that's ok as otherwise the user will have - no way of knowing why their breakpoint at "FN" resulted in the - program stopping at ".FN". */ - return gdbarch_convert_from_func_ptr_addr (gdbarch, bpaddr, ¤t_target); -}