/* code.h */ /* * Opcode is one byte */ /* Stack opcodes */ #define OP_NOP 0 /* Do nothing */ #define OP_PUSH 1 /* Push immediate */ #define OP_PUSHSTR 2 /* Push immediate string */ #define OP_POP 3 /* sp += n */ #define OP_ALLOC 4 /* sp -= n */ #define OP_LOAD 5 /* push(*(sp+n)) */ #define OP_STORE 6 /* *(sp+n) = pop() ; use sp after pop */ /* Branch opcodes are odd if link, even otherwise */ #define OP_B 8 /* relative branch */ #define OP_BL 9 #define OP_BI 10 /* indirect branch */ #define OP_BIL 11 #define OP_BZ 12 /* pop and relative branch if zero */ #define OP_BZL 13 #define OP_BNZ 14 /* pop and relative branch if not zero */ #define OP_BNZL 15 #define OP_RET 16 /* pop and branch to return address */ /* Calls */ #define OP_CALLNUM 17 /* call numbered function */ #define OP_CALLSTR 18 /* call string function */ /* Arithmetic */ #define OP_ADD 19 #define OP_SUB 20 #define OP_MUL 21 #define OP_DIV 22 #define OP_EQ 23 #define OP_NE 24 #define OP_LT 25 #define OP_GT 26 #define OP_LE 27 #define OP_GE 28 #define FLOP_ADD 29 #define FLOP_SUB 30 #define FLOP_MUL 31 #define FLOP_DIV 32 #define FLOP_EQ 33 #define FLOP_NE 34 #define FLOP_LT 35 #define FLOP_GT 36 #define FLOP_LE 37 #define FLOP_GE 38 char *instr_names[] = { "NOP", "PUSH", "PUSHSTR", "POP", "ALLOC", "LOAD", "STORE", "ERR", "B", "BL", "BI", "BIL", "BZ", "BZL", "BNZ", "BNZL", "RET", "CALLNUM", "CALLSTR", "ADD", "SUB", "MUL", "DIV", "EQ", "NE", "LT", "GT", "LE", "GE", "FLADD", "FLSUB", "FLMUL", "FLDIV", "FLEQ", "FLNE", "FLLT", "FLGT", "FLLE", "FLGE", }; #define NINSTR (sizeof(instr_names)/sizeof(char *)) #define INSTR_NAME(x) (instr_names[x]) /* * For opcodes which take an operand, the byte count is stored * in the top 2 bits */ #define BYTECOUNT(x) ((((x) >> 6) & 3) + 1) #define SET_BYTECOUNT(x) (((x)-1)<<6) #define OPCODE_MASK(x) ((x) & 0x3f) /* * For OP_PUSHSTR and OP_CALLSTR, the byte count is the number of bytes * which follow the opcode to describe the length of the string. In * most cases, the string will be <256 bytes long, so the byte count will * be 1. */ /* Internal functions */ #define INTFN_NOP 0 #define INTFN_GLOBAL_STORE 1 #define INTFN_GLOBAL_LOAD 2 #define INTFN_GLOBAL_ARRAY_STORE 3 #define INTFN_GLOBAL_ARRAY_LOAD 4 /* * This is important because sizeof(stkentry) must be the same both * in the compiler and the vm, in order to get string handling right. */ typedef int stkentry; /* * Structure of the file header: * * 2 "LC" (magic) * 2 00:01 (version) * 4 ptr (pointer to function table) * 4 abiversion1 * 4 abiversion2 * 4 abiversion3 * 4 abiversion4 * 4 abiversion5 * * ptr-28 code * * 1 or more of: * 4 length of block, or 0 to terminate * 4 type of block (0 for function) * 4 pointer to function (offset within file) * 4 number of arguments (unused for now) * n NULL-terminated function name. * - align to 4-byte boundary * */ #define MAGIC1 'L' #define MAGIC2 'C' #define VERSION1 0 #define VERSION2 1