From bb065bd2335290ffb1177b45bf3397e2d1102e5b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 16 Aug 2011 12:10:05 +0900 Subject: [PATCH] Be a little leniant with vector param stores. qcc always used vector stores to load values into the function parameters, but if the location of the value is too close to the end of the global data block (the vector spans the end of the block), it would trigger the bounds check code. Thus, allow such instructions without a murmer, so long as it actually is a parameter write. --- libs/gamecode/engine/pr_opcode.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/libs/gamecode/engine/pr_opcode.c b/libs/gamecode/engine/pr_opcode.c index 18aed9b11..9901347e5 100644 --- a/libs/gamecode/engine/pr_opcode.c +++ b/libs/gamecode/engine/pr_opcode.c @@ -1092,6 +1092,22 @@ check_branch (progs_t *pr, dstatement_t *st, opcode_t *op, short offset) (long)(st - pr->pr_statements), op->opname); } +static int +is_vector_parameter_store (progs_t *pr, dstatement_t *st, + unsigned short operand) +{ + int i; + + if (st->op != OP_STORE_V) + return 0; + if (operand != st->a) + return 0; + for (i = 0; i < MAX_PARMS; i++) + if (st->b == pr->pr_params[i] - pr->pr_globals) + return 1; + return 0; +} + #define ISDENORM(x) ((x) && !((x) & 0x7f800000)) static inline void @@ -1113,8 +1129,11 @@ check_global (progs_t *pr, dstatement_t *st, opcode_t *op, etype_t type, default: if (operand + (unsigned) pr_type_size[type] > pr->progs->numglobals) { - msg = "out of bounds global index"; - goto error; + if (operand >= pr->progs->numglobals + || !is_vector_parameter_store (pr, st, operand)) { + msg = "out of bounds global index"; + goto error; + } } if (type != ev_float || !check_denorm) break;