diff mbox series

[v3] target/ppc: code motion from translate_init.c.inc to gdbstub.c

Message ID 20210414145947.30155-1-bruno.larsen@eldorado.org.br (mailing list archive)
State New, archived
Headers show
Series [v3] target/ppc: code motion from translate_init.c.inc to gdbstub.c | expand

Commit Message

Bruno Larsen (billionai) April 14, 2021, 2:59 p.m. UTC
All the code related to gdb has been moved from translate_init.c.inc
file to the gdbstub.c file, where it makes more sense.

This new version puts the prototypes in internal.h, to not expose
them unnecessarily.

Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
Suggested-by: Fabiano Rosas <farosas@linux.ibm.com>
---
 target/ppc/gdbstub.c            | 258 ++++++++++++++++++++++++++++++++
 target/ppc/internal.h           |   5 +
 target/ppc/translate_init.c.inc | 254 +------------------------------
 3 files changed, 264 insertions(+), 253 deletions(-)

Comments

Richard Henderson April 14, 2021, 8:09 p.m. UTC | #1
On 4/14/21 7:59 AM, Bruno Larsen (billionai) wrote:
> All the code related to gdb has been moved from translate_init.c.inc
> file to the gdbstub.c file, where it makes more sense.
> 
> This new version puts the prototypes in internal.h, to not expose
> them unnecessarily.
> 
> Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
> Suggested-by: Fabiano Rosas <farosas@linux.ibm.com>
> ---
>   target/ppc/gdbstub.c            | 258 ++++++++++++++++++++++++++++++++
>   target/ppc/internal.h           |   5 +
>   target/ppc/translate_init.c.inc | 254 +------------------------------
>   3 files changed, 264 insertions(+), 253 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

