mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
Don't require pr_boundscheck for quoth.
I don't know about other FTEqcc compiled progs, but quoth doesn't try to do anything clever (all its denormals are either vars of the wrong type, or -0.0).
This commit is contained in:
parent
9d6fd32206
commit
3309f483b6
2 changed files with 35 additions and 20 deletions
|
@ -539,6 +539,8 @@ PR_DumpState (progs_t *pr)
|
|||
PR_StackTrace (pr);
|
||||
}
|
||||
|
||||
#define ISDENORM(x) ((x) && !((x) & 0x7f800000))
|
||||
|
||||
static const char *
|
||||
value_string (progs_t *pr, etype_t type, pr_type_t *val)
|
||||
{
|
||||
|
@ -611,7 +613,10 @@ value_string (progs_t *pr, etype_t type, pr_type_t *val)
|
|||
case ev_void:
|
||||
return "void";
|
||||
case ev_float:
|
||||
dsprintf (line, "%g", val->float_var);
|
||||
if (ISDENORM (val->integer_var) && val->uinteger_var != 0x80000000)
|
||||
dsprintf (line, "<%08x>", val->integer_var);
|
||||
else
|
||||
dsprintf (line, "%g", val->float_var);
|
||||
break;
|
||||
case ev_vector:
|
||||
dsprintf (line, "'%g %g %g'",
|
||||
|
|
|
@ -1204,9 +1204,10 @@ check_branch (progs_t *pr, dstatement_t *st, opcode_t *op, short offset)
|
|||
|
||||
static inline void
|
||||
check_global (progs_t *pr, dstatement_t *st, opcode_t *op, etype_t type,
|
||||
unsigned short operand)
|
||||
unsigned short operand, int check_denorm)
|
||||
{
|
||||
const char *msg;
|
||||
ddef_t *def;
|
||||
|
||||
switch (type) {
|
||||
case ev_short:
|
||||
|
@ -1223,11 +1224,19 @@ check_global (progs_t *pr, dstatement_t *st, opcode_t *op, etype_t type,
|
|||
msg = "out of bounds global index";
|
||||
goto error;
|
||||
}
|
||||
if (type == ev_float)
|
||||
if (ISDENORM (G_INT (pr, operand))
|
||||
&& !pr->denorm_found) {
|
||||
if (type != ev_float || !check_denorm)
|
||||
break;
|
||||
if (!ISDENORM (G_INT (pr, operand))
|
||||
|| G_UINT(pr, operand) == 0x80000000)
|
||||
break;
|
||||
if ((def = PR_GlobalAtOfs (pr, operand))
|
||||
&& (def->type & ~DEF_SAVEGLOBAL) != ev_float) {
|
||||
// FTEqcc uses store.f parameters of most types :/
|
||||
break;
|
||||
}
|
||||
if (!pr->denorm_found) {
|
||||
pr->denorm_found = 1;
|
||||
if (pr_boundscheck-> int_val) {
|
||||
if (pr_boundscheck->int_val) {
|
||||
Sys_Printf ("DENORMAL floats detected, these progs might "
|
||||
"not work. Good luck.\n");
|
||||
return;
|
||||
|
@ -1305,7 +1314,7 @@ PR_Check_Opcodes (progs_t *pr)
|
|||
switch (st->op) {
|
||||
case OP_IF:
|
||||
case OP_IFNOT:
|
||||
check_global (pr, st, op, op->type_a, st->a);
|
||||
check_global (pr, st, op, op->type_a, st->a, 1);
|
||||
check_branch (pr, st, op, st->b);
|
||||
break;
|
||||
case OP_GOTO:
|
||||
|
@ -1313,12 +1322,12 @@ PR_Check_Opcodes (progs_t *pr)
|
|||
break;
|
||||
case OP_DONE:
|
||||
case OP_RETURN:
|
||||
check_global (pr, st, op, ev_integer, st->a);
|
||||
check_global (pr, st, op, ev_void, st->b);
|
||||
check_global (pr, st, op, ev_void, st->c);
|
||||
check_global (pr, st, op, ev_integer, st->a, 1);
|
||||
check_global (pr, st, op, ev_void, st->b, 0);
|
||||
check_global (pr, st, op, ev_void, st->c, 0);
|
||||
break;
|
||||
case OP_RCALL1:
|
||||
check_global (pr, st, op, ev_void, st->c);
|
||||
check_global (pr, st, op, ev_void, st->c, 1);
|
||||
case OP_RCALL2:
|
||||
case OP_RCALL3:
|
||||
case OP_RCALL4:
|
||||
|
@ -1327,9 +1336,9 @@ PR_Check_Opcodes (progs_t *pr)
|
|||
case OP_RCALL7:
|
||||
case OP_RCALL8:
|
||||
if (st->op > OP_RCALL1)
|
||||
check_global (pr, st, op, ev_integer, st->c);
|
||||
check_global (pr, st, op, ev_integer, st->b);
|
||||
check_global (pr, st, op, ev_func, st->a);
|
||||
check_global (pr, st, op, ev_integer, st->c, 1);
|
||||
check_global (pr, st, op, ev_integer, st->b, 1);
|
||||
check_global (pr, st, op, ev_func, st->a, 1);
|
||||
break;
|
||||
case OP_STATE:
|
||||
case OP_STATE_F:
|
||||
|
@ -1337,18 +1346,19 @@ PR_Check_Opcodes (progs_t *pr)
|
|||
PR_Error (pr, "PR_Check_Opcodes: %s used with missing "
|
||||
"fields or globals", op->opname);
|
||||
}
|
||||
check_global (pr, st, op, op->type_a, st->a);
|
||||
check_global (pr, st, op, op->type_b, st->b);
|
||||
check_global (pr, st, op, op->type_c, st->c);
|
||||
check_global (pr, st, op, op->type_a, st->a, 1);
|
||||
check_global (pr, st, op, op->type_b, st->b, 1);
|
||||
check_global (pr, st, op, op->type_c, st->c, 1);
|
||||
break;
|
||||
case OP_MOVE:
|
||||
check_global_size (pr, st, op, st->b, st->a);
|
||||
check_global_size (pr, st, op, st->b, st->c);
|
||||
break;
|
||||
default:
|
||||
check_global (pr, st, op, op->type_a, st->a);
|
||||
check_global (pr, st, op, op->type_b, st->b);
|
||||
check_global (pr, st, op, op->type_c, st->c);
|
||||
check_global (pr, st, op, op->type_a, st->a, 1);
|
||||
check_global (pr, st, op, op->type_b, st->b,
|
||||
op->opcode != OP_STORE_F);
|
||||
check_global (pr, st, op, op->type_c, st->c, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue