mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-17 09:41:21 +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)
|
||||
{
|
||||
Operand = operand;
|
||||
ValueType = operand->ValueType;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -357,9 +358,23 @@ FxExpression *FxParameter::Resolve(FCompileContext& ctx)
|
|||
{
|
||||
CHECKRESOLVED();
|
||||
SAFE_RESOLVE(Operand, ctx);
|
||||
ValueType = Operand->ValueType;
|
||||
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)
|
||||
{
|
||||
if (Operand->isConstant())
|
||||
|
@ -367,7 +382,7 @@ ExpEmit FxParameter::Emit(VMFunctionBuilder *build)
|
|||
ExpVal val = Operand->EvalExpression(NULL);
|
||||
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)
|
||||
{
|
||||
|
@ -398,6 +413,7 @@ ExpEmit FxParameter::Emit(VMFunctionBuilder *build)
|
|||
else
|
||||
{
|
||||
build->Emit(OP_PARAM, 0, where.RegType, where.RegNum);
|
||||
build->FreeReg(where.RegType, where.RegNum);
|
||||
}
|
||||
}
|
||||
return ExpEmit();
|
||||
|
@ -2366,8 +2382,8 @@ FxRandom::FxRandom(FRandom * r, FxExpression *mi, FxExpression *ma, const FScrip
|
|||
{
|
||||
if (mi != NULL && ma != NULL)
|
||||
{
|
||||
min = new FxIntCast(mi);
|
||||
max = new FxIntCast(ma);
|
||||
min = new FxParameter(new FxIntCast(mi));
|
||||
max = new FxParameter(new FxIntCast(ma));
|
||||
}
|
||||
else min = max = NULL;
|
||||
rng = r;
|
||||
|
@ -2397,17 +2413,11 @@ FxExpression *FxRandom::Resolve(FCompileContext &ctx)
|
|||
CHECKRESOLVED();
|
||||
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(max, ctx);
|
||||
ABORT(min && max);
|
||||
assert(min->ValueType == VAL_Int);
|
||||
assert(max->ValueType == VAL_Int);
|
||||
}
|
||||
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));
|
||||
if (min != NULL && max != NULL)
|
||||
{
|
||||
ExpEmit op = min->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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
min->Emit(build);
|
||||
max->Emit(build);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1);
|
||||
}
|
||||
else
|
||||
|
@ -2532,8 +2522,8 @@ FxFRandom::FxFRandom(FRandom *r, FxExpression *mi, FxExpression *ma, const FScri
|
|||
{
|
||||
if (mi != NULL && ma != NULL)
|
||||
{
|
||||
min = mi;
|
||||
max = ma;
|
||||
min = new FxParameter(new FxFloatCast(mi));
|
||||
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));
|
||||
if (min != NULL && max != NULL)
|
||||
{
|
||||
ExpEmit op = min->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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
min->Emit(build);
|
||||
max->Emit(build);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1);
|
||||
}
|
||||
else
|
||||
|
@ -2659,6 +2629,7 @@ FxRandom2::FxRandom2(FRandom *r, FxExpression *m, const FScriptPosition &pos)
|
|||
rng = r;
|
||||
if (m) mask = new FxIntCast(m);
|
||||
else mask = new FxConstant(-1, pos);
|
||||
mask = new FxParameter(mask);
|
||||
ValueType = VAL_Int;
|
||||
}
|
||||
|
||||
|
@ -2721,17 +2692,7 @@ ExpEmit FxRandom2::Emit(VMFunctionBuilder *build)
|
|||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG));
|
||||
ExpEmit op = 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);
|
||||
}
|
||||
mask->Emit(build);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2, 1);
|
||||
ExpEmit out(build, REGT_INT);
|
||||
build->Emit(OP_RESULT, 0, REGT_INT, out.RegNum);
|
||||
|
@ -3513,17 +3474,22 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build)
|
|||
assert(Self == NULL);
|
||||
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
|
||||
if (ArgList != NULL)
|
||||
{
|
||||
for (; i < ArgList->Size(); ++i)
|
||||
{
|
||||
ExpEmit arg((*ArgList)[i]->Emit(build));
|
||||
assert(arg.RegType == REGT_INT);
|
||||
build->Emit(OP_PARAM, 0, arg.RegType | (arg.Konst ? REGT_KONST : 0), arg.RegNum);
|
||||
if (!arg.Konst)
|
||||
FxExpression *argex = (*ArgList)[i];
|
||||
assert(argex->ValueType == VAL_Int);
|
||||
if (argex->isConstant())
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -3991,7 +3957,7 @@ ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build)
|
|||
build->Emit(OP_PARAM, 0, REGT_POINTER, 0); // pass self
|
||||
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
|
||||
|
|
|
@ -465,6 +465,10 @@ size_t VMFunctionBuilder::Emit(int opcode, int opabc)
|
|||
#else
|
||||
*(VM_UWORD *)&Code[loc] = opcode | (opabc << 8);
|
||||
#endif
|
||||
if (opcode == OP_PARAMI)
|
||||
{
|
||||
ParamChange(1);
|
||||
}
|
||||
return loc / 4;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,8 +95,10 @@ const VMOpInfo OpInfo[NUM_OPS] =
|
|||
};
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define ABCs(x) ((*(VM_SWORD *)(x) << 8) >> 8)
|
||||
#define JMPOFS(x) ((*(VM_SWORD *)(x) << 8) >> 6)
|
||||
#else
|
||||
#define ABCs(x) (*(VM_SWORD *)(x) >> 8)
|
||||
#define JMPOFS(x) ((*(VM_SWORD *)(x) >> 6) & ~3)
|
||||
#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]));
|
||||
break;
|
||||
|
||||
case OP_PARAMI:
|
||||
col = printf_wrapper(out, "%d", i + 4 + ABCs(&code[i]));
|
||||
break;
|
||||
|
||||
case OP_RET:
|
||||
if (code[i+2] != REGT_NIL)
|
||||
{
|
||||
|
|
|
@ -25,8 +25,10 @@
|
|||
#define BCs (*(VM_SHALF *)(pc - 2))
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define ABCs ((*(VM_SWORD *)(pc - 4) << 8) >> 8)
|
||||
#define JMPOFS(x) ((*(VM_SWORD *)(x) << 8) >> 6)
|
||||
#else
|
||||
#define ABCs (*(VM_SWORD *)(pc - 4) >> 8)
|
||||
#define JMPOFS(x) ((*(VM_SWORD *)(x) >> 6) & ~3)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -395,6 +395,13 @@ begin:
|
|||
assert(*pc == OP_JMP);
|
||||
pc += (1 + *((VM_SHALF *)pc + 1)) << 2;
|
||||
NEXTOP;
|
||||
OP(PARAMI):
|
||||
assert(f->NumParam < sfunc->MaxParam);
|
||||
{
|
||||
VMValue *param = ®.param[f->NumParam++];
|
||||
::new(param) VMValue(ABCs);
|
||||
}
|
||||
NEXTOP;
|
||||
OP(PARAM):
|
||||
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(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(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_K, call, KPI8I8),
|
||||
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(ADD_RR, add, RIRIRI), // dA = dB + dkC
|
||||
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_RK, sub, RIRIKI),
|
||||
xx(SUB_KR, sub, RIKIRI),
|
||||
|
|
Loading…
Reference in a new issue