* Add native support for long double data type.
authorStu Grossman <grossman@cygnus>
Sat, 17 Feb 1996 00:07:35 +0000 (00:07 +0000)
committerStu Grossman <grossman@cygnus>
Sat, 17 Feb 1996 00:07:35 +0000 (00:07 +0000)
* c-exp.y (%union):  Change dval to typed_val_float.  Use DOUBLEST
to store actual data.  Change types of INT and FLOAT tokens to
typed_val_int and typed_val_float respectively.  Create new token
DOUBLE_KEYWORD to specify the string `double'.  Make production
for FLOAT use type determined by parse_number.  Add production for
"long double" data type.
* (parse_number):  Use sscanf to parse numbers as float, double or
long double depending upon the type of typed_val_float.dval.  Also
allow user to specify `f' or `l' suffix to explicitly specify
float or long double constants.  Change typed_val to
typed_val_int.
* (yylex):  Change typed_val to typed_val_int.  Also, scan for
"double" keyword.
* coffread.c (decode_base_type):  Add support for T_LNGDBL basic
type.
* configure, configure.in:  Add check for long double support in
the host compiler.
* defs.h:  Define DOUBLEST appropriatly depending on whether
HAVE_LONG_DOUBLE (from autoconf) is defined.  Also, fix prototypes
for functions that handle this type.
* expression.h (union exp_element):  doubleconst is now type
DOUBLEST.
* m2-exp.y f-exp.y (%union):  dval becomes type DOUBLEST.
* findvar.c (extract_floating):  Make return value be DOUBLEST.
Also, add support for numbers with size of long double.
* (store_floating):  Arg `val' is now type DOUBLEST.  Handle all
floating types.
* parser-defs.h parse.c (write_exp_elt_dblcst):  Arg expelt is now
DOUBLEST.
* valarith.c (value_binop):  Change temp variables v1, v2 and v to
type DOUBLEST.  Coerce type of result to long double if either op
was of that type.
* valops.c (value_arg_coerce):  If argument type is bigger than
double, coerce to long double.
* (call_function_by_hand):  If REG_STRUCT_HAS_ADDR is defined, and
arg type is float and > 8 bytes, then use pointer-to-object
calling conventions.
* valprint.c (print_floating):  Arg doub is now type DOUBLEST.
Use appropriate format and precision to print out floating point
values.
* value.h:  Fixup prototypes for value_as_double,
value_from_double, and unpack_double to use DOUBLEST.
* values.c (record_latest_value):  Remove check for invalid
floats.  Allow history to store them so that people may examine
them in hex if they want.
* (value_as_double unpack_double):  Change return value to DOUBLEST.
* (value_from_double):  Arg `num' is now DOUBLEST.
* (using_struct_return):  Use RETURN_VALUE_ON_STACK macro (target
specific) to expect certain types to always be returned on the stack.

gdb/ChangeLog
gdb/c-exp.y
gdb/configure
gdb/configure.in
gdb/f-exp.y
gdb/findvar.c
gdb/m2-exp.y
gdb/parse.c
gdb/parser-defs.h
gdb/valops.c
gdb/values.c

