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); }
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); }