// // float // Floating-point support // F.J. Alberti // case kPushfloat: // Push a float constant FSET(m->top[--m->pp], *(float32*)&fetch(pc)) pc += ALIGNMENT(4); checkOverflow(m, 0) break; case kPushfloat0: // Push 0.0 FSET(m->top[--m->pp], 0.0f); checkOverflow(m, 0) break; case kPushfloat1: // Push 1.0 FSET(m->top[--m->pp], 1.0f); checkOverflow(m, 0) break; case kInt2float: { // Integer -> float conversion int val = m->top[m->pp]; if (val == NIL) break; FSET(m->top[m->pp], (float)(val>>1)) break; } case kFloat2int: { // Float -> integer conversion int val = m->top[m->pp]; if (val == NIL) break; m->top[m->pp] = (int)FGET(val)<<1; break; } case kFloatadd: { // Addition #if defined(SCOL_DEBUG) checkUnderflow(m); #endif int val1 = m->top[m->pp++]; int val0 = m->top[m->pp]; if (val0 == NIL || val1 == NIL) { m->top[m->pp] = NIL; break; } FSET(m->top[m->pp], FGET(val0)+FGET(val1)) break; } case kFloatsub: { // Substraction #if defined(SCOL_DEBUG) checkUnderflow(m); #endif int val1 = m->top[m->pp++]; int val0 = m->top[m->pp]; if (val0 == NIL || val1 == NIL) { m->top[m->pp] = NIL; break; } FSET(m->top[m->pp], FGET(val0)-FGET(val1)) break; } case kFloatmul: { // Multiplication #if defined(SCOL_DEBUG) checkUnderflow(m); #endif int val1 = m->top[m->pp++]; int val0 = m->top[m->pp]; if (val0 == NIL || val1 == NIL) { m->top[m->pp] = NIL; break; } FSET(m->top[m->pp], FGET(val0)*FGET(val1)) break; } case kFloatdiv: { // Division #if defined(SCOL_DEBUG) checkUnderflow(m); #endif int val1 = m->top[m->pp++]; int val0 = m->top[m->pp]; if (val0 == NIL || val1 == NIL) { m->top[m->pp] = NIL; break; } float f1 = FGET(val1); if (f1 == 0.0) throw Exception(MERRNUL); FSET(m->top[m->pp], FGET(val0)/f1) break; } case kFloatneg: { // Negation int val = m->top[m->pp]; if (val == NIL) break; FSET(m->top[m->pp], -FGET(val)) break; } case kFloateq: { // Equality relation #if defined(SCOL_DEBUG) checkUnderflow(m); #endif int val1 = m->top[m->pp++]; int val0 = m->top[m->pp]; if (val0 == NIL || val1 == NIL) { m->top[m->pp] = NIL; break; } m->top[m->pp] = FGET(val0) == FGET(val1) ? 2 : 0; break; } case kFloatne: { // Non-equality relation #if defined(SCOL_DEBUG) checkUnderflow(m); #endif int val1 = m->top[m->pp++]; int val0 = m->top[m->pp]; if (val0 == NIL || val1 == NIL) { m->top[m->pp] = NIL; break; } m->top[m->pp] = FGET(val0) != FGET(val1) ? 2 : 0; break; } case kFloatlt: { // Less-than relation #if defined(SCOL_DEBUG) checkUnderflow(m); #endif int val1 = m->top[m->pp++]; int val0 = m->top[m->pp]; if (val0 == NIL || val1 == NIL) { m->top[m->pp] = NIL; break; } m->top[m->pp] = FGET(val0) < FGET(val1) ? 2 : 0; break; } case kFloatgt: { // Greater-than relation #if defined(SCOL_DEBUG) checkUnderflow(m); #endif int val1 = m->top[m->pp++]; int val0 = m->top[m->pp]; if (val0 == NIL || val1 == NIL) { m->top[m->pp] = NIL; break; } m->top[m->pp] = FGET(val0) > FGET(val1) ? 2 : 0; break; } case kFloatle: { // Less-than-or-equal relation #if defined(SCOL_DEBUG) checkUnderflow(m); #endif int val1 = m->top[m->pp++]; int val0 = m->top[m->pp]; if (val0 == NIL || val1 == NIL) { m->top[m->pp] = NIL; break; } m->top[m->pp] = FGET(val0) <= FGET(val1) ? 2 : 0; break; } case kFloatge: { // Greater-than-or-equal relation #if defined(SCOL_DEBUG) checkUnderflow(m); #endif int val1 = m->top[m->pp++]; int val0 = m->top[m->pp]; if (val0 == NIL || val1 == NIL) { m->top[m->pp] = NIL; break; } m->top[m->pp] = FGET(val0) >= FGET(val1) ? 2 : 0; break; }