<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <div class="markdown-here-wrapper" data-md-url="" style="">
      <p style="margin: 0px 0px 1.2em !important;">Hi,<br>
        thanks for the report.</p>
      <p style="margin: 0px 0px 1.2em !important;">By reading the
        Aarch64 ABI:</p>
      <p style="margin: 0px 0px 1.2em !important;"></p>
      <div class="markdown-here-exclude">
        <p></p>
        <blockquote type="cite">5.9.5 Homogeneous Aggregates<br>
          A Homogeneous Aggregate is a composite type where all of the
          Fundamental Data Types of the members<br>
          that compose the type are the same. The test for homogeneity
          is applied after data layout is completed and<br>
          without regard to access control or other source language
          restrictions. Note that for short-vector types the<br>
          fundamental types are 64-bit vector and 128-bit vector; the
          type of the elements in the short vector does not<br>
          form part of the test for homogeneity.<br>
          A Homogeneous Aggregate has a Base Type, which is the
          Fundamental Data Type of each Member. The<br>
          overall size is the size of the Base Type multiplied by the
          number uniquely addressable Members; its<br>
          alignment will be the alignment of the Base Type.<br>
          5.9.5.1 Homogeneous Floating-point Aggregates (HFA)<br>
          A Homogeneous Floating-point Aggregate (HFA) is a Homogeneous
          Aggregate with a Fundamental Data<br>
          Type that is a Floating-Point type and at most four uniquely
          addressable members.<br>
          5.9.5.2 Homogeneous Short-Vector Aggregates (HVA)<br>
          A Homogeneous Short-Vector Aggregate (HVA) is a Homogeneous
          Aggregate with a Fundamental Data<br>
          Type that is a Short-Vector type and at most four uniquely
          addressable members.</blockquote>
        <p></p>
      </div>
      <p style="margin: 0px 0px 1.2em !important;"></p>
      <p style="margin: 0px 0px 1.2em !important;">I’m frankly not clear
        at all at what should happen in some of the cases you have in
        your examples. For instance, this:</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">// HFA
typedef union {
    struct {
        struct {
            int x;
        } arr1[0];
    };
    float arr2[3];
} T22;
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">Works as an HFA, I
        suppose, because “x” is not an addressable member. But then…</p>
      <pre style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;font-size: 1em; line-height: 1.2em;margin: 1.2em 0px;"><code style="font-size: 0.85em; font-family: Consolas, Inconsolata, Courier, monospace;margin: 0px 0.15em; padding: 0px 0.3em; white-space: pre-wrap; border: 1px solid rgb(234, 234, 234); background-color: rgb(248, 248, 248); border-radius: 3px; display: inline;white-space: pre; overflow: auto; border-radius: 3px; border: 1px solid rgb(204, 204, 204); padding: 0.5em 0.7em; display: block !important;">// not HFA, int registers