index 13107954699af94cb99d10d6f456e86c07433386..8114a0a9f3e471ca79b9ea105a875c00cc1b90fa 100644 (file)
@@ -1,3 +1,56 @@
+Thu Feb 16 16:02:03 1996  Stu Grossman  (grossman@cygnus.com)
+
+       * Add native support for long double data type.
+       * c-exp.y (%union):  Change dval to typed_val_float.  Use DOUBLEST
+       to store actual data.  Change types of INT and FLOAT tokens to
+       typed_val_int and typed_val_float respectively.  Create new token
+       DOUBLE_KEYWORD to specify the string `double'.  Make production
+       for FLOAT use type determined by parse_number.  Add production for
+       "long double" data type.
+       * (parse_number):  Use sscanf to parse numbers as float, double or
+       long double depending upon the type of typed_val_float.dval.  Also
+       allow user to specify `f' or `l' suffix to explicitly specify
+       float or long double constants.  Change typed_val to
+       typed_val_int.
+       * (yylex):  Change typed_val to typed_val_int.  Also, scan for
+       "double" keyword.
+       * coffread.c (decode_base_type):  Add support for T_LNGDBL basic
+       type.
+       * configure, configure.in:  Add check for long double support in
+       the host compiler.
+       * defs.h:  Define DOUBLEST appropriatly depending on whether
+       HAVE_LONG_DOUBLE (from autoconf) is defined.  Also, fix prototypes
+       for functions that handle this type.
+       * expression.h (union exp_element):  doubleconst is now type
+       DOUBLEST.
+       * m2-exp.y f-exp.y (%union):  dval becomes type DOUBLEST.
+       * findvar.c (extract_floating):  Make return value be DOUBLEST.
+       Also, add support for numbers with size of long double.
+       * (store_floating):  Arg `val' is now type DOUBLEST.  Handle all
+       floating types.
+       * parser-defs.h parse.c (write_exp_elt_dblcst):  Arg expelt is now
+       DOUBLEST.
+       * valarith.c (value_binop):  Change temp variables v1, v2 and v to
+       type DOUBLEST.  Coerce type of result to long double if either op
+       was of that type.
+       * valops.c (value_arg_coerce):  If argument type is bigger than
+       double, coerce to long double.
+       * (call_function_by_hand):  If REG_STRUCT_HAS_ADDR is defined, and
+       arg type is float and > 8 bytes, then use pointer-to-object
+       calling conventions.
+       * valprint.c (print_floating):  Arg doub is now type DOUBLEST.
+       Use appropriate format and precision to print out floating point
+       values.
+       * value.h:  Fixup prototypes for value_as_double,
+       value_from_double, and unpack_double to use DOUBLEST.
+       * values.c (record_latest_value):  Remove check for invalid
+       floats.  Allow history to store them so that people may examine
+       them in hex if they want.
+       * (value_as_double unpack_double):  Change return value to DOUBLEST.
+       * (value_from_double):  Arg `num' is now DOUBLEST.
+       * (using_struct_return):  Use RETURN_VALUE_ON_STACK macro (target
+       specific) to expect certain types to always be returned on the stack.
+
 Fri Feb 16 14:00:54 1996  Fred Fish  <fnf@cygnus.com>
 
        * bcache.c, bcache.h: New files to implement a byte cache.
index f6bd88fe530ca5a4f80a9d9f1439152e45243af1..9070a0581685ae91deacf2f9c641043e54888543 100644 (file)
@@ -119,8 +119,11 @@ yyerror PARAMS ((char *));
     struct {
       LONGEST val;
       struct type *type;
-    } typed_val;
-    double dval;
+    } typed_val_int;
+    struct {
+      DOUBLEST dval;
+      struct type *type;
+    } typed_val_float;
     struct symbol *sym;
     struct type *tval;
     struct stoken sval;
@@ -152,8 +155,8 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
 %type <tval> ptype
 %type <lval> array_mod
 
-%token <typed_val> INT
-%token <dval> FLOAT
+%token <typed_val_int> INT
+%token <typed_val_float> FLOAT
 
 /* Both NAME and TYPENAME tokens represent symbols in the input,
    and both convey their data as strings.
@@ -183,7 +186,7 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
 
 /* Special type cases, put in to allow the parser to distinguish different
    legal basetypes.  */
-%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD
+%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD
 
 %token <voidval> VARIABLE
 
@@ -473,8 +476,8 @@ exp :       NAME_OR_INT
                        { YYSTYPE val;
                          parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
                          write_exp_elt_opcode (OP_LONG);
-                         write_exp_elt_type (val.typed_val.type);
-                         write_exp_elt_longcst ((LONGEST)val.typed_val.val);
+                         write_exp_elt_type (val.typed_val_int.type);
+                         write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
                          write_exp_elt_opcode (OP_LONG);
                        }
        ;
@@ -482,8 +485,8 @@ exp :       NAME_OR_INT
 
 exp    :       FLOAT
                        { write_exp_elt_opcode (OP_DOUBLE);
-                         write_exp_elt_type (builtin_type_double);
-                         write_exp_elt_dblcst ($1);
+                         write_exp_elt_type ($1.type);
+                         write_exp_elt_dblcst ($1.dval);
                          write_exp_elt_opcode (OP_DOUBLE); }
        ;
 
@@ -806,6 +809,10 @@ typebase  /* Implements (approximately): (type-qualifier)* type-specifier */
                        { $$ = builtin_type_short; }
        |       UNSIGNED SHORT INT_KEYWORD
                        { $$ = builtin_type_unsigned_short; }
+       |       DOUBLE_KEYWORD
+                       { $$ = builtin_type_double; }
+       |       LONG DOUBLE_KEYWORD
+                       { $$ = builtin_type_long_double; }
        |       STRUCT name
                        { $$ = lookup_struct (copy_name ($2),
                                              expression_context_block); }
