public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Carl Love <cel@linux.ibm.com>
To: Andrew Burgess <aburgess@redhat.com>,
	Carl Love <cel@linux.ibm.com>,
	gdb-patches@sourceware.org,
	UlrichWeigand <Ulrich.Weigand@de.ibm.com>,
	keiths@redhat.com
Subject: [PATCH 2/2] PowerPC, Fix-test-gdb.base-store.exp
Date: Fri, 20 Oct 2023 11:08:04 -0700	[thread overview]
Message-ID: <4e8742f920adecfedc347e386bf7f65f3ec62291.camel@linux.ibm.com> (raw)
In-Reply-To: <878r82hbwl.fsf@redhat.com>

GDB maintainers:

Ver 2:  In the new function, rs6000_value_from_register, moved the
declaration of frame to where it gets initialized.   Patch was retested
on Power10.

This is the second patch which fixes the 128-bit floating point
register mappings.  This fixes the remaining three issues with the
store.exp test.

             Carl 

-----------------------------------------
rs6000, Fix test gdb.base/store.exp

The test currently fails for IEEE 128-bit floating point types.  PowerPC
supports the IBM double 128-bit floating point format and IEEE 128-bit
format.  The IBM double 128-bit floating point format uses two 64-bit
floating point registers to store the 128-bit value.  The IEEE 128-bit
floating point format stores the value in a single 128-bit vector-scalar
register (vsr).

The various floating point values, 32-bit float, 64-bit double, IBM double
128-bit float and IEEE 128-bit floating point numbers are all mapped to the
DWARF fpr numbers.  The issue is the IEEE 128-bit floating point values are
actually stored in a vsr not the fprs.  This patch changes the register
mapping for the vsrs from the fpr to the vsr registers so the value is
properly accessed by GDB.  The functions rs6000_linux_register_to_value,
rs6000_linux_value_to_register, rs6000_linux_value_from_register check if
the value is an IEEE 128-bit floating point value and adjust the register
number as needed.  The test in function rs6000_convert_register_p is fixed
so it is only true for floating point values.

This patch fixes three regression tests in gdb.base/store.exp.

The patch has been tested on Power 8 LE/BE, Power 9 LE/BE and Power 10 LE
with no regressions.
---
 gdb/ppc-linux-tdep.c |  4 +++
 gdb/rs6000-tdep.c    | 65 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index dc03430e2af..fac56d961cb 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -63,6 +63,7 @@
 #include <ctype.h>
 #include "elf-bfd.h"
 #include "producer.h"
+#include "target-float.h"
 
 #include "features/rs6000/powerpc-32l.c"
 #include "features/rs6000/powerpc-altivec32l.c"
@@ -2102,6 +2103,9 @@ rs6000_linux_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
     /* FIXME: jimb/2004-05-05: What should we do when the debug info
        specifies registers the architecture doesn't have?  Our
        callers don't check the value we return.  */
+    /* Map dwarf register numbers for floating point, double, IBM double and
+       IEEE 128-bit floating point to the fpr range.  Will have to fix the
+       mapping for the IEEE 128-bit register numbers later.  */
     return tdep->ppc_fp0_regnum + (num - 32);
   else if (77 <= num && num < 77 + 32)
     return tdep->ppc_vr0_regnum + (num - 77);
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 23397d037ae..186646673f0 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -2676,7 +2676,25 @@ rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum,
 	  && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs
 	  && type->code () == TYPE_CODE_FLT
 	  && (type->length ()
-	      != builtin_type (gdbarch)->builtin_double->length ()));
+	      == builtin_type (gdbarch)->builtin_float->length ()));
+}
+
+static int
+ieee_128_float_regnum_adjust (struct gdbarch *gdbarch, struct type *type,
+			      int regnum)
+{
+  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+
+  /* If we have the an IEEE 128-bit floating point value, need to map the
+   register number to the corresponding VSR.  */
+  if (tdep->ppc_vsr0_regnum != -1
+      && regnum >= tdep->ppc_fp0_regnum
+      && regnum < (tdep->ppc_fp0_regnum + ppc_num_fprs)
+      && (gdbarch_long_double_format (gdbarch) == floatformats_ieee_quad)
+      && (type->length() == 16))
+    regnum = regnum - tdep->ppc_fp0_regnum + tdep->ppc_vsr0_regnum;
+
+  return regnum;
 }
 
 static int
