Add more math intrinsics

This commit is contained in:
drmortalwombat 2025-05-21 16:59:52 +02:00
parent 0ba148b6bb
commit 1fa4c39a20
6 changed files with 87 additions and 15 deletions

View File

@ -33,10 +33,15 @@ bool isfinite(float f);
#pragma intrinsic(sin) #pragma intrinsic(sin)
#pragma intrinsic(cos) #pragma intrinsic(cos)
#pragma intrinsic(tan) #pragma intrinsic(tan)
#pragma intrinsic(atan)
#pragma intrinsic(atan2)
#pragma intrinsic(log) #pragma intrinsic(log)
#pragma intrinsic(exp) #pragma intrinsic(exp)
#pragma intrinsic(pow)
#pragma intrinsic(sqrt)
#pragma compile("math.c") #pragma compile("math.c")

View File

@ -1197,6 +1197,26 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons
mResult = Value(exp->mLocation, TheFloatTypeDeclaration); mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(::exp(mParams[0].GetFloat())); mResult.PutFloat(::exp(mParams[0].GetFloat()));
} }
else if (!strcmp(iname->mString, "sqrt"))
{
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(::sqrt(mParams[0].GetFloat()));
}
else if (!strcmp(iname->mString, "atan"))
{
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(::atan(mParams[0].GetFloat()));
}
else if (!strcmp(iname->mString, "atan2"))
{
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(::atan2(mParams[0].GetFloat(), mParams[1].GetFloat()));
}
else if (!strcmp(iname->mString, "pow"))
{
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(::pow(mParams[0].GetFloat(), mParams[1].GetFloat()));
}
else else
mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname); mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname);
} }

View File

@ -1258,6 +1258,7 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
if (decp->mType == DT_CONST_FLOAT || decp->mType == DT_CONST_INTEGER) if (decp->mType == DT_CONST_FLOAT || decp->mType == DT_CONST_INTEGER)
{ {
double d = decp->mType == DT_CONST_FLOAT ? decp->mNumber : decp->mInteger; double d = decp->mType == DT_CONST_FLOAT ? decp->mNumber : decp->mInteger;
double e = 0.0;
bool check = false; bool check = false;
@ -1277,6 +1278,10 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
d = log(d); d = log(d);
else if (!strcmp(iname->mString, "exp")) else if (!strcmp(iname->mString, "exp"))
d = exp(d); d = exp(d);
else if (!strcmp(iname->mString, "sqrt"))
d = sqrt(d);
else if (!strcmp(iname->mString, "atan"))
d = atan(d);
else else
return this; return this;
@ -1289,6 +1294,36 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
return ex; return ex;
} }
} }
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_INTRINSIC) && mRight &&
mRight->mType == EX_LIST && mRight->mLeft->mType == EX_CONSTANT && mRight->mRight->mType == EX_CONSTANT)
{
Declaration* decf = mLeft->mDecValue, * decp1 = mRight->mLeft->mDecValue, * decp2 = mRight->mRight->mDecValue;
const Ident* iname = decf->mQualIdent;
if ((decp1->mType == DT_CONST_FLOAT || decp1->mType == DT_CONST_INTEGER) &&
(decp2->mType == DT_CONST_FLOAT || decp2->mType == DT_CONST_INTEGER))
{
double d1 = decp1->mType == DT_CONST_FLOAT ? decp1->mNumber : decp1->mInteger;
double d2 = decp2->mType == DT_CONST_FLOAT ? decp2->mNumber : decp2->mInteger;
bool check = false;
if (!strcmp(iname->mString, "pow"))
d1 = pow(d1, d2);
else if (!strcmp(iname->mString, "atan2"))
d1 = atan2(d1, d2);
else
return this;
Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_FLOAT);
dec->mBase = TheFloatTypeDeclaration;
dec->mNumber = d1;
ex->mDecValue = dec;
ex->mDecType = dec->mBase;
return ex;
}
}
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_CONSTEXPR) && dataSection) else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_CONSTEXPR) && dataSection)
{ {
ConstexprInterpreter cinter(mLocation, errors, dataSection); ConstexprInterpreter cinter(mLocation, errors, dataSection);

View File

@ -685,7 +685,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
} }
else else
{ {
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent); mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->FullIdent());
if (cexp) if (cexp)
mErrors->Error(cexp->mLocation, EINFO_CALLED_FROM, "Called from here"); mErrors->Error(cexp->mLocation, EINFO_CALLED_FROM, "Called from here");

View File

@ -462,7 +462,7 @@ void GlobalOptimizer::AnalyzeProcedure(Expression* exp, Declaration* procDec)
Analyze(exp, procDec, false); Analyze(exp, procDec, false);
} }
else else
mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->mQualIdent); mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->FullIdent());
procDec->mOptFlags &= ~OPTF_ANALYZING; procDec->mOptFlags &= ~OPTF_ANALYZING;
} }

View File

@ -3715,6 +3715,18 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else if (!strcmp(iname->mString, "exp")) else if (!strcmp(iname->mString, "exp"))
{ {
} }
else if (!strcmp(iname->mString, "sqrt"))
{
}
else if (!strcmp(iname->mString, "atan"))
{
}
else if (!strcmp(iname->mString, "pow"))
{
}
else if (!strcmp(iname->mString, "atan2"))
{
}
else if (!strcmp(iname->mString, "breakpoint")) else if (!strcmp(iname->mString, "breakpoint"))
{ {
InterInstruction* ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BREAKPOINT); InterInstruction* ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BREAKPOINT);
@ -6219,7 +6231,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
} }
} }
else else
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent->mString); mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->FullIdent());
if (strcmp(proc->mIdent->mString, "main")) if (strcmp(proc->mIdent->mString, "main"))
{ {