@@ -926,8 +933,30 @@ parse_number (p, len, parsed_float, putithere)
 
   if (parsed_float)
     {
+      char c;
+
       /* It's a float since it contains a point or an exponent.  */
-      putithere->dval = atof (p);
+
+      if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
+       sscanf (p, "%g", &putithere->typed_val_float.dval);
+      else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
+       sscanf (p, "%lg", &putithere->typed_val_float.dval);
+      else
+       sscanf (p, "%Lg", &putithere->typed_val_float.dval);
+
+      /* See if it has `f' or `l' suffix (float or long double).  */
+
+      c = tolower (p[len - 1]);
+
+      if (c == 'f')
+       putithere->typed_val_float.type = builtin_type_float;
+      else if (c == 'l')
+       putithere->typed_val_float.type = builtin_type_long_double;
+      else if (isdigit (c) || c == '.')
+       putithere->typed_val_float.type = builtin_type_double;
+      else
+       return ERROR;
+
       return FLOAT;
     }
 
@@ -1064,18 +1093,18 @@ parse_number (p, len, parsed_float, putithere)
       signed_type = builtin_type_long_long;
     }
 
-   putithere->typed_val.val = n;
+   putithere->typed_val_int.val = n;
 
    /* If the high bit of the worked out type is set then this number
       has to be unsigned. */
 
    if (unsigned_p || (n & high_bit)) 
      {
-       putithere->typed_val.type = unsigned_type;
+       putithere->typed_val_int.type = unsigned_type;
      }
    else 
      {
-       putithere->typed_val.type = signed_type;
+       putithere->typed_val_int.type = signed_type;
      }
 
    return INT;
@@ -1175,8 +1204,8 @@ yylex ()
       else if (c == '\'')
        error ("Empty character constant.");
 
-      yylval.typed_val.val = c;
-      yylval.typed_val.type = builtin_type_char;
+      yylval.typed_val_int.val = c;
+      yylval.typed_val_int.type = builtin_type_char;
 
       c = *lexptr++;
       if (c != '\'')
@@ -1409,6 +1438,8 @@ yylex ()
        return SIGNED_KEYWORD;
       if (STREQN (tokstart, "sizeof", 6))      
        return SIZEOF;
+      if (STREQN (tokstart, "double", 6))      
+       return DOUBLE_KEYWORD;
       break;
     case 5:
       if (current_language->la_language == language_cplus
index 826bea72e7b15a5b0d49423b9ee2b7f715986d18..7d074cc2bbb3124439290f0804a822713f72f20d 100755 (executable)
@@ -1295,6 +1295,39 @@ EOF
 
 fi
 
+
+echo $ac_n "checking for long double""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_c_long_double'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1305 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+long double foo;
+; return 0; }
+EOF
+if eval $ac_compile; then
+  rm -rf conftest*
+  ac_cv_c_long_double=yes
+else
+  rm -rf conftest*
+  ac_cv_c_long_double=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_c_long_double" 1>&6
+if test $ac_cv_c_long_double = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_LONG_DOUBLE 1
+EOF
+
+fi
+
 for ac_func in valloc getpagesize
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
@@ -1302,7 +1335,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1306 "configure"
+#line 1339 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1354,7 +1387,7 @@ else
   ac_cv_func_mmap=no
 else
 cat > conftest.$ac_ext <<EOF
-#line 1358 "configure"
+#line 1391 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Haertel and Jim Avera for this test. */
@@ -1588,7 +1621,7 @@ test -z "$x_direct_test_library" && x_direct_test_library=Xt
 test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
 test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
 cat > conftest.$ac_ext <<EOF
-#line 1592 "configure"
+#line 1625 "configure"
 #include "confdefs.h"
 #include <$x_direct_test_include>
 EOF
@@ -1651,7 +1684,7 @@ rm -f conftest*
 ac_save_LIBS="$LIBS"
 LIBS="-l$x_direct_test_library $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1655 "configure"
+#line 1688 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1770,7 +1803,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lICE  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1774 "configure"
+#line 1807 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1814,7 +1847,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1818 "configure"
+#line 1851 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1849,7 +1882,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet_stub  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1853 "configure"
+#line 1886 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1889,7 +1922,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1893 "configure"
+#line 1926 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1928,7 +1961,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1932 "configure"
+#line 1965 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -2033,7 +2066,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2037 "configure"
+#line 2070 "configure"
 #include "confdefs.h"
 #include <tclInt.h>
 EOF
