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>
Philippe Mathieu-Daudé committed
Feb 15, 2026 at 02:45 UTC
85b4bcf3d55e284ffce9a642fff1a76859549c52
5 files changed
+118
-81
configs/targets/sparc64-linux-user.mak
+1
-1
@@ -4,6 +4,6 @@ TARGET_ABI_DIR=sparc
4
TARGET_SYSTBL_ABI=common,64
5
TARGET_SYSTBL=syscall.tbl
6
TARGET_BIG_ENDIAN=y
7
-TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-cp0.xml
7
+TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-fpu.xml gdb-xml/sparc64-cp0.xml
8
TARGET_LONG_BITS=64
9
TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
configs/targets/sparc64-softmmu.mak
+1
-1
@@ -1,7 +1,7 @@
1
TARGET_ARCH=sparc64
2
TARGET_BASE_ARCH=sparc
3
TARGET_BIG_ENDIAN=y
4
-TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-cp0.xml
4
+TARGET_XML_FILES=gdb-xml/sparc64-core.xml gdb-xml/sparc64-fpu.xml gdb-xml/sparc64-cp0.xml
5
TARGET_LONG_BITS=64
6
TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
7
TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
gdb-xml/sparc64-core.xml
-50
@@ -39,54 +39,4 @@
39
<reg name="i5" bitsize="64" type="uint64" regnum="29"/>
40
<reg name="fp" bitsize="64" type="uint64" regnum="30"/>
41
<reg name="i7" bitsize="64" type="uint64" regnum="31"/>
42
-
43
- <reg name="f0" bitsize="32" type="ieee_single" regnum="32"/>
44
- <reg name="f1" bitsize="32" type="ieee_single" regnum="33"/>
45
- <reg name="f2" bitsize="32" type="ieee_single" regnum="34"/>
46
- <reg name="f3" bitsize="32" type="ieee_single" regnum="35"/>
47
- <reg name="f4" bitsize="32" type="ieee_single" regnum="36"/>
48
- <reg name="f5" bitsize="32" type="ieee_single" regnum="37"/>
49
- <reg name="f6" bitsize="32" type="ieee_single" regnum="38"/>
50
- <reg name="f7" bitsize="32" type="ieee_single" regnum="39"/>
51
- <reg name="f8" bitsize="32" type="ieee_single" regnum="40"/>
52
- <reg name="f9" bitsize="32" type="ieee_single" regnum="41"/>
53
- <reg name="f10" bitsize="32" type="ieee_single" regnum="42"/>
54
- <reg name="f11" bitsize="32" type="ieee_single" regnum="43"/>
55
- <reg name="f12" bitsize="32" type="ieee_single" regnum="44"/>
56
- <reg name="f13" bitsize="32" type="ieee_single" regnum="45"/>
57
- <reg name="f14" bitsize="32" type="ieee_single" regnum="46"/>
58
- <reg name="f15" bitsize="32" type="ieee_single" regnum="47"/>
59
- <reg name="f16" bitsize="32" type="ieee_single" regnum="48"/>
60
- <reg name="f17" bitsize="32" type="ieee_single" regnum="49"/>
61
- <reg name="f18" bitsize="32" type="ieee_single" regnum="50"/>
62
- <reg name="f19" bitsize="32" type="ieee_single" regnum="51"/>
63
- <reg name="f20" bitsize="32" type="ieee_single" regnum="52"/>
64
- <reg name="f21" bitsize="32" type="ieee_single" regnum="53"/>
65
- <reg name="f22" bitsize="32" type="ieee_single" regnum="54"/>
66
- <reg name="f23" bitsize="32" type="ieee_single" regnum="55"/>
67
- <reg name="f24" bitsize="32" type="ieee_single" regnum="56"/>
68
- <reg name="f25" bitsize="32" type="ieee_single" regnum="57"/>
69
- <reg name="f26" bitsize="32" type="ieee_single" regnum="58"/>
70
- <reg name="f27" bitsize="32" type="ieee_single" regnum="59"/>
71
- <reg name="f28" bitsize="32" type="ieee_single" regnum="60"/>
72
- <reg name="f29" bitsize="32" type="ieee_single" regnum="61"/>
73
- <reg name="f30" bitsize="32" type="ieee_single" regnum="62"/>
74
- <reg name="f31" bitsize="32" type="ieee_single" regnum="63"/>
75
-
76
- <reg name="f32" bitsize="64" type="ieee_double" regnum="64"/>
77
- <reg name="f34" bitsize="64" type="ieee_double" regnum="65"/>
78
- <reg name="f36" bitsize="64" type="ieee_double" regnum="66"/>
79
- <reg name="f38" bitsize="64" type="ieee_double" regnum="67"/>
80
- <reg name="f40" bitsize="64" type="ieee_double" regnum="68"/>
81
- <reg name="f42" bitsize="64" type="ieee_double" regnum="69"/>
82
- <reg name="f44" bitsize="64" type="ieee_double" regnum="70"/>
83
- <reg name="f46" bitsize="64" type="ieee_double" regnum="71"/>
84
- <reg name="f48" bitsize="64" type="ieee_double" regnum="72"/>
85
- <reg name="f50" bitsize="64" type="ieee_double" regnum="73"/>
86
- <reg name="f52" bitsize="64" type="ieee_double" regnum="74"/>
87
- <reg name="f54" bitsize="64" type="ieee_double" regnum="75"/>
88
- <reg name="f56" bitsize="64" type="ieee_double" regnum="76"/>
89
- <reg name="f58" bitsize="64" type="ieee_double" regnum="77"/>
90
- <reg name="f60" bitsize="64" type="ieee_double" regnum="78"/>
91
- <reg name="f62" bitsize="64" type="ieee_double" regnum="79"/>
42
</feature>
gdb-xml/sparc64-fpu.xml
new
+59
@@ -0,0 +1,59 @@
1
+<?xml version="1.0"?>
2
+<!-- Copyright (C) 2013-2026 Free Software Foundation, Inc.
3
+
4
+ Copying and distribution of this file, with or without modification,
5
+ are permitted in any medium without royalty provided the copyright
6
+ notice and this notice are preserved. -->
7
+
8
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
9
+<feature name="org.gnu.gdb.sparc.fpu">
10
+ <reg name="f0" bitsize="32" type="ieee_single" regnum="32"/>
11
+ <reg name="f1" bitsize="32" type="ieee_single" regnum="33"/>
12
+ <reg name="f2" bitsize="32" type="ieee_single" regnum="34"/>
13
+ <reg name="f3" bitsize="32" type="ieee_single" regnum="35"/>
14
+ <reg name="f4" bitsize="32" type="ieee_single" regnum="36"/>
15
+ <reg name="f5" bitsize="32" type="ieee_single" regnum="37"/>
16
+ <reg name="f6" bitsize="32" type="ieee_single" regnum="38"/>
17
+ <reg name="f7" bitsize="32" type="ieee_single" regnum="39"/>
18
+ <reg name="f8" bitsize="32" type="ieee_single" regnum="40"/>
19
+ <reg name="f9" bitsize="32" type="ieee_single" regnum="41"/>
20
+ <reg name="f10" bitsize="32" type="ieee_single" regnum="42"/>
21
+ <reg name="f11" bitsize="32" type="ieee_single" regnum="43"/>
22
+ <reg name="f12" bitsize="32" type="ieee_single" regnum="44"/>
23
+ <reg name="f13" bitsize="32" type="ieee_single" regnum="45"/>
24
+ <reg name="f14" bitsize="32" type="ieee_single" regnum="46"/>
25
+ <reg name="f15" bitsize="32" type="ieee_single" regnum="47"/>
26
+ <reg name="f16" bitsize="32" type="ieee_single" regnum="48"/>
27
+ <reg name="f17" bitsize="32" type="ieee_single" regnum="49"/>
28
+ <reg name="f18" bitsize="32" type="ieee_single" regnum="50"/>
29
+ <reg name="f19" bitsize="32" type="ieee_single" regnum="51"/>
30
+ <reg name="f20" bitsize="32" type="ieee_single" regnum="52"/>
31
+ <reg name="f21" bitsize="32" type="ieee_single" regnum="53"/>
32
+ <reg name="f22" bitsize="32" type="ieee_single" regnum="54"/>
33
+ <reg name="f23" bitsize="32" type="ieee_single" regnum="55"/>
34
+ <reg name="f24" bitsize="32" type="ieee_single" regnum="56"/>
35
+ <reg name="f25" bitsize="32" type="ieee_single" regnum="57"/>
36
+ <reg name="f26" bitsize="32" type="ieee_single" regnum="58"/>
37
+ <reg name="f27" bitsize="32" type="ieee_single" regnum="59"/>
38
+ <reg name="f28" bitsize="32" type="ieee_single" regnum="60"/>
39
+ <reg name="f29" bitsize="32" type="ieee_single" regnum="61"/>
40
+ <reg name="f30" bitsize="32" type="ieee_single" regnum="62"/>
41
+ <reg name="f31" bitsize="32" type="ieee_single" regnum="63"/>
42
+
43
+ <reg name="f32" bitsize="64" type="ieee_double" regnum="64"/>
44
+ <reg name="f34" bitsize="64" type="ieee_double" regnum="65"/>
45
+ <reg name="f36" bitsize="64" type="ieee_double" regnum="66"/>
46
+ <reg name="f38" bitsize="64" type="ieee_double" regnum="67"/>
47
+ <reg name="f40" bitsize="64" type="ieee_double" regnum="68"/>
48
+ <reg name="f42" bitsize="64" type="ieee_double" regnum="69"/>
49
+ <reg name="f44" bitsize="64" type="ieee_double" regnum="70"/>
50
+ <reg name="f46" bitsize="64" type="ieee_double" regnum="71"/>
51
+ <reg name="f48" bitsize="64" type="ieee_double" regnum="72"/>
52
+ <reg name="f50" bitsize="64" type="ieee_double" regnum="73"/>
53
+ <reg name="f52" bitsize="64" type="ieee_double" regnum="74"/>
54
+ <reg name="f54" bitsize="64" type="ieee_double" regnum="75"/>
55
+ <reg name="f56" bitsize="64" type="ieee_double" regnum="76"/>
56
+ <reg name="f58" bitsize="64" type="ieee_double" regnum="77"/>
57
+ <reg name="f60" bitsize="64" type="ieee_double" regnum="78"/>
58
+ <reg name="f62" bitsize="64" type="ieee_double" regnum="79"/>
59
+</feature>
target/sparc/gdbstub.c
+57
-29
@@ -40,32 +40,40 @@ int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
40
/* register window */
41
return gdb_get_rega(mem_buf, env->regwptr[n - 8]);
42
}
43
+ return 0;
44
+}
45
+
46
+__attribute__((unused))
47
+static int sparc_fpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
48
+{
49
+ CPUSPARCState *env = cpu_env(cs);
50
+
51
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
44
- if (n < 64) {
52
+ if (n < 32) {
53
/* fprs */
54
if (n & 1) {
47
- return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
55
+ return gdb_get_reg32(mem_buf, env->fpr[n / 2].l.lower);
56
} else {
49
- return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
57
+ return gdb_get_reg32(mem_buf, env->fpr[n / 2].l.upper);
58
}
59
}
60
#else
53
- if (n < 64) {
61
+ if (n < 32) {
62
/* f0-f31 */
63
if (n & 1) {
56
- return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
64
+ return gdb_get_reg32(mem_buf, env->fpr[n / 2].l.lower);
65
} else {
58
- return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
66
+ return gdb_get_reg32(mem_buf, env->fpr[n / 2].l.upper);
67
}
68
}
61
- if (n < 80) {
69
+ if (n < 48) {
70
/* f32-f62 (16 double width registers, even register numbers only)
63
- * n == 64: f32 : env->fpr[16]
64
- * n == 65: f34 : env->fpr[17]
71
+ * n == 32: f32 : env->fpr[16]
72
+ * n == 33: f34 : env->fpr[17]
73
* etc...
66
- * n == 79: f62 : env->fpr[31]
74
+ * n == 47: f62 : env->fpr[31]
75
*/
68
- return gdb_get_reg64(mem_buf, env->fpr[(n - 64) + 16].ll);
76
+ return gdb_get_reg64(mem_buf, env->fpr[(n - 32) + 16].ll);
77
}
78
#endif
79
return 0;
@@ -135,39 +143,55 @@ int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
143
if (n < 8) {
144
/* g0..g7 */
145
env->gregs[n] = tmp;
138
- } else if (n < 32) {
146
+ } else {
147
/* register window */
148
env->regwptr[n - 8] = tmp;
149
}
150
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
143
- else if (n < 64) {
144
- /* fprs */
145
- /* f0-f31 */
146
- if (n & 1) {
147
- env->fpr[(n - 32) / 2].l.lower = tmp;
148
- } else {
149
- env->fpr[(n - 32) / 2].l.upper = tmp;
150
- }
151
+ return 4;
152
+#else
153
+ return 8;
154
+#endif
155
+}
156
+
157
+__attribute__((unused))
158
+static int sparc_fpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
159
+{
160
+ CPUSPARCState *env = cpu_env(cs);
161
+
162
+#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
163
+ uint32_t tmp;
164
+
165
+ tmp = ldl_p(mem_buf);
166
+
167
+ /* fprs */
168
+ /* f0-f31 */
169
+ if (n & 1) {
170
+ env->fpr[n / 2].l.lower = tmp;
171
+ } else {
172
+ env->fpr[n / 2].l.upper = tmp;
173
}
174
+
175
return 4;
176
#else
154
- else if (n < 64) {
177
+ if (n < 32) {
178
/* f0-f31 */
156
- tmp = ldl_p(mem_buf);
179
+ uint32_t tmp = ldl_p(mem_buf);
180
if (n & 1) {
158
- env->fpr[(n - 32) / 2].l.lower = tmp;
181
+ env->fpr[n / 2].l.lower = tmp;
182
} else {
160
- env->fpr[(n - 32) / 2].l.upper = tmp;
183
+ env->fpr[n / 2].l.upper = tmp;
184
}
185
return 4;
163
- } else if (n < 80) {
186
+ } else {
187
+ uint64_t tmp = ldq_p(mem_buf);
188
/* f32-f62 (16 double width registers, even register numbers only)
165
- * n == 64: f32 : env->fpr[16]
166
- * n == 65: f34 : env->fpr[17]
189
+ * n == 32: f32 : env->fpr[16]
190
+ * n == 33: f34 : env->fpr[17]
191
* etc...
168
- * n == 79: f62 : env->fpr[31]
192
+ * n == 47: f62 : env->fpr[31]
193
*/
170
- env->fpr[(n - 64) + 16].ll = tmp;
194
+ env->fpr[(n - 32) + 16].ll = tmp;
195
}
196
return 8;
197
#endif
@@ -249,6 +273,10 @@ void sparc_cpu_register_gdb_regs(CPUState *cs)
273
#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
274
/* Not yet supported */
275
#else
276
+ gdb_register_coprocessor(cs, sparc_fpu_gdb_read_register,
277
+ sparc_fpu_gdb_write_register,
278
+ gdb_find_static_feature("sparc64-fpu.xml"),
279
+ 0);
280
gdb_register_coprocessor(cs, sparc_cp0_gdb_read_register,
281
sparc_cp0_gdb_write_register,
282
gdb_find_static_feature("sparc64-cp0.xml"),