|
|
7ab123 |
commit d81e75c0756f21d2c3d45ce86d8b45c65f01ef67
|
|
|
7ab123 |
Author: Tiago Daitx <tdaitx@sourceware.org>
|
|
|
7ab123 |
Date: Mon Apr 1 04:05:35 2013 +0000
|
|
|
7ab123 |
|
|
|
7ab123 |
gdb/ChangeLog
|
|
|
7ab123 |
2013-03-01 Tiago Stürmer Daitx <tdaitx@linux.vnet.ibm.com>
|
|
|
7ab123 |
|
|
|
7ab123 |
* ppc-sysv-tdep.c (ppc64_sysv_abi_push_float): New function.
|
|
|
7ab123 |
(ppc64_sysv_abi_push_dummy_call): Handle complex arguments.
|
|
|
7ab123 |
|
|
|
7ab123 |
Index: gdb-7.6.1/gdb/ppc-sysv-tdep.c
|
|
|
7ab123 |
===================================================================
|
|
|
7ab123 |
--- gdb-7.6.1.orig/gdb/ppc-sysv-tdep.c
|
|
|
7ab123 |
+++ gdb-7.6.1/gdb/ppc-sysv-tdep.c
|
|
|
7ab123 |
@@ -1101,6 +1101,83 @@ convert_code_addr_to_desc_addr (CORE_ADD
|
|
|
7ab123 |
return 1;
|
|
|
7ab123 |
}
|
|
|
7ab123 |
|
|
|
7ab123 |
+/* Push a float in either registers, or in the stack. Using the ppc 64 bit
|
|
|
7ab123 |
+ SysV ABI.
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ This implements a dumbed down version of the ABI. It always writes
|
|
|
7ab123 |
+ values to memory, GPR and FPR, even when not necessary. Doing this
|
|
|
7ab123 |
+ greatly simplifies the logic. */
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+static void
|
|
|
7ab123 |
+ppc64_sysv_abi_push_float (struct gdbarch *gdbarch, struct regcache *regcache,
|
|
|
7ab123 |
+ struct gdbarch_tdep *tdep, struct type *type,
|
|
|
7ab123 |
+ const bfd_byte *val, int freg, int greg,
|
|
|
7ab123 |
+ CORE_ADDR gparam)
|
|
|
7ab123 |
+{
|
|
|
7ab123 |
+ gdb_byte regval[MAX_REGISTER_SIZE];
|
|
|
7ab123 |
+ const gdb_byte *p;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ if (TYPE_LENGTH (type) <= 8)
|
|
|
7ab123 |
+ {
|
|
|
7ab123 |
+ /* Version 1.7 of the 64-bit PowerPC ELF ABI says:
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ "Single precision floating point values are mapped to
|
|
|
7ab123 |
+ the first word in a single doubleword."
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ And version 1.9 says:
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ "Single precision floating point values are mapped to
|
|
|
7ab123 |
+ the second word in a single doubleword."
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ GDB then writes single precision floating point values
|
|
|
7ab123 |
+ at both words in a doubleword, to support both ABIs. */
|
|
|
7ab123 |
+ if (TYPE_LENGTH (type) == 4)
|
|
|
7ab123 |
+ {
|
|
|
7ab123 |
+ memcpy (regval, val, 4);
|
|
|
7ab123 |
+ memcpy (regval + 4, val, 4);
|
|
|
7ab123 |
+ p = regval;
|
|
|
7ab123 |
+ }
|
|
|
7ab123 |
+ else
|
|
|
7ab123 |
+ p = val;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ /* Write value in the stack's parameter save area. */
|
|
|
7ab123 |
+ write_memory (gparam, p, 8);
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ /* Floats and Doubles go in f1 .. f13. They also consume a left aligned
|
|
|
7ab123 |
+ GREG, and can end up in memory. */
|
|
|
7ab123 |
+ if (freg <= 13)
|
|
|
7ab123 |
+ {
|
|
|
7ab123 |
+ struct type *regtype;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ regtype = register_type (gdbarch, tdep->ppc_fp0_regnum + freg);
|
|
|
7ab123 |
+ convert_typed_floating (val, type, regval, regtype);
|
|
|
7ab123 |
+ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, regval);
|
|
|
7ab123 |
+ }
|
|
|
7ab123 |
+ if (greg <= 10)
|
|
|
7ab123 |
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, regval);
|
|
|
7ab123 |
+ }
|
|
|
7ab123 |
+ else
|
|
|
7ab123 |
+ {
|
|
|
7ab123 |
+ /* IBM long double stored in two doublewords of the
|
|
|
7ab123 |
+ parameter save area and corresponding registers. */
|
|
|
7ab123 |
+ if (!tdep->soft_float && freg <= 13)
|
|
|
7ab123 |
+ {
|
|
|
7ab123 |
+ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, val);
|
|
|
7ab123 |
+ if (freg <= 12)
|
|
|
7ab123 |
+ regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg + 1,
|
|
|
7ab123 |
+ val + 8);
|
|
|
7ab123 |
+ }
|
|
|
7ab123 |
+ if (greg <= 10)
|
|
|
7ab123 |
+ {
|
|
|
7ab123 |
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, val);
|
|
|
7ab123 |
+ if (greg <= 9)
|
|
|
7ab123 |
+ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg + 1,
|
|
|
7ab123 |
+ val + 8);
|
|
|
7ab123 |
+ }
|
|
|
7ab123 |
+ write_memory (gparam, val, TYPE_LENGTH (type));
|
|
|
7ab123 |
+ }
|
|
|
7ab123 |
+}
|
|
|
7ab123 |
+
|
|
|
7ab123 |
/* Pass the arguments in either registers, or in the stack. Using the
|
|
|
7ab123 |
ppc 64 bit SysV ABI.
|
|
|
7ab123 |
|
|
|
7ab123 |
@@ -1218,53 +1295,9 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
|
|
7ab123 |
|
|
|
7ab123 |
if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8)
|
|
|
7ab123 |
{
|
|
|
7ab123 |
- /* Floats and Doubles go in f1 .. f13. They also
|
|
|
7ab123 |
- consume a left aligned GREG,, and can end up in
|
|
|
7ab123 |
- memory. */
|
|
|
7ab123 |
if (write_pass)
|
|
|
7ab123 |
- {
|
|
|
7ab123 |
- gdb_byte regval[MAX_REGISTER_SIZE];
|
|
|
7ab123 |
- const gdb_byte *p;
|
|
|
7ab123 |
-
|
|
|
7ab123 |
- /* Version 1.7 of the 64-bit PowerPC ELF ABI says:
|
|
|
7ab123 |
-
|
|
|
7ab123 |
- "Single precision floating point values are mapped to
|
|
|
7ab123 |
- the first word in a single doubleword."
|
|
|
7ab123 |
-
|
|
|
7ab123 |
- And version 1.9 says:
|
|
|
7ab123 |
-
|
|
|
7ab123 |
- "Single precision floating point values are mapped to
|
|
|
7ab123 |
- the second word in a single doubleword."
|
|
|
7ab123 |
-
|
|
|
7ab123 |
- GDB then writes single precision floating point values
|
|
|
7ab123 |
- at both words in a doubleword, to support both ABIs. */
|
|
|
7ab123 |
- if (TYPE_LENGTH (type) == 4)
|
|
|
7ab123 |
- {
|
|
|
7ab123 |
- memcpy (regval, val, 4);
|
|
|
7ab123 |
- memcpy (regval + 4, val, 4);
|
|
|
7ab123 |
- p = regval;
|
|
|
7ab123 |
- }
|
|
|
7ab123 |
- else
|
|
|
7ab123 |
- p = val;
|
|
|
7ab123 |
-
|
|
|
7ab123 |
- /* Write value in the stack's parameter save area. */
|
|
|
7ab123 |
- write_memory (gparam, p, 8);
|
|
|
7ab123 |
-
|
|
|
7ab123 |
- if (freg <= 13)
|
|
|
7ab123 |
- {
|
|
|
7ab123 |
- struct type *regtype
|
|
|
7ab123 |
- = register_type (gdbarch, tdep->ppc_fp0_regnum);
|
|
|
7ab123 |
-
|
|
|
7ab123 |
- convert_typed_floating (val, type, regval, regtype);
|
|
|
7ab123 |
- regcache_cooked_write (regcache,
|
|
|
7ab123 |
- tdep->ppc_fp0_regnum + freg,
|
|
|
7ab123 |
- regval);
|
|
|
7ab123 |
- }
|
|
|
7ab123 |
- if (greg <= 10)
|
|
|
7ab123 |
- regcache_cooked_write (regcache,
|
|
|
7ab123 |
- tdep->ppc_gp0_regnum + greg,
|
|
|
7ab123 |
- regval);
|
|
|
7ab123 |
- }
|
|
|
7ab123 |
+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type,
|
|
|
7ab123 |
+ val, freg, greg, gparam);
|
|
|
7ab123 |
|
|
|
7ab123 |
freg++;
|
|
|
7ab123 |
greg++;
|
|
|
7ab123 |
@@ -1276,35 +1309,58 @@ ppc64_sysv_abi_push_dummy_call (struct g
|
|
|
7ab123 |
&& (gdbarch_long_double_format (gdbarch)
|
|
|
7ab123 |
== floatformats_ibm_long_double))
|
|
|
7ab123 |
{
|
|
|
7ab123 |
- /* IBM long double stored in two doublewords of the
|
|
|
7ab123 |
- parameter save area and corresponding registers. */
|
|
|
7ab123 |
if (write_pass)
|
|
|
7ab123 |
+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep, type,
|
|
|
7ab123 |
+ val, freg, greg, gparam);
|
|
|
7ab123 |
+ freg += 2;
|
|
|
7ab123 |
+ greg += 2;
|
|
|
7ab123 |
+ gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
|
|
|
7ab123 |
+ }
|
|
|
7ab123 |
+ else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX
|
|
|
7ab123 |
+ && (TYPE_LENGTH (type) == 8 || TYPE_LENGTH (type) == 16))
|
|
|
7ab123 |
+ {
|
|
|
7ab123 |
+ int i;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ for (i = 0; i < 2; i++)
|
|
|
7ab123 |
{
|
|
|
7ab123 |
- if (!tdep->soft_float && freg <= 13)
|
|
|
7ab123 |
- {
|
|
|
7ab123 |
- regcache_cooked_write (regcache,
|
|
|
7ab123 |
- tdep->ppc_fp0_regnum + freg,
|
|
|
7ab123 |
- val);
|
|
|
7ab123 |
- if (freg <= 12)
|
|
|
7ab123 |
- regcache_cooked_write (regcache,
|
|
|
7ab123 |
- tdep->ppc_fp0_regnum + freg + 1,
|
|
|
7ab123 |
- val + 8);
|
|
|
7ab123 |
- }
|
|
|
7ab123 |
- if (greg <= 10)
|
|
|
7ab123 |
+ if (write_pass)
|
|
|
7ab123 |
{
|
|
|
7ab123 |
- regcache_cooked_write (regcache,
|
|
|
7ab123 |
- tdep->ppc_gp0_regnum + greg,
|
|
|
7ab123 |
- val);
|
|
|
7ab123 |
- if (greg <= 9)
|
|
|
7ab123 |
- regcache_cooked_write (regcache,
|
|
|
7ab123 |
- tdep->ppc_gp0_regnum + greg + 1,
|
|
|
7ab123 |
- val + 8);
|
|
|
7ab123 |
+ struct type *target_type;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ target_type = check_typedef (TYPE_TARGET_TYPE (type));
|
|
|
7ab123 |
+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep,
|
|
|
7ab123 |
+ target_type, val + i *
|
|
|
7ab123 |
+ TYPE_LENGTH (target_type),
|
|
|
7ab123 |
+ freg, greg, gparam);
|
|
|
7ab123 |
}
|
|
|
7ab123 |
- write_memory (gparam, val, TYPE_LENGTH (type));
|
|
|
7ab123 |
+ freg++;
|
|
|
7ab123 |
+ greg++;
|
|
|
7ab123 |
+ /* Always consume parameter stack space. */
|
|
|
7ab123 |
+ gparam = align_up (gparam + 8, tdep->wordsize);
|
|
|
7ab123 |
+ }
|
|
|
7ab123 |
+ }
|
|
|
7ab123 |
+ else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX
|
|
|
7ab123 |
+ && TYPE_LENGTH (type) == 32
|
|
|
7ab123 |
+ && (gdbarch_long_double_format (gdbarch)
|
|
|
7ab123 |
+ == floatformats_ibm_long_double))
|
|
|
7ab123 |
+ {
|
|
|
7ab123 |
+ int i;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ for (i = 0; i < 2; i++)
|
|
|
7ab123 |
+ {
|
|
|
7ab123 |
+ struct type *target_type;
|
|
|
7ab123 |
+
|
|
|
7ab123 |
+ target_type = check_typedef (TYPE_TARGET_TYPE (type));
|
|
|
7ab123 |
+ if (write_pass)
|
|
|
7ab123 |
+ ppc64_sysv_abi_push_float (gdbarch, regcache, tdep,
|
|
|
7ab123 |
+ target_type, val + i *
|
|
|
7ab123 |
+ TYPE_LENGTH (target_type),
|
|
|
7ab123 |
+ freg, greg, gparam);
|
|
|
7ab123 |
+ freg += 2;
|
|
|
7ab123 |
+ greg += 2;
|
|
|
7ab123 |
+ gparam = align_up (gparam + TYPE_LENGTH (target_type),
|
|
|
7ab123 |
+ tdep->wordsize);
|
|
|
7ab123 |
}
|
|
|
7ab123 |
- freg += 2;
|
|
|
7ab123 |
- greg += 2;
|
|
|
7ab123 |
- gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
|
|
|
7ab123 |
}
|
|
|
7ab123 |
else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT
|
|
|
7ab123 |
&& TYPE_LENGTH (type) <= 8)
|