<div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Apr 3, 2023 at 12:42 PM Pedro Alves 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">Hi Ben,<br>
<br>
On 2023-03-24 6:19 p.m., Ben Woodard via Dwarf-discuss wrote:<br>
<br>
> I will admit that in its current state it is a work in progress. My original intent was to simply<br>
> codify the existing behavior as implemented by GCC and LLVM (and probably other compilers) moving it<br>
> from a vendor attribute to something that was in the standard.<br>
<br>
In light of the recent discussion, I was thinking how it would help if the <br>
proposal was laid out in terms of vector types instead of hardware registers.<br></blockquote><div><br></div><div>I think the proposed language here is a bit too C/C++ centric.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Please see comments inline below.<br>
<br>
> 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>
I'd suggest replacing the above with something like this:<br>
<br>
~~~~~~~~~~~~<br>
Vector types<br>
<br>
As an extension to C and C++, GCC supports defining vector data types.<br></blockquote><div><br></div><div>DW_AT_GNU_vector is used for languages beyond C/C++ today.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
On some targets, operations on these vector types make use of SIMD<br>
vector registers and instructions.<br>
<br>
Vector types are similar to arrays, and you can index and initialize<br>
them similarly, but they have some important differences.  For<br>
example:<br></blockquote><div><br></div><div>
<div>These statements are not true in general for non C/C++ languages, and DW_TAG_array_type represents a variety of array types across many languages.<br></div>

</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
- Arrays automatically decay to pointers.  Vector types do not.<br></blockquote><div><br></div><div>
Array decay is only a C/C++ "feature" as far as I know.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
- You can pass vector types by value to functions, and likewise<br>
  functions can return vector types by value.  You can not do either<br>
  with C arrays.<br></blockquote><div><br></div><div>Arrays in other languages can be passed and returned by value at the language level (e.g. Ada) and sometimes even at the machine level (e.g. Rust).<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
- Vector types can be used with a subset of normal C operations: +, -,<br>
  *, /, unary minus, ^, |, &, ~, %.  For example, addition is defined as<br>
  the addition of the corresponding elements of the operands.<br></blockquote><div><br></div><div>The implicit statement here that non-vector arrays cannot be used with any normal operations is also not true in general (e.g. in Fortran 90 A = B + C works).<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
