Message ID | 6f6f811cb3453c1de41c8cb542aace23162f90a0.1594568655.git.alistair.francis@wdc.com |
---|---|

State | Committed |

Headers | show |

Series | glibc port for 32-bit RISC-V (RV32) | expand |

On Sun, 12 Jul 2020, Alistair Francis via Libc-alpha wrote: > Add a libm-test-ulps for RV32, this is the same as the RV64 one. > > This dosn't match what is generated by running `make regen-ulps` on RV32 > QEMU, but the current in tree RV64 doesn't match that either. For the record RV32 and RV64 QEMU ULPS results (obtained in the Linux user emulation mode) match each other in my setup. However those don't match RV64 results obtained with my HiFive Unleashed hardware, and then those don't match our existing RV64 results, so I guess they will have to be regenerated for the upcoming release. I'll leave this change up to Joseph to ack, as he's the expert in this area. Maciej

On Mon, Jul 13, 2020 at 10:23 AM Maciej W. Rozycki via Libc-alpha <libc-alpha@sourceware.org> wrote: > > On Sun, 12 Jul 2020, Alistair Francis via Libc-alpha wrote: > > > Add a libm-test-ulps for RV32, this is the same as the RV64 one. > > > > This dosn't match what is generated by running `make regen-ulps` on RV32 > > QEMU, but the current in tree RV64 doesn't match that either. > > For the record RV32 and RV64 QEMU ULPS results (obtained in the Linux > user emulation mode) match each other in my setup. However those don't > match RV64 results obtained with my HiFive Unleashed hardware, and then > those don't match our existing RV64 results, so I guess they will have to > be regenerated for the upcoming release. Yep, so the current RV64 in tree doesn't match what I generate in QEMU softmmu (full system) emulation for RV64. I kind of assumed that what is in tree matches the Unleased. > > I'll leave this change up to Joseph to ack, as he's the expert in this > area. Let me know if you want it re-generated. I was assuming that what is in tree works as it has been in a few releases now. Alistair > > Maciej

On Mon, 13 Jul 2020, Alistair Francis wrote: > > For the record RV32 and RV64 QEMU ULPS results (obtained in the Linux > > user emulation mode) match each other in my setup. However those don't > > match RV64 results obtained with my HiFive Unleashed hardware, and then > > those don't match our existing RV64 results, so I guess they will have to > > be regenerated for the upcoming release. > > Yep, so the current RV64 in tree doesn't match what I generate in QEMU > softmmu (full system) emulation for RV64. > > I kind of assumed that what is in tree matches the Unleased. For the record here's my RV64 diff to the Unleashed. Maciej Automatic regeneration of ULPs complete. Difference between the current baseline and the new baseline is: --- ../sysdeps/riscv/rv64/rvd/libm-test-ulps 2020-06-24 19:09:06.149618620 +0100 +++ .../obj/glibc/lp64d/math/NewUlps 2020-07-13 17:38:39.366490448 +0100 @@ -61,7 +61,7 @@ Function: "asinh": double: 1 -float: 1 +float: 2 ldouble: 3 Function: "asinh_downward": @@ -633,6 +633,7 @@ Function: "cos": double: 1 +float: 1 ldouble: 1 Function: "cos_downward": @@ -652,7 +653,7 @@ Function: "cosh": double: 1 -float: 1 +float: 2 ldouble: 1 Function: "cosh_downward": @@ -947,6 +948,7 @@ ldouble: 5 Function: "exp": +float: 1 ldouble: 1 Function: "exp10": @@ -1055,7 +1057,7 @@ Function: "j0": double: 2 -float: 2 +float: 8 ldouble: 2 Function: "j0_downward": @@ -1064,23 +1066,23 @@ ldouble: 4 Function: "j0_towardzero": -double: 2 -float: 1 +double: 5 +float: 6 ldouble: 2 Function: "j0_upward": -double: 3 -float: 2 +double: 4 +float: 5 ldouble: 5 Function: "j1": -double: 1 -float: 2 +double: 2 +float: 8 ldouble: 4 Function: "j1_downward": double: 3 -float: 2 +float: 5 ldouble: 4 Function: "j1_towardzero": @@ -1224,6 +1226,7 @@ Function: "sin": double: 1 +float: 1 ldouble: 1 Function: "sin_downward": @@ -1321,27 +1324,27 @@ Function: "tgamma": double: 5 -float: 4 +float: 8 ldouble: 4 Function: "tgamma_downward": double: 5 -float: 5 +float: 7 ldouble: 5 Function: "tgamma_towardzero": double: 5 -float: 4 +float: 7 ldouble: 5 Function: "tgamma_upward": double: 4 -float: 4 +float: 8 ldouble: 4 Function: "y0": double: 2 -float: 1 +float: 6 ldouble: 3 Function: "y0_downward": Copy .../obj/glibc/lp64d/math/NewUlps to ../sysdeps/riscv/rv64/rvd/libm-test-ulps (relative to source). Maciej