> +void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
> +{
> +
> +    if (pcc->insns_flags & PPC_FLOAT) {

Watch the extra blank lines.


r~
David Gibson April 16, 2021, 3:44 a.m. UTC | #2
On Wed, Apr 14, 2021 at 01:09:19PM -0700, Richard Henderson wrote:
> On 4/14/21 7:59 AM, Bruno Larsen (billionai) wrote:
> > All the code related to gdb has been moved from translate_init.c.inc
> > file to the gdbstub.c file, where it makes more sense.
> > 
> > This new version puts the prototypes in internal.h, to not expose
> > them unnecessarily.
> > 
> > Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
> > Suggested-by: Fabiano Rosas <farosas@linux.ibm.com>
> > ---
> >   target/ppc/gdbstub.c            | 258 ++++++++++++++++++++++++++++++++
> >   target/ppc/internal.h           |   5 +
> >   target/ppc/translate_init.c.inc | 254 +------------------------------
> >   3 files changed, 264 insertions(+), 253 deletions(-)
> 
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Applied to ppc-for-6.1, thanks.

> 
> > +void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
> > +{
> > +
> > +    if (pcc->insns_flags & PPC_FLOAT) {
> 
> Watch the extra blank lines.

Fixed in my tree.
Fabiano Rosas April 26, 2021, 3:50 p.m. UTC | #3
David Gibson <david@gibson.dropbear.id.au> writes:

> On Wed, Apr 14, 2021 at 01:09:19PM -0700, Richard Henderson wrote:
>> On 4/14/21 7:59 AM, Bruno Larsen (billionai) wrote:
>> > All the code related to gdb has been moved from translate_init.c.inc
>> > file to the gdbstub.c file, where it makes more sense.
>> > 
>> > This new version puts the prototypes in internal.h, to not expose
>> > them unnecessarily.
>> > 
>> > Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
>> > Suggested-by: Fabiano Rosas <farosas@linux.ibm.com>
>> > ---
>> >   target/ppc/gdbstub.c            | 258 ++++++++++++++++++++++++++++++++
>> >   target/ppc/internal.h           |   5 +
>> >   target/ppc/translate_init.c.inc | 254 +------------------------------
>> >   3 files changed, 264 insertions(+), 253 deletions(-)
>> 
>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
> Applied to ppc-for-6.1, thanks.


The prototypes moved to internal.h in v3 so gdbstub.c needs to include
it now. The linux-user build is breaking with:

$ ../configure --target-list=ppc64le-linux-user
$ make -j$(nproc)
(...)
[316/959] Compiling C object libqemu-ppc64le-linux-user.fa.p/target_ppc_gdbstub.c.o                       
FAILED: libqemu-ppc64le-linux-user.fa.p/target_ppc_gdbstub.c.o                                            
cc -Ilibqemu-ppc64le-linux-user.fa.p -I. -I.. -Itarget/ppc -I../target/ppc -I../linux-user/host/x86_64 -Ilinux-user -I../linux-user -Ilinux-user/ppc -I../linux-user/ppc -I../capstone/include/capstone -Itrace -Iqap
i -Iui/shader -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -fdiagnostics-color=auto -pipe -Wall -Winvalid-pch -Werror -std=gnu99 -O2 -g -isystem /home/fabiano/kvm/qemu-patch-testing/linux-headers -isystem
 linux-headers -iquote . -iquote /home/fabiano/kvm/qemu-patch-testing -iquote /home/fabiano/kvm/qemu-patch-testing/include -iquote /home/fabiano/kvm/qemu-patch-testing/disas/libvixl -iquote /home/fabiano/kvm/qemu-
patch-testing/tcg/i386 -iquote /home/fabiano/kvm/qemu-patch-testing/accel/tcg -pthread -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes
 -Wredundant-decls -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -Wold-style-declaration -Wold-style-definition -Wtype-limits -Wformat-security -Wformat-y2k -Winit-self -Wig
nored-qualifiers -Wempty-body -Wnested-externs -Wendif-labels -Wexpansion-to-defined -Wimplicit-fallthrough=2 -Wno-missing-include-dirs -Wno-shift-negative-value -Wno-psabi -fstack-protector-strong -fPIC -isystem.
./linux-headers -isystemlinux-headers -DNEED_CPU_H '-DCONFIG_TARGET="ppc64le-linux-user-config-target.h"' '-DCONFIG_DEVICES="ppc64le-linux-user-config-devices.h"' -MD -MQ libqemu-ppc64le-linux-user.fa.p/target_ppc
_gdbstub.c.o -MF libqemu-ppc64le-linux-user.fa.p/target_ppc_gdbstub.c.o.d -o libqemu-ppc64le-linux-user.fa.p/target_ppc_gdbstub.c.o -c ../target/ppc/gdbstub.c                                                       
../target/ppc/gdbstub.c:615:8: error: no previous prototype for ‘ppc_gdb_arch_name’ [-Werror=missing-prototypes]                                                                                                     
  615 | gchar *ppc_gdb_arch_name(CPUState *cs)                                                            
      |        ^~~~~~~~~~~~~~~~~                                                                          
../target/ppc/gdbstub.c:624:6: error: no previous prototype for ‘ppc_gdb_init’ [-Werror=missing-prototypes]                                                                                                          
  624 | void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)                
      |      ^~~~~~~~~~~~                                                                                 
cc1: all warnings being treated as errors

>> > +void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
>> > +{
>> > +
>> > +    if (pcc->insns_flags & PPC_FLOAT) {
>> 
>> Watch the extra blank lines.
>
> Fixed in my tree.
David Gibson April 27, 2021, 1:52 a.m. UTC | #4
On Mon, Apr 26, 2021 at 12:50:54PM -0300, Fabiano Rosas wrote:
> David Gibson <david@gibson.dropbear.id.au> writes:
> 
> > On Wed, Apr 14, 2021 at 01:09:19PM -0700, Richard Henderson wrote:
> >> On 4/14/21 7:59 AM, Bruno Larsen (billionai) wrote:
> >> > All the code related to gdb has been moved from translate_init.c.inc
> >> > file to the gdbstub.c file, where it makes more sense.
> >> > 
> >> > This new version puts the prototypes in internal.h, to not expose
> >> > them unnecessarily.
> >> > 
> >> > Signed-off-by: Bruno Larsen (billionai) <bruno.larsen@eldorado.org.br>
> >> > Suggested-by: Fabiano Rosas <farosas@linux.ibm.com>
> >> > ---
> >> >   target/ppc/gdbstub.c            | 258 ++++++++++++++++++++++++++++++++
> >> >   target/ppc/internal.h           |   5 +
> >> >   target/ppc/translate_init.c.inc | 254 +------------------------------
> >> >   3 files changed, 264 insertions(+), 253 deletions(-)
> >> 
> >> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> >
> > Applied to ppc-for-6.1, thanks.
> 
> 
> The prototypes moved to internal.h in v3 so gdbstub.c needs to include
> it now. The linux-user build is breaking with:

Thanks for the report.  I've pulled this from ppc-for-6.1 and I'll
await the next spin.

> 
> $ ../configure --target-list=ppc64le-linux-user
> $ make -j$(nproc)
> (...)
> [316/959] Compiling C object libqemu-ppc64le-linux-user.fa.p/target_ppc_gdbstub.c.o                       
> FAILED: libqemu-ppc64le-linux-user.fa.p/target_ppc_gdbstub.c.o                                            
> cc -Ilibqemu-ppc64le-linux-user.fa.p -I. -I.. -Itarget/ppc -I../target/ppc -I../linux-user/host/x86_64 -Ilinux-user -I../linux-user -Ilinux-user/ppc -I../linux-user/ppc -I../capstone/include/capstone -Itrace -Iqap
> i -Iui/shader -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -fdiagnostics-color=auto -pipe -Wall -Winvalid-pch -Werror -std=gnu99 -O2 -g -isystem /home/fabiano/kvm/qemu-patch-testing/linux-headers -isystem
>  linux-headers -iquote . -iquote /home/fabiano/kvm/qemu-patch-testing -iquote /home/fabiano/kvm/qemu-patch-testing/include -iquote /home/fabiano/kvm/qemu-patch-testing/disas/libvixl -iquote /home/fabiano/kvm/qemu-
> patch-testing/tcg/i386 -iquote /home/fabiano/kvm/qemu-patch-testing/accel/tcg -pthread -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes
>  -Wredundant-decls -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -Wold-style-declaration -Wold-style-definition -Wtype-limits -Wformat-security -Wformat-y2k -Winit-self -Wig
> nored-qualifiers -Wempty-body -Wnested-externs -Wendif-labels -Wexpansion-to-defined -Wimplicit-fallthrough=2 -Wno-missing-include-dirs -Wno-shift-negative-value -Wno-psabi -fstack-protector-strong -fPIC -isystem.
> ./linux-headers -isystemlinux-headers -DNEED_CPU_H '-DCONFIG_TARGET="ppc64le-linux-user-config-target.h"' '-DCONFIG_DEVICES="ppc64le-linux-user-config-devices.h"' -MD -MQ libqemu-ppc64le-linux-user.fa.p/target_ppc
> _gdbstub.c.o -MF libqemu-ppc64le-linux-user.fa.p/target_ppc_gdbstub.c.o.d -o libqemu-ppc64le-linux-user.fa.p/target_ppc_gdbstub.c.o -c ../target/ppc/gdbstub.c                                                       
> ../target/ppc/gdbstub.c:615:8: error: no previous prototype for ‘ppc_gdb_arch_name’ [-Werror=missing-prototypes]                                                                                                     
>   615 | gchar *ppc_gdb_arch_name(CPUState *cs)                                                            
>       |        ^~~~~~~~~~~~~~~~~                                                                          
> ../target/ppc/gdbstub.c:624:6: error: no previous prototype for ‘ppc_gdb_init’ [-Werror=missing-prototypes]                                                                                                          
>   624 | void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)                
>       |      ^~~~~~~~~~~~                                                                                 
> cc1: all warnings being treated as errors
> 
> >> > +void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
> >> > +{
> >> > +
> >> > +    if (pcc->insns_flags & PPC_FLOAT) {
> >> 
> >> Watch the extra blank lines.
> >
> > Fixed in my tree.
>
diff mbox series

Patch

diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c
index c28319fb97..67e8a3175f 100644
--- a/target/ppc/gdbstub.c
+++ b/target/ppc/gdbstub.c
@@ -20,6 +20,7 @@ 
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/gdbstub.h"
+#include "exec/helper-proto.h"
 
 static int ppc_gdb_register_len_apple(int n)
 {
@@ -387,3 +388,260 @@  const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name)
     return NULL;
 }
 #endif
+
+static bool avr_need_swap(CPUPPCState *env)
+{
+#ifdef HOST_WORDS_BIGENDIAN
+    return msr_le;
+#else
+    return !msr_le;
+#endif
+}
+
+#if !defined(CONFIG_USER_ONLY)
+static int gdb_find_spr_idx(CPUPPCState *env, int n)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
+        ppc_spr_t *spr = &env->spr_cb[i];
+
+        if (spr->name && spr->gdb_id == n) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
+{
+    int reg;
+    int len;
+
+    reg = gdb_find_spr_idx(env, n);
+    if (reg < 0) {
+        return 0;
+    }
+
+    len = TARGET_LONG_SIZE;
+    gdb_get_regl(buf, env->spr[reg]);
+    ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
+    return len;
+}
+
+static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+    int reg;
+    int len;
+
+    reg = gdb_find_spr_idx(env, n);
+    if (reg < 0) {
+        return 0;
+    }
+
+    len = TARGET_LONG_SIZE;
+    ppc_maybe_bswap_register(env, mem_buf, len);
+    env->spr[reg] = ldn_p(mem_buf, len);
+
+    return len;
+}
+#endif
+
+static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
+{
+    uint8_t *mem_buf;
+    if (n < 32) {
+        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
+        mem_buf = gdb_get_reg_ptr(buf, 8);
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        return 8;
+    }
+    if (n == 32) {
+        gdb_get_reg32(buf, env->fpscr);
+        mem_buf = gdb_get_reg_ptr(buf, 4);
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+    if (n < 32) {
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
+        return 8;
+    }
+    if (n == 32) {
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
+{
+    uint8_t *mem_buf;
+
+    if (n < 32) {
+        ppc_avr_t *avr = cpu_avr_ptr(env, n);
+        if (!avr_need_swap(env)) {
+            gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]);
+        } else {
+            gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]);
+        }
+        mem_buf = gdb_get_reg_ptr(buf, 16);
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        ppc_maybe_bswap_register(env, mem_buf + 8, 8);
+        return 16;
+    }
+    if (n == 32) {
+        gdb_get_reg32(buf, helper_mfvscr(env));
+        mem_buf = gdb_get_reg_ptr(buf, 4);
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        return 4;
+    }
+    if (n == 33) {
+        gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
+        mem_buf = gdb_get_reg_ptr(buf, 4);
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+    if (n < 32) {
+        ppc_avr_t *avr = cpu_avr_ptr(env, n);
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        ppc_maybe_bswap_register(env, mem_buf + 8, 8);
+        if (!avr_need_swap(env)) {
+            avr->u64[0] = ldq_p(mem_buf);
+            avr->u64[1] = ldq_p(mem_buf + 8);
+        } else {
+            avr->u64[1] = ldq_p(mem_buf);
+            avr->u64[0] = ldq_p(mem_buf + 8);
+        }
+        return 16;
+    }
+    if (n == 32) {
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        helper_mtvscr(env, ldl_p(mem_buf));
+        return 4;
+    }
+    if (n == 33) {
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
+{
+    if (n < 32) {
+#if defined(TARGET_PPC64)
+        gdb_get_reg32(buf, env->gpr[n] >> 32);
+        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
+#else
+        gdb_get_reg32(buf, env->gprh[n]);
+#endif
+        return 4;
+    }
+    if (n == 32) {
+        gdb_get_reg64(buf, env->spe_acc);
+        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
+        return 8;
+    }
+    if (n == 33) {
+        gdb_get_reg32(buf, env->spe_fscr);
+        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+    if (n < 32) {
+#if defined(TARGET_PPC64)
+        target_ulong lo = (uint32_t)env->gpr[n];
+        target_ulong hi;
+
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+
+        hi = (target_ulong)ldl_p(mem_buf) << 32;
+        env->gpr[n] = lo | hi;
+#else
+        env->gprh[n] = ldl_p(mem_buf);
+#endif
+        return 4;
+    }
+    if (n == 32) {
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        env->spe_acc = ldq_p(mem_buf);
+        return 8;
+    }
+    if (n == 33) {
+        ppc_maybe_bswap_register(env, mem_buf, 4);
+        env->spe_fscr = ldl_p(mem_buf);
+        return 4;
+    }
+    return 0;
+}
+
+static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
+{
+    if (n < 32) {
+        gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
+        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
+        return 8;
+    }
+    return 0;
+}
+
+static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
+{
+    if (n < 32) {
+        ppc_maybe_bswap_register(env, mem_buf, 8);
+        *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
+        return 8;
+    }
+    return 0;
+}
+
+gchar *ppc_gdb_arch_name(CPUState *cs)
+{
+#if defined(TARGET_PPC64)
+    return g_strdup("powerpc:common64");
+#else
+    return g_strdup("powerpc:common");
+#endif
+}
+
+void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
+{
+
+    if (pcc->insns_flags & PPC_FLOAT) {
+        gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
+                                 33, "power-fpu.xml", 0);
+    }
+    if (pcc->insns_flags & PPC_ALTIVEC) {
+        gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
+                                 34, "power-altivec.xml", 0);
+    }
+    if (pcc->insns_flags & PPC_SPE) {
+        gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
+                                 34, "power-spe.xml", 0);
+    }
+    if (pcc->insns_flags2 & PPC2_VSX) {
+        gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
+                                 32, "power-vsx.xml", 0);
+    }
+#ifndef CONFIG_USER_ONLY
+    gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
+                             pcc->gdb_num_sprs, "power-spr.xml", 0);
+#endif
+}
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index d547448065..c401658e8d 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -215,4 +215,9 @@  void helper_compute_fprf_float128(CPUPPCState *env, float128 arg);
 void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
                                  MMUAccessType access_type,
                                  int mmu_idx, uintptr_t retaddr);
+
+/* gdbstub.c */
+void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
+gchar *ppc_gdb_arch_name(CPUState *cs);
+
 #endif /* PPC_INTERNAL_H */
diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc
index c03a7c4f52..80fef0b90d 100644
--- a/target/ppc/translate_init.c.inc
+++ b/target/ppc/translate_init.c.inc
@@ -9895,230 +9895,6 @@  static void dump_ppc_insns(CPUPPCState *env)
     }
 }
 #endif
