1 /* Target-dependent code for the AMDGPU architectures.
3 Copyright (C) 2019-2023 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
22 #include "amd-dbgapi-target.h"
23 #include "amdgpu-tdep.h"
24 #include "arch-utils.h"
26 #include "dwarf2/frame.h"
27 #include "frame-unwind.h"
29 #include "gdbsupport/selftest.h"
33 #include "observable.h"
35 #include "reggroups.h"
37 /* See amdgpu-tdep.h. */
40 is_amdgpu_arch (struct gdbarch
*arch
)
42 gdb_assert (arch
!= nullptr);
43 return gdbarch_bfd_arch_info (arch
)->arch
== bfd_arch_amdgcn
;
46 /* See amdgpu-tdep.h. */
49 get_amdgpu_gdbarch_tdep (gdbarch
*arch
)
51 return gdbarch_tdep
<amdgpu_gdbarch_tdep
> (arch
);
54 /* Dummy implementation of gdbarch_return_value_as_value. */
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
)
61 gdb_assert_not_reached ("not implemented");
64 /* Return the name of register REGNUM. */
67 amdgpu_register_name (struct gdbarch
*gdbarch
, int regnum
)
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
78 But there are two known cases where INFERIOR_PTID doesn't represent a GPU
81 - The user does "set arch amdgcn:gfxNNN" followed with "maint print
83 - The "register_name" selftest
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
))
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
);
96 amd_dbgapi_register_exists_t register_exists
;
97 if (amd_dbgapi_wave_register_exists (wave_id
, tdep
->register_ids
[regnum
],
99 != AMD_DBGAPI_STATUS_SUCCESS
100 || register_exists
!= AMD_DBGAPI_REGISTER_PRESENT
)
103 return tdep
->register_names
[regnum
].c_str ();
106 /* Return the internal register number for the DWARF register number DWARF_REG.
108 Return -1 if there's no internal register mapping to DWARF_REG. */
111 amdgpu_dwarf_reg_to_regnum (struct gdbarch
*gdbarch
, int dwarf_reg
)
113 amdgpu_gdbarch_tdep
*tdep
= get_amdgpu_gdbarch_tdep (gdbarch
);
115 if (dwarf_reg
< tdep
->dwarf_regnum_to_gdb_regnum
.size ())
116 return tdep
->dwarf_regnum_to_gdb_regnum
[dwarf_reg
];
121 /* A hierarchy of classes to represent an amd-dbgapi register type. */
123 struct amd_dbgapi_register_type
136 amd_dbgapi_register_type (kind kind
, std::string lookup_name
)
137 : m_kind (kind
), m_lookup_name (std::move (lookup_name
))
140 virtual ~amd_dbgapi_register_type () = default;
142 /* Return the type's kind. */
146 /* Name to use for this type in the existing type map. */
147 const std::string
&lookup_name () const
148 { return m_lookup_name
; }
152 std::string m_lookup_name
;
155 using amd_dbgapi_register_type_up
= std::unique_ptr
<amd_dbgapi_register_type
>;
157 struct amd_dbgapi_register_type_integer
: public amd_dbgapi_register_type
159 amd_dbgapi_register_type_integer (bool is_unsigned
, unsigned int bit_size
)
160 : amd_dbgapi_register_type
162 string_printf ("%sint%d", is_unsigned
? "u" : "", bit_size
)),
163 m_is_unsigned (is_unsigned
),
164 m_bit_size (bit_size
)
167 bool is_unsigned () const
168 { return m_is_unsigned
; }
170 unsigned int bit_size () const
171 { return m_bit_size
; }
175 unsigned int m_bit_size
;
178 struct amd_dbgapi_register_type_float
: public amd_dbgapi_register_type
180 amd_dbgapi_register_type_float ()
181 : amd_dbgapi_register_type (kind::FLOAT
, "float")
185 struct amd_dbgapi_register_type_double
: public amd_dbgapi_register_type
187 amd_dbgapi_register_type_double ()
188 : amd_dbgapi_register_type (kind::DOUBLE
, "double")
192 struct amd_dbgapi_register_type_vector
: public amd_dbgapi_register_type
194 amd_dbgapi_register_type_vector (const amd_dbgapi_register_type
&element_type
,
196 : amd_dbgapi_register_type (kind::VECTOR
,
197 make_lookup_name (element_type
, count
)),
198 m_element_type (element_type
),
202 const amd_dbgapi_register_type
&element_type () const
203 { return m_element_type
; }
205 unsigned int count () const
208 static std::string make_lookup_name
209 (const amd_dbgapi_register_type
&element_type
, unsigned int count
)
211 return string_printf ("%s[%d]", element_type
.lookup_name ().c_str (),
216 const amd_dbgapi_register_type
&m_element_type
;
217 unsigned int m_count
;
220 struct amd_dbgapi_register_type_code_ptr
: public amd_dbgapi_register_type
222 amd_dbgapi_register_type_code_ptr ()
223 : amd_dbgapi_register_type (kind::CODE_PTR
, "void (*)()")
227 struct amd_dbgapi_register_type_flags
: public amd_dbgapi_register_type
232 unsigned int bit_pos_start
;
233 unsigned int bit_pos_end
;
234 const amd_dbgapi_register_type
*type
;
237 using container_type
= std::vector
<field
>;
238 using const_iterator_type
= container_type::const_iterator
;
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
))
247 unsigned int bit_size () const
248 { return m_bit_size
; }
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
)
254 m_fields
.push_back (field
{std::move (name
), bit_pos_start
,
258 container_type::size_type
size () const
259 { return m_fields
.size (); }
261 const field
&operator[] (container_type::size_type pos
) const
262 { return m_fields
[pos
]; }
264 const_iterator_type
begin () const
265 { return m_fields
.begin (); }
267 const_iterator_type
end () const
268 { return m_fields
.end (); }
270 const std::string
&name () const
273 static std::string
make_lookup_name (int bits
, gdb::string_view name
)
275 std::string res
= string_printf ("flags%d_t ", bits
);
276 res
.append (name
.data (), name
.size ());
281 unsigned int m_bit_size
;
282 container_type m_fields
;
286 using amd_dbgapi_register_type_flags_up
287 = std::unique_ptr
<amd_dbgapi_register_type_flags
>;
289 struct amd_dbgapi_register_type_enum
: public amd_dbgapi_register_type
297 using container_type
= std::vector
<enumerator
>;
298 using const_iterator_type
= container_type::const_iterator
;
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 ())
305 void set_bit_size (int bit_size
)
306 { m_bit_size
= bit_size
; }
308 unsigned int bit_size () const
309 { return m_bit_size
; }
311 void add_enumerator (std::string name
, ULONGEST value
)
312 { m_enumerators
.push_back (enumerator
{std::move (name
), value
}); }
314 container_type::size_type
size () const
315 { return m_enumerators
.size (); }
317 const enumerator
&operator[] (container_type::size_type pos
) const
318 { return m_enumerators
[pos
]; }
320 const_iterator_type
begin () const
321 { return m_enumerators
.begin (); }
323 const_iterator_type
end () const
324 { return m_enumerators
.end (); }
326 const std::string
&name () const
329 static std::string
make_lookup_name (gdb::string_view name
)
331 std::string res
= "enum ";
332 res
.append (name
.data (), name
.length ());
337 unsigned int m_bit_size
= 32;
338 container_type m_enumerators
;
342 using amd_dbgapi_register_type_enum_up
343 = std::unique_ptr
<amd_dbgapi_register_type_enum
>;
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
>;
349 /* Parse S as a ULONGEST, raise an error on overflow. */
352 try_strtoulst (gdb::string_view s
)
355 ULONGEST value
= strtoulst (s
.data (), nullptr, 0);
357 error (_("Failed to parse integer."));
362 /* Shared regex bits. */
363 #define IDENTIFIER "[A-Za-z0-9_.]+"
365 #define WSOPT "[ \t]*"
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
);
372 /* parse_amd_dbgapi_register_type helper for enum types. */
375 parse_amd_dbgapi_register_type_enum_fields
376 (amd_dbgapi_register_type_enum
&enum_type
, gdb::string_view fields
)
378 compiled_regex
regex (/* name */
383 WSOPT
"(," WSOPT
")?",
385 _("Error in AMDGPU enum register type regex"));
386 regmatch_t matches
[4];
388 while (!fields
.empty ())
390 int res
= regex
.exec (fields
.data (), ARRAY_SIZE (matches
), matches
, 0);
391 if (res
== REG_NOMATCH
)
392 error (_("Failed to parse enum fields"));
394 auto sv_from_match
= [fields
] (const regmatch_t
&m
)
395 { return fields
.substr (m
.rm_so
, m
.rm_eo
- m
.rm_so
); };
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
);
401 if (value
> std::numeric_limits
<uint32_t>::max ())
402 enum_type
.set_bit_size (64);
404 enum_type
.add_enumerator (gdb::to_string (name
), value
);
406 fields
= fields
.substr (matches
[0].rm_eo
);
410 /* parse_amd_dbgapi_register_type helper for flags types. */
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
)
418 gdb_assert (bits
== 32 || bits
== 64);
420 std::string regex_str
421 = string_printf (/* type */
422 "^(bool|uint%d_t|enum" WS IDENTIFIER WSOPT
"(\\{[^}]*})?)"
425 "(" IDENTIFIER
")" WSOPT
427 "@([0-9]+)(-[0-9]+)?" WSOPT
";" WSOPT
,
429 compiled_regex
regex (regex_str
.c_str (), REG_EXTENDED
,
430 _("Error in AMDGPU register type flags fields regex"));
431 regmatch_t matches
[6];
433 while (!fields
.empty ())
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"));
439 auto sv_from_match
= [fields
] (const regmatch_t
&m
)
440 { return fields
.substr (m
.rm_so
, m
.rm_eo
- m
.rm_so
); };
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
);
447 if (field_type_str
== "bool")
448 flags_type
.add_field (gdb::to_string (field_name
), pos_begin
, pos_begin
,
452 if (matches
[5].rm_so
== -1)
453 error (_("Missing end bit position"));
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
,
463 fields
= fields
.substr (matches
[0].rm_eo
);
467 /* parse_amd_dbgapi_register_type helper for scalars. */
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
)
473 std::string name_str
= gdb::to_string (name
);
474 auto it
= type_map
.find (name_str
);
475 if (it
!= type_map
.end ())
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"));
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 ());
503 error (_("unknown type %s"), name_str
.c_str ());
505 auto insertion_pair
= type_map
.emplace (name
, std::move (type
));
506 return *insertion_pair
.first
->second
;
509 /* Parse an amd-dbgapi register type string into an amd_dbgapi_register_type
512 See the documentation of AMD_DBGAPI_REGISTER_INFO_TYPE in amd-dbgapi.h for
513 details about the format. */
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
)
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
); };
523 if (pos_open_bracket
!= gdb::string_view::npos
)
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
);
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
);
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 ())
544 gdb_assert (existing_type_it
->second
->kind ()
545 == amd_dbgapi_register_type::kind::VECTOR
);
546 return *existing_type_it
->second
;
549 amd_dbgapi_register_type_up type
550 (new amd_dbgapi_register_type_vector (element_type
, count
));
552 = type_map
.emplace (type
->lookup_name (), std::move (type
));
553 return *insertion_pair
.first
->second
;
556 if (type_str
.find ("flags32_t") == 0 || type_str
.find ("flags64_t") == 0)
558 /* Split 'type_str' into 4 tokens: "(type) (name) ({ (fields) })". */
559 compiled_regex
regex ("^(flags32_t|flags64_t)"
560 WS
"(" IDENTIFIER
")" WSOPT
561 "(\\{" WSOPT
"(.*)})?",
563 _("Error in AMDGPU register type regex"));
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"));
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
);
577 if (matches
[3].rm_so
== -1)
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 ());
584 if (existing_type_it
->second
->kind ()
585 != amd_dbgapi_register_type::kind::FLAGS
)
586 error (_("type mismatch"));
588 return *existing_type_it
->second
;
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 ());
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]);
601 parse_amd_dbgapi_register_type_flags_fields
602 (*flags_type
, bit_size
, name
, fields_without_braces
, type_map
);
605 = type_map
.emplace (flags_type
->lookup_name (),
606 std::move (flags_type
));
607 return *insertion_pair
.first
->second
;
611 if (type_str
.find ("enum") == 0)
613 compiled_regex
regex ("^enum" WS
"(" IDENTIFIER
")" WSOPT
"(\\{" WSOPT
"([^}]*)})?",
615 _("Error in AMDGPU register type enum regex"));
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"));
623 gdb::string_view name
= sv_from_match (matches
[1]);
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
);
629 if (matches
[2].rm_so
== -1)
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 ());
636 if (existing_type_it
->second
->kind ()
637 != amd_dbgapi_register_type::kind::ENUM
)
638 error (_("type mismatch"));
640 return *existing_type_it
->second
;
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 ());
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]);
653 parse_amd_dbgapi_register_type_enum_fields
654 (*enum_type
, fields_without_braces
);
657 = type_map
.emplace (enum_type
->lookup_name (),
658 std::move (enum_type
));
659 return *insertion_pair
.first
->second
;
663 return parse_amd_dbgapi_register_type_scalar (type_str
, type_map
);
666 /* Convert an amd_dbgapi_register_type object to a GDB type. */
669 amd_dbgapi_register_type_to_gdb_type (const amd_dbgapi_register_type
&type
,
670 struct gdbarch
*gdbarch
)
672 switch (type
.kind ())
674 case amd_dbgapi_register_type::kind::INTEGER
:
676 const auto &integer_type
677 = gdb::checked_static_cast
<const amd_dbgapi_register_type_integer
&>
679 switch (integer_type
.bit_size ())
682 if (integer_type
.is_unsigned ())
683 return builtin_type (gdbarch
)->builtin_uint32
;
685 return builtin_type (gdbarch
)->builtin_int32
;
688 if (integer_type
.is_unsigned ())
689 return builtin_type (gdbarch
)->builtin_uint64
;
691 return builtin_type (gdbarch
)->builtin_int64
;
694 gdb_assert_not_reached ("invalid bit size");
698 case amd_dbgapi_register_type::kind::VECTOR
:
700 const auto &vector_type
701 = gdb::checked_static_cast
<const amd_dbgapi_register_type_vector
&>
703 struct type
*element_type
704 = amd_dbgapi_register_type_to_gdb_type (vector_type
.element_type (),
706 return init_vector_type (element_type
, vector_type
.count ());
709 case amd_dbgapi_register_type::kind::FLOAT
:
710 return builtin_type (gdbarch
)->builtin_float
;
712 case amd_dbgapi_register_type::kind::DOUBLE
:
713 return builtin_type (gdbarch
)->builtin_double
;
715 case amd_dbgapi_register_type::kind::CODE_PTR
:
716 return builtin_type (gdbarch
)->builtin_func_ptr
;
718 case amd_dbgapi_register_type::kind::FLAGS
:
720 const auto &flags_type
721 = gdb::checked_static_cast
<const amd_dbgapi_register_type_flags
&>
723 struct type
*gdb_type
724 = arch_flags_type (gdbarch
, flags_type
.name ().c_str (),
725 flags_type
.bit_size ());
727 for (const auto &field
: flags_type
)
729 if (field
.type
== nullptr)
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 ());
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 ());
750 case amd_dbgapi_register_type::kind::ENUM
:
752 const auto &enum_type
753 = gdb::checked_static_cast
<const amd_dbgapi_register_type_enum
&>
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 ()));
760 gdb_type
->set_num_fields (enum_type
.size ());
762 ((struct field
*) TYPE_ZALLOC (gdb_type
, (sizeof (struct field
)
763 * enum_type
.size ())));
764 gdb_type
->set_is_unsigned (true);
766 for (size_t i
= 0; i
< enum_type
.size (); ++i
)
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
);
777 gdb_assert_not_reached ("unhandled amd_dbgapi_register_type kind");
782 amdgpu_register_type (struct gdbarch
*gdbarch
, int regnum
)
784 amdgpu_gdbarch_tdep
*tdep
= get_amdgpu_gdbarch_tdep (gdbarch
);
786 if (tdep
->register_types
[regnum
] == nullptr)
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. */
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"));
799 gdb::unique_xmalloc_ptr
<char> bytes_holder (bytes
);
800 amd_dbgapi_register_type_map type_map
;
801 const amd_dbgapi_register_type
®ister_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);
808 return tdep
->register_types
[regnum
];
812 amdgpu_register_reggroup_p (struct gdbarch
*gdbarch
, int regnum
,
813 const reggroup
*group
)
815 amdgpu_gdbarch_tdep
*tdep
= get_amdgpu_gdbarch_tdep (gdbarch
);
817 auto it
= tdep
->register_class_map
.find (group
->name ());
818 if (it
== tdep
->register_class_map
.end ())
819 return group
== all_reggroup
;
821 amd_dbgapi_register_class_state_t state
;
822 if (amd_dbgapi_register_is_in_register_class (it
->second
,
823 tdep
->register_ids
[regnum
],
825 != AMD_DBGAPI_STATUS_SUCCESS
)
826 return group
== all_reggroup
;
828 return (state
== AMD_DBGAPI_REGISTER_CLASS_STATE_MEMBER
829 || group
== all_reggroup
);
833 amdgpu_breakpoint_kind_from_pc (struct gdbarch
*gdbarch
, CORE_ADDR
*)
835 return get_amdgpu_gdbarch_tdep (gdbarch
)->breakpoint_instruction_size
;
838 static const gdb_byte
*
839 amdgpu_sw_breakpoint_from_kind (struct gdbarch
*gdbarch
, int kind
, int *size
)
842 return get_amdgpu_gdbarch_tdep (gdbarch
)->breakpoint_instruction_bytes
.get ();
845 struct amdgpu_frame_cache
851 static amdgpu_frame_cache
*
852 amdgpu_frame_cache (frame_info_ptr this_frame
, void **this_cache
)
854 if (*this_cache
!= nullptr)
855 return (struct amdgpu_frame_cache
*) *this_cache
;
857 struct amdgpu_frame_cache
*cache
858 = FRAME_OBSTACK_ZALLOC (struct amdgpu_frame_cache
);
859 (*this_cache
) = cache
;
861 cache
->pc
= get_frame_func (this_frame
);
868 amdgpu_frame_this_id (frame_info_ptr this_frame
, void **this_cache
,
871 struct amdgpu_frame_cache
*cache
872 = amdgpu_frame_cache (this_frame
, this_cache
);
874 if (get_frame_type (this_frame
) == INLINE_FRAME
)
875 (*this_id
) = frame_id_build (cache
->base
, cache
->pc
);
877 (*this_id
) = outer_frame_id
;
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 ());
886 amdgpu_dummy_id (struct gdbarch
*gdbarch
, frame_info_ptr this_frame
)
888 return frame_id_build (0, get_frame_pc (this_frame
));
891 static struct value
*
892 amdgpu_frame_prev_register (frame_info_ptr this_frame
, void **this_cache
,
895 return frame_unwind_got_register (this_frame
, regnum
, regnum
);
898 static const frame_unwind amdgpu_frame_unwind
= {
901 default_frame_unwind_stop_reason
,
902 amdgpu_frame_this_id
,
903 amdgpu_frame_prev_register
,
905 default_frame_sniffer
,
911 print_insn_amdgpu (bfd_vma memaddr
, struct disassemble_info
*info
)
913 gdb_disassemble_info
*di
914 = static_cast<gdb_disassemble_info
*> (info
->application_data
);
916 /* Try to read at most INSTRUCTION_SIZE bytes. */
918 amd_dbgapi_size_t instruction_size
= gdbarch_max_insn_length (di
->arch ());
919 gdb::byte_vector
buffer (instruction_size
);
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)
928 int ret
= info
->read_memory_func (memaddr
, buffer
.data (),
929 instruction_size
, info
);
936 if (instruction_size
== 0)
938 info
->memory_error_func (-1, memaddr
, info
);
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
,
946 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
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
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);
959 string_file
string (disasm
->stream ()->can_emit_style_escape ());
960 print_address (disasm
->arch (), address
, &string
);
961 *symbol_text
= xstrdup (string
.c_str ());
963 return AMD_DBGAPI_STATUS_SUCCESS
;
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
,
973 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
976 status
= amd_dbgapi_architecture_get_info
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"));
983 info
->fprintf_func (di
, "<illegal instruction>");
985 /* Skip to the next valid instruction address. */
986 return align_up (memaddr
+ 1, alignment
) - memaddr
;
989 /* Print the instruction. */
990 info
->fprintf_func (di
, "%s", instruction_text
);
992 /* Free the memory allocated by the amd-dbgapi. */
993 xfree (instruction_text
);
995 return static_cast<int> (instruction_size
);
999 amdgpu_skip_prologue (struct gdbarch
*gdbarch
, CORE_ADDR start_pc
)
1001 CORE_ADDR func_addr
;
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
1006 if (find_pc_partial_function (start_pc
, nullptr, &func_addr
, nullptr))
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
);
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
1016 && cust
->producer () != nullptr
1017 && producer_is_llvm (cust
->producer ()))
1018 return std::max (start_pc
, post_prologue_pc
);
1025 amdgpu_supports_arch_info (const struct bfd_arch_info
*info
)
1027 amd_dbgapi_architecture_id_t architecture_id
;
1028 amd_dbgapi_status_t status
1029 = amd_dbgapi_get_architecture (info
->mach
, &architecture_id
);
1031 gdb_assert (status
!= AMD_DBGAPI_STATUS_ERROR_NOT_INITIALIZED
);
1032 return status
== AMD_DBGAPI_STATUS_SUCCESS
;
1035 static struct gdbarch
*
1036 amdgpu_gdbarch_init (struct gdbarch_info info
, struct gdbarch_list
*arches
)
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
;
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
);
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
);
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
);
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
,
1077 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1079 warning (_("Failed to get architecture from amd-dbgapi"));
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 ®ister_class_count
,
1089 ®ister_class_ids
);
1090 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1092 warning (_("Failed to get register class list from amd-dbgapi"));
1096 gdb::unique_xmalloc_ptr
<amd_dbgapi_register_class_id_t
>
1097 register_class_ids_holder (register_class_ids
);
1099 for (size_t i
= 0; i
< register_class_count
; ++i
)
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
)
1107 warning (_("Failed to get register class name from amd-dbgapi"));
1111 gdb::unique_xmalloc_ptr
<char> name (bytes
);
1113 auto inserted
= tdep
->register_class_map
.emplace (name
.get (),
1114 register_class_ids
[i
]);
1115 gdb_assert (inserted
.second
);
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)
1122 /* Allocate the reggroup in the gdbarch. */
1124 (gdbarch
, reggroup_gdbarch_new (gdbarch
, name
.get (), USER_REGGROUP
));
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
,
1133 if (status
!= AMD_DBGAPI_STATUS_SUCCESS
)
1135 warning (_("Failed to get register list from amd-dbgapi"));
1139 gdb::unique_xmalloc_ptr
<amd_dbgapi_register_id_t
> register_ids_holder
1142 tdep
->register_ids
.insert (tdep
->register_ids
.end (), ®ister_ids
[0],
1143 ®ister_ids
[register_count
]);
1145 tdep
->register_properties
.resize (register_count
,
1146 AMD_DBGAPI_REGISTER_PROPERTY_NONE
);
1147 for (size_t regnum
= 0; regnum
< register_count
; ++regnum
)
1149 auto ®ister_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 ®ister_properties
)
1154 != AMD_DBGAPI_STATUS_SUCCESS
)
1156 warning (_("Failed to get register properties from amd-dbgapi"));
1161 set_gdbarch_num_regs (gdbarch
, register_count
);
1162 set_gdbarch_num_pseudo_regs (gdbarch
, 0);
1164 tdep
->register_names
.resize (register_count
);
1165 tdep
->register_types
.resize (register_count
);
1166 for (size_t i
= 0; i
< register_count
; ++i
)
1168 /* Set amd-dbgapi register id -> gdb regnum mapping. */
1169 tdep
->regnum_map
.emplace (tdep
->register_ids
[i
], i
);
1171 /* Get register name. */
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
)
1178 tdep
->register_names
[i
] = bytes
;
1182 /* Get register DWARF number. */
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
)
1189 if (dwarf_num
>= tdep
->dwarf_regnum_to_gdb_regnum
.size ())
1190 tdep
->dwarf_regnum_to_gdb_regnum
.resize (dwarf_num
+ 1, -1);
1192 tdep
->dwarf_regnum_to_gdb_regnum
[dwarf_num
] = i
;
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
)
1202 warning (_("Failed to get PC register from amd-dbgapi"));
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);
1211 set_gdbarch_dwarf2_reg_to_regnum (gdbarch
, amdgpu_dwarf_reg_to_regnum
);
1213 set_gdbarch_return_value_as_value (gdbarch
, amdgpu_return_value_as_value
);
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
);
1221 set_gdbarch_print_insn (gdbarch
, print_insn_amdgpu
);
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"));
1231 set_gdbarch_max_insn_length (gdbarch
, max_insn_length
);
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"));
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"));
1247 tdep
->breakpoint_instruction_bytes
.reset (breakpoint_instruction_bytes
);
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
);
1254 amd_dbgapi_size_t pc_adjust
;
1255 status
= amd_dbgapi_architecture_get_info
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"));
1262 set_gdbarch_decr_pc_after_break (gdbarch
, pc_adjust
);
1264 return gdbarch_u
.release ();
1267 #if defined GDB_SELF_TEST
1270 amdgpu_register_type_parse_test ()
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
=
1282 } FP_ROUND.32 @0-1; \
1283 enum fp_round FP_ROUND.64_16 @2-3; \
1285 FLUSH_SRC_DST = 0, \
1289 } FP_DENORM.32 @4-5; \
1290 enum fp_denorm FP_DENORM.64_16 @6-7; \
1291 bool DX10_CLAMP @8; \
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; \
1309 uint32_t CSP @29-31; \
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
);
1315 gdb_assert (type
.kind () == amd_dbgapi_register_type::kind::FLAGS
);
1318 = gdb::checked_static_cast
<const amd_dbgapi_register_type_flags
&> (type
);
1319 gdb_assert (f
.size () == 23);
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
)
1325 gdb_assert (field
.name
== name
);
1326 gdb_assert (field
.type
->kind ()
1327 == amd_dbgapi_register_type::kind::ENUM
);
1330 = gdb::checked_static_cast
<const amd_dbgapi_register_type_enum
&>
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);
1339 check_fp_round_field ("FP_ROUND.32", f
[0]);
1340 check_fp_round_field ("FP_ROUND.64_16", f
[1]);
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
);
1347 = gdb::checked_static_cast
<const amd_dbgapi_register_type_integer
&>
1349 gdb_assert (i
.bit_size () == 32);
1350 gdb_assert (i
.is_unsigned ());
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
);
1360 gdb_assert (type
.kind () == amd_dbgapi_register_type::kind::VECTOR
);
1363 = gdb::checked_static_cast
<const amd_dbgapi_register_type_vector
&>
1365 gdb_assert (v
.count () == 64);
1367 const auto &et
= v
.element_type ();
1368 gdb_assert (et
.kind () == amd_dbgapi_register_type::kind::INTEGER
);
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 ());
1379 void _initialize_amdgpu_tdep ();
1382 _initialize_amdgpu_tdep ()
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
);