On 7/13/20 3:19 PM, Maciej W. Rozycki via Libc-alpha wrote: > On Mon, 13 Jul 2020, Alistair Francis wrote: > >>> For the record RV32 and RV64 QEMU ULPS results (obtained in the Linux >>> user emulation mode) match each other in my setup. However those don't >>> match RV64 results obtained with my HiFive Unleashed hardware, and then >>> those don't match our existing RV64 results, so I guess they will have to >>> be regenerated for the upcoming release. >> >> Yep, so the current RV64 in tree doesn't match what I generate in QEMU >> softmmu (full system) emulation for RV64. >> >> I kind of assumed that what is in tree matches the Unleased. > > For the record here's my RV64 diff to the Unleashed. > > Maciej That's close enough that you should commit this blind to the development branch that way developers don't get build failures. We do this routinely for i686 and older hardware being used Fedora Koji builders. > Automatic regeneration of ULPs complete. > Difference between the current baseline and the new baseline is: > --- ../sysdeps/riscv/rv64/rvd/libm-test-ulps 2020-06-24 19:09:06.149618620 +0100 > +++ .../obj/glibc/lp64d/math/NewUlps 2020-07-13 17:38:39.366490448 +0100 > @@ -61,7 +61,7 @@ > > Function: "asinh": > double: 1 > -float: 1 > +float: 2 > ldouble: 3 > > Function: "asinh_downward": > @@ -633,6 +633,7 @@ > > Function: "cos": > double: 1 > +float: 1 > ldouble: 1 > > Function: "cos_downward": > @@ -652,7 +653,7 @@ > > Function: "cosh": > double: 1 > -float: 1 > +float: 2 > ldouble: 1 > > Function: "cosh_downward": > @@ -947,6 +948,7 @@ > ldouble: 5 > > Function: "exp": > +float: 1 > ldouble: 1 > > Function: "exp10": > @@ -1055,7 +1057,7 @@ > > Function: "j0": > double: 2 > -float: 2 > +float: 8 > ldouble: 2 > > Function: "j0_downward": > @@ -1064,23 +1066,23 @@ > ldouble: 4 > > Function: "j0_towardzero": > -double: 2 > -float: 1 > +double: 5 > +float: 6 > ldouble: 2 > > Function: "j0_upward": > -double: 3 > -float: 2 > +double: 4 > +float: 5 > ldouble: 5 > > Function: "j1": > -double: 1 > -float: 2 > +double: 2 > +float: 8 > ldouble: 4 > > Function: "j1_downward": > double: 3 > -float: 2 > +float: 5 > ldouble: 4 > > Function: "j1_towardzero": > @@ -1224,6 +1226,7 @@ > > Function: "sin": > double: 1 > +float: 1 > ldouble: 1 > > Function: "sin_downward": > @@ -1321,27 +1324,27 @@ > > Function: "tgamma": > double: 5 > -float: 4 > +float: 8 > ldouble: 4 > > Function: "tgamma_downward": > double: 5 > -float: 5 > +float: 7 > ldouble: 5 > > Function: "tgamma_towardzero": > double: 5 > -float: 4 > +float: 7 > ldouble: 5 > > Function: "tgamma_upward": > double: 4 > -float: 4 > +float: 8 > ldouble: 4 > > Function: "y0": > double: 2 > -float: 1 > +float: 6 > ldouble: 3 > > Function: "y0_downward": > Copy .../obj/glibc/lp64d/math/NewUlps to ../sysdeps/riscv/rv64/rvd/libm-test-ulps (relative to source). > > Maciej >

On Mon, 13 Jul 2020, Maciej W. Rozycki via Libc-alpha wrote: > On Sun, 12 Jul 2020, Alistair Francis via Libc-alpha wrote: > > > Add a libm-test-ulps for RV32, this is the same as the RV64 one. > > > > This dosn't match what is generated by running `make regen-ulps` on RV32 > > QEMU, but the current in tree RV64 doesn't match that either. > > For the record RV32 and RV64 QEMU ULPS results (obtained in the Linux > user emulation mode) match each other in my setup. However those don't > match RV64 results obtained with my HiFive Unleashed hardware, and then > those don't match our existing RV64 results, so I guess they will have to > be regenerated for the upcoming release. If results on QEMU and on hardware (for the same binaries) don't match, that indicates a bug in one or the other, which you could find by identifying the exact instruction at which different floating-point values first appear. (You can get different results from compilation with different options or compiler versions, however, without any such bug, because of e.g. changes in when the compiler chose to contract an expression to use fused multiply-add.)

