@@ -271,6 +271,10 @@ JRT_LEAF(jdouble, SharedRuntime::drem(jdouble x, jdouble y))
271
271
#endif
272
272
JRT_END
273
273
274
+ JRT_LEAF(jfloat, SharedRuntime::i2f(jint x))
275
+ return (jfloat)x;
276
+ JRT_END
277
+
274
278
#ifdef __SOFTFP__
275
279
JRT_LEAF(jfloat, SharedRuntime::fadd(jfloat x, jfloat y))
276
280
return x + y;
@@ -304,10 +308,6 @@ JRT_LEAF(jdouble, SharedRuntime::ddiv(jdouble x, jdouble y))
304
308
return x / y;
305
309
JRT_END
306
310
307
- JRT_LEAF(jfloat, SharedRuntime::i2f(jint x))
308
- return (jfloat)x;
309
- JRT_END
310
-
311
311
JRT_LEAF(jdouble, SharedRuntime::i2d(jint x))
312
312
return (jdouble)x;
313
313
JRT_END
@@ -448,6 +448,86 @@ JRT_LEAF(jdouble, SharedRuntime::l2d(jlong x))
448
448
return (jdouble)x;
449
449
JRT_END
450
450
451
+ // Reference implementation at src/java.base/share/classes/java/lang/Float.java:floatToFloat16
452
+ JRT_LEAF(jshort, SharedRuntime::f2hf(jfloat x))
453
+ jint doppel = SharedRuntime::f2i(x);
454
+ jshort sign_bit = (jshort) ((doppel & 0x80000000) >> 16);
455
+ if (g_isnan(x))
456
+ return (jshort)(sign_bit | 0x7c00 | (doppel & 0x007fe000) >> 13 | (doppel & 0x00001ff0) >> 4 | (doppel & 0x0000000f));
457
+
458
+ jfloat abs_f = (x >= 0.0f) ? x : (x * -1.0f);
459
+
460
+ // Overflow threshold is halffloat max value + 1/2 ulp
461
+ if (abs_f >= (65504.0f + 16.0f)) {
462
+ return (jshort)(sign_bit | 0x7c00); // Positive or negative infinity
463
+ }
464
+
465
+ // Smallest magnitude of Halffloat is 0x1.0p-24, half-way or smaller rounds to zero
466
+ if (abs_f <= (pow(2, -24) * 0.5f)) { // Covers float zeros and subnormals.
467
+ return sign_bit; // Positive or negative zero
468
+ }
469
+
470
+ jint exp = 0x7f800000 & doppel;
471
+
472
+ // For binary16 subnormals, beside forcing exp to -15, retain
473
+ // the difference exp_delta = E_min - exp. This is the excess
474
+ // shift value, in addition to 13, to be used in the
475
+ // computations below. Further the (hidden) msb with value 1
476
+ // in f must be involved as well
477
+ jint exp_delta = 0;
478
+ jint msb = 0x00000000;
479
+ if (exp < -14) {
480
+ exp_delta = -14 - exp;
481
+ exp = -15;
482
+ msb = 0x00800000;
483
+ }
484
+ jint f_signif_bits = ((doppel & 0x007fffff) | msb);
485
+
486
+ // Significand bits as if using rounding to zero
487
+ jshort signif_bits = (jshort)(f_signif_bits >> (13 + exp_delta));
488
+
489
+ jint lsb = f_signif_bits & (1 << (13 + exp_delta));
490
+ jint round = f_signif_bits & (1 << (12 + exp_delta));
491
+ jint sticky = f_signif_bits & ((1 << (12 + exp_delta)) - 1);
492
+
493
+ if (round != 0 && ((lsb | sticky) != 0 )) {
494
+ signif_bits++;
495
+ }
496
+
497
+ return (jshort)(sign_bit | ( ((exp + 15) << 10) + signif_bits ) );
498
+ JRT_END
499
+
500
+ // Reference implementation at src/java.base/share/classes/java/lang/Float.java:float16ToFloat
501
+ JRT_LEAF(jfloat, SharedRuntime::hf2f(jshort x))
502
+ // Halffloat format has 1 signbit, 5 exponent bits and
503
+ // 10 significand bits
504
+ jint hf_arg = (jint)x;
505
+ jint hf_sign_bit = 0x8000 & hf_arg;
506
+ jint hf_exp_bits = 0x7c00 & hf_arg;
507
+ jint hf_significand_bits = 0x03ff & hf_arg;
508
+
509
+ jint significand_shift = 13; //difference between float and halffloat precision
510
+
511
+ jfloat sign = (hf_sign_bit != 0) ? -1.0f : 1.0f;
512
+
513
+ // Extract halffloat exponent, remove its bias
514
+ jint hf_exp = (hf_exp_bits >> 10) - 15;
515
+
516
+ if (hf_exp == -15) {
517
+ // For subnormal values, return 2^-24 * significand bits
518
+ return (sign * (pow(2,-24)) * hf_significand_bits);
519
+ }else if (hf_exp == 16) {
520
+ return (hf_significand_bits == 0) ? sign * float_infinity : (SharedRuntime::i2f((hf_sign_bit << 16) | 0x7f800000 |
521
+ (hf_significand_bits << significand_shift)));
522
+ }
523
+
524
+ // Add the bias of float exponent and shift
525
+ int float_exp_bits = (hf_exp + 127) << (24 - 1);
526
+
527
+ // Combine sign, exponent and significand bits
528
+ return SharedRuntime::i2f((hf_sign_bit << 16) | float_exp_bits | (hf_significand_bits << significand_shift));
529
+ JRT_END
530
+
451
531
// Exception handling across interpreter/compiler boundaries
452
532
//
453
533
// exception_handler_for_return_address(...) returns the continuation address.
0 commit comments