From 22ea0b87d7b3881130fd81fc23123f56a3cd4706 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sat, 15 Aug 2020 04:31:27 +0000 Subject: [PATCH] Try to fix up some qcc inline logic to no longer result in so many offset_0 values. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5744 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- CMakeLists.txt | 2 +- engine/client/m_download.c | 2 + engine/qclib/execloop.h | 65 +++++++++-- engine/qclib/pr_comp.h | 4 + engine/qclib/progsint.h | 12 +- engine/qclib/qcc_pr_comp.c | 224 +++++++++++++++++++++++++------------ engine/server/svq2_game.c | 3 + 7 files changed, 225 insertions(+), 87 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e951b0e0..cedea9ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1168,7 +1168,7 @@ INSTALL(TARGETS ${INSTALLTARGS} LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" ) -IF (1) +IF (0) ADD_CUSTOM_TARGET(menusys ALL VERBATIM COMMAND fteqcc -srcfile "${CMAKE_CURRENT_SOURCE_DIR}/quakec/menusys/menu.src" -o "${CMAKE_CURRENT_BINARY_DIR}/menu.dat" diff --git a/engine/client/m_download.c b/engine/client/m_download.c index f9e0c620..bc10f92a 100644 --- a/engine/client/m_download.c +++ b/engine/client/m_download.c @@ -3777,6 +3777,7 @@ void PM_Command_f(void) Con_Printf(" package is an engine update\n"); if (p->flags & DPF_TESTING) Con_Printf(S_COLOR_YELLOW" package is untested\n"); +#ifdef WEBCLIENT if (!PM_SignatureOkay(p)) { if (!p->signature) @@ -3788,6 +3789,7 @@ void PM_Command_f(void) else Con_Printf(CON_ERROR" Unable to verify signature"CON_DEFAULT"\n"); //clientside problem. } +#endif found++; } if (!found) diff --git a/engine/qclib/execloop.h b/engine/qclib/execloop.h index a4e38f73..822ffad6 100644 --- a/engine/qclib/execloop.h +++ b/engine/qclib/execloop.h @@ -359,25 +359,33 @@ reeval: //store a value to a pointer case OP_STOREP_IF: - i = OPB->_int; + i = OPB->_int + OPC->_int*sizeof(ptr->_float); errorif (QCPOINTERWRITEFAIL(i, sizeof(float))) { - if (i == -1) - break; - QCFAULT(&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); + if (!(ptr=PR_GetWriteTempStringPtr(progfuncs, OPB->_int, OPC->_int*sizeof(ptr->_float), sizeof(ptr->_float)))) + { + if (i == -1) + break; + QCFAULT(&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); + } } - ptr = QCPOINTERM(i); + else + ptr = QCPOINTERM(i); ptr->_float = (float)OPA->_int; break; case OP_STOREP_FI: - i = OPB->_int; + i = OPB->_int + OPC->_int*sizeof(ptr->_int); errorif (QCPOINTERWRITEFAIL(i, sizeof(int))) { - if (i == -1) - break; - QCFAULT(&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); + if (!(ptr=PR_GetWriteTempStringPtr(progfuncs, OPB->_int, OPC->_int*sizeof(ptr->_int), sizeof(ptr->_int)))) + { + if (i == -1) + break; + QCFAULT(&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); + } } - ptr = QCPOINTERM(i); + else + ptr = QCPOINTERM(i); ptr->_int = (int)OPA->_float; break; case OP_STOREP_I: @@ -421,7 +429,7 @@ reeval: ptr->_vector[2] = OPA->_vector[2]; break; - case OP_STOREP_C: //store character in a string + case OP_STOREP_C: //store (float) character in a string i = OPB->_int + (OPC->_int)*sizeof(char); errorif (QCPOINTERWRITEFAIL(i, sizeof(char))) { @@ -436,6 +444,21 @@ reeval: ptr = QCPOINTERM(i); *(unsigned char *)ptr = (char)OPA->_float; break; + case OP_STOREP_B: //store (byte) character in a string + i = OPB->_int + (OPC->_int)*sizeof(pbyte); + errorif (QCPOINTERWRITEFAIL(i, sizeof(pbyte))) + { + if (!(ptr=PR_GetWriteTempStringPtr(progfuncs, OPB->_int, OPC->_int*sizeof(pbyte), sizeof(pbyte)))) + { + if (i == -1) + break; + QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, prinst.addressableused); + } + } + else + ptr = QCPOINTERM(i); + *(pbyte *)ptr = (pbyte)OPA->_int; + break; case OP_STOREF_F: case OP_STOREF_I: @@ -956,7 +979,7 @@ reeval: { if (i == -1) { - OPC->_int = 0; + OPC->_float = 0; break; } QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, ptr); @@ -966,6 +989,24 @@ reeval: ptr = QCPOINTERM(i); OPC->_float = *(unsigned char *)ptr; break; + case OP_LOADP_B: //load character from a string/pointer + i = (unsigned int)OPA->_int + (int)OPB->_int; + errorif (QCPOINTERREADFAIL(i, sizeof(pbyte))) + { + if (!(ptr=PR_GetReadTempStringPtr(progfuncs, OPA->_int, OPB->_int, sizeof(pbyte)))) + { + if (i == -1) + { + OPC->_int = 0; + break; + } + QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, ptr); + } + } + else + ptr = QCPOINTERM(i); + OPC->_int = *(pbyte *)ptr; + break; case OP_LOADP_I: case OP_LOADP_F: case OP_LOADP_FLD: diff --git a/engine/qclib/pr_comp.h b/engine/qclib/pr_comp.h index 5b07ee8b..c1b035d4 100644 --- a/engine/qclib/pr_comp.h +++ b/engine/qclib/pr_comp.h @@ -338,6 +338,10 @@ enum qcop_e { OP_STOREF_S, //1 string reference OP_STOREF_I, //1 non-string reference/int +//r5744+ + OP_STOREP_B,//((char*)b)[(int)c] = (int)a + OP_LOADP_B, //(int)c = *(char*) + OP_NUMREALOPS, /* diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index 4b126a3b..3c26c300 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -215,11 +215,13 @@ typedef struct //ASSIGNS_IC } QCC_opcode_t; extern QCC_opcode_t pr_opcodes[]; // sized by initialization -#define OPF_VALID 0x01 //we're allowed to use this opcode in the current target. -#define OPF_STD 0x10 //reads a+b, writes c. -#define OPF_STORE 0x20 //b+=a or just b=a -#define OPF_STOREPTR 0x40 //the form of c=(*b+=a) -#define OPF_LOADPTR 0x80 +#define OPF_VALID 0x001 //we're allowed to use this opcode in the current target. +#define OPF_STD 0x002 //reads a+b, writes c. +#define OPF_STORE 0x010 //b+=a or just b=a +#define OPF_STOREPTR 0x020 //the form of c=(*b+=a) +#define OPF_STOREPTROFS 0x040 //a[c] <- b (c must be 0 when QCC_OPCode_StorePOffset returns false) +#define OPF_STOREFLD 0x080 //a.b <- c +#define OPF_LOADPTR 0x100 //FIXME: add jumps diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index 95233d50..60ad23bd 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -404,12 +404,12 @@ QCC_opcode_t pr_opcodes[] = {6, "=", "STORE_FLD", PC_STORE, ASSOC_RIGHT, &type_field, &type_field, &type_field, OPF_STORE}, {6, "=", "STORE_FNC", PC_STORE, ASSOC_RIGHT, &type_function, &type_function, &type_function, OPF_STORE}, - {6, "=", "STOREP_F", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_float, &type_float, OPF_STOREPTR}, - {6, "=", "STOREP_V", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_vector, &type_vector, OPF_STOREPTR}, - {6, "=", "STOREP_S", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_string, &type_string, OPF_STOREPTR}, - {6, "=", "STOREP_ENT", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_entity, &type_entity, OPF_STOREPTR}, - {6, "=", "STOREP_FLD", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_field, &type_field, OPF_STOREPTR}, - {6, "=", "STOREP_FNC", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_function, &type_function, OPF_STOREPTR}, + {6, "=", "STOREP_F", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_float, &type_float, OPF_STOREPTROFS}, + {6, "=", "STOREP_V", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_vector, &type_vector, OPF_STOREPTROFS}, + {6, "=", "STOREP_S", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_string, &type_string, OPF_STOREPTROFS}, + {6, "=", "STOREP_ENT", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_entity, &type_entity, OPF_STOREPTROFS}, + {6, "=", "STOREP_FLD", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_field, &type_field, OPF_STOREPTROFS}, + {6, "=", "STOREP_FNC", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_function, &type_function, OPF_STOREPTROFS}, {6, "", "RETURN", PC_NONE, ASSOC_LEFT, &type_vector, &type_void, &type_void}, @@ -529,9 +529,9 @@ QCC_opcode_t pr_opcodes[] = {7, "", "CP_FTOI", PC_STORE, ASSOC_LEFT, &type_pointer, &type_float, &type_integer}, {7, ".", "LOADF_I", PC_MEMBER, ASSOC_LEFT, &type_entity, &type_field, &type_integer}, - {7, "=", "STOREP_I", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_integer, &type_integer, OPF_STOREPTR}, - {7, "=", "STOREP_IF", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_float, &type_integer, OPF_STOREPTR}, - {7, "=", "STOREP_FI", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_integer, &type_float, OPF_STOREPTR}, + {7, "=", "STOREP_I", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_integer, &type_integer, OPF_STOREPTROFS}, + {7, "=", "STOREP_IF", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_float, &type_integer, OPF_STOREPTROFS}, + {7, "=", "STOREP_FI", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_integer, &type_float, OPF_STOREPTROFS}, {7, "&", "BITAND_I", PC_BITAND, ASSOC_LEFT, &type_integer, &type_integer, &type_integer,OPF_STD}, {7, "|", "BITOR_I", PC_BITOR, ASSOC_LEFT, &type_integer, &type_integer, &type_integer,OPF_STD}, @@ -598,7 +598,7 @@ QCC_opcode_t pr_opcodes[] = //string manipulation. {7, "+", "ADD_SF", PC_ADDSUB, ASSOC_LEFT, &type_string, &type_float, &type_string, OPF_STD}, {7, "-", "SUB_S", PC_ADDSUB, ASSOC_LEFT, &type_string, &type_string, &type_float, OPF_STD}, - {7, "", "STOREP_C", PC_STORE, ASSOC_RIGHT, &type_string, &type_float, &type_float}, + {7, "", "STOREP_C", PC_STORE, ASSOC_RIGHT, &type_string, &type_float, &type_float, OPF_STOREPTROFS}, {7, "", "LOADP_C", PC_STORE, ASSOC_LEFT, &type_string, &type_float, &type_float, OPF_LOADPTR}, //------------------------------------- @@ -660,10 +660,13 @@ QCC_opcode_t pr_opcodes[] = {7, "", "IF_F", PC_NONE, ASSOC_RIGHT, &type_float, NULL, &type_void}, {7, "","IFNOT_F", PC_NONE, ASSOC_RIGHT, &type_float, NULL, &type_void}, -{7, "<=>", "STOREF_V", PC_NONE, ASSOC_RIGHT, &type_entity, &type_field, &type_vector}, //ent.fld=c -{7, "<=>", "STOREF_F", PC_NONE, ASSOC_RIGHT, &type_entity, &type_field, &type_float}, -{7, "<=>", "STOREF_S", PC_NONE, ASSOC_RIGHT, &type_entity, &type_field, &type_string}, -{7, "<=>", "STOREF_I", PC_NONE, ASSOC_RIGHT, &type_entity, &type_field, &type_integer}, +{7, "<=>", "STOREF_V", PC_NONE, ASSOC_RIGHT, &type_entity, &type_field, &type_vector, OPF_STOREFLD}, //ent.fld=c +{7, "<=>", "STOREF_F", PC_NONE, ASSOC_RIGHT, &type_entity, &type_field, &type_float, OPF_STOREFLD}, +{7, "<=>", "STOREF_S", PC_NONE, ASSOC_RIGHT, &type_entity, &type_field, &type_string, OPF_STOREFLD}, +{7, "<=>", "STOREF_I", PC_NONE, ASSOC_RIGHT, &type_entity, &type_field, &type_integer, OPF_STOREFLD}, + + {7, "", "STOREP_B", PC_STORE, ASSOC_RIGHT, &type_string, &type_integer, &type_integer, OPF_STOREPTROFS}, + {7, "", "LOADP_B", PC_STORE, ASSOC_LEFT, &type_string, &type_integer, &type_integer, OPF_LOADPTR}, /* emulated ops begin here */ {7, "<>", "OP_EMULATED", PC_NONE, ASSOC_LEFT, &type_float, &type_float, &type_float}, @@ -708,7 +711,7 @@ QCC_opcode_t pr_opcodes[] = {7, "=", "LOADA_STRUCT", PC_STORE, ASSOC_LEFT, &type_float, &type_integer, &type_float}, {7, "=", "LOADP_P", PC_STORE, ASSOC_LEFT, &type_pointer, &type_integer, &type_pointer, OPF_LOADPTR}, - {7, "=", "STOREP_P", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_pointer, &type_pointer, OPF_STOREPTR}, + {7, "=", "STOREP_P", PC_STORE, ASSOC_RIGHT, &type_pointer, &type_pointer, &type_pointer, OPF_STOREPTROFS}, {7, "~", "BITNOT_F", PC_UNARY, ASSOC_LEFT, &type_float, &type_void, &type_float}, {7, "~", "BITNOT_I", PC_UNARY, ASSOC_LEFT, &type_integer, &type_void, &type_integer}, @@ -787,7 +790,7 @@ static pbool OpAssignsToC(unsigned int op) return false; /*if(op >= OP_STORE_I && op <= OP_STORE_FI) return false; <- add STOREP_*?*/ - if(op == OP_STOREP_C || op == OP_LOADP_C) + if(op == OP_STOREP_C || op == OP_STOREP_B) return false; if (op >= OP_STORE_F && op <= OP_STOREP_FNC) return false; //actually they do. @@ -807,7 +810,7 @@ static pbool OpAssignsToB(unsigned int op) return true; if(op >= OP_STORE_I && op <= OP_STORE_FI) return true; - if(op == OP_STOREP_C || op == OP_LOADP_C) + if(op == OP_STOREP_C || op == OP_STOREP_B) return true; if(op >= OP_MULSTORE_F && op <= OP_SUBSTOREP_V) return true; @@ -1195,6 +1198,8 @@ static pbool QCC_OPCodeValidForTarget(qcc_targetformat_t targfmt, QCC_opcode_t * case QCF_FTEH2: case QCF_FTE: case QCF_FTEDEBUG: + if (num >= OP_STOREP_B) + return (qcc_targetversion>=5744); if (num >= OP_STOREF_V) //to be enabled at a later date - opcodes added in r5698. return (qcc_targetversion>=5698); return true; @@ -1447,6 +1452,8 @@ static pbool QCC_OPCode_StorePOffset(void) case QCF_FTEH2: case QCF_FTEDEBUG: return (qcc_targetversion>=5712); + case QCF_QSS: + return true; default: return false; } @@ -1456,6 +1463,29 @@ void QCC_OPCodeSetTarget(qcc_targetformat_t targfmt, unsigned int targver) size_t i; qcc_targetformat = targfmt; qcc_targetversion = targver; + + switch(qcc_targetformat) + { + case QCF_FTE: + case QCF_FTEH2: + case QCF_FTEDEBUG: + if (qcc_targetversion > 5744) + { + if (qcc_targetversion != ~0u) + QCC_PR_ParseWarning(WARN_BADTARGET, "target revision %u is unknown, assuming revision %u", qcc_targetversion, 5744); + qcc_targetversion = 5744; + } + break; + default: + if (qcc_targetversion > 0) + { + if (qcc_targetversion != ~0u) + QCC_PR_ParseWarning(WARN_BADTARGET, "target revision %u is unknown, assuming revision %u", qcc_targetversion, 0); + qcc_targetversion = 0; + } + break; + } + for (i = 0; i < OP_NUMREALOPS; i++) { QCC_opcode_t *op = &pr_opcodes[i]; @@ -1469,35 +1499,36 @@ void QCC_OPCodeSetTarget(qcc_targetformat_t targfmt, unsigned int targver) static struct { qcc_targetformat_t target; const char *name; + unsigned int defaultrev; } targets[] = { - {QCF_STANDARD, "standard"}, - {QCF_STANDARD, "vanilla"}, - {QCF_STANDARD, "q1"}, - {QCF_STANDARD, "id"}, - {QCF_STANDARD, "quakec"}, + {QCF_STANDARD, "standard", 0}, + {QCF_STANDARD, "vanilla", 0}, + {QCF_STANDARD, "q1", 0}, + {QCF_STANDARD, "id", 0}, + {QCF_STANDARD, "quakec", 0}, - {QCF_STANDARD, "qs"}, - {QCF_QSS, "qss"}, + {QCF_STANDARD, "qs", 0}, + {QCF_QSS, "qss", 0}, - {QCF_HEXEN2, "hexen2"}, - {QCF_HEXEN2, "h2"}, - {QCF_UHEXEN2, "uhexen2"}, + {QCF_HEXEN2, "hexen2", 0}, + {QCF_HEXEN2, "h2", 0}, + {QCF_UHEXEN2, "uhexen2", 0}, - {QCF_KK7, "kkqwsv"}, - {QCF_KK7, "kk7"}, - {QCF_KK7, "bigprogs"}, - {QCF_KK7, "version7"}, - {QCF_KK7, "kkqwsv"}, + {QCF_KK7, "kkqwsv", 0}, + {QCF_KK7, "kk7", 0}, + {QCF_KK7, "version7", 0}, - {QCF_FTE, "fte"}, - {QCF_FTEH2, "fteh2"}, - {QCF_FTEDEBUG, "ftedebug"}, - {QCF_FTEDEBUG, "debug"}, + {QCF_FTE, "fte", 5529}, //'latest' stable revision. + {QCF_FTEH2, "fteh2", 5529}, + {QCF_FTEDEBUG, "ftedebug", 5529}, + {QCF_FTEDEBUG, "debug", 5529}, - {QCF_DARKPLACES,"darkplaces"}, - {QCF_DARKPLACES,"dp"}, + {QCF_FTE, "quake2c", 5744}, //an alias for Paril's project, which does various pointer stuff. the revision should be high enough for str[int] ops. - {QCF_QTEST, "qtest"}, + {QCF_DARKPLACES,"darkplaces", 0}, + {QCF_DARKPLACES,"dp", 0}, + + {QCF_QTEST, "qtest", 0}, {0, NULL} }; pbool QCC_OPCodeSetTargetName(const char *targ) @@ -1513,7 +1544,7 @@ pbool QCC_OPCodeSetTargetName(const char *targ) else { tlen = strlen(targ); - ver = "0x7fffffff"; + ver = NULL; } for (i = 0; targets[i].name; i++) @@ -1537,7 +1568,7 @@ pbool QCC_OPCodeSetTargetName(const char *targ) } } - QCC_OPCodeSetTarget(targets[i].target, atoi(ver)); + QCC_OPCodeSetTarget(targets[i].target, ver?atoi(ver):targets[i].defaultrev); return true; } return false; @@ -5371,6 +5402,7 @@ struct inlinectx_s QCC_def_t *fdef; QCC_function_t *func; QCC_sref_t arglist[8]; + pbool argisout[8]; QCC_sref_t result; @@ -5381,10 +5413,13 @@ struct inlinectx_s int bias; } locals[64]; int numlocals; + + const char *error; }; -static pbool QCC_PR_InlinePushResult(struct inlinectx_s *ctx, QCC_sref_t src, QCC_sref_t mappedto) +static pbool QCC_PR_InlinePushResult(struct inlinectx_s *ctx, QCC_sref_t src/*original statement's symbol*/, QCC_sref_t mappedto/*effective value*/) { - int i; + QCC_def_t *local; + int i, p; for (i = 0; i < ctx->numlocals; i++) { if (ctx->locals[i].srcsym == src.sym) @@ -5393,12 +5428,33 @@ static pbool QCC_PR_InlinePushResult(struct inlinectx_s *ctx, QCC_sref_t src, QC if (i == ctx->numlocals) { if (ctx->numlocals >= sizeof(ctx->locals)/sizeof(ctx->locals[0])) + { + ctx->error = "too many temps"; return false; + } + + for (local = ctx->func->firstlocal, p = 0; local && p < MAX_PARMS && (unsigned int)p < ctx->func->type->num_parms; local = local->deftail->nextlocal, p++) + { + if (src.sym->symbolheader == local) + { + if (ctx->argisout[p]) + { + /*if (ctx->arglist[p].sym->symbolheader != mappedto.sym || ctx->arglist[p].ofs != mappedto.ofs) + { +// ctx->error = "assignment wrote to variable other than intended output."; + return false; + }*/ + return true; + } + } + } + ctx->locals[i].srcsym = src.sym; ctx->numlocals++; } else if (ctx->locals[i].def) QCC_FreeDef(ctx->locals[i].def); + ctx->locals[i].def = mappedto.sym; ctx->locals[i].bias = mappedto.ofs - src.ofs; //FIXME: this feels unsafe (needed for array[immediate] fixups) return true; @@ -5419,13 +5475,21 @@ static QCC_sref_t QCC_PR_InlineFindDef(struct inlinectx_s *ctx, QCC_sref_t src, if (ctx->locals[p].srcsym == src.sym && ctx->locals[p].def) { d = ctx->locals[p].def; - if (assign) + if (assign && src.sym) { - QCC_FreeDef(ctx->locals[p].def); - ctx->locals[p].def = NULL; + if (!(src.sym->localscope || src.sym->temp)) + { //update the symbol to refer to its original value... +// QCC_FreeDef(ctx->locals[p].def); + ctx->locals[p].def = ctx->locals[p].srcsym; + ctx->locals[p].bias = 0; + return QCC_MakeSRefForce(src.sym, src.ofs, src.cast); + } + //substitute the assignment with a new temp +// QCC_FreeDef(ctx->locals[p].def); + ctx->locals[p].srcsym = src.sym; + ctx->locals[p].def = QCC_GetTemp(src.sym->type).sym; ctx->locals[p].bias = 0; - d = NULL; - return QCC_MakeSRefForce(NULL, 0, NULL); + return QCC_MakeSRefForce(ctx->locals[p].def, src.ofs, src.cast); } return QCC_MakeSRefForce(d, src.ofs + ctx->locals[p].bias, src.cast); } @@ -5439,6 +5503,14 @@ static QCC_sref_t QCC_PR_InlineFindDef(struct inlinectx_s *ctx, QCC_sref_t src, { if (src.sym->symbolheader == local) { + if (assign && !ctx->argisout[p]) + { +// QCC_FreeDef(ctx->locals[p].def); + ctx->locals[p].srcsym = src.sym; + ctx->locals[p].def = QCC_GetTemp(src.sym->type).sym; + ctx->locals[p].bias = 0; + return QCC_MakeSRefForce(ctx->locals[p].def, src.ofs, src.cast); + } return QCC_MakeSRefForce(ctx->arglist[p].sym->symbolheader, ctx->arglist[p].ofs+src.ofs, src.cast); } } @@ -5448,6 +5520,7 @@ static QCC_sref_t QCC_PR_InlineFindDef(struct inlinectx_s *ctx, QCC_sref_t src, return nullsref; ctx->locals[ctx->numlocals].srcsym = src.sym; ctx->locals[ctx->numlocals].def = QCC_GetTemp(src.sym->type).sym; + ctx->locals[ctx->numlocals].bias = 0; return QCC_MakeSRefForce(ctx->locals[ctx->numlocals++].def, src.ofs, src.cast); } return QCC_MakeSRefForce(src.sym, src.ofs, src.cast); @@ -5489,7 +5562,7 @@ static QCC_sref_t QCC_PR_InlineFindDef(struct inlinectx_s *ctx, QCC_sref_t src, } //returns a string saying why inlining failed. -static char *QCC_PR_InlineStatements(struct inlinectx_s *ctx) +static const char *QCC_PR_InlineStatements(struct inlinectx_s *ctx) { /*FIXME: what happens with: t = foo; @@ -5630,8 +5703,14 @@ static char *QCC_PR_InlineStatements(struct inlinectx_s *ctx) QCC_PR_InlinePushResult(ctx, r, QCC_GetAliasTemp(QCC_MakeSRefForce(&def_ret, 0, a.cast->aux_type))); } } - else - if (pr_opcodes[st->op].associative == ASSOC_RIGHT) + else if (pr_opcodes[st->op].flags & (OPF_STOREFLD|OPF_STOREPTROFS)) + { //these forms don't write to any actual globals, we've no real scope for optimising these out. + a = QCC_PR_InlineFindDef(ctx, st->a, false); + b = QCC_PR_InlineFindDef(ctx, st->b, false); + c = QCC_PR_InlineFindDef(ctx, st->c, false); + QCC_PR_SimpleStatement(&pr_opcodes[st->op], a, b, c, false); + } + else if (pr_opcodes[st->op].associative == ASSOC_RIGHT) { //a->b if (st->a.cast) @@ -5642,11 +5721,11 @@ static char *QCC_PR_InlineStatements(struct inlinectx_s *ctx) } else a = nullsref; - b = QCC_PR_InlineFindDef(ctx, st->b, true); + b = QCC_PR_InlineFindDef(ctx, st->b, !(pr_opcodes[st->op].flags & OPF_STOREPTR)); c = QCC_PR_StatementFlags(&pr_opcodes[st->op], a, b, NULL, 0); if (!QCC_PR_InlinePushResult(ctx, st->b, c)) - return "too many temps"; + return ctx->error; } else if (OpAssignsToC(st->op)) { @@ -5682,7 +5761,7 @@ static char *QCC_PR_InlineStatements(struct inlinectx_s *ctx) } if (!QCC_PR_InlinePushResult(ctx, st->c, c)) - return "too many temps"; + return ctx->error; } else { @@ -5725,19 +5804,28 @@ static QCC_sref_t QCC_PR_Inline(QCC_sref_t fdef, QCC_ref_t **arglist, unsigned i #else // QCC_def_t *dd = NULL; struct inlinectx_s ctx; - char *error; + const char *error; int statements, i; unsigned int a; const QCC_eval_t *eval = QCC_SRef_EvalConst(fdef); //make sure that its a function type and that there's no special weirdness if (!eval || eval->function < 0 || argcount > 8 || eval->function >= numfunctions || fdef.sym->arraysize != 0 || fdef.cast->type != ev_function || argcount != fdef.cast->num_parms || fdef.cast->vargs || fdef.cast->vargcount) + { + QCC_PR_ParseWarning(0, "Couldn't inline \"%s\": %s", ctx.func->name, "inconsistent context"); return nullsref; + } ctx.func = &functions[eval->function]; if (fdef.cast != ctx.func->type) + { + QCC_PR_ParseWarning(0, "Couldn't inline \"%s\": %s", ctx.func->name, "function was cast"); return nullsref; + } ctx.numlocals = 0; for (a = 0; a < argcount; a++) + { ctx.arglist[a] = QCC_RefToDef(arglist[a], true); + ctx.argisout[a] = ctx.func->type->params[a].out; + } ctx.fdef = fdef.sym; ctx.result = nullsref; if ((int)ctx.func->code <= 0) @@ -5787,6 +5875,8 @@ static QCC_sref_t QCC_PR_Inline(QCC_sref_t fdef, QCC_ref_t **arglist, unsigned i statements = numstatements; error = QCC_PR_InlineStatements(&ctx); + if (!error) + error = ctx.error; if (error) { QCC_PR_ParseWarning(0, "Couldn't inline \"%s\": %s", ctx.func->name, error); @@ -10138,8 +10228,16 @@ QCC_sref_t QCC_RefToDef(QCC_ref_t *ref, pbool freetemps) case REF_FIELD: return QCC_PR_ExpandField(ref->base, ref->index, ref->cast, freetemps?0:(STFL_PRESERVEA|STFL_PRESERVEB)); case REF_STRING: - idx = QCC_SupplyConversion(ref->index, ev_float, true); - return QCC_PR_StatementFlags(&pr_opcodes[OP_LOADP_C], ref->base, idx, NULL, freetemps?0:(STFL_PRESERVEA|STFL_PRESERVEB)); + if (ref->index.cast->type == ev_float) + { + idx = QCC_SupplyConversion(ref->index, ev_float, true); + return QCC_PR_StatementFlags(&pr_opcodes[OP_LOADP_C], ref->base, idx, NULL, freetemps?0:(STFL_PRESERVEA|STFL_PRESERVEB)); + } + else + { + idx = QCC_SupplyConversion(ref->index, ev_integer, true); + return QCC_PR_StatementFlags(&pr_opcodes[OP_LOADP_B], ref->base, idx, NULL, freetemps?0:(STFL_PRESERVEA|STFL_PRESERVEB)); + } case REF_ACCESSOR: if (ref->accessor && ref->accessor->getset_func[0].cast) { @@ -14698,18 +14796,6 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, const char *name, QCC_function_t *s } def->allowinline = !!(flags & GDF_INLINE); - if (def->allowinline) - { - unsigned int p; - for (p = 0; p < type->num_parms; p++) - { - if (type->params[p].out) - break; - } - if (p != type->num_parms || type->type != ev_function) - def->allowinline = false; //FIXME: warn about invalid usage! - } - if (flags & GDF_USED) { def->used = true; diff --git a/engine/server/svq2_game.c b/engine/server/svq2_game.c index 6738d082..7fd69d5a 100644 --- a/engine/server/svq2_game.c +++ b/engine/server/svq2_game.c @@ -44,6 +44,9 @@ void *SVQ2_GetGameAPI (void *parms) "game" "i386" ARCH_DL_POSTFIX, //compat is often better than consistancy #endif "game" ARCH_CPU_POSTFIX ARCH_DL_POSTFIX, +#ifdef ARCH_ALTCPU_POSTFIX + "game" ARCH_ALTCPU_POSTFIX ARCH_DL_POSTFIX, +#endif "game" ARCH_DL_POSTFIX, #if defined(__linux__) //FTE doesn't provide gamecode. Borrow someone else's. Lets just hope that its installed. // "/usr/lib/yamagi-quake2/%s/game.so",