]> sourceware.org Git - systemtap.git/commitdiff
PR13838: Add float32 support and corresponding test cases
authorAlice Zhang <alizhang@redhat.com>
Tue, 10 Nov 2020 18:11:13 +0000 (13:11 -0500)
committerAlice Zhang <alizhang@redhat.com>
Thu, 12 Nov 2020 18:21:02 +0000 (13:21 -0500)
runtime/softfloat.* & runtime/softfloat/: add f32 support and f32 to f64
conversion
tapset/floatingpoint.stp: fixed some documentation typos & add f32_tp_f64
tapset function
testsuite/buildok/floatingpoint.stp: add f32 related test cases
main.cxx: add float parameter to sdt_benchmark_thread function for test purpose

runtime/softfloat.c & tapset/floatingpoint.stp : delete unnecessary functions
to keep the code concise

main.cxx
runtime/softfloat.c
runtime/softfloat.h
runtime/softfloat/internals.h
runtime/softfloat/primitives.h
runtime/softfloat/specialize.h
tapset/floatingpoint.stp
testsuite/buildok/floatingpoint.stp

index e63be8f168a7ea52aa19a2b1ea6fa6307ea1e4d9..f3a0d983086ce1f3f647446e503e77b91dcbb14c 100644 (file)
--- a/main.cxx
+++ b/main.cxx
@@ -375,10 +375,11 @@ setup_signals (sighandler_t handler)
 
 
 static void
-sdt_benchmark_thread(unsigned long i, double *fpointer)
+sdt_benchmark_thread(unsigned long i, double *fpointer, float *fpointer2)
 {
   PROBE(stap, benchmark__thread__start);
   *fpointer += 0.0;
+  *fpointer2 += 0.0;
   while (i--)
     PROBE1(stap, benchmark, i);
   PROBE(stap, benchmark__thread__end);
@@ -405,8 +406,9 @@ run_sdt_benchmark(systemtap_session& s)
     {
       vector<thread> handles;
       double f = 2.71828;
+      float f2 = 1.41421;
       for (unsigned long i = 0; i < threads; ++i)
-        handles.push_back(thread(sdt_benchmark_thread, loops,&f));
+        handles.push_back(thread(sdt_benchmark_thread, loops, &f, &f2));
       for (unsigned long i = 0; i < threads; ++i)
         handles[i].join();
     }
index 7122c6625c8cd507d0b3d01bdccb2fc1ccc67cdd..6951933709a8b59e432778911ef2f5786d03951c 100644 (file)
@@ -52,6 +52,30 @@ THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags = 0;
 
 THREAD_LOCAL uint_fast8_t extF80_roundingPrecision = 80;
 
+#ifndef softfloat_countLeadingZeros32
+
+#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32
+
+uint_fast8_t softfloat_countLeadingZeros32( uint32_t a )
+{
+    uint_fast8_t count;
+
+    count = 0;
+    if ( a < 0x10000 ) {
+        count = 16;
+        a <<= 16;
+    }
+    if ( a < 0x1000000 ) {
+        count += 8;
+        a <<= 8;
+    }
+    count += softfloat_countLeadingZeros8[a>>24];
+    return count;
+
+}
+
+#endif
+
 #ifndef softfloat_countLeadingZeros64
 
 #define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64
@@ -178,7 +202,6 @@ void
 
 #endif
 
-
 #ifndef softfloat_shiftRightJam64
 
 uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist )
@@ -501,6 +524,17 @@ int_fast64_t f64_to_i64( float64_t a, uint_fast8_t roundingMode, bool exact )
 
 }
 
