* alpha-tdep.c (alpha_register_type): Change from _virtual_type.
authorRichard Henderson <rth@redhat.com>
Mon, 2 Jun 2003 22:43:31 +0000 (22:43 +0000)
committerRichard Henderson <rth@redhat.com>
Mon, 2 Jun 2003 22:43:31 +0000 (22:43 +0000)
        (alpha_convert_flt_dbl, alpha_convert_dbl_flt): Remove.
        (alpha_lds, alpha_sts): New.
        (alpha_convert_register_p): Change from _register_convertible.
        (alpha_register_to_value): Change from _convert_to_virtual;
        restructure and fail for type sizes other than 4 or 8.
        (alpha_value_to_register): Similarly.
        (alpha_extract_return_value): Use alpha_sts.
        (alpha_store_return_value): Use alpha_lds.
        (alpha_gdbarch_init): Update hooks.

gdb/ChangeLog
gdb/alpha-tdep.c

index 37a13149ab3dae74ff4bebaffeb9213776a59bdc..21326c274b4b226292ac53a15cc7d08aa126ea52 100644 (file)
@@ -1,3 +1,16 @@
+2003-06-02  Richard Henderson  <rth@redhat.com>
+
+       * alpha-tdep.c (alpha_register_type): Change from _virtual_type.
+       (alpha_convert_flt_dbl, alpha_convert_dbl_flt): Remove.
+       (alpha_lds, alpha_sts): New.
+       (alpha_convert_register_p): Change from _register_convertible.
+       (alpha_register_to_value): Change from _convert_to_virtual; 
+       restructure and fail for type sizes other than 4 or 8.
+       (alpha_value_to_register): Similarly.
+       (alpha_extract_return_value): Use alpha_sts.
+       (alpha_store_return_value): Use alpha_lds.
+       (alpha_gdbarch_init): Update hooks.
+
 2003-06-02  Richard Henderson  <rth@redhat.com>
 
        * alpha-tdep.c (alpha_register_virtual_type): Use alpha-specific
index 50d5dea4becb04d51275b98ab1d9c27c46a4b643..6d9c58d4e5d22a6999e4cc6a69b5f88635f37e71 100644 (file)
@@ -80,14 +80,8 @@ alpha_cannot_store_register (int regno)
   return regno == ALPHA_ZERO_REGNUM;
 }
 
-static int
-alpha_register_convertible (int regno)
-{
-  return (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31);
-}
-
 static struct type *
-alpha_register_virtual_type (int regno)
+alpha_register_type (struct gdbarch *gdbarch, int regno)
 {
   if (regno == ALPHA_SP_REGNUM || regno == ALPHA_GP_REGNUM)
     return builtin_type_void_data_ptr;
@@ -153,73 +147,91 @@ alpha_register_virtual_size (int regno)
   return 8;
 }
 
+/* The following represents exactly the conversion performed by
+   the LDS instruction.  This applies to both single-precision
+   floating point and 32-bit integers.  */
+
+static void
+alpha_lds (void *out, const void *in)
+{
+  ULONGEST mem     = extract_unsigned_integer (in, 4);
+  ULONGEST frac    = (mem >>  0) & 0x7fffff;
+  ULONGEST sign    = (mem >> 31) & 1;
+  ULONGEST exp_msb = (mem >> 30) & 1;
+  ULONGEST exp_low = (mem >> 23) & 0x7f;
+  ULONGEST exp, reg;
+
+  exp = (exp_msb << 10) | exp_low;
+  if (exp_msb)
+    {
+      if (exp_low == 0x7f)
+       exp = 0x7ff;
+    }
+  else
+    {
+      if (exp_low != 0x00)
+       exp |= 0x380;
+    }
+
+  reg = (sign << 63) | (exp << 52) | (frac << 29);
+  store_unsigned_integer (out, 8, reg);
+}
+
+/* Similarly, this represents exactly the conversion performed by
+   the STS instruction.  */
+
+static inline void
+alpha_sts (void *out, const void *in)
+{
+  ULONGEST reg, mem;
+
+  reg = extract_unsigned_integer (in, 8);
+  mem = ((reg >> 32) & 0xc0000000) | ((reg >> 29) & 0x3fffffff);
+  store_unsigned_integer (out, 4, mem);
+}
+
 /* The alpha needs a conversion between register and memory format if the
    register is a floating point register and memory format is float, as the
    register format must be double or memory format is an integer with 4
    bytes or less, as the representation of integers in floating point
    registers is different. */
 
