Multiarch TARGET_FLOAT_FORMAT, TARGET_DOUBLE_FORMAT,
authorAndrew Cagney <cagney@redhat.com>
Fri, 2 Jun 2000 01:59:13 +0000 (01:59 +0000)
committerAndrew Cagney <cagney@redhat.com>
Fri, 2 Jun 2000 01:59:13 +0000 (01:59 +0000)
TARGET_LONG_DOUBLE_FORMAT.  Update d10v.

gdb/ChangeLog
gdb/arch-utils.c
gdb/arch-utils.h
gdb/d10v-tdep.c
gdb/defs.h
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh

index ea682aad7225781c772835320c30b00a98609d78..f5d96be146d002056146b8f0002fdaf5adef1383 100644 (file)
@@ -1,3 +1,22 @@
+Tue May 30 13:31:57 2000  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * defs.h (TARGET_FLOAT_FORMAT, TARGET_DOUBLE_FORMAT,
+       TARGET_LONG_DOUBLE_FORMAT): Delete.
+
+       * gdbarch.sh: Add support for parameterized expressions.
+       (TARGET_FLOAT_FORMAT, TARGET_DOUBLE_FORMAT,
+       TARGET_LONG_DOUBLE_FORMAT): Add.  Include "floatformat.h".
+       * gdbarch.h, gdbarch.c: Regenerate.
+       
+       * arch-utils.c (default_single_format, default_double_format,
+       default_long_double_format): New functions. Include
+       "floatformat.h"
+       * arch-utils.h: Declare.
+       
+       * d10v-tdep.c (d10v_gdbarch_init): Set floating point format.
+       Note that long double is 64 bit, the rest are 32 bit.  Include
+       "floatformat.h".
+
 2000-06-02  Mark Kettenis  <kettenis@gnu.org>
 
        * config/alpha/nm-fbsd.h (CANNOT_STEP_BREAKPOINT): Define.
index a012b421dbedaa4a579fd97dea1bbd354d4ad3a7..be2433d37e6787b1f602d4d4e587c70869196ae8 100644 (file)
@@ -41,6 +41,8 @@
 #include "symfile.h"           /* for overlay functions */
 #endif
 
+#include "floatformat.h"
+
 /* Convenience macro for allocting typesafe memory. */
 
 #ifndef XMALLOC
@@ -163,6 +165,47 @@ core_addr_greaterthan (lhs, rhs)
 }
 
 
+/* Helper functions for TARGET_{FLOAT,DOUBLE}_FORMAT */
+
+const struct floatformat *
+default_float_format (struct gdbarch *gdbarch)
+{
+#if GDB_MULTI_ARCH
+  int byte_order = gdbarch_byte_order (gdbarch);
+#else
+  int byte_order = TARGET_BYTE_ORDER;
+#endif
+  switch (byte_order)
+    {
+    case BIG_ENDIAN:
+      return &floatformat_ieee_single_big;
+    case LITTLE_ENDIAN:
+      return &floatformat_ieee_single_little;
+    default:
+      internal_error ("default_float_format: bad byte order");
+    }
+}
+
+
+const struct floatformat *
+default_double_format (struct gdbarch *gdbarch)
+{
+#if GDB_MULTI_ARCH
+  int byte_order = gdbarch_byte_order (gdbarch);
+#else
+  int byte_order = TARGET_BYTE_ORDER;
+#endif
+  switch (byte_order)
+    {
+    case BIG_ENDIAN:
+      return &floatformat_ieee_double_big;
+    case LITTLE_ENDIAN:
+      return &floatformat_ieee_double_little;
+    default:
+      internal_error ("default_double_format: bad byte order");
+    }
+}
+
 /* */
 
 extern initialize_file_ftype __initialize_gdbarch_utils;
index 5762cddccd87bbbebd52348f6f6e43da7cc089c7..a9ff6f52ad93e128dafde76b21c5d427d8e78586 100644 (file)
@@ -63,4 +63,8 @@ extern gdbarch_prologue_frameless_p_ftype generic_prologue_frameless_p;
 extern int core_addr_lessthan (CORE_ADDR lhs, CORE_ADDR rhs);
 extern int core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs);
 
