Enlightenment CVS committal

Author  : raster
Project : e17
Module  : libs/embryo

Dir     : e17/libs/embryo/src/lib


Modified Files:
        embryo_amx.c 


Log Message:


embryo speedups...

this makes embryo just about the fastest "scripting vm" around - unless you
tie yourself to a particular cpu and add a jit for that cpu (which embryo
doesnt have).

 bash:                  4681.700 (estimate - ran only 1/100th of loop)
 python:                  38.193
 ruby:                    21.015
 perl:                    18.925
 java (gij-3.4) (no jit):  2.484
 embryo:                   1.041
 java (kaffe)      (jit):  0.176
 c:                        0.157

notice emrbyo is more than double the speed of the java vm. this is all
portable code - no jit tied to 1 cpu. we can add that later per cpu - but for
a vm/scripting solution thats cross-platform and runs anwyeher on 32, 64bit
cpus, ppc, x86, x86-64, alpha, arm, sparc, mips etc. it's pretty damn good.

yes this test is VERY naieve and simple and only tests a subset - but it
tests the general execution and interpreting engine, being able to make
logical decisions, interpret code and do math operations. we should do a more
comprehensive test, but this is pretty good for a simple one.

here's the source used:

bash:
#!/bin/bash
I=1
while [ $I -lt 1000000 ]; do
  let I++
done

python:
i = 1
while i < 100000000:
    i = i + 1

ruby:
1.upto(100000000) { }

perl:
#!/usr/bin/perl
for ($i = 1; $i < 100000000; $i++) {
}

java:
public class loop {
   public static void main(String[] args) {
      int i;
      for (i = 1; i < 100000000; i++) { }
   }
}

embryo:
main() {
   new i;
   for (i = 1; i < 100000000; i++) { }
}

c:
main() {
   int i;
   for (i = 1; i < 100000000; i++);
}
         

===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/embryo/src/lib/embryo_amx.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -3 -r1.24 -r1.25
--- embryo_amx.c        11 Oct 2004 19:26:08 -0000      1.24
+++ embryo_amx.c        14 Oct 2004 04:17:20 -0000      1.25
@@ -189,16 +189,23 @@
 #endif   
    ep->flags = EMBRYO_FLAG_RELOC;
 
-#ifdef WORDS_BIGENDIAN
      {
        Embryo_Cell cip, code_size;
        Embryo_Cell *code;
        
        code_size = hdr->dat - hdr->cod;
        code = (Embryo_Cell *)((unsigned char *)ep->code + (int)hdr->cod);
-       for (cip = 0; cip < (code_size / sizeof(Embryo_Cell)); cip++) 
embryo_swap_32(&(code[cip]));
+       for (cip = 0; cip < (code_size / sizeof(Embryo_Cell)); cip++)
+         {
+/* move this here - later we probably want something that verifies opcodes
+ * are valid and ok...
+ */
+#ifdef WORDS_BIGENDIAN
+            embryo_swap_32(&(code[cip]));
+#endif
+            
+         }
      }
-#endif  
    /* init native api for handling floating point - default in embryo */
    _embryo_args_init(ep);
    _embryo_fp_init(ep);
@@ -973,6 +980,25 @@
    return ep->run_count;
 }
 
