#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); }