sp [-1].data.f = mathfunc (sp [-1].data.f); \
++ip;
+#define MATH_BINOP(mathfunc) \
+ sp--; \
+ sp [-1].data.f = mathfunc (sp [-1].data.f, sp [0].data.f); \
+ ++ip;
+
MINT_IN_CASE(MINT_ABS) MATH_UNOP(fabs); MINT_IN_BREAK;
MINT_IN_CASE(MINT_ASIN) MATH_UNOP(asin); MINT_IN_BREAK;
MINT_IN_CASE(MINT_ASINH) MATH_UNOP(asinh); MINT_IN_BREAK;
MINT_IN_CASE(MINT_ACOSH) MATH_UNOP(acosh); MINT_IN_BREAK;
MINT_IN_CASE(MINT_ATAN) MATH_UNOP(atan); MINT_IN_BREAK;
MINT_IN_CASE(MINT_ATANH) MATH_UNOP(atanh); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CEILING) MATH_UNOP(ceil); MINT_IN_BREAK;
MINT_IN_CASE(MINT_COS) MATH_UNOP(cos); MINT_IN_BREAK;
MINT_IN_CASE(MINT_CBRT) MATH_UNOP(cbrt); MINT_IN_BREAK;
MINT_IN_CASE(MINT_COSH) MATH_UNOP(cosh); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_EXP) MATH_UNOP(exp); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_FLOOR) MATH_UNOP(floor); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LOG) MATH_UNOP(log); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LOG2) MATH_UNOP(log2); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LOG10) MATH_UNOP(log10); MINT_IN_BREAK;
MINT_IN_CASE(MINT_SIN) MATH_UNOP(sin); MINT_IN_BREAK;
MINT_IN_CASE(MINT_SQRT) MATH_UNOP(sqrt); MINT_IN_BREAK;
MINT_IN_CASE(MINT_SINH) MATH_UNOP(sinh); MINT_IN_BREAK;
MINT_IN_CASE(MINT_TAN) MATH_UNOP(tan); MINT_IN_BREAK;
MINT_IN_CASE(MINT_TANH) MATH_UNOP(tanh); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_ATAN2) MATH_BINOP(atan2); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_POW) MATH_BINOP(pow); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_FMA)
+ sp -= 2;
+ sp [-1].data.f = fma (sp [-1].data.f, sp [0].data.f, sp [1].data.f);
+ ip++;
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_SCALEB)
+ sp--;
+ sp [-1].data.f = scalbn (sp [-1].data.f, sp [0].data.i);
+ ip++;
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_ILOGB) {
+ int result;
+ double x = sp [-1].data.f;
+ if (FP_ILOGB0 != INT_MIN && x == 0.0)
+ result = INT_MIN;
+ else if (FP_ILOGBNAN != INT_MAX && isnan(x))
+ result = INT_MAX;
+ else
+ result = ilogb (x);
+ sp [-1].data.i = result;
+ ip++;
+ MINT_IN_BREAK;
+ }
+
+#define MATH_UNOPF(mathfunc) \
+ sp [-1].data.f_r4 = mathfunc (sp [-1].data.f_r4); \
+ ++ip;
+
+#define MATH_BINOPF(mathfunc) \
+ sp--; \
+ sp [-1].data.f_r4 = mathfunc (sp [-1].data.f_r4, sp [0].data.f_r4); \
+ ++ip;
+ MINT_IN_CASE(MINT_ABSF) MATH_UNOPF(fabsf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_ASINF) MATH_UNOPF(asinf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_ASINHF) MATH_UNOPF(asinhf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_ACOSF) MATH_UNOPF(acosf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_ACOSHF) MATH_UNOPF(acoshf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_ATANF) MATH_UNOPF(atanf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_ATANHF) MATH_UNOPF(atanhf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CEILINGF) MATH_UNOPF(ceilf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_COSF) MATH_UNOPF(cosf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CBRTF) MATH_UNOPF(cbrtf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_COSHF) MATH_UNOPF(coshf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_EXPF) MATH_UNOPF(expf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_FLOORF) MATH_UNOPF(floorf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LOGF) MATH_UNOPF(logf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LOG2F) MATH_UNOPF(log2f); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_LOG10F) MATH_UNOPF(log10f); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_SINF) MATH_UNOPF(sinf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_SQRTF) MATH_UNOPF(sqrtf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_SINHF) MATH_UNOPF(sinhf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_TANF) MATH_UNOPF(tanf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_TANHF) MATH_UNOPF(tanhf); MINT_IN_BREAK;
+
+ MINT_IN_CASE(MINT_ATAN2F) MATH_BINOPF(atan2f); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_POWF) MATH_BINOPF(powf); MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_FMAF)
+ sp -= 2;
+ sp [-1].data.f_r4 = fmaf (sp [-1].data.f_r4, sp [0].data.f_r4, sp [1].data.f_r4);
+ ip++;
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_SCALEBF)
+ sp--;
+ sp [-1].data.f_r4 = scalbnf (sp [-1].data.f_r4, sp [0].data.i);
+ ip++;
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_ILOGBF) {
+ int result;
+ float x = sp [-1].data.f_r4;
+ if (FP_ILOGB0 != INT_MIN && x == 0.0)
+ result = INT_MIN;
+ else if (FP_ILOGBNAN != INT_MAX && isnan(x))
+ result = INT_MAX;
+ else
+ result = ilogbf (x);
+ sp [-1].data.i = result;
+ ip++;
+ MINT_IN_BREAK;
+ }
+
MINT_IN_CASE(MINT_INTRINS_ENUM_HASFLAG) {
MonoClass *klass = (MonoClass*)frame->imethod->data_items[ip [1]];
mono_interp_enum_hasflag (sp, klass);
OPDEF(MINT_START_ABORT_PROT, "start_abort_protected", 1, Pop0, Push0, MintOpNoArgs)
// Math intrinsics
+// double
OPDEF(MINT_ABS, "abs", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_ASIN, "asin", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_ASINH, "asinh", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_ACOSH, "acosh", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_ATAN, "atan", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_ATANH, "atanh", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_ATAN2, "atan2", 1, Pop2, Push1, MintOpNoArgs)
+OPDEF(MINT_CEILING, "ceiling", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_COS, "cos", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_CBRT, "cbrt", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_COSH, "cosh", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_EXP, "exp", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_FMA, "fma", 1, Pop3, Push1, MintOpNoArgs)
+OPDEF(MINT_FLOOR, "floor", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_ILOGB, "ilogb", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_LOG, "log", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_LOG2, "log2", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_LOG10, "log10", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_POW, "pow", 1, Pop2, Push1, MintOpNoArgs)
+OPDEF(MINT_SCALEB, "scaleb", 1, Pop2, Push1, MintOpNoArgs)
OPDEF(MINT_SIN, "sin", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_SQRT, "sqrt", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_SINH, "sinh", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_TAN, "tan", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_TANH, "tanh", 1, Pop1, Push1, MintOpNoArgs)
+// float. These must be kept in the same order as their double counterpart
+OPDEF(MINT_ABSF, "absf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_ASINF, "asinf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_ASINHF, "asinhf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_ACOSF, "acosf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_ACOSHF, "acoshf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_ATANF, "atanf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_ATANHF, "atanhf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_ATAN2F, "atan2f", 1, Pop2, Push1, MintOpNoArgs)
+OPDEF(MINT_CEILINGF, "ceilingf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_COSF, "cosf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_CBRTF, "cbrtf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_COSHF, "coshf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_EXPF, "expf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_FMAF, "fmaf", 1, Pop3, Push1, MintOpNoArgs)
+OPDEF(MINT_FLOORF, "floorf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_ILOGBF, "ilogbf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_LOGF, "logf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_LOG2F, "log2f", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_LOG10F, "log10f", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_POWF, "powf", 1, Pop2, Push1, MintOpNoArgs)
+OPDEF(MINT_SCALEBF, "scalebf", 1, Pop2, Push1, MintOpNoArgs)
+OPDEF(MINT_SINF, "sinf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_SQRTF, "sqrtf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_SINHF, "sinhf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_TANF, "tanf", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_TANHF, "tanhf", 1, Pop1, Push1, MintOpNoArgs)
+
OPDEF(MINT_PROF_ENTER, "prof_enter", 2, Pop0, Push0, MintOpNoArgs)
OPDEF(MINT_PROF_EXIT, "prof_exit", 4, Pop1, Push0, MintOpShortAndInt)
OPDEF(MINT_PROF_EXIT_VOID, "prof_exit_void", 4, Pop0, Push0, MintOpShortAndInt)
} else if (in_corlib && !strcmp (klass_name_space, "System") && !strcmp (klass_name, "ByReference`1")) {
g_assert (!strcmp (tm, "get_Value"));
*op = MINT_INTRINS_BYREFERENCE_GET_VALUE;
- } else if (in_corlib && !strcmp (klass_name_space, "System") && !strcmp (klass_name, "Math") && csignature->param_count == 1 && csignature->params [0]->type == MONO_TYPE_R8) {
- if (tm [0] == 'A') {
- if (strcmp (tm, "Abs") == 0 && csignature->params [0]->type == MONO_TYPE_R8) {
- *op = MINT_ABS;
- } else if (strcmp (tm, "Asin") == 0){
- *op = MINT_ASIN;
- } else if (strcmp (tm, "Asinh") == 0){
- *op = MINT_ASINH;
- } else if (strcmp (tm, "Acos") == 0){
- *op = MINT_ACOS;
- } else if (strcmp (tm, "Acosh") == 0){
- *op = MINT_ACOSH;
- } else if (strcmp (tm, "Atan") == 0){
- *op = MINT_ATAN;
- } else if (strcmp (tm, "Atanh") == 0){
- *op = MINT_ATANH;
- }
- } else if (tm [0] == 'C') {
- if (strcmp (tm, "Cos") == 0) {
- *op = MINT_COS;
- } else if (strcmp (tm, "Cbrt") == 0){
- *op = MINT_CBRT;
- } else if (strcmp (tm, "Cosh") == 0){
- *op = MINT_COSH;
- }
- } else if (tm [0] == 'S') {
- if (strcmp (tm, "Sin") == 0) {
- *op = MINT_SIN;
- } else if (strcmp (tm, "Sqrt") == 0) {
- *op = MINT_SQRT;
- } else if (strcmp (tm, "Sinh") == 0){
- *op = MINT_SINH;
- }
- } else if (tm [0] == 'T') {
- if (strcmp (tm, "Tan") == 0) {
- *op = MINT_TAN;
- } else if (strcmp (tm, "Tanh") == 0){
- *op = MINT_TANH;
+ } else if (in_corlib && !strcmp (klass_name_space, "System") &&
+ (!strcmp (klass_name, "Math") || !strcmp (klass_name, "MathF"))) {
+ gboolean is_float = strcmp (klass_name, "MathF") == 0;
+ int param_type = is_float ? MONO_TYPE_R4 : MONO_TYPE_R8;
+ // FIXME add also intrinsic for Round
+ if (csignature->param_count == 1 && csignature->params [0]->type == param_type) {
+ // unops
+ if (tm [0] == 'A') {
+ if (strcmp (tm, "Abs") == 0) {
+ *op = MINT_ABS;
+ } else if (strcmp (tm, "Asin") == 0){
+ *op = MINT_ASIN;
+ } else if (strcmp (tm, "Asinh") == 0){
+ *op = MINT_ASINH;
+ } else if (strcmp (tm, "Acos") == 0){
+ *op = MINT_ACOS;
+ } else if (strcmp (tm, "Acosh") == 0){
+ *op = MINT_ACOSH;
+ } else if (strcmp (tm, "Atan") == 0){
+ *op = MINT_ATAN;
+ } else if (strcmp (tm, "Atanh") == 0){
+ *op = MINT_ATANH;
+ }
+ } else if (tm [0] == 'C') {
+ if (strcmp (tm, "Ceiling") == 0) {
+ *op = MINT_CEILING;
+ } else if (strcmp (tm, "Cos") == 0) {
+ *op = MINT_COS;
+ } else if (strcmp (tm, "Cbrt") == 0){
+ *op = MINT_CBRT;
+ } else if (strcmp (tm, "Cosh") == 0){
+ *op = MINT_COSH;
+ }
+ } else if (strcmp (tm, "Exp") == 0) {
+ *op = MINT_EXP;
+ } else if (strcmp (tm, "Floor") == 0) {
+ *op = MINT_FLOOR;
+ } else if (strcmp (tm, "ILogB") == 0) {
+ *op = MINT_ILOGB;
+ } else if (tm [0] == 'L') {
+ if (strcmp (tm, "Log") == 0) {
+ *op = MINT_LOG;
+ } else if (strcmp (tm, "Log2") == 0) {
+ *op = MINT_LOG2;
+ } else if (strcmp (tm, "Log10") == 0) {
+ *op = MINT_LOG10;
+ }
+ } else if (tm [0] == 'S') {
+ if (strcmp (tm, "Sin") == 0) {
+ *op = MINT_SIN;
+ } else if (strcmp (tm, "Sqrt") == 0) {
+ *op = MINT_SQRT;
+ } else if (strcmp (tm, "Sinh") == 0){
+ *op = MINT_SINH;
+ }
+ } else if (tm [0] == 'T') {
+ if (strcmp (tm, "Tan") == 0) {
+ *op = MINT_TAN;
+ } else if (strcmp (tm, "Tanh") == 0){
+ *op = MINT_TANH;
+ }
}
+ } else if (csignature->param_count == 2 && csignature->params [0]->type == param_type && csignature->params [1]->type == param_type) {
+ if (strcmp (tm, "Atan2") == 0)
+ *op = MINT_ATAN2;
+ else if (strcmp (tm, "Pow") == 0)
+ *op = MINT_POW;
+ } else if (csignature->param_count == 3 && csignature->params [0]->type == param_type && csignature->params [1]->type == param_type && csignature->params [2]->type == param_type) {
+ if (strcmp (tm, "FusedMultiplyAdd") == 0)
+ *op = MINT_FMA;
+ } else if (csignature->param_count == 2 && csignature->params [0]->type == param_type && csignature->params [1]->type == MONO_TYPE_I4 && strcmp (tm, "ScaleB") == 0) {
+ *op = MINT_SCALEB;
+ }
+
+ if (*op != -1 && is_float) {
+ *op = *op + (MINT_ABSF - MINT_ABS);
}
} else if (in_corlib && !strcmp (klass_name_space, "System") && (!strcmp (klass_name, "Span`1") || !strcmp (klass_name, "ReadOnlySpan`1"))) {
if (!strcmp (tm, "get_Item")) {