mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-16 01:02:03 +00:00
- same as last commit for FxMulDiv and FxPow.
- some streamlining of FxAddSub.
This commit is contained in:
parent
a00181c899
commit
b6801d526b
1 changed files with 117 additions and 72 deletions
|
@ -2417,39 +2417,6 @@ bool FxBinary::ResolveLR(FCompileContext& ctx, bool castnumeric)
|
|||
{
|
||||
switch (Operator)
|
||||
{
|
||||
case '/':
|
||||
if (right->IsVector())
|
||||
{
|
||||
// For division, the vector must be the first operand.
|
||||
ScriptPosition.Message(MSG_ERROR, "Incompatible operands for division");
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
case '*':
|
||||
if (left->IsVector())
|
||||
{
|
||||
right = new FxFloatCast(right);
|
||||
right = right->Resolve(ctx);
|
||||
if (right == nullptr)
|
||||
{
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
ValueType = left->ValueType;
|
||||
}
|
||||
else
|
||||
{
|
||||
left = new FxFloatCast(left);
|
||||
left = left->Resolve(ctx);
|
||||
if (left == nullptr)
|
||||
{
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
ValueType = right->ValueType;
|
||||
}
|
||||
break;
|
||||
|
||||
case TK_Eq:
|
||||
case TK_Neq:
|
||||
if (left->ValueType != right->ValueType)
|
||||
|
@ -2540,15 +2507,34 @@ bool FxBinary::ResolveLR(FCompileContext& ctx, bool castnumeric)
|
|||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FxBinary::Promote(FCompileContext &ctx)
|
||||
{
|
||||
if (left->ValueType->GetRegType() == REGT_FLOAT && right->ValueType->GetRegType() == REGT_INT)
|
||||
// math operations of unsigned ints results in an unsigned int. (16 and 8 bit values never get here, they get promoted to regular ints elsewhere already.)
|
||||
if (left->ValueType == TypeUInt32 && right->ValueType == TypeUInt32)
|
||||
{
|
||||
right = (new FxFloatCast(right))->Resolve(ctx);
|
||||
ValueType = TypeUInt32;
|
||||
}
|
||||
else if (left->ValueType->GetRegType() == REGT_INT && right->ValueType->GetRegType() == REGT_FLOAT)
|
||||
else if (left->IsInteger() && right->IsInteger())
|
||||
{
|
||||
left = (new FxFloatCast(left))->Resolve(ctx);
|
||||
ValueType = TypeSInt32; // Addition and subtraction forces all integer-derived types to signed int.
|
||||
}
|
||||
else
|
||||
{
|
||||
ValueType = TypeFloat64;
|
||||
if (left->IsFloat() && right->IsInteger())
|
||||
{
|
||||
right = (new FxFloatCast(right))->Resolve(ctx);
|
||||
}
|
||||
else if (left->IsInteger() && right->IsFloat())
|
||||
{
|
||||
left = (new FxFloatCast(left))->Resolve(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2590,34 +2576,17 @@ FxExpression *FxAddSub::Resolve(FCompileContext& ctx)
|
|||
}
|
||||
else
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Incompatible operands for %s", Operator == '+' ? "addition" : "subtraction");
|
||||
delete this;
|
||||
return nullptr;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (left->IsNumeric() && right->IsNumeric())
|
||||
{
|
||||
// Addition and subtraction of unsigned ints results in an unsigned int. (16 and 8 bit values never get here, they get promoted to regular ints elsewhere already.)
|
||||
if (left->ValueType == TypeUInt32 && right->ValueType == TypeUInt32)
|
||||
{
|
||||
ValueType = TypeUInt32;
|
||||
}
|
||||
else if (left->ValueType->GetRegType() == REGT_INT && right->ValueType->GetRegType() == REGT_INT)
|
||||
{
|
||||
ValueType = TypeSInt32; // Addition and subtraction forces all integer-derived types to signed int.
|
||||
}
|
||||
else
|
||||
{
|
||||
ValueType = TypeFloat64;
|
||||
Promote(ctx);
|
||||
}
|
||||
Promote(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
// To check: It may be that this could pass in DECORATE, although setting TypeVoid here would pretty much prevent that.
|
||||
ScriptPosition.Message(MSG_ERROR, "Incompatible operands for %s", Operator == '+' ? "addition" : "subtraction");
|
||||
delete this;
|
||||
return false;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (left->isConstant() && right->isConstant())
|
||||
|
@ -2651,6 +2620,11 @@ FxExpression *FxAddSub::Resolve(FCompileContext& ctx)
|
|||
}
|
||||
}
|
||||
return this;
|
||||
|
||||
error:
|
||||
ScriptPosition.Message(MSG_ERROR, "Incompatible operands for %s", Operator == '+' ? "addition" : "subtraction");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -2750,16 +2724,70 @@ FxExpression *FxMulDiv::Resolve(FCompileContext& ctx)
|
|||
{
|
||||
CHECKRESOLVED();
|
||||
|
||||
if (!ResolveLR(ctx, true))
|
||||
return nullptr;
|
||||
|
||||
if (!IsNumeric() && !IsVector())
|
||||
RESOLVE(left, ctx);
|
||||
RESOLVE(right, ctx);
|
||||
if (!left || !right)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
|
||||
delete this;
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
else if (left->isConstant() && right->isConstant())
|
||||
|
||||
if (left->IsVector() || right->IsVector())
|
||||
{
|
||||
switch (Operator)
|
||||
{
|
||||
case '/':
|
||||
// For division, the vector must be the first operand.
|
||||
if (right->IsVector()) goto error;
|
||||
|
||||
case '*':
|
||||
if (left->IsVector() && right->IsNumeric())
|
||||
{
|
||||
if (right->IsInteger())
|
||||
{
|
||||
right = new FxFloatCast(right);
|
||||
right = right->Resolve(ctx);
|
||||
if (right == nullptr)
|
||||
{
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ValueType = left->ValueType;
|
||||
}
|
||||
else if (right->IsVector() && left->IsNumeric())
|
||||
{
|
||||
if (left->IsInteger())
|
||||
{
|
||||
left = new FxFloatCast(left);
|
||||
left = left->Resolve(ctx);
|
||||
if (left == nullptr)
|
||||
{
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ValueType = right->ValueType;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Vector modulus is not permitted
|
||||
goto error;
|
||||
|
||||
}
|
||||
}
|
||||
else if (left->IsNumeric() && right->IsNumeric())
|
||||
{
|
||||
Promote(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
// To check: It may be that this could pass in DECORATE, although setting TypeVoid here would pretty much prevent that.
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (left->isConstant() && right->isConstant())
|
||||
{
|
||||
if (IsFloat())
|
||||
{
|
||||
|
@ -2805,8 +2833,13 @@ FxExpression *FxMulDiv::Resolve(FCompileContext& ctx)
|
|||
|
||||
}
|
||||
}
|
||||
Promote(ctx);
|
||||
return this;
|
||||
|
||||
error:
|
||||
ScriptPosition.Message(MSG_ERROR, "Incompatible operands for %s", Operator == '*' ? "multiplication" : Operator == '%' ? "modulus" : "division");
|
||||
delete this;
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -2818,7 +2851,6 @@ FxExpression *FxMulDiv::Resolve(FCompileContext& ctx)
|
|||
|
||||
ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
// allocate the result first so that the operation does not leave gaps in the register set.
|
||||
ExpEmit op1 = left->Emit(build);
|
||||
ExpEmit op2 = right->Emit(build);
|
||||
|
||||
|
@ -2919,15 +2951,29 @@ FxExpression *FxPow::Resolve(FCompileContext& ctx)
|
|||
{
|
||||
CHECKRESOLVED();
|
||||
|
||||
if (!ResolveLR(ctx, true))
|
||||
return nullptr;
|
||||
|
||||
if (!IsNumeric())
|
||||
RESOLVE(left, ctx);
|
||||
RESOLVE(right, ctx);
|
||||
if (!left || !right)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
if (!left->IsNumeric() || !right->IsNumeric())
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Numeric type expected for '**'");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
if (!left->IsFloat())
|
||||
{
|
||||
left = (new FxFloatCast(left))->Resolve(ctx);
|
||||
ABORT(left);
|
||||
}
|
||||
if (!right->IsFloat())
|
||||
{
|
||||
right = (new FxFloatCast(right))->Resolve(ctx);
|
||||
ABORT(right);
|
||||
}
|
||||
if (left->isConstant() && right->isConstant())
|
||||
{
|
||||
double v1 = static_cast<FxConstant *>(left)->GetValue().GetFloat();
|
||||
|
@ -2937,7 +2983,6 @@ FxExpression *FxPow::Resolve(FCompileContext& ctx)
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue