<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>> However, there is no Binding can extend a float value to a
      64 bits value and fill its upper 32 bits. So, we have to modify
      shared code. <br>
      <br>
      Yes, that's what I was thinking. The CAST binding operator could
      be extended to handle that case. We'd probably want to refactor it
      into an enum, where each enum constant denotes particular
      conversion semantics (right now the semantics are derived only
      from the source and destination types). There could be some
      `RISCV_FLOAT_TO_REG_BITS` enum constant for the conversion you
      need, and then the resulting bits could be written to the return
      buffer.<br>
    </p>
    <p>What you have now is also a possibility, but if you want to avoid
      modifying shared code it seems simpler to use different segment
      masks for the return storages, and then select the instruction
      based on that.<br>
      <br>
      I had a look at the PR, and it looks like it is based on the
      current code in the openjdk/jdk repo. We have 2 patches to bring
      over the code from the panama-foreign repo to the mainline JDK
      repo, those will likely be integrated in the next 1-2 weeks [1],
      [2] (before RDP1 at least).<br>
      <br>
      Going directly into the JDK repo is probably fine as well, but in
      that case the patch should be based at least on the PR from [2] I
      think, to avoid having to do 2 reviews.</p>
    <p>Jorn</p>
    <p>[1]: <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/pull/10872">https://github.com/openjdk/jdk/pull/10872</a><br>
      [2]: <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/pull/11019">https://github.com/openjdk/jdk/pull/11019</a><br>
    </p>
    <div class="moz-cite-prefix">On 22/11/2022 11:12, 何伟凯 wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:29acf760.8ed1.1849ed3946d.Coremail.weikai@isrc.iscas.ac.cn">
      
      <br>
      <p class="md-end-block md-p" style="box-sizing:border-box;line-height:var(--text-line-height);orphans:4;margin:var(--p-spacing) 0;white-space:pre-wrap;position:relative;color:#B0B1AC;font-family:JetBrainsMonoNL, "JetBrains Mono", "Fira Code", "Cascadia Code", Menlo, "Ubuntu Mono", Consolas, HYZhengYuan;font-size:18px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;">
        <span class="ke-content-forecolor" style="box-sizing:border-box;font-family:SimSun;color:#64451D;">According to my understanding, if we want to fill upper 32 bits of date before it is transfered into return buffer, we have to add a Binding in UnboxBindingCalculator by using Binding.Builder, then BindingSpecializer will generate corresponding operations.</span>
</p>
      <p class="md-end-block md-p" style="box-sizing:border-box;line-height:var(--text-line-height);orphans:4;margin:var(--p-spacing) 0;white-space:pre-wrap;position:relative;color:#B0B1AC;font-family:JetBrainsMonoNL, "JetBrains Mono", "Fira Code", "Cascadia Code", Menlo, "Ubuntu Mono", Consolas, HYZhengYuan;font-size:18px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;">
        <span class="ke-content-forecolor" style="box-sizing:border-box;font-family:SimSun;color:#64451D;">However, there is no Binding can extend a float value to a 64 bits value and fill its upper 32 bits. So, we have to modify shared code. </span>
</p>
      <p class="md-end-block md-p" style="box-sizing:border-box;line-height:var(--text-line-height);orphans:4;margin:var(--p-spacing) 0;white-space:pre-wrap;position:relative;color:#B0B1AC;font-family:JetBrainsMonoNL, "JetBrains Mono", "Fira Code", "Cascadia Code", Menlo, "Ubuntu Mono", Consolas, HYZhengYuan;font-size:18px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;">
        <span class="ke-content-forecolor" style="box-sizing:border-box;font-family:SimSun;color:#64451D;">Is there any misunderstanding?</span>
</p>
      <p class="md-end-block md-p" style="box-sizing:border-box;line-height:var(--text-line-height);orphans:4;margin:var(--p-spacing) 0;white-space:pre-wrap;position:relative;color:#B0B1AC;font-family:JetBrainsMonoNL, "JetBrains Mono", "Fira Code", "Cascadia Code", Menlo, "Ubuntu Mono", Consolas, HYZhengYuan;font-size:18px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;">
        <span class="ke-content-forecolor" style="box-sizing:border-box;font-family:SimSun;color:#64451D;">To avoid modifying of shared code, we take another approach that fills all bits of return buffer with 1s while creating upcallStub. Hence, floating-point data can be copied from return buffer into register by fld and integer data by ld.</span>