@@ -2090,7 +2123,7 @@ if test "$cross_compiling" = yes; then
 
 else
 cat > conftest.$ac_ext <<EOF
-#line 2094 "configure"
+#line 2127 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -2250,7 +2283,7 @@ else
   ac_cv_c_tclib="-l$installedtcllibroot"
 else
 cat > conftest.$ac_ext <<EOF
-#line 2254 "configure"
+#line 2287 "configure"
 #include "confdefs.h"
 
     Tcl_AppInit()
@@ -2366,7 +2399,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2370 "configure"
+#line 2403 "configure"
 #include "confdefs.h"
 #include <tk.h>
 EOF
@@ -2430,7 +2463,7 @@ if test "$cross_compiling" = yes; then
 
 else
 cat > conftest.$ac_ext <<EOF
-#line 2434 "configure"
+#line 2467 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -2611,7 +2644,7 @@ else
   ac_cv_c_tklib="-l$installedtklibroot"
 else
 cat > conftest.$ac_ext <<EOF
-#line 2615 "configure"
+#line 2648 "configure"
 #include "confdefs.h"
 
        Tcl_AppInit()
@@ -2658,7 +2691,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2662 "configure"
+#line 2695 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -2696,7 +2729,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldld  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2700 "configure"
+#line 2733 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
index 71b82888445a3a41a45269317325754f150696a2..f560defb47183b6064f76ede76cc8714ee165bac 100644 (file)
@@ -57,6 +57,19 @@ if test $gdb_have_fpregset_t = yes; then
   AC_DEFINE(HAVE_FPREGSET_T)
 fi
 
+dnl See if compiler supports "long double" type.  Can't use AC_C_LONG_DOUBLE
+dnl because autoconf complains about cross-compilation issues.  However, this
+dnl code uses the same variables as the macro for compatibility.
+
+AC_MSG_CHECKING(for long double)
+AC_CACHE_VAL(ac_cv_c_long_double,
+[AC_TRY_COMPILE(, [long double foo;],
+ac_cv_c_long_double=yes, ac_cv_c_long_double=no)])
+AC_MSG_RESULT($ac_cv_c_long_double)
+if test $ac_cv_c_long_double = yes; then
+  AC_DEFINE(HAVE_LONG_DOUBLE)
+fi
+
 AC_FUNC_MMAP
 
 dnl Handle optional features that can be enabled.
index 6b6aa989b28a7b19692f5553b5f4a6fc16302003..b50094aa98ccdccd042c4c673e40e985eb35681e 100644 (file)
@@ -122,7 +122,7 @@ void yyerror PARAMS ((char *));
       LONGEST val;
       struct type *type;
     } typed_val;
-    double dval;
+    DOUBLEST dval;
     struct symbol *sym;
     struct type *tval;
     struct stoken sval;
index fd3a532af24675136bc27e119d052403a3b17d06..f0f46d6734f94354d70ba588afd10bc20e568eed 100644 (file)
@@ -15,7 +15,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -228,7 +228,7 @@ store_address (addr, len, val)
    3.  We probably should have a LONGEST_DOUBLE or DOUBLEST or whatever
    we want to call it which is long double where available.  */
 
-double
+DOUBLEST
 extract_floating (addr, len)
      PTR addr;
      int len;
@@ -247,6 +247,13 @@ extract_floating (addr, len)
       SWAP_FLOATING (&retval, sizeof (retval));
       return retval;
     }
+  else if (len == sizeof (long double))
+    {
+      long double retval;
+      memcpy (&retval, addr, sizeof (retval));
+      SWAP_FLOATING (&retval, sizeof (retval));
+      return retval;
+    }
   else
     {
       error ("Can't deal with a floating point number of %d bytes.", len);
@@ -257,7 +264,7 @@ void
 store_floating (addr, len, val)
      PTR addr;
      int len;
-     double val;
+     DOUBLEST val;
 {
   if (len == sizeof (float))
     {
@@ -266,6 +273,13 @@ store_floating (addr, len, val)
       memcpy (addr, &floatval, sizeof (floatval));
     }
   else if (len == sizeof (double))
+    {
+      double doubleval = val;
+
+      SWAP_FLOATING (&doubleval, sizeof (doubleval));
+      memcpy (addr, &doubleval, sizeof (doubleval));
+    }
+  else if (len == sizeof (long double))
     {
       SWAP_FLOATING (&val, sizeof (val));
       memcpy (addr, &val, sizeof (val));
@@ -971,6 +985,7 @@ symbol_read_needs_frame (sym)
 
     case LOC_BLOCK:
     case LOC_CONST_BYTES:
+    case LOC_UNRESOLVED:
     case LOC_OPTIMIZED_OUT:
       return 0;
     }
@@ -1098,6 +1113,17 @@ read_var_value (var, frame)
       }
       break;
 
+    case LOC_UNRESOLVED:
+      {
+       struct minimal_symbol *msym;
+
+       msym = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL);
+       if (msym == NULL)
+         return 0;
+       addr = SYMBOL_VALUE_ADDRESS (msym);
+      }
+      break;
+
     case LOC_OPTIMIZED_OUT:
       VALUE_LVAL (v) = not_lval;
       VALUE_OPTIMIZED_OUT (v) = 1;
