Files
SAPFOR/dvm/fdvm/trunk/fdvm/acc_f2c_handlers.cpp
2023-09-14 19:43:13 +03:00

306 lines
9.2 KiB
C++

#include "dvm.h"
void __convert_args(SgExpression *expr, SgExpression *&Arg, SgExpression *&Arg1, SgExpression *&Arg2)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
Arg = currArgs->lhs();
Arg1 = currArgs->rhs()->lhs();
Arg2 = currArgs->rhs()->rhs()->lhs();
convertExpr(Arg, Arg);
convertExpr(Arg1, Arg1);
convertExpr(Arg2, Arg2);
}
void __convert_args(SgExpression *expr, SgExpression *&Arg, SgExpression *&Arg1)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
Arg = currArgs->lhs();
Arg1 = currArgs->rhs()->lhs();
convertExpr(Arg, Arg);
convertExpr(Arg1, Arg1);
}
void __convert_args(SgExpression *expr, SgExpression *&Arg)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
Arg = currArgs->lhs();
convertExpr(Arg, Arg);
}
void __cmplx_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
int countArgs = 0;
bool kind = false;
int kind_val = -1;
int kind_pos = -1;
while (currArgs)
{
if (currArgs->lhs()->variant() == KEYWORD_ARG)
{
kind = true;
kind_val = currArgs->lhs()->rhs()->valueInteger();
kind_pos = countArgs;
}
countArgs++;
currArgs = currArgs->rhs();
}
if (kind == false)
{
if (countArgs == 1)
createNewFCall(expr, retExp, name, 1);
else if (countArgs == 2)
createNewFCall(expr, retExp, name, 2);
else if (countArgs == 3) // with KIND
{
kind_val = ((SgFunctionCallExp *)expr)->args()->rhs()->rhs()->lhs()->valueInteger();
if (kind_val == 4)
createNewFCall(expr, retExp, "cmplx2", 2);
else if (kind_val == 8)
createNewFCall(expr, retExp, "dcmplx2", 2);
else
createNewFCall(expr, retExp, name, 2);
}
}
else // with key word KIND
{
const char *name_kind;
if (kind_val == 4)
name_kind = "cmplx2";
else if (kind_val == 8)
name_kind = "dcmplx2";
else
name_kind = name;
if (countArgs == 2)
createNewFCall(expr, retExp, name_kind, 1);
else if (countArgs == 3)
{
if (kind_pos == 2)
createNewFCall(expr, retExp, name_kind, 2);
else if (kind_pos == 0)
{
SgFunctionCallExp *tmp = new SgFunctionCallExp(*createNewFunctionSymbol(NULL));
tmp->addArg(*((SgFunctionCallExp *)expr)->args()->rhs()->lhs());
tmp->addArg(*((SgFunctionCallExp *)expr)->args()->rhs()->rhs()->lhs());
createNewFCall(tmp, retExp, name_kind, 2);
}
else
createNewFCall(expr, retExp, "ERROR", 1);
}
}
}
void __minmax_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
SgFunctionCallExp *retFunc = createNewFCall(name);
//set first 2 agrs
SgExpression *Arg = currArgs->lhs();
convertExpr(Arg, Arg);
retFunc->addArg(*Arg);
currArgs = currArgs->rhs();
Arg = currArgs->lhs();
convertExpr(Arg, Arg);
retFunc->addArg(*Arg);
currArgs = currArgs->rhs();
//create nested MAX/MIN functions
while (currArgs)
{
SgFunctionCallExp *tmp = createNewFCall(name);
tmp->addArg(*retFunc);
Arg = currArgs->lhs();
convertExpr(Arg, Arg);
tmp->addArg(*Arg);
currArgs = currArgs->rhs();
retFunc = tmp;
}
retExp = retFunc;
}
static bool isArgIntType(SgExpression *Arg)
{
bool res = true;
if (Arg->variant() == VAR_REF)
{
SgType *tmp = Arg->symbol()->type();
if (tmp->equivalentToType(C_Type(SgTypeDouble())) ||
tmp->equivalentToType(C_Type(SgTypeFloat())))
res = false;
}
else
{
if (Arg->lhs())
res = res && isArgIntType(Arg->lhs());
if (Arg->rhs())
res = res && isArgIntType(Arg->rhs());
}
return res;
}
//TODO: add more complex analysis above
void __mod_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg, *Arg1;
__convert_args(expr, Arg, Arg1);
if (isArgIntType(Arg) && isArgIntType(Arg1))
retExp = &(*Arg % *Arg1);
else
{
retExp = createNewFCall("fmod");
((SgFunctionCallExp*) retExp)->addArg(*Arg);
((SgFunctionCallExp*) retExp)->addArg(*Arg1);
}
}
void __iand_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg, *Arg1;
__convert_args(expr, Arg, Arg1);
retExp = &(*Arg & *Arg1);
}
void __ior_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg, *Arg1;
__convert_args(expr, Arg, Arg1);
retExp = &(*Arg | *Arg1);
}
void __ieor_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg, *Arg1;
__convert_args(expr, Arg, Arg1);
SgExpression *xor_op = new SgExpression(XOR_OP);
xor_op->setLhs(*Arg);
xor_op->setRhs(*Arg1);
retExp = xor_op;
}
void __arc_sincostan_d_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg;
__convert_args(expr, Arg);
SgFunctionCallExp *retFunc = createNewFCall(name);
retFunc->addArg(*Arg);
retExp = &(*retFunc * *new SgValueExp(180.0) / *new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "CUDART_PI")));
}
void __atan2d_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg, *Arg1;
__convert_args(expr, Arg, Arg1);
SgFunctionCallExp *retFunc = createNewFCall(name);
retFunc->addArg(*Arg);
retFunc->addArg(*Arg1);
retExp = &(*retFunc * *new SgValueExp(180.0) / *new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "CUDART_PI")));
}
void __sindcosdtand_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg;
__convert_args(expr, Arg);
SgFunctionCallExp *retFunc = createNewFCall(name);
retFunc->addArg(*Arg * *new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "CUDART_PI")) / *new SgValueExp(180.0));
retExp = retFunc;
}
void __cotan_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg;
__convert_args(expr, Arg);
SgFunctionCallExp *retFunc = createNewFCall(name);
retFunc->addArg(*Arg);
retExp = &(*new SgValueExp(1.0) / *retFunc);
}
void __cotand_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *Arg;
__convert_args(expr, Arg);
SgFunctionCallExp *retFunc = createNewFCall(name);
retFunc->addArg(*Arg * *new SgVarRefExp(new SgSymbol(VARIABLE_NAME, "CUDART_PI")) / *new SgValueExp(180.0));
retExp = &(*new SgValueExp(1.0) / *retFunc);
}
void __ishftc_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression *currArgs = ((SgFunctionCallExp *)expr)->args();
int countArgs = 0;
while (currArgs)
{
countArgs++;
currArgs = currArgs->rhs();
}
switch (countArgs)
{
case 2:
createNewFCall(expr, retExp, "ishc", 2);
break;
case 3:
createNewFCall(expr, retExp, name, 3);
break;
default:
//printf("this function takes 2 or 3 arguments");
break;
}
}
void __merge_bits_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression* Arg, * Arg1, * Arg2;
__convert_args(expr, Arg, Arg1, Arg2);
SgExpression *xor_op = new SgExpression(XOR_OP);
xor_op->setLhs(*Arg2);
xor_op->setRhs(*new SgValueExp(-1));
retExp = &((*Arg & *Arg2) | (*Arg1 & *xor_op));
}
void __not_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression* Arg;
__convert_args(expr, Arg);
SgExpression* xor_op = new SgExpression(XOR_OP);
xor_op->setLhs(*Arg);
xor_op->setRhs(*new SgValueExp(-1));
retExp = xor_op;
}
void __poppar_handler(SgExpression *expr, SgExpression *&retExp, const char *name, int nArgs)
{
SgExpression* Arg;
__convert_args(expr, Arg);
SgFunctionCallExp* func = createNewFCall(name);
func->addArg(*Arg);
retExp = &(*func & *new SgValueExp(1));
}
void __modulo_handler(SgExpression* expr, SgExpression*& retExp, const char* name, int nArgs)
{
SgExpression* Arg, * Arg1;
__convert_args(expr, Arg, Arg1);
SgFunctionCallExp* floor = createNewFCall("floor");
SgFunctionCallExp* doubleA = createNewFCall("double");
doubleA->addArg(*Arg);
SgFunctionCallExp* doubleB = createNewFCall("double");
doubleB->addArg(*Arg1);
floor->addArg(*doubleA / *doubleB);
retExp = &(*Arg - *Arg1 * *floor);
}