* ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call): Write 32-bit
authorThiago Jung Bauermann <bauerman@br.ibm.com>
Fri, 1 Feb 2008 15:04:18 +0000 (15:04 +0000)
committerThiago Jung Bauermann <bauerman@br.ibm.com>
Fri, 1 Feb 2008 15:04:18 +0000 (15:04 +0000)
float in both first and second word in the doubleword, to support
old and new ABIs.

gdb/ChangeLog
gdb/ppc-sysv-tdep.c

index 7ddc112caf2ba1a9935ba64a7cb1688001857106..ad3a59f054b2541aa6eee496a62dc609b29e307c 100644 (file)
@@ -1,3 +1,9 @@
+2008-02-01  Thiago Jung Bauermann  <bauerman@br.ibm.com>
+
+       * ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call): Write 32-bit
+       float in both first and second word in the doubleword, to support
+       old and new ABIs.
+
 2008-02-01  Vladimir Prus  <vladimir@codesourcery.com>
 
        Properly rethrow exception.  This fixes errors
index c9646ebbbc262abd40b027dabd34336e77f096be..7a87743416523ff4cc0e2c06ff6cdf27ef6bfe1b 100644 (file)
@@ -971,6 +971,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
@@ -978,40 +979,53 @@ 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