On 7/13/20 5:26 PM, Joseph Myers wrote: > On Mon, 13 Jul 2020, Maciej W. Rozycki via Libc-alpha wrote: > >> On Sun, 12 Jul 2020, Alistair Francis via Libc-alpha wrote: >> >>> Add a libm-test-ulps for RV32, this is the same as the RV64 one. >>> >>> This dosn't match what is generated by running `make regen-ulps` on RV32 >>> QEMU, but the current in tree RV64 doesn't match that either. >> >> For the record RV32 and RV64 QEMU ULPS results (obtained in the Linux >> user emulation mode) match each other in my setup. However those don't >> match RV64 results obtained with my HiFive Unleashed hardware, and then >> those don't match our existing RV64 results, so I guess they will have to >> be regenerated for the upcoming release. > > If results on QEMU and on hardware (for the same binaries) don't match, > that indicates a bug in one or the other, which you could find by > identifying the exact instruction at which different floating-point values > first appear. (You can get different results from compilation with > different options or compiler versions, however, without any such bug, > because of e.g. changes in when the compiler chose to contract an > expression to use fused multiply-add.) Is it really a "bug?" QEMU as an emulator could be taking liberties that the hardware does not for the express purpose of improving emulated performance? Is it ever QEMU's contract that it will operate identically to hardware given the same software configuration?

On Mon, 13 Jul 2020, Carlos O'Donell via Libc-alpha wrote: > > If results on QEMU and on hardware (for the same binaries) don't match, > > that indicates a bug in one or the other, which you could find by > > identifying the exact instruction at which different floating-point values > > first appear. (You can get different results from compilation with > > different options or compiler versions, however, without any such bug, > > because of e.g. changes in when the compiler chose to contract an > > expression to use fused multiply-add.) > > Is it really a "bug?" QEMU as an emulator could be taking liberties that > the hardware does not for the express purpose of improving emulated > performance? Is it ever QEMU's contract that it will operate identically > to hardware given the same software configuration? I believe the semantics of the RISC-V floating-point instructions are fully specified (including details such as choice of NaN results) and so it's a bug for either hardware or emulator to produce results other than those in the architecture specification. Sometimes architecture specifications do not fully specify results for all floating-point instructions. For example, the Power instructions to estimate reciprocal or reciprocal square root have accuracy bounds in the architecture specification, but the exact result is not specified, so it would be legitimate for hardware and emulation to produce different results for those instructions. But AArch64 has an instruction to estimate reciprocal square root whose exact semantics are fully specified in the architecture specification, meaning it's a bug if emulation fails to produce a result with exactly the same bit-pattern as hardware. My understanding is that all the RISC-V floating-point instructions are fully specified, as on AArch64.

On Mon, Jul 13, 2020 at 2:59 PM Joseph Myers <joseph@codesourcery.com> wrote: > > On Mon, 13 Jul 2020, Carlos O'Donell via Libc-alpha wrote: > > > > If results on QEMU and on hardware (for the same binaries) don't match, > > > that indicates a bug in one or the other, which you could find by > > > identifying the exact instruction at which different floating-point values > > > first appear. (You can get different results from compilation with > > > different options or compiler versions, however, without any such bug, > > > because of e.g. changes in when the compiler chose to contract an > > > expression to use fused multiply-add.) > > > > Is it really a "bug?" QEMU as an emulator could be taking liberties that > > the hardware does not for the express purpose of improving emulated > > performance? Is it ever QEMU's contract that it will operate identically > > to hardware given the same software configuration? > > I believe the semantics of the RISC-V floating-point instructions are > fully specified (including details such as choice of NaN results) and so > it's a bug for either hardware or emulator to produce results other than > those in the architecture specification. > > Sometimes architecture specifications do not fully specify results for all > floating-point instructions. For example, the Power instructions to > estimate reciprocal or reciprocal square root have accuracy bounds in the > architecture specification, but the exact result is not specified, so it > would be legitimate for hardware and emulation to produce different > results for those instructions. But AArch64 has an instruction to > estimate reciprocal square root whose exact semantics are fully specified > in the architecture specification, meaning it's a bug if emulation fails > to produce a result with exactly the same bit-pattern as hardware. My > understanding is that all the RISC-V floating-point instructions are fully > specified, as on AArch64. This is indeed the case (at least for now; the forthcoming vector extension adds an unordered sum reduction whose result can vary by implementation). I think it would be good to confirm whether the exact same binaries were used for the QEMU and Unleashed experiments, and if not, whether the disparity remains when that's rectified. > > -- > Joseph S. Myers > joseph@codesourcery.com