+/*----------------------------------------------------------------------------
+| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point
+| NaN, and returns the bit pattern of this value as an unsigned integer.
+*----------------------------------------------------------------------------*/
+uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr )
+{
+
+    return (uint_fast32_t) aPtr->sign<<31 | 0x7FC00000 | aPtr->v64>>41;
+
+}
+
 /*----------------------------------------------------------------------------
 | Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point
 | NaN, and returns the bit pattern of this value as an unsigned integer.
@@ -512,6 +546,24 @@ uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr )
             | aPtr->v64>>12;
 }
 
+/*----------------------------------------------------------------------------
+| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts
+| this NaN to the common NaN form, and stores the resulting common NaN at the
+| location pointed to by 'zPtr'.  If the NaN is a signaling NaN, the invalid
+| exception is raised.
+*----------------------------------------------------------------------------*/
+void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr )
+{
+
+    if ( softfloat_isSigNaNF32UI( uiA ) ) {
+        softfloat_raiseFlags( softfloat_flag_invalid );
+    }
+    zPtr->sign = uiA>>31;
+    zPtr->v64  = (uint_fast64_t) uiA<<41;
+    zPtr->v0   = 0;
+
+}
+
 /*----------------------------------------------------------------------------
 | Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
 | this NaN to the common NaN form, and stores the resulting common NaN at the
@@ -977,7 +1029,7 @@ float64_t
     *------------------------------------------------------------------------*/
     if ( ! expA ) {
         if ( ! sigA ) goto zeroProd;
-        normExpSig = softfloat_normSubnormalF64Sig( sigA );
+
         expA = normExpSig.exp;
         sigA = normExpSig.sig;
     }
@@ -1657,6 +1709,18 @@ void softfloat_mul64To128M( uint64_t a, uint64_t b, uint32_t *zPtr )
 
 #endif
 
+struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t sig )
+{
+    int_fast8_t shiftDist;
+    struct exp16_sig32 z;
+
+    shiftDist = softfloat_countLeadingZeros32( sig ) - 8;
+    z.exp = 1 - shiftDist;
+    z.sig = sig<<shiftDist;
+    return z;
+
+}
+
 struct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t sig )
 {
     int_fast8_t shiftDist;
@@ -2300,3 +2364,56 @@ bool f64_lt( float64_t a, float64_t b )
             ? signA && ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))
             : (uiA != uiB) && (signA ^ (uiA < uiB));
 }
+
+/*------------------------------------------------------------------------
+| float32_t conversions
+*------------------------------------------------------------------------*/
+float64_t f32_to_f64( float32_t a )
+{
+    union ui32_f32 uA;
+    uint_fast32_t uiA;
+    bool sign;
+    int_fast16_t exp;
+    uint_fast32_t frac;
+    struct commonNaN commonNaN;
+    uint_fast64_t uiZ;
+    struct exp16_sig32 normExpSig;
+    union ui64_f64 uZ;
+
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+    uA.f = a;
+    uiA = uA.ui;
+    sign = signF32UI( uiA );
+    exp  = expF32UI( uiA );
+    frac = fracF32UI( uiA );
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+    if ( exp == 0xFF ) {
+        if ( frac ) {
+            softfloat_f32UIToCommonNaN( uiA, &commonNaN );
+            uiZ = softfloat_commonNaNToF64UI( &commonNaN );
+        } else {
+            uiZ = packToF64UI( sign, 0x7FF, 0 );
+        }
+        goto uiZ;
+    }
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+    if ( ! exp ) {
+        if ( ! frac ) {
+            uiZ = packToF64UI( sign, 0, 0 );
+            goto uiZ;
+        }
+        normExpSig = softfloat_normSubnormalF32Sig( frac );
+        exp = normExpSig.exp - 1;
+        frac = normExpSig.sig;
+    }
+    /*------------------------------------------------------------------------
+    *------------------------------------------------------------------------*/
+    uiZ = packToF64UI( sign, exp + 0x380, (uint_fast64_t) frac<<29 );
+ uiZ:
+    uZ.ui = uiZ;
+    return uZ.f;
+}
+
index adc7c0356a11db4a6698693fe5e1db1c326bb0ed..a4ffa9d60b8d9c1e374b1b58e781df5f272e1152 100644 (file)
@@ -91,6 +91,7 @@ void softfloat_raiseFlags( uint_fast8_t );
 | Integer/String-to-floating-point conversion routines.
 *----------------------------------------------------------------------------*/
 float64_t i64_to_f64( int64_t );