typedef union {
    struct {
        struct {
            long long x;
        } arr1[0];
    };
    float arr2[3];
} T23;
</code></pre>
      <p style="margin: 0px 0px 1.2em !important;">This also only has
        one “addressable member” (whatever that means). But clang uses
        float registers in the latter, not the former.</p>
      <p style="margin: 0px 0px 1.2em !important;">Also, switching
        godbolt to use GCC I don’t see any difference in the assembly
        generated for the two examples. They both seem to use int
        registers (e.g. mov, not fmov).</p>
      <p style="margin: 0px 0px 1.2em !important;">So, there seems to be
        some issue here, although, given the very vague definition of
        HFA in the ABI, it is not clear to me whether we’re staring at a
        FFM bug, an llvm bug, or a gcc bug.</p>
      <p style="margin: 0px 0px 1.2em !important;">The FFM code seems to
        be very conservative: if there’s a member layout in the
        struct/union that’s not a value layout (padding, struct/union,
        sequence), then the struct/union is not an HFA. It is possible
        that’s too restrictive, but we’d need some authoritative opinion
        on how the rules have to be interpreted (cc’ing Nick).</p>
      <p style="margin: 0px 0px 1.2em !important;">Cheers<br>
        Maurizio</p>
      <p style="margin: 0px 0px 1.2em !important;">On 06/10/2024 10:16,
        Владимир Козелков wrote:</p>
      <p style="margin: 0px 0px 1.2em !important;"></p>
      <div class="markdown-here-exclude">
        <p></p>
        <blockquote type="cite" cite="mid:CAGF0iuRV1_ZUMEb4FRPM=AJpPKfdCQTJECs+z4qj_d7rKf37Vg@mail.gmail.com">
          
          <div dir="ltr">Hello! <br>
            <div>Under the <a href="https://github.com/openjdk/jdk/pull/21041" moz-do-not-send="true">pull request</a> I was advised to
              write about new issues to this email.<br>
            </div>
            <div><br>
            </div>
            <div>I'm building my own port of the Panama project to
              Android, which uses LibLLVM for native code generation, so
              I've been doing a lot of research into how the calling
              convention works there.<br>
            </div>
            <div><br>
            </div>
            <div>Based on the data I received, I created my own <a href="https://github.com/vova7878/PanamaPort/blob/master/AndroidPanama/src/main/java/com/v7878/foreign/_LLVMCallingConvention.java" moz-do-not-send="true">classifier</a> of structures for
              the arranger with an eye on LLVM (In most cases, it
              calculates registers itself)<br>
            </div>
            <div><br>
            </div>
            <div>Initially my implementation rejected structures and
              sequences of size 0, but then I added support for them
              back. Everything worked pretty well until I dug into the
              godbolt tests and compared my implementation to the
              reference implementation from OpenJDK.</div>
            <div><br>
            </div>
            <div>It seems to me that<a href="https://github.com/openjdk/jdk/blob/260d4658aefe370d8994574c20057de07fd6f197/src/java.base/share/classes/jdk/internal/foreign/abi/aarch64/TypeClass.java#L85" moz-do-not-send="true">
                jdk.internal.foreign.abi.aarch64.TypeClass.isHomogeneousFloatAggregate</a>
              does not work correctly for union types and sequences with
              nested GroupLayout. Additionally, I made examples in
              godbolt that show how it determines HFA<br>
            </div>
            <div><br>
            </div>
            <div>C++ <a href="https://godbolt.org/z/fcsMvaKhd" moz-do-not-send="true" class="moz-txt-link-freetext">https://godbolt.org/z/fcsMvaKhd</a></div>
            <div>C <a href="https://godbolt.org/z/er8Yev7ME" moz-do-not-send="true" class="moz-txt-link-freetext">https://godbolt.org/z/er8Yev7ME</a></div>
            <div><br>
            </div>
            <div>I don't have a PC on aarch64 to run tests on java, but
              it looks to me like OpenJDK implementation is not correct
              for some cases<br>
            </div>
          </div>
        </blockquote>
        <p></p>
      </div>
      <p style="margin: 0px 0px 1.2em !important;"></p>
      <div title="MDH:PHA+SGksPGJyPnRoYW5rcyBmb3IgdGhlIHJlcG9ydC48L3A+PHA+QnkgcmVhZGluZyB0aGUgQWFy
