Browse Source

target/sparc: Restore 'gdb-xml/sparc64-fpu.xml'

Restore gdb-xml/sparc64-fpu.xml from mainstream binutils, tag
'binutils-2_46', found in the gdb/features/sparc/folder [*].

Extract sparc_fpu_gdb_write_register() out of
sparc_cpu_gdb_read_register() and sparc_fpu_gdb_write_register()
out of sparc_cpu_gdb_write_register(), taking care to update the
register indexes in the switch cases.

Register these helpers with a call to gdb_register_coprocessor()
in sparc_cpu_register_gdb_regs().

[*] https://sourceware.org/git/?p=binutils-gdb.git;a=tree;f=gdb/features/sparc;hb=refs/tags/binutils-2_46

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20260219191955.83815-13-philmd@linaro.org>
master
Philippe Mathieu-Daudé 6 months ago
parent
commit
85b4bcf3d5
  1. 2
      configs/targets/sparc64-linux-user.mak
  2. 2
      configs/targets/sparc64-softmmu.mak
  3. 50
      gdb-xml/sparc64-core.xml
  4. 59
      gdb-xml/sparc64-fpu.xml
  5. 86
      target/sparc/gdbstub.c

2
configs/targets/sparc64-linux-user.mak

@ -4,6 +4,6 @@ TARGET_ABI_DIR=sparc
TARGET_SYSTBL_ABI=common,64
TARGET_SYSTBL=syscall.tbl
TARGET_BIG_ENDIAN=y
TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-cp0.xml
TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-fpu.xml gdb-xml/sparc64-cp0.xml
TARGET_LONG_BITS=64
TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y

2
configs/targets/sparc64-softmmu.mak

@ -1,7 +1,7 @@
TARGET_ARCH=sparc64
TARGET_BASE_ARCH=sparc
TARGET_BIG_ENDIAN=y
TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-cp0.xml
TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-fpu.xml gdb-xml/sparc64-cp0.xml
TARGET_LONG_BITS=64
TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y

50
gdb-xml/sparc64-core.xml

@ -39,54 +39,4 @@
<reg name="i5" bitsize="64" type="uint64" regnum="29"/>
<reg name="fp" bitsize="64" type="uint64" regnum="30"/>
<reg name="i7" bitsize="64" type="uint64" regnum="31"/>
<reg name="f0" bitsize="32" type="ieee_single" regnum="32"/>
<reg name="f1" bitsize="32" type="ieee_single" regnum="33"/>
<reg name="f2" bitsize="32" type="ieee_single" regnum="34"/>
<reg name="f3" bitsize="32" type="ieee_single" regnum="35"/>
<reg name="f4" bitsize="32" type="ieee_single" regnum="36"/>
<reg name="f5" bitsize="32" type="ieee_single" regnum="37"/>
<reg name="f6" bitsize="32" type="ieee_single" regnum="38"/>
<reg name="f7" bitsize="32" type="ieee_single" regnum="39"/>
<reg name="f8" bitsize="32" type="ieee_single" regnum="40"/>
<reg name="f9" bitsize="32" type="ieee_single" regnum="41"/>
<reg name="f10" bitsize="32" type="ieee_single" regnum="42"/>
<reg name="f11" bitsize="32" type="ieee_single" regnum="43"/>
<reg name="f12" bitsize="32" type="ieee_single" regnum="44"/>
<reg name="f13" bitsize="32" type="ieee_single" regnum="45"/>
<reg name="f14" bitsize="32" type="ieee_single" regnum="46"/>
<reg name="f15" bitsize="32" type="ieee_single" regnum="47"/>
<reg name="f16" bitsize="32" type="ieee_single" regnum="48"/>
<reg name="f17" bitsize="32" type="ieee_single" regnum="49"/>
<reg name="f18" bitsize="32" type="ieee_single" regnum="50"/>
<reg name="f19" bitsize="32" type="ieee_single" regnum="51"/>
<reg name="f20" bitsize="32" type="ieee_single" regnum="52"/>
<reg name="f21" bitsize="32" type="ieee_single" regnum="53"/>
<reg name="f22" bitsize="32" type="ieee_single" regnum="54"/>
<reg name="f23" bitsize="32" type="ieee_single" regnum="55"/>
<reg name="f24" bitsize="32" type="ieee_single" regnum="56"/>
<reg name="f25" bitsize="32" type="ieee_single" regnum="57"/>
<reg name="f26" bitsize="32" type="ieee_single" regnum="58"/>
<reg name="f27" bitsize="32" type="ieee_single" regnum="59"/>
<reg name="f28" bitsize="32" type="ieee_single" regnum="60"/>
<reg name="f29" bitsize="32" type="ieee_single" regnum="61"/>
<reg name="f30" bitsize="32" type="ieee_single" regnum="62"/>
<reg name="f31" bitsize="32" type="ieee_single" regnum="63"/>
<reg name="f32" bitsize="64" type="ieee_double" regnum="64"/>
<reg name="f34" bitsize="64" type="ieee_double" regnum="65"/>
<reg name="f36" bitsize="64" type="ieee_double" regnum="66"/>
<reg name="f38" bitsize="64" type="ieee_double" regnum="67"/>
<reg name="f40" bitsize="64" type="ieee_double" regnum="68"/>
<reg name="f42" bitsize="64" type="ieee_double" regnum="69"/>
<reg name="f44" bitsize="64" type="ieee_double" regnum="70"/>
<reg name="f46" bitsize="64" type="ieee_double" regnum="71"/>
<reg name="f48" bitsize="64" type="ieee_double" regnum="72"/>
<reg name="f50" bitsize="64" type="ieee_double" regnum="73"/>
<reg name="f52" bitsize="64" type="ieee_double" regnum="74"/>
<reg name="f54" bitsize="64" type="ieee_double" regnum="75"/>
<reg name="f56" bitsize="64" type="ieee_double" regnum="76"/>
<reg name="f58" bitsize="64" type="ieee_double" regnum="77"/>
<reg name="f60" bitsize="64" type="ieee_double" regnum="78"/>
<reg name="f62" bitsize="64" type="ieee_double" regnum="79"/>
</feature>

