<div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Mar 27, 2023 at 11:52 PM Cary Coutant via Dwarf-discuss <<a href="mailto:dwarf-discuss@lists.dwarfstd.org">dwarf-discuss@lists.dwarfstd.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">> Vector registers<br>
><br>
> It has been the long standing existing practice to treat hardware<br>
> vector registers as arrays of a fundamental base type. To deliniate<br>
> these hardware register arrays from arrays in the language source they<br>
> have been given the DW_AT_GNU_vector attribute. This proposal simply<br>
> standardizes the existing behavior.<br>
><br>
> In Section 2.2 Attribute Types, DW_AT_vector and<br>
> DW_AT_variable_vector_width shall be added to Table 2.2<br>
><br>
>     --------------------------------------------------------------------<br>
>     DW_AT_vector                | A hardware vector register<br>
>     DW_AT_variable_vector_width | Array bound for hardware<br>
>                                 | implementation defined vector register<br>
>                                 | width<br>
>     --------------------------------------------------------------------<br>
<br>
I don't understand what tags this DW_AT_vector attribute would apply<br>
to. Vector registers aren't *types*, they're *locations*, so it<br>
doesn't really make sense to me to put this attribute on a<br>
DW_TAG_array_type. We don't have DW_TAGs that describe registers; the<br>
ABI defines the registers and DWARF producers and consumers should<br>
understand and agree on the sizes and shapes of the various registers.<br>
<br>
In Tony's proposal, the new attribute modifies a base type, thus<br>
introducing a vector type, which might get placed in a vector<br>
register. But there, I don't see how the vector base type is<br>
fundamentally different from an array type. It seems it's just a dodge<br>
to make it a base type so that we can put whole vectors on the stack.<br>
<br>
Maybe what we're looking for is a DW_TAG_vector_type, whose DW_AT_type<br>
attribute gives the base type for each element of the vector. This<br>
seems to be more DWARF-like, and if we decide there's a reason to<br>
allow stack entries with vector types, we can do that.<br>
<br>
-cary<br>
-- <br>
Dwarf-discuss mailing list<br>
<a href="mailto:Dwarf-discuss@lists.dwarfstd.org" target="_blank">Dwarf-discuss@lists.dwarfstd.org</a><br>
<a href="https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss" rel="noreferrer" target="_blank">https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss</a></blockquote><div><br></div><div>(Caveat this is all amd64 specific, I haven't looked at ARM.)

</div><div><br></div><div>Last I looked into this I concluded that DW_AT_GNU_vector is a big hack to make debuggers capable of handling function entries and exits that involve the intrinsic types that hardware vendors have added for their SIMD features.<br></div><div><br></div><div>In the SYSV AMD64 ABI (download link <a href="https://gitlab.com/x86-psABIs/x86-64-ABI/-/jobs/artifacts/master/raw/x86-64-ABI/abi.pdf?job=build">https://gitlab.com/x86-psABIs/x86-64-ABI/-/jobs/artifacts/master/raw/x86-64-ABI/abi.pdf?job=build</a>) in Section 3.2.3 there is a subsection "Classification". Immediately after the base types, _m64/_m128/_m256/_m512 are special cased to be part of the "SSE" class. If you follow the algorithm described you'll note that non-special cased arrays are treated as aggregates of the element type and are not "promoted" to the "SSE" class. So _m256d and double[4], despite having identical layouts in memory, will be classified as SSE/SSEUP and MEMORY respectively by that algorithm (in particular note footnote 15 here). This is also easily verifable by compiling a trivial function that takes _m256d and double[4] parameters.<br></div><div><br></div><div>A debugger usually doesn't care about any of this because the DIEs for local/global variables will contain location information specifying where to get the bytes from to render the variable. DWARF does not, however, specify the locations of function return values at exit or parameters at function entry[0]. These locations are needed, in turn, to display the function return value upon function exit (think `ret` in gdb)[1] and to invoke a function with user supplied parameters (think `call` in gdb). Debuggers generally infer these locations from their knowledge of the platform ABI[2]. The DW_AT_GNU_vector attribute informs the debugger that these types are among the ones special-cased in the ABI and prevents the need to do something even more unprincipled such as name matching.</div><div><br></div><div>
DW_AT[_GNU]_vector is best understood not as "a hardware vector register" but rather as a marker that "this type is eligible to be passed in hardware vector registers at function boundaries according to the platform ABI".<br></div><div><br></div><div>- Kyle<br></div><div><br></div><div>[0] DWARF has DW_TAG_formal_parameter and those can contain location information *but* DWARF does not specify that the location information must be valid at function entry. For debug builds, compilers often emit locations that are only valid after the function prologue has completed. Post-prologue locations are useless for invoking the function in a debugger.<br></div><div>[1] Inferring the function return value location causes issues in other contexts and I have a DWARF issue on that 
(221105.1)</div><div>[2] See e.g. amd64_classify in gdb/amd64-tdep.c</div></div></div>