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);
{
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();
}
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
#endif
-
#ifndef softfloat_shiftRightJam64
uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist )
}
+/*----------------------------------------------------------------------------
+| 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.
| 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
*------------------------------------------------------------------------*/
if ( ! expA ) {
if ( ! sigA ) goto zeroProd;
- normExpSig = softfloat_normSubnormalF64Sig( sigA );
+
expA = normExpSig.exp;
sigA = normExpSig.sig;
}
#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;
? 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;
+}
+
| 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 *);
/*----------------------------------------------------------------------------
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
#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 {
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)
#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
#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.
*----------------------------------------------------------------------------*/
*
* @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)
%{
%}
/*
- *function fp_div - fp divide
+ * sfunction fp_div - fp divide
*
* @div1: the 64 bit floating point dividend
* @div2: 64 bit floating point divisor
%}
/**
- * 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
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;
+%}
+
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"))