Try to fix the bugs that Paril found... I wonder if I broke anything new.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5723 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
c09cf1481a
commit
82ecdfbfa8
6 changed files with 293 additions and 89 deletions
|
@ -251,6 +251,9 @@ reeval:
|
||||||
case OP_NOT_ENT:
|
case OP_NOT_ENT:
|
||||||
OPC->_float = (float)(!(OPA->edict));//(PROG_TO_EDICT(progfuncs, OPA->edict) == (edictrun_t *)sv_edicts);
|
OPC->_float = (float)(!(OPA->edict));//(PROG_TO_EDICT(progfuncs, OPA->edict) == (edictrun_t *)sv_edicts);
|
||||||
break;
|
break;
|
||||||
|
case OP_NOT_I:
|
||||||
|
OPC->_int = !OPA->_int;
|
||||||
|
break;
|
||||||
|
|
||||||
case OP_EQ_F:
|
case OP_EQ_F:
|
||||||
OPC->_float = (float)(OPA->_float == OPB->_float);
|
OPC->_float = (float)(OPA->_float == OPB->_float);
|
||||||
|
@ -1351,10 +1354,6 @@ reeval:
|
||||||
OPC->_int = (OPA->_float || OPB->_int);
|
OPC->_int = (OPA->_float || OPB->_int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_NOT_I:
|
|
||||||
OPC->_int = !OPA->_int;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OP_NE_IF:
|
case OP_NE_IF:
|
||||||
OPC->_int = (OPA->_int != OPB->_float);
|
OPC->_int = (OPA->_int != OPB->_float);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -383,6 +383,7 @@ typedef struct QCC_type_s
|
||||||
struct accessor_s *accessors;
|
struct accessor_s *accessors;
|
||||||
|
|
||||||
struct QCC_type_s *ptrto; //(cache) this points to a type that is a pointer back to this type. yeah, weird.
|
struct QCC_type_s *ptrto; //(cache) this points to a type that is a pointer back to this type. yeah, weird.
|
||||||
|
struct QCC_type_s *fldto; //(cache) this points to a type that is a pointer back to this type. yeah, weird.
|
||||||
} QCC_type_t;
|
} QCC_type_t;
|
||||||
int typecmp(QCC_type_t *a, QCC_type_t *b);
|
int typecmp(QCC_type_t *a, QCC_type_t *b);
|
||||||
int typecmp_lax(QCC_type_t *a, QCC_type_t *b);
|
int typecmp_lax(QCC_type_t *a, QCC_type_t *b);
|
||||||
|
|
|
@ -222,6 +222,7 @@ void QCC_PR_DiscardRef(QCC_ref_t *ref);
|
||||||
QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *type, pbool dowrap);
|
QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *type, pbool dowrap);
|
||||||
const char *QCC_VarAtOffset(QCC_sref_t ref);
|
const char *QCC_VarAtOffset(QCC_sref_t ref);
|
||||||
QCC_sref_t QCC_EvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit);
|
QCC_sref_t QCC_EvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit);
|
||||||
|
QCC_sref_t QCC_PR_ParseInitializerTemp(QCC_type_t *type);
|
||||||
pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t def, unsigned int flags);
|
pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t def, unsigned int flags);
|
||||||
#define PIF_WRAP 1 //new initialisation is meant to wrap an existing one.
|
#define PIF_WRAP 1 //new initialisation is meant to wrap an existing one.
|
||||||
#define PIF_STRONGER 2 //previous initialisation was weak.
|
#define PIF_STRONGER 2 //previous initialisation was weak.
|
||||||
|
@ -255,7 +256,8 @@ enum
|
||||||
STFL_CONVERTA=1u<<1, //convert to/from ints/floats to match the operand types required by the opcode
|
STFL_CONVERTA=1u<<1, //convert to/from ints/floats to match the operand types required by the opcode
|
||||||
STFL_PRESERVEB=1u<<2,
|
STFL_PRESERVEB=1u<<2,
|
||||||
STFL_CONVERTB=1u<<3,
|
STFL_CONVERTB=1u<<3,
|
||||||
STFL_DISCARDRESULT=1u<<4
|
STFL_DISCARDRESULT=1u<<4,
|
||||||
|
STFL_NOEMULATE=1u<<5, //don't emulate unsupported opcode with other opcodes.
|
||||||
};
|
};
|
||||||
#define QCC_PR_Statement(op,a,b,st) QCC_PR_StatementFlags(op,a,b,st,STFL_CONVERTA|STFL_CONVERTB)
|
#define QCC_PR_Statement(op,a,b,st) QCC_PR_StatementFlags(op,a,b,st,STFL_CONVERTA|STFL_CONVERTB)
|
||||||
QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_t var_b, QCC_statement_t **outstatement, unsigned int flags);
|
QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_t var_b, QCC_statement_t **outstatement, unsigned int flags);
|
||||||
|
@ -2067,6 +2069,9 @@ const char *QCC_VarAtOffset(QCC_sref_t ref)
|
||||||
{
|
{
|
||||||
if (ref.sym && ref.sym->temp)
|
if (ref.sym && ref.sym->temp)
|
||||||
{
|
{
|
||||||
|
if (!ref.ofs)
|
||||||
|
QC_snprintfz(message, sizeof(message), "temp_%i", ref.sym->ofs-tempsinfo[0].def->ofs);
|
||||||
|
else
|
||||||
QC_snprintfz(message, sizeof(message), "temp_%i+%i", ref.sym->ofs-tempsinfo[0].def->ofs, ref.ofs);
|
QC_snprintfz(message, sizeof(message), "temp_%i+%i", ref.sym->ofs-tempsinfo[0].def->ofs, ref.ofs);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
@ -2141,12 +2146,18 @@ const char *QCC_VarAtOffset(QCC_sref_t ref)
|
||||||
QC_snprintfz(message, sizeof(message), "'%g %g %g'", val->vector[0], val->vector[1], val->vector[2]);
|
QC_snprintfz(message, sizeof(message), "'%g %g %g'", val->vector[0], val->vector[1], val->vector[2]);
|
||||||
return message;
|
return message;
|
||||||
default:
|
default:
|
||||||
|
if (!ref.ofs)
|
||||||
QC_snprintfz(message, sizeof(message), "IMMEDIATE");
|
QC_snprintfz(message, sizeof(message), "IMMEDIATE");
|
||||||
|
else
|
||||||
|
QC_snprintfz(message, sizeof(message), "IMMEDIATE+%i", ref.ofs);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ref.ofs || ref.cast != ref.sym->type)
|
else if (ref.ofs || ref.cast != ref.sym->type)
|
||||||
{
|
{
|
||||||
|
if (!ref.ofs)
|
||||||
|
QC_snprintfz(message, sizeof(message), "%s", ref.sym->name);
|
||||||
|
else
|
||||||
QC_snprintfz(message, sizeof(message), "%s+%i", ref.sym->name, ref.ofs);
|
QC_snprintfz(message, sizeof(message), "%s+%i", ref.sym->name, ref.ofs);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
@ -3118,7 +3129,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!QCC_OPCodeValid(op))
|
if (!QCC_OPCodeValid(op) && !(flags&STFL_NOEMULATE))
|
||||||
{
|
{
|
||||||
QCC_sref_t tmp;
|
QCC_sref_t tmp;
|
||||||
//FIXME: add support for flags so we don't corrupt temps
|
//FIXME: add support for flags so we don't corrupt temps
|
||||||
|
@ -3455,6 +3466,24 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
||||||
var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_BITAND_F], var_b, var_a, NULL, 0);
|
var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_BITAND_F], var_b, var_a, NULL, 0);
|
||||||
return QCC_PR_StatementFlags(&pr_opcodes[OP_BITOR_F], var_c, var_a, NULL, 0);
|
return QCC_PR_StatementFlags(&pr_opcodes[OP_BITOR_F], var_c, var_a, NULL, 0);
|
||||||
|
|
||||||
|
case OP_BITXOR_I:
|
||||||
|
{
|
||||||
|
QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "BitxorInt", NULL, false, 0, 0);
|
||||||
|
if (!fnc.cast)
|
||||||
|
{
|
||||||
|
QCC_PR_ParseError(0, "BitxorInt function not defined: cannot emulate int^int");
|
||||||
|
var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_BITNOT_I], var_b, nullsref, NULL, STFL_PRESERVEA);
|
||||||
|
var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_BITAND_I], var_a, var_c, NULL, STFL_PRESERVEA);
|
||||||
|
var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_BITNOT_I], var_a, nullsref, NULL, 0);
|
||||||
|
var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_BITAND_I], var_b, var_a, NULL, 0);
|
||||||
|
return QCC_PR_StatementFlags(&pr_opcodes[OP_BITOR_I], var_c, var_a, NULL, 0);
|
||||||
|
}
|
||||||
|
var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_integer, var_b, type_integer);
|
||||||
|
var_c.cast = type_integer;
|
||||||
|
return var_c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case OP_BITXOR_V:
|
case OP_BITXOR_V:
|
||||||
// r = (a & ~b) | (b & ~a);
|
// r = (a & ~b) | (b & ~a);
|
||||||
var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_BITNOT_V], var_b, nullsref, NULL, STFL_PRESERVEA);
|
var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_BITNOT_V], var_b, nullsref, NULL, STFL_PRESERVEA);
|
||||||
|
@ -3542,10 +3571,23 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_BITNOT_I:
|
case OP_BITNOT_I:
|
||||||
|
op = &pr_opcodes[OP_SUB_I];
|
||||||
|
if (QCC_OPCodeValid(op))
|
||||||
|
{
|
||||||
op = &pr_opcodes[OP_SUB_I];
|
op = &pr_opcodes[OP_SUB_I];
|
||||||
var_b = var_a;
|
var_b = var_a;
|
||||||
var_a = QCC_MakeIntConst(~0);
|
var_a = QCC_MakeIntConst(~0);
|
||||||
var_a.sym->referenced = true;
|
var_a.sym->referenced = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "SubInt", NULL, false, 0, 0);
|
||||||
|
if (!fnc.cast)
|
||||||
|
QCC_PR_ParseError(0, "SubInt function not defined: cannot emulate ~int");
|
||||||
|
var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, QCC_MakeIntConst(~0), type_integer, var_a, type_integer);
|
||||||
|
var_c.cast = type_integer;
|
||||||
|
return var_c;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OP_BITNOT_F:
|
case OP_BITNOT_F:
|
||||||
op = &pr_opcodes[OP_SUB_F];
|
op = &pr_opcodes[OP_SUB_F];
|
||||||
|
@ -3915,6 +3957,27 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
||||||
var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_CONV_FTOI], var_a, nullsref, NULL, flags&STFL_PRESERVEA);
|
var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_CONV_FTOI], var_a, nullsref, NULL, flags&STFL_PRESERVEA);
|
||||||
return QCC_PR_StatementFlags(&pr_opcodes[OP_RSHIFT_I], var_a, var_b, NULL, flags&STFL_PRESERVEB);
|
return QCC_PR_StatementFlags(&pr_opcodes[OP_RSHIFT_I], var_a, var_b, NULL, flags&STFL_PRESERVEB);
|
||||||
|
|
||||||
|
case OP_LSHIFT_I:
|
||||||
|
{
|
||||||
|
QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "LShiftInt", NULL, false, 0, 0);
|
||||||
|
if (!fnc.cast)
|
||||||
|
QCC_PR_ParseError(0, "LShiftInt function not defined: cannot emulate int<<int");
|
||||||
|
var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, QCC_MakeIntConst(~0), type_integer, var_a, type_integer);
|
||||||
|
var_c.cast = type_integer;
|
||||||
|
return var_c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OP_RSHIFT_I:
|
||||||
|
{
|
||||||
|
QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "RShiftInt", NULL, false, 0, 0);
|
||||||
|
if (!fnc.cast)
|
||||||
|
QCC_PR_ParseError(0, "RShiftInt function not defined: cannot emulate int>>int");
|
||||||
|
var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, QCC_MakeIntConst(~0), type_integer, var_a, type_integer);
|
||||||
|
var_c.cast = type_integer;
|
||||||
|
return var_c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
//convert both to ints
|
//convert both to ints
|
||||||
case OP_LSHIFT_F:
|
case OP_LSHIFT_F:
|
||||||
if (QCC_OPCodeValid(&pr_opcodes[OP_LSHIFT_I]))
|
if (QCC_OPCodeValid(&pr_opcodes[OP_LSHIFT_I]))
|
||||||
|
@ -5334,9 +5397,9 @@ static char *QCC_PR_InlineStatements(struct inlinectx_s *ctx)
|
||||||
{
|
{
|
||||||
QCC_sref_t r;
|
QCC_sref_t r;
|
||||||
c = QCC_PR_InlineFindDef(ctx, st->c, true);
|
c = QCC_PR_InlineFindDef(ctx, st->c, true);
|
||||||
r = QCC_PR_StatementFlags(&pr_opcodes[st->op], a, b, NULL, 0);
|
r = QCC_PR_StatementFlags(&pr_opcodes[st->op], a, b, NULL, STFL_NOEMULATE);
|
||||||
if (c.cast && !QCC_SRef_EvalConst(r))
|
if (c.cast && !QCC_SRef_EvalConst(r))
|
||||||
c = QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_ENT], r, c, NULL, 0);
|
c = QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_ENT], r, c, NULL, STFL_NOEMULATE);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QCC_FreeTemp(c);
|
QCC_FreeTemp(c);
|
||||||
|
@ -5388,15 +5451,16 @@ static QCC_sref_t QCC_PR_Inline(QCC_sref_t fdef, QCC_ref_t **arglist, unsigned i
|
||||||
unsigned int a;
|
unsigned int a;
|
||||||
const QCC_eval_t *eval = QCC_SRef_EvalConst(fdef);
|
const QCC_eval_t *eval = QCC_SRef_EvalConst(fdef);
|
||||||
//make sure that its a function type and that there's no special weirdness
|
//make sure that its a function type and that there's no special weirdness
|
||||||
if (!eval || fdef.cast != fdef.sym->type || 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)
|
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)
|
||||||
|
return nullsref;
|
||||||
|
ctx.func = &functions[eval->function];
|
||||||
|
if (fdef.cast != ctx.func->type)
|
||||||
return nullsref;
|
return nullsref;
|
||||||
|
|
||||||
ctx.numlocals = 0;
|
ctx.numlocals = 0;
|
||||||
for (a = 0; a < argcount; a++)
|
for (a = 0; a < argcount; a++)
|
||||||
ctx.arglist[a] = QCC_RefToDef(arglist[a], true);
|
ctx.arglist[a] = QCC_RefToDef(arglist[a], true);
|
||||||
ctx.fdef = fdef.sym;
|
ctx.fdef = fdef.sym;
|
||||||
ctx.result = nullsref;
|
ctx.result = nullsref;
|
||||||
ctx.func = &functions[eval->function];
|
|
||||||
if ((int)ctx.func->code <= 0)
|
if ((int)ctx.func->code <= 0)
|
||||||
{
|
{
|
||||||
char *fname = ctx.func->name;
|
char *fname = ctx.func->name;
|
||||||
|
@ -7277,6 +7341,33 @@ static QCC_sref_t QCC_PR_ExpandField(QCC_sref_t ent, QCC_sref_t field, QCC_type_
|
||||||
//FIXME: class.staticmember should directly read staticmember instead of trying to dereference
|
//FIXME: class.staticmember should directly read staticmember instead of trying to dereference
|
||||||
switch(fieldtype->type)
|
switch(fieldtype->type)
|
||||||
{
|
{
|
||||||
|
case ev_struct:
|
||||||
|
case ev_union:
|
||||||
|
case ev_enum:
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
QCC_type_t *type = fieldtype;
|
||||||
|
QCC_sref_t dest = QCC_GetTemp(type);
|
||||||
|
QCC_sref_t source = field;
|
||||||
|
//don't bother trying to optimise any temps here, its not likely to happen anyway.
|
||||||
|
for (i = 0; i+2 < type->size; i+=3, dest.ofs += 3, source.ofs += 3)
|
||||||
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_LOAD_V], ent, source, dest, false);
|
||||||
|
for (; i < type->size; i++, dest.ofs++, source.ofs++)
|
||||||
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_LOAD_F], ent, source, dest, false);
|
||||||
|
source.ofs -= type->size;
|
||||||
|
dest.ofs -= type->size;
|
||||||
|
if (!(preserveflags & STFL_PRESERVEA))
|
||||||
|
QCC_FreeTemp(ent);
|
||||||
|
if (!(preserveflags & STFL_PRESERVEB))
|
||||||
|
QCC_FreeTemp(field);
|
||||||
|
|
||||||
|
QCC_PR_ParseWarning(WARN_UNDESIRABLECONVENTION, "QCC_PR_ExpandField: inefficient");
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ev_void:
|
||||||
|
case ev_accessor:
|
||||||
|
case ev_boolean:
|
||||||
default:
|
default:
|
||||||
QCC_PR_ParseErrorPrintSRef(ERR_INTERNAL, field, "QCC_PR_ExpandField: invalid field type");
|
QCC_PR_ParseErrorPrintSRef(ERR_INTERNAL, field, "QCC_PR_ExpandField: invalid field type");
|
||||||
r = field;
|
r = field;
|
||||||
|
@ -8617,7 +8708,7 @@ static QCC_ref_t *QCC_PR_RefTerm (QCC_ref_t *retbuf, unsigned int exprflags)
|
||||||
QCC_PR_ParseErrorPrintSRef (ERR_TYPEMISMATCH, e, "Unable to dereference non-pointer type.");
|
QCC_PR_ParseErrorPrintSRef (ERR_TYPEMISMATCH, e, "Unable to dereference non-pointer type.");
|
||||||
}
|
}
|
||||||
if (flag_qccx && QCC_PR_CheckToken ("@"))
|
if (flag_qccx && QCC_PR_CheckToken ("@"))
|
||||||
{
|
{ //@foo is equivelent to (string)*(int*)&foo
|
||||||
r = QCC_PR_RefExpression (retbuf, UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
|
r = QCC_PR_RefExpression (retbuf, UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
|
||||||
if (r->cast->type == ev_float || r->cast->type == ev_integer)
|
if (r->cast->type == ev_float || r->cast->type == ev_integer)
|
||||||
{
|
{
|
||||||
|
@ -8698,8 +8789,9 @@ static QCC_ref_t *QCC_PR_RefTerm (QCC_ref_t *retbuf, unsigned int exprflags)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
e = QCC_GetTemp(newtype);
|
e = QCC_PR_ParseInitializerTemp(newtype);
|
||||||
QCC_PR_ParseInitializerType(0, NULL, e, 0);
|
if (newtype->type == ev_function && QCC_PR_PeekToken("("))
|
||||||
|
e.sym->allowinline = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -8857,15 +8949,21 @@ static void QCC_StoreToSRef(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *type
|
||||||
case ev_union:
|
case ev_union:
|
||||||
case ev_enum:
|
case ev_enum:
|
||||||
//don't bother trying to optimise any temps here, its not likely to happen anyway.
|
//don't bother trying to optimise any temps here, its not likely to happen anyway.
|
||||||
|
if (QCC_SRef_IsNull(source))
|
||||||
|
{
|
||||||
|
for (i = 0; i+2 < type->size; i+=3, dest.ofs += 3)
|
||||||
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STORE_V], QCC_MakeVectorConst(0,0,0), dest, nullsref, false);
|
||||||
|
for (; i < type->size; i++, dest.ofs++)
|
||||||
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STORE_F], QCC_MakeIntConst(0), dest, nullsref, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for (i = 0; i+2 < type->size; i+=3, dest.ofs += 3, source.ofs += 3)
|
for (i = 0; i+2 < type->size; i+=3, dest.ofs += 3, source.ofs += 3)
|
||||||
{
|
|
||||||
QCC_PR_SimpleStatement(&pr_opcodes[OP_STORE_V], source, dest, nullsref, false);
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STORE_V], source, dest, nullsref, false);
|
||||||
}
|
|
||||||
for (; i < type->size; i++, dest.ofs++, source.ofs++)
|
for (; i < type->size; i++, dest.ofs++, source.ofs++)
|
||||||
{
|
|
||||||
QCC_PR_SimpleStatement(&pr_opcodes[OP_STORE_F], source, dest, nullsref, false);
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STORE_F], source, dest, nullsref, false);
|
||||||
}
|
|
||||||
source.ofs -= type->size;
|
source.ofs -= type->size;
|
||||||
|
}
|
||||||
dest.ofs -= type->size;
|
dest.ofs -= type->size;
|
||||||
if (!preservesource)
|
if (!preservesource)
|
||||||
QCC_FreeTemp(source);
|
QCC_FreeTemp(source);
|
||||||
|
@ -8955,10 +9053,15 @@ static void QCC_StoreToPointer(QCC_sref_t dest, QCC_sref_t idx, QCC_sref_t sourc
|
||||||
for (i = 0; i+2 < type->size; i+=3)
|
for (i = 0; i+2 < type->size; i+=3)
|
||||||
{
|
{
|
||||||
QCC_sref_t newidx = idx.sym?QCC_PR_StatementFlags(&pr_opcodes[OP_ADD_I], idx, QCC_MakeIntConst(i), NULL, STFL_PRESERVEA):QCC_MakeIntConst(i);
|
QCC_sref_t newidx = idx.sym?QCC_PR_StatementFlags(&pr_opcodes[OP_ADD_I], idx, QCC_MakeIntConst(i), NULL, STFL_PRESERVEA):QCC_MakeIntConst(i);
|
||||||
|
if (QCC_SRef_IsNull(source))
|
||||||
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STOREP_V], QCC_MakeVectorConst(0,0,0), dest, newidx, false);
|
||||||
|
else
|
||||||
|
{
|
||||||
QCC_PR_SimpleStatement(&pr_opcodes[OP_STOREP_V], source, dest, newidx, false);
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STOREP_V], source, dest, newidx, false);
|
||||||
QCC_FreeTemp(newidx);
|
|
||||||
source.ofs += 3;
|
source.ofs += 3;
|
||||||
}
|
}
|
||||||
|
QCC_FreeTemp(newidx);
|
||||||
|
}
|
||||||
for (; i < type->size; i++)
|
for (; i < type->size; i++)
|
||||||
{
|
{
|
||||||
QCC_sref_t newidx = idx.sym?QCC_PR_StatementFlags(&pr_opcodes[OP_ADD_I], idx, QCC_MakeIntConst(i), NULL, STFL_PRESERVEA):QCC_MakeIntConst(i);
|
QCC_sref_t newidx = idx.sym?QCC_PR_StatementFlags(&pr_opcodes[OP_ADD_I], idx, QCC_MakeIntConst(i), NULL, STFL_PRESERVEA):QCC_MakeIntConst(i);
|
||||||
|
@ -8972,17 +9075,27 @@ static void QCC_StoreToPointer(QCC_sref_t dest, QCC_sref_t idx, QCC_sref_t sourc
|
||||||
for (i = 0; i+2 < type->size; i+=3)
|
for (i = 0; i+2 < type->size; i+=3)
|
||||||
{
|
{
|
||||||
QCC_sref_t newptr = QCC_PR_StatementFlags(&pr_opcodes[OP_ADD_PIW], dest, QCC_MakeIntConst(i), NULL, STFL_PRESERVEA);
|
QCC_sref_t newptr = QCC_PR_StatementFlags(&pr_opcodes[OP_ADD_PIW], dest, QCC_MakeIntConst(i), NULL, STFL_PRESERVEA);
|
||||||
|
if (QCC_SRef_IsNull(source))
|
||||||
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STOREP_V], QCC_MakeVectorConst(0,0,0), newptr, idx, false);
|
||||||
|
else
|
||||||
|
{
|
||||||
QCC_PR_SimpleStatement(&pr_opcodes[OP_STOREP_V], source, newptr, idx, false);
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STOREP_V], source, newptr, idx, false);
|
||||||
QCC_FreeTemp(newptr);
|
|
||||||
source.ofs += 3;
|
source.ofs += 3;
|
||||||
}
|
}
|
||||||
|
QCC_FreeTemp(newptr);
|
||||||
|
}
|
||||||
for (; i < type->size; i++)
|
for (; i < type->size; i++)
|
||||||
{
|
{
|
||||||
QCC_sref_t newptr = QCC_PR_StatementFlags(&pr_opcodes[OP_ADD_PIW], dest, QCC_MakeIntConst(i), NULL, STFL_PRESERVEA);
|
QCC_sref_t newptr = QCC_PR_StatementFlags(&pr_opcodes[OP_ADD_PIW], dest, QCC_MakeIntConst(i), NULL, STFL_PRESERVEA);
|
||||||
|
if (QCC_SRef_IsNull(source))
|
||||||
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STOREP_F], QCC_MakeIntConst(0), newptr, idx, false);
|
||||||
|
else
|
||||||
|
{
|
||||||
QCC_PR_SimpleStatement(&pr_opcodes[OP_STOREP_F], source, newptr, idx, false);
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STOREP_F], source, newptr, idx, false);
|
||||||
QCC_FreeTemp(newptr);
|
|
||||||
source.ofs += 1;
|
source.ofs += 1;
|
||||||
}
|
}
|
||||||
|
QCC_FreeTemp(newptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -9578,6 +9691,7 @@ QCC_sref_t QCC_RefToDef(QCC_ref_t *ref, pbool freetemps)
|
||||||
QCC_sref_t QCC_StoreSRefToRef(QCC_ref_t *dest, QCC_sref_t source, pbool readable, pbool preservedest)
|
QCC_sref_t QCC_StoreSRefToRef(QCC_ref_t *dest, QCC_sref_t source, pbool readable, pbool preservedest)
|
||||||
{
|
{
|
||||||
QCC_ref_t ptrref;
|
QCC_ref_t ptrref;
|
||||||
|
pbool nullsrc = QCC_SRef_IsNull(source);
|
||||||
if (dest->readonly)
|
if (dest->readonly)
|
||||||
{
|
{
|
||||||
QCC_PR_ParseWarning(WARN_ASSIGNMENTTOCONSTANT, "Assignment to constant %s", QCC_GetSRefName(dest->base));
|
QCC_PR_ParseWarning(WARN_ASSIGNMENTTOCONSTANT, "Assignment to constant %s", QCC_GetSRefName(dest->base));
|
||||||
|
@ -9586,16 +9700,21 @@ QCC_sref_t QCC_StoreSRefToRef(QCC_ref_t *dest, QCC_sref_t source, pbool readable
|
||||||
QCC_PR_ParsePrintSRef(WARN_ASSIGNMENTTOCONSTANT, dest->index);
|
QCC_PR_ParsePrintSRef(WARN_ASSIGNMENTTOCONSTANT, dest->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QCC_SRef_IsNull(source))
|
if (!nullsrc)
|
||||||
|
/*{
|
||||||
|
if (dest->cast->type == ev_struct || dest->cast->type == ev_union)
|
||||||
{
|
{
|
||||||
if (dest->cast->type == ev_vector)
|
QCC_FreeTemp(source);
|
||||||
|
source = QCC_MakeIntConst(0);
|
||||||
|
}
|
||||||
|
else if (dest->cast->type == ev_vector)
|
||||||
{
|
{
|
||||||
QCC_FreeTemp(source);
|
QCC_FreeTemp(source);
|
||||||
source = QCC_MakeVectorConst(0, 0, 0);
|
source = QCC_MakeVectorConst(0, 0, 0);
|
||||||
}
|
}
|
||||||
source.cast = dest->cast;
|
source.cast = dest->cast;
|
||||||
}
|
}
|
||||||
else
|
else*/
|
||||||
{
|
{
|
||||||
QCC_type_t *t = source.cast;
|
QCC_type_t *t = source.cast;
|
||||||
while(t)
|
while(t)
|
||||||
|
@ -9740,6 +9859,10 @@ QCC_sref_t QCC_StoreSRefToRef(QCC_ref_t *dest, QCC_sref_t source, pbool readable
|
||||||
//fixme: we should do this earlier, to preserve original instruction ordering.
|
//fixme: we should do this earlier, to preserve original instruction ordering.
|
||||||
//such that self.enemy = (self = world); still has the same result (more common with function calls)
|
//such that self.enemy = (self = world); still has the same result (more common with function calls)
|
||||||
|
|
||||||
|
dest->base.sym->referenced = true;
|
||||||
|
dest->index.sym->referenced = true;
|
||||||
|
source.sym->referenced = true;
|
||||||
|
|
||||||
if (dest->cast->type == ev_float)
|
if (dest->cast->type == ev_float)
|
||||||
storef_opcode = OP_STOREF_F;
|
storef_opcode = OP_STOREF_F;
|
||||||
else if (dest->cast->type == ev_vector)
|
else if (dest->cast->type == ev_vector)
|
||||||
|
@ -9750,29 +9873,75 @@ QCC_sref_t QCC_StoreSRefToRef(QCC_ref_t *dest, QCC_sref_t source, pbool readable
|
||||||
dest->cast->type == ev_field ||
|
dest->cast->type == ev_field ||
|
||||||
dest->cast->type == ev_function ||
|
dest->cast->type == ev_function ||
|
||||||
dest->cast->type == ev_pointer ||
|
dest->cast->type == ev_pointer ||
|
||||||
dest->cast->type == ev_integer)
|
dest->cast->type == ev_integer ||
|
||||||
|
dest->cast->type == ev_struct ||
|
||||||
|
dest->cast->type == ev_union ||
|
||||||
|
dest->cast->type == ev_enum)
|
||||||
storef_opcode = OP_STOREF_I;
|
storef_opcode = OP_STOREF_I;
|
||||||
else
|
else
|
||||||
storef_opcode = OP_DONE;
|
storef_opcode = OP_DONE;
|
||||||
//don't use it for arrays. address+storep_with_offset is less opcodes.
|
//don't use it for arrays. address+storep_with_offset is less opcodes.
|
||||||
if (storef_opcode!=OP_DONE && dest->cast->size == 1 && QCC_OPCodeValid(&pr_opcodes[storef_opcode]))
|
if (storef_opcode!=OP_DONE && dest->index.cast->size == dest->cast->size && QCC_OPCodeValid(&pr_opcodes[storef_opcode]))
|
||||||
{
|
{
|
||||||
dest->base.sym->referenced = true;
|
|
||||||
dest->index.sym->referenced = true;
|
|
||||||
source.sym->referenced = true;
|
|
||||||
//doesn't generate any temps.
|
//doesn't generate any temps.
|
||||||
|
int sz = dest->cast->size, i;
|
||||||
|
if (nullsrc)
|
||||||
|
{
|
||||||
|
for (i = 0; i+2 < sz; i+=3, dest->index.ofs += 3)
|
||||||
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STOREF_V], dest->base, dest->index, QCC_MakeVectorConst(0,0,0), true);
|
||||||
|
for (; i < sz; i++, dest->index.ofs++)
|
||||||
|
QCC_PR_SimpleStatement(&pr_opcodes[storef_opcode], dest->base, dest->index, QCC_MakeIntConst(0), true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i+2 < sz; i+=3, dest->index.ofs += 3, source.ofs += 3)
|
||||||
|
QCC_PR_SimpleStatement(&pr_opcodes[OP_STOREF_V], dest->base, dest->index, source, true);
|
||||||
|
for (; i < sz; i++, dest->index.ofs++, source.ofs++)
|
||||||
QCC_PR_SimpleStatement(&pr_opcodes[storef_opcode], dest->base, dest->index, source, true);
|
QCC_PR_SimpleStatement(&pr_opcodes[storef_opcode], dest->base, dest->index, source, true);
|
||||||
|
source.ofs -= i;
|
||||||
|
}
|
||||||
|
dest->index.ofs -= i;
|
||||||
|
if (!readable)
|
||||||
|
{
|
||||||
|
QCC_FreeTemp(source);
|
||||||
|
source = nullsref;
|
||||||
|
}
|
||||||
|
|
||||||
if (!preservedest)
|
if (!preservedest)
|
||||||
{
|
{
|
||||||
QCC_FreeTemp(dest->base);
|
QCC_FreeTemp(dest->base);
|
||||||
QCC_FreeTemp(dest->index);
|
QCC_FreeTemp(dest->index);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (1)//dest->cast->type >= ev_variant)
|
||||||
|
{
|
||||||
|
QCC_sref_t t;
|
||||||
|
int sz = dest->cast->size, i;
|
||||||
|
for (i = 0; i+2 < sz; i+=3, dest->index.ofs += 3, source.ofs+=3)
|
||||||
|
{
|
||||||
|
t = QCC_PR_StatementFlags(&pr_opcodes[OP_ADDRESS], dest->base, dest->index, NULL, STFL_PRESERVEA|STFL_PRESERVEB);
|
||||||
|
QCC_StoreToPointer(t, nullsref, nullsrc?QCC_MakeVectorConst(0,0,0):source, type_vector);
|
||||||
|
QCC_FreeTemp(t);
|
||||||
|
}
|
||||||
|
for (; i < sz; i++, dest->index.ofs++, source.ofs++)
|
||||||
|
{
|
||||||
|
t = QCC_PR_StatementFlags(&pr_opcodes[OP_ADDRESS], dest->base, dest->index, NULL, STFL_PRESERVEA|STFL_PRESERVEB);
|
||||||
|
QCC_StoreToPointer(t, nullsref, nullsrc?QCC_MakeFloatConst(0):source, (dest->cast->size!=1)?type_float:dest->cast);
|
||||||
|
QCC_FreeTemp(t);
|
||||||
|
}
|
||||||
|
source.ofs -= i;
|
||||||
|
dest->index.ofs -= i;
|
||||||
|
|
||||||
if (!readable)
|
if (!readable)
|
||||||
{
|
{
|
||||||
QCC_FreeTemp(source);
|
QCC_FreeTemp(source);
|
||||||
source = nullsref;
|
source = nullsref;
|
||||||
}
|
}
|
||||||
|
if (!preservedest)
|
||||||
|
{
|
||||||
|
QCC_FreeTemp(dest->base);
|
||||||
|
QCC_FreeTemp(dest->index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -9782,13 +9951,6 @@ QCC_sref_t QCC_StoreSRefToRef(QCC_ref_t *dest, QCC_sref_t source, pbool readable
|
||||||
preservedest = false;
|
preservedest = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// source = QCC_StoreToRef(
|
|
||||||
// QCC_PR_BuildRef(&tmp, REF_POINTER,
|
|
||||||
// QCC_PR_StatementFlags(&pr_opcodes[OP_ADDRESS], dest->base, dest->index, NULL, preservedest?STFL_PRESERVEA:0), //pointer address
|
|
||||||
// NULL, (dest->index->type->type == ev_field)?dest->index->type->aux_type:type_variant, dest->readonly),
|
|
||||||
// source, readable, false);
|
|
||||||
// QCC_PR_ParseWarning(ERR_INTERNAL, "FIXME: trying to do references: assignments to ent.field not supported.\n");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10268,6 +10430,12 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags)
|
||||||
ops_ptr = opcodes_divstorep;
|
ops_ptr = opcodes_divstorep;
|
||||||
opname = "/=";
|
opname = "/=";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ops = NULL;
|
||||||
|
ops_ptr = NULL;
|
||||||
|
opname = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ops)
|
if (ops)
|
||||||
{
|
{
|
||||||
|
@ -10286,6 +10454,7 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags)
|
||||||
if (conditional&1)
|
if (conditional&1)
|
||||||
QCC_PR_ParseWarning(WARN_ASSIGNMENTINCONDITIONAL, "suggest parenthesis for assignment used as truth value");
|
QCC_PR_ParseWarning(WARN_ASSIGNMENTINCONDITIONAL, "suggest parenthesis for assignment used as truth value");
|
||||||
|
|
||||||
|
//FIXME: if this is a simple store, rhsr->type == REF_FIELD, and lhsd is a simple def, then we should just expand the field directly to the lhsd for more effient .structs
|
||||||
rhsd = QCC_RefToDef(rhsr, true);
|
rhsd = QCC_RefToDef(rhsr, true);
|
||||||
|
|
||||||
if (ops_ptr && (lhsr->type == REF_FIELD || lhsr->type == REF_POINTER))
|
if (ops_ptr && (lhsr->type == REF_FIELD || lhsr->type == REF_POINTER))
|
||||||
|
@ -10363,7 +10532,8 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags)
|
||||||
else */if (QCC_SRef_IsNull(rhsd))
|
else */if (QCC_SRef_IsNull(rhsd))
|
||||||
{
|
{
|
||||||
QCC_FreeTemp(rhsd);
|
QCC_FreeTemp(rhsd);
|
||||||
if (lhsr->cast->type == ev_vector)
|
rhsd = QCC_MakeIntConst(0);
|
||||||
|
/*if (lhsr->cast->type == ev_vector)
|
||||||
rhsd = QCC_MakeVectorConst(0,0,0);
|
rhsd = QCC_MakeVectorConst(0,0,0);
|
||||||
else if (lhsr->cast->type == ev_struct || lhsr->cast->type == ev_union)
|
else if (lhsr->cast->type == ev_struct || lhsr->cast->type == ev_union)
|
||||||
{
|
{
|
||||||
|
@ -10375,7 +10545,7 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags)
|
||||||
rhsd = QCC_MakeIntConst(0);
|
rhsd = QCC_MakeIntConst(0);
|
||||||
else
|
else
|
||||||
rhsd = QCC_MakeIntConst(0);
|
rhsd = QCC_MakeIntConst(0);
|
||||||
rhsd.cast = lhsr->cast;
|
rhsd.cast = lhsr->cast;*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rhsd = QCC_SupplyConversionForAssignment(lhsr, rhsd, lhsr->cast, true);
|
rhsd = QCC_SupplyConversionForAssignment(lhsr, rhsd, lhsr->cast, true);
|
||||||
|
@ -12069,11 +12239,17 @@ void QCC_PR_ParseAsm(void)
|
||||||
else
|
else
|
||||||
a=nullsref;
|
a=nullsref;
|
||||||
if (pr_opcodes[op].type_b != &type_void)
|
if (pr_opcodes[op].type_b != &type_void)
|
||||||
|
{
|
||||||
|
QCC_PR_CheckToken(",");
|
||||||
b = QCC_PR_ParseValue(pr_classtype, false, false, true);
|
b = QCC_PR_ParseValue(pr_classtype, false, false, true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
b=nullsref;
|
b=nullsref;
|
||||||
if (pr_opcodes[op].associative==ASSOC_LEFT && pr_opcodes[op].type_c != &type_void)
|
if (pr_opcodes[op].associative==ASSOC_LEFT && pr_opcodes[op].type_c != &type_void)
|
||||||
|
{
|
||||||
|
QCC_PR_CheckToken(",");
|
||||||
c = QCC_PR_ParseValue(pr_classtype, false, false, true);
|
c = QCC_PR_ParseValue(pr_classtype, false, false, true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
c=nullsref;
|
c=nullsref;
|
||||||
|
|
||||||
|
@ -13637,10 +13813,11 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, QCC_def_t *arraydef, char *ar
|
||||||
// QCC_sref_t fasttrackpossible = nullsref;
|
// QCC_sref_t fasttrackpossible = nullsref;
|
||||||
int numslots;
|
int numslots;
|
||||||
|
|
||||||
if (thearray.cast->type == ev_vector)
|
|
||||||
numslots = thearray.sym->arraysize;
|
numslots = thearray.sym->arraysize;
|
||||||
else
|
if (!numslots)
|
||||||
numslots = thearray.sym->arraysize*thearray.cast->size;
|
numslots = 1;
|
||||||
|
if (thearray.cast->type != ev_vector)
|
||||||
|
numslots *= thearray.cast->size;
|
||||||
|
|
||||||
// if (flag_fasttrackarrays && numslots > 6)
|
// if (flag_fasttrackarrays && numslots > 6)
|
||||||
// fasttrackpossible = QCC_PR_GetSRef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
|
// fasttrackpossible = QCC_PR_GetSRef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
|
||||||
|
@ -14622,8 +14799,10 @@ static pbool QCC_PR_GenerateInitializerType(QCC_def_t *basedef, QCC_sref_t tmp,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QCC_sref_t rhs;
|
QCC_sref_t rhs;
|
||||||
|
pbool nullsource;
|
||||||
finalnotconst:
|
finalnotconst:
|
||||||
rhs = tmp;
|
rhs = tmp;
|
||||||
|
nullsource = QCC_SRef_IsNull(rhs);
|
||||||
if (def.sym->initialized)
|
if (def.sym->initialized)
|
||||||
QCC_PR_ParseErrorPrintSRef (ERR_REDECLARATION, def, "%s initialised twice", basedef->name);
|
QCC_PR_ParseErrorPrintSRef (ERR_REDECLARATION, def, "%s initialised twice", basedef->name);
|
||||||
|
|
||||||
|
@ -14635,17 +14814,20 @@ finalnotconst:
|
||||||
rhs.cast = def.cast = type_vector;
|
rhs.cast = def.cast = type_vector;
|
||||||
if (type->size - i == 3)
|
if (type->size - i == 3)
|
||||||
{
|
{
|
||||||
QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_V], rhs, def, NULL, STFL_PRESERVEB));
|
QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_V], nullsource?QCC_MakeVectorConst(0,0,0):rhs, def, NULL, STFL_PRESERVEB));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_V], rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB));
|
QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_V], nullsource?QCC_MakeVectorConst(0,0,0):rhs, def, NULL, STFL_PRESERVEA|STFL_PRESERVEB));
|
||||||
i+=3;
|
i+=3;
|
||||||
def.ofs += 3;
|
def.ofs += 3;
|
||||||
rhs.ofs += 3;
|
rhs.ofs += 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (nullsource)
|
||||||
|
rhs = QCC_MakeIntConst(0);
|
||||||
|
|
||||||
if (def.cast->type == ev_function)
|
if (def.cast->type == ev_function)
|
||||||
{
|
{
|
||||||
rhs.cast = def.cast = type_function;
|
rhs.cast = def.cast = type_function;
|
||||||
|
@ -14721,9 +14903,8 @@ finalnotconst:
|
||||||
QCC_FreeTemp(tmp);
|
QCC_FreeTemp(tmp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
//basedef can be null, meaning its initialising a temp
|
|
||||||
//returns true where its a const/static initialiser. false if non-const/final initialiser
|
QCC_sref_t QCC_PR_ParseInitializerType_Internal(int arraysize, QCC_def_t *basedef, QCC_sref_t def, unsigned int flags)
|
||||||
pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t def, unsigned int flags)
|
|
||||||
{
|
{
|
||||||
QCC_sref_t tmp;
|
QCC_sref_t tmp;
|
||||||
int i;
|
int i;
|
||||||
|
@ -14751,6 +14932,7 @@ pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
pbool isblock;
|
||||||
QCC_type_t *type = def.cast;
|
QCC_type_t *type = def.cast;
|
||||||
if (type->type == ev_function && pr_token_type == tt_punct)
|
if (type->type == ev_function && pr_token_type == tt_punct)
|
||||||
{
|
{
|
||||||
|
@ -14912,6 +15094,13 @@ pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t
|
||||||
{
|
{
|
||||||
pr_scope = parentfunc;
|
pr_scope = parentfunc;
|
||||||
tmp = QCC_MakeIntConst(f - functions);
|
tmp = QCC_MakeIntConst(f - functions);
|
||||||
|
|
||||||
|
if (!basedef && def.sym->temp)
|
||||||
|
{ //skip the store-to-temp
|
||||||
|
QCC_FreeTemp(def);
|
||||||
|
tmp.cast = def.cast;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type->type == ev_string && QCC_PR_CheckName("_"))
|
else if (type->type == ev_string && QCC_PR_CheckName("_"))
|
||||||
|
@ -14936,15 +15125,17 @@ pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t
|
||||||
}
|
}
|
||||||
QCC_PR_Lex();
|
QCC_PR_Lex();
|
||||||
QCC_PR_Expect(")");
|
QCC_PR_Expect(")");
|
||||||
return ret;
|
return ret?def:nullsref;
|
||||||
}
|
}
|
||||||
tmp = QCC_MakeTranslateStringConst(pr_immediate_string);
|
tmp = QCC_MakeTranslateStringConst(pr_immediate_string);
|
||||||
QCC_PR_Lex();
|
QCC_PR_Lex();
|
||||||
QCC_PR_Expect(")");
|
QCC_PR_Expect(")");
|
||||||
}
|
}
|
||||||
else if ((type->type == ev_struct && QCC_PR_CheckToken("{")) || (type->type == ev_union && ((type->num_parms == 1 && !type->params->paramname) || QCC_PR_CheckToken("{"))))
|
else if ((isblock=(type->type == ev_struct || type->type == ev_union) && QCC_PR_CheckToken("{"))
|
||||||
|
|| (type->type == ev_union && type->num_parms == 1 && !type->params->paramname))
|
||||||
{
|
{
|
||||||
//structs go recursive
|
//structs go recursive
|
||||||
|
QCC_type_t *parenttype;
|
||||||
unsigned int partnum;
|
unsigned int partnum;
|
||||||
pbool isunion;
|
pbool isunion;
|
||||||
gofs_t offset = def.ofs;
|
gofs_t offset = def.ofs;
|
||||||
|
@ -14954,7 +15145,7 @@ pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t
|
||||||
memset(isinited, 0, sizeof(pbool)*type->size);
|
memset(isinited, 0, sizeof(pbool)*type->size);
|
||||||
|
|
||||||
if (QCC_PR_PeekToken(".")) //won't be a float (.0 won't match)
|
if (QCC_PR_PeekToken(".")) //won't be a float (.0 won't match)
|
||||||
{
|
{ //designated initialisers
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if (QCC_PR_CheckToken("."))
|
if (QCC_PR_CheckToken("."))
|
||||||
|
@ -15003,39 +15194,43 @@ pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t
|
||||||
ret &= QCC_PR_ParseInitializerType((type)->params[partnum].arraysize, basedef, def, flags);
|
ret &= QCC_PR_ParseInitializerType((type)->params[partnum].arraysize, basedef, def, flags);
|
||||||
if (isunion || !QCC_PR_CheckToken(","))
|
if (isunion || !QCC_PR_CheckToken(","))
|
||||||
{
|
{
|
||||||
if (isunion && (type->num_parms == 1 && !type->params->paramname))
|
if (!isblock)
|
||||||
break;
|
break;
|
||||||
QCC_PR_Expect("}");
|
QCC_PR_Expect("}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (; type; type = type->parentclass)
|
|
||||||
|
for (parenttype=type; parenttype; parenttype = parenttype->parentclass)
|
||||||
{
|
{
|
||||||
for (partnum = 0; partnum < (type)->num_parms; partnum++)
|
for (partnum = 0; partnum < (parenttype)->num_parms; partnum++)
|
||||||
{
|
{
|
||||||
//copy into the def. should be from a const.
|
//copy into the def. should be from a const.
|
||||||
def.cast = (type)->params[partnum].type;
|
def.cast = (parenttype)->params[partnum].type;
|
||||||
def.ofs = (type)->params[partnum].ofs;
|
def.ofs = (parenttype)->params[partnum].ofs;
|
||||||
if (isinited[def.ofs])
|
if (isinited[def.ofs])
|
||||||
continue;
|
continue;
|
||||||
isinited[def.ofs] = true;
|
isinited[def.ofs] = true;
|
||||||
def.ofs += offset;
|
def.ofs += offset;
|
||||||
if ((type)->params[partnum].defltvalue.cast)
|
if ((parenttype)->params[partnum].defltvalue.cast)
|
||||||
tmp = (type)->params[partnum].defltvalue;
|
tmp = (parenttype)->params[partnum].defltvalue;
|
||||||
else
|
else
|
||||||
tmp = QCC_MakeIntConst(0);
|
tmp = QCC_MakeIntConst(0);
|
||||||
QCC_ForceUnFreeDef(tmp.sym);
|
QCC_ForceUnFreeDef(tmp.sym);
|
||||||
QCC_PR_GenerateInitializerType(basedef, tmp, def, def.cast, flags);
|
QCC_PR_GenerateInitializerType(basedef, tmp, def, def.cast, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
def.cast = type;
|
||||||
|
def.ofs = offset;
|
||||||
|
return ret?def:nullsref;
|
||||||
}
|
}
|
||||||
else if (type->type == ev_vector && QCC_PR_PeekToken("{"))
|
else if (type->type == ev_vector && QCC_PR_PeekToken("{"))
|
||||||
{ //vectors can be treated as an array of 3 floats.
|
{ //vectors can be treated as an array of 3 floats.
|
||||||
def.cast = type_float;
|
def.cast = type_float;
|
||||||
ret &= QCC_PR_ParseInitializerType(3, basedef, def, flags);
|
ret &= QCC_PR_ParseInitializerType(3, basedef, def, flags);
|
||||||
return ret;
|
def.cast = type;
|
||||||
|
return ret?def:nullsref;
|
||||||
}
|
}
|
||||||
else if (type->type == ev_pointer && QCC_PR_CheckToken("{"))
|
else if (type->type == ev_pointer && QCC_PR_CheckToken("{"))
|
||||||
{
|
{
|
||||||
|
@ -15086,7 +15281,22 @@ pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t
|
||||||
|
|
||||||
ret = QCC_PR_GenerateInitializerType(basedef, tmp, def, type, flags);
|
ret = QCC_PR_GenerateInitializerType(basedef, tmp, def, type, flags);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret?def:nullsref;
|
||||||
|
}
|
||||||
|
QCC_sref_t QCC_PR_ParseInitializerTemp(QCC_type_t *type)
|
||||||
|
{
|
||||||
|
QCC_sref_t def = QCC_GetTemp(type);
|
||||||
|
def = QCC_PR_ParseInitializerType_Internal(0, NULL, def, 0);
|
||||||
|
if (def.cast != type)
|
||||||
|
QCC_PR_ParseError(ERR_INTERNAL, "QCC_PR_ParseInitializerTemp changed type\n");
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
//returns true where its a const/static initialiser. false if non-const/final initialiser
|
||||||
|
pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t def, unsigned int flags)
|
||||||
|
{
|
||||||
|
if (QCC_PR_ParseInitializerType_Internal(arraysize, basedef, def, flags).cast)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QCC_PR_ParseInitializerDef(QCC_def_t *def, unsigned int flags)
|
void QCC_PR_ParseInitializerDef(QCC_def_t *def, unsigned int flags)
|
||||||
|
|
|
@ -5067,32 +5067,26 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
|
||||||
}
|
}
|
||||||
QCC_type_t *QCC_PR_PointerType (QCC_type_t *pointsto)
|
QCC_type_t *QCC_PR_PointerType (QCC_type_t *pointsto)
|
||||||
{
|
{
|
||||||
QCC_type_t *ptype, *e;
|
QCC_type_t *ptype;
|
||||||
char name[128];
|
char name[128];
|
||||||
if (pointsto->ptrto)
|
if (pointsto->ptrto)
|
||||||
return pointsto->ptrto;
|
return pointsto->ptrto;
|
||||||
QC_snprintfz(name, sizeof(name), "%s*", pointsto->name);
|
QC_snprintfz(name, sizeof(name), "%s*", pointsto->name);
|
||||||
ptype = QCC_PR_NewType(name, ev_pointer, false);
|
ptype = QCC_PR_NewType(strcpy(qccHunkAlloc(strlen(name)+1), name), ev_pointer, false);
|
||||||
ptype->aux_type = pointsto;
|
ptype->aux_type = pointsto;
|
||||||
e = QCC_PR_FindType (ptype);
|
return pointsto->ptrto = QCC_PR_FindType (ptype);
|
||||||
if (e == ptype)
|
|
||||||
{
|
|
||||||
char name[128];
|
|
||||||
QC_snprintfz(name, sizeof(name), "ptr to %s", pointsto->name);
|
|
||||||
e->name = strcpy(qccHunkAlloc(strlen(name)+1), name);
|
|
||||||
}
|
|
||||||
pointsto->ptrto = e;
|
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
QCC_type_t *QCC_PR_FieldType (QCC_type_t *pointsto)
|
QCC_type_t *QCC_PR_FieldType (QCC_type_t *pointsto)
|
||||||
{
|
{
|
||||||
QCC_type_t *ptype;
|
QCC_type_t *ptype;
|
||||||
char name[128];
|
char name[128];
|
||||||
QC_snprintfz(name, sizeof(name), "FIELD_TYPE(%s)", pointsto->name);
|
if (pointsto->fldto)
|
||||||
ptype = QCC_PR_NewType(name, ev_field, false);
|
return pointsto->fldto;
|
||||||
|
QC_snprintfz(name, sizeof(name), ".%s", pointsto->name);
|
||||||
|
ptype = QCC_PR_NewType(strcpy(qccHunkAlloc(strlen(name)+1), name), ev_field, false);
|
||||||
ptype->aux_type = pointsto;
|
ptype->aux_type = pointsto;
|
||||||
ptype->size = ptype->aux_type->size;
|
ptype->size = ptype->aux_type->size;
|
||||||
return QCC_PR_FindType (ptype);
|
return pointsto->fldto = QCC_PR_FindType (ptype);
|
||||||
}
|
}
|
||||||
QCC_type_t *QCC_PR_GenFunctionType (QCC_type_t *rettype, struct QCC_typeparam_s *args, int numargs)
|
QCC_type_t *QCC_PR_GenFunctionType (QCC_type_t *rettype, struct QCC_typeparam_s *args, int numargs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2482,8 +2482,8 @@ static void DebuggerStart(void)
|
||||||
qcdebugger->setWorkingDirectory(enginebasedir);
|
qcdebugger->setWorkingDirectory(enginebasedir);
|
||||||
qcdebugger->setArguments(QStringList(cmdline));
|
qcdebugger->setArguments(QStringList(cmdline));
|
||||||
|
|
||||||
QObject::connect(qcdebugger, static_cast<void(QProcess::*)(int)>(&QProcess::finished),
|
QObject::connect(qcdebugger, static_cast<void(QProcess::*)(int,QProcess::ExitStatus)>(&QProcess::finished),
|
||||||
[=](int exitcode)
|
[=](int exitcode,QProcess::ExitStatus status)
|
||||||
{
|
{
|
||||||
// GUIprintf("Debuggee finished\n");
|
// GUIprintf("Debuggee finished\n");
|
||||||
// DebuggerStop(); //can't kill it here, there's still code running inside it
|
// DebuggerStop(); //can't kill it here, there's still code running inside it
|
||||||
|
|
|
@ -2162,7 +2162,7 @@ strofs = (strofs+3)&~3;
|
||||||
}
|
}
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (((signed)a >= (signed)numpr_globals && statements[i].a.sym) || ((signed)b >= (signed)numpr_globals && statements[i].b.sym) || ((signed)c >= (signed)numpr_globals && statements[i].c.sym))
|
if (((signed)a >= (signed)numpr_globals && statements[i].a.sym) || ((signed)b >= (signed)numpr_globals && statements[i].b.sym) || ((signed)c >= (signed)numpr_globals && statements[i].c.sym))
|
||||||
externs->Printf("invalid offset on %s instruction\n", pr_opcodes[statements[i].op].opname);
|
externs->Printf("invalid offset on %s instruction (from line %i)\n", pr_opcodes[statements[i].op].opname, statements[i].linenum);
|
||||||
#endif
|
#endif
|
||||||
//truncate to 16bit. should probably warn if the high bits are not 0x0000 or 0xffff
|
//truncate to 16bit. should probably warn if the high bits are not 0x0000 or 0xffff
|
||||||
statements16[i].a = (unsigned short)PRLittleShort((unsigned short)a);
|
statements16[i].a = (unsigned short)PRLittleShort((unsigned short)a);
|
||||||
|
|
Loading…
Reference in a new issue