- backend update from GZDoom.

This commit is contained in:
Christoph Oelckers 2022-06-25 10:39:49 +02:00
parent 30b81c0920
commit eb8fae761e
25 changed files with 416 additions and 94 deletions

View file

@ -1688,6 +1688,13 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
delete this;
return x;
}
else if ((basex->IsVector2() && IsVector2()) || (basex->IsVector3() && IsVector3()))
{
auto x = basex;
basex = nullptr;
delete this;
return x;
}
// todo: pointers to class objects.
// All other types are only compatible to themselves and have already been handled above by the equality check.
// Anything that falls through here is not compatible and must print an error.
@ -2587,6 +2594,12 @@ FxExpression *FxMultiAssign::Resolve(FCompileContext &ctx)
}
auto VMRight = static_cast<FxVMFunctionCall *>(Right);
auto rets = VMRight->GetReturnTypes();
if (Base.Size() == 1)
{
Right->ScriptPosition.Message(MSG_ERROR, "Multi-assignment with only one element", VMRight->Function->SymbolName.GetChars());
delete this;
return nullptr;
}
if (rets.Size() < Base.Size())
{
Right->ScriptPosition.Message(MSG_ERROR, "Insufficient returns in function %s", VMRight->Function->SymbolName.GetChars());
@ -2764,7 +2777,7 @@ FxExpression *FxAddSub::Resolve(FCompileContext& ctx)
else if (left->IsVector() && right->IsVector())
{
// a vector2 can be added to or subtracted from a vector 3 but it needs to be the right operand.
if (left->ValueType == right->ValueType || (left->ValueType == TypeVector3 && right->ValueType == TypeVector2))
if (left->ValueType == right->ValueType || (left->IsVector3() && right->IsVector2()))
{
ValueType = left->ValueType;
}
@ -2857,8 +2870,9 @@ ExpEmit FxAddSub::Emit(VMFunctionBuilder *build)
if (IsVector())
{
assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT);
build->Emit(right->ValueType == TypeVector2? OP_ADDV2_RR : OP_ADDV3_RR, to.RegNum, op1.RegNum, op2.RegNum);
if (left->ValueType == TypeVector3 && right->ValueType == TypeVector2 && to.RegNum != op1.RegNum)
build->Emit(right->IsVector2() ? OP_ADDV2_RR : OP_ADDV3_RR, to.RegNum, op1.RegNum, op2.RegNum);
if (left->IsVector3() && right->IsVector2() && to.RegNum != op1.RegNum)
{
// must move the z-coordinate
build->Emit(OP_MOVEF, to.RegNum + 2, op1.RegNum + 2);
@ -2890,7 +2904,7 @@ ExpEmit FxAddSub::Emit(VMFunctionBuilder *build)
if (IsVector())
{
assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT);
build->Emit(right->ValueType == TypeVector2 ? OP_SUBV2_RR : OP_SUBV3_RR, to.RegNum, op1.RegNum, op2.RegNum);
build->Emit(right->IsVector2() ? OP_SUBV2_RR : OP_SUBV3_RR, to.RegNum, op1.RegNum, op2.RegNum);
return to;
}
else if (ValueType->GetRegType() == REGT_FLOAT)
@ -3093,11 +3107,11 @@ ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build)
int op;
if (op2.Konst)
{
op = Operator == '*' ? (ValueType == TypeVector2 ? OP_MULVF2_RK : OP_MULVF3_RK) : (ValueType == TypeVector2 ? OP_DIVVF2_RK : OP_DIVVF3_RK);
op = Operator == '*' ? (IsVector2() ? OP_MULVF2_RK : OP_MULVF3_RK) : (IsVector2() ? OP_DIVVF2_RK : OP_DIVVF3_RK);
}
else
{
op = Operator == '*' ? (ValueType == TypeVector2 ? OP_MULVF2_RR : OP_MULVF3_RR) : (ValueType == TypeVector2 ? OP_DIVVF2_RR : OP_DIVVF3_RR);
op = Operator == '*' ? (IsVector2() ? OP_MULVF2_RR : OP_MULVF3_RR) : (IsVector2() ? OP_DIVVF2_RR : OP_DIVVF3_RR);
}
op1.Free(build);
op2.Free(build);
@ -9067,13 +9081,13 @@ ExpEmit FxVectorBuiltin::Emit(VMFunctionBuilder *build)
ExpEmit op = Self->Emit(build);
if (Function == NAME_Length)
{
build->Emit(Self->ValueType == TypeVector2 ? OP_LENV2 : OP_LENV3, to.RegNum, op.RegNum);
build->Emit(Self->ValueType == TypeVector2 || Self->ValueType == TypeFVector2 ? OP_LENV2 : OP_LENV3, to.RegNum, op.RegNum);
}
else
{
ExpEmit len(build, REGT_FLOAT);
build->Emit(Self->ValueType == TypeVector2 ? OP_LENV2 : OP_LENV3, len.RegNum, op.RegNum);
build->Emit(Self->ValueType == TypeVector2 ? OP_DIVVF2_RR : OP_DIVVF3_RR, to.RegNum, op.RegNum, len.RegNum);
build->Emit(Self->ValueType == TypeVector2 || Self->ValueType == TypeFVector2 ? OP_LENV2 : OP_LENV3, len.RegNum, op.RegNum);
build->Emit(Self->ValueType == TypeVector2 || Self->ValueType == TypeFVector2 ? OP_DIVVF2_RR : OP_DIVVF3_RR, to.RegNum, op.RegNum, len.RegNum);
len.Free(build);
}
op.Free(build);
@ -10734,6 +10748,10 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build)
FxLocalVariableDeclaration::FxLocalVariableDeclaration(PType *type, FName name, FxExpression *initval, int varflags, const FScriptPosition &p)
:FxExpression(EFX_LocalVariableDeclaration, p)
{
// Local FVector isn't different from Vector
if (type == TypeFVector2) type = TypeVector2;
else if (type == TypeFVector3) type = TypeVector3;
ValueType = type;
VarFlags = varflags;
Name = name;

View file

@ -336,7 +336,9 @@ public:
bool IsFloat() const { return ValueType->isFloat(); }
bool IsInteger() const { return ValueType->isNumeric() && ValueType->isIntCompatible(); }
bool IsPointer() const { return ValueType->isPointer(); }
bool IsVector() const { return ValueType == TypeVector2 || ValueType == TypeVector3; };
bool IsVector() const { return ValueType == TypeVector2 || ValueType == TypeVector3 || ValueType == TypeFVector2 || ValueType == TypeFVector3; };
bool IsVector2() const { return ValueType == TypeVector2 || ValueType == TypeFVector2; };
bool IsVector3() const { return ValueType == TypeVector3 || ValueType == TypeFVector3; };
bool IsBoolCompat() const { return ValueType->isScalar(); }
bool IsObject() const { return ValueType->isObjectPointer(); }
bool IsArray() const { return ValueType->isArray() || (ValueType->isPointer() && ValueType->toPointer()->PointedType->isArray()); }