59
gdb-xml/sparc64-fpu.xml

@ -0,0 +1,59 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2013-2026 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.sparc.fpu">
<reg name="f0" bitsize="32" type="ieee_single" regnum="32"/>
<reg name="f1" bitsize="32" type="ieee_single" regnum="33"/>
<reg name="f2" bitsize="32" type="ieee_single" regnum="34"/>
<reg name="f3" bitsize="32" type="ieee_single" regnum="35"/>
<reg name="f4" bitsize="32" type="ieee_single" regnum="36"/>
<reg name="f5" bitsize="32" type="ieee_single" regnum="37"/>
<reg name="f6" bitsize="32" type="ieee_single" regnum="38"/>
<reg name="f7" bitsize="32" type="ieee_single" regnum="39"/>
<reg name="f8" bitsize="32" type="ieee_single" regnum="40"/>
<reg name="f9" bitsize="32" type="ieee_single" regnum="41"/>
<reg name="f10" bitsize="32" type="ieee_single" regnum="42"/>
<reg name="f11" bitsize="32" type="ieee_single" regnum="43"/>
<reg name="f12" bitsize="32" type="ieee_single" regnum="44"/>
<reg name="f13" bitsize="32" type="ieee_single" regnum="45"/>
<reg name="f14" bitsize="32" type="ieee_single" regnum="46"/>
<reg name="f15" bitsize="32" type="ieee_single" regnum="47"/>
<reg name="f16" bitsize="32" type="ieee_single" regnum="48"/>
<reg name="f17" bitsize="32" type="ieee_single" regnum="49"/>
<reg name="f18" bitsize="32" type="ieee_single" regnum="50"/>
<reg name="f19" bitsize="32" type="ieee_single" regnum="51"/>
<reg name="f20" bitsize="32" type="ieee_single" regnum="52"/>
<reg name="f21" bitsize="32" type="ieee_single" regnum="53"/>
<reg name="f22" bitsize="32" type="ieee_single" regnum="54"/>
<reg name="f23" bitsize="32" type="ieee_single" regnum="55"/>
<reg name="f24" bitsize="32" type="ieee_single" regnum="56"/>
<reg name="f25" bitsize="32" type="ieee_single" regnum="57"/>
<reg name="f26" bitsize="32" type="ieee_single" regnum="58"/>
<reg name="f27" bitsize="32" type="ieee_single" regnum="59"/>
<reg name="f28" bitsize="32" type="ieee_single" regnum="60"/>
<reg name="f29" bitsize="32" type="ieee_single" regnum="61"/>
<reg name="f30" bitsize="32" type="ieee_single" regnum="62"/>
<reg name="f31" bitsize="32" type="ieee_single" regnum="63"/>
<reg name="f32" bitsize="64" type="ieee_double" regnum="64"/>
<reg name="f34" bitsize="64" type="ieee_double" regnum="65"/>
<reg name="f36" bitsize="64" type="ieee_double" regnum="66"/>
<reg name="f38" bitsize="64" type="ieee_double" regnum="67"/>
<reg name="f40" bitsize="64" type="ieee_double" regnum="68"/>
<reg name="f42" bitsize="64" type="ieee_double" regnum="69"/>
<reg name="f44" bitsize="64" type="ieee_double" regnum="70"/>
<reg name="f46" bitsize="64" type="ieee_double" regnum="71"/>
<reg name="f48" bitsize="64" type="ieee_double" regnum="72"/>
<reg name="f50" bitsize="64" type="ieee_double" regnum="73"/>
<reg name="f52" bitsize="64" type="ieee_double" regnum="74"/>
<reg name="f54" bitsize="64" type="ieee_double" regnum="75"/>
<reg name="f56" bitsize="64" type="ieee_double" regnum="76"/>
<reg name="f58" bitsize="64" type="ieee_double" regnum="77"/>
<reg name="f60" bitsize="64" type="ieee_double" regnum="78"/>
<reg name="f62" bitsize="64" type="ieee_double" regnum="79"/>
</feature>

