mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-07 13:30:19 +00:00
- Added PARAMI for the common case of passing an integer constant to a function.
- Made FxParameter::Emit free its operand's register. SVN r1918 (scripting)
This commit is contained in:
parent
caa5f6dbdc
commit
126c738116
6 changed files with 61 additions and 75 deletions
|
@ -334,6 +334,7 @@ FxParameter::FxParameter(FxExpression *operand)
|
||||||
: FxExpression(operand->ScriptPosition)
|
: FxExpression(operand->ScriptPosition)
|
||||||
{
|
{
|
||||||
Operand = operand;
|
Operand = operand;
|
||||||
|
ValueType = operand->ValueType;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -357,9 +358,23 @@ FxExpression *FxParameter::Resolve(FCompileContext& ctx)
|
||||||
{
|
{
|
||||||
CHECKRESOLVED();
|
CHECKRESOLVED();
|
||||||
SAFE_RESOLVE(Operand, ctx);
|
SAFE_RESOLVE(Operand, ctx);
|
||||||
|
ValueType = Operand->ValueType;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void EmitConstantInt(VMFunctionBuilder *build, int val)
|
||||||
|
{
|
||||||
|
// If it fits in 24 bits, use PARAMI instead of PARAM.
|
||||||
|
if ((val << 8) >> 8)
|
||||||
|
{
|
||||||
|
build->Emit(OP_PARAMI, val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
build->Emit(OP_PARAM, 0, REGT_INT | REGT_KONST, build->GetConstantInt(val));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ExpEmit FxParameter::Emit(VMFunctionBuilder *build)
|
ExpEmit FxParameter::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
if (Operand->isConstant())
|
if (Operand->isConstant())
|
||||||
|
@ -367,7 +382,7 @@ ExpEmit FxParameter::Emit(VMFunctionBuilder *build)
|
||||||
ExpVal val = Operand->EvalExpression(NULL);
|
ExpVal val = Operand->EvalExpression(NULL);
|
||||||
if (val.Type == VAL_Int || val.Type == VAL_Sound || val.Type == VAL_Name || val.Type == VAL_Color)
|
if (val.Type == VAL_Int || val.Type == VAL_Sound || val.Type == VAL_Name || val.Type == VAL_Color)
|
||||||
{
|
{
|
||||||
build->Emit(OP_PARAM, 0, REGT_INT | REGT_KONST, build->GetConstantInt(val.Int));
|
EmitConstantInt(build, val.Int);
|
||||||
}
|
}
|
||||||
else if (val.Type == VAL_Float)
|
else if (val.Type == VAL_Float)
|
||||||
{
|
{
|
||||||
|
@ -398,6 +413,7 @@ ExpEmit FxParameter::Emit(VMFunctionBuilder *build)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
build->Emit(OP_PARAM, 0, where.RegType, where.RegNum);
|
build->Emit(OP_PARAM, 0, where.RegType, where.RegNum);
|
||||||
|
build->FreeReg(where.RegType, where.RegNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ExpEmit();
|
return ExpEmit();
|
||||||
|
@ -2366,8 +2382,8 @@ FxRandom::FxRandom(FRandom * r, FxExpression *mi, FxExpression *ma, const FScrip
|
||||||
{
|
{
|
||||||
if (mi != NULL && ma != NULL)
|
if (mi != NULL && ma != NULL)
|
||||||
{
|
{
|
||||||
min = new FxIntCast(mi);
|
min = new FxParameter(new FxIntCast(mi));
|
||||||
max = new FxIntCast(ma);
|
max = new FxParameter(new FxIntCast(ma));
|
||||||
}
|
}
|
||||||
else min = max = NULL;
|
else min = max = NULL;
|
||||||
rng = r;
|
rng = r;
|
||||||
|
@ -2397,17 +2413,11 @@ FxExpression *FxRandom::Resolve(FCompileContext &ctx)
|
||||||
CHECKRESOLVED();
|
CHECKRESOLVED();
|
||||||
if (min && max)
|
if (min && max)
|
||||||
{
|
{
|
||||||
if (min->ValueType != VAL_Int)
|
|
||||||
{
|
|
||||||
min = new FxIntCast(min);
|
|
||||||
}
|
|
||||||
if (max->ValueType != VAL_Int)
|
|
||||||
{
|
|
||||||
max = new FxIntCast(max);
|
|
||||||
}
|
|
||||||
RESOLVE(min, ctx);
|
RESOLVE(min, ctx);
|
||||||
RESOLVE(max, ctx);
|
RESOLVE(max, ctx);
|
||||||
ABORT(min && max);
|
ABORT(min && max);
|
||||||
|
assert(min->ValueType == VAL_Int);
|
||||||
|
assert(max->ValueType == VAL_Int);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
@ -2489,28 +2499,8 @@ ExpEmit FxRandom::Emit(VMFunctionBuilder *build)
|
||||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG));
|
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG));
|
||||||
if (min != NULL && max != NULL)
|
if (min != NULL && max != NULL)
|
||||||
{
|
{
|
||||||
ExpEmit op = min->Emit(build);
|
min->Emit(build);
|
||||||
assert(op.RegType == REGT_INT);
|
max->Emit(build);
|
||||||
if (op.Konst)
|
|
||||||
{
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_INT | REGT_KONST, op.RegNum);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
build->FreeReg(REGT_INT, op.RegNum);
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_INT, op.RegNum);
|
|
||||||
}
|
|
||||||
op = max->Emit(build);
|
|
||||||
assert(op.RegType == REGT_INT);
|
|
||||||
if (op.Konst)
|
|
||||||
{
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_INT | REGT_KONST, op.RegNum);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
build->FreeReg(REGT_INT, op.RegNum);
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_INT, op.RegNum);
|
|
||||||
}
|
|
||||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1);
|
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2532,8 +2522,8 @@ FxFRandom::FxFRandom(FRandom *r, FxExpression *mi, FxExpression *ma, const FScri
|
||||||
{
|
{
|
||||||
if (mi != NULL && ma != NULL)
|
if (mi != NULL && ma != NULL)
|
||||||
{
|
{
|
||||||
min = mi;
|
min = new FxParameter(new FxFloatCast(mi));
|
||||||
max = ma;
|
max = new FxParameter(new FxFloatCast(ma));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2614,28 +2604,8 @@ ExpEmit FxFRandom::Emit(VMFunctionBuilder *build)
|
||||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG));
|
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG));
|
||||||
if (min != NULL && max != NULL)
|
if (min != NULL && max != NULL)
|
||||||
{
|
{
|
||||||
ExpEmit op = min->Emit(build);
|
min->Emit(build);
|
||||||
assert(op.RegType == REGT_FLOAT);
|
max->Emit(build);
|
||||||
if (op.Konst)
|
|
||||||
{
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, op.RegNum);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
build->FreeReg(REGT_FLOAT, op.RegNum);
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_FLOAT, op.RegNum);
|
|
||||||
}
|
|
||||||
op = max->Emit(build);
|
|
||||||
assert(op.RegType == REGT_FLOAT);
|
|
||||||
if (op.Konst)
|
|
||||||
{
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, op.RegNum);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
build->FreeReg(REGT_FLOAT, op.RegNum);
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_FLOAT, op.RegNum);
|
|
||||||
}
|
|
||||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1);
|
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2659,6 +2629,7 @@ FxRandom2::FxRandom2(FRandom *r, FxExpression *m, const FScriptPosition &pos)
|
||||||
rng = r;
|
rng = r;
|
||||||
if (m) mask = new FxIntCast(m);
|
if (m) mask = new FxIntCast(m);
|
||||||
else mask = new FxConstant(-1, pos);
|
else mask = new FxConstant(-1, pos);
|
||||||
|
mask = new FxParameter(mask);
|
||||||
ValueType = VAL_Int;
|
ValueType = VAL_Int;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2721,17 +2692,7 @@ ExpEmit FxRandom2::Emit(VMFunctionBuilder *build)
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG));
|
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG));
|
||||||
ExpEmit op = mask->Emit(build);
|
mask->Emit(build);
|
||||||
assert(op.RegType == REGT_INT);
|
|
||||||
if (op.Konst)
|
|
||||||
{
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_INT | REGT_KONST, op.RegNum);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
build->FreeReg(REGT_INT, op.RegNum);
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_INT, op.RegNum);
|
|
||||||
}
|
|
||||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2, 1);
|
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2, 1);
|
||||||
ExpEmit out(build, REGT_INT);
|
ExpEmit out(build, REGT_INT);
|
||||||
build->Emit(OP_RESULT, 0, REGT_INT, out.RegNum);
|
build->Emit(OP_RESULT, 0, REGT_INT, out.RegNum);
|
||||||
|
@ -3513,17 +3474,22 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build)
|
||||||
assert(Self == NULL);
|
assert(Self == NULL);
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
|
|
||||||
build->Emit(OP_PARAM, 0, REGT_INT | REGT_KONST, build->GetConstantInt(Special)); // pass special number
|
build->Emit(OP_PARAMI, Special); // pass special number
|
||||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 0); // pass self
|
build->Emit(OP_PARAM, 0, REGT_POINTER, 0); // pass self
|
||||||
if (ArgList != NULL)
|
if (ArgList != NULL)
|
||||||
{
|
{
|
||||||
for (; i < ArgList->Size(); ++i)
|
for (; i < ArgList->Size(); ++i)
|
||||||
{
|
{
|
||||||
ExpEmit arg((*ArgList)[i]->Emit(build));
|
FxExpression *argex = (*ArgList)[i];
|
||||||
assert(arg.RegType == REGT_INT);
|
assert(argex->ValueType == VAL_Int);
|
||||||
build->Emit(OP_PARAM, 0, arg.RegType | (arg.Konst ? REGT_KONST : 0), arg.RegNum);
|
if (argex->isConstant())
|
||||||
if (!arg.Konst)
|
|
||||||
{
|
{
|
||||||
|
EmitConstantInt(build, argex->EvalExpression(NULL).GetInt());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExpEmit arg(argex->Emit(build));
|
||||||
|
build->Emit(OP_PARAM, 0, arg.RegType, arg.RegNum);
|
||||||
build->FreeReg(arg.RegType, arg.RegNum);
|
build->FreeReg(arg.RegType, arg.RegNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3991,7 +3957,7 @@ ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build)
|
||||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 0); // pass self
|
build->Emit(OP_PARAM, 0, REGT_POINTER, 0); // pass self
|
||||||
for (unsigned i = 0; i < names.Size(); ++i)
|
for (unsigned i = 0; i < names.Size(); ++i)
|
||||||
{
|
{
|
||||||
build->Emit(OP_PARAM, 0, REGT_INT | REGT_KONST, build->GetConstantInt(names[i]));
|
EmitConstantInt(build, names[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the DecoFindMultiNameState function. If not found, create it and install it
|
// Find the DecoFindMultiNameState function. If not found, create it and install it
|
||||||
|
|
|
@ -465,6 +465,10 @@ size_t VMFunctionBuilder::Emit(int opcode, int opabc)
|
||||||
#else
|
#else
|
||||||
*(VM_UWORD *)&Code[loc] = opcode | (opabc << 8);
|
*(VM_UWORD *)&Code[loc] = opcode | (opabc << 8);
|
||||||
#endif
|
#endif
|
||||||
|
if (opcode == OP_PARAMI)
|
||||||
|
{
|
||||||
|
ParamChange(1);
|
||||||
|
}
|
||||||
return loc / 4;
|
return loc / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,8 +95,10 @@ const VMOpInfo OpInfo[NUM_OPS] =
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
#define ABCs(x) ((*(VM_SWORD *)(x) << 8) >> 8)
|
||||||
#define JMPOFS(x) ((*(VM_SWORD *)(x) << 8) >> 6)
|
#define JMPOFS(x) ((*(VM_SWORD *)(x) << 8) >> 6)
|
||||||
#else
|
#else
|
||||||
|
#define ABCs(x) (*(VM_SWORD *)(x) >> 8)
|
||||||
#define JMPOFS(x) ((*(VM_SWORD *)(x) >> 6) & ~3)
|
#define JMPOFS(x) ((*(VM_SWORD *)(x) >> 6) & ~3)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -214,6 +216,10 @@ void VMDisasm(FILE *out, const VM_UBYTE *code, int codesize, const VMScriptFunct
|
||||||
col = printf_wrapper(out, "%08x", i + 4 + JMPOFS(&code[i]));
|
col = printf_wrapper(out, "%08x", i + 4 + JMPOFS(&code[i]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OP_PARAMI:
|
||||||
|
col = printf_wrapper(out, "%d", i + 4 + ABCs(&code[i]));
|
||||||
|
break;
|
||||||
|
|
||||||
case OP_RET:
|
case OP_RET:
|
||||||
if (code[i+2] != REGT_NIL)
|
if (code[i+2] != REGT_NIL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,8 +25,10 @@
|
||||||
#define BCs (*(VM_SHALF *)(pc - 2))
|
#define BCs (*(VM_SHALF *)(pc - 2))
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
#define ABCs ((*(VM_SWORD *)(pc - 4) << 8) >> 8)
|
||||||
#define JMPOFS(x) ((*(VM_SWORD *)(x) << 8) >> 6)
|
#define JMPOFS(x) ((*(VM_SWORD *)(x) << 8) >> 6)
|
||||||
#else
|
#else
|
||||||
|
#define ABCs (*(VM_SWORD *)(pc - 4) >> 8)
|
||||||
#define JMPOFS(x) ((*(VM_SWORD *)(x) >> 6) & ~3)
|
#define JMPOFS(x) ((*(VM_SWORD *)(x) >> 6) & ~3)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -395,6 +395,13 @@ begin:
|
||||||
assert(*pc == OP_JMP);
|
assert(*pc == OP_JMP);
|
||||||
pc += (1 + *((VM_SHALF *)pc + 1)) << 2;
|
pc += (1 + *((VM_SHALF *)pc + 1)) << 2;
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
|
OP(PARAMI):
|
||||||
|
assert(f->NumParam < sfunc->MaxParam);
|
||||||
|
{
|
||||||
|
VMValue *param = ®.param[f->NumParam++];
|
||||||
|
::new(param) VMValue(ABCs);
|
||||||
|
}
|
||||||
|
NEXTOP;
|
||||||
OP(PARAM):
|
OP(PARAM):
|
||||||
assert(f->NumParam < sfunc->MaxParam);
|
assert(f->NumParam < sfunc->MaxParam);
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,6 +74,7 @@ xx(TEST, test, RII16), // if (dA != BC) then pc++
|
||||||
xx(JMP, jmp, I24), // pc += ABC -- The ABC fields contain a signed 24-bit offset.
|
xx(JMP, jmp, I24), // pc += ABC -- The ABC fields contain a signed 24-bit offset.
|
||||||
xx(IJMP, ijmp, RII16), // pc += dA + BC -- BC is a signed offset. The target instruction must be a JMP.
|
xx(IJMP, ijmp, RII16), // pc += dA + BC -- BC is a signed offset. The target instruction must be a JMP.
|
||||||
xx(PARAM, param, __BCP), // push parameter encoded in BC for function call (B=regtype, C=regnum)
|
xx(PARAM, param, __BCP), // push parameter encoded in BC for function call (B=regtype, C=regnum)
|
||||||
|
xx(PARAMI, parami, I24), // push immediate, signed integer for function call
|
||||||
xx(CALL, call, RPI8I8), // Call function pkA with parameter count B and expected result count C
|
xx(CALL, call, RPI8I8), // Call function pkA with parameter count B and expected result count C
|
||||||
xx(CALL_K, call, KPI8I8),
|
xx(CALL_K, call, KPI8I8),
|
||||||
xx(RESULT, result, __BCP), // Result should go in register encoded in BC (in caller, after CALL)
|
xx(RESULT, result, __BCP), // Result should go in register encoded in BC (in caller, after CALL)
|
||||||
|
@ -106,7 +107,7 @@ xx(SRA_RI, sra, RIRII8),
|
||||||
xx(SRA_KR, sra, RIKIRI),
|
xx(SRA_KR, sra, RIKIRI),
|
||||||
xx(ADD_RR, add, RIRIRI), // dA = dB + dkC
|
xx(ADD_RR, add, RIRIRI), // dA = dB + dkC
|
||||||
xx(ADD_RK, add, RIRIKI),
|
xx(ADD_RK, add, RIRIKI),
|
||||||
xx(ADDI, add, RIRIIs), // dA = dB + C -- C is a signed 8-bit constant
|
xx(ADDI, addi, RIRIIs), // dA = dB + C -- C is a signed 8-bit constant
|
||||||
xx(SUB_RR, sub, RIRIRI), // dA = dkB - dkC
|
xx(SUB_RR, sub, RIRIRI), // dA = dkB - dkC
|
||||||
xx(SUB_RK, sub, RIRIKI),
|
xx(SUB_RK, sub, RIRIKI),
|
||||||
xx(SUB_KR, sub, RIKIRI),
|
xx(SUB_KR, sub, RIKIRI),
|
||||||
|
|
Loading…
Reference in a new issue