+float32_t i64_to_f32( int64_t );
 float64_t str_to_f64( const char *);
 
 /*----------------------------------------------------------------------------
@@ -110,4 +111,9 @@ bool f64_eq( float64_t, float64_t );
 bool f64_le( float64_t, float64_t );
 bool f64_lt( float64_t, float64_t );
 
+/*----------------------------------------------------------------------------
+| 32-bit (single-precision) floating-point operations.
+*----------------------------------------------------------------------------*/
+float64_t f32_to_f64( float32_t );
+
 #endif
index 8f1dbbe97b176b5ce4a7916188522f18469ba3e1..27d3f8beaf4dcb4615672809b4ac81d309a9ad5a 100644 (file)
@@ -41,6 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "softfloat/primitives.h"
 #include "softfloat/softfloat_types.h"
 
+union ui32_f32 { uint32_t ui; float32_t f; };
 union ui64_f64 { uint64_t ui; float64_t f; };
 
 enum {
@@ -65,8 +66,22 @@ int_fast64_t
 int_fast64_t softfloat_roundMToI64( bool, uint32_t *, uint_fast8_t, bool );
 #endif
 
-/*----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+#define signF32UI( a ) ((bool) ((uint32_t) (a)>>31))
+#define expF32UI( a ) ((int_fast16_t) ((a)>>23) & 0xFF)
+#define fracF32UI( a ) ((a) & 0x007FFFFF)
+#define packToF32UI( sign, exp, sig ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig))
+
+#define isNaNF32UI( a ) (((~(a) & 0x7F800000) == 0) && ((a) & 0x007FFFFF))
+
+struct exp16_sig32 { int_fast16_t exp; uint_fast32_t sig; };
+struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t );
 
+float32_t softfloat_roundPackToF32( bool, int_fast16_t, uint_fast32_t );
+float32_t softfloat_normRoundPackToF32( bool, int_fast16_t, uint_fast32_t );
+
+/*----------------------------------------------------------------------------*/
 /*----------------------------------------------------------------------------*/
 #define signF64UI( a ) ((bool) ((uint64_t) (a)>>63))
 #define expF64UI( a ) ((int_fast16_t) ((a)>>52) & 0x7FF)
index 606de8777260d3f91bf5b0bb5bcd670f2c0d9da6..a67539c5dd014dba437051458719d2d11ec34020 100644 (file)
@@ -57,6 +57,27 @@ uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist );
 #endif
 #endif
 
+#ifndef softfloat_shiftRightJam32
+/*----------------------------------------------------------------------------
+| Shifts 'a' right by the number of bits given in 'dist', which must not
+| be zero.  If any nonzero bits are shifted off, they are "jammed" into the
+| least-significant bit of the shifted value by setting the least-significant
+| bit to 1.  This shifted-and-jammed value is returned.
+|   The value of 'dist' can be arbitrarily large.  In particular, if 'dist' is
+| greater than 32, the result will be either 0 or 1, depending on whether 'a'
+| is zero or nonzero.
+*----------------------------------------------------------------------------*/
+#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
+INLINE uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist )
+{
+    return
+        (dist < 31) ? a>>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0);
+}
+#else
+uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist );
+#endif
+#endif
+
 #ifndef softfloat_shiftRightJam64
 /*----------------------------------------------------------------------------
 | Shifts 'a' right by the number of bits given in 'dist', which must not
index a3a3eb2181d248d82d1ec9f6be5a6c2a7eae52e8..03e937382a93871a7bdea4dac8e09e9b7250506d 100644 (file)
@@ -82,6 +82,46 @@ struct commonNaN {
 #endif
 };
 
+/*----------------------------------------------------------------------------
+| The bit pattern for a default generated 32-bit floating-point NaN.
+*----------------------------------------------------------------------------*/
+#define defaultNaNF32UI 0x7FC00000
+
+/*----------------------------------------------------------------------------
+| Returns true when 32-bit unsigned integer 'uiA' has the bit pattern of a
+| 32-bit floating-point signaling NaN.
+| Note:  This macro evaluates its argument more than once.
+*----------------------------------------------------------------------------*/
+#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF))
+
+/*----------------------------------------------------------------------------
+| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts
+| this NaN to the common NaN form, and stores the resulting common NaN at the
+| location pointed to by 'zPtr'.  If the NaN is a signaling NaN, the invalid
+| exception is raised.
+*----------------------------------------------------------------------------*/
+void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr );
+
+/*----------------------------------------------------------------------------
+| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point
+| NaN, and returns the bit pattern of this value as an unsigned integer.
+*----------------------------------------------------------------------------*/
+uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr );
+
+/*----------------------------------------------------------------------------
+| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating-
+| point values, at least one of which is a NaN, returns the bit pattern of
+| the combined NaN result.  If either 'uiA' or 'uiB' has the pattern of a
+| signaling NaN, the invalid exception is raised.
+*----------------------------------------------------------------------------*/
+uint_fast32_t
+ softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
+
+/*----------------------------------------------------------------------------
+| The bit pattern for a default generated 64-bit floating-point NaN.
+*----------------------------------------------------------------------------*/
+#define defaultNaNF64UI UINT64_C( 0x7FF8000000000000 )
+
 /*----------------------------------------------------------------------------
 | The bit pattern for a default generated 64-bit floating-point NaN.
 *----------------------------------------------------------------------------*/