86
target/sparc/gdbstub.c

@ -40,32 +40,40 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
/* register window */
return gdb_get_rega(mem_buf, env->regwptr[n - 8]);
}
return 0;
}
__attribute__((unused))
static int sparc_fpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
CPUSPARCState *env = cpu_env(cs);
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
if (n < 64) {
if (n < 32) {
/* fprs */
if (n & 1) {
return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
return gdb_get_reg32(mem_buf, env->fpr[n / 2].l.lower);
} else {
return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
return gdb_get_reg32(mem_buf, env->fpr[n / 2].l.upper);
}
}
#else
if (n < 64) {
if (n < 32) {
/* f0-f31 */
if (n & 1) {
return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
return gdb_get_reg32(mem_buf, env->fpr[n / 2].l.lower);
} else {
return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
return gdb_get_reg32(mem_buf, env->fpr[n / 2].l.upper);
}
}
if (n < 80) {
if (n < 48) {
/* f32-f62 (16 double width registers, even register numbers only)
* n == 64: f32 : env->fpr[16]
* n == 65: f34 : env->fpr[17]
* n == 32: f32 : env->fpr[16]
* n == 33: f34 : env->fpr[17]
* etc...
* n == 79: f62 : env->fpr[31]
* n == 47: f62 : env->fpr[31]
*/
return gdb_get_reg64(mem_buf, env->fpr[(n - 64) + 16].ll);
return gdb_get_reg64(mem_buf, env->fpr[(n - 32) + 16].ll);
}
#endif
return 0;
@ -135,39 +143,55 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
if (n < 8) {
/* g0..g7 */
env->gregs[n] = tmp;
} else if (n < 32) {
} else {
/* register window */
env->regwptr[n - 8] = tmp;
}
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
else if (n < 64) {
/* fprs */
/* f0-f31 */
if (n & 1) {
env->fpr[(n - 32) / 2].l.lower = tmp;
} else {
env->fpr[(n - 32) / 2].l.upper = tmp;
}
return 4;
#else
return 8;
#endif
}
__attribute__((unused))
static int sparc_fpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
CPUSPARCState *env = cpu_env(cs);
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
uint32_t tmp;
tmp = ldl_p(mem_buf);
/* fprs */
/* f0-f31 */
if (n & 1) {
env->fpr[n / 2].l.lower = tmp;
} else {
env->fpr[n / 2].l.upper = tmp;
}
return 4;
#else
else if (n < 64) {
if (n < 32) {
/* f0-f31 */
tmp = ldl_p(mem_buf);
uint32_t tmp = ldl_p(mem_buf);
if (n & 1) {
env->fpr[(n - 32) / 2].l.lower = tmp;
env->fpr[n / 2].l.lower = tmp;
} else {
env->fpr[(n - 32) / 2].l.upper = tmp;
env->fpr[n / 2].l.upper = tmp;
}
return 4;
} else if (n < 80) {
} else {
uint64_t tmp = ldq_p(mem_buf);
/* f32-f62 (16 double width registers, even register numbers only)
* n == 64: f32 : env->fpr[16]
* n == 65: f34 : env->fpr[17]
* n == 32: f32 : env->fpr[16]
* n == 33: f34 : env->fpr[17]
* etc...
* n == 79: f62 : env->fpr[31]
* n == 47: f62 : env->fpr[31]
*/
env->fpr[(n - 64) + 16].ll = tmp;
env->fpr[(n - 32) + 16].ll = tmp;
}
return 8;
#endif
@ -249,6 +273,10 @@ void sparc_cpu_register_gdb_regs(CPUState *cs)
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
/* Not yet supported */
#else
gdb_register_coprocessor(cs, sparc_fpu_gdb_read_register,
sparc_fpu_gdb_write_register,
gdb_find_static_feature("sparc64-fpu.xml"),
0);
gdb_register_coprocessor(cs, sparc_cp0_gdb_read_register,
sparc_cp0_gdb_write_register,
gdb_find_static_feature("sparc64-cp0.xml"),

Loading…
Cancel
Save