On Mon, 13 Jul 2020, Andrew Waterman wrote: > > Sometimes architecture specifications do not fully specify results for all > > floating-point instructions. For example, the Power instructions to > > estimate reciprocal or reciprocal square root have accuracy bounds in the > > architecture specification, but the exact result is not specified, so it > > would be legitimate for hardware and emulation to produce different > > results for those instructions. But AArch64 has an instruction to > > estimate reciprocal square root whose exact semantics are fully specified > > in the architecture specification, meaning it's a bug if emulation fails > > to produce a result with exactly the same bit-pattern as hardware. My > > understanding is that all the RISC-V floating-point instructions are fully > > specified, as on AArch64. > > This is indeed the case (at least for now; the forthcoming vector > extension adds an unordered sum reduction whose result can vary by > implementation). I think it would be good to confirm whether the > exact same binaries were used for the QEMU and Unleashed experiments, > and if not, whether the disparity remains when that's rectified. Well, yes. I just ran `make regen-ulps' consecutively with different `test-wrapper*' variables each time so as to redirect execution either to my HiFive Unleashed board or (user-mode) QEMU. I have double-checked the logs now and no rebuild was made for subsequent runs, so the very same executables and DSOs were used. I tend to trust hardware with these matters and only use QEMU for quick comparative verification where hardware is slow, or where hardware is unavailable. A silicon erratum cannot be excluded in this case of course, but I would check QEMU first. Maciej

On Tue, 14 Jul 2020, Maciej W. Rozycki via Libc-alpha wrote: > Well, yes. I just ran `make regen-ulps' consecutively with different > `test-wrapper*' variables each time so as to redirect execution either to > my HiFive Unleashed board or (user-mode) QEMU. I have double-checked the > logs now and no rebuild was made for subsequent runs, so the very same > executables and DSOs were used. So picking one function and setting its ulps back to the lower value, then rerunning the test on whichever of hardware and QEMU gave the higher value, should result in a test log showing a specific input to a specific function (in a specific rounding mode) for which the results on hardware and QEMU differ. After confirming the difference with a minimal test just making that one function call, it should be possible to trace the execution of the function, whether in a debugger or inserting printf calls, to find the exact instruction for which hardware and QEMU produce different results with the same inputs.

