Esempio n. 1
0
void
prim_subtract(PRIM_PROTOTYPE)
{
	CHECKOP(2);
	oper1 = POP();
	oper2 = POP();
	if (!arith_type(oper2, oper1))
		abort_interp("Invalid argument type.");
	if ((oper1->type == PROG_FLOAT) || (oper2->type == PROG_FLOAT)) {
		tf1 = (oper2->type == PROG_FLOAT) ? oper2->data.fnumber : oper2->data.number;
		tf2 = (oper1->type == PROG_FLOAT) ? oper1->data.fnumber : oper1->data.number;
		if (!nogood(tf1) && !nogood(tf2)) {
			fresult = tf1 - tf2;
		} else {
			fresult = 0.0;
			fr->error.error_flags.f_bounds = 1;
		}
	} else {
		result = oper2->data.number - oper1->data.number;
		tl = (double) oper2->data.number - (double) oper1->data.number;
		if (!arith_good(tl))
			fr->error.error_flags.i_bounds = 1;
	}
	tmp = (oper2->type == PROG_FLOAT || oper1->type == PROG_FLOAT) ? PROG_FLOAT : oper2->type;
	CLEAR(oper1);
	CLEAR(oper2);
	if (tmp == PROG_FLOAT)
		push(arg, top, tmp, MIPSCAST & fresult);
	else
		push(arg, top, tmp, MIPSCAST & result);
}
Esempio n. 2
0
void
prim_divide(PRIM_PROTOTYPE)
{
    CHECKOP(2);
    oper1 = POP();
    oper2 = POP();
    if (!arith_type(oper2, oper1))
        abort_interp("Invalid argument type");
    if ((oper1->type == PROG_FLOAT) || (oper2->type == PROG_FLOAT)) {
        if ((oper1->type == PROG_INTEGER && !oper1->data.number) ||
            (oper1->type == PROG_FLOAT && fabs(oper1->data.fnumber)
             < DBL_EPSILON)) {
            fresult = tp_alt_infinity_handler ?
                ((oper2->type ==
                  PROG_INTEGER) ? oper2->data.number : oper2->data.fnumber) *
                INF : 0.0;
            fr->error.error_flags.div_zero = 1;
        } else {
            tf1 =
                (oper2->type ==
                 PROG_FLOAT) ? oper2->data.fnumber : oper2->data.number;
            tf2 =
                (oper1->type ==
                 PROG_FLOAT) ? oper1->data.fnumber : oper1->data.number;
            if (!no_good(tf1) && !no_good(tf2)) {
                fresult = tf1 / tf2;
            } else {
                if (ISNAN(tf1) || ISNAN(tf2)) {
                    fresult = tp_alt_infinity_handler ? NAN : 0.0;
                    if (!tp_alt_infinity_handler)
                        fr->error.error_flags.nan = 1;
                } else {
                    fresult = tp_alt_infinity_handler ? (tf1 / tf2) : 0.0;
                    if (!tp_alt_infinity_handler)
                        fr->error.error_flags.f_bounds = 1;
                }
            }
        }
    } else {
        if (oper1->data.number) {
            result = oper2->data.number / oper1->data.number;
        } else {
            result = 0;
            fr->error.error_flags.div_zero = 1;
        }
    }
    tmp = (oper2->type == PROG_FLOAT
           || oper1->type == PROG_FLOAT) ? PROG_FLOAT : oper2->type;
    CLEAR(oper1);
    CLEAR(oper2);
    if (tmp == PROG_FLOAT)
        push(arg, top, tmp, MIPSCAST & fresult);
    else
        push(arg, top, tmp, MIPSCAST & result);
}
Esempio n. 3
0
void
prim_bitshift(PRIM_PROTOTYPE)
{
	CHECKOP(2);
	oper1 = POP();
	oper2 = POP();
	if (!arith_type(oper2, oper1) || oper1->type != PROG_INTEGER)
		abort_interp("Invalid argument type.");
	if (oper1->data.number > 0)
		result = oper2->data.number << oper1->data.number;
	else if (oper1->data.number < 0)
		result = oper2->data.number >> (-(oper1->data.number));
	else
Esempio n. 4
0
void
prim_bitand(PRIM_PROTOTYPE)
{
	CHECKOP(2);
	oper1 = POP();
	oper2 = POP();
	if (!arith_type(oper2, oper1))
		abort_interp("Invalid argument type.");
	result = oper2->data.number & oper1->data.number;
	tmp = oper2->type;
	CLEAR(oper1);
	CLEAR(oper2);
	push(arg, top, tmp, MIPSCAST & result);
}
Esempio n. 5
0
void
prim_mod(PRIM_PROTOTYPE)
{
	CHECKOP(2);
	oper1 = POP();
	oper2 = POP();
	if ((!arith_type(oper2, oper1)) || (oper1->type == PROG_FLOAT) ||
		(oper2->type == PROG_FLOAT)) abort_interp("Invalid argument type.");
	if (oper1->data.number)
		result = oper2->data.number % oper1->data.number;
	else
		result = 0;
	tmp = oper2->type;
	CLEAR(oper1);
	CLEAR(oper2);
	push(arg, top, tmp, MIPSCAST & result);
}
Esempio n. 6
0
void
prim_add(PRIM_PROTOTYPE)
{
    CHECKOP(2);
    oper1 = POP();
    oper2 = POP();
    if (!arith_type(oper2, oper1))
        abort_interp("Invalid argument type");
    if ((oper1->type == PROG_FLOAT) || (oper2->type == PROG_FLOAT)) {
        tf1 =
            (oper1->type ==
             PROG_FLOAT) ? oper1->data.fnumber : oper1->data.number;
        tf2 =
            (oper2->type ==
             PROG_FLOAT) ? oper2->data.fnumber : oper2->data.number;
        if (!no_good(tf1) && !no_good(tf2)) {
            fresult = tf1 + tf2;
        } else {
            if (ISNAN(tf1) || ISNAN(tf2)) {
                fresult = tp_alt_infinity_handler ? NAN : 0.0;
                if (!tp_alt_infinity_handler)
                    fr->error.error_flags.nan = 1;
            } else {
                fresult = tp_alt_infinity_handler ? (tf1 + tf2) : 0.0;
                if (!tp_alt_infinity_handler)
                    fr->error.error_flags.f_bounds = 1;
            }
        }
    } else {
        result = oper1->data.number + oper2->data.number;
        tl = (double) oper1->data.number + (double) oper2->data.number;
        if (!arith_good(tl))
            fr->error.error_flags.i_bounds = 1;
    }
    tmp = (oper2->type == PROG_FLOAT
           || oper1->type == PROG_FLOAT) ? PROG_FLOAT : oper2->type;
    CLEAR(oper1);
    CLEAR(oper2);
    if (tmp == PROG_FLOAT)
        push(arg, top, tmp, MIPSCAST & fresult);
    else
        push(arg, top, tmp, MIPSCAST & result);
}
Esempio n. 7
0
void
prim_divide(PRIM_PROTOTYPE)
{
	CHECKOP(2);
	oper1 = POP();
	oper2 = POP();
	if (!arith_type(oper2, oper1))
		abort_interp("Invalid argument type.");
	if ((oper1->type == PROG_FLOAT) || (oper2->type == PROG_FLOAT)) {
		if ((oper1->type == PROG_INTEGER && !oper1->data.number) ||
			(oper1->type == PROG_FLOAT && fabs(oper1->data.fnumber) < DBL_EPSILON)) {
			/* FIXME: This should be NaN.  */
			fresult = INF;
			fr->error.error_flags.div_zero = 1;
		} else {
			tf1 = (oper2->type == PROG_FLOAT) ? oper2->data.fnumber : oper2->data.number;
			tf2 = (oper1->type == PROG_FLOAT) ? oper1->data.fnumber : oper1->data.number;
			if (!nogood(tf1) && !nogood(tf2)) {
				fresult = tf1 / tf2;
			} else {
				fresult = 0.0;
				fr->error.error_flags.f_bounds = 1;
			}
		}
	} else {
		if (oper1->data.number) {
			result = oper2->data.number / oper1->data.number;
		} else {
			result = 0;
			fr->error.error_flags.div_zero = 1;
		}
	}
	tmp = (oper2->type == PROG_FLOAT || oper1->type == PROG_FLOAT) ? PROG_FLOAT : oper2->type;
	CLEAR(oper1);
	CLEAR(oper2);
	if (tmp == PROG_FLOAT)
		push(arg, top, tmp, MIPSCAST & fresult);
	else
		push(arg, top, tmp, MIPSCAST & result);
}