+/* Floating point values. */
+extern const struct floatformat *default_float_format (struct gdbarch *gdbarch);
+extern const struct floatformat *default_double_format (struct gdbarch *gdbarch);
+
 #endif
index 7ac4174000e6b5c0cb32dbff1cadbf8b52272374..094741eba7cb0379e6cee981e52467a59da1cc5d 100644 (file)
@@ -36,6 +36,7 @@
 #include "language.h"
 #include "arch-utils.h"
 
+#include "floatformat.h"
 #include "sim-d10v.h"
 
 #undef XMALLOC
@@ -1596,9 +1597,26 @@ d10v_gdbarch_init (info, arches)
   set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
   set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_long_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
+  /* NOTE: The d10v as a 32 bit ``float'' and ``double''. ``long
+     double'' is 64 bits. */
   set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
   set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
+  switch (info.byte_order)
+    {
+    case BIG_ENDIAN:
+      set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big);
+      set_gdbarch_double_format (gdbarch, &floatformat_ieee_single_big);
+      set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
+      break;
+    case LITTLE_ENDIAN:
+      set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
+      set_gdbarch_double_format (gdbarch, &floatformat_ieee_single_little);
+      set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_little);
+      break;
+    default:
+      internal_error ("d10v_gdbarch_init: bad byte order for float format");
+    }
 
   set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
   set_gdbarch_call_dummy_length (gdbarch, 0);
index b11edd14ef7a73ba8969c37d5f4bbb2fb6dfcf90..79ebd0c114a87f3e51cee8e5944afda0c1d47ede 100644 (file)
@@ -1114,21 +1114,6 @@ extern const struct floatformat floatformat_unknown;
 #define HOST_LONG_DOUBLE_FORMAT &floatformat_unknown
 #endif
 
-#ifndef TARGET_FLOAT_FORMAT
-#define TARGET_FLOAT_FORMAT (TARGET_BYTE_ORDER == BIG_ENDIAN \
-                            ? &floatformat_ieee_single_big \
-                            : &floatformat_ieee_single_little)
-#endif
-#ifndef TARGET_DOUBLE_FORMAT
-#define TARGET_DOUBLE_FORMAT (TARGET_BYTE_ORDER == BIG_ENDIAN \
-                             ? &floatformat_ieee_double_big \
-                             : &floatformat_ieee_double_little)
-#endif
-
-#ifndef TARGET_LONG_DOUBLE_FORMAT
-#define TARGET_LONG_DOUBLE_FORMAT &floatformat_unknown
-#endif
-
 /* Use `long double' if the host compiler supports it.  (Note that this is not
    necessarily any longer than `double'.  On SunOS/gcc, it's the same as
    double.)  This is necessary because GDB internally converts all floating
index bcad7b95bd73642ae4b86b03e992a16ed0aa3bb2..2c90782943c90ac794e7a9e582fbf5452d65796b 100644 (file)
@@ -58,6 +58,7 @@
 #endif
 #include "symcat.h"
 
+#include "floatformat.h"
 
 /* Static function declarations */
 
@@ -220,6 +221,9 @@ struct gdbarch
   gdbarch_stack_align_ftype *stack_align;
   gdbarch_reg_struct_has_addr_ftype *reg_struct_has_addr;
   gdbarch_save_dummy_frame_tos_ftype *save_dummy_frame_tos;
+  const struct floatformat * float_format;
+  const struct floatformat * double_format;
+  const struct floatformat * long_double_format;
 };
 
 
@@ -331,6 +335,9 @@ struct gdbarch startup_gdbarch = {
   0,
   0,
   0,
+  0,
+  0,
+  0,
   /* startup_gdbarch() */
 };
 struct gdbarch *current_gdbarch = &startup_gdbarch;
@@ -637,6 +644,12 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of stack_align, has predicate */
   /* Skip verify of reg_struct_has_addr, has predicate */
   /* Skip verify of save_dummy_frame_tos, has predicate */
+  if (gdbarch->float_format == 0)
+    gdbarch->float_format = default_float_format (gdbarch);
+  if (gdbarch->double_format == 0)
+    gdbarch->double_format = default_double_format (gdbarch);
+  if (gdbarch->long_double_format == 0)
+    gdbarch->long_double_format = &floatformat_unknown;
 }
 
 