@@ -1126,11 +1152,14 @@ value_from_register (type, regnum, frame)
   CORE_ADDR addr;
   int optim;
   value_ptr v = allocate_value (type);
-  int len = TYPE_LENGTH (type);
   char *value_bytes = 0;
   int value_bytes_copied = 0;
   int num_storage_locs;
   enum lval_type lval;
+  int len;
+
+  CHECK_TYPEDEF (type);
+  len = TYPE_LENGTH (type);
 
   VALUE_REGNO (v) = regnum;
 
index 9ec896f28646b450fea6629bf5802fac105b7941..35f7423c1da3ed58457982c6d0045b62d16bd7b4 100644 (file)
@@ -136,7 +136,7 @@ static struct block *modblock=0;
   {
     LONGEST lval;
     unsigned LONGEST ulval;
-    double dval;
+    DOUBLEST dval;
     struct symbol *sym;
     struct type *tval;
     struct stoken sval;
index 316ab53c93c4252d769a7850e7315a56cbf90488..7d458c12a3b2a769b850d72a0a774220cca865be 100644 (file)
@@ -215,7 +215,7 @@ write_exp_elt_longcst (expelt)
 
 void
 write_exp_elt_dblcst (expelt)
-     double expelt;
+     DOUBLEST expelt;
 {
   union exp_element tmp;
 
index c9c5b464a44844698f5125af7a1df40c4490d6e8..9e7b1c72889eb99d22948b5aa2513c8956174afd 100644 (file)
@@ -95,7 +95,7 @@ extern void write_exp_elt_sym PARAMS ((struct symbol *));
 
 extern void write_exp_elt_longcst PARAMS ((LONGEST));
 
-extern void write_exp_elt_dblcst PARAMS ((double));
+extern void write_exp_elt_dblcst PARAMS ((DOUBLEST));
 
 extern void write_exp_elt_type PARAMS ((struct type *));
 
index 046d21388735148f0f8022c96108b868bfdc9e06..e58f23378f89e03690ec1c45c5e0a59663b239e2 100644 (file)
@@ -407,12 +407,13 @@ value_assign (toval, fromval)
   if (!toval->modifiable)
     error ("Left operand of assignment is not a modifiable lvalue.");
 
-  COERCE_ARRAY (fromval);
   COERCE_REF (toval);
 
   type = VALUE_TYPE (toval);
   if (VALUE_LVAL (toval) != lval_internalvar)
     fromval = value_cast (type, fromval);
+  else
+    COERCE_ARRAY (fromval);
   CHECK_TYPEDEF (type);
 
   /* If TOVAL is a special machine register requiring conversion
@@ -886,10 +887,18 @@ value_arg_coerce (arg, param_type)
       if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
        type = builtin_type_int;
       break;
-    case TYPE_CODE_FLT:
-      if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
-       type = builtin_type_double;
-      break;
+   case TYPE_CODE_FLT:
+     /* coerce float to double, unless the function prototype specifies float */
+#if 0
+     if (param_type == 0)
+#endif
+       {
+        if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
+          type = builtin_type_double;
+        else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double))
+          type = builtin_type_long_double;
+       }
+     break;
     case TYPE_CODE_FUNC:
       type = lookup_pointer_type (type);
       break;
@@ -1139,7 +1148,10 @@ call_function_by_hand (function, nargs, args)
             || TYPE_CODE (arg_type) == TYPE_CODE_ARRAY
             || TYPE_CODE (arg_type) == TYPE_CODE_STRING
             || TYPE_CODE (arg_type) == TYPE_CODE_BITSTRING
