ref: 7b85121d0017aae0d76eb1ee8bc56d1be515ae01
parent: de460d9820e51b180d9b646263f5d42575e7fb6c
author: Lennart Augustsson <lennart.augustsson@epicgames.com>
date: Sun Feb 25 13:24:50 EST 2024
Make floating point evaluation recursion free.
--- a/src/runtime/eval.c
+++ b/src/runtime/eval.c
@@ -2418,12 +2418,12 @@
#endif
#if WANT_FLOAT
+#if 1
case T_FADD: FARITHBIN(+);
case T_FSUB: FARITHBIN(-);
case T_FMUL: FARITHBIN(*);
case T_FDIV: FARITHBIN(/);
case T_FNEG: FARITHUN(-);
- case T_ITOF: OPINT1(rd = (flt_t)xi); SETDBL(n, rd); RET;
case T_FEQ: CMPF(==);
case T_FNE: CMPF(!=);
case T_FLT: CMPF(<);
@@ -2430,6 +2430,27 @@
case T_FLE: CMPF(<=);
case T_FGT: CMPF(>);
case T_FGE: CMPF(>=);
+#else
+ case T_FADD:
+ case T_FSUB:
+ case T_FMUL:
+ case T_FDIV:
+ case T_FEQ:
+ case T_FNE:
+ case T_FLT:
+ case T_FLE:
+ case T_FGT:
+ case T_FGE:
+ n = ARG(TOP(1));
+ PUSH(combBINDBL2);
+ break;
+ case T_FNEG:
+ n = ARG(TOP(0));
+ PUSH(combUNDBL1);
+ break;
+
+#endif
+ case T_ITOF: OPINT1(rd = (flt_t)xi); SETDBL(n, rd); RET;
case T_FREAD:
CHECK(1);
msg = evalstring(ARG(TOP(0)), 0);
@@ -2437,9 +2458,9 @@
xd = strtod(msg, NULL);
#elif WORD_SIZE == 32
xd = strtof(msg, NULL);
-#else
+#else /* WORD_SIZE */
#error Unknown WORD_SIZE
-#endif
+#endif /* WORD_SIZE */
FREE(msg);
POP(1);
n = TOP(-1);
@@ -2633,6 +2654,7 @@
x = TOP(0);
enum node_tag tag = GETTAG(x);
uvalue_t xu, yu, ru;
+ flt_t xd, yd, rd;
NODEPTR p;
switch (tag) {@@ -2716,6 +2738,73 @@
ERR("UNINT");}
SETINT(n, (value_t)ru);
+ goto ret;
+
+ case T_BINDBL2:
+ n = ARG(TOP(1));
+ TOP(0) = combBINDBL1;
+ goto top;
+
+ case T_BINDBL1:
+ /* First argument */
+#if SANITY
+ if (GETTAG(n) != T_DBL)
+ ERR("BINDBL 0");+#endif
+ xd = GETDBLVALUE(n);
+ /* Second argument */
+ y = ARG(TOP(2));
+ while (GETTAG(y) == T_IND)
+ y = INDIR(y);
+#if SANITY
+ if (GETTAG(y) != T_DBL)
+ ERR("BINDBL 1");+#endif
+ yd = GETDBLVALUE(y);
+ p = FUN(TOP(1));
+ POP(3);
+ n = TOP(-1);
+ bindbl:
+ switch (GETTAG(p)) {+ case T_IND: p = INDIR(p); goto bindbl;
+ case T_FADD: rd = xd + yd; break;
+ case T_FSUB: rd = xd - yd; break;
+ case T_FMUL: rd = xd * yd; break;
+ case T_FDIV: rd = xd * yd; break;
+
+ case T_FEQ: GOIND(xd == yd ? combTrue : combFalse);
+ case T_FNE: GOIND(xd != yd ? combTrue : combFalse);
+ case T_FLT: GOIND(xd < yd ? combTrue : combFalse);
+ case T_FLE: GOIND(xd <= yd ? combTrue : combFalse);
+ case T_FGT: GOIND(xd > yd ? combTrue : combFalse);
+ case T_FGE: GOIND(xd >= yd ? combTrue : combFalse);
+
+ default:
+ //fprintf(stderr, "tag=%d\n", GETTAG(FUN(TOP(0))));
+ ERR("BINDBL");+ }
+ SETDBLVALUE(n, rd);
+ goto ret;
+
+ case T_UNDBL1:
+ /* The argument */
+#if SANITY
+ if (GETTAG(n) != T_DBL)
+ ERR("UNDBL 0");+#endif
+ xd = GETDBLVALUE(n);
+ p = FUN(TOP(1));
+ POP(2);
+ n = TOP(-1);
+ undbl:
+ switch (GETTAG(p)) {+ case T_IND: p = INDIR(p); goto undbl;
+ case T_FNEG: rd = -xd; break;
+ default:
+ //fprintf(stderr, "tag=%d\n", GETTAG(FUN(TOP(0))));
+ ERR("UNDBL");+ }
+ SETDBLVALUE(n, rd);
goto ret;
default:
--
⑨