[AArch64,arm] Fix some formatting issues in the aarch64/arm codebase
[binutils-gdb.git] / gdb / amdgpu-tdep.c
1 /* Target-dependent code for the AMDGPU architectures.
2
3 Copyright (C) 2019-2023 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "defs.h"
21
22 #include "amd-dbgapi-target.h"
23 #include "amdgpu-tdep.h"
24 #include "arch-utils.h"
25 #include "disasm.h"
26 #include "dwarf2/frame.h"
27 #include "frame-unwind.h"
28 #include "gdbarch.h"
29 #include "gdbsupport/selftest.h"
30 #include "gdbtypes.h"
31 #include "inferior.h"
32 #include "objfiles.h"
33 #include "observable.h"
34 #include "producer.h"
35 #include "reggroups.h"
36
37 /* See amdgpu-tdep.h. */
38
39 bool
40 is_amdgpu_arch (struct gdbarch *arch)
41 {
42 gdb_assert (arch != nullptr);
43 return gdbarch_bfd_arch_info (arch)->arch == bfd_arch_amdgcn;
44 }
45
46 /* See amdgpu-tdep.h. */
47
48 amdgpu_gdbarch_tdep *
49 get_amdgpu_gdbarch_tdep (gdbarch *arch)
50 {
51 return gdbarch_tdep<amdgpu_gdbarch_tdep> (arch);
52 }
53
54 /* Dummy implementation of gdbarch_return_value_as_value. */
55
56 static return_value_convention
57 amdgpu_return_value_as_value (gdbarch *arch, value *function, type *valtype,
58 regcache *regcache, value **read_value,
59 const gdb_byte *writebuf)
60 {
61 gdb_assert_not_reached ("not implemented");
62 }
63
64 /* Return the name of register REGNUM. */
65
66 static const char *
67 amdgpu_register_name (struct gdbarch *gdbarch, int regnum)
68 {
69 /* The list of registers reported by amd-dbgapi for a given architecture
70 contains some duplicate names. For instance, there is an "exec" register
71 for waves in the wave32 mode and one for the waves in the wave64 mode.
72 However, at most one register with a given name is actually allocated for
73 a specific wave. If INFERIOR_PTID represents a GPU wave, we query
74 amd-dbgapi to know whether the requested register actually exists for the
75 current wave, so there won't be duplicates in the the register names we
76 report for that wave.
77
78 But there are two known cases where INFERIOR_PTID doesn't represent a GPU
79 wave:
80
81 - The user does "set arch amdgcn:gfxNNN" followed with "maint print
82 registers"
83 - The "register_name" selftest
84
85 In these cases, we can't query amd-dbgapi to know whether we should hide
86 the register or not. The "register_name" selftest checks that there aren't
87 duplicates in the register names returned by the gdbarch, so if we simply
88 return all register names, that test will fail. The other simple option is
89 to never return a register name, which is what we do here. */
90 if (!ptid_is_gpu (inferior_ptid))
91 return "";
92
93 amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (inferior_ptid);
94 amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);
95
96 amd_dbgapi_register_exists_t register_exists;
97 if (amd_dbgapi_wave_register_exists (wave_id, tdep->register_ids[regnum],
98 &register_exists)
99 != AMD_DBGAPI_STATUS_SUCCESS
100 || register_exists != AMD_DBGAPI_REGISTER_PRESENT)
101 return "";
102
103 return tdep->register_names[regnum].c_str ();
104 }
105
106 /* Return the internal register number for the DWARF register number DWARF_REG.
107
108 Return -1 if there's no internal register mapping to DWARF_REG. */
109
110 static int
111 amdgpu_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dwarf_reg)
112 {
113 amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);
114
115 if (dwarf_reg < tdep->dwarf_regnum_to_gdb_regnum.size ())
116 return tdep->dwarf_regnum_to_gdb_regnum[dwarf_reg];
117
118 return -1;
119 }
120
121 /* A hierarchy of classes to represent an amd-dbgapi register type. */
122
123 struct amd_dbgapi_register_type
124 {
125 enum class kind
126 {
127 INTEGER,
128 FLOAT,
129 DOUBLE,
130 VECTOR,
131 CODE_PTR,
132 FLAGS,
133 ENUM,
134 };
135
136 amd_dbgapi_register_type (kind kind, std::string lookup_name)
137 : m_kind (kind), m_lookup_name (std::move (lookup_name))
138 {}
139
140 virtual ~amd_dbgapi_register_type () = default;
141
142 /* Return the type's kind. */
143 kind kind () const
144 { return m_kind; }
145
146 /* Name to use for this type in the existing type map. */
147 const std::string &lookup_name () const
148 { return m_lookup_name; }
149
150 private:
151 enum kind m_kind;
152 std::string m_lookup_name;
153 };
154
155 using amd_dbgapi_register_type_up = std::unique_ptr<amd_dbgapi_register_type>;
156
157 struct amd_dbgapi_register_type_integer : public amd_dbgapi_register_type
158 {
159 amd_dbgapi_register_type_integer (bool is_unsigned, unsigned int bit_size)
160 : amd_dbgapi_register_type
161 (kind::INTEGER,
162 string_printf ("%sint%d", is_unsigned ? "u" : "", bit_size)),
163 m_is_unsigned (is_unsigned),
164 m_bit_size (bit_size)
165 {}
166
167 bool is_unsigned () const
168 { return m_is_unsigned; }
169
170 unsigned int bit_size () const
171 { return m_bit_size; }
172
173 private:
174 bool m_is_unsigned;
175 unsigned int m_bit_size;
176 };
177
178 struct amd_dbgapi_register_type_float : public amd_dbgapi_register_type
179 {
180 amd_dbgapi_register_type_float ()
181 : amd_dbgapi_register_type (kind::FLOAT, "float")
182 {}
183 };
184
185 struct amd_dbgapi_register_type_double : public amd_dbgapi_register_type
186 {
187 amd_dbgapi_register_type_double ()
188 : amd_dbgapi_register_type (kind::DOUBLE, "double")
189 {}
190 };
191
192 struct amd_dbgapi_register_type_vector : public amd_dbgapi_register_type
193 {
194 amd_dbgapi_register_type_vector (const amd_dbgapi_register_type &element_type,
195 unsigned int count)
196 : amd_dbgapi_register_type (kind::VECTOR,
197 make_lookup_name (element_type, count)),
198 m_element_type (element_type),
199 m_count (count)
200 {}
201
202 const amd_dbgapi_register_type &element_type () const
203 { return m_element_type; }
204
205 unsigned int count () const
206 { return m_count; }
207
208 static std::string make_lookup_name
209 (const amd_dbgapi_register_type &element_type, unsigned int count)
210 {
211 return string_printf ("%s[%d]", element_type.lookup_name ().c_str (),
212 count);
213 }
214
215 private:
216 const amd_dbgapi_register_type &m_element_type;
217 unsigned int m_count;
218 };
219
220 struct amd_dbgapi_register_type_code_ptr : public amd_dbgapi_register_type
221 {
222 amd_dbgapi_register_type_code_ptr ()
223 : amd_dbgapi_register_type (kind::CODE_PTR, "void (*)()")
224 {}
225 };
226
227 struct amd_dbgapi_register_type_flags : public amd_dbgapi_register_type
228 {
229 struct field
230 {
231 std::string name;
232 unsigned int bit_pos_start;
233 unsigned int bit_pos_end;
234 const amd_dbgapi_register_type *type;
235 };
236
237 using container_type = std::vector<field>;
238 using const_iterator_type = container_type::const_iterator;
239
240 amd_dbgapi_register_type_flags (unsigned int bit_size, gdb::string_view name)
241 : amd_dbgapi_register_type (kind::FLAGS,
242 make_lookup_name (bit_size, name)),
243 m_bit_size (bit_size),
244 m_name (std::move (name))
245 {}
246
247 unsigned int bit_size () const
248 { return m_bit_size; }
249
250 void add_field (std::string name, unsigned int bit_pos_start,
251 unsigned int bit_pos_end,
252 const amd_dbgapi_register_type *type)
253 {
254 m_fields.push_back (field {std::move (name), bit_pos_start,
255 bit_pos_end, type});
256 }
257
258 container_type::size_type size () const
259 { return m_fields.size (); }
260
261 const field &operator[] (container_type::size_type pos) const
262 { return m_fields[pos]; }
263
264 const_iterator_type begin () const
265 { return m_fields.begin (); }
266
267 const_iterator_type end () const
268 { return m_fields.end (); }
269
270 const std::string &name () const
271 { return m_name; }
272
273 static std::string make_lookup_name (int bits, gdb::string_view name)
274 {
275 std::string res = string_printf ("flags%d_t ", bits);
276 res.append (name.data (), name.size ());
277 return res;
278 }
279
280 private:
281 unsigned int m_bit_size;
282 container_type m_fields;
283 std::string m_name;
284 };
285
286 using amd_dbgapi_register_type_flags_up
287 = std::unique_ptr<amd_dbgapi_register_type_flags>;
288
289 struct amd_dbgapi_register_type_enum : public amd_dbgapi_register_type
290 {
291 struct enumerator
292 {
293 std::string name;
294 ULONGEST value;
295 };
296
297 using container_type = std::vector<enumerator>;
298 using const_iterator_type = container_type::const_iterator;
299
300 amd_dbgapi_register_type_enum (gdb::string_view name)
301 : amd_dbgapi_register_type (kind::ENUM, make_lookup_name (name)),
302 m_name (name.data (), name.length ())
303 {}
304
305 void set_bit_size (int bit_size)
306 { m_bit_size = bit_size; }
307
308 unsigned int bit_size () const
309 { return m_bit_size; }
310
311 void add_enumerator (std::string name, ULONGEST value)
312 { m_enumerators.push_back (enumerator {std::move (name), value}); }
313
314 container_type::size_type size () const
315 { return m_enumerators.size (); }
316
317 const enumerator &operator[] (container_type::size_type pos) const
318 { return m_enumerators[pos]; }
319
320 const_iterator_type begin () const
321 { return m_enumerators.begin (); }
322
323 const_iterator_type end () const
324 { return m_enumerators.end (); }
325
326 const std::string &name () const
327 { return m_name; }
328
329 static std::string make_lookup_name (gdb::string_view name)
330 {
331 std::string res = "enum ";
332 res.append (name.data (), name.length ());
333 return res;
334 }
335
336 private:
337 unsigned int m_bit_size = 32;
338 container_type m_enumerators;
339 std::string m_name;
340 };
341
342 using amd_dbgapi_register_type_enum_up
343 = std::unique_ptr<amd_dbgapi_register_type_enum>;
344
345 /* Map type lookup names to types. */
346 using amd_dbgapi_register_type_map
347 = std::unordered_map<std::string, amd_dbgapi_register_type_up>;
348
349 /* Parse S as a ULONGEST, raise an error on overflow. */
350
351 static ULONGEST
352 try_strtoulst (gdb::string_view s)
353 {
354 errno = 0;
355 ULONGEST value = strtoulst (s.data (), nullptr, 0);
356 if (errno != 0)
357 error (_("Failed to parse integer."));
358
359 return value;
360 };
361
362 /* Shared regex bits. */
363 #define IDENTIFIER "[A-Za-z0-9_.]+"
364 #define WS "[ \t]+"
365 #define WSOPT "[ \t]*"
366
367 static const amd_dbgapi_register_type &
368 parse_amd_dbgapi_register_type (gdb::string_view type_name,
369 amd_dbgapi_register_type_map &type_map);
370
371
372 /* parse_amd_dbgapi_register_type helper for enum types. */
373
374 static void
375 parse_amd_dbgapi_register_type_enum_fields
376 (amd_dbgapi_register_type_enum &enum_type, gdb::string_view fields)
377 {
378 compiled_regex regex (/* name */
379 "^(" IDENTIFIER ")"
380 WSOPT "=" WSOPT
381 /* value */
382 "([0-9]+)"
383 WSOPT "(," WSOPT ")?",
384 REG_EXTENDED,
385 _("Error in AMDGPU enum register type regex"));
386 regmatch_t matches[4];
387
388 while (!fields.empty ())
389 {
390 int res = regex.exec (fields.data (), ARRAY_SIZE (matches), matches, 0);
391 if (res == REG_NOMATCH)
392 error (_("Failed to parse enum fields"));
393
394 auto sv_from_match = [fields] (const regmatch_t &m)
395 { return fields.substr (m.rm_so, m.rm_eo - m.rm_so); };
396
397 gdb::string_view name = sv_from_match (matches[1]);
398 gdb::string_view value_str = sv_from_match (matches[2]);
399 ULONGEST value = try_strtoulst (value_str);
400
401 if (value > std::numeric_limits<uint32_t>::max ())
402 enum_type.set_bit_size (64);
403
404 enum_type.add_enumerator (gdb::to_string (name), value);
405
406 fields = fields.substr (matches[0].rm_eo);
407 }
408 }
409
410 /* parse_amd_dbgapi_register_type helper for flags types. */
411
412 static void
413 parse_amd_dbgapi_register_type_flags_fields
414 (amd_dbgapi_register_type_flags &flags_type,
415 int bits, gdb::string_view name, gdb::string_view fields,
416 amd_dbgapi_register_type_map &type_map)
417 {
418 gdb_assert (bits == 32 || bits == 64);
419
420 std::string regex_str
421 = string_printf (/* type */
422 "^(bool|uint%d_t|enum" WS IDENTIFIER WSOPT "(\\{[^}]*})?)"
423 WS
424 /* name */
425 "(" IDENTIFIER ")" WSOPT
426 /* bit position */
427 "@([0-9]+)(-[0-9]+)?" WSOPT ";" WSOPT,
428 bits);
429 compiled_regex regex (regex_str.c_str (), REG_EXTENDED,
430 _("Error in AMDGPU register type flags fields regex"));
431 regmatch_t matches[6];
432
433 while (!fields.empty ())
434 {
435 int res = regex.exec (fields.data (), ARRAY_SIZE (matches), matches, 0);
436 if (res == REG_NOMATCH)
437 error (_("Failed to parse flags type fields string"));
438
439 auto sv_from_match = [fields] (const regmatch_t &m)
440 { return fields.substr (m.rm_so, m.rm_eo - m.rm_so); };
441
442 gdb::string_view field_type_str = sv_from_match (matches[1]);
443 gdb::string_view field_name = sv_from_match (matches[3]);
444 gdb::string_view pos_begin_str = sv_from_match (matches[4]);
445 ULONGEST pos_begin = try_strtoulst (pos_begin_str);
446
447 if (field_type_str == "bool")
448 flags_type.add_field (gdb::to_string (field_name), pos_begin, pos_begin,
449 nullptr);
450 else
451 {
452 if (matches[5].rm_so == -1)
453 error (_("Missing end bit position"));
454
455 gdb::string_view pos_end_str = sv_from_match (matches[5]);
456 ULONGEST pos_end = try_strtoulst (pos_end_str.substr (1));
457 const amd_dbgapi_register_type &field_type
458 = parse_amd_dbgapi_register_type (field_type_str, type_map);
459 flags_type.add_field (gdb::to_string (field_name), pos_begin, pos_end,
460 &field_type);
461 }
462
463 fields = fields.substr (matches[0].rm_eo);
464 }
465 }
466
467 /* parse_amd_dbgapi_register_type helper for scalars. */
468
469 static const amd_dbgapi_register_type &
470 parse_amd_dbgapi_register_type_scalar (gdb::string_view name,
471 amd_dbgapi_register_type_map &type_map)
472 {
473 std::string name_str = gdb::to_string (name);
474 auto it = type_map.find (name_str);
475 if (it != type_map.end ())
476 {
477 enum amd_dbgapi_register_type::kind kind = it->second->kind ();
478 if (kind != amd_dbgapi_register_type::kind::INTEGER
479 && kind != amd_dbgapi_register_type::kind::FLOAT
480 && kind != amd_dbgapi_register_type::kind::DOUBLE
481 && kind != amd_dbgapi_register_type::kind::CODE_PTR)
482 error (_("type mismatch"));
483
484 return *it->second;
485 }
486
487 amd_dbgapi_register_type_up type;
488 if (name == "int32_t")
489 type.reset (new amd_dbgapi_register_type_integer (false, 32));
490 else if (name == "uint32_t")
491 type.reset (new amd_dbgapi_register_type_integer (true, 32));
492 else if (name == "int64_t")
493 type.reset (new amd_dbgapi_register_type_integer (false, 64));
494 else if (name == "uint64_t")
495 type.reset (new amd_dbgapi_register_type_integer (true, 64));
496 else if (name == "float")
497 type.reset (new amd_dbgapi_register_type_float ());
498 else if (name == "double")
499 type.reset (new amd_dbgapi_register_type_double ());
500 else if (name == "void (*)()")
501 type.reset (new amd_dbgapi_register_type_code_ptr ());
502 else
503 error (_("unknown type %s"), name_str.c_str ());
504
505 auto insertion_pair = type_map.emplace (name, std::move (type));
506 return *insertion_pair.first->second;
507 }
508
509 /* Parse an amd-dbgapi register type string into an amd_dbgapi_register_type
510 object.
511
512 See the documentation of AMD_DBGAPI_REGISTER_INFO_TYPE in amd-dbgapi.h for
513 details about the format. */
514
515 static const amd_dbgapi_register_type &
516 parse_amd_dbgapi_register_type (gdb::string_view type_str,
517 amd_dbgapi_register_type_map &type_map)
518 {
519 size_t pos_open_bracket = type_str.find_last_of ('[');
520 auto sv_from_match = [type_str] (const regmatch_t &m)
521 { return type_str.substr (m.rm_so, m.rm_eo - m.rm_so); };
522
523 if (pos_open_bracket != gdb::string_view::npos)
524 {
525 /* Vector types. */
526 gdb::string_view element_type_str
527 = type_str.substr (0, pos_open_bracket);
528 const amd_dbgapi_register_type &element_type
529 = parse_amd_dbgapi_register_type (element_type_str, type_map);
530
531 size_t pos_close_bracket = type_str.find_last_of (']');
532 gdb_assert (pos_close_bracket != gdb::string_view::npos);
533 gdb::string_view count_str_view
534 = type_str.substr (pos_open_bracket + 1,
535 pos_close_bracket - pos_open_bracket);
536 std::string count_str = gdb::to_string (count_str_view);
537 unsigned int count = std::stoul (count_str);
538
539 std::string lookup_name
540 = amd_dbgapi_register_type_vector::make_lookup_name (element_type, count);
541 auto existing_type_it = type_map.find (lookup_name);
542 if (existing_type_it != type_map.end ())
543 {
544 gdb_assert (existing_type_it->second->kind ()
545 == amd_dbgapi_register_type::kind::VECTOR);
546 return *existing_type_it->second;
547 }
548
549 amd_dbgapi_register_type_up type
550 (new amd_dbgapi_register_type_vector (element_type, count));
551 auto insertion_pair
552 = type_map.emplace (type->lookup_name (), std::move (type));
553 return *insertion_pair.first->second;
554 }
555
556 if (type_str.find ("flags32_t") == 0 || type_str.find ("flags64_t") == 0)
557 {
558 /* Split 'type_str' into 4 tokens: "(type) (name) ({ (fields) })". */
559 compiled_regex regex ("^(flags32_t|flags64_t)"
560 WS "(" IDENTIFIER ")" WSOPT
561 "(\\{" WSOPT "(.*)})?",
562 REG_EXTENDED,
563 _("Error in AMDGPU register type regex"));
564
565 regmatch_t matches[5];
566 int res = regex.exec (type_str.data (), ARRAY_SIZE (matches), matches, 0);
567 if (res == REG_NOMATCH)
568 error (_("Failed to parse flags type string"));
569
570 gdb::string_view flags_keyword = sv_from_match (matches[1]);
571 unsigned int bit_size = flags_keyword == "flags32_t" ? 32 : 64;
572 gdb::string_view name = sv_from_match (matches[2]);
573 std::string lookup_name
574 = amd_dbgapi_register_type_flags::make_lookup_name (bit_size, name);
575 auto existing_type_it = type_map.find (lookup_name);
576
577 if (matches[3].rm_so == -1)
578 {
579 /* No braces, lookup existing type. */
580 if (existing_type_it == type_map.end ())
581 error (_("reference to unknown type %s."),
582 gdb::to_string (name).c_str ());
583
584 if (existing_type_it->second->kind ()
585 != amd_dbgapi_register_type::kind::FLAGS)
586 error (_("type mismatch"));
587
588 return *existing_type_it->second;
589 }
590 else
591 {
592 /* With braces, it's a definition. */
593 if (existing_type_it != type_map.end ())
594 error (_("re-definition of type %s."),
595 gdb::to_string (name).c_str ());
596
597 amd_dbgapi_register_type_flags_up flags_type
598 (new amd_dbgapi_register_type_flags (bit_size, name));
599 gdb::string_view fields_without_braces = sv_from_match (matches[4]);
600
601 parse_amd_dbgapi_register_type_flags_fields
602 (*flags_type, bit_size, name, fields_without_braces, type_map);
603
604 auto insertion_pair
605 = type_map.emplace (flags_type->lookup_name (),
606 std::move (flags_type));
607 return *insertion_pair.first->second;
608 }
609 }
610
611 if (type_str.find ("enum") == 0)
612 {
613 compiled_regex regex ("^enum" WS "(" IDENTIFIER ")" WSOPT "(\\{" WSOPT "([^}]*)})?",
614 REG_EXTENDED,
615 _("Error in AMDGPU register type enum regex"));
616
617 /* Split 'type_name' into 3 tokens: "(name) ( { (fields) } )". */
618 regmatch_t matches[4];
619 int res = regex.exec (type_str.data (), ARRAY_SIZE (matches), matches, 0);
620 if (res == REG_NOMATCH)
621 error (_("Failed to parse flags type string"));
622
623 gdb::string_view name = sv_from_match (matches[1]);
624
625 std::string lookup_name
626 = amd_dbgapi_register_type_enum::make_lookup_name (name);
627 auto existing_type_it = type_map.find (lookup_name);
628
629 if (matches[2].rm_so == -1)
630 {
631 /* No braces, lookup existing type. */
632 if (existing_type_it == type_map.end ())
633 error (_("reference to unknown type %s"),
634 gdb::to_string (name).c_str ());
635
636 if (existing_type_it->second->kind ()
637 != amd_dbgapi_register_type::kind::ENUM)
638 error (_("type mismatch"));
639
640 return *existing_type_it->second;
641 }
642 else
643 {
644 /* With braces, it's a definition. */
645 if (existing_type_it != type_map.end ())
646 error (_("re-definition of type %s"),
647 gdb::to_string (name).c_str ());
648
649 amd_dbgapi_register_type_enum_up enum_type
650 (new amd_dbgapi_register_type_enum (name));
651 gdb::string_view fields_without_braces = sv_from_match (matches[3]);
652
653 parse_amd_dbgapi_register_type_enum_fields
654 (*enum_type, fields_without_braces);
655
656 auto insertion_pair
657 = type_map.emplace (enum_type->lookup_name (),
658 std::move (enum_type));
659 return *insertion_pair.first->second;
660 }
661 }
662
663 return parse_amd_dbgapi_register_type_scalar (type_str, type_map);
664 }
665
666 /* Convert an amd_dbgapi_register_type object to a GDB type. */
667
668 static type *
669 amd_dbgapi_register_type_to_gdb_type (const amd_dbgapi_register_type &type,
670 struct gdbarch *gdbarch)
671 {
672 switch (type.kind ())
673 {
674 case amd_dbgapi_register_type::kind::INTEGER:
675 {
676 const auto &integer_type
677 = gdb::checked_static_cast<const amd_dbgapi_register_type_integer &>
678 (type);
679 switch (integer_type.bit_size ())
680 {
681 case 32:
682 if (integer_type.is_unsigned ())
683 return builtin_type (gdbarch)->builtin_uint32;
684 else
685 return builtin_type (gdbarch)->builtin_int32;
686
687 case 64:
688 if (integer_type.is_unsigned ())
689 return builtin_type (gdbarch)->builtin_uint64;
690 else
691 return builtin_type (gdbarch)->builtin_int64;
692
693 default:
694 gdb_assert_not_reached ("invalid bit size");
695 }
696 }
697
698 case amd_dbgapi_register_type::kind::VECTOR:
699 {
700 const auto &vector_type
701 = gdb::checked_static_cast<const amd_dbgapi_register_type_vector &>
702 (type);
703 struct type *element_type
704 = amd_dbgapi_register_type_to_gdb_type (vector_type.element_type (),
705 gdbarch);
706 return init_vector_type (element_type, vector_type.count ());
707 }
708
709 case amd_dbgapi_register_type::kind::FLOAT:
710 return builtin_type (gdbarch)->builtin_float;
711
712 case amd_dbgapi_register_type::kind::DOUBLE:
713 return builtin_type (gdbarch)->builtin_double;
714
715 case amd_dbgapi_register_type::kind::CODE_PTR:
716 return builtin_type (gdbarch)->builtin_func_ptr;
717
718 case amd_dbgapi_register_type::kind::FLAGS:
719 {
720 const auto &flags_type
721 = gdb::checked_static_cast<const amd_dbgapi_register_type_flags &>
722 (type);
723 struct type *gdb_type
724 = arch_flags_type (gdbarch, flags_type.name ().c_str (),
725 flags_type.bit_size ());
726
727 for (const auto &field : flags_type)
728 {
729 if (field.type == nullptr)
730 {
731 gdb_assert (field.bit_pos_start == field.bit_pos_end);
732 append_flags_type_flag (gdb_type, field.bit_pos_start,
733 field.name.c_str ());
734 }
735 else
736 {
737 struct type *field_type
738 = amd_dbgapi_register_type_to_gdb_type (*field.type, gdbarch);
739 gdb_assert (field_type != nullptr);
740 append_flags_type_field
741 (gdb_type, field.bit_pos_start,
742 field.bit_pos_end - field.bit_pos_start + 1,
743 field_type, field.name.c_str ());
744 }
745 }
746
747 return gdb_type;
748 }
749
750 case amd_dbgapi_register_type::kind::ENUM:
751 {
752 const auto &enum_type
753 = gdb::checked_static_cast<const amd_dbgapi_register_type_enum &>
754 (type);
755 struct type *gdb_type
756 = (type_allocator (gdbarch)
757 .new_type (TYPE_CODE_ENUM, enum_type.bit_size (),
758 enum_type.name ().c_str ()));
759
760 gdb_type->set_num_fields (enum_type.size ());
761 gdb_type->set_fields
762 ((struct field *) TYPE_ZALLOC (gdb_type, (sizeof (struct field)
763 * enum_type.size ())));
764 gdb_type->set_is_unsigned (true);
765
766 for (size_t i = 0; i < enum_type.size (); ++i)
767 {
768 const auto &field = enum_type[i];
769 gdb_type->field (i).set_name (xstrdup (field.name.c_str ()));
770 gdb_type->field (i).set_loc_enumval (field.value);
771 }
772
773 return gdb_type;
774 }
775
776 default:
777 gdb_assert_not_reached ("unhandled amd_dbgapi_register_type kind");
778 }
779 }
780
781 static type *
782 amdgpu_register_type (struct gdbarch *gdbarch, int regnum)
783 {
784 amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);
785
786 if (tdep->register_types[regnum] == nullptr)
787 {
788 /* This is done lazily (not at gdbarch initialization time), because it
789 requires access to builtin_type, which can't be used while the gdbarch
790 is not fully initialized. */
791 char *bytes;
792 amd_dbgapi_status_t status
793 = amd_dbgapi_register_get_info (tdep->register_ids[regnum],
794 AMD_DBGAPI_REGISTER_INFO_TYPE,
795 sizeof (bytes), &bytes);
796 if (status != AMD_DBGAPI_STATUS_SUCCESS)
797 error (_("Failed to get register type from amd-dbgapi"));
798
799 gdb::unique_xmalloc_ptr<char> bytes_holder (bytes);
800 amd_dbgapi_register_type_map type_map;
801 const amd_dbgapi_register_type &register_type
802 = parse_amd_dbgapi_register_type (bytes, type_map);
803 tdep->register_types[regnum]
804 = amd_dbgapi_register_type_to_gdb_type (register_type, gdbarch);
805 gdb_assert (tdep->register_types[regnum] != nullptr);
806 }
807
808 return tdep->register_types[regnum];
809 }
810
811 static int
812 amdgpu_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
813 const reggroup *group)
814 {
815 amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);
816
817 auto it = tdep->register_class_map.find (group->name ());
818 if (it == tdep->register_class_map.end ())
819 return group == all_reggroup;
820
821 amd_dbgapi_register_class_state_t state;
822 if (amd_dbgapi_register_is_in_register_class (it->second,
823 tdep->register_ids[regnum],
824 &state)
825 != AMD_DBGAPI_STATUS_SUCCESS)
826 return group == all_reggroup;
827
828 return (state == AMD_DBGAPI_REGISTER_CLASS_STATE_MEMBER
829 || group == all_reggroup);
830 }
831
832 static int
833 amdgpu_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *)
834 {
835 return get_amdgpu_gdbarch_tdep (gdbarch)->breakpoint_instruction_size;
836 }
837
838 static const gdb_byte *
839 amdgpu_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
840 {
841 *size = kind;
842 return get_amdgpu_gdbarch_tdep (gdbarch)->breakpoint_instruction_bytes.get ();
843 }
844
845 struct amdgpu_frame_cache
846 {
847 CORE_ADDR base;
848 CORE_ADDR pc;
849 };
850
851 static amdgpu_frame_cache *
852 amdgpu_frame_cache (frame_info_ptr this_frame, void **this_cache)
853 {
854 if (*this_cache != nullptr)
855 return (struct amdgpu_frame_cache *) *this_cache;
856
857 struct amdgpu_frame_cache *cache
858 = FRAME_OBSTACK_ZALLOC (struct amdgpu_frame_cache);
859 (*this_cache) = cache;
860
861 cache->pc = get_frame_func (this_frame);
862 cache->base = 0;
863
864 return cache;
865 }
866
867 static void
868 amdgpu_frame_this_id (frame_info_ptr this_frame, void **this_cache,
869 frame_id *this_id)
870 {
871 struct amdgpu_frame_cache *cache
872 = amdgpu_frame_cache (this_frame, this_cache);
873
874 if (get_frame_type (this_frame) == INLINE_FRAME)
875 (*this_id) = frame_id_build (cache->base, cache->pc);
876 else
877 (*this_id) = outer_frame_id;
878
879 frame_debug_printf ("this_frame=%d, type=%d, this_id=%s",
880 frame_relative_level (this_frame),
881 get_frame_type (this_frame),
882 this_id->to_string ().c_str ());
883 }
884
885 static frame_id
886 amdgpu_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
887 {
888 return frame_id_build (0, get_frame_pc (this_frame));
889 }
890
891 static struct value *
892 amdgpu_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
893 int regnum)
894 {
895 return frame_unwind_got_register (this_frame, regnum, regnum);
896 }
897
898 static const frame_unwind amdgpu_frame_unwind = {
899 "amdgpu",
900 NORMAL_FRAME,
901 default_frame_unwind_stop_reason,
902 amdgpu_frame_this_id,
903 amdgpu_frame_prev_register,
904 nullptr,
905 default_frame_sniffer,
906 nullptr,
907 nullptr,
908 };
909
910 static int
911 print_insn_amdgpu (bfd_vma memaddr, struct disassemble_info *info)
912 {
913 gdb_disassemble_info *di
914 = static_cast<gdb_disassemble_info *> (info->application_data);
915
916 /* Try to read at most INSTRUCTION_SIZE bytes. */
917
918 amd_dbgapi_size_t instruction_size = gdbarch_max_insn_length (di->arch ());
919 gdb::byte_vector buffer (instruction_size);
920
921 /* read_memory_func doesn't support partial reads, so if the read
922 fails, try one byte less, on and on until we manage to read
923 something. A case where this would happen is if we're trying to
924 read the last instruction at the end of a file section and that
925 instruction is smaller than the largest instruction. */
926 while (instruction_size > 0)
927 {
928 int ret = info->read_memory_func (memaddr, buffer.data (),
929 instruction_size, info);
930 if (ret == 0)
931 break;
932
933 --instruction_size;
934 }
935
936 if (instruction_size == 0)
937 {
938 info->memory_error_func (-1, memaddr, info);
939 return -1;
940 }
941
942 amd_dbgapi_architecture_id_t architecture_id;
943 amd_dbgapi_status_t status
944 = amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (di->arch ())->mach,
945 &architecture_id);
946 if (status != AMD_DBGAPI_STATUS_SUCCESS)
947 return -1;
948
949 auto symbolizer = [] (amd_dbgapi_symbolizer_id_t symbolizer_id,
950 amd_dbgapi_global_address_t address,
951 char **symbol_text) -> amd_dbgapi_status_t
952 {
953 gdb_disassemble_info *disasm_info
954 = reinterpret_cast<gdb_disassemble_info *> (symbolizer_id);
955 gdb_printing_disassembler *disasm
956 = dynamic_cast<gdb_printing_disassembler *> (disasm_info);
957 gdb_assert (disasm != nullptr);
958
959 string_file string (disasm->stream ()->can_emit_style_escape ());
960 print_address (disasm->arch (), address, &string);
961 *symbol_text = xstrdup (string.c_str ());
962
963 return AMD_DBGAPI_STATUS_SUCCESS;
964 };
965 auto symbolizer_id = reinterpret_cast<amd_dbgapi_symbolizer_id_t> (di);
966 char *instruction_text = nullptr;
967 status = amd_dbgapi_disassemble_instruction (architecture_id, memaddr,
968 &instruction_size,
969 buffer.data (),
970 &instruction_text,
971 symbolizer_id,
972 symbolizer);
973 if (status != AMD_DBGAPI_STATUS_SUCCESS)
974 {
975 size_t alignment;
976 status = amd_dbgapi_architecture_get_info
977 (architecture_id,
978 AMD_DBGAPI_ARCHITECTURE_INFO_MINIMUM_INSTRUCTION_ALIGNMENT,
979 sizeof (alignment), &alignment);
980 if (status != AMD_DBGAPI_STATUS_SUCCESS)
981 error (_("amd_dbgapi_architecture_get_info failed"));
982
983 info->fprintf_func (di, "<illegal instruction>");
984
985 /* Skip to the next valid instruction address. */
986 return align_up (memaddr + 1, alignment) - memaddr;
987 }
988
989 /* Print the instruction. */
990 info->fprintf_func (di, "%s", instruction_text);
991
992 /* Free the memory allocated by the amd-dbgapi. */
993 xfree (instruction_text);
994
995 return static_cast<int> (instruction_size);
996 }
997
998 static CORE_ADDR
999 amdgpu_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
1000 {
1001 CORE_ADDR func_addr;
1002
1003 /* See if we can determine the end of the prologue via the symbol table.
1004 If so, then return either PC, or the PC after the prologue, whichever
1005 is greater. */
1006 if (find_pc_partial_function (start_pc, nullptr, &func_addr, nullptr))
1007 {
1008 CORE_ADDR post_prologue_pc
1009 = skip_prologue_using_sal (gdbarch, func_addr);
1010 struct compunit_symtab *cust = find_pc_compunit_symtab (func_addr);
1011
1012 /* Clang always emits a line note before the prologue and another
1013 one after. We trust clang to emit usable line notes. */
1014 if (post_prologue_pc != 0
1015 && cust != nullptr
1016 && cust->producer () != nullptr
1017 && producer_is_llvm (cust->producer ()))
1018 return std::max (start_pc, post_prologue_pc);
1019 }
1020
1021 return start_pc;
1022 }
1023
1024 static bool
1025 amdgpu_supports_arch_info (const struct bfd_arch_info *info)
1026 {
1027 amd_dbgapi_architecture_id_t architecture_id;
1028 amd_dbgapi_status_t status
1029 = amd_dbgapi_get_architecture (info->mach, &architecture_id);
1030
1031 gdb_assert (status != AMD_DBGAPI_STATUS_ERROR_NOT_INITIALIZED);
1032 return status == AMD_DBGAPI_STATUS_SUCCESS;
1033 }
1034
1035 static struct gdbarch *
1036 amdgpu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1037 {
1038 /* If there is already a candidate, use it. */
1039 arches = gdbarch_list_lookup_by_info (arches, &info);
1040 if (arches != nullptr)
1041 return arches->gdbarch;
1042
1043 /* Allocate space for the new architecture. */
1044 gdbarch_up gdbarch_u
1045 (gdbarch_alloc (&info, gdbarch_tdep_up (new amdgpu_gdbarch_tdep)));
1046 gdbarch *gdbarch = gdbarch_u.get ();
1047 amdgpu_gdbarch_tdep *tdep = gdbarch_tdep<amdgpu_gdbarch_tdep> (gdbarch);
1048
1049 /* Data types. */
1050 set_gdbarch_char_signed (gdbarch, 0);
1051 set_gdbarch_ptr_bit (gdbarch, 64);
1052 set_gdbarch_addr_bit (gdbarch, 64);
1053 set_gdbarch_short_bit (gdbarch, 16);
1054 set_gdbarch_int_bit (gdbarch, 32);
1055 set_gdbarch_long_bit (gdbarch, 64);
1056 set_gdbarch_long_long_bit (gdbarch, 64);
1057 set_gdbarch_float_bit (gdbarch, 32);
1058 set_gdbarch_double_bit (gdbarch, 64);
1059 set_gdbarch_long_double_bit (gdbarch, 128);
1060 set_gdbarch_half_format (gdbarch, floatformats_ieee_half);
1061 set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
1062 set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
1063 set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
1064
1065 /* Frame interpretation. */
1066 set_gdbarch_skip_prologue (gdbarch, amdgpu_skip_prologue);
1067 set_gdbarch_inner_than (gdbarch, core_addr_greaterthan);
1068 dwarf2_append_unwinders (gdbarch);
1069 frame_unwind_append_unwinder (gdbarch, &amdgpu_frame_unwind);
1070 set_gdbarch_dummy_id (gdbarch, amdgpu_dummy_id);
1071
1072 /* Registers and memory. */
1073 amd_dbgapi_architecture_id_t architecture_id;
1074 amd_dbgapi_status_t status
1075 = amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch)->mach,
1076 &architecture_id);
1077 if (status != AMD_DBGAPI_STATUS_SUCCESS)
1078 {
1079 warning (_("Failed to get architecture from amd-dbgapi"));
1080 return nullptr;
1081 }
1082
1083
1084 /* Add register groups. */
1085 size_t register_class_count;
1086 amd_dbgapi_register_class_id_t *register_class_ids;
1087 status = amd_dbgapi_architecture_register_class_list (architecture_id,
1088 &register_class_count,
1089 &register_class_ids);
1090 if (status != AMD_DBGAPI_STATUS_SUCCESS)
1091 {
1092 warning (_("Failed to get register class list from amd-dbgapi"));
1093 return nullptr;
1094 }
1095
1096 gdb::unique_xmalloc_ptr<amd_dbgapi_register_class_id_t>
1097 register_class_ids_holder (register_class_ids);
1098
1099 for (size_t i = 0; i < register_class_count; ++i)
1100 {
1101 char *bytes;
1102 status = amd_dbgapi_architecture_register_class_get_info
1103 (register_class_ids[i], AMD_DBGAPI_REGISTER_CLASS_INFO_NAME,
1104 sizeof (bytes), &bytes);
1105 if (status != AMD_DBGAPI_STATUS_SUCCESS)
1106 {
1107 warning (_("Failed to get register class name from amd-dbgapi"));
1108 return nullptr;
1109 }
1110
1111 gdb::unique_xmalloc_ptr<char> name (bytes);
1112
1113 auto inserted = tdep->register_class_map.emplace (name.get (),
1114 register_class_ids[i]);
1115 gdb_assert (inserted.second);
1116
1117 /* Avoid creating a user reggroup with the same name as some built-in
1118 reggroup, such as "general", "system", "vector", etc. */
1119 if (reggroup_find (gdbarch, name.get ()) != nullptr)
1120 continue;
1121
1122 /* Allocate the reggroup in the gdbarch. */
1123 reggroup_add
1124 (gdbarch, reggroup_gdbarch_new (gdbarch, name.get (), USER_REGGROUP));
1125 }
1126
1127 /* Add registers. */
1128 size_t register_count;
1129 amd_dbgapi_register_id_t *register_ids;
1130 status = amd_dbgapi_architecture_register_list (architecture_id,
1131 &register_count,
1132 &register_ids);
1133 if (status != AMD_DBGAPI_STATUS_SUCCESS)
1134 {
1135 warning (_("Failed to get register list from amd-dbgapi"));
1136 return nullptr;
1137 }
1138
1139 gdb::unique_xmalloc_ptr<amd_dbgapi_register_id_t> register_ids_holder
1140 (register_ids);
1141
1142 tdep->register_ids.insert (tdep->register_ids.end (), &register_ids[0],
1143 &register_ids[register_count]);
1144
1145 tdep->register_properties.resize (register_count,
1146 AMD_DBGAPI_REGISTER_PROPERTY_NONE);
1147 for (size_t regnum = 0; regnum < register_count; ++regnum)
1148 {
1149 auto &register_properties = tdep->register_properties[regnum];
1150 if (amd_dbgapi_register_get_info (register_ids[regnum],
1151 AMD_DBGAPI_REGISTER_INFO_PROPERTIES,
1152 sizeof (register_properties),
1153 &register_properties)
1154 != AMD_DBGAPI_STATUS_SUCCESS)
1155 {
1156 warning (_("Failed to get register properties from amd-dbgapi"));
1157 return nullptr;
1158 }
1159 }
1160
1161 set_gdbarch_num_regs (gdbarch, register_count);
1162 set_gdbarch_num_pseudo_regs (gdbarch, 0);
1163
1164 tdep->register_names.resize (register_count);
1165 tdep->register_types.resize (register_count);
1166 for (size_t i = 0; i < register_count; ++i)
1167 {
1168 /* Set amd-dbgapi register id -> gdb regnum mapping. */
1169 tdep->regnum_map.emplace (tdep->register_ids[i], i);
1170
1171 /* Get register name. */
1172 char *bytes;
1173 status = amd_dbgapi_register_get_info (tdep->register_ids[i],
1174 AMD_DBGAPI_REGISTER_INFO_NAME,
1175 sizeof (bytes), &bytes);
1176 if (status == AMD_DBGAPI_STATUS_SUCCESS)
1177 {
1178 tdep->register_names[i] = bytes;
1179 xfree (bytes);
1180 }
1181
1182 /* Get register DWARF number. */
1183 uint64_t dwarf_num;
1184 status = amd_dbgapi_register_get_info (tdep->register_ids[i],
1185 AMD_DBGAPI_REGISTER_INFO_DWARF,
1186 sizeof (dwarf_num), &dwarf_num);
1187 if (status == AMD_DBGAPI_STATUS_SUCCESS)
1188 {
1189 if (dwarf_num >= tdep->dwarf_regnum_to_gdb_regnum.size ())
1190 tdep->dwarf_regnum_to_gdb_regnum.resize (dwarf_num + 1, -1);
1191
1192 tdep->dwarf_regnum_to_gdb_regnum[dwarf_num] = i;
1193 }
1194 }
1195
1196 amd_dbgapi_register_id_t pc_register_id;
1197 status = amd_dbgapi_architecture_get_info
1198 (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_PC_REGISTER,
1199 sizeof (pc_register_id), &pc_register_id);
1200 if (status != AMD_DBGAPI_STATUS_SUCCESS)
1201 {
1202 warning (_("Failed to get PC register from amd-dbgapi"));
1203 return nullptr;
1204 }
1205
1206 set_gdbarch_pc_regnum (gdbarch, tdep->regnum_map[pc_register_id]);
1207 set_gdbarch_ps_regnum (gdbarch, -1);
1208 set_gdbarch_sp_regnum (gdbarch, -1);
1209 set_gdbarch_fp0_regnum (gdbarch, -1);
1210
1211 set_gdbarch_dwarf2_reg_to_regnum (gdbarch, amdgpu_dwarf_reg_to_regnum);
1212
1213 set_gdbarch_return_value_as_value (gdbarch, amdgpu_return_value_as_value);
1214
1215 /* Register representation. */
1216 set_gdbarch_register_name (gdbarch, amdgpu_register_name);
1217 set_gdbarch_register_type (gdbarch, amdgpu_register_type);
1218 set_gdbarch_register_reggroup_p (gdbarch, amdgpu_register_reggroup_p);
1219
1220 /* Disassembly. */
1221 set_gdbarch_print_insn (gdbarch, print_insn_amdgpu);
1222
1223 /* Instructions. */
1224 amd_dbgapi_size_t max_insn_length = 0;
1225 status = amd_dbgapi_architecture_get_info
1226 (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_LARGEST_INSTRUCTION_SIZE,
1227 sizeof (max_insn_length), &max_insn_length);
1228 if (status != AMD_DBGAPI_STATUS_SUCCESS)
1229 error (_("amd_dbgapi_architecture_get_info failed"));
1230
1231 set_gdbarch_max_insn_length (gdbarch, max_insn_length);
1232
1233 status = amd_dbgapi_architecture_get_info
1234 (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_SIZE,
1235 sizeof (tdep->breakpoint_instruction_size),
1236 &tdep->breakpoint_instruction_size);
1237 if (status != AMD_DBGAPI_STATUS_SUCCESS)
1238 error (_("amd_dbgapi_architecture_get_info failed"));
1239
1240 gdb_byte *breakpoint_instruction_bytes;
1241 status = amd_dbgapi_architecture_get_info
1242 (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION,
1243 sizeof (breakpoint_instruction_bytes), &breakpoint_instruction_bytes);
1244 if (status != AMD_DBGAPI_STATUS_SUCCESS)
1245 error (_("amd_dbgapi_architecture_get_info failed"));
1246
1247 tdep->breakpoint_instruction_bytes.reset (breakpoint_instruction_bytes);
1248
1249 set_gdbarch_breakpoint_kind_from_pc (gdbarch,
1250 amdgpu_breakpoint_kind_from_pc);
1251 set_gdbarch_sw_breakpoint_from_kind (gdbarch,
1252 amdgpu_sw_breakpoint_from_kind);
1253
1254 amd_dbgapi_size_t pc_adjust;
1255 status = amd_dbgapi_architecture_get_info
1256 (architecture_id,
1257 AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_PC_ADJUST,
1258 sizeof (pc_adjust), &pc_adjust);
1259 if (status != AMD_DBGAPI_STATUS_SUCCESS)
1260 error (_("amd_dbgapi_architecture_get_info failed"));
1261
1262 set_gdbarch_decr_pc_after_break (gdbarch, pc_adjust);
1263
1264 return gdbarch_u.release ();
1265 }
1266
1267 #if defined GDB_SELF_TEST
1268
1269 static void
1270 amdgpu_register_type_parse_test ()
1271 {
1272 {
1273 /* A type that exercises flags and enums, in particular looking up an
1274 existing enum type by name. */
1275 const char *flags_type_str =
1276 "flags32_t mode { \
1277 enum fp_round { \
1278 NEAREST_EVEN = 0, \
1279 PLUS_INF = 1, \
1280 MINUS_INF = 2, \
1281 ZERO = 3 \
1282 } FP_ROUND.32 @0-1; \
1283 enum fp_round FP_ROUND.64_16 @2-3; \
1284 enum fp_denorm { \
1285 FLUSH_SRC_DST = 0, \
1286 FLUSH_DST = 1, \
1287 FLUSH_SRC = 2, \
1288 FLUSH_NONE = 3 \
1289 } FP_DENORM.32 @4-5; \
1290 enum fp_denorm FP_DENORM.64_16 @6-7; \
1291 bool DX10_CLAMP @8; \
1292 bool IEEE @9; \
1293 bool LOD_CLAMPED @10; \
1294 bool DEBUG_EN @11; \
1295 bool EXCP_EN.INVALID @12; \
1296 bool EXCP_EN.DENORM @13; \
1297 bool EXCP_EN.DIV0 @14; \
1298 bool EXCP_EN.OVERFLOW @15; \
1299 bool EXCP_EN.UNDERFLOW @16; \
1300 bool EXCP_EN.INEXACT @17; \
1301 bool EXCP_EN.INT_DIV0 @18; \
1302 bool EXCP_EN.ADDR_WATCH @19; \
1303 bool FP16_OVFL @23; \
1304 bool POPS_PACKER0 @24; \
1305 bool POPS_PACKER1 @25; \
1306 bool DISABLE_PERF @26; \
1307 bool GPR_IDX_EN @27; \
1308 bool VSKIP @28; \
1309 uint32_t CSP @29-31; \
1310 }";
1311 amd_dbgapi_register_type_map type_map;
1312 const amd_dbgapi_register_type &type
1313 = parse_amd_dbgapi_register_type (flags_type_str, type_map);
1314
1315 gdb_assert (type.kind () == amd_dbgapi_register_type::kind::FLAGS);
1316
1317 const auto &f
1318 = gdb::checked_static_cast<const amd_dbgapi_register_type_flags &> (type);
1319 gdb_assert (f.size () == 23);
1320
1321 /* Check the two "FP_ROUND" fields. */
1322 auto check_fp_round_field
1323 = [] (const char *name, const amd_dbgapi_register_type_flags::field &field)
1324 {
1325 gdb_assert (field.name == name);
1326 gdb_assert (field.type->kind ()
1327 == amd_dbgapi_register_type::kind::ENUM);
1328
1329 const auto &e
1330 = gdb::checked_static_cast<const amd_dbgapi_register_type_enum &>
1331 (*field.type);
1332 gdb_assert (e.size () == 4);
1333 gdb_assert (e[0].name == "NEAREST_EVEN");
1334 gdb_assert (e[0].value == 0);
1335 gdb_assert (e[3].name == "ZERO");
1336 gdb_assert (e[3].value == 3);
1337 };
1338
1339 check_fp_round_field ("FP_ROUND.32", f[0]);
1340 check_fp_round_field ("FP_ROUND.64_16", f[1]);
1341
1342 /* Check the "CSP" field. */
1343 gdb_assert (f[22].name == "CSP");
1344 gdb_assert (f[22].type->kind () == amd_dbgapi_register_type::kind::INTEGER);
1345
1346 const auto &i
1347 = gdb::checked_static_cast<const amd_dbgapi_register_type_integer &>
1348 (*f[22].type);
1349 gdb_assert (i.bit_size () == 32);
1350 gdb_assert (i.is_unsigned ());
1351 }
1352
1353 {
1354 /* Test the vector type. */
1355 const char *vector_type_str = "int32_t[64]";
1356 amd_dbgapi_register_type_map type_map;
1357 const amd_dbgapi_register_type &type
1358 = parse_amd_dbgapi_register_type (vector_type_str, type_map);
1359
1360 gdb_assert (type.kind () == amd_dbgapi_register_type::kind::VECTOR);
1361
1362 const auto &v
1363 = gdb::checked_static_cast<const amd_dbgapi_register_type_vector &>
1364 (type);
1365 gdb_assert (v.count () == 64);
1366
1367 const auto &et = v.element_type ();
1368 gdb_assert (et.kind () == amd_dbgapi_register_type::kind::INTEGER);
1369
1370 const auto &i
1371 = gdb::checked_static_cast<const amd_dbgapi_register_type_integer &> (et);
1372 gdb_assert (i.bit_size () == 32);
1373 gdb_assert (!i.is_unsigned ());
1374 }
1375 }
1376
1377 #endif
1378
1379 void _initialize_amdgpu_tdep ();
1380
1381 void
1382 _initialize_amdgpu_tdep ()
1383 {
1384 gdbarch_register (bfd_arch_amdgcn, amdgpu_gdbarch_init, NULL,
1385 amdgpu_supports_arch_info);
1386 #if defined GDB_SELF_TEST
1387 selftests::register_test ("amdgpu-register-type-parse-flags-fields",
1388 amdgpu_register_type_parse_test);
1389 #endif
1390 }