]> Nishi Git Mirror - gwion.git/commitdiff
:art: Add arthmetic imm ops
authorJérémie Astor <fennecdjay@gmail.com>
Thu, 1 Jul 2021 19:50:51 +0000 (21:50 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Thu, 1 Jul 2021 19:50:51 +0000 (21:50 +0200)
include/opcode.h
opcode.txt
src/lib/prim.c
src/vm/vm.c

index 426c2adf692a5c1b900e86e12c259ccbec6f464b..3b2c28ed4bbdf2dc5978898b648f1f1bce336cf5 100644 (file)
@@ -35,11 +35,16 @@ enum {
   eAllocWord,
   eAllocWord2,
   eAllocWord3,
-  eint_plus,
-  eint_minus,
+  eint_add,
+  eint_sub,
   eint_mul,
   eint_div,
-  eint_modulo,
+  eint_mod,
+  eint_add_imm,
+  eint_sub_imm,
+  eint_mul_imm,
+  eint_div_imm,
+  eint_mod_imm,
   eint_eq,
   eint_neq,
   eint_and,
@@ -48,6 +53,10 @@ enum {
   eint_ge,
   eint_lt,
   eint_le,
+  eint_gt_imm,
+  eint_ge_imm,
+  eint_lt_imm,
+  eint_le_imm,
   eint_sl,
   eint_sr,
   eint_sand,
@@ -71,10 +80,14 @@ enum {
   eint_pre_dec,
   eint_post_inc,
   eint_post_dec,
-  eFloatPlus,
-  eFloatMinus,
-  eFloatTimes,
-  eFloatDivide,
+  efloat_add,
+  efloat_sub,
+  efloat_mul,
+  efloat_div,
+  efloat_add_imm,
+  efloat_sub_imm,
+  efloat_mul_imm,
+  efloat_div_imm,
   efloat_and,
   efloat_or,
   efloat_eq,
@@ -83,6 +96,10 @@ enum {
   efloat_ge,
   efloat_lt,
   efloat_le,
+  efloat_gt_imm,
+  efloat_ge_imm,
+  efloat_lt_imm,
+  efloat_le_imm,
   efloat_negate,
   efloat_not,
   efloat_r_assign,
@@ -236,11 +253,16 @@ enum {
 #define  AllocWord            (f_instr)eAllocWord
 #define  AllocWord2           (f_instr)eAllocWord2
 #define  AllocWord3           (f_instr)eAllocWord3
-#define  int_plus             (f_instr)eint_plus
-#define  int_minus            (f_instr)eint_minus
+#define  int_add              (f_instr)eint_add
+#define  int_sub              (f_instr)eint_sub
 #define  int_mul              (f_instr)eint_mul
 #define  int_div              (f_instr)eint_div
-#define  int_modulo           (f_instr)eint_modulo
+#define  int_mod              (f_instr)eint_mod
+#define  int_add_imm          (f_instr)eint_add_imm
+#define  int_sub_imm          (f_instr)eint_sub_imm
+#define  int_mul_imm          (f_instr)eint_mul_imm
+#define  int_div_imm          (f_instr)eint_div_imm
+#define  int_mod_imm          (f_instr)eint_mod_imm
 #define  int_eq               (f_instr)eint_eq
 #define  int_neq              (f_instr)eint_neq
 #define  int_and              (f_instr)eint_and
@@ -249,6 +271,10 @@ enum {
 #define  int_ge               (f_instr)eint_ge
 #define  int_lt               (f_instr)eint_lt
 #define  int_le               (f_instr)eint_le
+#define  int_gt_imm           (f_instr)eint_gt_imm
+#define  int_ge_imm           (f_instr)eint_ge_imm
+#define  int_lt_imm           (f_instr)eint_lt_imm
+#define  int_le_imm           (f_instr)eint_le_imm
 #define  int_sl               (f_instr)eint_sl
 #define  int_sr               (f_instr)eint_sr
 #define  int_sand             (f_instr)eint_sand
@@ -272,10 +298,14 @@ enum {
 #define  int_pre_dec          (f_instr)eint_pre_dec
 #define  int_post_inc         (f_instr)eint_post_inc
 #define  int_post_dec         (f_instr)eint_post_dec
-#define  FloatPlus            (f_instr)eFloatPlus
-#define  FloatMinus           (f_instr)eFloatMinus
-#define  FloatTimes           (f_instr)eFloatTimes
-#define  FloatDivide          (f_instr)eFloatDivide
+#define  float_add            (f_instr)efloat_add
+#define  float_sub            (f_instr)efloat_sub
+#define  float_mul            (f_instr)efloat_mul
+#define  float_div            (f_instr)efloat_div
+#define  float_add_imm        (f_instr)efloat_add_imm
+#define  float_sub_imm        (f_instr)efloat_sub_imm
+#define  float_mul_imm        (f_instr)efloat_mul_imm
+#define  float_div_imm        (f_instr)efloat_div_imm
 #define  float_and            (f_instr)efloat_and
 #define  float_or             (f_instr)efloat_or
 #define  float_eq             (f_instr)efloat_eq
@@ -284,6 +314,10 @@ enum {
 #define  float_ge             (f_instr)efloat_ge
 #define  float_lt             (f_instr)efloat_lt
 #define  float_le             (f_instr)efloat_le
+#define  float_gt_imm         (f_instr)efloat_gt_imm
+#define  float_ge_imm         (f_instr)efloat_ge_imm
+#define  float_lt_imm         (f_instr)efloat_lt_imm
+#define  float_le_imm         (f_instr)efloat_le_imm
 #define  float_negate         (f_instr)efloat_negate
 #define  float_not            (f_instr)efloat_not
 #define  float_r_assign       (f_instr)efloat_r_assign
@@ -592,12 +626,12 @@ ANN static inline void dump_opcodes(const VM_Code code) {
         gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
         gw_out("\n");
         break;
-      case eint_plus:
-        gw_out("{Y}┃{0}{-}% 4lu{0}: int_plus    ", j);
+      case eint_add:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_add     ", j);
         gw_out("\n");
         break;
-      case eint_minus:
-        gw_out("{Y}┃{0}{-}% 4lu{0}: int_minus   ", j);
+      case eint_sub:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_sub     ", j);
         gw_out("\n");
         break;
       case eint_mul:
@@ -608,8 +642,33 @@ ANN static inline void dump_opcodes(const VM_Code code) {
         gw_out("{Y}┃{0}{-}% 4lu{0}: int_div     ", j);
         gw_out("\n");
         break;
-      case eint_modulo:
-        gw_out("{Y}┃{0}{-}% 4lu{0}: int_modulo  ", j);
+      case eint_mod:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_mod     ", j);
+        gw_out("\n");
+        break;
+      case eint_add_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_add_imm ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eint_sub_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_sub_imm ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eint_mul_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_mul_imm ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eint_div_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_div_imm ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eint_mod_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_mod_imm ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
         gw_out("\n");
         break;
       case eint_eq:
@@ -644,6 +703,26 @@ ANN static inline void dump_opcodes(const VM_Code code) {
         gw_out("{Y}┃{0}{-}% 4lu{0}: int_le      ", j);
         gw_out("\n");
         break;
+      case eint_gt_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_gt_imm  ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eint_ge_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_ge_imm  ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eint_lt_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_lt_imm  ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
+      case eint_le_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: int_le_imm  ", j);
+        gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+        gw_out("\n");
+        break;
       case eint_sl:
         gw_out("{Y}┃{0}{-}% 4lu{0}: int_sl      ", j);
         gw_out("\n");
@@ -736,20 +815,40 @@ ANN static inline void dump_opcodes(const VM_Code code) {
         gw_out("{Y}┃{0}{-}% 4lu{0}: int_post_dec", j);
         gw_out("\n");
         break;
-      case eFloatPlus:
-        gw_out("{Y}┃{0}{-}% 4lu{0}: FloatPlus   ", j);
+      case efloat_add:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_add   ", j);
+        gw_out("\n");
+        break;
+      case efloat_sub:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_sub   ", j);
         gw_out("\n");
         break;
-      case eFloatMinus:
-        gw_out("{Y}┃{0}{-}% 4lu{0}: FloatMinus  ", j);
+      case efloat_mul:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_mul   ", j);
         gw_out("\n");
         break;
-      case eFloatTimes:
-        gw_out("{Y}┃{0}{-}% 4lu{0}: FloatTimes  ", j);
+      case efloat_div:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_div   ", j);
         gw_out("\n");
         break;
-      case eFloatDivide:
-        gw_out("{Y}┃{0}{-}% 4lu{0}: FloatDivide ", j);
+      case efloat_add_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_add_imm", j);
+        gw_out(" {-R}%-14f", instr->f);
+        gw_out("\n");
+        break;
+      case efloat_sub_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_sub_imm", j);
+        gw_out(" {-R}%-14f", instr->f);
+        gw_out("\n");
+        break;
+      case efloat_mul_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_mul_imm", j);
+        gw_out(" {-R}%-14f", instr->f);
+        gw_out("\n");
+        break;
+      case efloat_div_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_div_imm", j);
+        gw_out(" {-R}%-14f", instr->f);
         gw_out("\n");
         break;
       case efloat_and:
@@ -784,6 +883,26 @@ ANN static inline void dump_opcodes(const VM_Code code) {
         gw_out("{Y}┃{0}{-}% 4lu{0}: float_le    ", j);
         gw_out("\n");
         break;
+      case efloat_gt_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_gt_imm", j);
+        gw_out(" {-R}%-14f", instr->f);
+        gw_out("\n");
+        break;
+      case efloat_ge_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_ge_imm", j);
+        gw_out(" {-R}%-14f", instr->f);
+        gw_out("\n");
+        break;
+      case efloat_lt_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_lt_imm", j);
+        gw_out(" {-R}%-14f", instr->f);
+        gw_out("\n");
+        break;
+      case efloat_le_imm:
+        gw_out("{Y}┃{0}{-}% 4lu{0}: float_le_imm", j);
+        gw_out(" {-R}%-14f", instr->f);
+        gw_out("\n");
+        break;
       case efloat_negate:
         gw_out("{Y}┃{0}{-}% 4lu{0}: float_negate", j);
         gw_out("\n");
index 796e058edf2ee74c38279b90a4ef610c48095165..2bd04b7514e6a757d18947d547ac7079d5e5f9ca 100644 (file)
@@ -32,11 +32,16 @@ Goto~pc
 AllocWord~u
 AllocWord2~u
 AllocWord3~u~u
-int_plus
-int_minus
+int_add
+int_sub
 int_mul
 int_div
-int_modulo
+int_mod
+int_add_imm~i
+int_sub_imm~i
+int_mul_imm~i
+int_div_imm~i
+int_mod_imm~i
 int_eq
 int_neq
 int_and
@@ -45,6 +50,10 @@ int_gt
 int_ge
 int_lt
 int_le
+int_gt_imm~i
+int_ge_imm~i
+int_lt_imm~i
+int_le_imm~i
 int_sl
 int_sr
 int_sand
@@ -68,10 +77,14 @@ int_pre_inc
 int_pre_dec
 int_post_inc
 int_post_dec
-FloatPlus
-FloatMinus
-FloatTimes
-FloatDivide
+float_add
+float_sub
+float_mul
+float_div
+float_add_imm~f
+float_sub_imm~f
+float_mul_imm~f
+float_div_imm~f
 float_and
 float_or
 float_eq
@@ -80,6 +93,10 @@ float_gt
 float_ge
 float_lt
 float_le
+float_gt_imm~f
+float_ge_imm~f
+float_lt_imm~f
+float_le_imm~f
 float_negate
 float_not
 float_r_assign
index 9717036a409c605b4319b766bc3bfa82deff7b0f..60bbdc1990c123a2a697d528442383c771aec1ae 100644 (file)
@@ -101,30 +101,51 @@ BINARY_INT_FOLD(or, et_bool, ||,)
 BINARY_INT_FOLD(eq, et_bool, ==,)
 BINARY_INT_FOLD(neq, et_bool, !=,)
 
+#define BINARY_OP_EMIT(name, type, member) \
+static OP_EMIT(opem_##type##_##name) { \
+  Exp_Binary *const bin = (Exp_Binary *)data; \
+  if(!is_prim_##type(bin->rhs)) \
+    (void)emit_add_instr(emit, type##_##name); \
+  else { \
+    const Instr instr = (Instr)vector_back(&emit->code->instr); \
+    instr->opcode = e##type##_##name##_imm; \
+    instr->m_val = bin->rhs->d.prim.d.member; \
+  } \
+  return GW_OK; \
+}
+
+#define BINARY_INT_EMIT(name) BINARY_OP_EMIT(name, int, num)
+BINARY_INT_EMIT(add)
+BINARY_INT_EMIT(sub)
+BINARY_INT_EMIT(mul)
+BINARY_INT_EMIT(div)
+BINARY_INT_EMIT(mod)
+BINARY_INT_EMIT(lt)
+BINARY_INT_EMIT(le)
+BINARY_INT_EMIT(gt)
+BINARY_INT_EMIT(ge)
+
+#define IMPORT_BINARY_INT(name, op)          \
+  GWI_BB(gwi_oper_add(gwi, opck_int_##name)) \
+  GWI_BB(gwi_oper_emi(gwi, opem_int_##name)) \
+  GWI_BB(gwi_oper_end(gwi, #op, NULL))
+
 GWION_IMPORT(int_op) {
   GWI_BB(gwi_oper_ini(gwi, "int", "int", "int"))
-  GWI_BB(gwi_oper_add(gwi, opck_int_add))
-  GWI_BB(gwi_oper_end(gwi, "+", int_plus))
-  GWI_BB(gwi_oper_add(gwi, opck_int_sub))
-  GWI_BB(gwi_oper_end(gwi, "-", int_minus))
-  GWI_BB(gwi_oper_add(gwi, opck_int_mul))
-  GWI_BB(gwi_oper_end(gwi, "*", int_mul))
-  GWI_BB(gwi_oper_add(gwi, opck_int_div))
-  GWI_BB(gwi_oper_end(gwi, "/", int_div))
-  GWI_BB(gwi_oper_add(gwi, opck_int_mod))
-  return gwi_oper_end(gwi, "%", int_modulo);
+  IMPORT_BINARY_INT(add, +)
+  IMPORT_BINARY_INT(sub, -)
+  IMPORT_BINARY_INT(mul, *)
+  IMPORT_BINARY_INT(div, /)
+  IMPORT_BINARY_INT(mod, %)
+  return GW_OK;
 }
 
 static GWION_IMPORT(int_logical) {
   GWI_BB(gwi_oper_ini(gwi, "int", "int", "int"))
-  GWI_BB(gwi_oper_add(gwi, opck_int_gt))
-  GWI_BB(gwi_oper_end(gwi, ">", int_gt))
-  GWI_BB(gwi_oper_add(gwi, opck_int_ge))
-  GWI_BB(gwi_oper_end(gwi, ">=", int_ge))
-  GWI_BB(gwi_oper_add(gwi, opck_int_lt))
-  GWI_BB(gwi_oper_end(gwi, "<", int_lt))
-  GWI_BB(gwi_oper_add(gwi, opck_int_le))
-  GWI_BB(gwi_oper_end(gwi, "<=", int_le))
+  IMPORT_BINARY_INT(gt, >)
+  IMPORT_BINARY_INT(ge, >=)
+  IMPORT_BINARY_INT(lt, <)
+  IMPORT_BINARY_INT(le, <=)
   GWI_BB(gwi_oper_add(gwi, opck_int_sr))
   GWI_BB(gwi_oper_end(gwi, ">>", int_sr))
   GWI_BB(gwi_oper_add(gwi, opck_int_sl))
@@ -401,16 +422,16 @@ static GWION_IMPORT(dur) {
   CHECK_FF("-=>", rassign, r_minus)
   CHECK_FF("*=>", rassign, r_mul)
   CHECK_FF("/=>", rassign, r_div)
-  GWI_BB(gwi_oper_end(gwi, "+", FloatPlus))
-  GWI_BB(gwi_oper_end(gwi, "-", FloatMinus))
-  GWI_BB(gwi_oper_end(gwi, "*", FloatTimes))
+  GWI_BB(gwi_oper_end(gwi, "+", float_add))
+  GWI_BB(gwi_oper_end(gwi, "-", float_sub))
+  GWI_BB(gwi_oper_end(gwi, "*", float_mul))
   GWI_BB(gwi_oper_ini(gwi, "dur", "dur", "float"))
   GWI_BB(gwi_oper_eff(gwi, "ZeroDivideException"))
-  GWI_BB(gwi_oper_end(gwi, "/", FloatDivide))
+  GWI_BB(gwi_oper_end(gwi, "/", float_div))
 
   GWI_BB(gwi_oper_ini(gwi, "dur", "float", "dur"))
   GWI_BB(gwi_oper_eff(gwi, "ZeroDivideException"))
-  GWI_BB(gwi_oper_end(gwi, "/", FloatDivide))
+  GWI_BB(gwi_oper_end(gwi, "/", float_div))
 
   GWI_BB(gwi_oper_ini(gwi, "float", "dur", "dur"))
   CHECK_FF("*=>", rassign, r_mul)
@@ -441,18 +462,18 @@ static GWION_IMPORT(time) {
   GWI_BB(gwi_oper_ini(gwi, "time", "time", "time"))
   CHECK_FF("=>", rassign, r_assign)
   GWI_BB(gwi_oper_ini(gwi, "time", "dur", "time"))
-  GWI_BB(gwi_oper_end(gwi, "+", FloatPlus))
-  GWI_BB(gwi_oper_end(gwi, "*", FloatTimes))
+  GWI_BB(gwi_oper_end(gwi, "+", float_add))
+  GWI_BB(gwi_oper_end(gwi, "*", float_mul))
   GWI_BB(gwi_oper_eff(gwi, "ZeroDivideException"))
-  GWI_BB(gwi_oper_end(gwi, "/", FloatDivide))
+  GWI_BB(gwi_oper_end(gwi, "/", float_div))
   GWI_BB(gwi_oper_ini(gwi, "time", "time", "dur"))
-  GWI_BB(gwi_oper_end(gwi, "-", FloatMinus))
+  GWI_BB(gwi_oper_end(gwi, "-", float_sub))
   GWI_BB(gwi_oper_ini(gwi, "float", "time", "time"))
   CHECK_FF("*=>", rassign, r_mul)
   CHECK_FF("/=>", rassign, r_div)
   GWI_BB(gwi_oper_ini(gwi, "dur", "time", "time"))
   CHECK_FF("=>", rassign, r_assign)
-  GWI_BB(gwi_oper_end(gwi, "+", FloatPlus))
+  GWI_BB(gwi_oper_end(gwi, "+", float_add))
   GWI_BB(gwi_oper_ini(gwi, "dur", "@now", "time"))
   _CHECK_OP("=>", now, Time_Advance)
   GWI_BB(gwi_oper_ini(gwi, "time", "time", "int"))
@@ -488,23 +509,34 @@ BINARY_FLOAT_FOLD2(ge, et_bool, >=,)
 BINARY_FLOAT_FOLD2(lt, et_bool, <,)
 BINARY_FLOAT_FOLD2(le, et_bool, <=,)
 
+#define BINARY_FLOAT_EMIT(name) BINARY_OP_EMIT(name, float, fnum)
+BINARY_FLOAT_EMIT(add)
+BINARY_FLOAT_EMIT(sub)
+BINARY_FLOAT_EMIT(mul)
+BINARY_FLOAT_EMIT(div)
+BINARY_FLOAT_EMIT(ge)
+BINARY_FLOAT_EMIT(gt)
+BINARY_FLOAT_EMIT(le)
+BINARY_FLOAT_EMIT(lt)
+
 #define UNARY_FLOAT_FOLD(name, TYPE, OP)                                       \
   UNARY_FOLD(float, name, TYPE, OP, is_prim_int, m_float, ae_prim_float, fnum)
 UNARY_FLOAT_FOLD(negate, et_float, -)
 // UNARY_INT_FOLD(cmp, et_float, ~)
 UNARY_FLOAT_FOLD(not, et_bool, !)
 
+#define IMPORT_BINARY_FLOAT(name, op)          \
+  GWI_BB(gwi_oper_add(gwi, opck_float_##name)) \
+  GWI_BB(gwi_oper_emi(gwi, opem_float_##name)) \
+  GWI_BB(gwi_oper_end(gwi, #op, NULL))
+
 static GWION_IMPORT(float) {
   GWI_BB(gwi_oper_cond(gwi, "float", BranchEqFloat, BranchNeqFloat))
   GWI_BB(gwi_oper_ini(gwi, "float", "float", "float"))
-  GWI_BB(gwi_oper_add(gwi, opck_float_add))
-  GWI_BB(gwi_oper_end(gwi, "+", FloatPlus))
-  GWI_BB(gwi_oper_add(gwi, opck_float_sub))
-  GWI_BB(gwi_oper_end(gwi, "-", FloatMinus))
-  GWI_BB(gwi_oper_add(gwi, opck_float_mul))
-  GWI_BB(gwi_oper_end(gwi, "*", FloatTimes))
-  GWI_BB(gwi_oper_add(gwi, opck_float_div))
-  GWI_BB(gwi_oper_end(gwi, "/", FloatDivide))
+  IMPORT_BINARY_FLOAT(add, +);
+  IMPORT_BINARY_FLOAT(sub, -);
+  IMPORT_BINARY_FLOAT(mul, *);
+  IMPORT_BINARY_FLOAT(div, /);
   GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
   CHECK_FF("=>", rassign, r_assign)
   CHECK_FF("+=>", rassign, r_plus)
@@ -520,14 +552,10 @@ static GWION_IMPORT(float) {
   GWI_BB(gwi_oper_end(gwi, "==", float_eq))
   GWI_BB(gwi_oper_add(gwi, opck_float_neq))
   GWI_BB(gwi_oper_end(gwi, "!=", float_neq))
-  GWI_BB(gwi_oper_add(gwi, opck_float_gt))
-  GWI_BB(gwi_oper_end(gwi, ">", float_gt))
-  GWI_BB(gwi_oper_add(gwi, opck_float_ge))
-  GWI_BB(gwi_oper_end(gwi, ">=", float_ge))
-  GWI_BB(gwi_oper_add(gwi, opck_float_lt))
-  GWI_BB(gwi_oper_end(gwi, "<", float_lt))
-  GWI_BB(gwi_oper_add(gwi, opck_float_le))
-  GWI_BB(gwi_oper_end(gwi, "<=", float_le))
+  IMPORT_BINARY_FLOAT(gt, >);
+  IMPORT_BINARY_FLOAT(ge, >=);
+  IMPORT_BINARY_FLOAT(lt, <);
+  IMPORT_BINARY_FLOAT(le, <=);
   GWI_BB(gwi_oper_ini(gwi, NULL, "float", "float"))
   //  CHECK_FF("-", unary_meta, negate)
   GWI_BB(gwi_oper_add(gwi, opck_float_negate))
@@ -535,7 +563,7 @@ static GWION_IMPORT(float) {
   GWI_BB(gwi_oper_ini(gwi, "int", "dur", "dur"))
   GWI_BB(gwi_oper_end(gwi, "::", int_float_mul))
   GWI_BB(gwi_oper_ini(gwi, "float", "dur", "dur"))
-  GWI_BB(gwi_oper_end(gwi, "::", FloatTimes))
+  GWI_BB(gwi_oper_end(gwi, "::", float_mul))
   GWI_BB(gwi_oper_ini(gwi, NULL, "float", "bool"))
   //  GWI_BB(gwi_oper_add(gwi, opck_unary_meta2))
   GWI_BB(gwi_oper_add(gwi, opck_float_not))
@@ -544,7 +572,7 @@ static GWION_IMPORT(float) {
 }
 
 GWION_IMPORT(prim) {
-  GWI_BB(import_int(gwi))      // const folded
+  GWI_BB(import_int(gwi))      // const folded + imm optimized
   GWI_BB(import_float(gwi))    // const folded
   GWI_BB(import_intfloat(gwi)) // const folded
   GWI_BB(import_floatint(gwi)) // const folded
index 7c5e68464f7f560663a3193aa4bd1ed48dce0461..05b218edfc6cdfcd5b47fc0faa865e30e285a2cd 100644 (file)
@@ -212,9 +212,9 @@ __attribute__((hot)) ANN static inline void vm_ugen_init(const VM *vm) {
 #define VM_INFO
 #endif
 
-ANN static inline m_bool overflow_(const m_bit *mem, const VM_Shred c) {
+ANN static inline bool overflow_(const m_bit *mem, const VM_Shred c) {
   return mem > (((m_bit *)c + sizeof(struct VM_Shred_) + SIZEOF_REG) +
-                (SIZEOF_MEM) - (MEM_STEP * 16));
+                (SIZEOF_MEM));
 }
 
 ANN /*static inline */ VM_Shred init_spork_shred(const VM_Shred shred,
@@ -282,18 +282,25 @@ ANN static VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code,
   DISPATCH();
 
 #define INT_OP(op, ...)   OP(m_int, SZ_INT, op, __VA_ARGS__)
+#define INT_IMM_OP(op)   *(m_int*)(reg-SZ_INT) op VAL; DISPATCH()
 #define FLOAT_OP(op, ...) OP(m_float, SZ_FLOAT, op, __VA_ARGS__)
+#define FLOAT_IMM_OP(op)   *(m_float*)(reg-SZ_FLOAT) op VAL; DISPATCH()
 
 #define LOGICAL(t, sz0, sz, op)                                                \
   reg -= sz0;                                                                  \
-  *(m_int *)(reg - SZ_INT) = (*(t *)(reg - SZ_INT) op * (t *)(reg + sz));      \
+  *(m_uint *)(reg - SZ_INT) = (*(t *)(reg - SZ_INT) op * (t *)(reg + sz));      \
   DISPATCH()
 
 #define INT_LOGICAL(op) LOGICAL(m_int, SZ_INT, 0, op)
+#define INT_IMM_LOGICAL(op) *(m_int *)(reg - SZ_INT) = *(m_int*)(reg-SZ_INT) op IVAL; DISPATCH();
 
 #define FLOAT_LOGICAL(op)                                                      \
   LOGICAL(m_float, SZ_FLOAT * 2 - SZ_INT, SZ_FLOAT - SZ_INT, op)
 
+#define FLOAT_IMM_LOGICAL(op) \
+  reg -= SZ_FLOAT - SZ_INT;\
+  *(m_uint *)(reg - SZ_INT) = *(m_float*)(reg-SZ_INT) op FVAL; DISPATCH();
+
 #define SELF(t, sz, op)                                                        \
   *(t *)(reg - sz) = op * (t *)(reg - sz);                                     \
   DISPATCH();
@@ -376,10 +383,12 @@ _Pragma(STRINGIFY(COMPILER diagnostic ignored UNINITIALIZED)
 #define VMSZ (SZ_INT > SZ_FLOAT ? SZ_INT : SZ_FLOAT)
 
 #define VAL   (*(m_uint *)(byte + VMSZ))
+#define IVAL  (*(m_int *)(byte + VMSZ))
 #define FVAL  (*(m_float *)(byte + VMSZ))
 #define VAL2  (*(m_uint *)(byte + SZ_INT + SZ_INT))
-#define UVAL  (*(uint16_t *)(byte + SZ_INT + SZ_INT))
-#define UVAL2 (*(uint16_t *)(byte + SZ_INT + SZ_INT + sizeof(uint16_t)))
+#define IVAL2  (*(m_int *)(byte + SZ_INT + SZ_INT))
+#define SVAL  (*(uint16_t *)(byte + SZ_INT + SZ_INT))
+#define SVAL2 (*(uint16_t *)(byte + SZ_INT + SZ_INT + sizeof(uint16_t)))
 
 #define BRANCH_DISPATCH(check)                                                 \
   if (check)                                                                   \
@@ -404,25 +413,33 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       &&structmember, &&structmemberfloat, &&structmemberother,
       &&structmemberaddr, &&memsetimm, &&memaddimm, &&repeatidx, &&repeat,
       &&regpushme, &&regpushmaybe, &&funcreturn, &&_goto, &&allocint,
-      &&allocfloat, &&allocother, &&intplus, &&intminus, &&intmul, &&intdiv,
-      &&intmod,
+      &&allocfloat, &&allocother,
+      &&intplus, &&intminus, &&intmul, &&intdiv, &&intmod,
+      &&intplusimm, &&intminusimm, &&intmulimm, &&intdivimm, &&intmodimm,
       // int relationnal
-      &&inteq, &&intne, &&intand, &&intor, &&intgt, &&intge, &&intlt, &&intle,
+      &&inteq, &&intne, &&intand, &&intor,
+      &&intgt, &&intge, &&intlt, &&intle,
+      &&intgtimm, &&intgeimm, &&intltimm, &&intleimm,
       &&intsl, &&intsr, &&intsand, &&intsor, &&intxor, &&intnegate, &&intnot,
       &&intcmp, &&intrassign, &&intradd, &&intrsub, &&intrmul, &&intrdiv,
       &&intrmod, &&intrsl, &&intrsr, &&intrsand, &&intrsor, &&intrxor, &&preinc,
-      &&predec, &&postinc, &&postdec, &&floatadd, &&floatsub, &&floatmul,
-      &&floatdiv,
+      &&predec, &&postinc, &&postdec,
+      &&floatadd, &&floatsub, &&floatmul, &&floatdiv,
+      &&floataddimm, &&floatsubimm, &&floatmulimm, &&floatdivimm,
       // logical
-      &&floatand, &&floator, &&floateq, &&floatne, &&floatgt, &&floatge,
-      &&floatlt, &&floatle, &&floatneg, &&floatnot, &&floatrassign, &&floatradd,
+      &&floatand, &&floator, &&floateq, &&floatne,
+      &&floatgt, &&floatge, &&floatlt, &&floatle,
+      &&floatgtimm, &&floatgeimm, &&floatltimm, &&floatleimm,
+      &&floatneg, &&floatnot, &&floatrassign, &&floatradd,
       &&floatrsub, &&floatrmul, &&floatrdiv, &&ifadd, &&ifsub, &&ifmul, &&ifdiv,
       &&ifand, &&ifor, &&ifeq, &&ifne, &&ifgt, &&ifge, &&iflt, &&ifle,
       &&ifrassign, &&ifradd, &&ifrsub, &&ifrmul, &&ifrdiv, &&fiadd, &&fisub,
       &&fimul, &&fidiv, &&fiand, &&fior, &&fieq, &&fine, &&figt, &&fige, &&filt,
       &&file, &&firassign, &&firadd, &&firsub, &&firmul, &&firdiv, &&itof,
-      &&ftoi, &&timeadv, &&recurs, &&setcode, &&regmove, &&regtomem,
-      &&regtomemother, &&overflow, &&funcusrend, &&funcusrend2, &&funcmemberend,
+      &&ftoi, &&timeadv, &&recurs, &&setcode, &&regmove,
+      &&regtomem, &&regtomemother,
+      &&overflow,
+      &&funcusrend, &&funcusrend2, &&funcmemberend,
       &&sporkini, &&forkini, &&sporkfunc, &&sporkmemberfptr, &&sporkexp,
       &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat,
       &&branchnefloat, &&unroll, &&arrayappend, &&autounrollinit, &&autoloop,
@@ -457,7 +474,7 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
     do {
       SDISPATCH();
     regsetimm:
-      *(m_uint *)(reg + (m_int)VAL2) = VAL;
+      *(m_uint *)(reg + IVAL2) = VAL;
       DISPATCH();
     regpushimm:
       *(m_uint *)reg = VAL;
@@ -478,24 +495,24 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       reg += SZ_INT;
       DISPATCH()
     regpushmem:
-      *(m_uint *)reg = *(m_uint *)(mem + (m_int)VAL);
+      *(m_uint *)reg = *(m_uint *)(mem + IVAL);
       reg += SZ_INT;
       DISPATCH();
     regpushmemfloat:
-      *(m_float *)reg = *(m_float *)(mem + (m_int)VAL);
+      *(m_float *)reg = *(m_float *)(mem + IVAL);
       reg += SZ_FLOAT;
       DISPATCH();
     regpushmemother:
       for (m_uint i = 0; i <= VAL2; i += SZ_INT)
-        *(m_uint *)(reg + i) = *(m_uint *)((m_bit *)(mem + (m_int)VAL) + i);
+        *(m_uint *)(reg + i) = *(m_uint *)((m_bit *)(mem + IVAL) + i);
       reg += VAL2;
       DISPATCH();
     regpushmemaddr:
-      *(m_bit **)reg = &*(m_bit *)(mem + (m_int)VAL);
+      *(m_bit **)reg = &*(m_bit *)(mem + IVAL);
       reg += SZ_INT;
       DISPATCH()
     regpushmemderef:
-      memcpy(reg, *(m_uint **)(mem + (m_int)VAL), VAL2);
+      memcpy(reg, *(m_uint **)(mem + IVAL), VAL2);
       reg += VAL2;
       DISPATCH()
     pushnow:
@@ -517,41 +534,41 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       reg += VAL2;
       DISPATCH();
     baseaddr:
-      *(m_uint **)reg = &*(m_uint *)(shred->base + (m_int)VAL);
+      *(m_uint **)reg = &*(m_uint *)(shred->base + IVAL);
       reg += SZ_INT;
       DISPATCH();
     regtoreg:
-      *(m_uint *)(reg + (m_int)VAL) = *(m_uint *)(reg + (m_int)VAL2);
+      *(m_uint *)(reg + IVAL) = *(m_uint *)(reg + IVAL2);
       DISPATCH()
     regtoregother:
-      memcpy(*(m_bit **)(reg - SZ_INT), reg + (m_int)VAL, VAL2);
+      memcpy(*(m_bit **)(reg - SZ_INT), reg + IVAL, VAL2);
       DISPATCH()
     regtoregaddr:
-      *(m_uint **)(reg + (m_int)VAL) = &*(m_uint *)(reg + (m_int)VAL2);
+      *(m_uint **)(reg + IVAL) = &*(m_uint *)(reg + IVAL2);
       DISPATCH()
     regtoregderef:
-      memcpy(*(m_bit **)(reg - SZ_INT), *(m_bit **)(reg + (m_int)VAL), VAL2);
+      memcpy(*(m_bit **)(reg - SZ_INT), *(m_bit **)(reg + IVAL), VAL2);
       DISPATCH()
     structmember:
       *(m_bit **)(reg - SZ_INT) =
-          *(m_bit **)(*(m_bit **)(reg - SZ_INT) + (m_int)VAL);
+          *(m_bit **)(*(m_bit **)(reg - SZ_INT) + IVAL);
       DISPATCH()
     structmemberfloat:
       *(m_bit **)(reg - SZ_INT) =
-          *(m_bit **)(*(m_bit **)(reg - SZ_INT) + (m_int)VAL);
+          *(m_bit **)(*(m_bit **)(reg - SZ_INT) + IVAL);
       DISPATCH()
     structmemberother:
       *(m_bit **)(reg - SZ_INT) =
-          *(m_bit **)(*(m_bit **)(reg - SZ_INT) + (m_int)VAL);
+          *(m_bit **)(*(m_bit **)(reg - SZ_INT) + IVAL);
       DISPATCH()
     structmemberaddr:
-      *(m_bit **)(reg - SZ_INT) = &*(*(m_bit **)(reg - SZ_INT) + (m_int)VAL);
+      *(m_bit **)(reg - SZ_INT) = &*(*(m_bit **)(reg - SZ_INT) + IVAL);
       DISPATCH()
     memsetimm:
       *(m_uint *)(mem + VAL) = VAL2;
       DISPATCH();
     memaddimm:
-      *(m_int *)(mem + VAL) += (m_int)VAL2;
+      *(m_int *)(mem + VAL) += IVAL2;
       //  (*(m_int*)(mem+VAL))--;
       DISPATCH();
     repeatidx:
@@ -601,6 +618,17 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
     intmod:
       INT_OP(%, TEST0(m_int, 0))
 
+    intplusimm:
+      INT_IMM_OP(+=)
+    intminusimm:
+      INT_IMM_OP(-=)
+    intmulimm:
+      INT_IMM_OP(*=)
+    intdivimm:
+      INT_IMM_OP(/=)
+    intmodimm:
+      INT_IMM_OP(%=)
+
     inteq:
       INT_LOGICAL(==)
     intne:
@@ -616,7 +644,15 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
     intlt:
       INT_LOGICAL(<)
     intle:
-      INT_LOGICAL(<=)
+      INT_IMM_LOGICAL(<=)
+    intgtimm:
+      INT_IMM_LOGICAL(>)
+    intgeimm:
+      INT_IMM_LOGICAL(>=)
+    intltimm:
+      INT_IMM_LOGICAL(<)
+    intleimm:
+      INT_IMM_LOGICAL(<=)
     intsl:
       INT_LOGICAL(<<)
     intsr:
@@ -683,6 +719,15 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
     floatdiv:
       FLOAT_OP(/)
 
+    floataddimm:
+      FLOAT_IMM_OP(+=)
+    floatsubimm:
+      FLOAT_IMM_OP(-=)
+    floatmulimm:
+      FLOAT_IMM_OP(*=)
+    floatdivimm:
+      FLOAT_IMM_OP(/=)
+
     floatand:
       FLOAT_LOGICAL(&&)
     floator:
@@ -699,6 +744,14 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       FLOAT_LOGICAL(<)
     floatle:
       FLOAT_LOGICAL(<=)
+    floatgtimm:
+      FLOAT_IMM_LOGICAL(>)
+    floatgeimm:
+      FLOAT_IMM_LOGICAL(>=)
+    floatltimm:
+      FLOAT_IMM_LOGICAL(<)
+    floatleimm:
+      FLOAT_IMM_LOGICAL(<=)
 
     floatneg:
       SELF(m_float, SZ_FLOAT, -)
@@ -815,11 +868,11 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       VM_OUT
       break;
     recurs : {
-      register const uint push = UVAL2;
+      register const uint push = SVAL2;
       mem += push;
       *(frame_t *)(mem - sizeof(frame_t)) =
-          (frame_t) {.code = code, .pc = UVAL, .push = push};
-      reg += (m_int)VAL;
+          (frame_t) {.code = code, .pc = SVAL, .push = push};
+      reg += IVAL;
       next = eFuncUsrEnd2;
     }
       DISPATCH();
@@ -831,7 +884,7 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
             *(m_uint *)reg /*+ code->stack_depth*/ + sizeof(frame_t);
         mem += push;
         *(frame_t *)(mem - sizeof(frame_t)) =
-            (frame_t) {.code = code, .pc = PC + UVAL, .push = push};
+            (frame_t) {.code = code, .pc = PC + SVAL, .push = push};
         next = eFuncUsrEnd;
       } else {
         mem += *(m_uint *)reg;
@@ -839,10 +892,10 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       }
       PRAGMA_POP()
     regmove:
-      reg += (m_int)VAL;
+      reg += IVAL;
       DISPATCH();
     regtomem:
-      *(m_uint *)(mem + VAL) = *(m_uint *)(reg + (m_int)VAL2);
+      *(m_uint *)(mem + VAL) = *(m_uint *)(reg + IVAL2);
       DISPATCH()
     regtomemother:
       memcpy(mem + VAL, reg, VAL2);
@@ -883,7 +936,7 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       DISPATCH() sporkfunc :
           //  LOOP_OPTIM
           PRAGMA_PUSH() for (m_uint i = 0; i < VAL; i += SZ_INT) *
-          (m_uint *)(child->reg + i) = *(m_uint *)(reg + i + (m_int)VAL2);
+          (m_uint *)(child->reg + i) = *(m_uint *)(reg + i + IVAL2);
       child->reg += VAL;
       DISPATCH()
       PRAGMA_POP()
@@ -964,12 +1017,12 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
     }
     arrayget:
       PRAGMA_PUSH()
-      m_vector_get(ARRAY(a.obj), *(m_int *)(reg + VAL), (reg + (m_int)VAL2));
+      m_vector_get(ARRAY(a.obj), *(m_int *)(reg + VAL), (reg + IVAL2));
       PRAGMA_POP()
       DISPATCH()
     arrayaddr:
       PRAGMA_PUSH()
-      *(m_bit **)(reg + (m_int)VAL2) =
+      *(m_bit **)(reg + IVAL2) =
           m_vector_addr(ARRAY(a.obj), *(m_int *)(reg + VAL));
       PRAGMA_POP()
       DISPATCH()
@@ -978,21 +1031,21 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       reg += SZ_INT;
       DISPATCH()
     addref : {
-      const M_Object o = *(M_Object *)(reg + (m_int)VAL);
+      const M_Object o = *(M_Object *)(reg + IVAL);
       //    if(o)
       ++o->ref;
     }
       DISPATCH()
     addrefaddr : {
-      const M_Object o = **(M_Object **)(reg + (m_int)VAL);
+      const M_Object o = **(M_Object **)(reg + IVAL);
       if (o) ++o->ref;
     }
       DISPATCH()
     structaddref:
-      struct_addref(vm->gwion, (Type)VAL2, *(m_bit **)(reg + (m_int)VAL));
+      struct_addref(vm->gwion, (Type)VAL2, *(m_bit **)(reg + IVAL));
       DISPATCH()
     structaddrefaddr:
-      struct_addref(vm->gwion, (Type)VAL2, **(m_bit ***)(reg + (m_int)VAL));
+      struct_addref(vm->gwion, (Type)VAL2, **(m_bit ***)(reg + IVAL));
       DISPATCH()
     objassign : {
       const M_Object o = **(M_Object **)(reg - SZ_INT);
@@ -1122,7 +1175,7 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto]
       vector_add(&shred->gc, 0);
       DISPATCH();
     gcadd:
-      vector_add(&shred->gc, *(vtype *)(reg + (m_int)VAL));
+      vector_add(&shred->gc, *(vtype *)(reg + IVAL));
       DISPATCH();
     gcend : {
       M_Object o;