diff options
-rw-r--r-- | gdb/ChangeLog | 22 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 6 | ||||
-rw-r--r-- | gdb/ppc-tdep.h | 4 | ||||
-rw-r--r-- | gdb/rs6000-tdep.c | 108 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/altivec-regs.exp | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/powerpc-vector-regs.c | 59 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/powerpc-vector-regs.exp | 62 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/vsx-regs.exp | 3 |
10 files changed, 279 insertions, 5 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b0971d1..384792c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2019-01-14 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> + + * ppc-tdep.h (struct gdbarch_tdep) <ppc_v0_alias_regnum>: New + field. + * rs6000-tdep.c: Include reggroups.h. + (IS_V_ALIAS_PSEUDOREG): Define. + (rs6000_register_name): Return names for the "vX" aliases. + (rs6000_pseudo_register_type): Return type for the "vX" aliases. + (rs6000_pseudo_register_reggroup_p): Restore. Handle "vX" + aliases. Call default_register_reggroup_p for all other + pseudo-registers. + (v_alias_pseudo_register_read, v_alias_pseudo_register_write): + New functions. + (rs6000_pseudo_register_read, rs6000_pseudo_register_write): + Handle "vX" aliases. + (v_alias_pseudo_register_collect): New function. + (rs6000_ax_pseudo_register_collect): Handle "vX" aliases. + (rs6000_gdbarch_init): Initialize "vX" aliases as + pseudo-registers. Restore registration of + rs6000_pseudo_register_reggroup_p with + set_tdesc_pseudo_register_reggroup_p. + 2019-01-13 Max Filippov <jcmvbkbc@gmail.com> * xtensa-linux-tdep.c (xtensa_linux_init_abi): Update diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 9eb75e7..eec6e3e 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2019-01-14 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> + + * gdb.texinfo (PowerPC Features): Document the alias + pseudo-registers for the org.gnu.gdb.power.altivec feature. + 2019-01-09 Simon Marchi <simon.marchi@ericsson.com> * gdb.texinfo (Print Settings): Remove mention of specific diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 4a00834..064ac90 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -43322,8 +43322,10 @@ The @samp{org.gnu.gdb.power.fpu} feature is optional. It should contain registers @samp{f0} through @samp{f31} and @samp{fpscr}. The @samp{org.gnu.gdb.power.altivec} feature is optional. It should -contain registers @samp{vr0} through @samp{vr31}, @samp{vscr}, -and @samp{vrsave}. +contain registers @samp{vr0} through @samp{vr31}, @samp{vscr}, and +@samp{vrsave}. @value{GDBN} will define pseudo-registers @samp{v0} +through @samp{v31} as aliases for the corresponding @samp{vrX} +registers. The @samp{org.gnu.gdb.power.vsx} feature is optional. It should contain registers @samp{vs0h} through @samp{vs31h}. @value{GDBN} will diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h index ff3c35ee..9297fe2 100644 --- a/gdb/ppc-tdep.h +++ b/gdb/ppc-tdep.h @@ -244,6 +244,10 @@ struct gdbarch_tdep int ppc_vr0_regnum; /* First AltiVec register. */ int ppc_vrsave_regnum; /* Last AltiVec register. */ + /* Altivec pseudo-register vX aliases for the raw vrX + registers. */ + int ppc_v0_alias_regnum; + /* SPE registers. */ int ppc_ev0_upper_regnum; /* First GPR upper half register. */ int ppc_ev0_regnum; /* First ev register. */ diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 53da2cc..e875ad9 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -36,6 +36,7 @@ #include "infcall.h" #include "sim-regno.h" #include "gdb/sim-ppc.h" +#include "reggroups.h" #include "dwarf2-frame.h" #include "target-descriptions.h" #include "user-regs.h" @@ -95,6 +96,13 @@ && (regnum) >= (tdep)->ppc_dl0_regnum \ && (regnum) < (tdep)->ppc_dl0_regnum + 16) +/* Determine if regnum is a "vX" alias for the raw "vrX" vector + registers. */ +#define IS_V_ALIAS_PSEUDOREG(tdep, regnum) (\ + (tdep)->ppc_v0_alias_regnum >= 0 \ + && (regnum) >= (tdep)->ppc_v0_alias_regnum \ + && (regnum) < (tdep)->ppc_v0_alias_regnum + ppc_num_vrs) + /* Determine if regnum is a POWER7 VSX register. */ #define IS_VSX_PSEUDOREG(tdep, regnum) ((tdep)->ppc_vsr0_regnum >= 0 \ && (regnum) >= (tdep)->ppc_vsr0_regnum \ @@ -2370,6 +2378,18 @@ rs6000_register_name (struct gdbarch *gdbarch, int regno) return dfp128_regnames[regno - tdep->ppc_dl0_regnum]; } + /* Check if this is a vX alias for a raw vrX vector register. */ + if (IS_V_ALIAS_PSEUDOREG (tdep, regno)) + { + static const char *const vector_alias_regnames[] = { + "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", + "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", + "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" + }; + return vector_alias_regnames[regno - tdep->ppc_v0_alias_regnum]; + } + /* Check if this is a VSX pseudo-register. */ if (IS_VSX_PSEUDOREG (tdep, regno)) { @@ -2460,6 +2480,11 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum) || IS_CDFP_PSEUDOREG (tdep, regnum)) /* PPC decimal128 pseudo-registers. */ return builtin_type (gdbarch)->builtin_declong; + else if (IS_V_ALIAS_PSEUDOREG (tdep, regnum)) + return gdbarch_register_type (gdbarch, + tdep->ppc_vr0_regnum + + (regnum + - tdep->ppc_v0_alias_regnum)); else if (IS_VSX_PSEUDOREG (tdep, regnum) || IS_CVSX_PSEUDOREG (tdep, regnum)) /* POWER7 VSX pseudo-registers. */ @@ -2475,6 +2500,24 @@ rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum) gdbarch_register_name (gdbarch, regnum), regnum); } +/* Check if REGNUM is a member of REGGROUP. We only need to handle + the vX aliases for the vector registers by always returning false + to avoid duplicated information in "info register vector/all", + since the raw vrX registers will already show in these cases. For + other pseudo-registers we use the default membership function. */ + +static int +rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + struct reggroup *group) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (IS_V_ALIAS_PSEUDOREG (tdep, regnum)) + return 0; + else + return default_register_reggroup_p (gdbarch, regnum, group); +} + /* The register format for RS/6000 floating point registers is always double, we need a conversion if the memory format is float. */ @@ -2717,6 +2760,35 @@ dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, } } +/* Read method for the vX aliases for the raw vrX registers. */ + +static enum register_status +v_alias_pseudo_register_read (struct gdbarch *gdbarch, + readable_regcache *regcache, int reg_nr, + gdb_byte *buffer) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr)); + + return regcache->raw_read (tdep->ppc_vr0_regnum + + (reg_nr - tdep->ppc_v0_alias_regnum), + buffer); +} + +/* Write method for the vX aliases for the raw vrX registers. */ + +static void +v_alias_pseudo_register_write (struct gdbarch *gdbarch, + struct regcache *regcache, + int reg_nr, const gdb_byte *buffer) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr)); + + regcache->raw_write (tdep->ppc_vr0_regnum + + (reg_nr - tdep->ppc_v0_alias_regnum), buffer); +} + /* Read method for POWER7 VSX pseudo-registers. */ static enum register_status vsx_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, @@ -2886,6 +2958,9 @@ rs6000_pseudo_register_read (struct gdbarch *gdbarch, else if (IS_DFP_PSEUDOREG (tdep, reg_nr) || IS_CDFP_PSEUDOREG (tdep, reg_nr)) return dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); + else if (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr)) + return v_alias_pseudo_register_read (gdbarch, regcache, reg_nr, + buffer); else if (IS_VSX_PSEUDOREG (tdep, reg_nr) || IS_CVSX_PSEUDOREG (tdep, reg_nr)) return vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer); @@ -2914,6 +2989,8 @@ rs6000_pseudo_register_write (struct gdbarch *gdbarch, else if (IS_DFP_PSEUDOREG (tdep, reg_nr) || IS_CDFP_PSEUDOREG (tdep, reg_nr)) dfp_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); + else if (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr)) + v_alias_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); else if (IS_VSX_PSEUDOREG (tdep, reg_nr) || IS_CVSX_PSEUDOREG (tdep, reg_nr)) vsx_pseudo_register_write (gdbarch, regcache, reg_nr, buffer); @@ -2954,6 +3031,20 @@ dfp_ax_pseudo_register_collect (struct gdbarch *gdbarch, ax_reg_mask (ax, fp0 + 2 * reg_index + 1); } +/* Set the register mask in AX with the raw vector register that + corresponds to its REG_NR alias. */ + +static void +v_alias_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, int reg_nr) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr)); + + ax_reg_mask (ax, tdep->ppc_vr0_regnum + + (reg_nr - tdep->ppc_v0_alias_regnum)); +} + /* Set the register mask in AX with the registers that form the VSX or checkpointed VSX pseudo-register REG_NR. */ @@ -3034,6 +3125,10 @@ rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch, { dfp_ax_pseudo_register_collect (gdbarch, ax, reg_nr); } + else if (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr)) + { + v_alias_pseudo_register_collect (gdbarch, ax, reg_nr); + } else if (IS_VSX_PSEUDOREG (tdep, reg_nr) || IS_CVSX_PSEUDOREG (tdep, reg_nr)) { @@ -6891,7 +6986,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) else tdep->lr_frame_offset = 4; - if (have_spe || have_dfp || have_vsx || have_htm_fpu || have_htm_vsx) + if (have_spe || have_dfp || have_altivec + || have_vsx || have_htm_fpu || have_htm_vsx) { set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, @@ -6910,6 +7006,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) num_pseudoregs += 32; if (have_dfp) num_pseudoregs += 16; + if (have_altivec) + num_pseudoregs += 32; if (have_vsx) /* Include both VSX and Extended FP registers. */ num_pseudoregs += 96; @@ -7022,6 +7120,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } set_tdesc_pseudo_register_type (gdbarch, rs6000_pseudo_register_type); + set_tdesc_pseudo_register_reggroup_p (gdbarch, + rs6000_pseudo_register_reggroup_p); tdesc_use_registers (gdbarch, tdesc, tdesc_data); /* Override the normal target description method to make the SPE upper @@ -7031,6 +7131,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Choose register numbers for all supported pseudo-registers. */ tdep->ppc_ev0_regnum = -1; tdep->ppc_dl0_regnum = -1; + tdep->ppc_v0_alias_regnum = -1; tdep->ppc_vsr0_regnum = -1; tdep->ppc_efpr0_regnum = -1; tdep->ppc_cdl0_regnum = -1; @@ -7049,6 +7150,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->ppc_dl0_regnum = cur_reg; cur_reg += 16; } + if (have_altivec) + { + tdep->ppc_v0_alias_regnum = cur_reg; + cur_reg += 32; + } if (have_vsx) { tdep->ppc_vsr0_regnum = cur_reg; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 621362f..af132ff 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,14 @@ 2019-01-14 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> + * gdb.arch/vsx-regs.exp: Add tests that use the vector register + aliases. + * gdb.arch/altivec-regs.exp: Likewise. Fix indentation of two + tests. + * gdb.arch/powerpc-vector-regs.c: New file. + * gdb.arch/powerpc-vector-regs.exp: New file. + +2019-01-14 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> + * gdb.arch/altivec-regs.exp: Fix the list passed to gdb_expect_list when testing "info vector". diff --git a/gdb/testsuite/gdb.arch/altivec-regs.exp b/gdb/testsuite/gdb.arch/altivec-regs.exp index d230392..a7b2aec 100644 --- a/gdb/testsuite/gdb.arch/altivec-regs.exp +++ b/gdb/testsuite/gdb.arch/altivec-regs.exp @@ -91,7 +91,8 @@ set vector_register ".uint128 = 0x1000000010000000100000001, v4_float = .0x0, 0x } for {set i 0} {$i < 32} {incr i 1} { - gdb_test "info reg vr$i" "vr$i.*$vector_register" "info reg vr$i" + gdb_test "info reg vr$i" "vr$i.*$vector_register" "info reg vr$i" + gdb_test "info reg v$i" "v$i.*$vector_register" "info reg v$i" } gdb_test "info reg vrsave" "vrsave.*0x1\[ \t\]+1" "info reg vrsave" @@ -110,7 +111,8 @@ if {$endianness == "big"} { } for {set i 0} {$i < 32} {incr i 1} { - gdb_test "print \$vr$i" ".* = $decimal_vector" "print vr$i" + gdb_test "print \$vr$i" ".* = $decimal_vector" "print vr$i" + gdb_test "print \$v$i" ".* = $decimal_vector" "print v$i" } gdb_test "print \$vrsave" ".* = 1" "print vrsave" diff --git a/gdb/testsuite/gdb.arch/powerpc-vector-regs.c b/gdb/testsuite/gdb.arch/powerpc-vector-regs.c new file mode 100644 index 0000000..925f0d7 --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-vector-regs.c @@ -0,0 +1,59 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright (C) 2019 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/>. */ + +/* Write bytes with values ranging from 0 to 31 to each byte of each + corresponding vector register. */ +int main (void) +{ + asm volatile ("vspltisb 0, 0" : : : "v0"); + asm volatile ("vspltisb 1, 1" : : : "v1"); + + asm volatile ("vaddubm 2, 1, 1" : : : "v2"); + asm volatile ("vaddubm 3, 2, 1" : : : "v3"); + asm volatile ("vaddubm 4, 3, 1" : : : "v4"); + asm volatile ("vaddubm 5, 4, 1" : : : "v5"); + asm volatile ("vaddubm 6, 5, 1" : : : "v6"); + asm volatile ("vaddubm 7, 6, 1" : : : "v7"); + asm volatile ("vaddubm 8, 7, 1" : : : "v8"); + asm volatile ("vaddubm 9, 8, 1" : : : "v9"); + asm volatile ("vaddubm 10, 9, 1" : : : "v10"); + asm volatile ("vaddubm 11, 10, 1" : : : "v11"); + asm volatile ("vaddubm 12, 11, 1" : : : "v12"); + asm volatile ("vaddubm 13, 12, 1" : : : "v13"); + asm volatile ("vaddubm 14, 13, 1" : : : "v14"); + asm volatile ("vaddubm 15, 14, 1" : : : "v15"); + asm volatile ("vaddubm 16, 15, 1" : : : "v16"); + asm volatile ("vaddubm 17, 16, 1" : : : "v17"); + asm volatile ("vaddubm 18, 17, 1" : : : "v18"); + asm volatile ("vaddubm 19, 18, 1" : : : "v19"); + asm volatile ("vaddubm 20, 19, 1" : : : "v20"); + asm volatile ("vaddubm 21, 20, 1" : : : "v21"); + asm volatile ("vaddubm 22, 21, 1" : : : "v22"); + asm volatile ("vaddubm 23, 22, 1" : : : "v23"); + asm volatile ("vaddubm 24, 23, 1" : : : "v24"); + asm volatile ("vaddubm 25, 24, 1" : : : "v25"); + asm volatile ("vaddubm 26, 25, 1" : : : "v26"); + asm volatile ("vaddubm 27, 26, 1" : : : "v27"); + asm volatile ("vaddubm 28, 27, 1" : : : "v28"); + asm volatile ("vaddubm 29, 28, 1" : : : "v29"); + asm volatile ("vaddubm 30, 29, 1" : : : "v30"); + asm volatile ("vaddubm 31, 30, 1" : : : "v31"); + + asm volatile ("nop"); // marker + + return 0; +} diff --git a/gdb/testsuite/gdb.arch/powerpc-vector-regs.exp b/gdb/testsuite/gdb.arch/powerpc-vector-regs.exp new file mode 100644 index 0000000..fdf7c56 --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-vector-regs.exp @@ -0,0 +1,62 @@ +# Copyright (C) 2019 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/>. + +# This file is part of the gdb testsuite. + +# Test vector register access on Power. The inferior executes +# instructions that fill the vector registers with values ranging from +# 0 to 31 in each of the 16 bytes of each corresponding register, and +# we then check if gdb sees these same values. + +if {![istarget "powerpc*"] || [skip_altivec_tests]} { + verbose "Skipping PowerPC vector register tests." + return +} + +standard_testfile + +if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable {debug}] != "" } { + untested "vector register tests for PowerPC" + return +} + +# Check if our test binary can actually run on this processor. +clean_restart ${binfile} + +gdb_run_cmd + +gdb_test_multiple "" "wait for exit" { + -re ".*Illegal instruction.*${gdb_prompt} $" { + unsupported "vector register tests for PowerPC" + return + } + -re ".*$inferior_exited_re normally.*${gdb_prompt} $" { + } +} + +# Run the actual test. +clean_restart ${binfile} + +gdb_breakpoint [gdb_get_line_number "marker"] + +gdb_run_cmd + +# Wait for the prompt. +gdb_test "" "Breakpoint.*at.*" "wait for prompt" + +for {set i 0} {$i < 32} {incr i 1} { + gdb_test "p/z \$vr$i.uint128" ".* = 0x(0?[format %x $i]){16}.*" + gdb_test "p/z \$v$i.uint128" ".* = 0x(0?[format %x $i]){16}.*" +} diff --git a/gdb/testsuite/gdb.arch/vsx-regs.exp b/gdb/testsuite/gdb.arch/vsx-regs.exp index 2454aee..d2fa612 100644 --- a/gdb/testsuite/gdb.arch/vsx-regs.exp +++ b/gdb/testsuite/gdb.arch/vsx-regs.exp @@ -136,6 +136,7 @@ for {set i 32} {$i < 64} {incr i 1} { for {set i 0} {$i < 32} {incr i 1} { gdb_test "info reg vr$i" "vr$i.*$vector_register3_vr" "info reg vr$i" + gdb_test "info reg v$i" "v$i.*$vector_register3_vr" "info reg v$i" } # Create a core file. We create the core file before the F32~F63/VR0~VR31 test @@ -155,6 +156,7 @@ for {set i 32} {$i < 64} {incr i 1} { for {set i 0} {$i < 32} {incr i 1} { gdb_test "info reg vr$i" "vr$i.*$vector_register1_vr" "info reg vr$i (doubleword 0)" + gdb_test "info reg v$i" "v$i.*$vector_register1_vr" "info reg v$i (doubleword 0)" } # 2: Set VR0~VR31 registers and check if it reflects on F32~F63. @@ -170,6 +172,7 @@ for {set i 32} {$i < 64} {incr i 1} { for {set i 0} {$i < 32} {incr i 1} { gdb_test "info reg vr$i" "vr$i.*$vector_register2_vr" "info reg vr$i (doubleword 1)" + gdb_test "info reg v$i" "v$i.*$vector_register2_vr" "info reg v$i (doubleword 1)" } # Test reading the core file. |