@@ -1184,6 +1197,21 @@ gdbarch_dump (void)
                       "gdbarch_update: SAVE_DUMMY_FRAME_TOS = 0x%08lx\n",
                       (long) current_gdbarch->save_dummy_frame_tos
                       /*SAVE_DUMMY_FRAME_TOS ()*/);
+#endif
+#ifdef TARGET_FLOAT_FORMAT
+  fprintf_unfiltered (gdb_stdlog,
+                      "gdbarch_update: TARGET_FLOAT_FORMAT = %ld\n",
+                      (long) TARGET_FLOAT_FORMAT);
+#endif
+#ifdef TARGET_DOUBLE_FORMAT
+  fprintf_unfiltered (gdb_stdlog,
+                      "gdbarch_update: TARGET_DOUBLE_FORMAT = %ld\n",
+                      (long) TARGET_DOUBLE_FORMAT);
+#endif
+#ifdef TARGET_LONG_DOUBLE_FORMAT
+  fprintf_unfiltered (gdb_stdlog,
+                      "gdbarch_update: TARGET_LONG_DOUBLE_FORMAT = %ld\n",
+                      (long) TARGET_LONG_DOUBLE_FORMAT);
 #endif
   fprintf_unfiltered (gdb_stdlog,
                       "gdbarch_update: GDB_MULTI_ARCH = %d\n",
@@ -2820,6 +2848,51 @@ set_gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch,
   gdbarch->save_dummy_frame_tos = save_dummy_frame_tos;
 }
 
+const struct floatformat *
+gdbarch_float_format (struct gdbarch *gdbarch)
+{
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_float_format called\n");
+  return gdbarch->float_format;
+}
+
+void
+set_gdbarch_float_format (struct gdbarch *gdbarch,
+                          const struct floatformat * float_format)
+{
+  gdbarch->float_format = float_format;
+}
+
+const struct floatformat *
+gdbarch_double_format (struct gdbarch *gdbarch)
+{
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_double_format called\n");
+  return gdbarch->double_format;
+}
+
+void
+set_gdbarch_double_format (struct gdbarch *gdbarch,
+                           const struct floatformat * double_format)
+{
+  gdbarch->double_format = double_format;
+}
+
+const struct floatformat *
+gdbarch_long_double_format (struct gdbarch *gdbarch)
+{
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_long_double_format called\n");
+  return gdbarch->long_double_format;
+}
+
+void
+set_gdbarch_long_double_format (struct gdbarch *gdbarch,
+                                const struct floatformat * long_double_format)
+{
+  gdbarch->long_double_format = long_double_format;
+}
+
 
 /* Keep a registrary of per-architecture data-pointers required by GDB
    modules. */
index 7121a224870d7e2f0b27f3ff260611092e95a027..d4a7849b48659696c8db8af523a11a309e8b0375 100644 (file)
@@ -1091,6 +1091,45 @@ extern void set_gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch, gdbarch_s
 #endif
 #endif
 
+/* Default (value) for non- multi-arch platforms. */
+#if (GDB_MULTI_ARCH == 0) && !defined (TARGET_FLOAT_FORMAT)
+#define TARGET_FLOAT_FORMAT (default_float_format (current_gdbarch))
+#endif
+
+extern const struct floatformat * gdbarch_float_format (struct gdbarch *gdbarch);
+extern void set_gdbarch_float_format (struct gdbarch *gdbarch, const struct floatformat * float_format);
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > 1) || !defined (TARGET_FLOAT_FORMAT)
+#define TARGET_FLOAT_FORMAT (gdbarch_float_format (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (GDB_MULTI_ARCH == 0) && !defined (TARGET_DOUBLE_FORMAT)
+#define TARGET_DOUBLE_FORMAT (default_double_format (current_gdbarch))
+#endif
+
+extern const struct floatformat * gdbarch_double_format (struct gdbarch *gdbarch);
+extern void set_gdbarch_double_format (struct gdbarch *gdbarch, const struct floatformat * double_format);
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > 1) || !defined (TARGET_DOUBLE_FORMAT)
+#define TARGET_DOUBLE_FORMAT (gdbarch_double_format (current_gdbarch))
+#endif
+#endif
+
+/* Default (value) for non- multi-arch platforms. */
+#if (GDB_MULTI_ARCH == 0) && !defined (TARGET_LONG_DOUBLE_FORMAT)
+#define TARGET_LONG_DOUBLE_FORMAT (&floatformat_unknown)
+#endif
+
+extern const struct floatformat * gdbarch_long_double_format (struct gdbarch *gdbarch);
+extern void set_gdbarch_long_double_format (struct gdbarch *gdbarch, const struct floatformat * long_double_format);
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > 1) || !defined (TARGET_LONG_DOUBLE_FORMAT)
+#define TARGET_LONG_DOUBLE_FORMAT (gdbarch_long_double_format (current_gdbarch))
+#endif
+#endif
+
 extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
 
 