@@ -2691,6 +2709,10 @@ rs6000_register_to_value (frame_info_ptr frame,
   
   gdb_assert (type->code () == TYPE_CODE_FLT);
 
+  /* We have an IEEE 128-bit float -- need to change regnum mapping from
+     fpr to vsr.  */
+  regnum = ieee_128_float_regnum_adjust (gdbarch, type, regnum);
+
   if (!get_frame_register_bytes (frame, regnum, 0,
 				 gdb::make_array_view (from,
 						       register_size (gdbarch,
@@ -2715,11 +2737,51 @@ rs6000_value_to_register (frame_info_ptr frame,
 
   gdb_assert (type->code () == TYPE_CODE_FLT);
 
+  /* We have an IEEE 128-bit float -- need to change regnum mapping from
+     fpr to vsr.  */
+  regnum = ieee_128_float_regnum_adjust (gdbarch, type, regnum);
+
   target_float_convert (from, type,
 			to, builtin_type (gdbarch)->builtin_double);
   put_frame_register (frame, regnum, to);
 }
 
+static struct value *
+rs6000_value_from_register (struct gdbarch *gdbarch, struct type *type,
+			    int regnum, struct frame_id frame_id)
+{
+  int len = type->length ();
+  struct value *value = value::allocate (type);
+
+  /* We have an IEEE 128-bit float -- need to change regnum mapping from
+     fpr to vsr.  */
+  regnum = ieee_128_float_regnum_adjust (gdbarch, type, regnum);
+
+  value->set_lval (lval_register);
+  frame_info_ptr frame = frame_find_by_id (frame_id);
+
+  if (frame == NULL)
+    frame_id = null_frame_id;
+  else
+    frame_id = get_frame_id (get_next_frame_sentinel_okay (frame));
+
+  VALUE_NEXT_FRAME_ID (value) = frame_id;
+  VALUE_REGNUM (value) = regnum;
+
+  /* Any structure stored in more than one register will always be
+     an integral number of registers.  Otherwise, you need to do
+     some fiddling with the last register copied here for little
+     endian machines.  */
+  if (type_byte_order (type) == BFD_ENDIAN_BIG
+      && len < register_size (gdbarch, regnum))
+    /* Big-endian, and we want less than full size.  */
+    value->set_offset (register_size (gdbarch, regnum) - len);
+  else
+    value->set_offset (0);
+
+  return value;
+}
+
  /* The type of a function that moves the value of REG between CACHE
     or BUF --- in either direction.  */
 typedef enum register_status (*move_ev_register_func) (struct regcache *,
@@ -8337,6 +8399,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_convert_register_p (gdbarch, rs6000_convert_register_p);
   set_gdbarch_register_to_value (gdbarch, rs6000_register_to_value);
   set_gdbarch_value_to_register (gdbarch, rs6000_value_to_register);
+  set_gdbarch_value_from_register (gdbarch, rs6000_value_from_register);
 
   set_gdbarch_stab_reg_to_regnum (gdbarch, rs6000_stab_reg_to_regnum);
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, rs6000_dwarf2_reg_to_regnum);
-- 
2.37.2



  parent reply	other threads:[~2023-10-20 18:08 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-12 14:51 Carl Love
2023-10-12 14:58 ` [Patch 1/2] " Carl Love
2023-10-13 20:34   ` Keith Seitz
2023-10-13 21:00     ` Carl Love
2023-10-16 11:12       ` Ulrich Weigand
2023-10-16 14:31   ` Andrew Burgess
2023-10-16 15:51     ` Carl Love
2023-10-19 15:54       ` Carl Love
2023-10-24  8:50       ` Andrew Burgess
2023-10-24 16:05         ` Carl Love
2023-10-20 18:08     ` [PATCH 1/2, ver2] " Carl Love
2023-10-24  9:30       ` Andrew Burgess
2023-10-25 13:24         ` Ulrich Weigand
2023-10-30  9:45           ` Andrew Burgess
2023-10-30 16:44             ` Ulrich Weigand
2023-10-30 17:16               ` Carl Love
2023-10-30 17:25               ` [PATCH 1/2, ver3] " Carl Love
2023-11-06 18:24                 ` Carl Love
2023-11-08 10:54                 ` Andrew Burgess
2023-10-12 15:00 ` [PATCH 2/2] " Carl Love
2023-10-13 20:35   ` Keith Seitz
2023-10-13 21:00     ` Carl Love
2023-10-16 11:13       ` Ulrich Weigand
2023-10-16 14:36   ` Andrew Burgess
2023-10-16 15:51     ` Carl Love
2023-10-20 18:08     ` Carl Love [this message]
2023-10-24  8:53       ` Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4e8742f920adecfedc347e386bf7f65f3ec62291.camel@linux.ibm.com \
    --to=cel@linux.ibm.com \
    --cc=Ulrich.Weigand@de.ibm.com \
    --cc=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=keiths@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).