A debugger that supports expression evaluation will want to be able to<br>
support these vector operations on vector objects too.<br></blockquote><div><br></div><div>Supporting expression evaluation requires very deep knowledge of the semantics of the program's language, to the point where I think saying much beyond "vector types may have different semantics than standard array types" in the DWARF spec isn't worth the effort. <br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Vector types may appear on function prototypes, so they affect calling<br>
convention.<br>
<br>
To distinguish vector types from regular C arrays, GCC's DWARF<br>
describes the vector types as array with the DW_AT_GNU_vector<br>
attribute, a GNU extension.  Clang also supports the GCC vector<br>
language extension, and supports the same DWARF attribute as well.<br>
Vector types have supported by GDB for well over a decade, using said<br>
DWARF extension.  This proposal standardizes the existing behavior.<br>
~~~~~~~~~~~~<br>
<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>
<br>
Here, I think it would be better to say "A vector type".  An object of vector<br>
type could well have a memory location, for instance.<br>
<br>
>     DW_AT_variable_vector_width | Array bound for hardware<br>
>                                 | implementation defined vector register<br>
>                                 | width<br>
<br>
Does GCC have a corresponding GNU extension for this?  I don't recall ever<br>
seeing it, and my grepping isn't finding it.<br>
<br>
>     --------------------------------------------------------------------<br>
> <br>
> The hyperlink in the "Identifies or Specifies" column shall point to<br>
> the paragraph added to Section 5.5 below for DW_AT_vector and the<br>
> paragraph added to Section 5.13 below for<br>
> DW_AT_variable_vector_width.<br>
> <br>
> In Section 2.5.1.2 Register values replace the description of<br>
> DW_OP_regval_type with the following:<br>
> <br>
>     --------------------------------------------------------------------<br>
>     The DW_OP_regval_type operation provides the contents of a given<br>
>     register interpreted as a value of a given type. The first operand<br>
>     is an unsigned LEB128 number, which identifies a register whose<br>
>     contents is to be pushed onto the stack. The second operand is an<br>
>     unsigned LEB128 number that represents the offset of a debugging<br>
>     information entry in the current compilation unit, which must be a<br>
>     DW_TAG_base_type entry that provides the type of the value<br>
>     contained in the specified register or it must be an<br>
>     DW_TAG_array_type with a DW_AT_vector attribute.<br>
> <br>
>     [non-normative] A DW_TAG_array_type with a DW_AT_vector attribute<br>
>     is the way that a vector register is specified and can be<br>
>     considered a base type for the architecture.<br>
>     --------------------------------------------------------------------<br>
> <br>
> In Section 2.5.1.3 Stack Operations replace the description of<br>
> DW_OP_deref_type with the following:<br>
> <br>
>     --------------------------------------------------------------------<br>
>     The DW_OP_deref_type operation behaves like the DW_OP_deref_size<br>
>     operation: it pops the top stack entry and treats it as an<br>
>     address. The popped value must have an integral type. The value<br>
>     retrieved from that address is pushed together with a type<br>
>     identifier. In the DW_OP_deref_type operation, the size in bytes<br>
>     of the data retrieved from the dereferenced address is specified<br>
>     by the first operand. This operand is a 1-byte unsigned integral<br>
>     constant whose value which is the same as the size of the type<br>
>     referenced by the second operand. The second operand is an<br>
>     unsigned LEB128 integer that represents the offset of a debugging<br>
>     information entry in the current compilation unit that provides<br>
>     the type of the data pushed. This entry must be either a<br>
>     DW_TAG_base_type entry or a DW_TAG_array_type entry with a<br>
>     DW_AT_vector attribute.<br>
>     --------------------------------------------------------------------<br>
> <br>
> Replace the description of DW_OP_xderef_type with the following:<br>
> <br>
>     --------------------------------------------------------------------<br>
>     The DW_OP_xderef_type operation behaves like the DW_OP_xderef_size<br>
>     operation: it pops the top two stack entries, treats them as an<br>
>     address and an address space identifier, and pushes the value<br>
>     retrieved. In the DW_OP_xderef_type operation, the size in bytes<br>
>     of the data retrieved from the dereferenced address is specified<br>
>     by the first operand. This operand is a 1-byte unsigned integral<br>
>     constant whose value value is the same as the size of the type<br>
>     referenced by the second operand. The second operand is an<br>
>     unsigned LEB128 integer that represents the offset of a debugging<br>
>     information entry in the current compilation unit that provides<br>
>     the type of the data pushed. This entry must be a DW_TAG_base_type<br>
>     entry or a DW_TAG_array_type entry with a DW_AT_vector attribute.<br>
>     --------------------------------------------------------------------<br>
> <br>
> In Section 5.5 Array Type Entries, replace first paragraph of<br>
> non-normative text with:<br>
> <br>
>     --------------------------------------------------------------------<br>
>     [non-normative] Many languages share the concept of an “array,”<br>
>     which is a table of components of identical type. Furthermore,<br>
>     many architectures contain vector registers which mirror the<br>
>     language concept of an array.<br>
>     --------------------------------------------------------------------<br>
> <br>
> Insert the following paragraph between the first paragraph of<br>
> normative text describing DW_TAG_array_type and the second paragraph<br>
> dealing with multidimensional ordering.<br>
> <br>
>     --------------------------------------------------------------------<br>
>     An array type that refers to a hardware vector register, shall be<br>
<br>
"a hardware vector register" -> "a vector type"<br>
<br>
>     denoted with DW_AT_vector. The the width of the register shall be<br>
<br>
Double "The the".<br>
<br>
"width of the register" -> "width of the vector"<br>
<br>
>     specified as an array dimension and the type contained within the<br>
>     register must be a DW_TAG_base_type entry.<br>
<br>
"register" -> "vector".<br>
<br>
>     --------------------------------------------------------------------<br>
> <br>
> In Section 5.13 Subrange Type Entries insert the following paragraph<br>
> between the paragraph defining DW_AT_threads_scaled and the one<br>
> defining DW_AT_lower_bound and DW_AT_upper_bound.<br>
> <br>
>     --------------------------------------------------------------------<br>
>     The subrange entry may have a DW_AT_variable_vector_width<br>
>     attribute, which is a flag. If present, this attriburte indicates<br>
<br>
"attriburte" -> "attribute"<br>
<br>
>     that the width of a vector is defined by the hardware<br>
>     implementation of the target. <br>
<br>
I think that saying:<br>
<br>
     that the width of a vector may be deduced based on knowledge of the ABI.<br>
<br>
is more in line what is typically said in the spec.<br>
<br>
Pedro Alves<br>
<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>- Kyle <br></div></div></div>