index 3dd27c2c16caa031131dfaaa33b91b6b576966a8..318bbfd26dece8639f2e02c7d79ff428f6e9c370 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/local/bin/bash
+#!/usr/local/bin/bash -u
 
 # Architecture commands for GDB, the GNU debugger.
 # Copyright 1998-2000 Free Software Foundation, Inc.
@@ -34,63 +34,50 @@ compare_new ()
 }
 
 
-# DEFAULT is a valid fallback definition of a MACRO when
-# multi-arch is not enabled.
-default_is_fallback_p ()
-{
-    [ "${predefault}" != "" -a "${invalid_p}" = "0" ]
-}
-
 # Format of the input table
 read="class level macro returntype function formal actual attrib staticdefault predefault postdefault invalid_p fmt print print_p description"
 
-class_is_variable_p ()
-{
-    [ "${class}" = "v" -o "${class}" = "V" ]
-}
-
-class_is_function_p ()
-{
-    [ "${class}" = "f" -o "${class}" = "F" ]
-}
-
-class_is_predicate_p ()
-{
-    [ "${class}" = "F" -o "${class}" = "V" ]
-}
-
-class_is_info_p ()
-{
-    [ "${class}" = "i" ]
-}
-
-
 do_read ()
 {
     if eval read $read
     then
        test "${staticdefault}" || staticdefault=0
+       # NOT YET: Breaks BELIEVE_PCC_PROMOTION and confuses non-
+       # multi-arch defaults.
+       # test "${predefault}" || predefault=0
        test "${fmt}" || fmt="%ld"
        test "${print}" || print="(long) ${macro}"
-       #FIXME:
-       #Should set PREDEFAULT to zero and force the user to provide
-       #an invalid_p=0
-       #test "${predefault}" || predefault=0 - NO
        case "${invalid_p}" in
            0 ) valid_p=1 ;;
            "" )
                if [ "${predefault}" ]
                then
+                   #invalid_p="gdbarch->${function} == ${predefault}"
                    valid_p="gdbarch->${function} != ${predefault}"
                else
+                   #invalid_p="gdbarch->${function} == 0"
                    valid_p="gdbarch->${function} != 0"
                fi
-               #NOT_YET
-               #test "${predefault}" && invalid_p="gdbarch->${function} == ${predefault}"
                ;;
            * ) valid_p="!(${invalid_p})"
        esac
+
+       # PREDEFAULT is a valid fallback definition of MEMBER when
+       # multi-arch is not enabled.  This ensures that the default
+       # value, when multi-arch is the same as the default value when
+       # not multi-arch.  POSTDEFAULT is always a valid definition of
+       # MEMBER as this again ensures consistency.
+       if [ "${postdefault}" != "" ]
+       then
+           fallbackdefault="${postdefault}"
+       elif [ "${predefault}" != "" ]
+       then
+           fallbackdefault="${predefault}"
+       else
+           fallbackdefault=""
+       fi
        #NOT YET:
+       # See gdbarch.log for basic verification of database
        :
     else
        false
@@ -98,6 +85,33 @@ do_read ()
 }
 
 
+fallback_default_p ()
+{
+    [ "${postdefault}" != "" -a "${invalid_p}" != "0" ] \
+       || [ "${predefault}" != "" -a "${invalid_p}" = "0" ]
+}
+
+class_is_variable_p ()
+{
+    [ "${class}" = "v" -o "${class}" = "V" ]
+}
+
+class_is_function_p ()
+{
+    [ "${class}" = "f" -o "${class}" = "F" ]
+}
+
+class_is_predicate_p ()
+{
+    [ "${class}" = "F" -o "${class}" = "V" ]
+}
+
+class_is_info_p ()
+{
+    [ "${class}" = "i" ]
+}
+
+
 # dump out/verify the doco
 for field in ${read}
 do