index c7be79015290c2ca85e5718815f1fe51390163cc..9e1084bb09ba98e3a0bf63a1747e201956e8c7dd 100644 (file)
@@ -51,8 +51,7 @@ function string_to_fp:long (input:string)
  *
  * @input: a long integer
  *
- * Description: Convert from a long to a softfloat floating point, then 
- *              print the floating point value.
+ * Description: Convert from a long to a 64 bit softfloat floating point.
  */
 function long_to_fp:long (input:long)
 %{
@@ -151,7 +150,7 @@ function fp_mul:long (mul1:long, mul2:long)
 %}
 
 /*
- *function fp_div - fp divide
+ * sfunction fp_div - fp divide
  *
  * @div1: the 64 bit floating point dividend
  * @div2: 64 bit floating point divisor
@@ -249,7 +248,7 @@ function fp_le:long (infp1:long, infp2:long)
 %}
 
 /**
- * sfunction fp_le - fp comparison function less than
+ * sfunction fp_lt - fp comparison function less than
  *
  * @infp1: the 64 bit floating point input
  * @infp2: second 64 bit floating point input
@@ -266,3 +265,21 @@ function fp_lt:long (infp1:long, infp2:long)
 
     STAP_RETVALUE = f64_lt(fp1, fp2);
 %}
+
+/**
+ * sfunction fp32_to_fp64 - Convert fp32 to 64 bit floating point
+ *
+ * @input: a long integer
+ *
+ * Description: Convert from 32 bit floating point to a 64 bit softfloat floating point.
+ */
+function fp32_to_fp64:long (input:long)
+%{
+    float64_t fp64;
+    float32_t fp32;
+    fp32.v = STAP_ARG_input;
+
+    fp64 = f32_to_f64(fp32);
+    STAP_RETVALUE = fp64.v;
+%}
+
index 56fb9596118f9c348b1f74991377559263540ee8..30907f8accac766ca5829eff8bb127d30c209529 100755 (executable)
@@ -7,12 +7,20 @@ function printlnfp(a) { println(fp_to_string(a,5)) }
 probe process("stap").function("sdt_benchmark_thread") {
     fp = user_long($fpointer)
     printlnfp(fp)
+    fp32 = user_int($fpointer2)
+    printlnfp(fp32_to_fp64(fp32))
     exit()
 }
 
 probe begin {
     a = 4614253070214989087 //3.14
     b = 4622500287032611308 //11.21
+    
+    a32 = 1078523331 //3.14
+    b32 = 3219463864 //-1.79
+
+    printlnfp(fp32_to_fp64(a32))
+    printlnfp(fp32_to_fp64(b32))
 
     println(fp_to_string(a, 5)) // 3.14
     printlnfp(string_to_fp("3.14"))
This page took 0.03818 seconds and 5 git commands to generate.