From 3309f483b69788552fafed46ec47a43e4d91c2e3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Nov 2010 14:12:40 +0900 Subject: [PATCH] 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). --- libs/gamecode/engine/pr_debug.c | 7 ++++- libs/gamecode/engine/pr_opcode.c | 48 +++++++++++++++++++------------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/libs/gamecode/engine/pr_debug.c b/libs/gamecode/engine/pr_debug.c index 9b7ecd846..46c9d6451 100644 --- a/libs/gamecode/engine/pr_debug.c +++ b/libs/gamecode/engine/pr_debug.c @@ -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'", diff --git a/libs/gamecode/engine/pr_opcode.c b/libs/gamecode/engine/pr_opcode.c index 7fdfde1f0..12ecfff9f 100644 --- a/libs/gamecode/engine/pr_opcode.c +++ b/libs/gamecode/engine/pr_opcode.c @@ -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; } }