This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: Printing decimal128 types out of registers
- From: Luis Machado <luisgpm at linux dot vnet dot ibm dot com>
- To: Thiago Jung Bauermann <bauerman at br dot ibm dot com>
- Cc: gdb-patches at sourceware dot org
- Date: Fri, 18 Jan 2008 13:42:34 -0200
- Subject: Re: Printing decimal128 types out of registers
- References: <1194460412.6686.34.camel@localhost> <1200596592.27321.20.camel@gargoyle> <1200598580.32125.11.camel@localhost.localdomain>
- Reply-to: luisgpm at linux dot vnet dot ibm dot com
> These files are generated. You should edit the XML and regenerate.
Fixed the formatting issues and regenerated the c files based on the xml
files.
Regards,
--
Luis Machado
Software Engineer
IBM Linux Technology Center
2008-01-18 Luis Machado <luisgpm@br.ibm.com>
* rs6000-tdep.c (rs6000_gdbarch_init): Add support for
Decimal128 pseudo-registers.
(rs6000_pseudo_register_type): Returns the correct type for
Decimal128 pseudo-registers.
(rs6000_pseudo_register_reggroup_p): Returns the correct register
group for Decimal128 pseudo-registers.
(ppc_pseudo_register_read): New function.
(ppc_pseudo_register_write): New function.
* ppc-tdep.h: Add new variables ppc_dl0_upper_regnum, ppc_dl0_regnum
and ppc_dl15_regnum.
* printcmd.c: Fix displaying of DFP types as hex.
* features/rs6000/powerpc-64.c: Regenerate.
* features/rs6000/powerpc-32.c: Regenerate.
* features/rs6000/powerpc-64.xml: Add decimal128 feature.
* features/rs6000/powerpc-32.xml: Add decimal128 feature.
* features/rs6000/power-dfp128.xml: New file.
* testsuite/gdb.arch/powerpc-d128-regs.exp: New testcase expect
file.
* testsuite/gdb.arch/powerpc-d128-regs.c: New testcase source
file.
* doc/gdb.textinfo: Add new powerpc dfp128 feature documentation.
Index: gdb/rs6000-tdep.c
===================================================================
--- gdb.orig/rs6000-tdep.c 2008-01-18 05:15:36.000000000 -0800
+++ gdb/rs6000-tdep.c 2008-01-18 05:15:57.000000000 -0800
@@ -2384,6 +2384,20 @@
return spe_regnames[regno - tdep->ppc_ev0_regnum];
}
+ /* Check if the decimal128 pseudo-registers are available. */
+ if (tdep->ppc_dl0_regnum >= 0
+ && tdep->ppc_dl0_regnum <= regno
+ && regno < tdep->ppc_dl0_regnum + 16)
+ {
+ static const char *const dfp128_regnames[] = {
+ "dl0", "dl1", "dl2", "dl3",
+ "dl4", "dl5", "dl6", "dl7",
+ "dl8", "dl9", "dl10", "dl11",
+ "dl12", "dl13", "dl14", "dl15"
+ };
+ return dfp128_regnames[regno - tdep->ppc_dl0_regnum];
+ }
+
return tdesc_register_name (gdbarch, regno);
}
@@ -2395,12 +2409,19 @@
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- /* These are the only pseudo-registers we support. */
- gdb_assert (tdep->ppc_ev0_regnum >= 0
- && regnum >= tdep->ppc_ev0_regnum
- && regnum < tdep->ppc_ev0_regnum + 32);
+ /* These are the e500 pseudo-registers. */
+ if (tdep->ppc_ev0_regnum >= 0
+ && regnum >= tdep->ppc_ev0_regnum
+ && regnum < tdep->ppc_ev0_regnum + 32)
+ return rs6000_builtin_type_vec64 (gdbarch);
+
+ /* These are the ppc decimal128 pseudo-registers. */
+ if (tdep->ppc_dl0_regnum >= 0
+ && regnum >= tdep->ppc_dl0_regnum
+ && regnum < tdep->ppc_dl0_regnum + 16)
+ return builtin_type (current_gdbarch)->builtin_declong;;
- return rs6000_builtin_type_vec64 (gdbarch);
+ return NULL;
}
/* Is REGNUM a member of REGGROUP? */
@@ -2410,10 +2431,17 @@
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- /* These are the only pseudo-registers we support. */
- gdb_assert (tdep->ppc_ev0_regnum >= 0
- && regnum >= tdep->ppc_ev0_regnum
- && regnum < tdep->ppc_ev0_regnum + 32);
+ /* These are the e500 pseudo-registers. */
+ if (tdep->ppc_ev0_regnum < 0
+ && regnum < tdep->ppc_ev0_regnum
+ && regnum >= tdep->ppc_ev0_regnum + 32)
+ return -1;
+
+ /* These are the ppc decimal128 pseudo-registers. */
+ if (tdep->ppc_dl0_regnum < 0
+ && regnum < tdep->ppc_dl0_regnum
+ && regnum >= tdep->ppc_dl0_regnum + 16)
+ return -1;
if (group == all_reggroup || group == vector_reggroup)
return 1;
@@ -2556,6 +2584,89 @@
gdbarch_register_name (gdbarch, reg_nr), reg_nr);
}
+/* Read method for PPC pseudo-registers. Currently this is handling the
+ 16 decimal128 registers that map into 16 pairs of FP registers. */
+static void
+ppc_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+ int reg_nr, gdb_byte *buffer)
+{
+ struct gdbarch *regcache_arch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int reg_index;
+ gdb_byte *byte_buffer = buffer;
+
+ gdb_assert (regcache_arch == gdbarch);
+
+ if (tdep->ppc_dl0_regnum <= reg_nr
+ && reg_nr < tdep->ppc_dl0_regnum + 16)
+ {
+ reg_index = reg_nr - tdep->ppc_dl0_regnum;
+
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ {
+ /* Read two FP registers to form a whole dl register. */
+ regcache_raw_read (regcache, tdep->ppc_dl0_upper_regnum +
+ 2 * reg_index, byte_buffer);
+ regcache_raw_read (regcache, tdep->ppc_dl0_upper_regnum +
+ 2 * reg_index + 1, byte_buffer + 8);
+ }
+ else
+ {
+ regcache_raw_read (regcache, tdep->ppc_dl0_upper_regnum +
+ 2 * reg_index + 1, byte_buffer + 8);
+ regcache_raw_read (regcache, tdep->ppc_dl0_upper_regnum +
+ 2 * reg_index, byte_buffer);
+ }
+ }
+ else
+ internal_error (__FILE__, __LINE__,
+ _("ppc_pseudo_register_read: "
+ "called on unexpected register '%s' (%d)"),
+ gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+}
+
+/* Write method for PPC pseudo-registers. Currently this is handling the
+ 16 decimal128 registers that map into 16 pairs of FP registers. */
+static void
+ppc_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+ int reg_nr, const gdb_byte *buffer)
+{
+ struct gdbarch *regcache_arch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int reg_index;
+ const gdb_byte *byte_buffer = buffer;
+
+ gdb_assert (regcache_arch == gdbarch);
+
+ if (tdep->ppc_dl0_regnum <= reg_nr
+ && reg_nr < tdep->ppc_dl0_regnum + 16)
+ {
+ reg_index = reg_nr - tdep->ppc_dl0_regnum;
+
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ {
+ /* Write each half of the dl register into a separate
+ FP register. */
+ regcache_raw_write (regcache, tdep->ppc_dl0_upper_regnum +
+ 2 * reg_index, byte_buffer);
+ regcache_raw_write (regcache, tdep->ppc_dl0_upper_regnum +
+ 2 * reg_index + 1, byte_buffer + 8);
+ }
+ else
+ {
+ regcache_raw_write (regcache, tdep->ppc_dl0_upper_regnum +
+ 2 * reg_index + 1, byte_buffer + 8);
+ regcache_raw_write (regcache, tdep->ppc_dl0_upper_regnum +
+ 2 * reg_index, byte_buffer);
+ }
+ }
+ else
+ internal_error (__FILE__, __LINE__,
+ _("ppc_pseudo_register_write: "
+ "called on unexpected register '%s' (%d)"),
+ gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+}
+
/* Convert a DBX STABS register number to a GDB register number. */
static int
rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
@@ -3174,7 +3285,8 @@
enum auto_boolean soft_float_flag = powerpc_soft_float_global;
int soft_float;
enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
- int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0;
+ int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0,
+ have_dfp128 = 0;
int tdesc_wordsize = -1;
const struct target_desc *tdesc = info.target_desc;
struct tdesc_arch_data *tdesc_data = NULL;
@@ -3380,6 +3492,12 @@
else
have_altivec = 0;
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.dfp128");
+
+ if (feature != NULL)
+ have_dfp128 = 1;
+
/* On machines supporting the SPE APU, the general-purpose registers
are 64 bits long. There are SIMD vector instructions to treat them
as pairs of floats, but the rest of the instruction set treats them
@@ -3568,6 +3686,7 @@
tdep->ppc_ev0_upper_regnum = have_spe ? PPC_SPE_UPPER_GP0_REGNUM : -1;
tdep->ppc_acc_regnum = have_spe ? PPC_SPE_ACC_REGNUM : -1;
tdep->ppc_spefscr_regnum = have_spe ? PPC_SPE_FSCR_REGNUM : -1;
+ tdep->ppc_dl0_upper_regnum = have_dfp128 ? PPC_F0_REGNUM : -1;
set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM);
set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1);
@@ -3600,6 +3719,11 @@
set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write);
}
+ else if (have_dfp128)
+ {
+ set_gdbarch_pseudo_register_read (gdbarch, ppc_pseudo_register_read);
+ set_gdbarch_pseudo_register_write (gdbarch, ppc_pseudo_register_write);
+ }
set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
@@ -3610,7 +3734,12 @@
set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc);
set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS + num_sprs);
- set_gdbarch_num_pseudo_regs (gdbarch, have_spe ? 32 : 0);
+
+ if (have_spe)
+ set_gdbarch_num_pseudo_regs (gdbarch, 32);
+ else
+ if (have_dfp128)
+ set_gdbarch_num_pseudo_regs (gdbarch, 16);
set_gdbarch_ptr_bit (gdbarch, wordsize * TARGET_CHAR_BIT);
set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
@@ -3734,6 +3863,10 @@
tdep->ppc_ev0_regnum = have_spe ? gdbarch_num_regs (gdbarch) : -1;
tdep->ppc_ev31_regnum = have_spe ? tdep->ppc_ev0_regnum + 31 : -1;
+ /* Set the register number for decimal128 pseudo-registers. */
+ tdep->ppc_dl0_regnum = have_dfp128 ? gdbarch_num_regs (gdbarch) : -1;
+ tdep->ppc_dl15_regnum = have_dfp128 ? tdep->ppc_dl0_regnum + 15 : -1;
+
return gdbarch;
}
Index: gdb/ppc-tdep.h
===================================================================
--- gdb.orig/ppc-tdep.h 2008-01-18 05:15:36.000000000 -0800
+++ gdb/ppc-tdep.h 2008-01-18 05:15:57.000000000 -0800
@@ -205,6 +205,11 @@
int ppc_acc_regnum; /* SPE 'acc' register */
int ppc_spefscr_regnum; /* SPE 'spefscr' register */
+ /* Decimal 128 registers. */
+ int ppc_dl0_regnum; /* First Decimal128 argument register pair. */
+ int ppc_dl15_regnum; /* Last Decimal128 argument register pair. */
+ int ppc_dl0_upper_regnum; /* First FPR upper half register for dl0. */
+
/* Offset to ABI specific location where link register is saved. */
int lr_frame_offset;
Index: gdb/features/rs6000/powerpc-64.c
===================================================================
--- gdb.orig/features/rs6000/powerpc-64.c 2008-01-18 05:15:36.000000000 -0800
+++ gdb/features/rs6000/powerpc-64.c 2008-01-18 07:29:24.000000000 -0800
@@ -160,5 +160,7 @@
tdesc_create_reg (feature, "vscr", 103, 1, "vector", 32, "int");
tdesc_create_reg (feature, "vrsave", 104, 1, "vector", 32, "int");
+ feature = tdesc_create_feature (result, "org.gnu.gdb.power.dfp128");
+
tdesc_powerpc_64 = result;
}
Index: gdb/features/rs6000/powerpc-32.c
===================================================================
--- gdb.orig/features/rs6000/powerpc-32.c 2008-01-18 05:15:36.000000000 -0800
+++ gdb/features/rs6000/powerpc-32.c 2008-01-18 05:15:57.000000000 -0800
@@ -160,5 +160,7 @@
tdesc_create_reg (feature, "vscr", 103, 1, "vector", 32, "int");
tdesc_create_reg (feature, "vrsave", 104, 1, "vector", 32, "int");
+ feature = tdesc_create_feature (result, "org.gnu.gdb.power.dfp128");
+
tdesc_powerpc_32 = result;
}
Index: gdb/doc/gdb.texinfo
===================================================================
--- gdb.orig/doc/gdb.texinfo 2008-01-18 05:15:36.000000000 -0800
+++ gdb/doc/gdb.texinfo 2008-01-18 05:15:57.000000000 -0800
@@ -26654,6 +26654,13 @@
these to present registers @samp{ev0} through @samp{ev31} to the
user.
+The @samp{org.gnu.gdb.power.dfp128} feature is optional and is aimed at targets
+that support DFP types. It should contain registers @samp{dl0} through
+@samp{dl15}. Each @samp{dl} register is actually a pair of 64-bit floating
+point registers, so, for example, @samp{dl0} is composed by joining @samp{f0}
+and @samp{f1}. @value{GDBN} will combine the pair of floating
+point registers to present a single @samp{dl} register.
+
@include gpl.texi
@raisesections
Index: gdb/testsuite/gdb.arch/powerpc-d128-regs.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb/testsuite/gdb.arch/powerpc-d128-regs.c 2008-01-18 05:15:57.000000000 -0800
@@ -0,0 +1,25 @@
+/* This file is part of GDB, the GNU debugger.
+
+ Copyright 2008 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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, see <http://www.gnu.org/licenses/>. */
+
+/* Tests ppc decimal128 pseudo-registers. */
+
+int main(void)
+{
+ _Decimal128 d128 = 1.2345678910dl;
+
+ return 0;
+}
Index: gdb/testsuite/gdb.arch/powerpc-d128-regs.exp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb/testsuite/gdb.arch/powerpc-d128-regs.exp 2008-01-18 05:15:57.000000000 -0800
@@ -0,0 +1,77 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2008
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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, see <http://www.gnu.org/licenses/>.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# Testcase for ppc decimal128 pseudo-registers.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+if ![istarget "powerpc64-*"] then {
+ verbose "Skipping powerpc Decimal128 pseudo-registers testcase."
+ return
+}
+
+set testfile "powerpc-d128-regs"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {quiet debug}] != "" } {
+ untested powerpc-d128-regs.exp
+ return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if { ![runto main] } then {
+ fail "run to main"
+ return
+}
+
+if [gdb_test "show arch" ".*currently powerpc:common.*" "Checking for PPC arch"] {
+ return -1;
+}
+
+gdb_test "next" ""
+
+for {set i 0} {$i < 16} {incr i 1} {
+gdb_test "set \$dl$i=d128" "" "Set dl$i register"
+
+gdb_test "print \$dl$i" "\\\$$decimal = 1\.2345678910" "Print dl$i register as DFP"
+
+gdb_test "info reg dl$i" \
+ "dl$i\[ \]*0x2205800000000000000000049c5de09c\[\t\]*1\.2345678910" \
+ "Print dl$i register with the info reg command"
+
+gdb_test "info reg f[expr 2*$i]" \
+ "f[expr 2*$i]\[ \]*8\.608957309287334e\-145\[\t\]*\\(raw 0x2205800000000000\\)" \
+ "Testing lower half of dl$i register"
+
+gdb_test "info reg f[expr 2*$i+1]" \
+ "f[expr 2*$i+1]\[ \]*9\.7841140127686122e\-314\[\t\]*\\(raw 0x000000049c5de09c\\)" \
+ "Testing upper half of dl$i register"
+
+}
Index: gdb/printcmd.c
===================================================================
--- gdb.orig/printcmd.c 2008-01-18 05:15:36.000000000 -0800
+++ gdb/printcmd.c 2008-01-18 05:15:57.000000000 -0800
@@ -326,7 +326,8 @@
if (len > sizeof(LONGEST) &&
(TYPE_CODE (type) == TYPE_CODE_INT
- || TYPE_CODE (type) == TYPE_CODE_ENUM))
+ || TYPE_CODE (type) == TYPE_CODE_ENUM
+ || TYPE_CODE (type) == TYPE_CODE_DECFLOAT))
{
switch (format)
{
Index: gdb/features/rs6000/powerpc-32.xml
===================================================================
--- gdb.orig/features/rs6000/powerpc-32.xml 2008-01-18 05:15:36.000000000 -0800
+++ gdb/features/rs6000/powerpc-32.xml 2008-01-18 05:15:57.000000000 -0800
@@ -14,4 +14,5 @@
<xi:include href="power-core.xml"/>
<xi:include href="power-fpu.xml"/>
<xi:include href="power-altivec.xml"/>
+ <xi:include href="power-dfp128.xml"/>
</target>
Index: gdb/features/rs6000/powerpc-64.xml
===================================================================
--- gdb.orig/features/rs6000/powerpc-64.xml 2008-01-18 05:15:36.000000000 -0800
+++ gdb/features/rs6000/powerpc-64.xml 2008-01-18 05:15:57.000000000 -0800
@@ -14,4 +14,5 @@
<xi:include href="power64-core.xml"/>
<xi:include href="power-fpu.xml"/>
<xi:include href="power-altivec.xml"/>
+ <xi:include href="power-dfp128.xml"/>
</target>
Index: gdb/features/rs6000/power-dfp128.xml
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gdb/features/rs6000/power-dfp128.xml 2008-01-18 05:15:36.000000000 -0800
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.dfp128"></feature>