floatOop as_floatOop(float value) { union { float f; uint32 i; } x; x.f = value; uint32 i = x.i; int32 exp = i >> expOffset & nthMask(expSize); int32 selfExp = exp - bias + selfBias; int32 fract = i & nthMask(fractSize); int32 r = (i & (nthMask(signSize) << signOffset)) | Float_Tag; if (selfExp <= 0) { // underflow - round towards zero } else if (selfExp >= nthMask(selfExpSize)) { if (exp < nthMask(expSize)) { // warning1("converting float %g to Inf", value); r |= nthMask(selfExpSize) << selfExpOffset; } else if (fract == 0) { r |= int32(infinityOop); } else { // NaN r |= (nthMask(selfExpSize) << selfExpOffset) | (fract << Tag_Size); } } else { r |= (selfExp << selfExpOffset) | (fract << Tag_Size); } return floatOop(r); }
void floatMap::print(oop obj) { if (obj->is_map()) { lprintf("float "); } else { floatOop(obj)->print_oop(); lprintf(": "); } immediateMap::print(obj); }
float* objVectorOopClass::convertFloatArray() { oop* src = objs(); oop* end = src + length(); float* result = NEW_RESOURCE_ARRAY( float, length()); float* dst = result; while (src < end) { oop s = *src++; if (s->is_smi()) *dst++ = float(smiOop(s)->value()); else if (s->is_float()) *dst++ = floatOop(s)->value(); else return NULL; } return result; }
static bool convertFloatObjVector( objVectorOop v, const char* prinName, void* FH, float*& floats, uint32& count) { count = v->length(); floats = NEW_RESOURCE_ARRAY(float, count); int badI = -1; for (int i = 0; i < count; ++i) { oop o = v->obj_at(i); floats[i] = o->is_float() ? floatOop(o)->value() : o->is_smi() ? smiOop(o)->value() : ((badI = i), (i = count), 0.0); } if (badI != -1) { static char buf[1000]; sprintf(buf, "%s failed: bad oop at: %d", prinName, badI); failure(FH, buf); return false; } return true; }
/* float formats: IEEE_float = { int sign:1; int fract: 23; int exp: 8 } Normally: Self_float = { int sign:1; int fract: 23; int exp: 6; int tag: 2} if FAST_FLOATS is defined Self_float = { int sign:1; int fract: 21; int exp: 8; int tag: 2} */ static const fint fractSize = 23; static const fint expSize = 8; static const fint expOffset = fractSize; # ifdef FAST_FLOATS floatOop infinityOop = floatOop(nthMask(expSize) << expOffset | Float_Tag); # else static const fint signSize = 1; static const fint signOffset = fractSize + expSize; static const fint selfExpSize = fint(expSize - Tag_Size); static const fint selfExpOffset = fint(expOffset + Tag_Size); static const fint bias = nthBit(expSize) / 2 - 1; static const fint selfBias = nthBit(selfExpSize) / 2 - 1; floatOop infinityOop = floatOop(nthMask(selfExpSize) << selfExpOffset | Float_Tag); floatOop as_floatOop(float value) {
void floatMap::print_oop(oop obj) { floatOop(obj)->print_oop(); }
void floatMap::print_string(oop obj, char* buf) { floatOop(obj)->print_string(buf); }