aboutsummaryrefslogtreecommitdiff
path: root/gdb/ppc-sysv-tdep.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2007-11-08 00:08:48 +0000
committerJoseph Myers <joseph@codesourcery.com>2007-11-08 00:08:48 +0000
commitb14d30e141e438bf7caebb1925569510eae049d7 (patch)
tree61e4f7993a702a3ec527bda64b5ccda54ca8ee7f /gdb/ppc-sysv-tdep.c
parent5d324c3ec4090c667b24441e3a5653f1dfd8e261 (diff)
downloadgdb-b14d30e141e438bf7caebb1925569510eae049d7.zip
gdb-b14d30e141e438bf7caebb1925569510eae049d7.tar.gz
gdb-b14d30e141e438bf7caebb1925569510eae049d7.tar.bz2
include:
2007-11-07 Joseph Myers <joseph@codesourcery.com> Daniel Jacobowitz <dan@codesourcery.com> * floatformat.h (struct floatformat): Add split_half field. (floatformat_ibm_long_double): New. libiberty: 2007-11-07 Joseph Myers <joseph@codesourcery.com> Daniel Jacobowitz <dan@codesourcery.com> * floatformat.c (mant_bits_set): New. (floatformat_to_double): Use it. Note no special handling of split formats. (floatformat_from_double): Note no special handing of split formats. (floatformat_ibm_long_double_is_valid, floatformat_ibm_long_double): New. (floatformat_ieee_single_big, floatformat_ieee_single_little, floatformat_ieee_double_big, floatformat_ieee_double_little, floatformat_ieee_double_littlebyte_bigword, floatformat_vax_f, floatformat_vax_d, floatformat_vax_g, floatformat_i387_ext, floatformat_m68881_ext, floatformat_i960_ext, floatformat_m88110_ext, floatformat_m88110_harris_ext, floatformat_arm_ext_big, floatformat_arm_ext_littlebyte_bigword, floatformat_ia64_spill_big, floatformat_ia64_spill_little, floatformat_ia64_quad_big, floatformat_ia64_quad_little): Update for addition of split_half field. gdb: 2007-11-07 Joseph Myers <joseph@codesourcery.com> Daniel Jacobowitz <dan@codesourcery.com> * gdbtypes.c (floatformats_ibm_long_double): New. * gdbtypes.h (floatformats_ibm_long_double): Declare. * ia64-tdep.c (floatformat_ia64_ext): Update for addition of split_half field. * mips-tdep.c (n32n64_floatformat_always_valid, floatformat_n32n64_long_double_big, floatformats_n32n64_long): Remove. (mips_gdbarch_init): Use floatformats_ibm_long_double instead of floatformats_n32n64_long. * ppc-linux-tdep.c (ppc_linux_init_abi): Use 128-bit IBM long double. * doublest.c (convert_floatformat_to_doublest, convert_doublest_to_floatformat): Handle split floating-point formats. * ppc-sysv-tdep.c (ppc_sysv_abi_push_dummy_call): Handle IBM long double arguments. (ppc64_sysv_abi_push_dummy_call): Likewise. (do_ppc_sysv_return_value): Handle IBM long double return.
Diffstat (limited to 'gdb/ppc-sysv-tdep.c')
-rw-r--r--gdb/ppc-sysv-tdep.c157
1 files changed, 150 insertions, 7 deletions
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index 5dc90f1..21947aa 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -53,6 +53,8 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
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),
&saved_sp);
@@ -141,6 +143,35 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
argoffset += 8;
}
}
+ else if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && len == 16
+ && !tdep->soft_float
+ && (gdbarch_long_double_format (current_gdbarch)
+ == floatformats_ibm_long_double))
+ {
+ /* IBM long double passed in two FP registers if
+ available, otherwise 8-byte aligned stack. */
+ if (freg <= 7)
+ {
+ 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);
+ }
+ freg += 2;
+ }
+ else
+ {
+ argoffset = align_up (argoffset, 8);
+ if (write_pass)
+ write_memory (sp + argoffset, val, len);
+ argoffset += 16;
+ }
+ }
else if (len == 8
&& (TYPE_CODE (type) == TYPE_CODE_INT /* long long */
|| TYPE_CODE (type) == TYPE_CODE_FLT)) /* double */
@@ -159,13 +190,6 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
write_memory (sp + argoffset, val, len);
argoffset += 8;
}
- else if (tdep->wordsize == 8)
- {
- if (write_pass)
- regcache_cooked_write (regcache,
- tdep->ppc_gp0_regnum + greg, val);
- greg += 1;
- }
else
{
/* Must start on an odd register - r3/r4 etc. */
@@ -183,6 +207,41 @@ 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))
+ {
+ /* Soft-float IBM long double passed in four consecutive
+ registers, or on the stack. The registers are not
+ necessarily odd/even pairs. */
+ if (greg > 7)
+ {
+ greg = 11;
+ argoffset = align_up (argoffset, 8);
+ if (write_pass)
+ write_memory (sp + argoffset, val, len);
+ argoffset += 16;
+ }
+ else
+ {
+ if (write_pass)
+ {
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg + 0,
+ val + 0);
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg + 1,
+ val + 4);
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg + 2,
+ val + 8);
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg + 3,
+ val + 12);
+ }
+ greg += 4;
+ }
+ }
else if (len == 16
&& TYPE_CODE (type) == TYPE_CODE_ARRAY
&& TYPE_VECTOR (type)
@@ -376,6 +435,55 @@ 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
+ && !tdep->soft_float
+ && (gdbarch_long_double_format (current_gdbarch)
+ == floatformats_ibm_long_double))
+ {
+ /* IBM long double stored in f1 and f2. */
+ if (readbuf)
+ {
+ regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, readbuf);
+ regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 2,
+ readbuf + 8);
+ }
+ if (writebuf)
+ {
+ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, writebuf);
+ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 2,
+ writebuf + 8);
+ }
+ 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))
+ {
+ /* Soft-float IBM long double stored in r3, r4, r5, r6. */
+ if (readbuf)
+ {
+ regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, readbuf);
+ regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4,
+ readbuf + 4);
+ regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 5,
+ readbuf + 8);
+ regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 6,
+ readbuf + 12);
+ }
+ if (writebuf)
+ {
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, writebuf);
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4,
+ writebuf + 4);
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 5,
+ writebuf + 8);
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 6,
+ writebuf + 12);
+ }
+ 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))
{
@@ -768,6 +876,41 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
greg++;
gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
}
+ else if (TYPE_CODE (type) == TYPE_CODE_FLT
+ && TYPE_LENGTH (type) == 16
+ && (gdbarch_long_double_format (current_gdbarch)
+ == floatformats_ibm_long_double))
+ {
+ /* IBM long double stored in two doublewords of the
+ parameter save area and corresponding registers. */
+ if (write_pass)
+ {
+ if (!tdep->soft_float && freg <= 13)
+ {
+ regcache_cooked_write (regcache,
+ tdep->ppc_fp0_regnum + freg,
+ val);
+ if (freg <= 12)
+ regcache_cooked_write (regcache,
+ tdep->ppc_fp0_regnum + freg + 1,
+ val + 8);
+ }
+ if (greg <= 10)
+ {
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg,
+ val);
+ if (greg <= 9)
+ regcache_cooked_write (regcache,
+ tdep->ppc_gp0_regnum + greg + 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)