@@ -173,15 +187,20 @@ do
 
        # If PREDEFAULT is empty, zero is used.
 
-       # Specify a non-empty PREDEFAULT and a zero INVALID_P to
-       # create a fallback value or function for when multi-arch is
-       # disabled.  Specify a zero PREDEFAULT function to make that
-       # fallback call internal_error().
+       # When POSTDEFAULT is empty, a non-empty PREDEFAULT and a zero
+       # INVALID_P will be used as default values when when
+       # multi-arch is disabled.  Specify a zero PREDEFAULT function
+       # to make that fallback call internal_error().
+
+       # Variable declarations can refer to ``gdbarch'' which will
+       # contain the current architecture.  Care should be taken.
 
     postdefault ) : ;;
 
        # A value to assign to MEMBER of the new gdbarch object should
-       # the target code fail to change the PREDEFAULT value.
+       # the target code fail to change the PREDEFAULT value.  Also
+       # use POSTDEFAULT as the fallback value for the non-
+       # multi-arch case.
 
        # If POSTDEFAULT is empty, no post update is performed.
 
@@ -189,11 +208,10 @@ do
        # INVALID_P will be used to determine if MEMBER should be
        # changed to POSTDEFAULT.
 
-       # FIXME: NOT YET.  Can this be simplified?  Specify a
-       # non-empty POSTDEFAULT and a zero INVALID_P to create a
-       # fallback value or function for when multi-arch is disabled.
-       # Specify a zero POSTDEFAULT function to make that fallback
-       # call internal_error(). This overrides PREDEFAULT.
+       # You cannot specify both a zero INVALID_P and a POSTDEFAULT.
+
+       # Variable declarations can refer to ``gdbarch'' which will
+       # contain the current architecture.  Care should be taken.
 
     invalid_p ) : ;;
 
@@ -207,7 +225,8 @@ do
        # If INVALID_P is empty, a check that MEMBER is no longer
        # equal to PREDEFAULT is used.
 
-       # The expression ``0'' disables the INVALID_P check.
+       # The expression ``0'' disables the INVALID_P check making
+       # PREDEFAULT a legitimate value.
 
        # See also PREDEFAULT and POSTDEFAULT.
 
@@ -305,8 +324,8 @@ v:1:CALL_DUMMY_STACK_ADJUST_P:int:call_dummy_stack_adjust_p::::0:-1:::0x%08lx
 v:2:CALL_DUMMY_STACK_ADJUST:int:call_dummy_stack_adjust::::0:::gdbarch->call_dummy_stack_adjust_p && gdbarch->call_dummy_stack_adjust == 0:0x%08lx::CALL_DUMMY_STACK_ADJUST_P
 f:2:FIX_CALL_DUMMY:void:fix_call_dummy:char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, struct value **args, struct type *type, int gcc_p:dummy, pc, fun, nargs, args, type, gcc_p:::0
 #
-v:2:BELIEVE_PCC_PROMOTION:int:believe_pcc_promotion::::0:::::
-v:2:BELIEVE_PCC_PROMOTION_TYPE:int:believe_pcc_promotion_type::::0:::::
+v:2:BELIEVE_PCC_PROMOTION:int:believe_pcc_promotion:::::::
+v:2:BELIEVE_PCC_PROMOTION_TYPE:int:believe_pcc_promotion_type:::::::
 f:2:COERCE_FLOAT_TO_DOUBLE:int:coerce_float_to_double:struct type *formal, struct type *actual:formal, actual:::default_coerce_float_to_double::0
 f:1:GET_SAVED_REGISTER:void:get_saved_register:char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval:raw_buffer, optimized, addrp, frame, regnum, lval::generic_get_saved_register:0
 #
@@ -364,6 +383,10 @@ f:2:FRAME_NUM_ARGS:int:frame_num_args:struct frame_info *frame:frame::0:0
 F:2:STACK_ALIGN:CORE_ADDR:stack_align:CORE_ADDR sp:sp::0:0
 F:2:REG_STRUCT_HAS_ADDR:int:reg_struct_has_addr:int gcc_p, struct type *type:gcc_p, type::0:0
 F:2:SAVE_DUMMY_FRAME_TOS:void:save_dummy_frame_tos:CORE_ADDR sp:sp::0:0