Y2g2NCBBQkk6PGJyPjwvcD48cD48YmxvY2txdW90ZSB0eXBlPSJjaXRlIj41LjkuNSBIb21vZ2Vu
ZW91cyBBZ2dyZWdhdGVzPGJyPkEgSG9tb2dlbmVvdXMgQWdncmVnYXRlIGlzIGEgY29tcG9zaXRl
IHR5cGUgd2hlcmUgYWxsIG9mIHRoZSBGdW5kYW1lbnRhbCBEYXRhIFR5cGVzIG9mIHRoZSBtZW1i
ZXJzPGJyPnRoYXQgY29tcG9zZSB0aGUgdHlwZSBhcmUgdGhlIHNhbWUuIFRoZSB0ZXN0IGZvciBo
b21vZ2VuZWl0eSBpcyBhcHBsaWVkIGFmdGVyIGRhdGEgbGF5b3V0IGlzIGNvbXBsZXRlZCBhbmQ8
YnI+d2l0aG91dCByZWdhcmQgdG8gYWNjZXNzIGNvbnRyb2wgb3Igb3RoZXIgc291cmNlIGxhbmd1
YWdlIHJlc3RyaWN0aW9ucy4gTm90ZSB0aGF0IGZvciBzaG9ydC12ZWN0b3IgdHlwZXMgdGhlPGJy
PmZ1bmRhbWVudGFsIHR5cGVzIGFyZSA2NC1iaXQgdmVjdG9yIGFuZCAxMjgtYml0IHZlY3Rvcjsg
dGhlIHR5cGUgb2YgdGhlIGVsZW1lbnRzIGluIHRoZSBzaG9ydCB2ZWN0b3IgZG9lcyBub3Q8YnI+
Zm9ybSBwYXJ0IG9mIHRoZSB0ZXN0IGZvciBob21vZ2VuZWl0eS48YnI+QSBIb21vZ2VuZW91cyBB
Z2dyZWdhdGUgaGFzIGEgQmFzZSBUeXBlLCB3aGljaCBpcyB0aGUgRnVuZGFtZW50YWwgRGF0YSBU
eXBlIG9mIGVhY2ggTWVtYmVyLiBUaGU8YnI+b3ZlcmFsbCBzaXplIGlzIHRoZSBzaXplIG9mIHRo
ZSBCYXNlIFR5cGUgbXVsdGlwbGllZCBieSB0aGUgbnVtYmVyIHVuaXF1ZWx5IGFkZHJlc3NhYmxl
IE1lbWJlcnM7IGl0czxicj5hbGlnbm1lbnQgd2lsbCBiZSB0aGUgYWxpZ25tZW50IG9mIHRoZSBC
YXNlIFR5cGUuPGJyPjUuOS41LjEgSG9tb2dlbmVvdXMgRmxvYXRpbmctcG9pbnQgQWdncmVnYXRl
cyAoSEZBKTxicj5BIEhvbW9nZW5lb3VzIEZsb2F0aW5nLXBvaW50IEFnZ3JlZ2F0ZSAoSEZBKSBp
cyBhIEhvbW9nZW5lb3VzIEFnZ3JlZ2F0ZSB3aXRoIGEgRnVuZGFtZW50YWwgRGF0YTxicj5UeXBl
IHRoYXQgaXMgYSBGbG9hdGluZy1Qb2ludCB0eXBlIGFuZCBhdCBtb3N0IGZvdXIgdW5pcXVlbHkg
YWRkcmVzc2FibGUgbWVtYmVycy48YnI+NS45LjUuMiBIb21vZ2VuZW91cyBTaG9ydC1WZWN0b3Ig
QWdncmVnYXRlcyAoSFZBKTxicj5BIEhvbW9nZW5lb3VzIFNob3J0LVZlY3RvciBBZ2dyZWdhdGUg
KEhWQSkgaXMgYSBIb21vZ2VuZW91cyBBZ2dyZWdhdGUgd2l0aCBhIEZ1bmRhbWVudGFsIERhdGE8
YnI+VHlwZSB0aGF0IGlzIGEgU2hvcnQtVmVjdG9yIHR5cGUgYW5kIGF0IG1vc3QgZm91ciB1bmlx
dWVseSBhZGRyZXNzYWJsZSBtZW1iZXJzLjwvYmxvY2txdW90ZT48L3A+PHA+SSdtIGZyYW5rbHkg
bm90IGNsZWFyIGF0IGFsbCBhdCB3aGF0IHNob3VsZCBoYXBwZW4gaW4gc29tZSBvZiB0aGUgY2Fz
ZXMgeW91IGhhdmUgaW4geW91ciBleGFtcGxlcy4gRm9yIGluc3RhbmNlLCB0aGlzOjwvcD48cD5g
YGA8YnI+Ly8gSEZBPGJyPnR5cGVkZWYgdW5pb24gezxicj4mbmJzcDsmbmJzcDsmbmJzcDsgc3Ry
dWN0IHs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHN0cnVj
dCB7PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu
YnNwOyZuYnNwOyZuYnNwOyBpbnQgeDs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7
Jm5ic3A7Jm5ic3A7IH0gYXJyMVswXTs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IH07PGJyPiZuYnNw
OyZuYnNwOyZuYnNwOyBmbG9hdCBhcnIyWzNdOzxicj59IFQyMjs8YnI+YGBgPC9wPjxwPldvcmtz
IGFzIGFuIEhGQSwgSSBzdXBwb3NlLCBiZWNhdXNlICJ4IiBpcyBub3QgYW4gYWRkcmVzc2FibGUg
bWVtYmVyLiBCdXQgdGhlbi4uLjwvcD48cD5gYGA8YnI+Ly8gbm90IEhGQSwgaW50IHJlZ2lzdGVy
czxicj50eXBlZGVmIHVuaW9uIHs8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7IHN0cnVjdCB7PGJyPiZu
YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyBzdHJ1Y3Qgezxicj4mbmJz
cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm
bmJzcDsgbG9uZyBsb25nIHg7PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw
OyZuYnNwOyB9IGFycjFbMF07PGJyPiZuYnNwOyZuYnNwOyZuYnNwOyB9Ozxicj4mbmJzcDsmbmJz
cDsmbmJzcDsgZmxvYXQgYXJyMlszXTs8YnI+fSBUMjM7PGJyPmBgYDwvcD48cD5UaGlzIGFsc28g
b25seSBoYXMgb25lICJhZGRyZXNzYWJsZSBtZW1iZXIiICh3aGF0ZXZlciB0aGF0IG1lYW5zKS4g
QnV0Jm5ic3A7IGNsYW5nIHVzZXMgZmxvYXQgcmVnaXN0ZXJzIGluIHRoZSBsYXR0ZXIsIG5vdCB0
aGUgZm9ybWVyLjwvcD48cD5BbHNvLCBzd2l0Y2hpbmcgZ29kYm9sdCB0byB1c2UgR0NDIEkgZG9u
J3Qgc2VlIGFueSBkaWZmZXJlbmNlIGluIHRoZSBhc3NlbWJseSBnZW5lcmF0ZWQgZm9yIHRoZSB0
d28gZXhhbXBsZXMuIFRoZXkgYm90aCBzZWVtIHRvIHVzZSBpbnQgcmVnaXN0ZXJzIChlLmcuIG1v
diwgbm90IGZtb3YpLjwvcD48cD5TbywgdGhlcmUgc2VlbXMgdG8gYmUgc29tZSBpc3N1ZSBoZXJl
LCBhbHRob3VnaCwgZ2l2ZW4gdGhlIHZlcnkgdmFndWUgZGVmaW5pdGlvbiBvZiBIRkEgaW4gdGhl
IEFCSSwgaXQgaXMgbm90IGNsZWFyIHRvIG1lIHdoZXRoZXIgd2UncmUgc3RhcmluZyBhdCBhIEZG
TSBidWcsIGFuIGxsdm0gYnVnLCBvciBhIGdjYyBidWcuPC9wPjxwPlRoZSBGRk0gY29kZSBzZWVt
cyB0byBiZSB2ZXJ5IGNvbnNlcnZhdGl2ZTogaWYgdGhlcmUncyBhIG1lbWJlciBsYXlvdXQgaW4g
dGhlIHN0cnVjdC91bmlvbiB0aGF0J3Mgbm90IGEgdmFsdWUgbGF5b3V0IChwYWRkaW5nLCBzdHJ1
Y3QvdW5pb24sIHNlcXVlbmNlKSwgdGhlbiB0aGUgc3RydWN0L3VuaW9uIGlzIG5vdCBhbiBIRkEu
IEl0IGlzIHBvc3NpYmxlIHRoYXQncyB0b28gcmVzdHJpY3RpdmUsIGJ1dCB3ZSdkIG5lZWQgc29t
ZSBhdXRob3JpdGF0aXZlIG9waW5pb24gb24gaG93IHRoZSBydWxlcyBoYXZlIHRvIGJlIGludGVy
cHJldGVkIChjYydpbmcgTmljaykuPC9wPjxwPkNoZWVyczxicj5NYXVyaXppbzxicj48L3A+PHA+
PGJyPjwvcD48cD48YnI+PC9wPjxkaXYgY2xhc3M9Im1vei1jaXRlLXByZWZpeCI+T24gMDYvMTAv
MjAyNCAxMDoxNiwg0JLQu9Cw0LTQuNC80LjRgCDQmtC+0LfQtdC70LrQvtCyIHdyb3RlOjxicj48
L2Rpdj48YmxvY2txdW90ZSB0eXBlPSJjaXRlIiBjaXRlPSJtaWQ6Q0FHRjBpdVJWMV9aVU1FYjRG
UlBNPUFKcFBLZmRDUVRKRUNzK3o0cWpfZDdyS2YzN1ZnQG1haWwuZ21haWwuY29tIj48bWV0YSBo
dHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgIj48ZGl2IGRpcj0i
bHRyIj5IZWxsbyEmbmJzcDs8YnI+PGRpdj5VbmRlciB0aGUgPGEgaHJlZj0iaHR0cHM6Ly9naXRo
dWIuY29tL29wZW5qZGsvamRrL3B1bGwvMjEwNDEiIG1vei1kby1ub3Qtc2VuZD0idHJ1ZSI+cHVs
bCByZXF1ZXN0PC9hPiBJIHdhcyBhZHZpc2VkIHRvIHdyaXRlIGFib3V0IG5ldyBpc3N1ZXMgdG8g
dGhpcyBlbWFpbC48YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5JJ20gYnVpbGRpbmcgbXkg
b3duIHBvcnQgb2YgdGhlIFBhbmFtYSBwcm9qZWN0IHRvIEFuZHJvaWQsIHdoaWNoIHVzZXMgTGli
TExWTSBmb3IgbmF0aXZlIGNvZGUgZ2VuZXJhdGlvbiwgc28gSSd2ZSBiZWVuIGRvaW5nIGEgbG90
IG9mIHJlc2VhcmNoIGludG8gaG93IHRoZSBjYWxsaW5nIGNvbnZlbnRpb24gd29ya3MgdGhlcmUu
PGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+QmFzZWQgb24gdGhlIGRhdGEgSSByZWNlaXZl
ZCwgSSBjcmVhdGVkIG15IG93biA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vdm92YTc4Nzgv
UGFuYW1hUG9ydC9ibG9iL21hc3Rlci9BbmRyb2lkUGFuYW1hL3NyYy9tYWluL2phdmEvY29tL3Y3
ODc4L2ZvcmVpZ24vX0xMVk1DYWxsaW5nQ29udmVudGlvbi5qYXZhIiBtb3otZG8tbm90LXNlbmQ9
InRydWUiPmNsYXNzaWZpZXI8L2E+IG9mIHN0cnVjdHVyZXMgZm9yIHRoZSBhcnJhbmdlciB3aXRo
IGFuIGV5ZSBvbiBMTFZNIChJbiBtb3N0IGNhc2VzLCBpdCBjYWxjdWxhdGVzIHJlZ2lzdGVycyBp
dHNlbGYpPGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+SW5pdGlhbGx5IG15IGltcGxlbWVu
dGF0aW9uIHJlamVjdGVkIHN0cnVjdHVyZXMgYW5kIHNlcXVlbmNlcyBvZiBzaXplIDAsIGJ1dCB0
aGVuIEkgYWRkZWQgc3VwcG9ydCBmb3IgdGhlbSBiYWNrLiZuYnNwO0V2ZXJ5dGhpbmcgd29ya2Vk
IHByZXR0eSB3ZWxsIHVudGlsIEkgZHVnIGludG8gdGhlIGdvZGJvbHQgdGVzdHMgYW5kIGNvbXBh
cmVkIG15IGltcGxlbWVudGF0aW9uIHRvIHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gZnJv
bSBPcGVuSkRLLjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+SXQgc2VlbXMgdG8gbWUgdGhhdDxh
IGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9vcGVuamRrL2pkay9ibG9iLzI2MGQ0NjU4YWVmZTM3
MGQ4OTk0NTc0YzIwMDU3ZGUwN2ZkNmYxOTcvc3JjL2phdmEuYmFzZS9zaGFyZS9jbGFzc2VzL2pk
ay9pbnRlcm5hbC9mb3JlaWduL2FiaS9hYXJjaDY0L1R5cGVDbGFzcy5qYXZhI0w4NSIgbW96LWRv
LW5vdC1zZW5kPSJ0cnVlIj4gamRrLmludGVybmFsLmZvcmVpZ24uYWJpLmFhcmNoNjQuVHlwZUNs
YXNzLmlzSG9tb2dlbmVvdXNGbG9hdEFnZ3JlZ2F0ZTwvYT4gZG9lcyBub3Qgd29yayBjb3JyZWN0
bHkgZm9yIHVuaW9uIHR5cGVzIGFuZCBzZXF1ZW5jZXMgd2l0aCBuZXN0ZWQgR3JvdXBMYXlvdXQu
Jm5ic3A7QWRkaXRpb25hbGx5LCBJIG1hZGUgZXhhbXBsZXMgaW4gZ29kYm9sdCB0aGF0IHNob3cg
aG93IGl0IGRldGVybWluZXMgSEZBPGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+QysrJm5i
c3A7PGEgaHJlZj0iaHR0cHM6Ly9nb2Rib2x0Lm9yZy96L2Zjc012YUtoZCIgbW96LWRvLW5vdC1z
ZW5kPSJ0cnVlIiBjbGFzcz0ibW96LXR4dC1saW5rLWZyZWV0ZXh0Ij5odHRwczovL2dvZGJvbHQu
b3JnL3ovZmNzTXZhS2hkPC9hPjwvZGl2PjxkaXY+QyZuYnNwOzxhIGhyZWY9Imh0dHBzOi8vZ29k
Ym9sdC5vcmcvei9lcjhZZXY3TUUiIG1vei1kby1ub3Qtc2VuZD0idHJ1ZSIgY2xhc3M9Im1vei10
eHQtbGluay1mcmVldGV4dCI+aHR0cHM6Ly9nb2Rib2x0Lm9yZy96L2VyOFlldjdNRTwvYT48L2Rp
dj48ZGl2Pjxicj48L2Rpdj48ZGl2PkkgZG9uJ3QgaGF2ZSBhIFBDIG9uIGFhcmNoNjQgdG8gcnVu
IHRlc3RzIG9uIGphdmEsIGJ1dCBpdCBsb29rcyB0byBtZSBsaWtlIE9wZW5KREsgaW1wbGVtZW50
YXRpb24gaXMgbm90IGNvcnJlY3QgZm9yIHNvbWUgY2FzZXM8YnI+PC9kaXY+PC9kaXY+Cgo8L2Js
b2NrcXVvdGU+" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0;">​</div>
    </div>
  </body>
</html>