diff --git a/sysdeps/riscv/rv32/rvd/libm-test-ulps b/sysdeps/riscv/rv32/rvd/libm-test-ulps new file mode 100644 index 0000000000..8e2971ce66 --- /dev/null +++ b/sysdeps/riscv/rv32/rvd/libm-test-ulps @@ -0,0 +1,1402 @@ +# Begin of automatic generation + +# Maximal error of functions: +Function: "acos": +float: 1 +ldouble: 1 + +Function: "acos_downward": +double: 1 +float: 1 +ldouble: 1 + +Function: "acos_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "acos_upward": +double: 1 +float: 1 +ldouble: 1 + +Function: "acosh": +double: 2 +float: 2 +ldouble: 2 + +Function: "acosh_downward": +double: 2 +float: 2 +ldouble: 3 + +Function: "acosh_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: "acosh_upward": +double: 2 +float: 2 +ldouble: 2 + +Function: "asin": +float: 1 +ldouble: 1 + +Function: "asin_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: "asin_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "asin_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "asinh": +double: 1 +float: 1 +ldouble: 3 + +Function: "asinh_downward": +double: 3 +float: 3 +ldouble: 4 + +Function: "asinh_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: "asinh_upward": +double: 3 +float: 3 +ldouble: 4 + +Function: "atan": +float: 1 +ldouble: 1 + +Function: "atan2": +float: 1 +ldouble: 1 + +Function: "atan2_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: "atan2_towardzero": +double: 1 +float: 2 +ldouble: 3 + +Function: "atan2_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "atan_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: "atan_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "atan_upward": +double: 1 +float: 2 +ldouble: 2 + +Function: "atanh": +double: 2 +float: 2 +ldouble: 3 + +Function: "atanh_downward": +double: 3 +float: 3 +ldouble: 4 + +Function: "atanh_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: "atanh_upward": +double: 3 +float: 3 +ldouble: 4 + +Function: "cabs": +double: 1 +ldouble: 1 + +Function: "cabs_downward": +double: 1 +ldouble: 1 + +Function: "cabs_towardzero": +double: 1 +ldouble: 1 + +Function: "cabs_upward": +double: 1 +ldouble: 1 + +Function: Real part of "cacos": +double: 1 +float: 2 +ldouble: 2 + +Function: Imaginary part of "cacos": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "cacos_downward": +double: 3 +float: 2 +ldouble: 3 + +Function: Imaginary part of "cacos_downward": +double: 5 +float: 3 +ldouble: 6 + +Function: Real part of "cacos_towardzero": +double: 3 +float: 2 +ldouble: 3 + +Function: Imaginary part of "cacos_towardzero": +double: 4 +float: 2 +ldouble: 5 + +Function: Real part of "cacos_upward": +double: 2 +float: 2 +ldouble: 3 + +Function: Imaginary part of "cacos_upward": +double: 5 +float: 5 +ldouble: 7 + +Function: Real part of "cacosh": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "cacosh": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "cacosh_downward": +double: 4 +float: 2 +ldouble: 5 + +Function: Imaginary part of "cacosh_downward": +double: 3 +float: 3 +ldouble: 4 + +Function: Real part of "cacosh_towardzero": +double: 4 +float: 2 +ldouble: 5 + +Function: Imaginary part of "cacosh_towardzero": +double: 3 +float: 2 +ldouble: 3 + +Function: Real part of "cacosh_upward": +double: 4 +float: 3 +ldouble: 6 + +Function: Imaginary part of "cacosh_upward": +double: 3 +float: 2 +ldouble: 4 + +Function: "carg": +float: 1 +ldouble: 2 + +Function: "carg_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: "carg_towardzero": +double: 1 +float: 2 +ldouble: 3 + +Function: "carg_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: Real part of "casin": +double: 1 +float: 1 +ldouble: 2 + +Function: Imaginary part of "casin": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "casin_downward": +double: 3 +float: 2 +ldouble: 3 + +Function: Imaginary part of "casin_downward": +double: 5 +float: 3 +ldouble: 6 + +Function: Real part of "casin_towardzero": +double: 3 +float: 1 +ldouble: 3 + +Function: Imaginary part of "casin_towardzero": +double: 4 +float: 2 +ldouble: 5 + +Function: Real part of "casin_upward": +double: 3 +float: 2 +ldouble: 3 + +Function: Imaginary part of "casin_upward": +double: 5 +float: 5 +ldouble: 7 + +Function: Real part of "casinh": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "casinh": +double: 1 +float: 1 +ldouble: 2 + +Function: Real part of "casinh_downward": +double: 5 +float: 3 +ldouble: 6 + +Function: Imaginary part of "casinh_downward": +double: 3 +float: 2 +ldouble: 3 + +Function: Real part of "casinh_towardzero": +double: 4 +float: 2 +ldouble: 5 + +Function: Imaginary part of "casinh_towardzero": +double: 3 +float: 1 +ldouble: 3 + +Function: Real part of "casinh_upward": +double: 5 +float: 5 +ldouble: 7 + +Function: Imaginary part of "casinh_upward": +double: 3 +float: 2 +ldouble: 3 + +Function: Real part of "catan": +double: 1 +float: 1 +ldouble: 1 + +Function: Imaginary part of "catan": +double: 1 +float: 1 +ldouble: 1 + +Function: Real part of "catan_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: Imaginary part of "catan_downward": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "catan_towardzero": +double: 1 +float: 2 +ldouble: 2 + +Function: Imaginary part of "catan_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "catan_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: Imaginary part of "catan_upward": +double: 2 +float: 2 +ldouble: 3 + +Function: Real part of "catanh": +double: 1 +float: 1 +ldouble: 1 + +Function: Imaginary part of "catanh": +double: 1 +float: 1 +ldouble: 1 + +Function: Real part of "catanh_downward": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "catanh_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "catanh_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "catanh_towardzero": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "catanh_upward": +double: 4 +float: 4 +ldouble: 4 + +Function: Imaginary part of "catanh_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "cbrt": +double: 3 +float: 1 +ldouble: 1 + +Function: "cbrt_downward": +double: 4 +float: 1 +ldouble: 1 + +Function: "cbrt_towardzero": +double: 3 +float: 1 +ldouble: 1 + +Function: "cbrt_upward": +double: 5 +float: 1 +ldouble: 1 + +Function: Real part of "ccos": +double: 1 +float: 1 +ldouble: 1 + +Function: Imaginary part of "ccos": +double: 1 +float: 1 +ldouble: 1 + +Function: Real part of "ccos_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: Imaginary part of "ccos_downward": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "ccos_towardzero": +double: 1 +float: 2 +ldouble: 2 + +Function: Imaginary part of "ccos_towardzero": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "ccos_upward": +double: 1 +float: 2 +ldouble: 3 + +Function: Imaginary part of "ccos_upward": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "ccosh": +double: 1 +float: 1 +ldouble: 1 + +Function: Imaginary part of "ccosh": +double: 1 +float: 1 +ldouble: 1 + +Function: Real part of "ccosh_downward": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "ccosh_downward": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "ccosh_towardzero": +double: 2 +float: 3 +ldouble: 2 + +Function: Imaginary part of "ccosh_towardzero": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "ccosh_upward": +double: 1 +float: 2 +ldouble: 3 + +Function: Imaginary part of "ccosh_upward": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "cexp": +double: 2 +float: 1 +ldouble: 1 + +Function: Imaginary part of "cexp": +double: 1 +float: 2 +ldouble: 1 + +Function: Real part of "cexp_downward": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "cexp_downward": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "cexp_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "cexp_towardzero": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "cexp_upward": +double: 1 +float: 2 +ldouble: 3 + +Function: Imaginary part of "cexp_upward": +double: 3 +float: 2 +ldouble: 3 + +Function: Real part of "clog": +double: 3 +float: 3 +ldouble: 2 + +Function: Imaginary part of "clog": +float: 1 +ldouble: 1 + +Function: Real part of "clog10": +double: 3 +float: 4 +ldouble: 2 + +Function: Imaginary part of "clog10": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "clog10_downward": +double: 5 +float: 5 +ldouble: 3 + +Function: Imaginary part of "clog10_downward": +double: 2 +float: 4 +ldouble: 3 + +Function: Real part of "clog10_towardzero": +double: 5 +float: 5 +ldouble: 4 + +Function: Imaginary part of "clog10_towardzero": +double: 2 +float: 4 +ldouble: 3 + +Function: Real part of "clog10_upward": +double: 6 +float: 5 +ldouble: 4 + +Function: Imaginary part of "clog10_upward": +double: 2 +float: 4 +ldouble: 3 + +Function: Real part of "clog_downward": +double: 4 +float: 3 +ldouble: 3 + +Function: Imaginary part of "clog_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "clog_towardzero": +double: 4 +float: 4 +ldouble: 3 + +Function: Imaginary part of "clog_towardzero": +double: 1 +float: 3 +ldouble: 2 + +Function: Real part of "clog_upward": +double: 4 +float: 3 +ldouble: 4 + +Function: Imaginary part of "clog_upward": +double: 1 +float: 2 +ldouble: 2 + +Function: "cos": +double: 1 +ldouble: 1 + +Function: "cos_downward": +double: 1 +float: 1 +ldouble: 3 + +Function: "cos_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "cos_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "cosh": +double: 1 +float: 1 +ldouble: 1 + +Function: "cosh_downward": +double: 2 +float: 1 +ldouble: 2 + +Function: "cosh_towardzero": +double: 2 +float: 1 +ldouble: 2 + +Function: "cosh_upward": +double: 2 +float: 2 +ldouble: 3 + +Function: Real part of "cpow": +double: 2 +float: 5 +ldouble: 4 + +Function: Imaginary part of "cpow": +float: 2 +ldouble: 1 + +Function: Real part of "cpow_downward": +double: 5 +float: 8 +ldouble: 6 + +Function: Imaginary part of "cpow_downward": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "cpow_towardzero": +double: 5 +float: 8 +ldouble: 6 + +Function: Imaginary part of "cpow_towardzero": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "cpow_upward": +double: 4 +float: 1 +ldouble: 3 + +Function: Imaginary part of "cpow_upward": +double: 1 +float: 2 +ldouble: 2 + +Function: Real part of "csin": +double: 1 +float: 1 +ldouble: 1 + +Function: Imaginary part of "csin": +ldouble: 1 + +Function: Real part of "csin_downward": +double: 3 +float: 3 +ldouble: 2 + +Function: Imaginary part of "csin_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: Real part of "csin_towardzero": +double: 3 +float: 3 +ldouble: 2 + +Function: Imaginary part of "csin_towardzero": +double: 1 +float: 1 +ldouble: 2 + +Function: Real part of "csin_upward": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "csin_upward": +double: 1 +float: 2 +ldouble: 3 + +Function: Real part of "csinh": +float: 1 +ldouble: 1 + +Function: Imaginary part of "csinh": +double: 1 +float: 1 +ldouble: 1 + +Function: Real part of "csinh_downward": +double: 2 +float: 1 +ldouble: 2 + +Function: Imaginary part of "csinh_downward": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "csinh_towardzero": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "csinh_towardzero": +double: 3 +float: 3 +ldouble: 2 + +Function: Real part of "csinh_upward": +double: 1 +float: 2 +ldouble: 3 + +Function: Imaginary part of "csinh_upward": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "csqrt": +double: 2 +float: 2 +ldouble: 2 + +Function: Imaginary part of "csqrt": +double: 2 +float: 2 +ldouble: 2 + +Function: Real part of "csqrt_downward": +double: 5 +float: 4 +ldouble: 4 + +Function: Imaginary part of "csqrt_downward": +double: 4 +float: 3 +ldouble: 3 + +Function: Real part of "csqrt_towardzero": +double: 4 +float: 3 +ldouble: 3 + +Function: Imaginary part of "csqrt_towardzero": +double: 4 +float: 3 +ldouble: 3 + +Function: Real part of "csqrt_upward": +double: 5 +float: 4 +ldouble: 4 + +Function: Imaginary part of "csqrt_upward": +double: 3 +float: 3 +ldouble: 3 + +Function: Real part of "ctan": +double: 1 +float: 1 +ldouble: 3 + +Function: Imaginary part of "ctan": +double: 2 +float: 2 +ldouble: 3 + +Function: Real part of "ctan_downward": +double: 6 +float: 5 +ldouble: 4 + +Function: Imaginary part of "ctan_downward": +double: 2 +float: 2 +ldouble: 5 + +Function: Real part of "ctan_towardzero": +double: 5 +float: 2 +ldouble: 4 + +Function: Imaginary part of "ctan_towardzero": +double: 2 +float: 2 +ldouble: 5 + +Function: Real part of "ctan_upward": +double: 2 +float: 4 +ldouble: 5 + +Function: Imaginary part of "ctan_upward": +double: 2 +float: 2 +ldouble: 5 + +Function: Real part of "ctanh": +double: 2 +float: 2 +ldouble: 3 + +Function: Imaginary part of "ctanh": +double: 2 +float: 1 +ldouble: 3 + +Function: Real part of "ctanh_downward": +double: 4 +float: 2 +ldouble: 5 + +Function: Imaginary part of "ctanh_downward": +double: 6 +float: 5 +ldouble: 4 + +Function: Real part of "ctanh_towardzero": +double: 2 +float: 2 +ldouble: 5 + +Function: Imaginary part of "ctanh_towardzero": +double: 5 +float: 2 +ldouble: 3 + +Function: Real part of "ctanh_upward": +double: 2 +float: 2 +ldouble: 5 + +Function: Imaginary part of "ctanh_upward": +double: 2 +float: 3 +ldouble: 5 + +Function: "erf": +double: 1 +float: 1 +ldouble: 1 + +Function: "erf_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: "erf_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "erf_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "erfc": +double: 2 +float: 2 +ldouble: 2 + +Function: "erfc_downward": +double: 4 +float: 4 +ldouble: 5 + +Function: "erfc_towardzero": +double: 3 +float: 3 +ldouble: 4 + +Function: "erfc_upward": +double: 4 +float: 4 +ldouble: 5 + +Function: "exp": +ldouble: 1 + +Function: "exp10": +double: 2 +ldouble: 2 + +Function: "exp10_downward": +double: 3 +float: 1 +ldouble: 3 + +Function: "exp10_towardzero": +double: 3 +float: 1 +ldouble: 3 + +Function: "exp10_upward": +double: 2 +float: 1 +ldouble: 3 + +Function: "exp2": +double: 1 +ldouble: 1 + +Function: "exp2_downward": +double: 1 +ldouble: 1 + +Function: "exp2_towardzero": +double: 1 +ldouble: 1 + +Function: "exp2_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "exp_downward": +double: 1 +float: 1 + +Function: "exp_towardzero": +double: 1 +float: 1 + +Function: "exp_upward": +double: 1 +float: 1 + +Function: "expm1": +double: 1 +float: 1 +ldouble: 1 + +Function: "expm1_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: "expm1_towardzero": +double: 1 +float: 2 +ldouble: 4 + +Function: "expm1_upward": +double: 1 +float: 1 +ldouble: 3 + +Function: "gamma": +double: 3 +float: 3 +ldouble: 5 + +Function: "gamma_downward": +double: 4 +float: 4 +ldouble: 8 + +Function: "gamma_towardzero": +double: 4 +float: 3 +ldouble: 5 + +Function: "gamma_upward": +double: 4 +float: 5 +ldouble: 8 + +Function: "hypot": +double: 1 +ldouble: 1 + +Function: "hypot_downward": +double: 1 +ldouble: 1 + +Function: "hypot_towardzero": +double: 1 +ldouble: 1 + +Function: "hypot_upward": +double: 1 +ldouble: 1 + +Function: "j0": +double: 2 +float: 2 +ldouble: 2 + +Function: "j0_downward": +double: 2 +float: 4 +ldouble: 4 + +Function: "j0_towardzero": +double: 2 +float: 1 +ldouble: 2 + +Function: "j0_upward": +double: 3 +float: 2 +ldouble: 5 + +Function: "j1": +double: 1 +float: 2 +ldouble: 4 + +Function: "j1_downward": +double: 3 +float: 2 +ldouble: 4 + +Function: "j1_towardzero": +double: 3 +float: 2 +ldouble: 4 + +Function: "j1_upward": +double: 3 +float: 4 +ldouble: 3 + +Function: "jn": +double: 4 +float: 4 +ldouble: 7 + +Function: "jn_downward": +double: 4 +float: 5 +ldouble: 8 + +Function: "jn_towardzero": +double: 4 +float: 5 +ldouble: 8 + +Function: "jn_upward": +double: 5 +float: 4 +ldouble: 7 + +Function: "lgamma": +double: 3 +float: 3 +ldouble: 5 + +Function: "lgamma_downward": +double: 4 +float: 4 +ldouble: 8 + +Function: "lgamma_towardzero": +double: 4 +float: 3 +ldouble: 5 + +Function: "lgamma_upward": +double: 4 +float: 5 +ldouble: 8 + +Function: "log": +ldouble: 1 + +Function: "log10": +double: 2 +float: 2 +ldouble: 1 + +Function: "log10_downward": +double: 2 +float: 3 +ldouble: 1 + +Function: "log10_towardzero": +double: 2 +float: 1 +ldouble: 1 + +Function: "log10_upward": +double: 2 +float: 2 +ldouble: 1 + +Function: "log1p": +double: 1 +float: 1 +ldouble: 2 + +Function: "log1p_downward": +double: 1 +float: 2 +ldouble: 3 + +Function: "log1p_towardzero": +double: 2 +float: 2 +ldouble: 3 + +Function: "log1p_upward": +double: 2 +float: 2 +ldouble: 2 + +Function: "log2": +double: 1 +float: 1 +ldouble: 2 + +Function: "log2_downward": +double: 3 +ldouble: 3 + +Function: "log2_towardzero": +double: 2 +ldouble: 1 + +Function: "log2_upward": +double: 3 +ldouble: 1 + +Function: "log_downward": +ldouble: 1 + +Function: "log_towardzero": +ldouble: 2 + +Function: "log_upward": +double: 1 +ldouble: 2 + +Function: "pow": +double: 1 +ldouble: 2 + +Function: "pow_downward": +double: 1 +float: 1 +ldouble: 2 + +Function: "pow_towardzero": +double: 1 +float: 1 +ldouble: 2 + +Function: "pow_upward": +double: 1 +float: 1 +ldouble: 2 + +Function: "sin": +double: 1 +ldouble: 1 + +Function: "sin_downward": +double: 1 +float: 1 +ldouble: 3 + +Function: "sin_towardzero": +double: 1 +float: 1 +ldouble: 2 + +Function: "sin_upward": +double: 1 +float: 1 +ldouble: 3 + +Function: "sincos": +double: 1 +ldouble: 1 + +Function: "sincos_downward": +double: 1 +float: 1 +ldouble: 3 + +Function: "sincos_towardzero": +double: 1 +float: 1 +ldouble: 2 + +Function: "sincos_upward": +double: 1 +float: 1 +ldouble: 3 + +Function: "sinh": +double: 2 +float: 2 +ldouble: 2 + +Function: "sinh_downward": +double: 3 +float: 3 +ldouble: 3 + +Function: "sinh_towardzero": +double: 2 +float: 2 +ldouble: 3 + +Function: "sinh_upward": +double: 3 +float: 3 +ldouble: 4 + +Function: "tan": +float: 1 +ldouble: 1 + +Function: "tan_downward": +double: 1 +float: 2 +ldouble: 1 + +Function: "tan_towardzero": +double: 1 +float: 1 +ldouble: 1 + +Function: "tan_upward": +double: 1 +float: 1 +ldouble: 1 + +Function: "tanh": +double: 2 +float: 2 +ldouble: 2 + +Function: "tanh_downward": +double: 3 +float: 3 +ldouble: 4 + +Function: "tanh_towardzero": +double: 2 +float: 2 +ldouble: 3 + +Function: "tanh_upward": +double: 3 +float: 3 +ldouble: 3 + +Function: "tgamma": +double: 5 +float: 4 +ldouble: 4 + +Function: "tgamma_downward": +double: 5 +float: 5 +ldouble: 5 + +Function: "tgamma_towardzero": +double: 5 +float: 4 +ldouble: 5 + +Function: "tgamma_upward": +double: 4 +float: 4 +ldouble: 4 + +Function: "y0": +double: 2 +float: 1 +ldouble: 3 + +Function: "y0_downward": +double: 3 +float: 4 +ldouble: 4 + +Function: "y0_towardzero": +double: 3 +float: 3 +ldouble: 3 + +Function: "y0_upward": +double: 2 +float: 5 +ldouble: 3 + +Function: "y1": +double: 3 +float: 2 +ldouble: 2 + +Function: "y1_downward": +double: 3 +float: 2 +ldouble: 4 + +Function: "y1_towardzero": +double: 3 +float: 2 +ldouble: 2 + +Function: "y1_upward": +double: 5 +float: 2 +ldouble: 5 + +Function: "yn": +double: 3 +float: 3 +ldouble: 5 + +Function: "yn_downward": +double: 3 +float: 4 +ldouble: 5 + +Function: "yn_towardzero": +double: 3 +float: 3 +ldouble: 5 + +Function: "yn_upward": +double: 4 +float: 5 +ldouble: 5 + +# end of automatic generation diff --git a/sysdeps/riscv/rv32/rvd/libm-test-ulps-name b/sysdeps/riscv/rv32/rvd/libm-test-ulps-name new file mode 100644 index 0000000000..827fcdca19 --- /dev/null +++ b/sysdeps/riscv/rv32/rvd/libm-test-ulps-name @@ -0,0 +1 @@ +RISC-V