</p>
      <p class="md-end-block md-p" style="box-sizing:border-box;line-height:var(--text-line-height);orphans:4;margin:var(--p-spacing) 0;white-space:pre-wrap;position:relative;color:#B0B1AC;font-family:JetBrainsMonoNL, "JetBrains Mono", "Fira Code", "Cascadia Code", Menlo, "Ubuntu Mono", Consolas, HYZhengYuan;font-size:18px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;">
        <span class="ke-content-forecolor" style="box-sizing:border-box;font-family:SimSun;color:#64451D;">link to the pr: </span><span class="md-link md-pair-s" spellcheck="false" style="box-sizing:border-box;word-break:break-all;"><span style="font-family:SimSun;"><span class="ke-content-forecolor" style="color:#64451D;"><a href="https://urldefense.com/v3/__https://www.github.com/openjdk/jdk/pull/11004__;!!ACWV5N9M2RV99hQ!Jqj877nU2TC_k7vSycUDqeM0JOcJgcw0lCQhcxo3-AyaL4xkRO3yS_7LoYxzueNhS9LJKgCc_AbsbxOEJ-NytAY$" style="box-sizing:border-box;cursor:pointer;color:#64451D;text-decoration:none;" moz-do-not-send="true">https://www.github.com/openjdk/jdk/pull/11004</a></span></span></span>
</p>
      <br>
      <p> WeiKai He
      </p>
      <p> <br>
      </p>
      <p> <br>
      </p>
      <blockquote name="replyContent" class="ReferenceQuote" style="padding-left:5px;margin-left:5px;border-left:#b6b6b6 2px
        solid;margin-right:0;"> -----原始邮件-----<br>
        <b>发件人:</b><span id="rc_from">"Jorn Vernee"
          <a class="moz-txt-link-rfc2396E" href="mailto:jorn.vernee@oracle.com"><jorn.vernee@oracle.com></a></span><br>
        <b>发送时间:</b><span id="rc_senttime">2022-11-06 06:16:33 (星期日)</span><br>
        <b>收件人:</b> "何伟凯" <a class="moz-txt-link-rfc2396E" href="mailto:weikai@isrc.iscas.ac.cn"><weikai@isrc.iscas.ac.cn></a><br>
        <b>抄送:</b> <a class="moz-txt-link-abbreviated" href="mailto:panama-dev@openjdk.org">panama-dev@openjdk.org</a><br>
        <b>主题:</b> Re: [External] : Re: Re: Panama-FFI API Porting for
        RISCV64<br>
        <br>
        <div class="moz-cite-prefix"> Reply in line...<br>
          On 01/11/2022 13:02, 何伟凯 wrote:<br>
        </div>
        <blockquote type="cite" cite="mid:3c970cf9.ba77.18433126fd4.Coremail.weikai@isrc.iscas.ac.cn">
          Thanks for your attention.<br>
          <br>
          flw will alter the bits being copied and it will be
          invalidated if we copy a float data with fld. When flw load a
          32-bits float value into a 64-bits register, it will fill
          upper 32 bits of the register, however, fld will not. Hence,
          using fld or flw depend on whether float or double is placed
          in the return buffer.<br>
        </blockquote>
        What I suggest is to write the right bit pattern for the whole
        register to the buffer in the Java code (including the upper 32
        bits for floats), and then just copy the bits from the buffer to
        the register in the VM code. Either with fld or another
        instruction that doesn't modify the bits.<br>
        <blockquote type="cite" cite="mid:3c970cf9.ba77.18433126fd4.Coremail.weikai@isrc.iscas.ac.cn">
          <br>
          Our modification is based on openjdk/jdk repo, because we
          would like to merge our code into the main stream. We have
          noticed changes in the panama-foreign repo, we also think the
          new VMStorage class will very helpful for solving the
          question. When the change merge into main stream of
          openjdk/jdk, we will follow it up.<br>
        </blockquote>
        <p> We are in the processes of moving all the changes in the
          panama-foreign repo to the openjdk/jdk repo for JDK 20. I
          haven't made the PR with most of the VM changes yet, but it
          will be based on the main PR for the JEP [1]. There are also
          some last-minute changes that will likely be added to the main
          JEP PR [2]. So, to avoid having to review things twice, I
          suggest basing the riscv port on the code in the
          panama-foreign repo for now, and then integrate into the
          mainline repo after the changes from the panama-foreign repo
          have been moved there. </p>
        <blockquote type="cite" cite="mid:3c970cf9.ba77.18433126fd4.Coremail.weikai@isrc.iscas.ac.cn">
          <br>
          We look forward to your further suggestions.<br>
        </blockquote>
        <p> I can take a look at the code once the PR goes up. </p>
        <p> Jorn </p>
        <p> [1]: <a class="moz-txt-link-freetext" href="https://urldefense.com/v3/__https://github.com/openjdk/jdk/pull/10872__;!!ACWV5N9M2RV99hQ!Jqj877nU2TC_k7vSycUDqeM0JOcJgcw0lCQhcxo3-AyaL4xkRO3yS_7LoYxzueNhS9LJKgCc_AbsbxOENw3Uhvk$" moz-do-not-send="true">https://github.com/openjdk/jdk/pull/10872</a><br>
          [2]: <a class="moz-txt-link-freetext" href="https://urldefense.com/v3/__https://github.com/openjdk/panama-foreign/pull/750__;!!ACWV5N9M2RV99hQ!Jqj877nU2TC_k7vSycUDqeM0JOcJgcw0lCQhcxo3-AyaL4xkRO3yS_7LoYxzueNhS9LJKgCc_AbsbxOEOFS7sDI$" moz-do-not-send="true">https://github.com/openjdk/panama-foreign/pull/750</a>
        </p>
        <blockquote type="cite" cite="mid:3c970cf9.ba77.18433126fd4.Coremail.weikai@isrc.iscas.ac.cn">
          <br>
          WeiKai He<br class="Apple-interchange-newline">
          <br>
          <br>
          <br>
          <br>
          <blockquote name="replyContent" class="ReferenceQuote" style="padding-left:5px;margin-left:5px;border-left:#b6b6b6
            2px solid;margin-right:0;"> <br>
            <p> Hello, </p>
            <p> The interface between Java and native is in general
              designed to communicate in register values (since it's
              intended to work with any foreign language in theory).
              Primitive types and the return buffer are use to transport
              the register values. The idea would be for the Java code
              to write the bits with the right semantics into the return
              buffer, for the entire width of the register (64-bits?),
              and then the native code could just copy the bits from the
              return buffer into the right register, without altering
              them.<br>
              <br>
              But, it sounds like this doesn't work for flw and fld?
              i.e. they both alter the bits being copied in an
              incompatible way? Or is the problem that 2 floats can
              'share' a register that would normally be taken up by a
              single double? </p>
            <p> Also, please note that the latest state of development
              is in the openjdk/panama-foreign repo on the
              foreign-memaccess+abi branch. It looks like the code you
              have is based on the openjdk/jdk repo. In the latest
              version in the panama-foreign repo, the use of VMReg is
              replaced by a new class called VMStorage (mirroring the
              Java class), and it is possible to attach a register mask
              to it which can also be used to indicate the width of the
              register, if needed [1]. </p>
            <p> Jorn </p>
            <p> [1]: <a class="moz-txt-link-freetext" href="https://urldefense.com/v3/__https://github.com/openjdk/panama-foreign/blob/foreign-memaccess*2Babi/src/hotspot/share/prims/vmstorageBase.inline.hpp*L43__;JSM!!ACWV5N9M2RV99hQ!IRN0FwuEVD3VWdh8KcgGWQ2QbjUx4l12MEy0b9-DZickSOF11M6lBm6M6FDqbnl6NYoEY9nJIMj0oxxfmL6GWpE$" moz-do-not-send="true">https://github.com/openjdk/panama-foreign/blob/foreign-memaccess%2Babi/src/hotspot/share/prims/vmstorageBase.inline.hpp#L43</a>
            </p>
            <div class="moz-cite-prefix"> On 30/10/2022 13:44, 何伟凯
              wrote:<br>
            </div>
            <blockquote type="cite" cite="mid:54bf4dd6.610b.18428ebfee6.Coremail.weikai@isrc.iscas.ac.cn">
              <pre style="word-wrap:break-word;" wrap="soft">## Summary