-static void
-alpha_convert_flt_dbl (void *out, const void *in)
-{
-  DOUBLEST d = extract_typed_floating (in, builtin_type_ieee_single_little);
-  store_typed_floating (out, builtin_type_ieee_double_little, d);
-}
-
-static void
-alpha_convert_dbl_flt (void *out, const void *in)
+static int
+alpha_convert_register_p (int regno)
 {
-  DOUBLEST d = extract_typed_floating (in, builtin_type_ieee_double_little);
-  store_typed_floating (out, builtin_type_ieee_single_little, d);
+  return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31);
 }
 
 static void
-alpha_register_convert_to_virtual (int regnum, struct type *valtype,
-                                  char *raw_buffer, char *virtual_buffer)
+alpha_register_to_value (int regnum, struct type *valtype, char *in, char *out)
 {
-  if (TYPE_LENGTH (valtype) >= ALPHA_REGISTER_SIZE)
+  switch (TYPE_LENGTH (valtype))
     {
-      memcpy (virtual_buffer, raw_buffer, ALPHA_REGISTER_SIZE);
-      return;
-    }
-
-  /* Note that everything below is less than 8 bytes long.  */
-
-  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
-    alpha_convert_dbl_flt (virtual_buffer, raw_buffer);
-  else if (TYPE_CODE (valtype) == TYPE_CODE_INT)
-    {
-      ULONGEST l;
-      l = extract_unsigned_integer (raw_buffer, ALPHA_REGISTER_SIZE);
-      l = ((l >> 32) & 0xc0000000) | ((l >> 29) & 0x3fffffff);
-      store_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype), l);
+    case 4:
+      alpha_sts (out, in);
+      break;
+    case 8:
+      memcpy (out, in, 8);
+      break;
+    default:
+      error ("Cannot retrieve value from floating point register");
     }
-  else
-    error ("Cannot retrieve value from floating point register");
 }
 
 static void
-alpha_register_convert_to_raw (struct type *valtype, int regnum,
-                              char *virtual_buffer, char *raw_buffer)
+alpha_value_to_register (struct type *valtype, int regnum, char *in, char *out)
 {
-  if (TYPE_LENGTH (valtype) >= ALPHA_REGISTER_SIZE)
+  switch (TYPE_LENGTH (valtype))
     {
-      memcpy (raw_buffer, virtual_buffer, ALPHA_REGISTER_SIZE);
-      return;
-    }
-
-  /* Note that everything below is less than 8 bytes long.  */
-
-  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
-    alpha_convert_flt_dbl (raw_buffer, virtual_buffer);
-  else if (TYPE_CODE (valtype) == TYPE_CODE_INT)
-    {
-      ULONGEST l = unpack_long (valtype, virtual_buffer);
-      l = ((l & 0xc0000000) << 32) | ((l & 0x3fffffff) << 29);
-      store_unsigned_integer (raw_buffer, ALPHA_REGISTER_SIZE, l);
+    case 4:
+      alpha_lds (out, in);
+      break;
+    case 8:
+      memcpy (out, in, 8);
+      break;
+    default:
+      error ("Cannot store value in floating point register");
     }
-  else
-    error ("Cannot store value in floating point register");
 }
 
 \f
@@ -425,7 +437,7 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
        {
        case 4:
          regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, raw_buffer);
-         alpha_convert_dbl_flt (valbuf, raw_buffer);
+         alpha_sts (valbuf, raw_buffer);
          break;
 
        case 8:
@@ -502,7 +514,7 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
       switch (length)
        {
        case 4:
-         alpha_convert_flt_dbl (raw_buffer, valbuf);
+         alpha_lds (raw_buffer, valbuf);
          regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, raw_buffer);
          break;
 
@@ -1497,15 +1509,14 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_register_byte (gdbarch, alpha_register_byte);
   set_gdbarch_register_raw_size (gdbarch, alpha_register_raw_size);
   set_gdbarch_register_virtual_size (gdbarch, alpha_register_virtual_size);
-  set_gdbarch_register_virtual_type (gdbarch, alpha_register_virtual_type);
+  set_gdbarch_register_type (gdbarch, alpha_register_type);
 
   set_gdbarch_cannot_fetch_register (gdbarch, alpha_cannot_fetch_register);
   set_gdbarch_cannot_store_register (gdbarch, alpha_cannot_store_register);
 
-  set_gdbarch_register_convertible (gdbarch, alpha_register_convertible);
-  set_gdbarch_register_convert_to_virtual (gdbarch,
-                                           alpha_register_convert_to_virtual);
-  set_gdbarch_register_convert_to_raw (gdbarch, alpha_register_convert_to_raw);
+  set_gdbarch_convert_register_p (gdbarch, alpha_convert_register_p);
+  set_gdbarch_register_to_value (gdbarch, alpha_register_to_value);
+  set_gdbarch_value_to_register (gdbarch, alpha_value_to_register);
 
   set_gdbarch_register_reggroup_p (gdbarch, alpha_register_reggroup_p);