* i386-tdep.c: Add missing ')' in comment.
authorMark Kettenis <kettenis@gnu.org>
Thu, 21 Dec 2000 20:52:59 +0000 (20:52 +0000)
committerMark Kettenis <kettenis@gnu.org>
Thu, 21 Dec 2000 20:52:59 +0000 (20:52 +0000)
(i386_extract_return_value): Return directly after issuing the
warning and filling *VALBUF with zeroes if we cannot get at the
floating-point registers.
(i386_store_return_value): New function.
* config/i386/tm-i386.h (STORE_RETURN_VALUE): Simply call
i386_store_return_value.
Add prototype for i386_store_return_value.

gdb/ChangeLog
gdb/config/i386/tm-i386.h
gdb/i386-tdep.c

index a4ef68bed67bcafe4184e3fc8666f0022709dc37..99aeb486750818423e22846513373aa383dc8b28 100644 (file)
@@ -1,5 +1,14 @@
 2000-12-21  Mark Kettenis  <kettenis@gnu.org>
 
+       * i386-tdep.c: Add missing ')' in comment.
+       (i386_extract_return_value): Return directly after issuing the
+       warning and filling *VALBUF with zeroes if we cannot get at the
+       floating-point registers.
+       (i386_store_return_value): New function.
+       * config/i386/tm-i386.h (STORE_RETURN_VALUE): Simply call
+       i386_store_return_value.
+       Add prototype for i386_store_return_value.
+
        * i386-linux-nat.c (store_fpxregs): Add code to detect support for
        the PTRACE_GETFPXREGS request, and return zero if it's not.
 
index 2f18086418137198e53c0c7324ac98971f67719a..fc89c3acf5088861d2609433e6d85d285e7e3208 100644 (file)
@@ -296,17 +296,11 @@ extern void i387_float_info (void);
 extern void i386_extract_return_value (struct type *type, char *regbuf,
                                       char *valbuf);
 
-/* Write into appropriate registers a function return value of type TYPE, given
-   in virtual format.  */
-
-#define STORE_RETURN_VALUE(TYPE,VALBUF) \
-  {                                                                                 \
-    if (TYPE_CODE (TYPE) == TYPE_CODE_FLT)                                  \
-      write_register_bytes (REGISTER_BYTE (FP0_REGNUM), (VALBUF),           \
-                           TYPE_LENGTH (TYPE));                             \
-    else                                                                    \
-      write_register_bytes (0, (VALBUF), TYPE_LENGTH (TYPE));                       \
-  }
+/* Write into the appropriate registers a function return value stored
+   in VALBUF of type TYPE, given in virtual format.  */
+#define STORE_RETURN_VALUE(type, valbuf) \
+  i386_store_return_value ((type), (valbuf))
+extern void i386_store_return_value (struct type *type, char *valbuf);
 
 /* Extract from an array REGBUF containing the (raw) register state the address
    in which a function should return its structure value, as a CORE_ADDR (or an
index 8aaf651dba330ac336bbe20993fea24a404bb9c6..0750efc962ad475d0674ce09b7646736698f7a05 100644 (file)
@@ -713,7 +713,7 @@ get_longjmp_target (CORE_ADDR *pc)
 
 /* These registers are used for returning integers (and on some
    targets also for returning `struct' and `union' values when their
-   size and alignment match an integer type.  */
+   size and alignment match an integer type).  */
 #define LOW_RETURN_REGNUM 0    /* %eax */
 #define HIGH_RETURN_REGNUM 2   /* %edx */
 
@@ -732,6 +732,7 @@ i386_extract_return_value (struct type *type, char *regbuf, char *valbuf)
        {
          warning ("Cannot find floating-point return value.");
          memset (valbuf, 0, len);
+         return;
        }
 
       /* Floating-point return values can be found in %st(0).  */
@@ -774,6 +775,64 @@ i386_extract_return_value (struct type *type, char *regbuf, char *valbuf)
     }
 }
 
+/* Write into the appropriate registers a function return value stored
+   in VALBUF of type TYPE, given in virtual format.  */
+
+void
+i386_store_return_value (struct type *type, char *valbuf)
+{
+  int len = TYPE_LENGTH (type);
+
+  if (TYPE_CODE_FLT == TYPE_CODE (type))
+    {
+      if (NUM_FREGS == 0)
+       {
+         warning ("Cannot set floating-point return value.");
+         return;
+       }
+
+      /* Floating-point return values can be found in %st(0).  */
+      if (len == TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT
+         && TARGET_LONG_DOUBLE_FORMAT == &floatformat_i387_ext)
+       {
+         /* Copy straight over.  */
+         write_register_bytes (REGISTER_BYTE (FP0_REGNUM), valbuf,
+                               FPU_REG_RAW_SIZE);
+       }
+      else
+       {
+         char buf[FPU_REG_RAW_SIZE];
+         DOUBLEST val;
+
+         /* Convert the value found in VALBUF to the extended
+             floating point format used by the FPU.  This is probably
+             not exactly how it would happen on the target itself, but
+             it is the best we can do.  */
+         val = extract_floating (valbuf, TYPE_LENGTH (type));
+         floatformat_from_doublest (&floatformat_i387_ext, &val, buf);
+         write_register_bytes (REGISTER_BYTE (FP0_REGNUM), buf,
+                               FPU_REG_RAW_SIZE);
+       }
+    }
+  else
+    {
+      int low_size = REGISTER_RAW_SIZE (LOW_RETURN_REGNUM);
+      int high_size = REGISTER_RAW_SIZE (HIGH_RETURN_REGNUM);
+
+      if (len <= low_size)
+       write_register_bytes (REGISTER_BYTE (LOW_RETURN_REGNUM), valbuf, len);
+      else if (len <= (low_size + high_size))
+       {
+         write_register_bytes (REGISTER_BYTE (LOW_RETURN_REGNUM),
+                               valbuf, low_size);
+         write_register_bytes (REGISTER_BYTE (HIGH_RETURN_REGNUM),
+                               valbuf + low_size, len - low_size);
+       }
+      else
+       internal_error ("Cannot store return value of %d bytes long.", len);
+    }
+}
+
 /* Convert data from raw format for register REGNUM in buffer FROM to
    virtual format with type TYPE in buffer TO.  In principle both
    formats are identical except that the virtual format has two extra