In recent, Panama FFI-API has been a preview feature. In many scenarios, the Panama FFI API can replace the JNI to implement native function access. The FFI API provides more secure and convenient access to native functions. The specific implementation of FFI API is related to ARCH and OS. In order to enable RISC V64 to use FFI API, porting is required. 

## Notable Things

Because there are different return value passing convention for special structures like `struct {int, float}` on the RISCV64[1]. 

When making an upcall, that's calling a Java method from a native function, return value of the Java method will be saved in a segment of stack memory called return buffer, and then riscv backend will transfer the data in memory to `a0` and `fa0`. 

The instructions used for data transfer are closely related to correctness. If the field containing in the special structure menteioned above is float, must use 'flw', otherwise, 'fld'. This requires a means to pass the width information of fields to the riscv backend.

Unfortunately, according to my understanding, the current interface does not provide a direct means to pass the width information of struct fields to the riscv backend, so the width information is encoded in other ways. Although this makes the riscv porting slightly different from other arch, it does not make the code more difficult to understand and maintain. For details, see comments in the code[2].

## Testing

All the tests in jtreg have been passed. Some tests under the user mode of the QEMU may fail, however they can pass on the development board.

## Reference

[1] <a target="_blank" href="https://urldefense.com/v3/__https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc__;!!ACWV5N9M2RV99hQ!IRN0FwuEVD3VWdh8KcgGWQ2QbjUx4l12MEy0b9-DZickSOF11M6lBm6M6FDqbnl6NYoEY9nJIMj0oxxfcMYlDXk$" moz-do-not-send="true" class="moz-txt-link-freetext">https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc</a> [2] <a target="_blank" href="https://urldefense.com/v3/__https://github.com/feilongjiang/jdk/tree/riscv-foreign-api__;!!ACWV5N9M2RV99hQ!IRN0FwuEVD3VWdh8KcgGWQ2QbjUx4l12MEy0b9-DZickSOF11M6lBm6M6FDqbnl6NYoEY9nJIMj0oxxf2M3LPtI$" moz-do-not-send="true" class="moz-txt-link-freetext">https://github.com/feilongjiang/jdk/tree/riscv-foreign-api</a></pre>
            </blockquote>
          </blockquote>
        </blockquote>
      </blockquote>
    </blockquote>
  </body>
</html>