306 lines
9.2 KiB
C++
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);
|
|
}
|
|
|