+#
+v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch)
+v:2:TARGET_DOUBLE_FORMAT:const struct floatformat *:double_format::::::default_double_format (gdbarch)
+v:2:TARGET_LONG_DOUBLE_FORMAT:const struct floatformat *:long_double_format::::::&floatformat_unknown
 EOF
   grep -v '^#'
 }
@@ -380,7 +403,8 @@ ${class} ${macro}(${actual})
     level=${level}
     staticdefault=${staticdefault}
     predefault=${predefault}
-    postdefault=${predefault}
+    postdefault=${postdefault}
+    fallbackdefault=${fallbackdefault}
     invalid_p=${invalid_p}
     valid_p=${valid_p}
     fmt=${fmt}
@@ -388,12 +412,18 @@ ${class} ${macro}(${actual})
     print_p=${print_p}
     description=${description}
 EOF
-    if class_is_predicate_p && default_is_fallback_p
+    if class_is_predicate_p && fallback_default_p
     then
        echo "Error: predicate function can not have a non- multi-arch default" 1>&2
        kill $$
        exit 1
     fi
+    if [ "${invalid_p}" = "0" -a "${postdefault}" != "" ]
+    then
+       echo "Error: postdefault is useless when invalid_p=0" 1>&2
+       kill $$
+       exit 1
+    fi
 done
 
 exec 1>&2
@@ -527,12 +557,13 @@ do
     fi
     if class_is_variable_p
     then
-       if default_is_fallback_p || class_is_predicate_p
+       if fallback_default_p || class_is_predicate_p
        then
            echo ""
            echo "/* Default (value) for non- multi-arch platforms. */"
            echo "#if (GDB_MULTI_ARCH == 0) && !defined (${macro})"
-           echo "#define ${macro} (${predefault})"
+           echo "#define ${macro} (${fallbackdefault})" \
+               | sed -e 's/\([^a-z_]\)\(gdbarch[^a-z_]\)/\1current_\2/g'
            echo "#endif"
        fi
        echo ""
@@ -546,16 +577,18 @@ do
     fi
     if class_is_function_p
     then
-       if default_is_fallback_p || class_is_predicate_p
+       if fallback_default_p || class_is_predicate_p
        then
            echo ""
            echo "/* Default (function) for non- multi-arch platforms. */"
            echo "#if (GDB_MULTI_ARCH == 0) && !defined (${macro})"
-           if [ "${predefault}" = "0" ]
+           if [ "${fallbackdefault}" = "0" ]
            then
                echo "#define ${macro}(${actual}) (internal_error (\"${macro}\"), 0)"
            else
-               echo "#define ${macro}(${actual}) (${predefault} (${actual}))"
+               # FIXME: Should be passing current_gdbarch through!
+               echo "#define ${macro}(${actual}) (${fallbackdefault} (${actual}))" \
+                   | sed -e 's/\([^a-z_]\)\(gdbarch[^a-z_]\)/\1current_\2/g'
            fi
            echo "#endif"
        fi
@@ -916,6 +949,7 @@ cat <<EOF
 #endif
 #include "symcat.h"
 
+#include "floatformat.h"
 
 /* Static function declarations */
 
@@ -1136,7 +1170,20 @@ do
        elif class_is_predicate_p
        then
            echo "  /* Skip verify of ${function}, has predicate */"
-       elif [ "${invalid_p}" ]
+       # FIXME: See do_read for potential simplification
+       elif [ "${invalid_p}" -a "${postdefault}" ]
+       then
+           echo "  if (${invalid_p})"
+           echo "    gdbarch->${function} = ${postdefault};"
+       elif [ "${predefault}" -a "${postdefault}" ]
+       then
+           echo "  if (gdbarch->${function} == ${predefault})"
+           echo "    gdbarch->${function} = ${postdefault};"
+       elif [ "${postdefault}" ]
+       then
+           echo "  if (gdbarch->${function} == 0)"
+           echo "    gdbarch->${function} = ${postdefault};"
+       elif [ "${invalid_p}" ]
        then
            echo "  if ((GDB_MULTI_ARCH >= ${level})"
            echo "      && (${invalid_p}))"