home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / oxcc1433.zip / SRC / BTERP.C < prev    next >
C/C++ Source or Header  |  1995-11-06  |  70KB  |  2,885 lines

  1. /* 
  2.     bterp.c -- v1.430 interpreter prototype for oxcc byte codes
  3.  
  4.     Copyright (c) 1995
  5.     Norman D. Culver dba
  6.     Oxbow Software
  7.     1323 S.E. 17th Street #662
  8.     Ft. Lauderdale, FL 33316
  9.     (305) 527-1663 Voice
  10.     (305) 760-7584 Fax
  11.     (305) 760-4679 Data
  12.     norman.culver@channel1.com
  13.     All rights reserved.
  14.  
  15.  * Redistribution and use in source and binary forms are permitted
  16.  * provided that: (1) source distributions retain this entire copyright
  17.  * notice and comment, and (2) distributions including binaries display
  18.  * the following acknowledgement:  ``This product includes software
  19.  * developed by Norman D. Culver dba Oxbow Software''
  20.  * in the documentation or other materials provided with the distribution
  21.  * and in all advertising materials mentioning features or use of this
  22.  * software.
  23.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  24.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  25.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  26.  
  27. */
  28.  
  29. #define SUPPORT_LONG_LONG 1
  30. #define SUPPORT_LONG_DOUBLE 1
  31.  
  32. #define NEED_BYTECODES 1
  33. #define NEED_AOUT_FORMAT 1
  34. #include "oxbytes.h"
  35.  
  36. #define NEED_FUNCTHUNK 1
  37. #include "oxanf.h"
  38. #include <stdlib.h>
  39. #include <setjmp.h>
  40. #include <stdio.h>
  41.  
  42. #define PROG bterp
  43. #define USING_FRAMEWORK 1
  44.  
  45. #define SWITCHMOD 1009
  46. typedef struct _key
  47. {
  48.     unsigned long k[2];
  49.     unsigned long hv;
  50. } KEY, *KEYP;
  51.  
  52. typedef struct _nodeS
  53. {
  54.     unsigned long value;
  55.     unsigned long key[2];
  56.     struct _nodeS *fptr;
  57. } NodeS, *NodePS;
  58.  
  59. typedef struct _callblk {
  60.     void *loc;
  61.     char *es;
  62.     unsigned short argofs;
  63.     unsigned short flags;
  64.     long argsiz;
  65.     char *base_stack;            /* must be last element */
  66. } *PCB;
  67.  
  68. typedef struct _stakblk {
  69.     void *backlink;
  70.     long first_loc;
  71.     long last_loc;
  72.     char *cbes;
  73.     void *thunkaddr;
  74.     int stksize;
  75. } SB, *PSB;
  76.  
  77. typedef struct _fe {
  78.     char *filename;
  79.     long string_size;
  80.     char *strings;
  81.     char *text_start_address;
  82.     char *data_start_address;
  83.     char *bss_start_address;
  84. } *FE;
  85.  
  86. typedef struct _iv {
  87.     struct _iv *piv;
  88.     char *text_base;
  89.     char *dd;
  90.     void **struclist;
  91.     long slcnt;
  92.     long strretcnt;
  93.     void *allocalist;
  94.     NodePS *swtable;
  95.     char *chunkbase;
  96.     void *chunklist;
  97.     long chunksize;
  98.     FE entry;
  99.     char *filename;
  100.     char *funcptr;
  101.     Pft ft;
  102.     long funcaddr;
  103.     long stksiz;
  104.     long argsiz;
  105.     long maxes;
  106.     char *base_stack;
  107.     char *e_stack;
  108.     jmp_buf jb;
  109. #define MAX_RUNARGS 15
  110.     long run_argcnt;
  111.     char *run_args[MAX_RUNARGS];
  112.     int debug;
  113. } *Piv;
  114.  
  115. typedef struct _retval {
  116.     void *ptr;
  117.     long p1;
  118.     long p2;
  119. } RV;
  120.  
  121. int cfeprintf(const char *fmt, ...);
  122.  
  123. void _ExternCall();
  124. void _ExternCallS();
  125. void *oxlink_load_bare_symb(const char *symb, int dynlink);
  126. void *oxlink_find_bare_func(const char *);
  127. void *oxlink_find_func(const char *);
  128. int oxlink_load_file(const char *);
  129. int oxlink_load_object(const char *);
  130. int oxlink_unload_file(const char *, int);
  131. void oxlink_demand_load(void);
  132. void oxlink_demand_noload(void);
  133. void *oxlink_get_entry_struct(const char *filename);
  134. char *oxlink_errstr(void);
  135.  
  136. static void* bterp_eval();
  137.  
  138. #define SZ (20)    /* size of evaluation stack frame */
  139.  
  140. #define MIN(a,b) ((a<b)?a:b)
  141.  
  142. #define SRC(a) (a<<4)
  143. #define G1(a) ((unsigned long)*((unsigned char*)(a)))
  144. #define G2(a) ((unsigned long)*((unsigned short*)(a)))
  145. #define G3(a) (*((unsigned long*)(a))&0x00ffffff)
  146. #define G4(a) (*((unsigned long*)(a)))
  147. #define G8(a) (*((double*)(a)))
  148. #define GX(a) (*((long double*)(a)))
  149. #define GP1(a) ((long)*((char*)(a)))
  150. #define GP2(a) ((long)*((short*)(a)))
  151. #define GP3(a) ((*((long*)(a))<<8)>>8)
  152. #define GP4(a) (*((long*)(a)))
  153.  
  154. #define NEG_ES(t) {*((t*)es)=-(*((t*)es));break;}
  155. #define NOT_ES(t) {*((t*)es)=!(*((t*)es));break;}
  156. #define NOT_ES1 {*es=(((long*)es)[0]==0&&((long*)es)[1]==0)?1:0;}
  157. #define COMP_ES(t) {*((t*)es)=~(*((t*)es));break;}
  158. #define TRUTH_ES(t) {*((long*)es)=(*((t*)es))?1:0;break;}
  159. #define TRUTH_ES1 {*((long*)es)=(((long*)es)[0]==0&&((long*)es)[1]==0)?0:1;}
  160. #define GT_ES(t) {*((long*)oes)=(*((t*)oes)>*((t*)es))?1:0;es=oes;break;}
  161. #define LT_ES(t) {*((long*)oes)=(*((t*)oes)<*((t*)es))?1:0;es=oes;break;}
  162. #define GE_ES(t) {*((long*)oes)=(*((t*)oes)>=*((t*)es))?1:0;es=oes;break;}
  163. #define LE_ES(t) {*((long*)oes)=(*((t*)oes)<=*((t*)es))?1:0;es=oes;break;}
  164. #define NE_ES(t) {*((long*)oes)=(*((t*)oes)!=*((t*)es))?1:0;es=oes;break;}
  165. #define EQ_ES(t) {*((long*)oes)=(*((t*)oes)==*((t*)es))?1:0;es=oes;break;}
  166. #define ADD_ES(t) {*((t*)oes)+=*((t*)es);es=oes;break;}
  167. #define SUB_ES(t) {*((t*)oes)-=*((t*)es);es=oes;break;}
  168. #define MUL_ES(t) {*((t*)oes)*=*((t*)es);es=oes;break;}
  169. #define DIV_ES(t) {*((t*)oes)/=*((t*)es);es=oes;break;}
  170. #define OR_ES(t)  {*((t*)oes)|=*((t*)es);es=oes;break;}
  171. #define AND_ES(t) {*((t*)oes)&=*((t*)es);es=oes;break;}
  172. #define XOR_ES(t) {*((t*)oes)^=*((t*)es);es=oes;break;}
  173. #define MOD_ES(t) {*((t*)oes)%=*((unsigned long*)es);es=oes;break;}
  174. #define MODL_ES(t) {*((t*)oes)%=*((unsigned long long*)es);es=oes;break;}
  175. #define MODI_ES(t) {*((t*)es)%=*((unsigned short*)np);pc+=2;break;}
  176. #define RSH_ES(t) {*((t*)oes)>>=*((unsigned char*)es);es=oes;break;}
  177. #define LSH_ES(t) {*((t*)oes)<<=*((unsigned char*)es);es=oes;break;}
  178. #define RSHI_ES(t) {*((t*)es)>>=*np;pc+=1;break;}
  179. #define LSHI_ES(t) {*((t*)es)<<=*np;pc+=1;break;}
  180. #define DEREF_ES(t) {*((long*)es)=**((t**)es);break;}
  181. #define UDEREF_ES(t) {*((unsigned long*)es)=**((t**)es);break;}
  182. #define FDEREF_ES(t) {*((t*)es)=**((t**)es);break;}
  183. #define DEREF1_ES(t) {*((long*)nes)=**((t**)es);es=nes;break;}
  184. #define UDEREF1_ES(t) {*((unsigned long*)nes)=**((t**)es);es=nes;break;}
  185. #define FDEREF1_ES(t) {*((t*)nes)=**((t**)es);es=nes;break;}
  186. #define SIGNE if(*(es+3)&0x80)*((long*)(es+4))=-1;else *((long*)(es+4))=0
  187. #define USIGNE *((long*)(es+4))=0
  188. #define LOADI1() {*((long*)nes)=GP1(np);es=nes;SIGNE;pc+=1;break;}
  189. #define LOADI2() {*((long*)nes)=GP2(np);es=nes;SIGNE;pc+=2;break;}
  190. #define LOADI4() {*((long*)nes)=GP4(np);es=nes;SIGNE;pc+=4;break;}
  191. #define LOADUI1() {*((unsigned long*)nes)=G1(np);es=nes;USIGNE;pc+=1;break;}
  192. #define LOADUI2() {*((unsigned long*)nes)=G2(np);es=nes;USIGNE;pc+=2;break;}
  193. #define LOADUI4() {*((unsigned long*)nes)=G4(np);es=nes;USIGNE;pc+=4;break;}
  194. #define LOADI8() {*((double*)nes)=G8(np);es=nes;pc+=8;break;}
  195. #define LOADIX() {*((long double*)nes)=GX(np);es=nes;pc+=XSZ;break;}
  196.  
  197. #define LOADADDRI1() {*((unsigned long*)nes)=(G1(np)<<2);es=nes;pc+=1;break;}
  198. #define LOADADDRI2() {*((unsigned long*)nes)=(G2(np)<<2);es=nes;pc+=2;break;}
  199. #define LOADADDRI3() {*((unsigned long*)nes)=(G3(np));es=nes;pc+=3;break;}
  200. #define LOADADDRI4() {*((unsigned long*)nes)=G4(np);es=nes;pc+=4;break;}
  201.  
  202. #define LOADSTK1(t) {*((t*)nes)=*((t*)(fs+(G1(np)<<2)));es=nes;pc+=1;break;}
  203. #define LOADSTK2(t) {*((t*)nes)=*((t*)(fs+(G2(np)<<2)));es=nes;pc+=2;break;}
  204. #define LOADSTK3(t) {*((t*)nes)=*((t*)(fs+(G3(np))));es=nes;pc+=3;break;}
  205.  
  206. #define STORSTK1(t) {*((t*)(fs+(G1(np)<<2)))=*((t*)es);es=oes;pc+=1;break;}
  207. #define STORSTK2(t) {*((t*)(fs+(G2(np)<<2)))=*((t*)es);es=oes;pc+=2;break;}
  208. #define STORSTK3(t) {*((t*)(fs+(G3(np)<<0)))=*((t*)es);es=oes;pc+=3;break;}
  209.  
  210. #define STORSTKI1(t) {*((t*)(fs+(G1(np)<<2)))=*((t*)(np+1));pc+=sizeof(t)+1;break;}
  211. #define STORSTKI2(t) {*((t*)(fs+(G2(np)<<2)))=*((t*)(np+2));pc+=sizeof(t)+2;break;}
  212. #define STORSTKI3(t) {*((t*)(fs+(G3(np)<<0)))=*((t*)(np+3));pc+=sizeof(t)+3;break;}
  213.  
  214. #define LOADMEM1(t) {*((t*)nes)=*((t*)(dd+(G1(np)<<2)));es=nes;pc+=1;break;}
  215. #define LOADMEM2(t) {*((t*)nes)=*((t*)(dd+(G2(np)<<2)));es=nes;pc+=2;break;}
  216. #define LOADMEM3(t) {*((t*)nes)=*((t*)(dd+(G3(np))));es=nes;pc+=3;break;}
  217. #define LOADMEM4(t) {*((t*)nes)=*((t*)((void*)G4(np)));es=nes;pc+=4;break;}
  218.  
  219. #define STORMEM1(t) {*((t*)(dd+(G1(np)<<2)))=*((t*)es);es=oes;pc+=1;break;}
  220. #define STORMEM2(t) {*((t*)(dd+(G2(np)<<2)))=*((t*)es);es=oes;pc+=2;break;}
  221. #define STORMEM3(t) {*((t*)(dd+(G3(np)<<2)))=*((t*)es);es=oes;pc+=3;break;}
  222. #define STORMEM4(t) {*((t*)((void*)G4(np)))=*((t*)es);es=oes;pc+=4;break;}
  223.  
  224. #define STORMEMI1(t) {*((t*)(dd+(G1(np)<<2)))=*((t*)(np+1));pc+=sizeof(t)+1;break;}
  225. #define STORMEMI2(t) {*((t*)(dd+(G2(np)<<2)))=*((t*)(np+2));pc+=sizeof(t)+2;break;}
  226. #define STORMEMI3(t) {*((t*)(dd+(G3(np)<<0)))=*((t*)(np+3));pc+=sizeof(t)+3;break;}
  227. #define STORMEMI4(t) {*((t*)((void*)G4(np)))=*((t*)(np+4));pc+=sizeof(t)+4;break;}
  228.  
  229. static unsigned long bfields[33] = {
  230.     0x00000000,0x00000001,0x00000003,0x00000007,
  231.     0x0000000f,0x0000001f,0x0000003f,0x0000007f,
  232.     0x000000ff,0x000001ff,0x000003ff,0x000007ff,
  233.     0x00000fff,0x00001fff,0x00003fff,0x00007fff,
  234.     0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
  235.     0x000fffff,0x001fffff,0x003fffff,0x007fffff,
  236.     0x00ffffff,0x01ffffff,0x03ffffff,0x07ffffff,
  237.     0x0fffffff,0x1fffffff,0x3fffffff,0x7fffffff,
  238.     0xfffffff
  239.     };
  240. static unsigned long tsfields[33] = {
  241.     0x00000000,0x00000001,0x00000002,0x00000004,
  242.     0x00000008,0x00000010,0x00000020,0x00000040,
  243.     0x00000080,0x00000100,0x00000200,0x00000400,
  244.     0x00000800,0x00001000,0x00002000,0x00004000,
  245.     0x00008000,0x00010000,0x00020000,0x00040000,
  246.     0x00080000,0x00100000,0x00200000,0x00400000,
  247.     0x00800000,0x01000000,0x02000000,0x04000000,
  248.     0x08000000,0x10000000,0x20000000,0x40000000,
  249.     0x80000000
  250.     };
  251. static unsigned long sfields[33] = {
  252.     0x00000000,0xfffffffe,0xfffffffc,0xfffffff8,
  253.     0xfffffff0,0xffffffe0,0xffffffc0,0xffffff80,
  254.     0xffffff00,0xfffffe00,0xfffffc00,0xfffff800,
  255.     0xfffff000,0xffffe000,0xffffc000,0xffff8000,
  256.     0xffff0000,0xfffe0000,0xfffc0000,0xfff80000,
  257.     0xfff00000,0xffe00000,0xffc00000,0xff800000,
  258.     0xff000000,0xfe000000,0xfc000000,0xf8000000,
  259.     0xf0000000,0xe0000000,0xc0000000,0x80000000,
  260.     0x80000000
  261.     };
  262. #if SUPPORT_LONG_LONG
  263. static unsigned long long lbfields[65] = {
  264.     0x0000000000000000LL,0x0000000000000001LL,0x0000000000000003LL,0x0000000000000007LL,
  265.     0x000000000000000fLL,0x000000000000001fLL,0x000000000000003fLL,0x000000000000007fLL,
  266.     0x00000000000000ffLL,0x00000000000001ffLL,0x00000000000003ffLL,0x00000000000007ffLL,
  267.     0x0000000000000fffLL,0x0000000000001fffLL,0x0000000000003fffLL,0x0000000000007fffLL,
  268.     0x000000000000ffffLL,0x000000000001ffffLL,0x000000000003ffffLL,0x000000000007ffffLL,
  269.     0x00000000000fffffLL,0x00000000001fffffLL,0x00000000003fffffLL,0x00000000007fffffLL,
  270.     0x0000000000ffffffLL,0x0000000001ffffffLL,0x0000000003ffffffLL,0x0000000007ffffffLL,
  271.     0x000000000fffffffLL,0x000000001fffffffLL,0x000000003fffffffLL,0x000000007fffffffLL,
  272.     0x00000000ffffffffLL,0x00000001ffffffffLL,0x00000003ffffffffLL,0x00000007ffffffffLL,
  273.     0x0000000fffffffffLL,0x0000001fffffffffLL,0x0000003fffffffffLL,0x0000007fffffffffLL,
  274.     0x000000ffffffffffLL,0x000001ffffffffffLL,0x000003ffffffffffLL,0x000007ffffffffffLL,
  275.     0x00000fffffffffffLL,0x00001fffffffffffLL,0x00003fffffffffffLL,0x00007fffffffffffLL,
  276.     0x0000ffffffffffffLL,0x0001ffffffffffffLL,0x0003ffffffffffffLL,0x0007ffffffffffffLL,
  277.     0x000fffffffffffffLL,0x001fffffffffffffLL,0x003fffffffffffffLL,0x007fffffffffffffLL,
  278.     0x00ffffffffffffffLL,0x01ffffffffffffffLL,0x03ffffffffffffffLL,0x07ffffffffffffffLL,
  279.     0x0fffffffffffffffLL,0x1fffffffffffffffLL,0x3fffffffffffffffLL,0x7fffffffffffffffLL,
  280.     0xfffffffffffffffLL
  281.     };
  282. static unsigned long long ltsfields[65] = {
  283.     0x0000000000000000LL,0x0000000000000001LL,0x0000000000000002LL,0x0000000000000004LL,
  284.     0x0000000000000008LL,0x0000000000000010LL,0x0000000000000020LL,0x0000000000000040LL,
  285.     0x0000000000000080LL,0x0000000000000100LL,0x0000000000000200LL,0x0000000000000400LL,
  286.     0x0000000000000800LL,0x0000000000001000LL,0x0000000000002000LL,0x0000000000004000LL,
  287.     0x0000000000008000LL,0x0000000000010000LL,0x0000000000020000LL,0x0000000000040000LL,
  288.     0x0000000000080000LL,0x0000000000100000LL,0x0000000000200000LL,0x0000000000400000LL,
  289.     0x0000000000800000LL,0x0000000001000000LL,0x0000000002000000LL,0x0000000004000000LL,
  290.     0x0000000008000000LL,0x0000000010000000LL,0x0000000020000000LL,0x0000000040000000LL,
  291.     0x0000000080000000LL,0x0000000100000000LL,0x0000000200000000LL,0x0000000400000000LL,
  292.     0x0000000800000000LL,0x0000001000000000LL,0x0000002000000000LL,0x0000004000000000LL,
  293.     0x0000008000000000LL,0x0000010000000000LL,0x0000020000000000LL,0x0000040000000000LL,
  294.     0x0000080000000000LL,0x0000100000000000LL,0x0000200000000000LL,0x0000400000000000LL,
  295.     0x0000800000000000LL,0x0001000000000000LL,0x0002000000000000LL,0x0004000000000000LL,
  296.     0x0008000000000000LL,0x0010000000000000LL,0x0020000000000000LL,0x0040000000000000LL,
  297.     0x0080000000000000LL,0x0100000000000000LL,0x0200000000000000LL,0x0400000000000000LL,
  298.     0x0800000000000000LL,0x1000000000000000LL,0x2000000000000000LL,0x4000000000000000LL,
  299.     0x8000000000000000LL
  300.     };
  301. static unsigned long long lsfields[65] = {
  302.     0x0000000000000000LL,0xfffffffffffffffeLL,0xfffffffffffffffcLL,0xfffffffffffffff8LL,
  303.     0xfffffffffffffff0LL,0xffffffffffffffe0LL,0xffffffffffffffc0LL,0xffffffffffffff80LL,
  304.     0xffffffffffffff00LL,0xfffffffffffffe00LL,0xfffffffffffffc00LL,0xfffffffffffff800LL,
  305.     0xfffffffffffff000LL,0xffffffffffffe000LL,0xffffffffffffc000LL,0xffffffffffff8000LL,
  306.     0xffffffffffff0000LL,0xfffffffffffe0000LL,0xfffffffffffc0000LL,0xfffffffffff80000LL,
  307.     0xfffffffffff00000LL,0xffffffffffe00000LL,0xffffffffffc00000LL,0xffffffffff800000LL,
  308.     0xffffffffff000000LL,0xfffffffffe000000LL,0xfffffffffc000000LL,0xfffffffff8000000LL,
  309.     0xfffffffff0000000LL,0xffffffffe0000000LL,0xffffffffc0000000LL,0xffffffff80000000LL,
  310.     0xffffffff00000000LL,0xfffffffe00000000LL,0xfffffffc00000000LL,0xfffffff800000000LL,
  311.     0xfffffff000000000LL,0xffffffe000000000LL,0xffffffc000000000LL,0xffffff8000000000LL,  
  312.     0xffffff0000000000LL,0xfffffe0000000000LL,0xfffffc0000000000LL,0xfffff80000000000LL,
  313.     0xfffff00000000000LL,0xffffe00000000000LL,0xffffc00000000000LL,0xffff800000000000LL,
  314.     0xffff000000000000LL,0xfffe000000000000LL,0xfffc000000000000LL,0xfff8000000000000LL,
  315.     0xfff0000000000000LL,0xffe0000000000000LL,0xffc0000000000000LL,0xff80000000000000LL,
  316.     0xff00000000000000LL,0xfe00000000000000LL,0xfc00000000000000LL,0xf800000000000000LL,
  317.     0xf000000000000000LL,0xe000000000000000LL,0xc000000000000000LL,0x8000000000000000LL,
  318.     0x8000000000000000LL
  319.     };
  320. #endif /* SUPPORT_LONG_LONG */
  321.  
  322. static char thunk386[41] =
  323. {/* THE EXTERNAL CALLBACK THUNK (Intel 386) */
  324.     0x55,                /* pushl %ebp */
  325.     0x89,0xE5,            /* movl %esp,%ebp */
  326.     0x68,0,0,0,0,        /* pushl ft */
  327.     0x68,0,0,0,0,        /* pushl iv */
  328.     0x68,0,0,0,0,        /* pushl base_stack */
  329.     0x83,0xEC,0x0C,        /* subl $12,%esp (RETVAL) */
  330.     0xB8,0,0,0,0,        /* movl _bterp_handle_callbacks,%eax */
  331.     0xFF,0xD0,            /* call *%eax */
  332.     0x8B,0x04,0x24,        /* movl (%esp),%eax     */
  333.     0x8B,0x54,0x24,0x04,/* movl 4(%esp),%edx */
  334.     0x8B,0x4C,0x24,0x08,/* movl 8(%esp),%ecx */
  335.     0xC9,                /* leave */
  336.     0xC3                /* ret */
  337. };
  338. static char thunk386S[42] =
  339. {/* THE EXTERNAL CALLBACK THUNK (Intel 386) */
  340.     0x55,                /* pushl %ebp */
  341.     0x89,0xE5,            /* movl %esp,%ebp */
  342.     0x68,0,0,0,0,        /* pushl ft */
  343.     0x68,0,0,0,0,        /* pushl iv */
  344.     0x68,0,0,0,0,        /* pushl base_stack */
  345.     0x83,0xEC,0x0C,        /* subl $12,%esp (RETVAL) */
  346.     0xB8,0,0,0,0,        /* movl _bterp_handle_callbacks,%eax */
  347.     0xFF,0xD0,            /* call *%eax */
  348.     0x8B,0x04,0x24,        /* movl (%esp),%eax     */
  349.     0x8B,0x54,0x24,0x04,/* movl 4(%esp),%edx */
  350.     0x8B,0x4C,0x24,0x08,/* movl 8(%esp),%ecx */
  351.     0xC9,                /* leave */
  352.     0xC2,0x04            /* ret $4 (prune structret arg, GCC convention) */
  353. };
  354.  
  355.  
  356.  
  357. /* ========================== INTERPRETER CODE =========================== */
  358.  
  359. static int
  360. findswitch(Piv iv, unsigned long *key, void *result)
  361. {
  362. int bin;
  363. NodePS node;
  364.     bin = (((~key[0] ^ key[1]) * 1103515245UL) + 12345) % SWITCHMOD;
  365.     if((node = iv->swtable[bin]))
  366.     {
  367.         do {
  368.             if(node->key[0] == key[0] && node->key[1] == key[1])
  369.             {
  370.                 *((NodePS*)result) = node;
  371.                 return 1;
  372.             }
  373.         } while((node = node->fptr));
  374.     }
  375.     return 0;
  376. }
  377. static void *
  378. new_Snode(Piv iv)
  379. {
  380. void *p;
  381.  
  382.     if(iv->chunksize < sizeof(NodeS))
  383.     {
  384.         iv->chunkbase = calloc(1, 4088);
  385.         *((void**)iv->chunkbase) = iv->chunklist;
  386.         iv->chunklist = iv->chunkbase;
  387.         iv->chunkbase += sizeof(void*);
  388.         iv->chunksize = 4088 - sizeof(void*);
  389.     }
  390.     p = iv->chunkbase;
  391.     iv->chunkbase += sizeof(NodeS);
  392.     iv->chunksize -= sizeof(NodeS);
  393.     return p;
  394. }
  395. static void
  396. saveswitch(Piv iv, unsigned long *key, long value)
  397. {
  398. int bin;
  399. NodePS node;
  400.  
  401.     bin = (((~key[0] ^ key[1]) * 1103515245UL) + 12345) % SWITCHMOD;
  402.     node = new_Snode(iv);
  403.     node->key[0] = key[0];
  404.     node->key[1] = key[1];
  405.     node->value = value;
  406.     node->fptr = iv->swtable[bin];
  407.     iv->swtable[bin] = node;
  408. }
  409. static void
  410. purge_allocas(Piv iv, void *last)
  411. {
  412.     while(iv->allocalist && (iv->allocalist != last))
  413.     {
  414.     void *this = iv->allocalist;
  415.         iv->allocalist = *((void**)this);
  416.         free(this);
  417.     }
  418. }
  419.  
  420. static void
  421. _bterp_handle_callbacks(RV retval, char *base_stack, Piv iv, Pft ft, 
  422.                             int ebp, int pret, ...)
  423. {/* Call to interpreted function from external function */
  424. unsigned short fmods;
  425. long stksiz, maxes, strucsiz, fs_size, argofs, es_beg, argsiz;
  426. int hidden;
  427. void *strret = 0;
  428. void *argaddr, *e_stack, *lastalloca;
  429. void *pes;
  430. DATUM lastval;
  431.  
  432.     fmods = ft->fmods;
  433.     argaddr = ((long*)&pret)+1;
  434.     if((hidden = (fmods & Fretstr)))
  435.     {/* return a struct or union */
  436.         strucsiz = ft->retsiz<<2;
  437.         strret = (void*) *(((long*)&pret)+1);
  438.     }
  439.     stksiz = ft->stksiz<<2;
  440.     maxes = ft->maxes;
  441.     argsiz = ft->argsiz<<2;
  442.  
  443.     if(fmods & Fnested)
  444.     {/* callback to nested function */
  445.         argofs = ft->stkbeg+(stksiz-argsiz-hidden);
  446.         e_stack = ((PSB)base_stack)->cbes;
  447.     }
  448.     else
  449.     {/* callback to non-nested function */
  450.         if(fmods & Fellipsis)
  451.             argsiz += 128;
  452.         es_beg = stksiz+hidden+argsiz;
  453.         argofs = stksiz;
  454.         fs_size = es_beg + ((maxes+6)*SZ);
  455.  
  456.         /* Create a stack for the called function */
  457.         base_stack = calloc(1, fs_size + sizeof(SB));
  458.         e_stack = base_stack + sizeof(SB) + es_beg;
  459.         ((PSB)base_stack)->stksize = fs_size + sizeof(SB);
  460.     }
  461.  
  462.     /* Copy the callers arguments */
  463.     memcpy(base_stack+argofs+sizeof(SB),argaddr,argsiz+hidden);
  464.  
  465.     /* EVALUATE THE FUNCTION */
  466.     lastalloca = iv->allocalist;
  467.     pes = bterp_eval(iv, ft->funcaddr, base_stack, e_stack,
  468.         base_stack+((PSB)base_stack)->stksize);
  469.  
  470.     /* Transfer the return value */
  471. #if SUPPORT_LONG_DOUBLE
  472.     lastval.Ulongdouble = *((long double*)pes);
  473. #else
  474.     lastval.Udouble = *((double*)pes);
  475. #endif
  476.  
  477.     /* Return to callers' stack */
  478.     if(fmods & Fretdbl)
  479.     {
  480.         asm ("fldl %0" :: "g"(lastval.Udouble));
  481.     }
  482.     else if(fmods & Fretflt)
  483.     {
  484.         asm ("flds %0" :: "g"(lastval.Ufloat));
  485.     }
  486.     else if(fmods & Fretldbl)
  487.     {
  488. #if SUPPORT_LONG_DOUBLE
  489.         asm ("fstpt %0" :: "g"(lastval.Udouble));
  490. #else
  491.         asm ("fldl %0" :: "g"(lastval.Udouble));
  492. #endif
  493.     }
  494.     else if(strret)
  495.     {/* return pointer to struct */
  496.         retval.ptr = strret;
  497.         /* GCC needs this */
  498.         memcpy(&retval.p1, strret, MIN(8,strucsiz));    /* 8 bytes of struct */
  499.     }
  500.     else
  501.     {
  502.         retval.ptr = lastval.Upointer;
  503.         retval.p1 = lastval.lng.d[1];
  504.         retval.p2 = lastval.lng.d[2];
  505.     }
  506.     purge_allocas(iv, lastalloca);
  507.     if(fmods & Fnested)
  508.     {
  509. #if 0
  510.         *((char**)pes) -= SZ;
  511. #endif
  512.         ft->fmods &= ~Fthunked;
  513.         free(((PSB)base_stack)->thunkaddr);
  514.     }
  515.     else
  516.     {
  517.         free(base_stack);
  518.     }
  519. }
  520.  
  521. static void *
  522. make_callback_thunk(Piv iv, void *base_stack, Pft ft)
  523. {
  524. char *pth;
  525.  
  526.     if(ft->fmods & Fretstr)
  527.     {
  528.         pth = malloc(sizeof(thunk386S));
  529.         memcpy(pth, thunk386S, sizeof(thunk386S));
  530.     }
  531.     else
  532.     {
  533.         pth = malloc(sizeof(thunk386));
  534.         memcpy(pth, thunk386, sizeof(thunk386));
  535.     }
  536.     *((long*)&pth[4]) = (long)ft;
  537.     *((long*)&pth[9]) = (long)iv;
  538.     *((long*)&pth[14]) = (long)base_stack;
  539.     *((long*)&pth[22]) = (long)_bterp_handle_callbacks;
  540.  
  541.     return pth;
  542. }
  543. static void
  544. ensure_strrets(Piv iv)
  545. {
  546.     if(iv->strretcnt+1 >= iv->slcnt) {
  547.         iv->slcnt += 128;
  548.         iv->struclist = realloc(iv->struclist, iv->slcnt * sizeof(void *));
  549.     }
  550. }
  551. static void
  552. prune_structs(Piv iv)
  553. {
  554.     while(iv->strretcnt > 0)
  555.     {
  556.         free(iv->struclist[--iv->strretcnt]);
  557.     }
  558. }
  559. static int
  560. mover(Piv iv, unsigned char *dp, int opcode, int size, char *src, char *dst)
  561. {
  562. char *s, *d;
  563. int bump;
  564.  
  565.     switch(opcode)
  566.     {
  567.         case S1|D1:
  568.             s = src+(G1(dp)<<2);
  569.             d = dst+(G1(dp+1)<<2);
  570.             bump = 3;
  571.             break;
  572.         case S1|D2:
  573.             s = src+(G1(dp)<<2);
  574.             d = dst+(G2(dp+1)<<2);
  575.             bump = 4;
  576.             break;
  577.         case S1|D3:
  578.             s = src+(G1(dp)<<2);
  579.             d = dst+(G3(dp+1)<<0);
  580.             bump = 5;
  581.             break;
  582.         case S1|D4:
  583.             s = src+(G1(dp)<<2);
  584.             d = (void*)G4(dp+1);
  585.             bump = 6;
  586.             break;
  587.         case S2|D1:
  588.             s = src+(G2(dp)<<2);
  589.             d = dst+G1(dp+2);
  590.             bump = 4;
  591.             break;
  592.         case S2|D2:
  593.             s = src+(G2(dp)<<2);
  594.             d = dst+(G2(dp+2)<<2);
  595.             bump = 5;
  596.             break;
  597.         case S2|D3:
  598.             s = src+(G2(dp)<<2);
  599.             d = dst+(G3(dp+2)<<0);
  600.             bump = 6;
  601.             break;
  602.         case S2|D4:
  603.             s = src+(G2(dp)<<2);
  604.             d = (void*)G4(dp+2);
  605.             bump = 7;
  606.             break;
  607.         case S3|D1:
  608.             s = src+(G3(dp)<<0);
  609.             d = dst+(G1(dp+3)<<2);
  610.             bump = 5;
  611.             break;
  612.         case S3|D2:
  613.             s = src+(G3(dp)<<0);
  614.             d = dst+(G2(dp+3)<<2);
  615.             bump = 6;
  616.             break;
  617.         case S3|D3:
  618.             s = src+(G3(dp)<<0);
  619.             d = dst+(G3(dp+3)<<0);
  620.             bump = 7;
  621.             break;
  622.         case S3|D4:
  623.             s = src+(G3(dp)<<0);
  624.             d = (void*)G4(dp+3);
  625.             bump = 8;
  626.             break;
  627.         case S4|D1:
  628.             s = (void*)G4(dp);
  629.             d = dst+(G1(dp+4)<<2);
  630.             bump = 6;
  631.             break;
  632.         case S4|D2:
  633.             s = (void*)G4(dp);
  634.             d = dst+(G2(dp+4)<<2);
  635.             bump = 7;
  636.             break;
  637.         case S4|D3:
  638.             s = (void*)G4(dp);
  639.             d = dst+(G3(dp+4)<<0);
  640.             bump = 8;
  641.             break;
  642.         case S4|D4:
  643.             s = (void*)G4(dp);
  644.             d = (void*)G4(dp+4);
  645.             bump = 9;
  646.             break;
  647.         default:
  648.             printf("bterp: BAD OPCODE for `mover' at pc=%lx\n",
  649.                 ((char*)dp - iv->text_base) - 1);
  650.             longjmp(iv->jb, 1);            
  651.     }
  652.     if(size == B1)
  653.         *((char*)d) = *((char*)s);
  654.     else if(size == B2)
  655.         *((short*)d) = *((short*)s);
  656.     else if(size == B4)
  657.         *((long*)d) = *((long*)s);
  658.     else if(size == B8)
  659.         *((double*)d) = *((double*)s);
  660.     else
  661.         memcpy(d,s,XSZ);
  662.     return bump;
  663. }
  664. static void
  665. load_efunc(Piv iv, Pft ft)
  666. {
  667. void *e_faddr;
  668.     if(!(e_faddr = oxlink_find_bare_func((void*)ft->funcaddr)))
  669.     {/* not in core, load the file */
  670.         if(!(e_faddr = oxlink_load_bare_symb((void*)ft->funcaddr, 1)))
  671.         {
  672.             printf("bterp: Can't load function `%s'\n", (char*)ft->funcaddr);
  673.             exit(1);
  674.         }
  675.     }
  676.     ft->funcaddr = (long)e_faddr;
  677.     ft->fmods |= Fthunked;
  678. }
  679. /* MOST OF THESE BUILTINS ARE UNNECESSARY DEMOS */
  680. /* PUT ANYTHING THAT COULD BE CALLED THROUGH A FUNCPTR HERE */
  681. static int
  682. do_builtin(Piv iv, unsigned char code, char **pes)
  683. {/* NOTE: builtins with no args and void return must leave a pseudo ret on stack */
  684. char *es, *oes;
  685.     es = *pes;
  686.     oes = es-SZ;
  687.  
  688.     switch(code)
  689.     {
  690.         case ALLOCA:
  691.         {
  692.         char *abuf = malloc(*((unsigned*)es)+sizeof(void*));
  693.             *((void**)es) = abuf+sizeof(void*);
  694.             *((void**)abuf) = iv->allocalist;
  695.             iv->allocalist = abuf;
  696.             return 1;
  697.         }
  698.         case STRLEN:
  699.         {
  700.             *((unsigned*)es) = strlen(*((const char**)es));
  701.             return 1;
  702.         }
  703.         case STRCPY:
  704.         {
  705.             *((void**)oes) = strcpy(*((char**)oes),*((const char**)es));
  706.             *pes = oes;
  707.             return 1;
  708.         }
  709.         case STRCAT:
  710.         {
  711.             *((void**)oes) = strcat(*((char**)oes),*((const char**)es));
  712.             *pes = oes;
  713.             return 1;
  714.         }
  715.         case MEMCPY:
  716.         {
  717.             *((void**)(oes-SZ)) = memcpy(*((void**)(oes-SZ)),*((const void**)oes),*((unsigned*)es));
  718.             *pes -= 2*SZ;
  719.             return 1;
  720.         }
  721.         case MEMMOVE:
  722.         {
  723.             *((void**)(oes-SZ)) = memmove(*((void**)(oes-SZ)),*((const void**)oes),*((unsigned*)es));
  724.             *pes -= 2*SZ;
  725.             return 1;
  726.         }
  727.         case MEMSET:
  728.         {
  729.             *((void**)(oes-SZ)) = 
  730.                 memset(*((void**)(oes-SZ)),*((int*)oes),*((long*)es));
  731.             *pes -= 2*SZ;
  732.             return 1;
  733.         }
  734.         case BZERO:
  735.         {
  736.             memset(*((void**)oes),0,*((unsigned*)es));
  737.             *pes = oes;
  738.             return 0;
  739.         }
  740.         case DEBUG:
  741.         {
  742.             iv->debug=1;
  743.             printf("DEBUG ON\n");
  744.             fflush(stdout);
  745.             *pes = es+SZ;    /* pseudo ret */
  746.             return 0;
  747.         }
  748.         case NODEBUG:
  749.         {
  750.             iv->debug=0;
  751.             printf("DEBUG OFF\n");
  752.             fflush(stdout);
  753.             *pes = es+SZ;    /* pseudo ret */
  754.             return 0;
  755.         }
  756.         case MALLOC:
  757.         {
  758.             *((void**)es) = malloc(*((unsigned*)es));
  759.             return 1;
  760.         }
  761.         case CALLOC:
  762.         {
  763.             *((void**)oes) = calloc(*((unsigned*)oes),*((unsigned*)es));
  764.             *pes = oes;
  765.             return 1;
  766.         }
  767.         case REALLOC:
  768.         {
  769.             *((void**)oes) = realloc(*((void**)oes),*((unsigned*)es));
  770.             *pes = oes;
  771.             return 1;
  772.         }
  773.     }    
  774.     return 0;
  775. }
  776. static void *
  777. bterp_eval(Piv iv, long pc_offset, void *base_stack, char *es, char *eb)
  778. {
  779. char *dd, *fs;
  780. unsigned char *pc, *np;
  781. char *oes, *nes, *bes;
  782. long first_loc = -100;
  783. long last_loc = 0;
  784.  
  785.   dd = iv->dd;
  786.   fs = base_stack + sizeof(SB);
  787.   pc = iv->text_base + pc_offset;
  788.   bes = es;
  789.  
  790. if(iv->debug) {
  791. printf("FUNCTION ofs=%lx pc=%p bs=%p fs=%p es=%p dd=%p eb=%p\n", 
  792. pc_offset, pc, base_stack, fs, es, dd, eb);
  793. fflush(stdout);
  794. }
  795.   for(;;++pc)
  796.   {
  797.     np = pc+1;
  798.     oes = es-SZ;
  799.     nes = es+SZ;
  800.  
  801. if(iv->debug) {
  802. printf("ofs:%lx op=%x es=%p val=%lx oval=%lx nval=%lx\n",
  803. ((char*)pc) - iv->text_base, *pc, es, 
  804. *((long*)es), *((long*)oes), *((long*)nes));
  805. fflush(stdout);
  806. }
  807. if(es < bes) {
  808. printf("STACK UNDERFLOW ofs:%lx op=%x es=%p val=%lx oval=%lx nval=%lx\n",
  809. ((char*)pc) - iv->text_base, *pc, es, *((long*)es), *((long*)oes), *((long*)nes));
  810. fflush(stdout);
  811. longjmp(iv->jb, (int)es);
  812. }
  813. if(es >= eb) {
  814. printf("STACK OVERFLOW ofs:%lx op=%x es=%p val=%lx oval=%lx nval=%lx\n",
  815. ((char*)pc) - iv->text_base, *pc, es, *((long*)es), *((long*)oes), *((long*)nes));
  816. fflush(stdout);
  817. longjmp(iv->jb, (int)es);
  818. }
  819.     switch(*pc)
  820.     {
  821.         case LOCATE|J1:
  822.         {
  823.             last_loc = ((char*)(pc + GP1(np))) - iv->text_base;
  824.             if(first_loc == -100) first_loc = last_loc;             
  825.             ++pc;
  826.             break;
  827.         }
  828.         case LOCATE|J2:
  829.         {
  830.             last_loc = ((char*)(pc + GP2(np))) - iv->text_base;
  831.             if(first_loc == -100) first_loc = last_loc;             
  832.             pc += 2;
  833.             break;
  834.         }
  835.         case LOCATE|J3:
  836.         {
  837.             last_loc = ((char*)(pc + GP3(np))) - iv->text_base;
  838.             if(first_loc == -100) first_loc = last_loc;             
  839.             pc += 3;
  840.             break;
  841.         }
  842.         case LOCATE|J4:
  843.         {
  844.             last_loc = ((char*)(pc + GP4(np))) - iv->text_base;
  845.             if(first_loc == -100) first_loc = last_loc;             
  846.             pc += 4;
  847.             break;
  848.         }
  849.         case LS|A1|B1:
  850.             LOADSTK1(char);
  851.         case LS|A1|B2:
  852.             LOADSTK1(short);
  853.         case LS|A1|B4:
  854.             LOADSTK1(long);
  855.         case LS|A1|B8:
  856.             LOADSTK1(double);
  857.         case LS|A2|B1:
  858.             LOADSTK2(char);
  859.         case LS|A2|B2:
  860.             LOADSTK2(short);
  861.         case LS|A2|B4:
  862.             LOADSTK2(long);
  863.         case LS|A2|B8:
  864.             LOADSTK2(double);
  865.         case LS|A3|B1:
  866.             LOADSTK3(char);
  867.         case LS|A3|B2:
  868.             LOADSTK3(short);
  869.         case LS|A3|B4:
  870.             LOADSTK3(long);
  871.         case LS|A3|B8:
  872.             LOADSTK3(double);
  873.  
  874.         case NEG|BYTE:
  875.             NEG_ES(char);
  876.         case NEG|SHORT:
  877.             NEG_ES(short);
  878.         case NEG|LONG:
  879.             NEG_ES(long);
  880.         case NEG|UBYTE:
  881.             NEG_ES(unsigned char);
  882.         case NEG|USHORT:
  883.             NEG_ES(unsigned short);
  884.         case NEG|ULONG:
  885.             NEG_ES(unsigned long);
  886.         case NEG|FLOAT:
  887.             NEG_ES(float);
  888.         case NEG|DOUBLE:
  889.             NEG_ES(double);
  890.  
  891.         case LM|A1|B1:
  892.             LOADMEM1(char);
  893.         case LM|A1|B2:
  894.             LOADMEM1(short);
  895.         case LM|A1|B4:
  896.             LOADMEM1(long);
  897.         case LM|A1|B8:
  898.             LOADMEM1(double);
  899.         case LM|A2|B1:
  900.             LOADMEM2(char);
  901.         case LM|A2|B2:
  902.             LOADMEM2(short);
  903.         case LM|A2|B4:
  904.             LOADMEM2(long);
  905.         case LM|A2|B8:
  906.             LOADMEM2(double);
  907.         case LM|A3|B1:
  908.             LOADMEM3(char);
  909.         case LM|A3|B2:
  910.             LOADMEM3(short);
  911.         case LM|A3|B4:
  912.             LOADMEM3(long);
  913.         case LM|A3|B8:
  914.             LOADMEM3(double);
  915.         case LM|A4|B1:
  916.             LOADMEM4(char);
  917.         case LM|A4|B2:
  918.             LOADMEM4(short);
  919.         case LM|A4|B4:
  920.             LOADMEM4(long);
  921.         case LM|A4|B8:
  922.             LOADMEM4(double);
  923.  
  924.         case COMP|B1:
  925.             COMP_ES(char);
  926.         case COMP|B2:
  927.             COMP_ES(short);
  928.         case COMP|B4:
  929.             COMP_ES(long);
  930. #if SUPPORT_LONG_LONG
  931.         case COMP|B8:
  932.             COMP_ES(long long);
  933. #else
  934. #endif
  935.         case JMP|J1:
  936.             pc += GP1(np)-1;
  937.             break;
  938.         case JMP|J2:
  939.             pc += GP2(np)-1;
  940.             break;
  941.         case JMP|J3:
  942.             pc += GP3(np)-1;
  943.             break;
  944.         case JMP|J4:
  945.             pc += GP4(np)-1;
  946.             break;
  947.  
  948.         case LJMPT|J1:
  949.             if(*(es)) pc += GP1(np)-1;
  950.             else {pc += 1; es=oes;}
  951.             break;
  952.         case LJMPT|J2:
  953.             if(*(es)) pc += GP2(np)-1;
  954.             else {pc += 2; es=oes;}
  955.             break;
  956.         case LJMPT|J3:
  957.             if(*(es)) pc += GP3(np)-1;
  958.             else {pc += 3; es=oes;}
  959.             break;
  960.         case LJMPT|J4:
  961.             if(*(es)) pc += GP4(np)-1;
  962.             else {pc += 4; es=oes;}
  963.             break;
  964.  
  965.         case JMPT|J1:
  966.             if(*(es)) pc += GP1(np)-1;
  967.             else pc += 1;
  968.             es = oes;
  969.             break;
  970.         case JMPT|J2:
  971.             if(*(es)) pc += GP2(np)-1;
  972.             else pc += 2;
  973.             es = oes;
  974.             break;
  975.         case JMPT|J3:
  976.             if(*(es)) pc += GP3(np)-1;
  977.             else pc += 3;
  978.             es = oes;
  979.             break;
  980.         case JMPT|J4:
  981.             if(*(es)) pc += GP4(np)-1;
  982.             else pc += 4;
  983.             es = oes;
  984.             break;
  985.  
  986.         case LJMPF|J1:
  987.             if(!*(es)) pc += GP1(np)-1;
  988.             else {pc += 1; es=oes;}
  989.             break;
  990.         case LJMPF|J2:
  991.             if(!*(es)) pc += GP2(np)-1;
  992.             else {pc += 2; es=oes;};
  993.             break;
  994.         case LJMPF|J3:
  995.             if(!*(es)) pc += GP3(np)-1;
  996.             else {pc += 3; es=oes;}
  997.             break;
  998.         case LJMPF|J4:
  999.             if(!*(es)) pc += GP4(np)-1;
  1000.             else {pc +=4; es=oes;}
  1001.             break;
  1002.  
  1003.         case JMPF|J1:
  1004.             if(!*(es)) pc += GP1(np)-1;
  1005.             else pc += 1;
  1006.             es = oes;
  1007.             break;
  1008.         case JMPF|J2:
  1009.             if(!*(es)) pc += GP2(np)-1;
  1010.             else pc += 2;
  1011.             es = oes;
  1012.             break;
  1013.         case JMPF|J3:
  1014.             if(!*(es)) pc += GP3(np)-1;
  1015.             else pc += 3;
  1016.             es = oes;
  1017.             break;
  1018.         case JMPF|J4:
  1019.             if(!*(es)) pc += GP4(np)-1;
  1020.             else pc +=4;
  1021.             es = oes;
  1022.             break;
  1023.  
  1024.         case NOT|B1:
  1025.             NOT_ES(char);
  1026.         case NOT|B2:
  1027.             NOT_ES(short);
  1028.         case NOT|B4:    /* also FLOAT */
  1029.             NOT_ES(long);
  1030.         case NOT|B8:    /* also DOUBLE */
  1031. #if SUPPORT_LONG_LONG
  1032.             NOT_ES(long long);
  1033. #else
  1034.             NOT_ES1;
  1035. #endif
  1036.         case SS|A1|B1:
  1037.             STORSTK1(char);
  1038.         case SS|A1|B2:
  1039.             STORSTK1(short);
  1040.         case SS|A1|B4:
  1041.             STORSTK1(long);
  1042.         case SS|A1|B8:
  1043.             STORSTK1(double);
  1044.         case SS|A2|B1:
  1045.             STORSTK2(char);
  1046.         case SS|A2|B2:
  1047.             STORSTK2(short);
  1048.         case SS|A2|B4:
  1049.             STORSTK2(long);
  1050.         case SS|A2|B8:
  1051.             STORSTK2(double);
  1052.         case SS|A3|B1:
  1053.             STORSTK3(char);
  1054.         case SS|A3|B2:
  1055.             STORSTK3(short);
  1056.         case SS|A3|B4:
  1057.             STORSTK3(long);
  1058.         case SS|A3|B8:
  1059.             STORSTK3(double);
  1060.  
  1061.         case TRUTHOF|B2:
  1062.             TRUTH_ES(short);
  1063.         case TRUTHOF|B4:        /* also FLOAT */
  1064.             TRUTH_ES(long);
  1065.         case TRUTHOF|B8:        /* also DOUBLE */
  1066. #if SUPPORT_LONG_LONG
  1067.             TRUTH_ES(long long);
  1068. #else
  1069.             TRUTH_ES1;
  1070. #endif
  1071.         case CVT:
  1072.         {
  1073.             ++pc;
  1074.             ++np;
  1075.             switch(*pc)
  1076.             {
  1077.                 case SRC(BYTE)|SHORT:
  1078.                     *((short*)es) = *((char*)es);
  1079.                     break;
  1080.                 case SRC(BYTE)|LONG:
  1081.                     *((long*)es) = *((char*)es);
  1082.                     break;
  1083.                 case SRC(BYTE)|USHORT:
  1084.                     *((unsigned short*)es) = *((char*)es);
  1085.                     break;
  1086.                 case SRC(BYTE)|ULONG:
  1087.                     *((unsigned long*)es) = *((char*)es);
  1088.                     break;
  1089.                 case SRC(BYTE)|FLOAT:
  1090.                     *((float*)es) = *((char*)es);
  1091.                     break;
  1092.                 case SRC(BYTE)|DOUBLE:
  1093.                     *((double*)es) = *((char*)es);
  1094.                     break;
  1095. #if SUPPORT_LONG_LONG
  1096.                 case SRC(BYTE)|CLONGLONG:
  1097.                     *((long long*)es) = *((char*)es);
  1098.                     break;
  1099.                 case SRC(BYTE)|CULONGLONG:
  1100.                     *((unsigned long long*)es) = *((char*)es);
  1101.                     break;
  1102. #endif
  1103. #if SUPPORT_LONG_DOUBLE
  1104.                 case SRC(BYTE)|CLONGDOUBLE:
  1105.                     *((long double*)es) = *((char*)es);
  1106.                     break;
  1107. #endif
  1108.                 case SRC(SHORT)|LONG:
  1109.                     *((long*)es) = *((short*)es);
  1110.                     break;
  1111.                 case SRC(SHORT)|ULONG:
  1112.                     *((unsigned long*)es) = *((short*)es);
  1113.                     break;
  1114.                 case SRC(SHORT)|FLOAT:
  1115.                     *((float*)es) = *((short*)es);
  1116.                     break;
  1117.                 case SRC(SHORT)|DOUBLE:
  1118.                     *((double*)es) = *((short*)es);
  1119.                     break;
  1120. #if SUPPORT_LONG_LONG
  1121.                 case SRC(SHORT)|CLONGLONG:
  1122.                     *((long long*)es) = *((short*)es);
  1123.                     break;
  1124.                 case SRC(SHORT)|CULONGLONG:
  1125.                     *((unsigned long long*)es) = *((short*)es);
  1126.                     break;
  1127. #endif
  1128. #if SUPPORT_LONG_DOUBLE
  1129.                 case SRC(SHORT)|CLONGDOUBLE:
  1130.                     *((long double*)es) = *((short*)es);
  1131.                     break;
  1132. #endif
  1133.                 case SRC(LONG)|FLOAT:
  1134.                     *((float*)es) = *((long*)es);
  1135.                     break;
  1136.                 case SRC(LONG)|DOUBLE:
  1137.                     *((double*)es) = *((long*)es);
  1138.                     break;
  1139. #if SUPPORT_LONG_LONG
  1140.                 case SRC(LONG)|CLONGLONG:
  1141.                     *((long long*)es) = *((long*)es);
  1142.                     break;
  1143.                 case SRC(LONG)|CULONGLONG:
  1144.                     *((unsigned long long*)es) = *((long*)es);
  1145.                     break;
  1146. #endif
  1147. #if SUPPORT_LONG_DOUBLE
  1148.                 case SRC(LONG)|CLONGDOUBLE:
  1149.                     *((long double*)es) = *((long*)es);
  1150.                     break;
  1151. #endif
  1152.                 case SRC(UBYTE)|SHORT:
  1153.                     *((short*)es) = *((unsigned char*)es);
  1154.                     break;
  1155.                 case SRC(UBYTE)|LONG:
  1156.                     *((long*)es) = *((unsigned char*)es);
  1157.                     break;
  1158.                 case SRC(UBYTE)|USHORT:
  1159.                     *((unsigned short*)es) = *((unsigned char*)es);
  1160.                     break;
  1161.                 case SRC(UBYTE)|ULONG:
  1162.                     *((unsigned long*)es) = *((unsigned char*)es);
  1163.                     break;
  1164.                 case SRC(UBYTE)|FLOAT:
  1165.                     *((float*)es) = *((unsigned char*)es);
  1166.                     break;
  1167.                 case SRC(UBYTE)|DOUBLE:
  1168.                     *((double*)es) = *((unsigned char*)es);
  1169.                     break;
  1170. #if SUPPORT_LONG_LONG
  1171.                 case SRC(UBYTE)|CLONGLONG:
  1172.                     *((long long*)es) = *((unsigned char*)es);
  1173.                     break;
  1174.                 case SRC(UBYTE)|CULONGLONG:
  1175.                     *((unsigned long long*)es) = *((unsigned char*)es);
  1176.                     break;
  1177. #endif
  1178. #if SUPPORT_LONG_DOUBLE
  1179.                 case SRC(UBYTE)|CLONGDOUBLE:
  1180.                     *((long double*)es) = *((unsigned char*)es);
  1181.                     break;
  1182. #endif
  1183.                 case SRC(USHORT)|LONG:
  1184.                     *((long*)es) = *((unsigned short*)es);
  1185.                     break;
  1186.                 case SRC(USHORT)|ULONG:
  1187.                     *((unsigned long*)es) = *((unsigned short*)es);
  1188.                     break;
  1189.                 case SRC(USHORT)|FLOAT:
  1190.                     *((float*)es) = *((unsigned short*)es);
  1191.                     break;
  1192.                 case SRC(USHORT)|DOUBLE:
  1193.                     *((double*)es) = *((unsigned short*)es);
  1194.                     break;
  1195. #if SUPPORT_LONG_LONG
  1196.                 case SRC(USHORT)|CLONGLONG:
  1197.                     *((long long*)es) = *((unsigned short*)es);
  1198.                     break;
  1199.                 case SRC(USHORT)|CULONGLONG:
  1200.                     *((unsigned long long*)es) = *((unsigned short*)es);
  1201.                     break;
  1202. #endif
  1203. #if SUPPORT_LONG_DOUBLE
  1204.                 case SRC(USHORT)|CLONGDOUBLE:
  1205.                     *((long double*)es) = *((unsigned short*)es);
  1206.                     break;
  1207. #endif
  1208.                 case SRC(ULONG)|FLOAT:
  1209.                     *((float*)es) = *((unsigned long*)es);
  1210.                     break;
  1211.                 case SRC(ULONG)|DOUBLE:
  1212.                     *((double*)es) = *((unsigned long*)es);
  1213.                     break;
  1214. #if SUPPORT_LONG_LONG
  1215.                 case SRC(ULONG)|CLONGLONG:
  1216.                     *((long long*)es) = *((unsigned long*)es);
  1217.                     break;
  1218.                 case SRC(ULONG)|CULONGLONG:
  1219.                     *((unsigned long long*)es) = *((unsigned long*)es);
  1220.                     break;
  1221. #endif
  1222. #if SUPPORT_LONG_DOUBLE
  1223.                 case SRC(ULONG)|CLONGDOUBLE:
  1224.                     *((long double*)es) = *((unsigned long*)es);
  1225.                     break;
  1226. #endif
  1227.                 case SRC(FLOAT)|BYTE:
  1228.                     *((char*)es) = *((float*)es);
  1229.                     break;
  1230.                 case SRC(FLOAT)|SHORT:
  1231.                     *((short*)es) = *((float*)es);
  1232.                     break;
  1233.                 case SRC(FLOAT)|LONG:
  1234.                     *((long*)es) = *((float*)es);
  1235.                     break;
  1236.                 case SRC(FLOAT)|UBYTE:
  1237.                     *((unsigned char*)es) = *((float*)es);
  1238.                     break;
  1239.                 case SRC(FLOAT)|USHORT:
  1240.                     *((unsigned short*)es) = *((float*)es);
  1241.                     break;
  1242.                 case SRC(FLOAT)|ULONG:
  1243.                     *((unsigned long*)es) = *((float*)es);
  1244.                     break;
  1245.                 case SRC(FLOAT)|DOUBLE:
  1246.                     *((double*)es) = *((float*)es);
  1247.                     break;
  1248. #if SUPPORT_LONG_LONG
  1249.                 case SRC(FLOAT)|CLONGLONG:
  1250.                     *((long long*)es) = *((float*)es);
  1251.                     break;
  1252.                 case SRC(FLOAT)|CULONGLONG:
  1253.                     *((unsigned long long*)es) = *((float*)es);
  1254.                     break;
  1255. #endif
  1256. #if SUPPORT_LONG_DOUBLE
  1257.                 case SRC(FLOAT)|CLONGDOUBLE:
  1258.                     *((long double*)es) = *((float*)es);
  1259.                     break;
  1260. #endif
  1261.                 case SRC(DOUBLE)|BYTE:
  1262.                     *((char*)es) = *((double*)es);
  1263.                     break;
  1264.                 case SRC(DOUBLE)|SHORT:
  1265.                     *((short*)es) = *((double*)es);
  1266.                     break;
  1267.                 case SRC(DOUBLE)|LONG:
  1268.                     *((long*)es) = *((double*)es);
  1269.                     break;
  1270.                 case SRC(DOUBLE)|UBYTE:
  1271.                     *((unsigned char*)es) = *((double*)es);
  1272.                     break;
  1273.                 case SRC(DOUBLE)|USHORT:
  1274.                     *((unsigned short*)es) = *((double*)es);
  1275.                     break;
  1276.                 case SRC(DOUBLE)|ULONG:
  1277.                     *((unsigned long*)es) = *((double*)es);
  1278.                     break;
  1279.                 case SRC(DOUBLE)|FLOAT:
  1280.                     *((float*)es) = *((double*)es);
  1281.                     break;
  1282. #if SUPPORT_LONG_LONG
  1283.                 case SRC(DOUBLE)|CLONGLONG:
  1284.                     *((long long*)es) = *((double*)es);
  1285.                     break;
  1286.                 case SRC(DOUBLE)|CULONGLONG:
  1287.                     *((unsigned long long*)es) = *((double*)es);
  1288.                     break;
  1289. #endif
  1290. #if SUPPORT_LONG_DOUBLE
  1291.                 case SRC(DOUBLE)|CLONGDOUBLE:
  1292.                     *((long double*)es) = *((double*)es);
  1293.                     break;
  1294. #endif
  1295. #if SUPPORT_LONG_LONG
  1296.                 case SRC(CLONGLONG)|FLOAT:
  1297.                     *((float*)es) = *((long long*)es);
  1298.                     break;
  1299.                 case SRC(CLONGLONG)|DOUBLE:
  1300.                     *((double*)es) = *((long long*)es);
  1301.                     break;
  1302. #if SUPPORT_LONG_DOUBLE
  1303.                 case SRC(CLONGLONG)|CLONGDOUBLE:
  1304.                     *((long double*)es) = *((long long*)es);
  1305.                     break;
  1306. #endif
  1307.                 case SRC(CULONGLONG)|FLOAT:
  1308.                     *((float*)es) = *((unsigned long long*)es);
  1309.                     break;
  1310.                 case SRC(CULONGLONG)|DOUBLE:
  1311.                     *((double*)es) = *((unsigned long long*)es);
  1312.                     break;
  1313. #if SUPPORT_LONG_DOUBLE
  1314.                 case SRC(CULONGLONG)|CLONGDOUBLE:
  1315.                     *((long double*)es) = *((unsigned long long*)es);
  1316.                     break;
  1317. #endif
  1318. #endif
  1319. #if SUPPORT_LONG_DOUBLE
  1320.                 case SRC(CLONGDOUBLE)|BYTE:
  1321.                     *((char*)es) = *((long double*)es);
  1322.                     break;
  1323.                 case SRC(CLONGDOUBLE)|SHORT:
  1324.                     *((short*)es) = *((long double*)es);
  1325.                     break;
  1326.                 case SRC(CLONGDOUBLE)|LONG:
  1327.                     *((long*)es) = *((long double*)es);
  1328.                     break;
  1329.                 case SRC(CLONGDOUBLE)|UBYTE:
  1330.                     *((unsigned char*)es) = *((long double*)es);
  1331.                     break;
  1332.                 case SRC(CLONGDOUBLE)|USHORT:
  1333.                     *((unsigned short*)es) = *((long double*)es);
  1334.                     break;
  1335.                 case SRC(CLONGDOUBLE)|ULONG:
  1336.                     *((unsigned long*)es) = *((long double*)es);
  1337.                     break;
  1338.                 case SRC(CLONGDOUBLE)|FLOAT:
  1339.                     *((float*)es) = *((long double*)es);
  1340.                     break;
  1341.                 case SRC(CLONGDOUBLE)|DOUBLE:
  1342.                     *((double*)es) = *((long double*)es);
  1343.                     break;
  1344. #if SUPPORT_LONG_LONG
  1345.                 case SRC(CLONGDOUBLE)|CLONGLONG:
  1346.                     *((long long*)es) = *((long double*)es);
  1347.                     break;
  1348.                 case SRC(CLONGDOUBLE)|CULONGLONG:
  1349.                     *((unsigned long long*)es) = *((long double*)es);
  1350.                     break;
  1351. #endif
  1352. #endif
  1353.             }
  1354.             break;
  1355.         }
  1356.         case IMMED:
  1357.         {
  1358.             ++pc;
  1359.             ++np;
  1360.             switch(*pc)
  1361.             {
  1362.  
  1363.                 case SMI|A1|B1:
  1364.                     STORMEMI1(char);
  1365.                 case SMI|A1|B2:
  1366.                     STORMEMI1(short);
  1367.                 case SMI|A1|B4:
  1368.                     STORMEMI1(long);
  1369.                 case SMI|A1|B8:
  1370.                     STORMEMI1(double);
  1371.                 case SMI|A2|B1:
  1372.                     STORMEMI2(char);
  1373.                 case SMI|A2|B2:
  1374.                     STORMEMI2(short);
  1375.                 case SMI|A2|B4:
  1376.                     STORMEMI2(long);
  1377.                 case SMI|A2|B8:
  1378.                     STORMEMI2(double);
  1379.                 case SMI|A3|B1:
  1380.                     STORMEMI3(char);
  1381.                 case SMI|A3|B2:
  1382.                     STORMEMI3(short);
  1383.                 case SMI|A3|B4:
  1384.                     STORMEMI3(long);
  1385.                 case SMI|A3|B8:
  1386.                     STORMEMI3(double);
  1387.                 case SMI|A4|B1:
  1388.                     STORMEMI4(char);
  1389.                 case SMI|A4|B2:
  1390.                     STORMEMI4(short);
  1391.                 case SMI|A4|B4:
  1392.                     STORMEMI4(long);
  1393.                 case SMI|A4|B8:
  1394.                     STORMEMI4(double);
  1395.  
  1396.                 case SSI|A1|B1:
  1397.                     STORSTKI1(char);
  1398.                 case SSI|A1|B2:
  1399.                     STORSTKI1(short);
  1400.                 case SSI|A1|B4:
  1401.                     STORSTKI1(long);
  1402.                 case SSI|A1|B8:
  1403.                     STORSTKI1(double);
  1404.                 case SSI|A2|B1:
  1405.                     STORSTKI2(char);
  1406.                 case SSI|A2|B2:
  1407.                     STORSTKI2(short);
  1408.                 case SSI|A2|B4:
  1409.                     STORSTKI2(long);
  1410.                 case SSI|A2|B8:
  1411.                     STORSTKI2(double);
  1412.                 case SSI|A3|B1:
  1413.                     STORSTKI3(char);
  1414.                 case SSI|A3|B2:
  1415.                     STORSTKI3(short);
  1416.                 case SSI|A3|B4:
  1417.                     STORSTKI3(long);
  1418.                 case SSI|A3|B8:
  1419.                     STORSTKI3(double);
  1420.  
  1421.                 case MODI|BYTE:
  1422.                     MODI_ES(char);
  1423.                 case MODI|SHORT:
  1424.                     MODI_ES(short);
  1425.                 case MODI|LONG:
  1426.                     MODI_ES(long);
  1427.                 case MODI|UBYTE:
  1428.                     MODI_ES(unsigned char);
  1429.                 case MODI|USHORT:
  1430.                     MODI_ES(unsigned short);
  1431.                 case MODI|ULONG:
  1432.                     MODI_ES(unsigned long);
  1433.  
  1434.                 case DEREF|BYTE:
  1435.                     DEREF_ES(char);
  1436.                 case DEREF|SHORT:
  1437.                     DEREF_ES(short);
  1438.                 case DEREF|LONG:
  1439.                     DEREF_ES(long);
  1440.                 case DEREF|UBYTE:
  1441.                     UDEREF_ES(unsigned char);
  1442.                 case DEREF|USHORT:
  1443.                     UDEREF_ES(unsigned short);
  1444.                 case DEREF|ULONG:
  1445.                     UDEREF_ES(unsigned long);
  1446.                 case DEREF|FLOAT:
  1447.                     FDEREF_ES(float);
  1448.                 case DEREF|DOUBLE:
  1449.                     FDEREF_ES(double);
  1450.  
  1451.                 case DEREF1|BYTE:
  1452.                     DEREF1_ES(char);
  1453.                 case DEREF1|SHORT:
  1454.                     DEREF1_ES(short);
  1455.                 case DEREF1|LONG:
  1456.                     DEREF1_ES(long);
  1457.                 case DEREF1|UBYTE:
  1458.                     UDEREF1_ES(unsigned char);
  1459.                 case DEREF1|USHORT:
  1460.                     UDEREF1_ES(unsigned short);
  1461.                 case DEREF1|ULONG:
  1462.                     UDEREF1_ES(unsigned long);
  1463.                 case DEREF1|FLOAT:
  1464.                     FDEREF1_ES(float);
  1465.                 case DEREF1|DOUBLE:
  1466.                     FDEREF1_ES(double);
  1467.             }
  1468.             break;
  1469.         }
  1470.         case LI|B1:
  1471.             LOADI1();
  1472.         case LI|B2:
  1473.             LOADI2();
  1474.         case LI|B4:
  1475.             LOADI4();
  1476.         case LI|B8:
  1477.             LOADI8();
  1478.         case LAI|D1:
  1479.             LOADADDRI1();
  1480.         case LAI|D2:
  1481.             LOADADDRI2();
  1482.         case LAI|D3:
  1483.             LOADADDRI3();
  1484.         case LAI|D4:
  1485.             LOADADDRI4();
  1486.  
  1487.         case LUI|B1:
  1488.             LOADUI1();
  1489.         case LUI|B2:
  1490.             LOADUI2();
  1491.         case LUI|B4:
  1492.             LOADUI4();
  1493.         case LUI|B8:
  1494.             LOADI8();
  1495.  
  1496.         case SM|A1|B1:
  1497.             STORMEM1(char);
  1498.         case SM|A1|B2:
  1499.             STORMEM1(short);
  1500.         case SM|A1|B4:
  1501.             STORMEM1(long);
  1502.         case SM|A1|B8:
  1503.             STORMEM1(double);
  1504.         case SM|A2|B1:
  1505.             STORMEM2(char);
  1506.         case SM|A2|B2:
  1507.             STORMEM2(short);
  1508.         case SM|A2|B4:
  1509.             STORMEM2(long);
  1510.         case SM|A2|B8:
  1511.             STORMEM2(double);
  1512.         case SM|A3|B1:
  1513.             STORMEM3(char);
  1514.         case SM|A3|B2:
  1515.             STORMEM3(short);
  1516.         case SM|A3|B4:
  1517.             STORMEM3(long);
  1518.         case SM|A3|B8:
  1519.             STORMEM3(double);
  1520.         case SM|A4|B1:
  1521.             STORMEM4(char);
  1522.         case SM|A4|B2:
  1523.             STORMEM4(short);
  1524.         case SM|A4|B4:
  1525.             STORMEM4(long);
  1526.         case SM|A4|B8:
  1527.             STORMEM4(double);
  1528.  
  1529.  
  1530.         case ADD|BYTE:
  1531.             ADD_ES(char);
  1532.         case ADD|SHORT:
  1533.             ADD_ES(short);
  1534.         case ADD|LONG:
  1535.             ADD_ES(long);
  1536.         case ADD|UBYTE:
  1537.             ADD_ES(unsigned char);
  1538.         case ADD|USHORT:
  1539.             ADD_ES(unsigned short);
  1540.         case ADD|ULONG:
  1541.             ADD_ES(unsigned long);
  1542.         case ADD|FLOAT:
  1543.             ADD_ES(float);
  1544.         case ADD|DOUBLE:
  1545.             ADD_ES(double);
  1546.  
  1547.         case SUB|BYTE:
  1548.             SUB_ES(char);
  1549.         case SUB|SHORT:
  1550.             SUB_ES(short);
  1551.         case SUB|LONG:
  1552.             SUB_ES(long);
  1553.         case SUB|UBYTE:
  1554.             SUB_ES(unsigned char);
  1555.         case SUB|USHORT:
  1556.             SUB_ES(unsigned short);
  1557.         case SUB|ULONG:
  1558.             SUB_ES(unsigned long);
  1559.         case SUB|FLOAT:
  1560.             SUB_ES(float);
  1561.         case SUB|DOUBLE:
  1562.             SUB_ES(double);
  1563.  
  1564.         case MUL|BYTE:
  1565.             MUL_ES(char);
  1566.         case MUL|SHORT:
  1567.             MUL_ES(short);
  1568.         case MUL|LONG:
  1569.             MUL_ES(long);
  1570.         case MUL|UBYTE:
  1571.             MUL_ES(unsigned char);
  1572.         case MUL|USHORT:
  1573.             MUL_ES(unsigned short);
  1574.         case MUL|ULONG:
  1575.             MUL_ES(unsigned long);
  1576.         case MUL|FLOAT:
  1577.             MUL_ES(float);
  1578.         case MUL|DOUBLE:
  1579.             MUL_ES(double);
  1580.  
  1581.         case DIV|BYTE:
  1582.             DIV_ES(char);
  1583.         case DIV|SHORT:
  1584.             DIV_ES(short);
  1585.         case DIV|LONG:
  1586.             DIV_ES(long);
  1587.         case DIV|UBYTE:
  1588.             DIV_ES(unsigned char);
  1589.         case DIV|USHORT:
  1590.             DIV_ES(unsigned short);
  1591.         case DIV|ULONG:
  1592.             DIV_ES(unsigned long);
  1593.         case DIV|FLOAT:
  1594.             DIV_ES(float);
  1595.         case DIV|DOUBLE:
  1596.             DIV_ES(double);
  1597.  
  1598.         case OR|B1:
  1599.             OR_ES(unsigned char);
  1600.         case OR|B2:
  1601.             OR_ES(unsigned short);
  1602.         case OR|B4:
  1603.             OR_ES(unsigned long);
  1604.  
  1605.         case XOR|B1:
  1606.             XOR_ES(unsigned char);
  1607.         case XOR|B2:
  1608.             XOR_ES(unsigned short);
  1609.         case XOR|B4:
  1610.             XOR_ES(unsigned long);
  1611.  
  1612.         case AND|B1:
  1613.             AND_ES(unsigned char);
  1614.         case AND|B2:
  1615.             AND_ES(unsigned short);
  1616.         case AND|B4:
  1617.             AND_ES(unsigned long);
  1618.  
  1619. #if SUPPORT_LONG_LONG
  1620.         case OR|B8:
  1621.             OR_ES(unsigned long long);
  1622.         case AND|B8:
  1623.             AND_ES(unsigned long long);
  1624.         case XOR|B8:
  1625.             XOR_ES(unsigned long long);
  1626. #else
  1627. #endif
  1628.  
  1629.         case MOD|BYTE:
  1630.             MOD_ES(char);
  1631.         case MOD|SHORT:
  1632.             MOD_ES(short);
  1633.         case MOD|LONG:
  1634.             MOD_ES(long);
  1635.         case MOD|UBYTE:
  1636.             MOD_ES(unsigned char);
  1637.         case MOD|USHORT:
  1638.             MOD_ES(unsigned short);
  1639.         case MOD|ULONG:
  1640.             MOD_ES(unsigned long);
  1641.  
  1642.         case XTD:
  1643.         {
  1644.             ++pc;
  1645.             ++np;
  1646.             switch(*pc)
  1647.             {
  1648.                 case LSH|B1:
  1649.                     LSH_ES(char);
  1650.                 case LSH|B2:
  1651.                     LSH_ES(short);
  1652.                 case LSH|B4:
  1653.                     LSH_ES(long);
  1654.                 case LSH|B8:
  1655.                     LSH_ES(long long);
  1656.  
  1657.                 case LSHI|B1:
  1658.                     LSHI_ES(char);
  1659.                 case LSHI|B2:
  1660.                     LSHI_ES(short);
  1661.                 case LSHI|B4:
  1662.                     LSHI_ES(long);
  1663.                 case LSHI|B8:
  1664.                     LSHI_ES(long long);
  1665.             
  1666.                 case RSH|BYTE:
  1667.                     RSH_ES(char);
  1668.                 case RSH|SHORT:
  1669.                     RSH_ES(short);
  1670.                 case RSH|LONG:
  1671.                     RSH_ES(long);
  1672.                 case RSH|UBYTE:
  1673.                     RSH_ES(unsigned char);
  1674.                 case RSH|USHORT:
  1675.                     RSH_ES(unsigned short);
  1676.                 case RSH|ULONG:
  1677.                     RSH_ES(unsigned long);
  1678.  
  1679.                 case RSHI|BYTE:
  1680.                     RSHI_ES(char);
  1681.                 case RSHI|SHORT:
  1682.                     RSHI_ES(short);
  1683.                 case RSHI|LONG:
  1684.                     RSHI_ES(long);
  1685.                 case RSHI|UBYTE:
  1686.                     RSHI_ES(unsigned char);
  1687.                 case RSHI|USHORT:
  1688.                     RSHI_ES(unsigned short);
  1689.                 case RSHI|ULONG:
  1690.                     RSHI_ES(unsigned long);
  1691.  
  1692.                 case BUILTIN:
  1693.                 {
  1694.                     ++pc;
  1695.                     ++np;
  1696.                     switch(*pc)
  1697.                     {/* THESE BUILTINS CANNOT BE CALLED THROUGH A FUNCPTR */
  1698.                         case SETJMP:
  1699.                         {
  1700.                         long *jb;
  1701.  
  1702.                             jb = *((void**)es);
  1703.                             *((long*)es) = 0;
  1704.     
  1705.                             jb[0] = (long)iv->allocalist;
  1706.                             jb[1] = (long)pc;
  1707.                             if((jb = (long*)setjmp(((void*)&jb[4]))))
  1708.                             {
  1709.                             void *bs,*qs;
  1710.                                 pc = (void*)jb[1];
  1711.                                 *((long*)es) = jb[2];            
  1712.                                 bs = (void*)jb[3];
  1713.                                 while(bs != base_stack)
  1714.                                 {
  1715.                                     qs = ((PSB)bs)->backlink;
  1716.                                     free(bs);
  1717.                                     bs = qs;
  1718.                                 }
  1719.                                 purge_allocas(iv, (void*)jb[0]);
  1720.                                 prune_structs(iv);
  1721.                             }
  1722.                             break;
  1723.                         }
  1724.                         case LONGJMP:
  1725.                         {
  1726.                         long *jb;
  1727.  
  1728.                             jb = *((void**)oes);
  1729.                             jb[2] = *((long*)es);
  1730.                             jb[3] = (long)base_stack;
  1731.                             longjmp(((void*)&jb[4]), (long)jb);
  1732.                             break;
  1733.                         }
  1734.                         case ABORT:
  1735.                             printf("bterp: program called abort.\n");
  1736.                         case EXIT:
  1737.                         {
  1738.                         void *bs, *qs;
  1739.                             bs = base_stack;
  1740.                             while(bs != iv->base_stack)
  1741.                             {
  1742.                                 qs = ((PSB)bs)->backlink;
  1743.                                 free(bs);
  1744.                                 bs = qs;
  1745.                             }
  1746.                             purge_allocas(iv, 0);
  1747.                             longjmp(iv->jb, (int)es);
  1748.                             break;
  1749.                         }
  1750.                         default:
  1751.                             do_builtin(iv, *pc, &es);
  1752.                             break;
  1753.                     }
  1754.                     break;
  1755.                 } /* END: XTD BUILTIN */
  1756.                 case CLRDAT:
  1757.                 {
  1758.                     memset(*((void**)oes), 0, *((long*)es));
  1759.                     es -= 2*SZ;
  1760.                     break;
  1761.                 }
  1762.                 case SWITCH:
  1763.                 {
  1764.                 unsigned long key[2];
  1765.                 unsigned char **result;
  1766.  
  1767.                     key[0] = *((unsigned short*)np)<<11;
  1768.                     key[1] = *((long*)es);
  1769.                     if(findswitch(iv, key, &result))
  1770.                     {
  1771.                          pc = *result - 1;    
  1772.                     }
  1773.                     else
  1774.                     {
  1775.                         pc += 2;
  1776.                     }
  1777.                     es = oes;
  1778.                     break;
  1779.                 }
  1780.                 case CALLSETUP:
  1781.                 {
  1782.                 PCB cb = (PCB)es;
  1783.                 Pft ft = cb->loc;
  1784.                 int hidden;
  1785.                 long stksiz, maxes;
  1786.                 long argsiz, strucsiz;
  1787.                 int flags = 0;
  1788.                     if(ft->fmods & Fbuiltin)
  1789.                     {/* This only happens if the programmer uses a function
  1790.                         pointer which points to a builtin function. */
  1791.                         flags = 0x80;
  1792.                     }
  1793.                     cb->argsiz = argsiz = G4(np);
  1794.                 
  1795.                     if((hidden = ft->fmods & Fretstr))
  1796.                     {/* function returning a structure */
  1797.                         strucsiz = ft->retsiz<<2;
  1798.                     }    
  1799.                     stksiz = ft->stksiz<<2;
  1800.                     maxes = ft->maxes;
  1801.  
  1802.                     if(ft->fmods & Fnested)
  1803.                     {/* Calling nested function */
  1804.                         cb->argofs = (ft->stkbeg+(stksiz-(ft->argsiz<<2)-hidden)) >> 2;
  1805.                         if(ft->funcaddr >= first_loc && ft->funcaddr <= last_loc)
  1806.                         {/* call from enclosing function */
  1807.                             cb->base_stack = base_stack;
  1808.                             cb->es = es;
  1809.                             cb->flags = 0x10 + hidden;
  1810.                         }
  1811.                         else
  1812.                         {/* callback from another function */
  1813.                         PSB prev = (PSB)(fs - sizeof(SB));
  1814.                         long floc = prev->first_loc;
  1815.                         long lloc = prev->last_loc;
  1816.  
  1817.                           while((prev = prev->backlink))
  1818.                           {
  1819.                             if(        ft->funcaddr >= floc
  1820.                                 &&    ft->funcaddr <= lloc)
  1821.                             {/* This is the container of the nested func */
  1822.                              cb->base_stack = (char*)prev;
  1823.                              cb->es = prev->cbes;
  1824.                              break;
  1825.                             }
  1826.                             floc = prev->first_loc;
  1827.                             lloc = prev->last_loc;
  1828.                           }
  1829.                           cb->flags = 0x20 + hidden;
  1830.                         }
  1831.                     }
  1832.                     else if(ft->fmods & Fextern)
  1833.                     {/* Calling external function */
  1834.                         /* Dynamic link it */
  1835.                         if(!(ft->fmods & Fthunked))
  1836.                             load_efunc(iv, ft);
  1837.  
  1838.                         cb->base_stack = calloc(1, sizeof(SB)+argsiz+hidden);
  1839.                         cb->argsiz = argsiz+hidden;
  1840.                         cb->argofs = 0; 
  1841.                         cb->flags = 0x40 + hidden;
  1842.                     }
  1843.                     else
  1844.                     {/* Calling interpreted function */
  1845.                       if(flags & 0x80)
  1846.                       {
  1847.                         cb->flags = flags;
  1848.                         cb->es = cb->base_stack = calloc(1, 128);
  1849.                       }
  1850.                       else
  1851.                       {
  1852.                       long es_beg;
  1853.                       long fs_size;
  1854.                       PSB sp;
  1855.                         es_beg = stksiz+hidden+argsiz;
  1856.                         fs_size = es_beg + ((maxes+6)*SZ);
  1857.                         cb->base_stack = calloc(1, fs_size+sizeof(SB));
  1858.                         sp = (PSB)cb->base_stack;
  1859.                         cb->es = cb->base_stack + sizeof(SB) + es_beg;
  1860.                         cb->argofs = stksiz >> 2;
  1861.                         cb->flags = flags + hidden;                        
  1862.                         sp->first_loc = first_loc;
  1863.                         sp->last_loc = last_loc;
  1864.                         sp->backlink = base_stack;
  1865.                         sp->stksize = fs_size+sizeof(SB);
  1866.                       }
  1867.                      }
  1868.                     if(hidden)
  1869.                     {/* function returning a structure */
  1870.                     void *strucptr = malloc(strucsiz);
  1871.         *((void**)(cb->base_stack+sizeof(SB)+(cb->argofs<<2))) = strucptr;
  1872.                         ensure_strrets(iv);
  1873.                         iv->struclist[iv->strretcnt++] = strucptr;
  1874.                     }
  1875.                     pc += 4;
  1876.                     break;
  1877.                 }
  1878.                 case RETSTRUCT:
  1879.                 {
  1880.                 long size = G2(np)<<2;
  1881.                 long offset = G2(np+2)<<2;
  1882.                 void *dst;
  1883.  
  1884.                     dst = fs + offset;
  1885.                     dst = *((void**)dst);
  1886.                     memcpy(dst, *((void**)es), size);
  1887. if(iv->debug) {
  1888. printf("RETSTRUCT ofs=%lx es=%p val=0x%lx\n", pc_offset, es, *((long*)es));
  1889. fflush(stdout);
  1890. }
  1891.                     return es;
  1892.                 }
  1893.                 case PRUNESTRUCT:
  1894.                 {
  1895.                     prune_structs(iv);
  1896.                     break;
  1897.                 }
  1898.                 case GETBITFIELD:
  1899.                 {
  1900.                     if(pc[1] + pc[2] <= 32)
  1901.                     {
  1902.                         *((long*)es) >>= pc[1];
  1903.                         *((long*)es) &= bfields[pc[2]];
  1904.                         if(pc[3])
  1905.                         {/* sign extend */
  1906.                             if(*((long*)es) & tsfields[pc[2]])
  1907.                             {
  1908.                                 *((long*)es) |= sfields[pc[2]];
  1909.                                 ((long*)es)[1] = 0xffffffff;
  1910.                             }
  1911.                             else ((long*)es)[1] = 0;
  1912.                         }
  1913.                     }
  1914.                     else
  1915.                     {
  1916. #if SUPPORT_LONG_LONG
  1917.                             *((long long*)es) >>= pc[1];
  1918.                             *((long long*)es) &= lbfields[pc[2]];
  1919.                             if(pc[3])
  1920.                             {
  1921.                                 if(*((long long*)es) & ltsfields[pc[2]])
  1922.                                     *((long long*)es) |= lsfields[pc[2]];
  1923.                             }
  1924. #else
  1925. #endif
  1926.                     }
  1927.                     pc += 3;
  1928.                     break;
  1929.                 }
  1930.                 case PUTBITFIELD:
  1931.                 {
  1932.                     if(pc[1] + pc[2] <= 32)
  1933.                     {
  1934.                     unsigned long mask = bfields[pc[2]];
  1935.                     void *dst = *((void **)oes);
  1936.                     unsigned long dat = *((long*)es);
  1937.                         dat &= mask;
  1938.                         dat <<= pc[1];
  1939.                         mask <<= pc[1];
  1940.                         switch(pc[3])
  1941.                         {
  1942.                             case    1:
  1943.                                 *((char*)dst) &= ~mask;
  1944.                                 *((char*)dst) |= dat;
  1945.                                 break;
  1946.                             case    2:
  1947.                                 *((short*)dst) &= ~mask;
  1948.                                 *((short*)dst) |= dat;
  1949.                                 break;
  1950.                             case    4:
  1951.                                 *((long*)dst) &= ~mask;
  1952.                                 *((long*)dst) |= dat;
  1953.                                 break;
  1954.                             default:
  1955.                                 break;
  1956.                         }
  1957.                     }
  1958.                     else
  1959.                     {
  1960. #if SUPPORT_LONG_LONG
  1961.                     unsigned long long mask = lbfields[pc[2]];
  1962.                     void *dst = *((void **)oes);
  1963.                     unsigned long long dat = *((unsigned long long *)es);
  1964.                         dat &= mask;
  1965.                         dat <<= pc[1];
  1966.                         mask <<= pc[1];
  1967.                         switch(pc[3])
  1968.                         {
  1969.                             case    1:
  1970.                                 *((char*)dst) &= ~mask;
  1971.                                 *((char*)dst) |= dat;
  1972.                                 break;
  1973.                             case    2:
  1974.                                 *((short*)dst) &= ~mask;
  1975.                                 *((short*)dst) |= dat;
  1976.                                 break;
  1977.                             case    4:
  1978.                                 *((long*)dst) &= ~mask;
  1979.                                 *((long*)dst) |= dat;
  1980.                                 break;
  1981.                             case    8:
  1982.                                 *((long long*)dst) &= ~mask;
  1983.                                 *((long long*)dst) |= dat;
  1984.                                 break;
  1985.                             default:
  1986.                                 break;
  1987.                         }
  1988. #else
  1989. #endif
  1990.                     }
  1991.                     pc += 3;
  1992.                     es -= 2*SZ;
  1993.                     break;
  1994.                 }
  1995. #if SUPPORT_LONG_DOUBLE
  1996.                 case LI:
  1997.                     LOADIX();
  1998. #endif
  1999.                 case IMMED:
  2000.                 {
  2001.                     ++pc;
  2002.                     ++np;
  2003.                     switch(*pc)
  2004.                     {
  2005. #if SUPPORT_LONG_DOUBLE
  2006.  
  2007.                         case SMI|A1:
  2008.                             STORMEMI1(long double);
  2009.                         case SMI|A2:
  2010.                             STORMEMI2(long double);
  2011.                         case SMI|A3:
  2012.                             STORMEMI3(long double);
  2013.                         case SMI|A4:
  2014.                             STORMEMI4(long double);
  2015.  
  2016.                         case SSI|A1:
  2017.                             STORSTKI1(long double);
  2018.                         case SSI|A2:
  2019.                             STORSTKI2(long double);
  2020.                         case SSI|A3:
  2021.                             STORSTKI3(long double);
  2022.  
  2023.                         case DEREF|LONGDOUBLE:
  2024.                             FDEREF_ES(long double);
  2025.                         case DEREF1|LONGDOUBLE:
  2026.                             FDEREF1_ES(long double);
  2027. #endif
  2028. #if SUPPORT_LONG_LONG
  2029.                         case DEREF|LONGLONG:
  2030.                         case DEREF|ULONGLONG:
  2031.                             FDEREF_ES(long long);
  2032.  
  2033.                         case DEREF1|LONGLONG:
  2034.                         case DEREF1|ULONGLONG:
  2035.                             FDEREF1_ES(long long);
  2036.  
  2037.                         case MODI|LONGLONG:
  2038.                             MODI_ES(long long);
  2039.                         case MODI|ULONGLONG:
  2040.                             MODI_ES(unsigned long long);
  2041. #endif
  2042.                     }
  2043.                     break;
  2044.                 }/* END: XTD IMMED */
  2045. #if SUPPORT_LONG_LONG
  2046.                 
  2047.                 case ADD|LONGLONG:
  2048.                     ADD_ES(long long);
  2049.                 case ADD|ULONGLONG:
  2050.                     ADD_ES(unsigned long long);
  2051.                 case SUB|LONGLONG:
  2052.                     SUB_ES(long long);
  2053.                 case SUB|ULONGLONG:
  2054.                     SUB_ES(unsigned long long);
  2055.                 case MUL|LONGLONG:
  2056.                     MUL_ES(long long);
  2057.                 case MUL|ULONGLONG:
  2058.                     MUL_ES(unsigned long long);
  2059.                 case DIV|LONGLONG:
  2060.                     DIV_ES(long long);
  2061.                 case DIV|ULONGLONG:
  2062.                     DIV_ES(unsigned long long);
  2063.                 case NEG|LONGLONG:
  2064.                     NEG_ES(long long);
  2065.                 case NEG|ULONGLONG:
  2066.                     NEG_ES(unsigned long long);
  2067.                 case LT|LONGLONG:
  2068.                     LT_ES(long long);
  2069.                 case LT|ULONGLONG:
  2070.                     LT_ES(unsigned long long);
  2071.                 case GT|LONGLONG:
  2072.                     GT_ES(long long);
  2073.                  case GT|ULONGLONG:
  2074.                     GT_ES(unsigned long long);
  2075.                 case LE|LONGLONG:
  2076.                     LE_ES(long long);
  2077.                 case LE|ULONGLONG:
  2078.                     LE_ES(unsigned long long);
  2079.                 case GE|LONGLONG:
  2080.                     GE_ES(long long);
  2081.                 case GE|ULONGLONG:
  2082.                     GE_ES(unsigned long long);
  2083.                 case NE|LONGLONG:
  2084.                     NE_ES(long long);
  2085.                 case NE|ULONGLONG:
  2086.                     NE_ES(unsigned long long);
  2087.                 case EQ|LONGLONG:
  2088.                     EQ_ES(long long);
  2089.                 case EQ|ULONGLONG:
  2090.                     EQ_ES(unsigned long long);
  2091.                 case RSH|SLONGLONG:
  2092.                     RSH_ES(long long);
  2093.                 case RSH|SULONGLONG:
  2094.                     RSH_ES(unsigned long long);
  2095.  
  2096.                 case MOD|LONGLONG:
  2097.                     MODL_ES(long long);
  2098.                 case MOD|ULONGLONG:
  2099.                     MODL_ES(unsigned long long);
  2100.  
  2101.  
  2102.                 case RSHI|SLONGLONG:
  2103.                     RSHI_ES(long long);
  2104.                 case RSHI|SULONGLONG:
  2105.                     RSHI_ES(unsigned long long);
  2106. #endif
  2107.  
  2108. #if SUPPORT_LONG_DOUBLE
  2109.                 
  2110.                 case ADD|LONGDOUBLE:
  2111.                     ADD_ES(long double);
  2112.                 case SUB|LONGDOUBLE:
  2113.                     SUB_ES(long double);
  2114.                 case MUL|LONGDOUBLE:
  2115.                     MUL_ES(long double);
  2116.                 case DIV|LONGDOUBLE:
  2117.                     DIV_ES(long double);
  2118.                 case TRUTHOF|BX:
  2119.                     TRUTH_ES(long double);
  2120.                 case NOT|BX:
  2121.                     NOT_ES(long double);
  2122.                 case NEG|LONGDOUBLE:
  2123.                     NEG_ES(long double);
  2124.                 case LT|LONGDOUBLE:
  2125.                     LT_ES(long double);
  2126.                 case GT|LONGDOUBLE:
  2127.                     GT_ES(long double);
  2128.                 case LE|LONGDOUBLE:
  2129.                     LE_ES(long double);
  2130.                 case GE|LONGDOUBLE:
  2131.                     GE_ES(long double);
  2132.                 case NE|LONGDOUBLE:
  2133.                     NE_ES(long double);
  2134.                 case EQ|LONGDOUBLE:
  2135.                     EQ_ES(long double);
  2136.  
  2137.                 case LS|A1:
  2138.                     LOADSTK1(long double);
  2139.                 case LS|A2:
  2140.                     LOADSTK2(long double);
  2141.                 case LS|A3:
  2142.                     LOADSTK3(long double);
  2143.  
  2144.                 case LM|A1:
  2145.                     LOADMEM1(long double);
  2146.                 case LM|A2:
  2147.                     LOADMEM2(long double);
  2148.                 case LM|A3:
  2149.                     LOADMEM3(long double);
  2150.                 case LM|A4:
  2151.                     LOADMEM4(long double);
  2152.  
  2153.                 case SS|A1:
  2154.                     STORSTK1(long double);
  2155.                 case SS|A2:
  2156.                     STORSTK2(long double);
  2157.                 case SS|A3:
  2158.                     STORSTK3(long double);
  2159.  
  2160.                 case SM|A1:
  2161.                     STORMEM1(long double);
  2162.                 case SM|A2:
  2163.                     STORMEM2(long double);
  2164.                 case SM|A3:
  2165.                     STORMEM3(long double);
  2166.                 case SM|A4:
  2167.                     STORMEM4(long double);
  2168.  
  2169.                 case MOVSS:
  2170.                 {
  2171.                     pc += mover(iv, np+1, *np, BX, fs, fs);
  2172.                     break;
  2173.                 }                
  2174.                 case MOVSM:
  2175.                 {
  2176.                     pc += mover(iv, np+1, *np, BX, fs, dd);
  2177.                     break;
  2178.                 }
  2179.                 case MOVMS:
  2180.                 {
  2181.                     pc += mover(iv, np+1, *np, BX, dd, fs);
  2182.                     break;
  2183.                 }
  2184.                 case MOVMM:
  2185.                 {
  2186.                     pc += mover(iv, np+1, *np, BX, dd, dd);
  2187.                     break;
  2188.                 }
  2189. #endif /* SUPPORT_LONG_DOUBLE */
  2190.             }
  2191.             break;
  2192.         }/* END: XTD */
  2193.  
  2194.         case GT|BYTE:
  2195.             GT_ES(char);
  2196.         case GT|SHORT:
  2197.             GT_ES(short);
  2198.         case GT|LONG:
  2199.             GT_ES(long);
  2200.         case GT|UBYTE:
  2201.             GT_ES(unsigned char);
  2202.         case GT|USHORT:
  2203.             GT_ES(unsigned short);
  2204.         case GT|ULONG:
  2205.             GT_ES(unsigned long);
  2206.         case GT|FLOAT:
  2207.             GT_ES(float);
  2208.         case GT|DOUBLE:
  2209.             GT_ES(double);
  2210.  
  2211.         case LT|BYTE:
  2212.             LT_ES(char);
  2213.         case LT|SHORT:
  2214.             LT_ES(short);
  2215.         case LT|LONG:
  2216.             LT_ES(long);
  2217.         case LT|UBYTE:
  2218.             LT_ES(unsigned char);
  2219.         case LT|USHORT:
  2220.             LT_ES(unsigned short);
  2221.         case LT|ULONG:
  2222.             LT_ES(unsigned long);
  2223.         case LT|FLOAT:
  2224.             LT_ES(float);
  2225.         case LT|DOUBLE:
  2226.             LT_ES(double);
  2227.  
  2228.         case GE|BYTE:
  2229.             GE_ES(char);
  2230.         case GE|SHORT:
  2231.             GE_ES(short);
  2232.         case GE|LONG:
  2233.             GE_ES(long);
  2234.         case GE|UBYTE:
  2235.             GE_ES(unsigned char);
  2236.         case GE|USHORT:
  2237.             GE_ES(unsigned short);
  2238.         case GE|ULONG:
  2239.             GE_ES(unsigned long);
  2240.         case GE|FLOAT:
  2241.             GE_ES(float);
  2242.         case GE|DOUBLE:
  2243.             GE_ES(double);
  2244.  
  2245.         case LE|BYTE:
  2246.             LE_ES(char);
  2247.         case LE|SHORT:
  2248.             LE_ES(short);
  2249.         case LE|LONG:
  2250.             LE_ES(long);
  2251.         case LE|UBYTE:
  2252.             LE_ES(unsigned char);
  2253.         case LE|USHORT:
  2254.             LE_ES(unsigned short);
  2255.         case LE|ULONG:
  2256.             LE_ES(unsigned long);
  2257.         case LE|FLOAT:
  2258.             LE_ES(float);
  2259.         case LE|DOUBLE:
  2260.             LE_ES(double);
  2261.  
  2262.         case NE|BYTE:
  2263.             NE_ES(char);
  2264.         case NE|SHORT:
  2265.             NE_ES(short);
  2266.         case NE|LONG:
  2267.             NE_ES(long);
  2268.         case NE|UBYTE:
  2269.             NE_ES(unsigned char);
  2270.         case NE|USHORT:
  2271.             NE_ES(unsigned short);
  2272.         case NE|ULONG:
  2273.             NE_ES(unsigned long);
  2274.         case NE|FLOAT:
  2275.             NE_ES(float);
  2276.         case NE|DOUBLE:
  2277.             NE_ES(double);
  2278.  
  2279.         case EQ|BYTE:
  2280.             EQ_ES(char);
  2281.         case EQ|SHORT:
  2282.             EQ_ES(short);
  2283.         case EQ|LONG:
  2284.             EQ_ES(long);
  2285.         case EQ|UBYTE:
  2286.             EQ_ES(unsigned char);
  2287.         case EQ|USHORT:
  2288.             EQ_ES(unsigned short);
  2289.         case EQ|ULONG:
  2290.             EQ_ES(unsigned long);
  2291.         case EQ|FLOAT:
  2292.             EQ_ES(float);
  2293.         case EQ|DOUBLE:
  2294.             EQ_ES(double);
  2295.  
  2296.         case ARG:
  2297.         case ARGA:
  2298.         case ARGF:
  2299.         {
  2300.         PCB cb = (PCB)(es-(3*SZ));
  2301.         long size = *((long*)es);
  2302.         void *src = oes-SZ;
  2303.         void *dst;
  2304.             if(cb->flags & 0x80)
  2305.             {/* arg to builtin func */
  2306.                 cb->es += SZ;
  2307.                 dst = cb->es;
  2308.             }
  2309.             else
  2310.             {
  2311.                 dst = cb->base_stack+sizeof(SB)+(cb->argofs<<2)+*((long*)oes);
  2312.             }
  2313.             if(*pc == ARGA)
  2314.             {/* dereference */
  2315.                 src = *((void**)src);
  2316.             }
  2317.             else if(*pc == ARGF)
  2318.             {/* Passing address of function */
  2319.             Pft ft = *((Pft*)src);
  2320.  
  2321.               if(ft->fmods & Fnested)
  2322.               {/* Record the current evaluation stack
  2323.                       the nested func will be called back */
  2324.                 ((PSB)base_stack)->cbes = (void*)cb;
  2325.               }
  2326.               if(cb->flags & 0x40)
  2327.               {/* To an external function */
  2328.                 if(!(ft->fmods & Fextern))
  2329.                 {/* Passing address of local function */
  2330.                   if(!(ft->fmods & Fthunked))
  2331.                   {
  2332.                     *((void**)src) = make_callback_thunk(    iv,
  2333.                                                             base_stack,
  2334.                                                             ft);
  2335.                     ft->fmods |= Fthunked;
  2336.                     if(ft->fmods & Fnested)
  2337.                     {/* The thunk will be freed later */
  2338.                         ((PSB)base_stack)->thunkaddr = *((void**)src);
  2339.                     }
  2340.                   }
  2341.                 }
  2342.               }
  2343.             }/* END: *pc == ARGF */
  2344.             switch(size)
  2345.             {
  2346.                 case 1:
  2347.                     *((char*)dst) = *((char*)src);
  2348.                     break;
  2349.                 case 2:
  2350.                     *((short*)dst) = *((short*)src);
  2351.                     break;
  2352.                 case 4:
  2353.                     *((long*)dst) = *((long*)src);
  2354.                     break;
  2355.                 case 8:
  2356.                     *((double*)dst) = *((double*)src);
  2357.                     break;
  2358.                 default:
  2359.                     memcpy(dst, src, size);
  2360.                     break;
  2361.             }
  2362.             es -= 3*SZ;
  2363.             break;
  2364.         }
  2365.  
  2366.         case MOVSS|B1:
  2367.         case MOVSS|B2:
  2368.         case MOVSS|B4:
  2369.         case MOVSS|B8:
  2370.         {
  2371.             pc += mover(iv, np+1, *np, *pc & 3, fs, fs);
  2372.             break;
  2373.         }
  2374.         case MOVSM|B1:
  2375.         case MOVSM|B2:
  2376.         case MOVSM|B4:
  2377.         case MOVSM|B8:
  2378.         {
  2379.             pc += mover(iv, np+1, *np, *pc & 3, fs, dd);
  2380.             break;
  2381.         }
  2382.         case MOVMS|B1:
  2383.         case MOVMS|B2:
  2384.         case MOVMS|B4:
  2385.         case MOVMS|B8:
  2386.         {
  2387.             pc += mover(iv, np+1, *np, *pc & 3, dd, fs);
  2388.             break;
  2389.         }        
  2390.         case MOVMM|B1:
  2391.         case MOVMM|B2:
  2392.         case MOVMM|B4:
  2393.         case MOVMM|B8:
  2394.         {
  2395.             pc += mover(iv, np+1, *np, *pc & 3, dd, dd);
  2396.             break;
  2397.         }
  2398.         case DUMP:
  2399.         {
  2400.             es = oes;
  2401.             break;
  2402.         }
  2403.         case REGAIN:
  2404.         {
  2405.             es = nes;
  2406.             break;
  2407.         }
  2408.         case CALL:
  2409.         {
  2410.         PCB cb = (PCB)es;
  2411.         Pft ft = cb->loc;
  2412.           if(cb->flags & 0x80)
  2413.           {/* call builtin function through a function pointer */
  2414.           char *pes = cb->es;
  2415.  
  2416.             if(do_builtin(iv, (unsigned char)ft->funcaddr, &pes))
  2417.             {/* builtin returned something */
  2418. #if SUPPORT_LONG_DOUBLE
  2419.                 *((long double*)es) = *((long double*)(pes));
  2420. #else
  2421.                 *((double*)es) = *((double*)pes);
  2422. #endif
  2423.             }
  2424.             free(cb->base_stack);
  2425.           }
  2426.           else if(cb->flags & 0x40)
  2427.           {/* call external function */
  2428.           unsigned short fmods = ft->fmods;
  2429.           DATUM lastval;
  2430.             if(fmods & Fretstr)
  2431.             {
  2432.               _ExternCallS(    ft->funcaddr, 
  2433.                             cb->base_stack+sizeof(SB), 
  2434.                             cb->argsiz,
  2435.                             &lastval);
  2436.             }
  2437.             else
  2438.             {
  2439.               _ExternCall(    ft->funcaddr, 
  2440.                             cb->base_stack+sizeof(SB), 
  2441.                             cb->argsiz,
  2442.                             &lastval);
  2443.             }
  2444.             if(fmods & Fretdbl)
  2445.             {
  2446.                 asm ("fstpl %0" : "=g"(lastval.Udouble) :);
  2447.             }
  2448.             else if(fmods & Fretflt)
  2449.             {
  2450.                 asm ("fstps %0" : "=g"(lastval.Ufloat) :);
  2451.             }
  2452.             else if(fmods & Fretldbl)
  2453.             {
  2454. #if SUPPORT_LONG_DOUBLE
  2455.                 asm ("fstpt %0" : "=g"(lastval.Ulongdouble) :);
  2456. #else
  2457.                 asm ("fstpl %0" : "=g"(lastval.Udouble) :);
  2458. #endif
  2459.             }
  2460. #if SUPPORT_LONG_DOUBLE
  2461.             *((long double*)es) = lastval.Ulongdouble;
  2462. #else
  2463.             *((double*)es) = lastval.Udouble;
  2464. #endif
  2465.             free(cb->base_stack);
  2466.           }/* END: call external func */
  2467.           else
  2468.           { /* call internal function */
  2469.           void *pes;
  2470.           void *lastalloca = iv->allocalist;
  2471.             pes = bterp_eval(iv, ft->funcaddr, cb->base_stack, cb->es, 
  2472.                 cb->base_stack+((PSB)cb->base_stack)->stksize);
  2473. #if SUPPORT_LONG_DOUBLE
  2474.             *((long double*)es) = *((long double*)pes);
  2475. #else
  2476.             *((double*)es) = *((double*)pes);
  2477. #endif
  2478.             if(cb->flags & 0x20)
  2479.             {/* calledback a nested function */
  2480.  
  2481.             }
  2482.             else if(!(cb->flags & 0x10))
  2483.             {/* called interpreted function */
  2484.                 free(cb->base_stack);
  2485.             } 
  2486.             purge_allocas(iv, lastalloca);
  2487.           }/* END: call internal function */
  2488.           break;
  2489.         }
  2490.         case RET:
  2491.         {
  2492. if(iv->debug) {
  2493. printf("RET ofs=%lx es=%p val=0x%lx\n", pc_offset, es, *((long*)es));
  2494. fflush(stdout);
  2495. }
  2496.             return es;
  2497.         }
  2498.         case SWAP:
  2499.         {
  2500.         char t[SZ];
  2501.             memcpy(t,es,SZ);
  2502.             memcpy(es,oes,SZ);
  2503.             memcpy(oes,t,SZ);
  2504.             break;
  2505.         }    
  2506.         case SWAP4:
  2507.         {
  2508.         long x;
  2509.             x = *((long *)es);
  2510.             *((long*)es) = *((long*)oes);
  2511.             *((long*)oes) = x;
  2512.             break;
  2513.         }
  2514.         case SWAP4DEEP:
  2515.         {
  2516.         long x;
  2517.             x = *((long*)oes);
  2518.             *((long*)oes) = *((long*)(oes-SZ));
  2519.             *((long*)(oes-SZ)) = x;
  2520.             break;
  2521.         }
  2522.         case DUP:
  2523.         {
  2524.             memcpy(nes,es,SZ);
  2525.             es = nes;
  2526.             break;
  2527.         }
  2528.         case DUP4:
  2529.         {
  2530.             *((long*)nes) = *((long*)es);
  2531.             es = nes;
  2532.             break;
  2533.         }
  2534.         case ABSMEM:
  2535.         {
  2536.             *((unsigned long*)es) += (unsigned long)dd;
  2537.             break;
  2538.         }
  2539.         case ABSSTK:
  2540.         {
  2541.             *((unsigned long*)es) += (unsigned long)fs;
  2542.             break;
  2543.         }
  2544.         case MOVDA1:
  2545.         {
  2546.             **((char**)(oes)) = *((char*)es);    
  2547.             es -= 2*SZ;
  2548.             break;
  2549.         }
  2550.         case MOVDA2:
  2551.         {
  2552.             **((short**)(oes)) = *((short*)es);    
  2553.             es -= 2*SZ;
  2554.             break;
  2555.         }
  2556.         case MOVDA4:
  2557.         {
  2558.             **((long**)(oes)) = *((long*)es);    
  2559.             es -= 2*SZ;
  2560.             break;
  2561.         }
  2562.         case MOVDA8:
  2563.         {
  2564.             **((double**)(oes)) = *((double*)es);    
  2565.             es -= 2*SZ;
  2566.             break;
  2567.         }
  2568.         case MOVDAX:
  2569.         {
  2570. #if SUPPORT_LONG_DOUBLE
  2571.             **((long double**)(oes)) = *((long double*)es);    
  2572. #else
  2573.             memcpy(*((void**)(oes)), es, XSZ);
  2574. #endif
  2575.             es -= 2*SZ;
  2576.             break;
  2577.         }
  2578.         case MOVAA1:
  2579.         {
  2580.             **((char**)(oes)) = **((char**)es);    
  2581.             es -= 2*SZ;
  2582.             break;
  2583.         }
  2584.         case MOVAA2:
  2585.         {
  2586.             **((short**)(oes)) = **((short**)es);    
  2587.             es -= 2*SZ;
  2588.             break;
  2589.         }
  2590.         case MOVAA4:
  2591.         {
  2592.             **((long**)(oes)) = **((long**)es);    
  2593.             es -= 2*SZ;
  2594.             break;
  2595.         }
  2596.         case MOVAA8:
  2597.         {
  2598.             **((double**)(oes)) = **((double**)es);    
  2599.             es -= 2*SZ;
  2600.             break;
  2601.         }
  2602.         case MOVAAX:
  2603.         {
  2604. #if SUPPORT_LONG_DOUBLE
  2605.             **((long double**)(oes)) = **((long double**)es);    
  2606. #else
  2607.             memcpy(*((void**)(oes)), *((void**)es), XSZ);
  2608. #endif
  2609.             es -= 2*SZ;
  2610.             break;
  2611.         }
  2612.         case MOVAAC:
  2613.         {
  2614.             memcpy(*((void**)(es-(2*SZ))), *((void**)(oes)), *((long*)(es)));
  2615.             es -= 3*SZ;
  2616.             break;
  2617.         }
  2618.     }
  2619.   }/* END: for(;;++pc) */
  2620. /* NOT REACHED */
  2621.   return 0;
  2622. }/* END: bterp_eval() */
  2623. /* ====================== END INTERPRETER CODE ===================== */
  2624.  
  2625. /* ==================  INITIALIZATION CODE BELOW THIS POINT ================ */
  2626. static Piv tiv;    /* temporary storage of iv whilst calling oxlink */
  2627.  
  2628. int 
  2629. bterp_setup_functhunk(FE entry, struct nlist *nl)
  2630. {/* Called from the dynamic linker */
  2631. Pft ft;
  2632.  
  2633.     ft = (void*)(entry->data_start_address + nl->n_value);
  2634.  
  2635.     if(ft->fmods & Fextern)
  2636.     {/* store a pointer to the function name string */
  2637.         if(!(ft->fmods & Fthunked))
  2638.         {
  2639.             ft->funcaddr = (long)(entry->strings + nl->n_un.n_strx);
  2640.         }
  2641.         return 0;
  2642.     }
  2643.     else if(!(ft->fmods & Fthunked))
  2644.     {/* export a useful address */
  2645.         nl->n_value = (long)make_callback_thunk(tiv, 0, ft);
  2646.         ft->fmods |= Fthunked;
  2647.     }
  2648.     return 1;
  2649. }
  2650. void
  2651. bterp_setup_switch(FE entry, struct nlist *nl)
  2652. {/* Called from the dynamic linker */
  2653. unsigned long key[2];
  2654. long value;
  2655.  
  2656.     if(tiv->swtable == 0)
  2657.         tiv->swtable = calloc(1, SWITCHMOD*sizeof(void*));
  2658.  
  2659.     key[0] = nl->n_desc<<11;
  2660.     key[1] = nl->n_un.n_strx;
  2661.     value = (long)(entry->text_start_address + nl->n_value);
  2662.     saveswitch(tiv, key, value);    
  2663. }
  2664.  
  2665. /* ====================== THE MAIN PROGRAM =============================== */
  2666.  
  2667. static char *
  2668. filenameof(char *path)
  2669. {
  2670. char *ret = path;
  2671. int i = strlen(path)-1;
  2672.  
  2673.     for( ; i >= 0; --i)
  2674.       if(path[i] == '/' || path[i] == '\\' || path[i] == ':')
  2675.         ret = &path[i+1];
  2676.     return ret;
  2677. }
  2678.  
  2679. static char *
  2680. propernameof(char *path)
  2681. {
  2682. int pathlen = strlen(path);
  2683. char *name = malloc(pathlen+8);
  2684. int i;
  2685.  
  2686.     strcpy(name, path);
  2687.     for(i = pathlen-1; i >= 0; --i)
  2688.     {
  2689.       if(name[i] == '/' || name[i] == '\\' || name[i] == ':')
  2690.           break;
  2691.       else if(name[i] == '.')
  2692.         return name;
  2693.     }
  2694.     strcat(name, ".byt");
  2695.     return name;
  2696. }
  2697. static char *
  2698. basenameof(char *filename)
  2699. {
  2700. char *name = malloc(strlen(filename)+8);
  2701. int i;
  2702.     strcpy(name, filename);
  2703.     for(i = 0; name[i]; ++i)
  2704.       if(name[i] == '.')
  2705.         name[i] = 0;
  2706.     return name;
  2707. }
  2708. static void
  2709. setup_run_args(Piv iv, int argc, char **argv, char *startname)
  2710. {
  2711. int i;
  2712.  
  2713.     if(!startname)
  2714.     {
  2715.         startname = basenameof(filenameof(argv[1]));
  2716.     }
  2717.     iv->run_argcnt = argc - 1;
  2718.     if(iv->run_argcnt > MAX_RUNARGS)
  2719.         iv->run_argcnt = MAX_RUNARGS;
  2720.     iv->run_args[0] = startname;
  2721.     for(i = 1; i < iv->run_argcnt; ++i)
  2722.     {
  2723.         iv->run_args[i] = argv[i+1];
  2724.     }
  2725. }
  2726. static void
  2727. Usage()
  2728. {
  2729. puts(
  2730. "Usage: bterp [+Sd] file [args]...\n"
  2731. "   +S name == start execution at function `name'\n"
  2732. "   +d      == print debug stmts\n"
  2733. "   Default execution starts at function `file'\n"
  2734. );
  2735. }
  2736. #if USING_FRAMEWORK
  2737. int
  2738. PROG (int argc, char **argv)
  2739. #else
  2740. int
  2741. main(int argc, char **argv)
  2742. #endif
  2743. {
  2744. int i, j;
  2745. char *startname;
  2746. long *argptr;
  2747. long es_beg, fs_size;
  2748. int *pes, ret;
  2749. Piv iv;
  2750.  
  2751.     iv = tiv = calloc(1, sizeof(struct _iv));
  2752.     iv->piv = iv;
  2753.  
  2754.     startname = 0;
  2755.     for(i = 1; i < argc; ++i)
  2756.     {
  2757.     int trimsize = 1;
  2758.         if(argv[i][0] == '+')
  2759.         {
  2760.             for (j=1; argv[i][j]; j++)
  2761.             {
  2762.                 switch(argv[i][j])
  2763.                 {    
  2764.                     case    'd':
  2765.                         iv->debug = 1;
  2766.                         break;
  2767.                     case    'S':
  2768.                         if(argv[i][j+1]) {
  2769.                             startname = &argv[i][j+1];
  2770.                         }
  2771.                         else if(i < argc-1) {
  2772.                             startname = argv[i+1];
  2773.                             trimsize = 2;
  2774.                         } else {
  2775.                             printf("bterp: No starting fuction name\n");
  2776.                             Usage();
  2777.                             return 1;
  2778.                         }
  2779.                         goto trim;
  2780.                         break;
  2781.                 }
  2782.             }
  2783. trim:
  2784.             /* Trim switch */
  2785.             for(j = i; j < argc-trimsize; ++j)
  2786.                 argv[j] = argv[j+trimsize];
  2787.             argc -= trimsize;
  2788.             --i;    /* i will be bumped by for */
  2789.         }
  2790.     }
  2791.     if(argc > 1)
  2792.     {
  2793.     PSB sp;
  2794.         iv->filename = propernameof(argv[1]);
  2795.         if(oxlink_load_object(iv->filename))        /* try library list */
  2796.         {
  2797.             oxlink_demand_noload();
  2798.             if(oxlink_load_file(iv->filename))        /* try search path */
  2799.             {
  2800.                 printf("bterp: file `%s' err:%s\n", iv->filename, oxlink_errstr());
  2801.                 exit(1);
  2802.             }
  2803.             oxlink_demand_load();
  2804.         }
  2805.         iv->entry = oxlink_get_entry_struct(iv->filename);
  2806.         iv->text_base = iv->entry->text_start_address;
  2807.         iv->dd = iv->entry->data_start_address;
  2808.  
  2809.         setup_run_args(iv, argc, argv, startname);
  2810.         if(!(iv->funcptr = oxlink_find_func("main")))
  2811.         {
  2812.           if(!(iv->funcptr = oxlink_find_func(iv->run_args[0])))
  2813.           {
  2814.             printf("bterp: function `%s' not found in file\n", iv->run_args[0]);
  2815.             oxlink_unload_file(iv->filename, 0);
  2816.             free(iv->filename);
  2817.             free(iv->run_args[0]);
  2818.             free(iv);
  2819.             return 1;
  2820.           }
  2821.         }
  2822.         iv->ft = *((Pft*)(&iv->funcptr[4]));
  2823.         iv->funcaddr = iv->ft->funcaddr;
  2824.         iv->stksiz = iv->ft->stksiz<<2;
  2825.         iv->argsiz = iv->ft->argsiz<<2;
  2826.         iv->maxes = iv->ft->maxes;
  2827.  
  2828.         es_beg = iv->stksiz+iv->argsiz;
  2829.         fs_size = es_beg + ((iv->maxes+6)*SZ);
  2830.         iv->base_stack = calloc(1, fs_size + sizeof(SB));
  2831.         iv->e_stack = iv->base_stack + sizeof(SB) + es_beg;
  2832.  
  2833.         /* Fill in _stakblk */
  2834.         sp = (PSB)iv->base_stack;
  2835.         sp->first_loc = iv->funcaddr;
  2836.         sp->last_loc = iv->dd - iv->text_base;
  2837.         sp->stksize = fs_size + sizeof(SB);
  2838.  
  2839.         /* Fill in the arguments */
  2840.         argptr = (long*)(iv->base_stack + iv->stksiz + sizeof(SB));
  2841.         if(iv->argsiz >= 4)
  2842.             argptr[0] = iv->run_argcnt;
  2843.         if(iv->argsiz >= 8)
  2844.             argptr[1] = (long)iv->run_args;
  2845.  
  2846.         if((pes = (void*)setjmp(iv->jb)))
  2847.             goto done;
  2848.  
  2849.         /* Call the starting function */
  2850.         pes = bterp_eval(iv, iv->funcaddr, iv->base_stack, iv->e_stack,
  2851.                 iv->base_stack + (fs_size+sizeof(SB)));
  2852. done:
  2853.         ret = *pes;
  2854.         prune_structs(iv);
  2855.         oxlink_unload_file(iv->filename, 0);
  2856.         free(iv->filename);
  2857.         free(iv->run_args[0]);
  2858.         free(iv->base_stack);
  2859.         if(iv->swtable)
  2860.         {
  2861.         void *p = iv->chunklist;
  2862.             free(iv->swtable);
  2863.             while(p)
  2864.             {
  2865.             void *q = p;
  2866.                 p = *((void**)p);
  2867.                 free(q);
  2868.             }
  2869.         }
  2870.         free(iv);
  2871.         return ret;
  2872.     }
  2873.     else
  2874.     {
  2875.         Usage();
  2876.         return 1;
  2877.     }
  2878. }
  2879. #if 0 /* used for testing */
  2880. int bterpcallback(int (*pfunc)())
  2881. {
  2882.     return pfunc();
  2883. }
  2884. #endif
  2885.