Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8293841

RISC-V: Implementation of Foreign Function & Memory API (Preview)



    • Enhancement
    • Resolution: Fixed
    • P3
    • 21
    • 21
    • hotspot
    • None
    • 21
    • b07
    • riscv
    • linux


      Add experimental Foreign Function & Memory API support for riscv.

      Code is mainly adapted from AArch64 port, and with some riscv ABI specific changes:
      1. According to the riscv spec [1], when multiple floating-point precisions are supported,
      then valid values of narrower n-bit types, n < FLEN, are represented in the lower n
      bits of a FLEN-bit NaN value, in a process termed NaN-boxing. The upper bits of a
      valid NaN-boxed value must be all 1s. We initialize all bits of the return buffer with
      1s so that we could always transfer returned floating-point value from the return buffer
      into register with a single fld without knowing the current type of the value.
      2. When the type class is aggregate type, the ABI of riscv is more complicated [1][2]:
        - Aggregates larger than 2 * XLEN bits are passed by reference
        - A struct containing just one floating-point real is passed in a floating-point
           argument register if it is no more than ABI_FLEN bits wide and at least one
           floating-point argument register is available. A struct containing two floating-point
           reals is passed in two floating-point registers, if neither real is more than ABI_FLEN
           bits wide and at least two floating-point argument registers are available.
        - A struct containing one floating-point real and one integer (or bitfield), in either order,
           is passed in a floating-point register and an integer register, provided the floating-point
           real is no more than ABI_FLEN bits wide and the integer is no more than XLEN bits wide,
           and at least one floating-point argument register and at least one integer argument
           register is available.
        - Aggregates whose total size is no more than XLEN bits are passed in a register,
           with the fields laid out as though they were passed in memory. If no register is available,
           the aggregate is passed on the stack.
      3. The va_list type is defined as void* on riscv [3]. In the base integer calling convention,
      variadic arguments are passed in the same manner as named arguments, with one exception.
      Variadic arguments with 2×XLEN-bit alignment and size at most 2×XLEN bits are passed in
      an aligned register pair (i.e., the first register in the pair is even-numbered), or on the stack
      by value if none is available. After a variadic argument has been passed on the stack, all future
      arguments will also be passed on the stack (i.e. the last argument register may be left unused
      due to the aligned register pair rule).
      4. The frame layout of riscv is a bit different from AArch64. sender_sp_offset on riscv is 0 [4],
      so the FP_BIAS is set to 0 on riscv.

      [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#hardware-floating-point-calling-convention
      [2]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#integer-calling-convention
      [3]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#va_list-va_start-and-va_arg
      [4]: https://github.com/openjdk/jdk/blob/0532045edb709a995a42c07d95cb1cbabe886bed/src/hotspot/cpu/riscv/frame_riscv.hpp#L111


        Issue Links



              fjiang Feilong Jiang
              fjiang Feilong Jiang
              0 Vote for this issue
              4 Start watching this issue