From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1717 invoked by alias); 18 Jan 2008 15:43:41 -0000 Received: (qmail 1703 invoked by uid 22791); 18 Jan 2008 15:43:39 -0000 X-Spam-Check-By: sourceware.org Received: from igw3.br.ibm.com (HELO igw3.br.ibm.com) (32.104.18.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 18 Jan 2008 15:43:05 +0000 Received: from mailhub3.br.ibm.com (unknown [9.18.232.110]) by igw3.br.ibm.com (Postfix) with ESMTP id CA84139037E for ; Fri, 18 Jan 2008 13:34:41 -0200 (BRDT) Received: from d24av01.br.ibm.com (d24av01.br.ibm.com [9.18.232.46]) by mailhub3.br.ibm.com (8.13.8/8.13.8/NCO v8.7) with ESMTP id m0IFgbMX4284598 for ; Fri, 18 Jan 2008 13:42:37 -0200 Received: from d24av01.br.ibm.com (loopback [127.0.0.1]) by d24av01.br.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m0IFgbli025356 for ; Fri, 18 Jan 2008 13:42:37 -0200 Received: from [9.18.238.70] (dyn531803.br.ibm.com [9.18.238.70] (may be forged)) by d24av01.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id m0IFgbph025352 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 18 Jan 2008 13:42:37 -0200 Subject: Re: Printing decimal128 types out of registers From: Luis Machado Reply-To: luisgpm@linux.vnet.ibm.com To: Thiago Jung Bauermann Cc: gdb-patches@sourceware.org In-Reply-To: <1200598580.32125.11.camel@localhost.localdomain> References: <1194460412.6686.34.camel@localhost> <1200596592.27321.20.camel@gargoyle> <1200598580.32125.11.camel@localhost.localdomain> Content-Type: multipart/mixed; boundary="=-lAnroNiqzMTRyIpVxH1g" Date: Fri, 18 Jan 2008 15:43:00 -0000 Message-Id: <1200670954.10815.1.camel@gargoyle> Mime-Version: 1.0 X-Mailer: Evolution 2.12.1 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-01/txt/msg00473.txt.bz2 --=-lAnroNiqzMTRyIpVxH1g Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 225 > 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 --=-lAnroNiqzMTRyIpVxH1g Content-Disposition: attachment; filename=registers-dfp.diff Content-Type: text/x-patch; name=registers-dfp.diff; charset=utf-8 Content-Transfer-Encoding: 7bit Content-length: 17514 2008-01-18 Luis Machado * 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 . */ + +/* 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 . + +# 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 @@ + 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 @@ + 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 @@ + + + + + --=-lAnroNiqzMTRyIpVxH1g--