-            || TYPE_CODE (arg_type) == TYPE_CODE_SET)
+            || TYPE_CODE (arg_type) == TYPE_CODE_SET
+            || (TYPE_CODE (arg_type) == TYPE_CODE_FLT
+                && TYPE_LENGTH (arg_type) > 8)
+            )
          && REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
          {
            CORE_ADDR addr;
@@ -1363,6 +1375,23 @@ value_array (lowbound, highbound, elemvec)
        }
     }
 
+  rangetype = create_range_type ((struct type *) NULL, builtin_type_int,
+                                lowbound, highbound);
+  arraytype = create_array_type ((struct type *) NULL, 
+                                VALUE_TYPE (elemvec[0]), rangetype);
+
+  if (!current_language->c_style_arrays)
+    {
+      val = allocate_value (arraytype);
+      for (idx = 0; idx < nelem; idx++)
+       {
+         memcpy (VALUE_CONTENTS_RAW (val) + (idx * typelength),
+                 VALUE_CONTENTS (elemvec[idx]),
+                 typelength);
+       }
+      return val;
+    }
+
   /* Allocate space to store the array in the inferior, and then initialize
      it by copying in each element.  FIXME:  Is it worth it to create a
      local buffer in which to collect each value and then write all the
@@ -1377,10 +1406,6 @@ value_array (lowbound, highbound, elemvec)
 
   /* Create the array type and set up an array value to be evaluated lazily. */
 
-  rangetype = create_range_type ((struct type *) NULL, builtin_type_int,
-                                lowbound, highbound);
-  arraytype = create_array_type ((struct type *) NULL, 
-                                VALUE_TYPE (elemvec[0]), rangetype);
   val = value_at_lazy (arraytype, addr);
   return (val);
 }
index 991d374a84d9e52f31caa389c020ff419b7ec91b..b1776aefb88986045879c19c80030be7378ed1a6 100644 (file)
@@ -239,14 +239,6 @@ record_latest_value (val)
 {
   int i;
 
-  /* Check error now if about to store an invalid float.  We return -1
-     to the caller, but allow them to continue, e.g. to print it as "Nan". */
-  if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FLT)
-    {
-      unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &i);
-      if (i) return -1;                /* Indicate value not saved in history */
-    }
-
   /* We don't want this value to have anything to do with the inferior anymore.
      In particular, "set $1 = 50" should not affect the variable from which
      the value was taken, and fast watchpoints should be able to assume that
@@ -560,11 +552,11 @@ value_as_long (val)
   return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
 }
 
-double
+DOUBLEST
 value_as_double (val)
      register value_ptr val;
 {
-  double foo;
+  DOUBLEST foo;
   int inv;
   
   foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &inv);
@@ -655,7 +647,7 @@ unpack_long (type, valaddr)
    the returned double is OK to use.  Argument is in target
    format, result is in host format.  */
 
-double
+DOUBLEST
 unpack_double (type, valaddr, invp)
      struct type *type;
      char *valaddr;
@@ -1268,7 +1260,7 @@ value_from_longest (type, num)
 value_ptr
 value_from_double (type, num)
      struct type *type;
-     double num;
+     DOUBLEST num;
 {
   register value_ptr val = allocate_value (type);
   struct type *base_type = check_typedef (type);
@@ -1350,6 +1342,14 @@ value_being_returned (valtype, retbuf, struct_return)
      ))
 #endif
 
+/* Some fundamental types (such as long double) are returned on the stack for
+   certain architectures.  This macro should return true for any type besides
+   struct, union or array that gets returned on the stack.  */
+
+#ifndef RETURN_VALUE_ON_STACK
+#define RETURN_VALUE_ON_STACK(TYPE) 0
+#endif
+
 /* Return true if the function specified is using the structure returning
    convention on this machine to return arguments, or 0 if it is using
    the value returning convention.  FUNCTION is the value representing
@@ -1370,9 +1370,10 @@ using_struct_return (function, funcaddr, value_type, gcc_p)
   if (code == TYPE_CODE_ERROR)
     error ("Function return type unknown.");
 
-  if (code == TYPE_CODE_STRUCT ||
-      code == TYPE_CODE_UNION ||
-      code == TYPE_CODE_ARRAY)
+  if (code == TYPE_CODE_STRUCT
+      || code == TYPE_CODE_UNION
+      || code == TYPE_CODE_ARRAY
+      || RETURN_VALUE_ON_STACK (value_type))
     return USE_STRUCT_CONVENTION (gcc_p, value_type);
 
   return 0;