+#ifdef __GNUC__
+#if 1
+#define EMBRYO_EXEC_JUMPTABLE
+#endif
+#endif
+
+/* jump table optimization - only works for gcc though */
+#ifdef EMBRYO_EXEC_JUMPTABLE
+#define SWITCH(x) while (1) { goto *switchtable[x];
+#define SWITCHEND break; }
+#define CASE(x) SWITCHTABLE_##x:
+#define BREAK break;
+#else
+#define SWITCH(x) switch (x) {
+#define SWITCHEND }
+#define CASE(x) case x:
+#define BREAK break
+#endif
+
 /**
  * Runs the given function of the given Embryo program in the current 
  * virtual machine.  The parameter @p fn can be found using
@@ -999,10 +1025,182 @@
    Embryo_Cell      reset_stk, reset_hea, *cip;
    Embryo_UCell     codesize;
    int              i;
-   unsigned int     op;
+   unsigned char    op;
    Embryo_Cell      offs;
    int              num;
-
+#ifdef EMBRYO_EXEC_JUMPTABLE
+   /* we limit the jumptable to 256 elements. why? above we forced "op" to be
+    * a unsigned char - that means 256 max values. we limit opcode overflow
+    * here, so eliminating crashes on table lookups with bad/corrupt bytecode.
+    * no need to atuall do compares, branches etc. the datatype does the work
+    * for us. so that means EXCESS elements are all declared as OP_NONE to
+    * keep them innocuous.
+    */
+   const static void *switchtable[256] =
+     {
+          &&SWITCHTABLE_EMBRYO_OP_NONE,
+              &&SWITCHTABLE_EMBRYO_OP_LOAD_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_LOAD_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_LOAD_S_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_LOAD_S_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_LREF_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_LREF_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_LREF_S_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_LREF_S_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_LOAD_I,
+              &&SWITCHTABLE_EMBRYO_OP_LODB_I,
+              &&SWITCHTABLE_EMBRYO_OP_CONST_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_CONST_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_ADDR_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_ADDR_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_STOR_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_STOR_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_STOR_S_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_STOR_S_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_SREF_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_SREF_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_SREF_S_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_SREF_S_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_STOR_I,
+              &&SWITCHTABLE_EMBRYO_OP_STRB_I,
+              &&SWITCHTABLE_EMBRYO_OP_LIDX,
+              &&SWITCHTABLE_EMBRYO_OP_LIDX_B,
+              &&SWITCHTABLE_EMBRYO_OP_IDXADDR,
+              &&SWITCHTABLE_EMBRYO_OP_IDXADDR_B,
+              &&SWITCHTABLE_EMBRYO_OP_ALIGN_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_ALIGN_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_LCTRL,
+              &&SWITCHTABLE_EMBRYO_OP_SCTRL,
+              &&SWITCHTABLE_EMBRYO_OP_MOVE_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_MOVE_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_XCHG,
+              &&SWITCHTABLE_EMBRYO_OP_PUSH_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_PUSH_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_PUSH_R,
+              &&SWITCHTABLE_EMBRYO_OP_PUSH_C,
+              &&SWITCHTABLE_EMBRYO_OP_PUSH,
+              &&SWITCHTABLE_EMBRYO_OP_PUSH_S,
+              &&SWITCHTABLE_EMBRYO_OP_POP_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_POP_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_STACK,
+              &&SWITCHTABLE_EMBRYO_OP_HEAP,
+              &&SWITCHTABLE_EMBRYO_OP_PROC,
+              &&SWITCHTABLE_EMBRYO_OP_RET,
+              &&SWITCHTABLE_EMBRYO_OP_RETN,
+              &&SWITCHTABLE_EMBRYO_OP_CALL,
+              &&SWITCHTABLE_EMBRYO_OP_CALL_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_JUMP,
+              &&SWITCHTABLE_EMBRYO_OP_JREL,
+              &&SWITCHTABLE_EMBRYO_OP_JZER,
+              &&SWITCHTABLE_EMBRYO_OP_JNZ,
+              &&SWITCHTABLE_EMBRYO_OP_JEQ,
+              &&SWITCHTABLE_EMBRYO_OP_JNEQ,
+              &&SWITCHTABLE_EMBRYO_OP_JLESS,
+              &&SWITCHTABLE_EMBRYO_OP_JLEQ,
+              &&SWITCHTABLE_EMBRYO_OP_JGRTR,
+              &&SWITCHTABLE_EMBRYO_OP_JGEQ,
+              &&SWITCHTABLE_EMBRYO_OP_JSLESS,
+              &&SWITCHTABLE_EMBRYO_OP_JSLEQ,
+              &&SWITCHTABLE_EMBRYO_OP_JSGRTR,
+              &&SWITCHTABLE_EMBRYO_OP_JSGEQ,
+              &&SWITCHTABLE_EMBRYO_OP_SHL,
+              &&SWITCHTABLE_EMBRYO_OP_SHR,
+              &&SWITCHTABLE_EMBRYO_OP_SSHR,
+              &&SWITCHTABLE_EMBRYO_OP_SHL_C_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_SHL_C_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_SHR_C_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_SHR_C_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_SMUL,
+              &&SWITCHTABLE_EMBRYO_OP_SDIV,
+              &&SWITCHTABLE_EMBRYO_OP_SDIV_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_UMUL,
+              &&SWITCHTABLE_EMBRYO_OP_UDIV,
+              &&SWITCHTABLE_EMBRYO_OP_UDIV_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_ADD,
+              &&SWITCHTABLE_EMBRYO_OP_SUB,
+              &&SWITCHTABLE_EMBRYO_OP_SUB_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_AND,
+              &&SWITCHTABLE_EMBRYO_OP_OR,
+              &&SWITCHTABLE_EMBRYO_OP_XOR,
+              &&SWITCHTABLE_EMBRYO_OP_NOT,
+              &&SWITCHTABLE_EMBRYO_OP_NEG,
+              &&SWITCHTABLE_EMBRYO_OP_INVERT,
+              &&SWITCHTABLE_EMBRYO_OP_ADD_C,
+              &&SWITCHTABLE_EMBRYO_OP_SMUL_C,
+              &&SWITCHTABLE_EMBRYO_OP_ZERO_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_ZERO_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_ZERO,
+              &&SWITCHTABLE_EMBRYO_OP_ZERO_S,
+              &&SWITCHTABLE_EMBRYO_OP_SIGN_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_SIGN_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_EQ,
+              &&SWITCHTABLE_EMBRYO_OP_NEQ,
+              &&SWITCHTABLE_EMBRYO_OP_LESS,
+              &&SWITCHTABLE_EMBRYO_OP_LEQ,
+              &&SWITCHTABLE_EMBRYO_OP_GRTR,
+              &&SWITCHTABLE_EMBRYO_OP_GEQ,
+              &&SWITCHTABLE_EMBRYO_OP_SLESS,
+              &&SWITCHTABLE_EMBRYO_OP_SLEQ,
+              &&SWITCHTABLE_EMBRYO_OP_SGRTR,
+              &&SWITCHTABLE_EMBRYO_OP_SGEQ,
+              &&SWITCHTABLE_EMBRYO_OP_EQ_C_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_EQ_C_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_INC_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_INC_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_INC,
+              &&SWITCHTABLE_EMBRYO_OP_INC_S,
+              &&SWITCHTABLE_EMBRYO_OP_INC_I,
+              &&SWITCHTABLE_EMBRYO_OP_DEC_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_DEC_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_DEC,
+              &&SWITCHTABLE_EMBRYO_OP_DEC_S,
+              &&SWITCHTABLE_EMBRYO_OP_DEC_I,
+              &&SWITCHTABLE_EMBRYO_OP_MOVS,
+              &&SWITCHTABLE_EMBRYO_OP_CMPS,
+              &&SWITCHTABLE_EMBRYO_OP_FILL,
+              &&SWITCHTABLE_EMBRYO_OP_HALT,
+              &&SWITCHTABLE_EMBRYO_OP_BOUNDS,
+              &&SWITCHTABLE_EMBRYO_OP_SYSREQ_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_SYSREQ_C,
+              &&SWITCHTABLE_EMBRYO_OP_FILE,
+              &&SWITCHTABLE_EMBRYO_OP_LINE,
+              &&SWITCHTABLE_EMBRYO_OP_SYMBOL,
+              &&SWITCHTABLE_EMBRYO_OP_SRANGE,
+              &&SWITCHTABLE_EMBRYO_OP_JUMP_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_SWITCH,
+              &&SWITCHTABLE_EMBRYO_OP_CASETBL,
+              &&SWITCHTABLE_EMBRYO_OP_SWAP_PRI,
+              &&SWITCHTABLE_EMBRYO_OP_SWAP_ALT,
+              &&SWITCHTABLE_EMBRYO_OP_PUSHADDR,
+              &&SWITCHTABLE_EMBRYO_OP_NOP,
+              &&SWITCHTABLE_EMBRYO_OP_SYSREQ_D,
+              &&SWITCHTABLE_EMBRYO_OP_SYMTAG,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE,
+         &&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE, 
&&SWITCHTABLE_EMBRYO_OP_NONE, &&SWITCHTABLE_EMBRYO_OP_NONE
+     };
+#endif     
    if (!ep) return EMBRYO_PROGRAM_FAIL;
    if (!(ep->flags & EMBRYO_FLAG_RELOC))
      {
@@ -1153,751 +1351,760 @@
    for (;;)
      {
        op = (Embryo_Opcode)*cip++;
-       switch (op)
+       SWITCH(op);
+       CASE(EMBRYO_OP_LOAD_PRI);
+       GETPARAM(offs);
+       pri = *(Embryo_Cell *)(data + (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_LOAD_ALT);
+       GETPARAM(offs);
+       alt = *(Embryo_Cell *)(data + (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_LOAD_S_PRI);
+       GETPARAM(offs);
+       pri = *(Embryo_Cell *)(data + (int)frm + (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_LOAD_S_ALT);
+       GETPARAM(offs);
+       alt = *(Embryo_Cell *)(data + (int)frm + (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_LREF_PRI);
+       GETPARAM(offs);
+       offs = *(Embryo_Cell *)(data + (int)offs);
+       pri = *(Embryo_Cell *)(data + (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_LREF_ALT);
+       GETPARAM(offs);
+       offs = *(Embryo_Cell *)(data + (int)offs);
+       alt = *(Embryo_Cell *)(data + (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_LREF_S_PRI);
+       GETPARAM(offs);
+       offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
+       pri = *(Embryo_Cell *)(data + (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_LREF_S_ALT);
+       GETPARAM(offs);
+       offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
+       alt = *(Embryo_Cell *)(data + (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_LOAD_I);
+       CHKMEM(pri);
+       pri = *(Embryo_Cell *)(data + (int)pri);
+       BREAK;
+       CASE(EMBRYO_OP_LODB_I);
+       GETPARAM(offs);
+       CHKMEM(pri);
+       switch (offs)
          {
-          case EMBRYO_OP_LOAD_PRI:
-            GETPARAM(offs);
-            pri = *(Embryo_Cell *)(data + (int)offs);
-            break;
-          case EMBRYO_OP_LOAD_ALT:
-            GETPARAM(offs);
-            alt = *(Embryo_Cell *)(data + (int)offs);
-            break;
-          case EMBRYO_OP_LOAD_S_PRI:
-            GETPARAM(offs);
-            pri = *(Embryo_Cell *)(data + (int)frm + (int)offs);
-            break;
-          case EMBRYO_OP_LOAD_S_ALT:
-            GETPARAM(offs);
-            alt = *(Embryo_Cell *)(data + (int)frm + (int)offs);
-            break;
-          case EMBRYO_OP_LREF_PRI:
-            GETPARAM(offs);
-            offs = *(Embryo_Cell *)(data + (int)offs);
-            pri = *(Embryo_Cell *)(data + (int)offs);
-            break;
-          case EMBRYO_OP_LREF_ALT:
-            GETPARAM(offs);
-            offs = *(Embryo_Cell *)(data + (int)offs);
-            alt = *(Embryo_Cell *)(data + (int)offs);
-            break;
-          case EMBRYO_OP_LREF_S_PRI:
-            GETPARAM(offs);
-            offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
-            pri = *(Embryo_Cell *)(data + (int)offs);
-            break;
-          case EMBRYO_OP_LREF_S_ALT:
-            GETPARAM(offs);
-            offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
-            alt = *(Embryo_Cell *)(data + (int)offs);
-            break;
-          case EMBRYO_OP_LOAD_I:
-            CHKMEM(pri);
-            pri = *(Embryo_Cell *)(data + (int)pri);
-            break;
-          case EMBRYO_OP_LODB_I:
-            GETPARAM(offs);
-            CHKMEM(pri);
-            switch (offs)
-              {
-               case 1:
-                 pri = *(data + (int)pri);
-                 break;
-               case 2:
-                 pri = *(unsigned short *)(data + (int)pri);
-                 break;
-               case 4:
-                 pri = *(unsigned int *)(data + (int)pri);
-                 break;
-               default:
-                 ABORT(ep, EMBRYO_ERROR_INVINSTR);
-                 break;
-              }
+          case 1:
+            pri = *(data + (int)pri);
             break;
-          case EMBRYO_OP_CONST_PRI:
-            GETPARAM(pri);
+          case 2:
+            pri = *(unsigned short *)(data + (int)pri);
             break;
-          case EMBRYO_OP_CONST_ALT:
-            GETPARAM(alt);
+          case 4:
+            pri = *(unsigned int *)(data + (int)pri);
             break;
-          case EMBRYO_OP_ADDR_PRI:
-            GETPARAM(pri);
-            pri += frm;
-            break;
-          case EMBRYO_OP_ADDR_ALT:
-            GETPARAM(alt);
-            alt += frm;
-            break;
-          case EMBRYO_OP_STOR_PRI:
-            GETPARAM(offs);
-            *(Embryo_Cell *)(data + (int)offs) = pri;
-            break;
-          case EMBRYO_OP_STOR_ALT:
-            GETPARAM(offs);
-            *(Embryo_Cell *)(data + (int)offs) = alt;
-            break;
-          case EMBRYO_OP_STOR_S_PRI:
-            GETPARAM(offs);
-            *(Embryo_Cell *)(data + (int)frm + (int)offs) = pri;
-            break;
-          case EMBRYO_OP_STOR_S_ALT:
-            GETPARAM(offs);
-            *(Embryo_Cell *)(data + (int)frm + (int)offs) = alt;
-            break;
-          case EMBRYO_OP_SREF_PRI:
-            GETPARAM(offs);
-            offs = *(Embryo_Cell *)(data + (int)offs);
-            *(Embryo_Cell *)(data + (int)offs) = pri;
-            break;
-          case EMBRYO_OP_SREF_ALT:
-            GETPARAM(offs);
-            offs = *(Embryo_Cell *)(data + (int)offs);
-            *(Embryo_Cell *)(data + (int)offs) = alt;
-            break;
-          case EMBRYO_OP_SREF_S_PRI:
-            GETPARAM(offs);
-            offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
-            *(Embryo_Cell *)(data + (int)offs) = pri;
-            break;
-          case EMBRYO_OP_SREF_S_ALT:
-            GETPARAM(offs);
-            offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
-            *(Embryo_Cell *)(data + (int)offs) = alt;
-            break;
-          case EMBRYO_OP_STOR_I:
-            CHKMEM(alt);
-            *(Embryo_Cell *)(data + (int)alt) = pri;
-            break;
-          case EMBRYO_OP_STRB_I:
-            GETPARAM(offs);
-            CHKMEM(alt);
-            switch (offs)
-              {
-               case 1:
-                 *(data + (int)alt) = (unsigned char)pri;
-                 break;
-               case 2:
-                 *(unsigned short *)(data + (int)alt) = (unsigned short)pri;
-                 break;
-               case 4:
-                 *(unsigned int *)(data + (int)alt) = (unsigned int)pri;
-                 break;
-               default:
-                 ABORT(ep, EMBRYO_ERROR_INVINSTR);
-                 break;
-              }
+          default:
+            ABORT(ep, EMBRYO_ERROR_INVINSTR);
             break;
-          case EMBRYO_OP_LIDX:
-            offs = (pri * sizeof(Embryo_Cell)) + alt;
-            CHKMEM(offs);
-            pri = *(Embryo_Cell *)(data + (int)offs);
-            break;
-          case EMBRYO_OP_LIDX_B:
-            GETPARAM(offs);
-            offs = (pri << (int)offs) + alt;
-            CHKMEM(offs);
-            pri = *(Embryo_Cell *)(data + (int)offs);
-            break;
-          case EMBRYO_OP_IDXADDR:
-            pri = (pri * sizeof(Embryo_Cell)) + alt;
-            break;
-          case EMBRYO_OP_IDXADDR_B:
-            GETPARAM(offs);
-            pri = (pri << (int)offs) + alt;
+         }
+       BREAK;
+       CASE(EMBRYO_OP_CONST_PRI);
+       GETPARAM(pri);
+       BREAK;
+       CASE(EMBRYO_OP_CONST_ALT);
+       GETPARAM(alt);
+       BREAK;
+       CASE(EMBRYO_OP_ADDR_PRI);
+       GETPARAM(pri);
+       pri += frm;
+       BREAK;
+       CASE(EMBRYO_OP_ADDR_ALT);
+       GETPARAM(alt);
+       alt += frm;
+       BREAK;
+       CASE(EMBRYO_OP_STOR_PRI);
+       GETPARAM(offs);
+       *(Embryo_Cell *)(data + (int)offs) = pri;
+       BREAK;
+       CASE(EMBRYO_OP_STOR_ALT);
+       GETPARAM(offs);
+       *(Embryo_Cell *)(data + (int)offs) = alt;
+       BREAK;
+       CASE(EMBRYO_OP_STOR_S_PRI);
+       GETPARAM(offs);
+       *(Embryo_Cell *)(data + (int)frm + (int)offs) = pri;
+       BREAK;
+       CASE(EMBRYO_OP_STOR_S_ALT);
+       GETPARAM(offs);
+       *(Embryo_Cell *)(data + (int)frm + (int)offs) = alt;
+       BREAK;
+       CASE(EMBRYO_OP_SREF_PRI);
+       GETPARAM(offs);
+       offs = *(Embryo_Cell *)(data + (int)offs);
+       *(Embryo_Cell *)(data + (int)offs) = pri;
+       BREAK;
+       CASE(EMBRYO_OP_SREF_ALT);
+       GETPARAM(offs);
+       offs = *(Embryo_Cell *)(data + (int)offs);
+       *(Embryo_Cell *)(data + (int)offs) = alt;
+       BREAK;
+       CASE(EMBRYO_OP_SREF_S_PRI);
+       GETPARAM(offs);
+       offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
+       *(Embryo_Cell *)(data + (int)offs) = pri;
+       BREAK;
+       CASE(EMBRYO_OP_SREF_S_ALT);
+       GETPARAM(offs);
+       offs = *(Embryo_Cell *)(data + (int)frm + (int)offs);
+       *(Embryo_Cell *)(data + (int)offs) = alt;
+       BREAK;
+       CASE(EMBRYO_OP_STOR_I);
+       CHKMEM(alt);
+       *(Embryo_Cell *)(data + (int)alt) = pri;
+       BREAK;
+       CASE(EMBRYO_OP_STRB_I);
+       GETPARAM(offs);
+       CHKMEM(alt);
+       switch (offs)
+         {
+          case 1:
+            *(data + (int)alt) = (unsigned char)pri;
+            break;
+          case 2:
+            *(unsigned short *)(data + (int)alt) = (unsigned short)pri;
+            break;
+          case 4:
+            *(unsigned int *)(data + (int)alt) = (unsigned int)pri;
+            break;
+          default:
+            ABORT(ep, EMBRYO_ERROR_INVINSTR);
             break;
-          case EMBRYO_OP_ALIGN_PRI:
-            GETPARAM(offs);
+         }
+       BREAK;
+       CASE(EMBRYO_OP_LIDX);
+       offs = (pri * sizeof(Embryo_Cell)) + alt;
+       CHKMEM(offs);
+       pri = *(Embryo_Cell *)(data + (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_LIDX_B);
+       GETPARAM(offs);
+       offs = (pri << (int)offs) + alt;
+       CHKMEM(offs);
+       pri = *(Embryo_Cell *)(data + (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_IDXADDR);
+       pri = (pri * sizeof(Embryo_Cell)) + alt;
+       BREAK;
+       CASE(EMBRYO_OP_IDXADDR_B);
+       GETPARAM(offs);
+       pri = (pri << (int)offs) + alt;
+       BREAK;
+       CASE(EMBRYO_OP_ALIGN_PRI);
+       GETPARAM(offs);
 #ifdef WORDS_BIGENDIAN
-            if ((size_t)offs < sizeof(Embryo_Cell))
-              pri ^= sizeof(Embryo_Cell) - offs;
+       if ((size_t)offs < sizeof(Embryo_Cell))
+         pri ^= sizeof(Embryo_Cell) - offs;
 #endif       
-            break;
-          case EMBRYO_OP_ALIGN_ALT:
-            GETPARAM(offs);
+       BREAK;
+       CASE(EMBRYO_OP_ALIGN_ALT);
+       GETPARAM(offs);
 #ifdef WORDS_BIGENDIAN
-            if ((size_t)offs < sizeof(Embryo_Cell))
-              alt ^= sizeof(Embryo_Cell) - offs;
+       if ((size_t)offs < sizeof(Embryo_Cell))
+         alt ^= sizeof(Embryo_Cell) - offs;
 #endif       
+       BREAK;
+       CASE(EMBRYO_OP_LCTRL);
+       GETPARAM(offs);
+       switch (offs)
+         {
+          case 0:
+            pri = hdr->cod;
             break;
-          case EMBRYO_OP_LCTRL:
-            GETPARAM(offs);
-            switch (offs)
-              {
-               case 0:
-                 pri = hdr->cod;
-                 break;
-               case 1:
-                 pri = hdr->dat;
-                 break;
-               case 2:
-                 pri = hea;
-                 break;
-               case 3:
-                 pri = ep->stp;
-                 break;
-               case 4:
-                 pri = stk;
-                 break;
-               case 5:
-                 pri = frm;
-                 break;
-               case 6:
-                 pri = (Embryo_Cell)((unsigned char *)cip - code);
-                 break;
-               default:
-                 ABORT(ep, EMBRYO_ERROR_INVINSTR);
-                 break;
-              }
-            break;
-          case EMBRYO_OP_SCTRL:
-            GETPARAM(offs);
-            switch (offs)
-              {
-               case 0:
-               case 1:
-               case 2:
-                 hea = pri;
-                 break;
-               case 3:
-                 /* cannot change these parameters */
-                 break;
-               case 4:
-                 stk = pri;
-                 break;
-               case 5:
-                 frm = pri;
-                 break;
-               case 6:
-                 cip = (Embryo_Cell *)(code + (int)pri);
-                 break;
-               default:
-                 ABORT(ep, EMBRYO_ERROR_INVINSTR);
-                 break;
-              }
-            break;
-          case EMBRYO_OP_MOVE_PRI:
-            pri = alt;
-            break;
-          case EMBRYO_OP_MOVE_ALT:
-            alt = pri;
-            break;
-          case EMBRYO_OP_XCHG:
-            offs = pri;         /* offs is a temporary variable */
-            pri = alt;
-            alt = offs;
-            break;
-          case EMBRYO_OP_PUSH_PRI:
-            PUSH(pri);
-            break;
-          case EMBRYO_OP_PUSH_ALT:
-            PUSH(alt);
-            break;
-          case EMBRYO_OP_PUSH_C:
-            GETPARAM(offs);
-            PUSH(offs);
-            break;
-          case EMBRYO_OP_PUSH_R:
-            GETPARAM(offs);
-            while (offs--) PUSH(pri);
-            break;
-          case EMBRYO_OP_PUSH:
-            GETPARAM(offs);
-            PUSH(*(Embryo_Cell *)(data + (int)offs));
-            break;
-          case EMBRYO_OP_PUSH_S:
-            GETPARAM(offs);
-            PUSH(*(Embryo_Cell *)(data + (int)frm + (int)offs));
-            break;
-          case EMBRYO_OP_POP_PRI:
-            POP(pri);
-            break;
-          case EMBRYO_OP_POP_ALT:
-            POP(alt);
-            break;
-          case EMBRYO_OP_STACK:
-            GETPARAM(offs);
-            alt = stk;
-            stk += offs;
-            CHKMARGIN();
-            CHKSTACK();
-            break;
-          case EMBRYO_OP_HEAP:
-            GETPARAM(offs);
-            alt = hea;
-            hea += offs;
-            CHKMARGIN();
-            CHKHEAP();
-            break;
-          case EMBRYO_OP_PROC:
-            PUSH(frm);
-            frm = stk;
-            CHKMARGIN();
-            break;
-          case EMBRYO_OP_RET:
-            POP(frm);
-            POP(offs);
-            if ((Embryo_UCell)offs >= codesize)
-              ABORT(ep, EMBRYO_ERROR_MEMACCESS);
-            cip = (Embryo_Cell *)(code + (int)offs);
-            break;
-          case EMBRYO_OP_RETN:
-            POP(frm);
-            POP(offs);
-            if ((Embryo_UCell)offs >= codesize)
-              ABORT(ep, EMBRYO_ERROR_MEMACCESS);
-            cip = (Embryo_Cell *)(code + (int)offs);
-            stk += *(Embryo_Cell *)(data + (int)stk) + sizeof(Embryo_Cell); /* remove 
parameters from the stack */
-            ep->stk = stk;
-            break;
-          case EMBRYO_OP_CALL:
-            PUSH(((unsigned char *)cip - code) + sizeof(Embryo_Cell));/* skip address 
*/
-            cip = JUMPABS(code, cip); /* jump to the address */
-            break;
-          case EMBRYO_OP_CALL_PRI:
-            PUSH((unsigned char *)cip - code);
-            cip = (Embryo_Cell *)(code + (int)pri);
-          break;
-          case EMBRYO_OP_JUMP:
-            /* since the GETPARAM() macro modifies cip, you cannot
-             * do GETPARAM(cip) directly */
-            cip = JUMPABS(code, cip);
-            break;
-          case EMBRYO_OP_JREL:
-            offs = *cip;
-            cip = (Embryo_Cell *)((unsigned char *)cip + (int)offs + 
sizeof(Embryo_Cell));
-            break;
-          case EMBRYO_OP_JZER:
-            if (pri == 0)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
-            break;
-          case EMBRYO_OP_JNZ:
-            if (pri != 0)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+          case 1:
+            pri = hdr->dat;
             break;
-          case EMBRYO_OP_JEQ:
-            if (pri==alt)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+          case 2:
+            pri = hea;
             break;
-          case EMBRYO_OP_JNEQ:
-            if (pri != alt)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+          case 3:
+            pri = ep->stp;
             break;
-          case EMBRYO_OP_JLESS:
-            if ((Embryo_UCell)pri < (Embryo_UCell)alt)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+          case 4:
+            pri = stk;
             break;
-          case EMBRYO_OP_JLEQ:
-            if ((Embryo_UCell)pri <= (Embryo_UCell)alt)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+          case 5:
+            pri = frm;
             break;
-          case EMBRYO_OP_JGRTR:
-            if ((Embryo_UCell)pri > (Embryo_UCell)alt)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+          case 6:
+            pri = (Embryo_Cell)((unsigned char *)cip - code);
             break;
-          case EMBRYO_OP_JGEQ:
-            if ((Embryo_UCell)pri >= (Embryo_UCell)alt)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+          default:
+            ABORT(ep, EMBRYO_ERROR_INVINSTR);
             break;
-          case EMBRYO_OP_JSLESS:
-            if (pri < alt)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+         }
+       BREAK;
+       CASE(EMBRYO_OP_SCTRL);
+       GETPARAM(offs);
+       switch (offs)
+         {
+          case 0:
+          case 1:
+          case 2:
+            hea = pri;
             break;
-          case EMBRYO_OP_JSLEQ:
-            if (pri <= alt)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+          case 3:
+            /* cannot change these parameters */
             break;
-          case EMBRYO_OP_JSGRTR:
-            if (pri > alt)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+          case 4:
+            stk = pri;
             break;
-          case EMBRYO_OP_JSGEQ:
-            if (pri >= alt)
-              cip = JUMPABS(code, cip);
-            else
-              cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+          case 5:
+            frm = pri;
             break;
-          case EMBRYO_OP_SHL:
-            pri <<= alt;
+          case 6:
+            cip = (Embryo_Cell *)(code + (int)pri);
             break;
-          case EMBRYO_OP_SHR:
-            pri = (Embryo_UCell)pri >> (int)alt;
+          default:
+            ABORT(ep, EMBRYO_ERROR_INVINSTR);
             break;
-          case EMBRYO_OP_SSHR:
-            pri >>= alt;
-            break;
-          case EMBRYO_OP_SHL_C_PRI:
-            GETPARAM(offs);
-            pri <<= offs;
-            break;
-          case EMBRYO_OP_SHL_C_ALT:
-            GETPARAM(offs);
-            alt <<= offs;
-            break;
-          case EMBRYO_OP_SHR_C_PRI:
-            GETPARAM(offs);
-            pri = (Embryo_UCell)pri >> (int)offs;
-            break;
-          case EMBRYO_OP_SHR_C_ALT:
-            GETPARAM(offs);
-            alt = (Embryo_UCell)alt >> (int)offs;
-            break;
-          case EMBRYO_OP_SMUL:
-            pri *= alt;
-            break;
-          case EMBRYO_OP_SDIV:
-            if (alt == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
-            /* divide must always round down; this is a bit
-             * involved to do in a machine-independent way.
-             */
-            offs = ((pri % alt) + alt) % alt; /* true modulus */
-            pri = (pri - offs) / alt;         /* division result */
-            alt = offs;
-            break;
-          case EMBRYO_OP_SDIV_ALT:
-            if (pri == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
-            /* divide must always round down; this is a bit
-             * involved to do in a machine-independent way.
-             */
-            offs = ((alt % pri) + pri) % pri; /* true modulus */
-            pri = (alt - offs) / pri;         /* division result */
-            alt = offs;
-            break;
-          case EMBRYO_OP_UMUL:
-            pri = (Embryo_UCell)pri * (Embryo_UCell)alt;
-            break;
-          case EMBRYO_OP_UDIV:
-            if (alt == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
-            offs = (Embryo_UCell)pri % (Embryo_UCell)alt; /* temporary storage */
-            pri = (Embryo_UCell)pri / (Embryo_UCell)alt;
-            alt = offs;
-            break;
-          case EMBRYO_OP_UDIV_ALT:
-            if (pri == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
-            offs = (Embryo_UCell)alt % (Embryo_UCell)pri;     /* temporary storage */
-            pri = (Embryo_UCell)alt / (Embryo_UCell)pri;
-            alt = offs;
-            break;
-          case EMBRYO_OP_ADD:
-            pri += alt;
-            break;
-          case EMBRYO_OP_SUB:
-            pri -= alt;
-            break;
-          case EMBRYO_OP_SUB_ALT:
-            pri = alt - pri;
-            break;
-          case EMBRYO_OP_AND:
-            pri &= alt;
-            break;
-          case EMBRYO_OP_OR:
-            pri |= alt;
-            break;
-          case EMBRYO_OP_XOR:
-            pri ^= alt;
-            break;
-          case EMBRYO_OP_NOT:
-            pri = !pri;
-            break;
-          case EMBRYO_OP_NEG:
-            pri = -pri;
-            break;
-          case EMBRYO_OP_INVERT:
-            pri = ~pri;
-            break;
-          case EMBRYO_OP_ADD_C:
-            GETPARAM(offs);
-            pri += offs;
-            break;
-          case EMBRYO_OP_SMUL_C:
-            GETPARAM(offs);
-            pri *= offs;
-            break;
-          case EMBRYO_OP_ZERO_PRI:
-            pri = 0;
-            break;
-          case EMBRYO_OP_ZERO_ALT:
-            alt = 0;
-            break;
-          case EMBRYO_OP_ZERO:
-            GETPARAM(offs);
-            *(Embryo_Cell *)(data + (int)offs) = 0;
-            break;
-          case EMBRYO_OP_ZERO_S:
-            GETPARAM(offs);
-            *(Embryo_Cell *)(data + (int)frm + (int)offs) = 0;
-            break;
-          case EMBRYO_OP_SIGN_PRI:
-            if ((pri & 0xff) >= 0x80) pri |= ~(Embryo_UCell)0xff;
-            break;
-          case EMBRYO_OP_SIGN_ALT:
-            if ((alt & 0xff) >= 0x80) alt |= ~(Embryo_UCell)0xff;
-            break;
-          case EMBRYO_OP_EQ:
-            pri = (pri == alt) ? 1 : 0;
-            break;
-          case EMBRYO_OP_NEQ:
-            pri = (pri != alt) ? 1 : 0;
-            break;
-          case EMBRYO_OP_LESS:
-            pri = ((Embryo_UCell)pri < (Embryo_UCell)alt) ? 1 : 0;
-            break;
-          case EMBRYO_OP_LEQ:
-          pri = ((Embryo_UCell)pri <= (Embryo_UCell)alt) ? 1 : 0;
-            break;
-          case EMBRYO_OP_GRTR:
-            pri = ((Embryo_UCell)pri > (Embryo_UCell)alt) ? 1 : 0;
-          break;
-          case EMBRYO_OP_GEQ:
-            pri = ((Embryo_UCell)pri >= (Embryo_UCell)alt) ? 1 : 0;
-            break;
-          case EMBRYO_OP_SLESS:
-            pri = (pri < alt) ? 1 : 0;
-            break;
-          case EMBRYO_OP_SLEQ:
-            pri = (pri <= alt) ? 1 : 0;
-            break;
-          case EMBRYO_OP_SGRTR:
-            pri = (pri > alt) ? 1 : 0;
-            break;
-          case EMBRYO_OP_SGEQ:
-            pri = (pri >= alt) ? 1 : 0;
-            break;
-          case EMBRYO_OP_EQ_C_PRI:
-            GETPARAM(offs);
-            pri = (pri == offs) ? 1 : 0;
-            break;
-          case EMBRYO_OP_EQ_C_ALT:
-            GETPARAM(offs);
-            pri = (alt == offs) ? 1 : 0;
-            break;
-          case EMBRYO_OP_INC_PRI:
-            pri++;
-            break;
-          case EMBRYO_OP_INC_ALT:
-            alt++;
-            break;
-          case EMBRYO_OP_INC:
-            GETPARAM(offs);
-            *(Embryo_Cell *)(data + (int)offs) += 1;
-            break;
-          case EMBRYO_OP_INC_S:
-            GETPARAM(offs);
-            *(Embryo_Cell *)(data + (int)frm + (int)offs) += 1;
-            break;
-          case EMBRYO_OP_INC_I:
-            *(Embryo_Cell *)(data + (int)pri) += 1;
-            break;
-          case EMBRYO_OP_DEC_PRI:
-            pri--;
-            break;
-          case EMBRYO_OP_DEC_ALT:
-            alt--;
-            break;
-          case EMBRYO_OP_DEC:
-            GETPARAM(offs);
-            *(Embryo_Cell *)(data + (int)offs) -= 1;
-            break;
-          case EMBRYO_OP_DEC_S:
-            GETPARAM(offs);
-            *(Embryo_Cell *)(data + (int)frm + (int)offs) -= 1;
-            break;
-          case EMBRYO_OP_DEC_I:
-            *(Embryo_Cell *)(data + (int)pri) -= 1;
-            break;
-          case EMBRYO_OP_MOVS:
-            GETPARAM(offs);
-            CHKMEM(pri);
-            CHKMEM(pri + offs);
-            CHKMEM(alt);
-            CHKMEM(alt + offs);
-            memcpy(data+(int)alt, data+(int)pri, (int)offs);
-            break;
-          case EMBRYO_OP_CMPS:
-            GETPARAM(offs);
-            CHKMEM(pri);
-            CHKMEM(pri + offs);
-            CHKMEM(alt);
-            CHKMEM(alt + offs);
-            pri = memcmp(data + (int)alt, data + (int)pri, (int)offs);
-            break;
-          case EMBRYO_OP_FILL:
-            GETPARAM(offs);
-            CHKMEM(alt);
-            CHKMEM(alt + offs);
-            for (i = (int)alt; 
-                 (size_t)offs >= sizeof(Embryo_Cell); 
-                 i += sizeof(Embryo_Cell), offs -= sizeof(Embryo_Cell))
-              *(Embryo_Cell *)(data + i) = pri;
-            break;
-          case EMBRYO_OP_HALT:
-            GETPARAM(offs);
-            ep->retval = pri;
-            /* store complete status */
-            ep->frm = frm;
-            ep->stk = stk;
-            ep->hea = hea;
-            ep->pri = pri;
-            ep->alt = alt;
-            ep->cip = (Embryo_Cell)((unsigned char*)cip - code);
-            if (offs == EMBRYO_ERROR_SLEEP)
+         }
+       BREAK;
+       CASE(EMBRYO_OP_MOVE_PRI);
+       pri = alt;
+       BREAK;
+       CASE(EMBRYO_OP_MOVE_ALT);
+       alt = pri;
+       BREAK;
+       CASE(EMBRYO_OP_XCHG);
+       offs = pri;         /* offs is a temporary variable */
+       pri = alt;
+       alt = offs;
+       BREAK;
+       CASE(EMBRYO_OP_PUSH_PRI);
+       PUSH(pri);
+       BREAK;
+       CASE(EMBRYO_OP_PUSH_ALT);
+       PUSH(alt);
+       BREAK;
+       CASE(EMBRYO_OP_PUSH_C);
+       GETPARAM(offs);
+       PUSH(offs);
+       BREAK;
+       CASE(EMBRYO_OP_PUSH_R);
+       GETPARAM(offs);
+       while (offs--) PUSH(pri);
+       BREAK;
+       CASE(EMBRYO_OP_PUSH);
+       GETPARAM(offs);
+       PUSH(*(Embryo_Cell *)(data + (int)offs));
+       BREAK;
+       CASE(EMBRYO_OP_PUSH_S);
+       GETPARAM(offs);
+       PUSH(*(Embryo_Cell *)(data + (int)frm + (int)offs));
+       BREAK;
+       CASE(EMBRYO_OP_POP_PRI);
+       POP(pri);
+       BREAK;
+       CASE(EMBRYO_OP_POP_ALT);
+       POP(alt);
+       BREAK;
+       CASE(EMBRYO_OP_STACK);
+       GETPARAM(offs);
+       alt = stk;
+       stk += offs;
+       CHKMARGIN();
+       CHKSTACK();
+       BREAK;
+       CASE(EMBRYO_OP_HEAP);
+       GETPARAM(offs);
+       alt = hea;
+       hea += offs;
+       CHKMARGIN();
+       CHKHEAP();
+       BREAK;
+       CASE(EMBRYO_OP_PROC);
+       PUSH(frm);
+       frm = stk;
+       CHKMARGIN();
+       BREAK;
+       CASE(EMBRYO_OP_RET);
+       POP(frm);
+       POP(offs);
+       if ((Embryo_UCell)offs >= codesize)
+         ABORT(ep, EMBRYO_ERROR_MEMACCESS);
+       cip = (Embryo_Cell *)(code + (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_RETN);
+       POP(frm);
+       POP(offs);
+       if ((Embryo_UCell)offs >= codesize)
+         ABORT(ep, EMBRYO_ERROR_MEMACCESS);
+       cip = (Embryo_Cell *)(code + (int)offs);
+       stk += *(Embryo_Cell *)(data + (int)stk) + sizeof(Embryo_Cell); /* remove 
parameters from the stack */
+       ep->stk = stk;
+       BREAK;
+       CASE(EMBRYO_OP_CALL);
+       PUSH(((unsigned char *)cip - code) + sizeof(Embryo_Cell));/* skip address */
+       cip = JUMPABS(code, cip); /* jump to the address */
+       BREAK;
+       CASE(EMBRYO_OP_CALL_PRI);
+       PUSH((unsigned char *)cip - code);
+       cip = (Embryo_Cell *)(code + (int)pri);
+       BREAK;
+       CASE(EMBRYO_OP_JUMP);
+       /* since the GETPARAM() macro modifies cip, you cannot
+        * do GETPARAM(cip) directly */
+       cip = JUMPABS(code, cip);
+       BREAK;
+       CASE(EMBRYO_OP_JREL);
+       offs = *cip;
+       cip = (Embryo_Cell *)((unsigned char *)cip + (int)offs + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JZER);
+       if (pri == 0)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JNZ);
+       if (pri != 0)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JEQ);
+       if (pri==alt)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JNEQ);
+       if (pri != alt)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JLESS);
+       if ((Embryo_UCell)pri < (Embryo_UCell)alt)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JLEQ);
+       if ((Embryo_UCell)pri <= (Embryo_UCell)alt)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JGRTR);
+       if ((Embryo_UCell)pri > (Embryo_UCell)alt)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JGEQ);
+       if ((Embryo_UCell)pri >= (Embryo_UCell)alt)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JSLESS);
+       if (pri < alt)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JSLEQ);
+       if (pri <= alt)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JSGRTR);
+       if (pri > alt)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_JSGEQ);
+       if (pri >= alt)
+         cip = JUMPABS(code, cip);
+       else
+         cip = (Embryo_Cell *)((unsigned char *)cip + sizeof(Embryo_Cell));
+       BREAK;
+       CASE(EMBRYO_OP_SHL);
+       pri <<= alt;
+       BREAK;
+       CASE(EMBRYO_OP_SHR);
+       pri = (Embryo_UCell)pri >> (int)alt;
+       BREAK;
+       CASE(EMBRYO_OP_SSHR);
+       pri >>= alt;
+       BREAK;
+       CASE(EMBRYO_OP_SHL_C_PRI);
+       GETPARAM(offs);
+       pri <<= offs;
+       BREAK;
+       CASE(EMBRYO_OP_SHL_C_ALT);
+       GETPARAM(offs);
+       alt <<= offs;
+       BREAK;
+       CASE(EMBRYO_OP_SHR_C_PRI);
+       GETPARAM(offs);
+       pri = (Embryo_UCell)pri >> (int)offs;
+       BREAK;
+       CASE(EMBRYO_OP_SHR_C_ALT);
+       GETPARAM(offs);
+       alt = (Embryo_UCell)alt >> (int)offs;
+       BREAK;
+       CASE(EMBRYO_OP_SMUL);
+       pri *= alt;
+       BREAK;
+       CASE(EMBRYO_OP_SDIV);
+       if (alt == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
+       /* divide must always round down; this is a bit
+        * involved to do in a machine-independent way.
+        */
+       offs = ((pri % alt) + alt) % alt; /* true modulus */
+       pri = (pri - offs) / alt;         /* division result */
+       alt = offs;
+       BREAK;
+       CASE(EMBRYO_OP_SDIV_ALT);
+       if (pri == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
+       /* divide must always round down; this is a bit
+        * involved to do in a machine-independent way.
+        */
+       offs = ((alt % pri) + pri) % pri; /* true modulus */
+       pri = (alt - offs) / pri;         /* division result */
+       alt = offs;
+       BREAK;
+       CASE(EMBRYO_OP_UMUL);
+       pri = (Embryo_UCell)pri * (Embryo_UCell)alt;
+       BREAK;
+       CASE(EMBRYO_OP_UDIV);
+       if (alt == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
+       offs = (Embryo_UCell)pri % (Embryo_UCell)alt; /* temporary storage */
+       pri = (Embryo_UCell)pri / (Embryo_UCell)alt;
+       alt = offs;
+       BREAK;
+       CASE(EMBRYO_OP_UDIV_ALT);
+       if (pri == 0) ABORT(ep, EMBRYO_ERROR_DIVIDE);
+       offs = (Embryo_UCell)alt % (Embryo_UCell)pri; /* temporary storage */
+       pri = (Embryo_UCell)alt / (Embryo_UCell)pri;
+       alt = offs;
+       BREAK;
+       CASE(EMBRYO_OP_ADD);
+       pri += alt;
+       BREAK;
+       CASE(EMBRYO_OP_SUB);
+       pri -= alt;
+       BREAK;
+       CASE(EMBRYO_OP_SUB_ALT);
+       pri = alt - pri;
+       BREAK;
+       CASE(EMBRYO_OP_AND);
+       pri &= alt;
+       BREAK;
+       CASE(EMBRYO_OP_OR);
+       pri |= alt;
+       BREAK;
+       CASE(EMBRYO_OP_XOR);
+       pri ^= alt;
+       BREAK;
+       CASE(EMBRYO_OP_NOT);
+       pri = !pri;
+       BREAK;
+       CASE(EMBRYO_OP_NEG);
+       pri = -pri;
+       BREAK;
+       CASE(EMBRYO_OP_INVERT);
+       pri = ~pri;
+       BREAK;
+       CASE(EMBRYO_OP_ADD_C);
+       GETPARAM(offs);
+       pri += offs;
+       BREAK;
+       CASE(EMBRYO_OP_SMUL_C);
+       GETPARAM(offs);
+       pri *= offs;
+       BREAK;
+       CASE(EMBRYO_OP_ZERO_PRI);
+       pri = 0;
+       BREAK;
+       CASE(EMBRYO_OP_ZERO_ALT);
+       alt = 0;
+       BREAK;
+       CASE(EMBRYO_OP_ZERO);
+       GETPARAM(offs);
+       *(Embryo_Cell *)(data + (int)offs) = 0;
+       BREAK;
+       CASE(EMBRYO_OP_ZERO_S);
+       GETPARAM(offs);
+       *(Embryo_Cell *)(data + (int)frm + (int)offs) = 0;
+       BREAK;
+       CASE(EMBRYO_OP_SIGN_PRI);
+       if ((pri & 0xff) >= 0x80) pri |= ~(Embryo_UCell)0xff;
+       BREAK;
+       CASE(EMBRYO_OP_SIGN_ALT);
+       if ((alt & 0xff) >= 0x80) alt |= ~(Embryo_UCell)0xff;
+       BREAK;
+       CASE(EMBRYO_OP_EQ);
+       pri = (pri == alt) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_NEQ);
+       pri = (pri != alt) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_LESS);
+       pri = ((Embryo_UCell)pri < (Embryo_UCell)alt) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_LEQ);
+       pri = ((Embryo_UCell)pri <= (Embryo_UCell)alt) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_GRTR);
+       pri = ((Embryo_UCell)pri > (Embryo_UCell)alt) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_GEQ);
+       pri = ((Embryo_UCell)pri >= (Embryo_UCell)alt) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_SLESS);
+       pri = (pri < alt) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_SLEQ);
+       pri = (pri <= alt) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_SGRTR);
+       pri = (pri > alt) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_SGEQ);
+       pri = (pri >= alt) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_EQ_C_PRI);
+       GETPARAM(offs);
+       pri = (pri == offs) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_EQ_C_ALT);
+       GETPARAM(offs);
+       pri = (alt == offs) ? 1 : 0;
+       BREAK;
+       CASE(EMBRYO_OP_INC_PRI);
+       pri++;
+       BREAK;
+       CASE(EMBRYO_OP_INC_ALT);
+       alt++;
+       BREAK;
+       CASE(EMBRYO_OP_INC);
+       GETPARAM(offs);
+       *(Embryo_Cell *)(data + (int)offs) += 1;
+       BREAK;
+       CASE(EMBRYO_OP_INC_S);
+       GETPARAM(offs);
+       *(Embryo_Cell *)(data + (int)frm + (int)offs) += 1;
+       BREAK;
+       CASE(EMBRYO_OP_INC_I);
+       *(Embryo_Cell *)(data + (int)pri) += 1;
+       BREAK;
+       CASE(EMBRYO_OP_DEC_PRI);
+       pri--;
+       BREAK;
+       CASE(EMBRYO_OP_DEC_ALT);
+       alt--;
+       BREAK;
+       CASE(EMBRYO_OP_DEC);
+       GETPARAM(offs);
+       *(Embryo_Cell *)(data + (int)offs) -= 1;
+       BREAK;
+       CASE(EMBRYO_OP_DEC_S);
+       GETPARAM(offs);
+       *(Embryo_Cell *)(data + (int)frm + (int)offs) -= 1;
+       BREAK;
+       CASE(EMBRYO_OP_DEC_I);
+       *(Embryo_Cell *)(data + (int)pri) -= 1;
+       BREAK;
+       CASE(EMBRYO_OP_MOVS);
+       GETPARAM(offs);
+       CHKMEM(pri);
+       CHKMEM(pri + offs);
+       CHKMEM(alt);
+       CHKMEM(alt + offs);
+       memcpy(data+(int)alt, data+(int)pri, (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_CMPS);
+       GETPARAM(offs);
+       CHKMEM(pri);
+       CHKMEM(pri + offs);
+       CHKMEM(alt);
+       CHKMEM(alt + offs);
+       pri = memcmp(data + (int)alt, data + (int)pri, (int)offs);
+       BREAK;
+       CASE(EMBRYO_OP_FILL);
+       GETPARAM(offs);
+       CHKMEM(alt);
+       CHKMEM(alt + offs);
+       for (i = (int)alt; 
+            (size_t)offs >= sizeof(Embryo_Cell); 
+            i += sizeof(Embryo_Cell), offs -= sizeof(Embryo_Cell))
+         *(Embryo_Cell *)(data + i) = pri;
+       BREAK;
+       CASE(EMBRYO_OP_HALT);
+       GETPARAM(offs);
+       ep->retval = pri;
+       /* store complete status */
+       ep->frm = frm;
+       ep->stk = stk;
+       ep->hea = hea;
+       ep->pri = pri;
+       ep->alt = alt;
+       ep->cip = (Embryo_Cell)((unsigned char*)cip - code);
+       if (offs == EMBRYO_ERROR_SLEEP)
+         {
+            ep->reset_stk = reset_stk;
+            ep->reset_hea = reset_hea;
+            ep->run_count--;
+            return EMBRYO_PROGRAM_SLEEP;
+         }
+       OK(ep, (int)offs);
+       CASE(EMBRYO_OP_BOUNDS);
+       GETPARAM(offs);
+       if ((Embryo_UCell)pri > (Embryo_UCell)offs)
+         ABORT(ep, EMBRYO_ERROR_BOUNDS);
+       BREAK;
+       CASE(EMBRYO_OP_SYSREQ_PRI);
+       /* save a few registers */
+       ep->cip = (Embryo_Cell)((unsigned char *)cip - code);
+       ep->hea = hea;
+       ep->frm = frm;
+       ep->stk = stk;
+       num = _embryo_native_call(ep, pri, &pri, (Embryo_Cell *)(data + (int)stk));
+       if (num != EMBRYO_ERROR_NONE)
+         {
+            if (num == EMBRYO_ERROR_SLEEP)
               {
+                 ep->pri = pri;
+                 ep->alt = alt;
                  ep->reset_stk = reset_stk;
                  ep->reset_hea = reset_hea;
                  ep->run_count--;
                  return EMBRYO_PROGRAM_SLEEP;
               }
-            OK(ep, (int)offs);
-          case EMBRYO_OP_BOUNDS:
-            GETPARAM(offs);
-            if ((Embryo_UCell)pri > (Embryo_UCell)offs)
-              ABORT(ep, EMBRYO_ERROR_BOUNDS);
-            break;
-          case EMBRYO_OP_SYSREQ_PRI:
-            /* save a few registers */
-            ep->cip = (Embryo_Cell)((unsigned char *)cip - code);
-            ep->hea = hea;
-            ep->frm = frm;
-            ep->stk = stk;
-            num = _embryo_native_call(ep, pri, &pri, (Embryo_Cell *)(data + 
(int)stk));
-            if (num != EMBRYO_ERROR_NONE)
+            ABORT(ep, num);
+         }
+       BREAK;
+       CASE(EMBRYO_OP_SYSREQ_C);
+       GETPARAM(offs);
+       /* save a few registers */
+       ep->cip = (Embryo_Cell)((unsigned char *)cip - code);
+       ep->hea = hea;
+       ep->frm = frm;
+       ep->stk = stk;
+       num = _embryo_native_call(ep, offs, &pri, (Embryo_Cell *)(data + (int)stk));
+       if (num != EMBRYO_ERROR_NONE)
+         {
+            if (num == EMBRYO_ERROR_SLEEP)
               {
-                 if (num == EMBRYO_ERROR_SLEEP)
-                   {
-                      ep->pri = pri;
-                      ep->alt = alt;
-                      ep->reset_stk = reset_stk;
-                      ep->reset_hea = reset_hea;
-                      ep->run_count--;
-                      return EMBRYO_PROGRAM_SLEEP;
-                   }
-                 ABORT(ep, num);
+                 ep->pri = pri;
+                 ep->alt = alt;
+                 ep->reset_stk = reset_stk;
+                 ep->reset_hea = reset_hea;
+                 ep->run_count--;
+                 return EMBRYO_PROGRAM_SLEEP;
               }
-            break;
-          case EMBRYO_OP_SYSREQ_C:
-            GETPARAM(offs);
-            /* save a few registers */
-            ep->cip = (Embryo_Cell)((unsigned char *)cip - code);
-            ep->hea = hea;
-            ep->frm = frm;
-            ep->stk = stk;
-            num = _embryo_native_call(ep, offs, &pri, (Embryo_Cell *)(data + 
(int)stk));
-            if (num != EMBRYO_ERROR_NONE)
               {
-                 if (num == EMBRYO_ERROR_SLEEP)
-                   {
-                      ep->pri = pri;
-                      ep->alt = alt;
-                      ep->reset_stk = reset_stk;
-                      ep->reset_hea = reset_hea;
-                      ep->run_count--;
-                      return EMBRYO_PROGRAM_SLEEP;
-                   }
+                 Embryo_Header    *hdr;
+                 int i, num;
+                 Embryo_Func_Stub *func_entry;
+                 
+                 hdr = (Embryo_Header *)ep->code;
+                 num = NUMENTRIES(hdr, natives, libraries);
+                 func_entry = GETENTRY(hdr, natives, 0);
+                 for (i = 0; i < num; i++)
                    {
-                      Embryo_Header    *hdr;
-                      int i, num;
-                      Embryo_Func_Stub *func_entry;
+                      char *entry_name;
                       
-                      hdr = (Embryo_Header *)ep->code;
-                      num = NUMENTRIES(hdr, natives, libraries);
-                      func_entry = GETENTRY(hdr, natives, 0);
-                      for (i = 0; i < num; i++)
-                        {
-                           char *entry_name;
-                           
-                           entry_name = GETENTRYNAME(hdr, func_entry);
-                           if (i == offs)
-                             printf("EMBRYO: CALL [%i] %s() non-existant!\n", i, 
entry_name);
-                           func_entry =
-                             (Embryo_Func_Stub *)((unsigned char *)func_entry + 
hdr->defsize);
-                        }
-                   }
-                 ABORT(ep, num);
-              }
-            break;
-          case EMBRYO_OP_SYSREQ_D:
-            GETPARAM(offs);
-            /* save a few registers */
-            ep->cip = (Embryo_Cell)((unsigned char *)cip - code);
-            ep->hea = hea;
-            ep->frm = frm;
-            ep->stk = stk;
-            num = _embryo_native_call(ep, offs, &pri, (Embryo_Cell *)(data + 
(int)stk));
-            if (num != EMBRYO_ERROR_NONE)
-              {
-                 if (num == EMBRYO_ERROR_SLEEP)
-                   {
-                      ep->pri = pri;
-                      ep->alt = alt;
-                      ep->reset_stk = reset_stk;
-                      ep->reset_hea = reset_hea;
-                      ep->run_count--;
-                      return EMBRYO_PROGRAM_SLEEP;
+                      entry_name = GETENTRYNAME(hdr, func_entry);
+                      if (i == offs)
+                        printf("EMBRYO: CALL [%i] %s() non-existant!\n", i, 
entry_name);
+                      func_entry =
+                        (Embryo_Func_Stub *)((unsigned char *)func_entry + 
hdr->defsize);
                    }
-                 ABORT(ep, ep->error);
               }
-            break;
-          case EMBRYO_OP_JUMP_PRI:
-            cip = (Embryo_Cell *)(code + (int)pri);
-            break;
-          case EMBRYO_OP_SWITCH:
+            ABORT(ep, num);
+         }
+       BREAK;
+       CASE(EMBRYO_OP_SYSREQ_D);
+       GETPARAM(offs);
+       /* save a few registers */
+       ep->cip = (Embryo_Cell)((unsigned char *)cip - code);
+       ep->hea = hea;
+       ep->frm = frm;
+       ep->stk = stk;
+       num = _embryo_native_call(ep, offs, &pri, (Embryo_Cell *)(data + (int)stk));
+       if (num != EMBRYO_ERROR_NONE)
+         {
+            if (num == EMBRYO_ERROR_SLEEP)
               {
-                 Embryo_Cell *cptr;
-
-                 /* +1, to skip the "casetbl" opcode */
-                 cptr = (Embryo_Cell *)(code + (*cip)) + 1;
-                 /* number of records in the case table */
-                 num = (int)(*cptr);
-                 /* preset to "none-matched" case */
-                 cip = (Embryo_Cell *)(code + *(cptr + 1));
-                 for (cptr += 2; 
-                      (num > 0) && (*cptr != pri); 
-                      num--, cptr += 2);
-                 /* case found */
-                 if (num > 0)
-                   cip = (Embryo_Cell *)(code + *(cptr + 1));
+                 ep->pri = pri;
+                 ep->alt = alt;
+                 ep->reset_stk = reset_stk;
+                 ep->reset_hea = reset_hea;
+                 ep->run_count--;
+                 return EMBRYO_PROGRAM_SLEEP;
               }
-            break;
-          case EMBRYO_OP_SWAP_PRI:
-            offs = *(Embryo_Cell *)(data + (int)stk);
-            *(Embryo_Cell *)(data + (int)stk) = pri;
-            pri = offs;
-            break;
-          case EMBRYO_OP_SWAP_ALT:
-            offs = *(Embryo_Cell *)(data + (int)stk);
-            *(Embryo_Cell *)(data + (int)stk) = alt;
-            alt = offs;
-            break;
-          case EMBRYO_OP_PUSHADDR:
-            GETPARAM(offs);
-            PUSH(frm + offs);
-            break;
-          case EMBRYO_OP_NOP:
-            break;
-          default:
-            ABORT(ep, EMBRYO_ERROR_INVINSTR);
+            ABORT(ep, ep->error);
+         }
+       BREAK;
+       CASE(EMBRYO_OP_JUMP_PRI);
+       cip = (Embryo_Cell *)(code + (int)pri);
+       BREAK;
+       CASE(EMBRYO_OP_SWITCH);
+         {
+            Embryo_Cell *cptr;
+            
+            /* +1, to skip the "casetbl" opcode */
+            cptr = (Embryo_Cell *)(code + (*cip)) + 1;
+            /* number of records in the case table */
+            num = (int)(*cptr);
+            /* preset to "none-matched" case */
+            cip = (Embryo_Cell *)(code + *(cptr + 1));
+            for (cptr += 2; 
+                 (num > 0) && (*cptr != pri); 
+                 num--, cptr += 2);
+            /* case found */
+            if (num > 0)
+              cip = (Embryo_Cell *)(code + *(cptr + 1));
          }
+       BREAK;
+       CASE(EMBRYO_OP_SWAP_PRI);
+       offs = *(Embryo_Cell *)(data + (int)stk);
+       *(Embryo_Cell *)(data + (int)stk) = pri;
+       pri = offs;
+       BREAK;
+       CASE(EMBRYO_OP_SWAP_ALT);
+       offs = *(Embryo_Cell *)(data + (int)stk);
+       *(Embryo_Cell *)(data + (int)stk) = alt;
+       alt = offs;
+       BREAK;
+       CASE(EMBRYO_OP_PUSHADDR);
+       GETPARAM(offs);
+       PUSH(frm + offs);
+       BREAK;
+       CASE(EMBRYO_OP_NOP);
+       BREAK;
+       CASE(EMBRYO_OP_NONE);
+       CASE(EMBRYO_OP_FILE);
+       CASE(EMBRYO_OP_LINE);
+       CASE(EMBRYO_OP_SYMBOL);
+       CASE(EMBRYO_OP_SRANGE);
+       CASE(EMBRYO_OP_CASETBL);
+       CASE(EMBRYO_OP_SYMTAG);
+       BREAK;
+#ifndef EMBRYO_EXEC_JUMPTABLE
+      default:
+       ABORT(ep, EMBRYO_ERROR_INVINSTR);
+#endif         
+       SWITCHEND;
      }
    ep->run_count--;
    




-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
enlightenment-cvs mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to