|
1 Support for target descriptions layered on top of sparc32/sparc64 |
|
2 which describe more registers than native ones. |
|
3 Pseudo registers always come after the real registers. |
|
4 One more step forward to modernize sparc tdep's. |
|
5 Submitted to upstream as: |
|
6 https://sourceware.org/bugzilla/show_bug.cgi?id=20936 |
|
7 |
|
8 --- gdb-7.11/gdb/sparc64-tdep.c.orig 2016-11-13 22:23:36.747445049 -0800 |
|
9 +++ gdb-7.11/gdb/sparc64-tdep.c 2016-11-13 22:23:47.678340579 -0800 |
|
10 @@ -31,6 +31,7 @@ |
|
11 #include "objfiles.h" |
|
12 #include "osabi.h" |
|
13 #include "regcache.h" |
|
14 +#include "target-descriptions.h" |
|
15 #include "target.h" |
|
16 #include "value.h" |
|
17 |
|
18 @@ -251,28 +252,29 @@ |
|
19 |
|
20 |
|
21 /* Register information. */ |
|
22 +#define SPARC64_FPU_REGISTERS \ |
|
23 + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ |
|
24 + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ |
|
25 + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ |
|
26 + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ |
|
27 + "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \ |
|
28 + "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62" |
|
29 +#define SPARC64_CP0_REGISTERS \ |
|
30 + "pc", "npc", \ |
|
31 + /* FIXME: Give "state" a name until we start using register groups. */ \ |
|
32 + "state", \ |
|
33 + "fsr", \ |
|
34 + "fprs", \ |
|
35 + "y" |
|
36 |
|
37 +static const char *sparc64_fpu_register_names[] = { SPARC64_FPU_REGISTERS }; |
|
38 +static const char *sparc64_cp0_register_names[] = { SPARC64_CP0_REGISTERS }; |
|
39 + |
|
40 static const char *sparc64_register_names[] = |
|
41 { |
|
42 - "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", |
|
43 - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", |
|
44 - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", |
|
45 - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", |
|
46 - |
|
47 - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", |
|
48 - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", |
|
49 - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", |
|
50 - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", |
|
51 - "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", |
|
52 - "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", |
|
53 - |
|
54 - "pc", "npc", |
|
55 - |
|
56 - /* FIXME: Give "state" a name until we start using register groups. */ |
|
57 - "state", |
|
58 - "fsr", |
|
59 - "fprs", |
|
60 - "y", |
|
61 + SPARC_CORE_REGISTERS, |
|
62 + SPARC64_FPU_REGISTERS, |
|
63 + SPARC64_CP0_REGISTERS |
|
64 }; |
|
65 |
|
66 /* Total number of registers. */ |
|
67 @@ -298,7 +300,19 @@ |
|
68 #define SPARC64_NUM_PSEUDO_REGS ARRAY_SIZE (sparc64_pseudo_register_names) |
|
69 |
|
70 /* Return the name of register REGNUM. */ |
|
71 +static const char * |
|
72 +sparc64_pseudo_register_name (struct gdbarch *gdbarch, int regnum) |
|
73 +{ |
|
74 + regnum -= gdbarch_num_regs (gdbarch); |
|
75 |
|
76 + if (regnum < SPARC64_NUM_PSEUDO_REGS) |
|
77 + return sparc64_pseudo_register_names[regnum]; |
|
78 + |
|
79 + internal_error (__FILE__, __LINE__, |
|
80 + _("sparc64_pseudo_register_name: bad register number %d"), |
|
81 + regnum); |
|
82 +} |
|
83 + |
|
84 static const char * |
|
85 sparc64_register_name (struct gdbarch *gdbarch, int regnum) |
|
86 { |
|
87 @@ -305,9 +319,8 @@ |
|
88 if (regnum >= 0 && regnum < SPARC64_NUM_REGS) |
|
89 return sparc64_register_names[regnum]; |
|
90 |
|
91 - if (regnum >= SPARC64_NUM_REGS |
|
92 - && regnum < SPARC64_NUM_REGS + SPARC64_NUM_PSEUDO_REGS) |
|
93 - return sparc64_pseudo_register_names[regnum - SPARC64_NUM_REGS]; |
|
94 + if (regnum >= gdbarch_num_regs (gdbarch)) |
|
95 + return sparc64_pseudo_register_name (gdbarch, regnum); |
|
96 |
|
97 return NULL; |
|
98 } |
|
99 @@ -314,7 +327,29 @@ |
|
100 |
|
101 /* Return the GDB type object for the "standard" data type of data in |
|
102 register REGNUM. */ |
|
103 +static struct type * |
|
104 +sparc64_pseudo_register_type (struct gdbarch *gdbarch, int regnum) |
|
105 +{ |
|
106 + regnum -= gdbarch_num_regs (gdbarch); |
|
107 |
|
108 + if (regnum == SPARC64_CWP_REGNUM) |
|
109 + return builtin_type (gdbarch)->builtin_int64; |
|
110 + if (regnum == SPARC64_PSTATE_REGNUM) |
|
111 + return sparc64_pstate_type (gdbarch); |
|
112 + if (regnum == SPARC64_ASI_REGNUM) |
|
113 + return builtin_type (gdbarch)->builtin_int64; |
|
114 + if (regnum == SPARC64_CCR_REGNUM) |
|
115 + return sparc64_ccr_type (gdbarch); |
|
116 + if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D62_REGNUM) |
|
117 + return builtin_type (gdbarch)->builtin_double; |
|
118 + if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q60_REGNUM) |
|
119 + return builtin_type (gdbarch)->builtin_long_double; |
|
120 + |
|
121 + internal_error (__FILE__, __LINE__, |
|
122 + _("sparc64_pseudo_register_type: bad register number %d"), |
|
123 + regnum); |
|
124 +} |
|
125 + |
|
126 static struct type * |
|
127 sparc64_register_type (struct gdbarch *gdbarch, int regnum) |
|
128 { |
|
129 @@ -344,20 +379,9 @@ |
|
130 return builtin_type (gdbarch)->builtin_int64; |
|
131 |
|
132 /* Pseudo registers. */ |
|
133 + if (regnum >= gdbarch_num_regs (gdbarch)) |
|
134 + return sparc64_pseudo_register_type (gdbarch, regnum); |
|
135 |
|
136 - if (regnum == SPARC64_CWP_REGNUM) |
|
137 - return builtin_type (gdbarch)->builtin_int64; |
|
138 - if (regnum == SPARC64_PSTATE_REGNUM) |
|
139 - return sparc64_pstate_type (gdbarch); |
|
140 - if (regnum == SPARC64_ASI_REGNUM) |
|
141 - return builtin_type (gdbarch)->builtin_int64; |
|
142 - if (regnum == SPARC64_CCR_REGNUM) |
|
143 - return sparc64_ccr_type (gdbarch); |
|
144 - if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D62_REGNUM) |
|
145 - return builtin_type (gdbarch)->builtin_double; |
|
146 - if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q60_REGNUM) |
|
147 - return builtin_type (gdbarch)->builtin_long_double; |
|
148 - |
|
149 internal_error (__FILE__, __LINE__, _("invalid regnum")); |
|
150 } |
|
151 |
|
152 @@ -369,7 +393,7 @@ |
|
153 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); |
|
154 enum register_status status; |
|
155 |
|
156 - gdb_assert (regnum >= SPARC64_NUM_REGS); |
|
157 + regnum -= gdbarch_num_regs (gdbarch); |
|
158 |
|
159 if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM) |
|
160 { |
|
161 @@ -446,8 +470,9 @@ |
|
162 int regnum, const gdb_byte *buf) |
|
163 { |
|
164 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); |
|
165 - gdb_assert (regnum >= SPARC64_NUM_REGS); |
|
166 |
|
167 + regnum -= gdbarch_num_regs (gdbarch); |
|
168 + |
|
169 if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM) |
|
170 { |
|
171 regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC64_D0_REGNUM); |
|
172 @@ -663,6 +688,7 @@ |
|
173 sparc64_store_floating_fields (struct regcache *regcache, struct type *type, |
|
174 const gdb_byte *valbuf, int element, int bitpos) |
|
175 { |
|
176 + struct gdbarch *gdbarch = get_regcache_arch (regcache); |
|
177 int len = TYPE_LENGTH (type); |
|
178 |
|
179 gdb_assert (element < 16); |
|
180 @@ -677,7 +703,7 @@ |
|
181 gdb_assert (bitpos == 0); |
|
182 gdb_assert ((element % 2) == 0); |
|
183 |
|
184 - regnum = SPARC64_Q0_REGNUM + element / 2; |
|
185 + regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM + element / 2; |
|
186 regcache_cooked_write (regcache, regnum, valbuf); |
|
187 } |
|
188 else if (len == 8) |
|
189 @@ -684,7 +710,8 @@ |
|
190 { |
|
191 gdb_assert (bitpos == 0 || bitpos == 64); |
|
192 |
|
193 - regnum = SPARC64_D0_REGNUM + element + bitpos / 64; |
|
194 + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM |
|
195 + + element + bitpos / 64; |
|
196 regcache_cooked_write (regcache, regnum, valbuf + (bitpos / 8)); |
|
197 } |
|
198 else |
|
199 @@ -737,6 +764,8 @@ |
|
200 sparc64_extract_floating_fields (struct regcache *regcache, struct type *type, |
|
201 gdb_byte *valbuf, int bitpos) |
|
202 { |
|
203 + struct gdbarch *gdbarch = get_regcache_arch (regcache); |
|
204 + |
|
205 if (sparc64_floating_p (type)) |
|
206 { |
|
207 int len = TYPE_LENGTH (type); |
|
208 @@ -746,7 +775,8 @@ |
|
209 { |
|
210 gdb_assert (bitpos == 0 || bitpos == 128); |
|
211 |
|
212 - regnum = SPARC64_Q0_REGNUM + bitpos / 128; |
|
213 + regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM |
|
214 + + bitpos / 128; |
|
215 regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8)); |
|
216 } |
|
217 else if (len == 8) |
|
218 @@ -753,7 +783,7 @@ |
|
219 { |
|
220 gdb_assert (bitpos % 64 == 0 && bitpos >= 0 && bitpos < 256); |
|
221 |
|
222 - regnum = SPARC64_D0_REGNUM + bitpos / 64; |
|
223 + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + bitpos / 64; |
|
224 regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8)); |
|
225 } |
|
226 else |
|
227 @@ -936,13 +966,13 @@ |
|
228 /* Float Complex or double Complex arguments. */ |
|
229 if (element < 16) |
|
230 { |
|
231 - regnum = SPARC64_D0_REGNUM + element; |
|
232 + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + element; |
|
233 |
|
234 if (len == 16) |
|
235 { |
|
236 - if (regnum < SPARC64_D30_REGNUM) |
|
237 + if (regnum < gdbarch_num_regs (gdbarch) + SPARC64_D30_REGNUM) |
|
238 regcache_cooked_write (regcache, regnum + 1, valbuf + 8); |
|
239 - if (regnum < SPARC64_D10_REGNUM) |
|
240 + if (regnum < gdbarch_num_regs (gdbarch) + SPARC64_D10_REGNUM) |
|
241 regcache_cooked_write (regcache, |
|
242 SPARC_O0_REGNUM + element + 1, |
|
243 valbuf + 8); |
|
244 @@ -957,12 +987,14 @@ |
|
245 if (element % 2) |
|
246 element++; |
|
247 if (element < 16) |
|
248 - regnum = SPARC64_Q0_REGNUM + element / 2; |
|
249 + regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM |
|
250 + + element / 2; |
|
251 } |
|
252 else if (len == 8) |
|
253 { |
|
254 if (element < 16) |
|
255 - regnum = SPARC64_D0_REGNUM + element; |
|
256 + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM |
|
257 + + element; |
|
258 } |
|
259 else if (len == 4) |
|
260 { |
|
261 @@ -977,7 +1009,8 @@ |
|
262 valbuf = buf; |
|
263 len = 8; |
|
264 if (element < 16) |
|
265 - regnum = SPARC64_D0_REGNUM + element; |
|
266 + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM |
|
267 + + element; |
|
268 } |
|
269 } |
|
270 else |
|
271 @@ -994,19 +1027,24 @@ |
|
272 |
|
273 /* If we're storing the value in a floating-point register, |
|
274 also store it in the corresponding %0 register(s). */ |
|
275 - if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D10_REGNUM) |
|
276 - { |
|
277 - gdb_assert (element < 6); |
|
278 - regnum = SPARC_O0_REGNUM + element; |
|
279 - regcache_cooked_write (regcache, regnum, valbuf); |
|
280 - } |
|
281 - else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM) |
|
282 - { |
|
283 - gdb_assert (element < 5); |
|
284 - regnum = SPARC_O0_REGNUM + element; |
|
285 - regcache_cooked_write (regcache, regnum, valbuf); |
|
286 - regcache_cooked_write (regcache, regnum + 1, valbuf + 8); |
|
287 - } |
|
288 + if (regnum >= gdbarch_num_regs (gdbarch)) |
|
289 + { |
|
290 + regnum -= gdbarch_num_regs (gdbarch); |
|
291 + |
|
292 + if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D10_REGNUM) |
|
293 + { |
|
294 + gdb_assert (element < 6); |
|
295 + regnum = SPARC_O0_REGNUM + element; |
|
296 + regcache_cooked_write (regcache, regnum, valbuf); |
|
297 + } |
|
298 + else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM) |
|
299 + { |
|
300 + gdb_assert (element < 5); |
|
301 + regnum = SPARC_O0_REGNUM + element; |
|
302 + regcache_cooked_write (regcache, regnum, valbuf); |
|
303 + regcache_cooked_write (regcache, regnum + 1, valbuf + 8); |
|
304 + } |
|
305 + } |
|
306 } |
|
307 |
|
308 /* Always store the argument in memory. */ |
|
309 @@ -1210,6 +1248,10 @@ |
|
310 |
|
311 tdep->pc_regnum = SPARC64_PC_REGNUM; |
|
312 tdep->npc_regnum = SPARC64_NPC_REGNUM; |
|
313 + tdep->fpu_register_names = sparc64_fpu_register_names; |
|
314 + tdep->fpu_registers_num = ARRAY_SIZE (sparc64_fpu_register_names); |
|
315 + tdep->cp0_register_names = sparc64_cp0_register_names; |
|
316 + tdep->cp0_registers_num = ARRAY_SIZE (sparc64_cp0_register_names); |
|
317 |
|
318 /* This is what all the fuss is about. */ |
|
319 set_gdbarch_long_bit (gdbarch, 64); |
|
320 @@ -1220,6 +1262,8 @@ |
|
321 set_gdbarch_register_name (gdbarch, sparc64_register_name); |
|
322 set_gdbarch_register_type (gdbarch, sparc64_register_type); |
|
323 set_gdbarch_num_pseudo_regs (gdbarch, SPARC64_NUM_PSEUDO_REGS); |
|
324 + set_tdesc_pseudo_register_name (gdbarch, sparc64_pseudo_register_name); |
|
325 + set_tdesc_pseudo_register_type (gdbarch, sparc64_pseudo_register_type); |
|
326 set_gdbarch_pseudo_register_read (gdbarch, sparc64_pseudo_register_read); |
|
327 set_gdbarch_pseudo_register_write (gdbarch, sparc64_pseudo_register_write); |
|
328 |