-
-static bool avr_need_swap(CPUPPCState *env)
-{
-#ifdef HOST_WORDS_BIGENDIAN
-    return msr_le;
-#else
-    return !msr_le;
-#endif
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static int gdb_find_spr_idx(CPUPPCState *env, int n)
-{
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
-        ppc_spr_t *spr = &env->spr_cb[i];
-
-        if (spr->name && spr->gdb_id == n) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
-{
-    int reg;
-    int len;
-
-    reg = gdb_find_spr_idx(env, n);
-    if (reg < 0) {
-        return 0;
-    }
-
-    len = TARGET_LONG_SIZE;
-    gdb_get_regl(buf, env->spr[reg]);
-    ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
-    return len;
-}
-
-static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    int reg;
-    int len;
-
-    reg = gdb_find_spr_idx(env, n);
-    if (reg < 0) {
-        return 0;
-    }
-
-    len = TARGET_LONG_SIZE;
-    ppc_maybe_bswap_register(env, mem_buf, len);
-    env->spr[reg] = ldn_p(mem_buf, len);
-
-    return len;
-}
-#endif
-
-static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
-{
-    uint8_t *mem_buf;
-    if (n < 32) {
-        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
-        mem_buf = gdb_get_reg_ptr(buf, 8);
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        return 8;
-    }
-    if (n == 32) {
-        gdb_get_reg32(buf, env->fpscr);
-        mem_buf = gdb_get_reg_ptr(buf, 4);
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
-        return 8;
-    }
-    if (n == 32) {
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
-{
-    uint8_t *mem_buf;
-
-    if (n < 32) {
-        ppc_avr_t *avr = cpu_avr_ptr(env, n);
-        if (!avr_need_swap(env)) {
-            gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]);
-        } else {
-            gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]);
-        }
-        mem_buf = gdb_get_reg_ptr(buf, 16);
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        ppc_maybe_bswap_register(env, mem_buf + 8, 8);
-        return 16;
-    }
-    if (n == 32) {
-        gdb_get_reg32(buf, helper_mfvscr(env));
-        mem_buf = gdb_get_reg_ptr(buf, 4);
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        return 4;
-    }
-    if (n == 33) {
-        gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
-        mem_buf = gdb_get_reg_ptr(buf, 4);
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        ppc_avr_t *avr = cpu_avr_ptr(env, n);
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        ppc_maybe_bswap_register(env, mem_buf + 8, 8);
-        if (!avr_need_swap(env)) {
-            avr->u64[0] = ldq_p(mem_buf);
-            avr->u64[1] = ldq_p(mem_buf + 8);
-        } else {
-            avr->u64[1] = ldq_p(mem_buf);
-            avr->u64[0] = ldq_p(mem_buf + 8);
-        }
-        return 16;
-    }
-    if (n == 32) {
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        helper_mtvscr(env, ldl_p(mem_buf));
-        return 4;
-    }
-    if (n == 33) {
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
-{
-    if (n < 32) {
-#if defined(TARGET_PPC64)
-        gdb_get_reg32(buf, env->gpr[n] >> 32);
-        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
-#else
-        gdb_get_reg32(buf, env->gprh[n]);
-#endif
-        return 4;
-    }
-    if (n == 32) {
-        gdb_get_reg64(buf, env->spe_acc);
-        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
-        return 8;
-    }
-    if (n == 33) {
-        gdb_get_reg32(buf, env->spe_fscr);
-        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-#if defined(TARGET_PPC64)
-        target_ulong lo = (uint32_t)env->gpr[n];
-        target_ulong hi;
-
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-
-        hi = (target_ulong)ldl_p(mem_buf) << 32;
-        env->gpr[n] = lo | hi;
-#else
-        env->gprh[n] = ldl_p(mem_buf);
-#endif
-        return 4;
-    }
-    if (n == 32) {
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        env->spe_acc = ldq_p(mem_buf);
-        return 8;
-    }
-    if (n == 33) {
-        ppc_maybe_bswap_register(env, mem_buf, 4);
-        env->spe_fscr = ldl_p(mem_buf);
-        return 4;
-    }
-    return 0;
-}
-
-static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
-{
-    if (n < 32) {
-        gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
-        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
-        return 8;
-    }
-    return 0;
-}
-
-static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        ppc_maybe_bswap_register(env, mem_buf, 8);
-        *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
-        return 8;
-    }
-    return 0;
-}
-
 static int ppc_fixup_cpu(PowerPCCPU *cpu)
 {
     CPUPPCState *env = &cpu->env;
@@ -10174,26 +9950,7 @@  static void ppc_cpu_realize(DeviceState *dev, Error **errp)
     }
     init_ppc_proc(cpu);
 
-    if (pcc->insns_flags & PPC_FLOAT) {
-        gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
-                                 33, "power-fpu.xml", 0);
-    }
-    if (pcc->insns_flags & PPC_ALTIVEC) {
-        gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
-                                 34, "power-altivec.xml", 0);
-    }
-    if (pcc->insns_flags & PPC_SPE) {
-        gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
-                                 34, "power-spe.xml", 0);
-    }
-    if (pcc->insns_flags2 & PPC2_VSX) {
-        gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
-                                 32, "power-vsx.xml", 0);
-    }
-#ifndef CONFIG_USER_ONLY
-    gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
-                             pcc->gdb_num_sprs, "power-spr.xml", 0);
-#endif
+    ppc_gdb_init(cs, pcc);
     qemu_init_vcpu(cs);
 
     pcc->parent_realize(dev, errp);
@@ -10835,15 +10592,6 @@  static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
     return pcc->pvr == pvr;
 }
 
-static gchar *ppc_gdb_arch_name(CPUState *cs)
-{
-#if defined(TARGET_PPC64)
-    return g_strdup("powerpc:common64");
-#else
-    return g_strdup("powerpc:common");
-#endif
-}
-
 static void ppc_disas_set_info(CPUState *cs, disassemble_info *info)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);