From 61097cfe732b4c3d877bc771a38d02c53ddcf130 Mon Sep 17 00:00:00 2001 From: Nunuhara Cabbage Date: Thu, 9 Jan 2020 19:10:06 -0800 Subject: [PATCH] aindump: option to check xsystem4 compatibility Add -A,--audit option to check an ain file's compatibility with xsystem4. Currently only checks for unimplemented instructions and syscalls. --- include/system4/instructions.h | 11 +- src/aindump/aindump.c | 40 ++- src/aindump/dasm.c | 4 +- src/instructions.c | 596 +++++++++++++++++---------------- 4 files changed, 363 insertions(+), 288 deletions(-) diff --git a/include/system4/instructions.h b/include/system4/instructions.h index c7075ce..75e1263 100644 --- a/include/system4/instructions.h +++ b/include/system4/instructions.h @@ -19,6 +19,7 @@ #ifndef SYSTEM4_INSTRUCTIONS_H #define SYSTEM4_INSTRUCTIONS_H +#include #include #include "system4.h" @@ -48,10 +49,17 @@ enum syscall_code { SYS_SLEEP = 0x15, SYS_GROUP_SAVE = 0x18, SYS_GROUP_LOAD = 0x19, + SYS_COPY_SAVE_FILE = 0x1C, NR_SYSCALLS }; -const char * const syscalls[NR_SYSCALLS]; +struct syscall { + const enum syscall_code code; + const char * const name; + const bool implemented; +}; + +const struct syscall syscalls[NR_SYSCALLS]; enum opcode { @@ -339,6 +347,7 @@ struct instruction { const char * const name; // assembler name const int nr_args; // number of arguments (???: always 1 or 0?) const int ip_inc; // amount to increment instruction pointer after instruction + const bool implemented; // implemented in xsystem4 const int args[INSTRUCTION_MAX_ARGS]; // argument data types }; diff --git a/src/aindump/aindump.c b/src/aindump/aindump.c index 891e16d..a50f513 100644 --- a/src/aindump/aindump.c +++ b/src/aindump/aindump.c @@ -44,6 +44,7 @@ static void usage(void) puts(" --function-types Dump function type section"); puts(" --global-group-names Dump global group names section"); puts(" -e, --enums Dump enums section"); + puts(" -A, --audit Audit AIN file for xsystem4 compatibility"); //puts(" -j, --json Dump to JSON format"); // TODO } @@ -212,6 +213,36 @@ static void ain_dump_enums(FILE *f, struct ain *ain) } } +static void ain_audit(FILE *f, struct ain *ain) +{ + for (size_t addr = 0; addr < ain->code_size;) { + uint16_t opcode = LittleEndian_getW(ain->code, addr); + const struct instruction *instr = &instructions[opcode]; + if (opcode >= NR_OPCODES) { + ERROR("0x%08lx: Invalid/unknown opcode: %x", opcode); + } + if (!instr->implemented) { + fprintf(f, "0x%08lx: %s (unimplemented instruction)\n", addr, instr->name); + } + if (opcode == CALLSYS) { + uint32_t syscode = LittleEndian_getDW(ain->code, addr + 2); + if (syscode >= NR_SYSCALLS) { + ERROR("0x%08lx: CALLSYS system.(0x%x)\n", addr, syscode); + } + const char * const name = syscalls[syscode].name; + if (!name) { + fprintf(f, "0x%08lx: CALLSYS system.(0x%x)\n", addr, syscode); + } else if (!syscalls[syscode].implemented) { + fprintf(f, "0x%08lx: CALLSYS %s (unimplemented system call)\n", addr, name); + } + + } + // TODO: audit library calls + addr += instruction_width(opcode); + } + fflush(f); +} + int main(int argc, char *argv[]) { bool dump_version = false; @@ -226,6 +257,7 @@ int main(int argc, char *argv[]) bool dump_functypes = false; bool dump_global_group_names = false; bool dump_enums = false; + bool audit = false; char *output_file = NULL; FILE *output = stdout; int err = AIN_SUCCESS; @@ -246,12 +278,13 @@ int main(int argc, char *argv[]) { "function-types", no_argument, 0, 't' }, { "global-group-names", no_argument, 0, 'r' }, { "enums", no_argument, 0, 'e' }, + { "audit", no_argument, 0, 'A' }, { "output", required_argument, 0, 'o' }, }; int option_index = 0; int c; - c = getopt_long(argc, argv, "hVcfgSmlsFeo:", long_options, &option_index); + c = getopt_long(argc, argv, "hVcfgSmlsFeAo:", long_options, &option_index); if (c == -1) break; @@ -295,6 +328,9 @@ int main(int argc, char *argv[]) case 'e': dump_enums = true; break; + case 'A': + audit = true; + break; case 'o': output_file = xstrdup(optarg); break; @@ -347,6 +383,8 @@ int main(int argc, char *argv[]) ain_dump_enums(output, ain); if (dump_code) disassemble_ain(ain, output); + if (audit) + ain_audit(output, ain); ain_free(ain); } diff --git a/src/aindump/dasm.c b/src/aindump/dasm.c index f09e8a9..4ca5e36 100644 --- a/src/aindump/dasm.c +++ b/src/aindump/dasm.c @@ -187,9 +187,9 @@ static void print_argument(struct dasm_state *dasm, int32_t arg, enum instructio print_sjis(dasm, ain->structures[arg].name); break; case T_SYSCALL: - if (arg < 0 || arg >= NR_SYSCALLS || !syscalls[arg]) + if (arg < 0 || arg >= NR_SYSCALLS || !syscalls[arg].name) DASM_ERROR(dasm, "Invalid/unknown syscall number: %d", arg); - fprintf(dasm->out, "%s", syscalls[arg]); + fprintf(dasm->out, "%s", syscalls[arg].name); break; case T_HLL: if (arg < 0 || arg >= ain->nr_libraries) diff --git a/src/instructions.c b/src/instructions.c index 9037f1b..fed71fd 100644 --- a/src/instructions.c +++ b/src/instructions.c @@ -21,30 +21,45 @@ #include "system4.h" #include "system4/instructions.h" -const char * const syscalls[NR_SYSCALLS] = { - [SYS_EXIT] = "system.Exit", - [SYS_GLOBAL_SAVE] = "system.GlobalSave", - [SYS_GLOBAL_LOAD] = "system.GlobalLoad", - [SYS_LOCK_PEEK] = "system.LockPeek", - [SYS_UNLOCK_PEEK] = "system.UnlockPeek", - [SYS_RESET] = "system.Reset", - [SYS_OUTPUT] = "system.Output", - [SYS_MSGBOX] = "system.MsgBox", - [SYS_RESUME_SAVE] = "system.ResumeSave", - [SYS_RESUME_LOAD] = "system.ResumeLoad", - [SYS_EXISTS_FILE] = "system.ExistsFile", - [SYS_OPEN_WEB] = "system.OpenWeb", - [SYS_GET_SAVE_FOLDER_NAME] = "system.GetSaveFolderName", - [SYS_GET_TIME] = "system.GetTime", - [SYS_ERROR] = "system.Error", - [SYS_EXISTS_SAVE_FILE] = "system.ExistsSaveFile", - [SYS_IS_DEBUG_MODE] = "system.IsDebugMode", - [SYS_MSGBOX_OK_CANCEL] = "system.MsgBoxOkCancel", - [SYS_GET_FUNC_STACK_NAME] = "system.GetFuncStackName", - [SYS_PEEK] = "system.Peek", - [SYS_SLEEP] = "system.Sleep", - [SYS_GROUP_SAVE] = "system.GroupSave", - [SYS_GROUP_LOAD] = "system.GroupLoad" +#define SYS(syscode, sysname) \ + [syscode] = { \ + .code = syscode, \ + .name = "system." #sysname , \ + .implemented = true \ + } + +#define TODO(syscode, sysname) \ + [syscode] = { \ + .code = syscode, \ + .name = "system." #sysname , \ + .implemented = false \ + } + +const struct syscall syscalls[NR_SYSCALLS] = { + SYS ( SYS_EXIT, Exit ), + SYS ( SYS_GLOBAL_SAVE, GlobalSave ), + SYS ( SYS_GLOBAL_LOAD, GlobalLoad ), + SYS ( SYS_LOCK_PEEK, LockPeek ), + SYS ( SYS_UNLOCK_PEEK, UnlockPeek ), + TODO ( SYS_RESET, Reset ), + SYS ( SYS_OUTPUT, Output ), + SYS ( SYS_MSGBOX, MsgBox ), + SYS ( SYS_RESUME_SAVE, ResumeSave ), + SYS ( SYS_RESUME_LOAD, ResumeLoad ), + SYS ( SYS_EXISTS_FILE, ExistsFile ), + TODO ( SYS_OPEN_WEB, OpenWeb ), + SYS ( SYS_GET_SAVE_FOLDER_NAME, GetSaveFolderName ), + SYS ( SYS_GET_TIME, GetTime ), + SYS ( SYS_ERROR, Error ), + SYS ( SYS_EXISTS_SAVE_FILE, ExistsSaveFile ), + SYS ( SYS_IS_DEBUG_MODE, IsDebugMode ), + TODO ( SYS_MSGBOX_OK_CANCEL, MsgBoxOkCancel ), + SYS ( SYS_GET_FUNC_STACK_NAME, GetFuncStackName ), + SYS ( SYS_PEEK, Peek ), + SYS ( SYS_SLEEP, Sleep ), + SYS ( SYS_GROUP_SAVE, GroupSave ), + SYS ( SYS_GROUP_LOAD, GroupLoad ), + TODO ( SYS_COPY_SAVE_FILE, CopySaveFile ), }; // JMP = instruction that modifies the instruction pointer @@ -55,6 +70,7 @@ const char * const syscalls[NR_SYSCALLS] = { .name = #code , \ .nr_args = nargs, \ .ip_inc = 2 + nargs * 4, \ + .implemented = true, \ .args = { __VA_ARGS__ } \ } #define JMP(code, nargs, ...) \ @@ -63,271 +79,283 @@ const char * const syscalls[NR_SYSCALLS] = { .name = #code , \ .nr_args = nargs, \ .ip_inc = 0, \ + .implemented = true, \ + .args = { __VA_ARGS__ } \ + } + +#undef TODO +#define TODO(code, nargs, ...) \ + [code] = { \ + .opcode = code, \ + .name = #code, \ + .nr_args = nargs, \ + .ip_inc = 2 + nargs * 4, \ + .implemented = false, \ .args = { __VA_ARGS__ } \ } const struct instruction instructions[NR_OPCODES] = { - OP(PUSH, 1, T_INT), - OP(POP, 0), - OP(REF, 0), - OP(REFREF, 0), - OP(PUSHGLOBALPAGE, 0), - OP(PUSHLOCALPAGE, 0), - OP(INV, 0), - OP(NOT, 0), - OP(COMPL, 0), - OP(ADD, 0), - OP(SUB, 0), - OP(MUL, 0), - OP(DIV, 0), - OP(MOD, 0), - OP(AND, 0), - OP(OR, 0), - OP(XOR, 0), - OP(LSHIFT, 0), - OP(RSHIFT, 0), - OP(LT, 0), - OP(GT, 0), - OP(LTE, 0), - OP(GTE, 0), - OP(NOTE, 0), - OP(EQUALE, 0), - OP(ASSIGN, 0), - OP(PLUSA, 0), - OP(MINUSA, 0), - OP(MULA, 0), - OP(DIVA, 0), - OP(MODA, 0), - OP(ANDA, 0), - OP(ORA, 0), - OP(XORA, 0), +// TYPE OPCODE NR_ARGS, ARG_TYPES... + OP ( PUSH, 1, T_INT ), + OP ( POP, 0 ), + OP ( REF, 0 ), + OP ( REFREF, 0 ), + OP ( PUSHGLOBALPAGE, 0 ), + OP ( PUSHLOCALPAGE, 0 ), + OP ( INV, 0 ), + OP ( NOT, 0 ), + OP ( COMPL, 0 ), + OP ( ADD, 0 ), + OP ( SUB, 0 ), + OP ( MUL, 0 ), + OP ( DIV, 0 ), + OP ( MOD, 0 ), + OP ( AND, 0 ), + OP ( OR, 0 ), + OP ( XOR, 0 ), + OP ( LSHIFT, 0 ), + OP ( RSHIFT, 0 ), + OP ( LT, 0 ), + OP ( GT, 0 ), + OP ( LTE, 0 ), + OP ( GTE, 0 ), + OP ( NOTE, 0 ), + OP ( EQUALE, 0 ), + OP ( ASSIGN, 0 ), + OP ( PLUSA, 0 ), + OP ( MINUSA, 0 ), + OP ( MULA, 0 ), + OP ( DIVA, 0 ), + OP ( MODA, 0 ), + OP ( ANDA, 0 ), + OP ( ORA, 0 ), + OP ( XORA, 0 ), + OP ( LSHIFTA, 0 ), + OP ( RSHIFTA, 0 ), + OP ( F_ASSIGN, 0 ), + OP ( F_PLUSA, 0 ), + OP ( F_MINUSA, 0 ), + OP ( F_MULA, 0 ), + OP ( F_DIVA, 0 ), + OP ( DUP2, 0 ), + OP ( DUP_X2, 0 ), + TODO ( CMP, 0 ), + JMP ( JUMP, 1, T_ADDR ), + JMP ( IFZ, 1, T_ADDR ), + JMP ( IFNZ, 1, T_ADDR ), + JMP ( RETURN, 0 ), + JMP ( CALLFUNC, 1, T_FUNC ), + OP ( INC, 0 ), + OP ( DEC, 0 ), + OP ( FTOI, 0 ), + OP ( ITOF, 0 ), + OP ( F_INV, 0 ), + OP ( F_ADD, 0 ), + OP ( F_SUB, 0 ), + OP ( F_MUL, 0 ), + OP ( F_DIV, 0 ), + OP ( F_LT, 0 ), + OP ( F_GT, 0 ), + OP ( F_LTE, 0 ), + OP ( F_GTE, 0 ), + OP ( F_NOTE, 0 ), + OP ( F_EQUALE, 0 ), + OP ( F_PUSH, 1, T_FLOAT ), + OP ( S_PUSH, 1, T_STRING ), + OP ( S_POP, 0 ), + OP ( S_ADD, 0 ), + OP ( S_ASSIGN, 0 ), + TODO ( S_PLUSA, 0 ), + OP ( S_REF, 0 ), + TODO ( S_REFREF, 0 ), + OP ( S_NOTE, 0 ), + OP ( S_EQUALE, 0 ), + TODO ( SF_CREATE, 0 ), + TODO ( SF_CREATEPIXEL, 0 ), + TODO ( SF_CREATEALPHA, 0 ), - OP(LSHIFTA, 0), - OP(RSHIFTA, 0), + OP ( SR_POP, 0 ), + OP ( SR_ASSIGN, 0 ), + OP ( SR_REF, 1, T_STRUCT ), + TODO ( SR_REFREF, 0 ), + OP ( A_ALLOC, 0 ), + OP ( A_REALLOC, 0 ), + OP ( A_FREE, 0 ), + OP ( A_NUMOF, 0 ), + OP ( A_COPY, 0 ), + OP ( A_FILL, 0 ), + OP ( C_REF, 0 ), + OP ( C_ASSIGN, 0 ), + JMP ( MSG, 1, T_MSG ), + OP ( CALLHLL, 2, T_HLL, T_HLLFUNC ), + OP ( PUSHSTRUCTPAGE, 0 ), + JMP ( CALLMETHOD, 1, T_FUNC ), + OP ( SH_GLOBALREF, 1, T_GLOBAL ), + OP ( SH_LOCALREF, 1, T_LOCAL ), + JMP ( SWITCH, 1, T_INT ), + JMP ( STRSWITCH, 1, T_INT ), + OP ( FUNC, 1, T_FUNC ), + OP ( _EOF, 1, T_FILE ), + OP ( CALLSYS, 1, T_SYSCALL ), + JMP ( SJUMP, 0 ), + OP ( CALLONJUMP, 0 ), + OP ( SWAP, 0 ), + OP ( SH_STRUCTREF, 1, T_INT ), + OP ( S_LENGTH, 0 ), + OP ( S_LENGTHBYTE, 0 ), + OP ( I_STRING, 0 ), + JMP ( CALLFUNC2, 0 ), + OP ( DUP2_X1, 0 ), + OP ( R_ASSIGN, 0 ), + OP ( FT_ASSIGNS, 0 ), + OP ( ASSERT, 0 ), + OP ( S_LT, 0 ), + OP ( S_GT, 0 ), + OP ( S_LTE, 0 ), + OP ( S_GTE, 0 ), + OP ( S_LENGTH2, 0 ), + TODO ( S_LENGTHBYTE2, 0 ), + TODO ( NEW, 0 ), + OP ( DELETE, 0 ), + TODO ( CHECKUDO, 0 ), + OP ( A_REF, 0 ), + OP ( DUP, 0 ), + OP ( DUP_U2, 0 ), + OP ( SP_INC, 0 ), + TODO ( SP_DEC, 0 ), + OP ( ENDFUNC, 1, T_FUNC ), + TODO ( R_EQUALE, 0 ), + TODO ( R_NOTE, 0 ), + OP ( SH_LOCALCREATE, 2, T_LOCAL, T_STRUCT ), + OP ( SH_LOCALDELETE, 1, T_LOCAL ), + TODO ( STOI, 0 ), + OP ( A_PUSHBACK, 0 ), + OP ( A_POPBACK, 0 ), + OP ( S_EMPTY, 0 ), + OP ( A_EMPTY, 0 ), + OP ( A_ERASE, 0 ), + OP ( A_INSERT, 0 ), + OP ( SH_LOCALINC, 1, T_LOCAL ), + OP ( SH_LOCALDEC, 1, T_LOCAL ), + OP ( SH_LOCALASSIGN, 2, T_LOCAL, T_INT ), + OP ( ITOB, 0 ), + OP ( S_FIND, 0 ), + OP ( S_GETPART, 0 ), + OP ( A_SORT, 0 ), + TODO ( S_PUSHBACK, 0 ), + TODO ( S_POPBACK, 0 ), + OP ( FTOS, 0 ), + OP ( S_MOD, 0 ), + OP ( S_PLUSA2, 0 ), + OP ( OBJSWAP, 0 ), + TODO ( S_ERASE, 0 ), + TODO ( SR_REF2, 0 ), + OP ( S_ERASE2, 0 ), + OP ( S_PUSHBACK2, 0 ), + OP ( S_POPBACK2, 0 ), + OP ( ITOLI, 0 ), + OP ( LI_ADD, 0 ), + OP ( LI_SUB, 0 ), + OP ( LI_MUL, 0 ), + OP ( LI_DIV, 0 ), + OP ( LI_MOD, 0 ), + OP ( LI_ASSIGN, 0 ), + OP ( LI_PLUSA, 0 ), + OP ( LI_MINUSA, 0 ), + OP ( LI_MULA, 0 ), + OP ( LI_DIVA, 0 ), + OP ( LI_MODA, 0 ), + OP ( LI_ANDA, 0 ), + OP ( LI_ORA, 0 ), + OP ( LI_XORA, 0 ), + OP ( LI_LSHIFTA, 0 ), + OP ( LI_RSHIFTA, 0 ), + OP ( LI_INC, 0 ), + OP ( LI_DEC, 0 ), + OP ( A_FIND, 0 ), + OP ( A_REVERSE, 0 ), - OP(F_ASSIGN, 0), - OP(F_PLUSA, 0), - OP(F_MINUSA, 0), - OP(F_MULA, 0), - OP(F_DIVA, 0), - OP(DUP2, 0), - OP(DUP_X2, 0), + // FIXME: all types are guesses + TODO ( SH_SR_ASSIGN, 0 ), + TODO ( SH_MEM_ASSIGN_LOCAL, 2, T_INT, T_LOCAL ), + TODO ( A_NUMOF_GLOB_1, 1, T_GLOBAL ), + TODO ( A_NUMOF_STRUCT_1, 1, T_INT ), + TODO ( SH_MEM_ASSIGN_IMM, 2, T_INT, T_INT ), + TODO ( SH_LOCALREFREF, 1, T_LOCAL ), + TODO ( SH_LOCALASSIGN_SUB_IMM, 2, T_INT, T_INT ), + TODO ( SH_IF_LOC_LT_IMM, 3, T_LOCAL, T_INT, T_ADDR ), + TODO ( SH_IF_LOC_GE_IMM, 3, T_LOCAL, T_INT, T_ADDR ), + TODO ( SH_LOCREF_ASSIGN_MEM, 2, T_INT, T_INT ), + TODO ( PAGE_REF, 0 ), // TODO: args? + TODO ( SH_GLOBAL_ASSIGN_LOCAL, 2, T_GLOBAL, T_LOCAL ), + TODO ( SH_STRUCTREF_GT_IMM, 2, T_INT, T_INT ), + TODO ( SH_STRUCT_ASSIGN_LOCALREF_ITOB, 2, T_INT, T_INT ), + TODO ( SH_LOCAL_ASSIGN_STRUCTREF, 2, T_INT, T_INT ), + TODO ( SH_IF_STRUCTREF_NE_LOCALREF, 3, T_STRUCT, T_LOCAL, T_ADDR ), + TODO ( SH_IF_STRUCTREF_GT_IMM, 3, T_INT, T_INT, T_ADDR ), + TODO ( SH_STRUCTREF_CALLMETHOD_NO_PARAM, 0 ), // TODO: args? + TODO ( SH_STRUCTREF2, 0 ), // TODO: args? + TODO ( SH_REF_STRUCTREF2, 0 ), // TODO: args? + TODO ( SH_STRUCTREF3, 0 ), // TODO: args? + TODO ( SH_STRUCTREF2_CALLMETHOD_NO_PARAM, 0 ), // TODO: args? + TODO ( SH_IF_STRUCTREF_Z, 2, T_INT, T_ADDR ), + TODO ( SH_IF_STRUCT_A_NOT_EMPTY, 2, T_INT, T_ADDR ), + TODO ( SH_IF_LOC_GT_IMM, 3, T_INT, T_INT, T_ADDR ), + TODO ( SH_IF_STRUCTREF_NE_IMM, 3, T_INT, T_INT, T_ADDR ), + TODO ( THISCALLMETHOD_NOPARAM, 0 ), // TODO: args? + TODO ( SH_IF_LOC_NE_IMM, 3, T_LOCAL, T_INT, T_ADDR ), + TODO ( SH_IF_STRUCTREF_EQ_IMM, 3, T_INT, T_INT, T_ADDR ), + TODO ( SH_GLOBAL_ASSIGN_IMM, 2, T_GLOBAL, T_INT ), + TODO ( SH_LOCALSTRUCT_ASSIGN_IMM, 0 ), // TODO: args? + TODO ( SH_STRUCT_A_PUSHBACK_LOCAL_STRUCT, 2, T_INT, T_INT ), + TODO ( SH_GLOBAL_A_PUSHBACK_LOCAL_STRUCT, 2, T_INT, T_INT ), + TODO ( SH_LOCAL_A_PUSHBACK_LOCAL_STRUCT, 2, T_INT, T_INT ), + TODO ( SH_IF_SREF_NE_STR0, 2, T_INT, T_ADDR ), + TODO ( SH_S_ASSIGN_REF, 0 ), + TODO ( SH_A_FIND_SREF, 0 ), // TODO: args? + TODO ( SH_SREF_EMPTY, 0 ), + TODO ( SH_STRUCTSREF_EQ_LOCALSREF, 2 , T_STRUCT, T_LOCAL ), + TODO ( SH_LOCALSREF_EQ_STR0, 2, T_INT, T_INT ), + TODO ( SH_STRUCTSREF_NE_LOCALSREF, 2, T_INT, T_INT ), + TODO ( SH_LOCALSREF_NE_STR0, 2, T_INT, T_INT ), + TODO ( SH_STRUCT_SR_REF, 2, T_INT, T_INT ), + TODO ( SH_STRUCT_S_REF, 1, T_INT ), + TODO ( S_REF2, 0 ), // TODO: args? + TODO ( SH_REF_LOCAL_ASSIGN_STRUCTREF2, 0 ), + TODO ( SH_GLOBAL_S_REF, 1, T_GLOBAL ), + TODO ( SH_LOCAL_S_REF, 1, T_INT ), + TODO ( SH_LOCALREF_SASSIGN_LOCALSREF, 2, T_INT, T_INT ), + TODO ( SH_LOCAL_APUSHBACK_LOCALSREF, 2, T_INT, T_INT ), + TODO ( SH_S_ASSIGN_CALLSYS19, 0 ), + TODO ( SH_S_ASSIGN_STR0, 1, T_INT ), + TODO ( SH_SASSIGN_LOCALSREF, 1, T_INT ), + TODO ( SH_STRUCTREF_SASSIGN_LOCALSREF, 2, T_INT, T_INT ), + TODO ( SH_LOCALSREF_EMPTY, 1, T_INT ), + TODO ( SH_GLOBAL_APUSHBACK_LOCALSREF, 2, T_INT, T_INT ), + TODO ( SH_STRUCT_APUSHBACK_LOCALSREF, 2, T_INT, T_INT ), + TODO ( SH_STRUCTSREF_EMPTY, 1, T_INT ), + TODO ( SH_GLOBALSREF_EMPTY, 1, T_GLOBAL ), + TODO ( SH_SASSIGN_STRUCTSREF, 1, T_INT ), + TODO ( SH_SASSIGN_GLOBALSREF, 1, T_INT ), + TODO ( SH_STRUCTSREF_NE_STR0, 2, T_INT, T_INT ), + TODO ( SH_GLOBALSREF_NE_STR0, 2, T_INT, T_INT ), + TODO ( SH_LOC_LT_IMM_OR_LOC_GE_IMM, 3, T_INT, T_ADDR, T_ADDR ), - OP(CMP, 0), // TODO - - JMP(JUMP, 1, T_ADDR), - JMP(IFZ, 1, T_ADDR), - JMP(IFNZ, 1, T_ADDR), - JMP(RETURN, 0), - JMP(CALLFUNC, 1, T_FUNC), - OP(INC, 0), - OP(DEC, 0), - OP(FTOI, 0), - OP(ITOF, 0), - OP(F_INV, 0), - OP(F_ADD, 0), - OP(F_SUB, 0), - OP(F_MUL, 0), - OP(F_DIV, 0), - OP(F_LT, 0), - OP(F_GT, 0), - OP(F_LTE, 0), - OP(F_GTE, 0), - OP(F_NOTE, 0), - OP(F_EQUALE, 0), - OP(F_PUSH, 1, T_FLOAT), - OP(S_PUSH, 1, T_STRING), - OP(S_POP, 0), - OP(S_ADD, 0), - OP(S_ASSIGN, 0), - OP(S_PLUSA, 0), // TODO - OP(S_REF, 0), - OP(S_REFREF, 0), // TODO - OP(S_NOTE, 0), - OP(S_EQUALE, 0), - OP(SF_CREATE, 0), // TODO - OP(SF_CREATEPIXEL, 0), // TODO - OP(SF_CREATEALPHA, 0), // TODO - - OP(SR_POP, 0), - OP(SR_ASSIGN, 0), - OP(SR_REF, 1, T_STRUCT), - OP(SR_REFREF, 0), // TODO - OP(A_ALLOC, 0), - OP(A_REALLOC, 0), - OP(A_FREE, 0), - OP(A_NUMOF, 0), - OP(A_COPY, 0), - OP(A_FILL, 0), - OP(C_REF, 0), - OP(C_ASSIGN, 0), - JMP(MSG, 1, T_MSG), - OP(CALLHLL, 2, T_HLL, T_HLLFUNC), - OP(PUSHSTRUCTPAGE, 0), - JMP(CALLMETHOD, 1, T_FUNC), - OP(SH_GLOBALREF, 1, T_GLOBAL), - OP(SH_LOCALREF, 1, T_LOCAL), - JMP(SWITCH, 1, T_INT), - JMP(STRSWITCH, 1, T_INT), - OP(FUNC, 1, T_FUNC), - OP(_EOF, 1, T_FILE), - OP(CALLSYS, 1, T_SYSCALL), - JMP(SJUMP, 0), - OP(CALLONJUMP, 0), - OP(SWAP, 0), - OP(SH_STRUCTREF, 1, T_INT), - OP(S_LENGTH, 0), - OP(S_LENGTHBYTE, 0), - OP(I_STRING, 0), - JMP(CALLFUNC2, 0), - OP(DUP2_X1, 0), - OP(R_ASSIGN, 0), - OP(FT_ASSIGNS, 0), // TODO - OP(ASSERT, 0), - OP(S_LT, 0), - OP(S_GT, 0), - OP(S_LTE, 0), - OP(S_GTE, 0), - OP(S_LENGTH2, 0), - OP(S_LENGTHBYTE2, 0), // TODO - OP(NEW, 0), // TODO - OP(DELETE, 0), - OP(CHECKUDO, 0), // TODO - OP(A_REF, 0), - OP(DUP, 0), - OP(DUP_U2, 0), - OP(SP_INC, 0), - OP(SP_DEC, 0), // TODO - OP(ENDFUNC, 1, T_FUNC), - OP(R_EQUALE, 0), // TODO - OP(R_NOTE, 0), // TODO - OP(SH_LOCALCREATE, 2, T_LOCAL, T_STRUCT), - OP(SH_LOCALDELETE, 1, T_LOCAL), - OP(STOI, 0), // TODO - OP(A_PUSHBACK, 0), - OP(A_POPBACK, 0), - OP(S_EMPTY, 0), - OP(A_EMPTY, 0), - OP(A_ERASE, 0), - OP(A_INSERT, 0), - OP(SH_LOCALINC, 1, T_LOCAL), - OP(SH_LOCALDEC, 1, T_LOCAL), - OP(SH_LOCALASSIGN, 2, T_LOCAL, T_INT), - OP(ITOB, 0), - OP(S_FIND, 0), - OP(S_GETPART, 0), - OP(A_SORT, 0), - OP(S_PUSHBACK, 0), // TODO - OP(S_POPBACK, 0), // TODO - OP(FTOS, 0), - OP(S_MOD, 0), - OP(S_PLUSA2, 0), - OP(OBJSWAP, 0), - OP(S_ERASE, 0), // TODO - OP(SR_REF2, 0), // TODO - OP(S_ERASE2, 0), - OP(S_PUSHBACK2, 0), - OP(S_POPBACK2, 0), - OP(ITOLI, 0), - OP(LI_ADD, 0), - OP(LI_SUB, 0), - OP(LI_MUL, 0), - OP(LI_DIV, 0), - OP(LI_MOD, 0), - OP(LI_ASSIGN, 0), - OP(LI_PLUSA, 0), - OP(LI_MINUSA, 0), - OP(LI_MULA, 0), - OP(LI_DIVA, 0), - OP(LI_MODA, 0), - OP(LI_ANDA, 0), - OP(LI_ORA, 0), - OP(LI_XORA, 0), - OP(LI_LSHIFTA, 0), - OP(LI_RSHIFTA, 0), - OP(LI_INC, 0), - OP(LI_DEC, 0), - OP(A_FIND, 0), - OP(A_REVERSE, 0), - OP(SH_SR_ASSIGN, 0), // TODO - OP(SH_MEM_ASSIGN_LOCAL, 0), // TODO - OP(A_NUMOF_GLOB_1, 0), // TODO - OP(A_NUMOF_STRUCT_1, 0), // TODO - OP(SH_MEM_ASSIGN_IMM, 0), // TODO - OP(SH_LOCALREFREF, 0), // TODO - OP(SH_LOCALASSIGN_SUB_IMM, 0), // TODO - OP(SH_IF_LOC_LT_IMM, 0), // TODO - OP(SH_IF_LOC_GE_IMM, 0), // TODO - OP(SH_LOCREF_ASSIGN_MEM, 0), // TODO - OP(PAGE_REF, 0), // TODO - OP(SH_GLOBAL_ASSIGN_LOCAL, 0), // TODO - OP(SH_STRUCTREF_GT_IMM, 0), // TODO - OP(SH_STRUCT_ASSIGN_LOCALREF_ITOB, 0), // TODO - OP(SH_LOCAL_ASSIGN_STRUCTREF, 0), // TODO - OP(SH_IF_STRUCTREF_NE_LOCALREF, 0), // TODO - OP(SH_IF_STRUCTREF_GT_IMM, 0), // TODO - OP(SH_STRUCTREF_CALLMETHOD_NO_PARAM, 0), // TODO - OP(SH_STRUCTREF2, 0), // TODO - OP(SH_REF_STRUCTREF2, 0), // TODO - OP(SH_STRUCTREF3, 0), // TODO - OP(SH_STRUCTREF2_CALLMETHOD_NO_PARAM, 0), // TODO - OP(SH_IF_STRUCTREF_Z, 0), // TODO - OP(SH_IF_STRUCT_A_NOT_EMPTY, 0), // TODO - OP(SH_IF_LOC_GT_IMM, 0), // TODO - OP(SH_IF_STRUCTREF_NE_IMM, 0), // TODO - OP(THISCALLMETHOD_NOPARAM, 0), // TODO - OP(SH_IF_LOC_NE_IMM, 0), // TODO - OP(SH_IF_STRUCTREF_EQ_IMM, 0), // TODO - OP(SH_GLOBAL_ASSIGN_IMM, 0), // TODO - OP(SH_LOCALSTRUCT_ASSIGN_IMM, 0), // TODO - OP(SH_STRUCT_A_PUSHBACK_LOCAL_STRUCT, 0), // TODO - OP(SH_GLOBAL_A_PUSHBACK_LOCAL_STRUCT, 0), // TODO - OP(SH_LOCAL_A_PUSHBACK_LOCAL_STRUCT, 0), // TODO - OP(SH_IF_SREF_NE_STR0, 0), // TODO - OP(SH_S_ASSIGN_REF, 0), // TODO - OP(SH_A_FIND_SREF, 0), // TODO - OP(SH_SREF_EMPTY, 0), // TODO - OP(SH_STRUCTSREF_EQ_LOCALSREF, 0), // TODO - OP(SH_LOCALSREF_EQ_STR0, 0), // TODO - OP(SH_STRUCTSREF_NE_LOCALSREF, 0), // TODO - OP(SH_LOCALSREF_NE_STR0, 0), // TODO - OP(SH_STRUCT_SR_REF, 0), // TODO - OP(SH_STRUCT_S_REF, 0), // TODO - OP(S_REF2, 0), // TODO - OP(SH_REF_LOCAL_ASSIGN_STRUCTREF2, 0), // TODO - OP(SH_GLOBAL_S_REF, 0), // TODO - OP(SH_LOCAL_S_REF, 0), // TODO - OP(SH_LOCALREF_SASSIGN_LOCALSREF, 0), // TODO - OP(SH_LOCAL_APUSHBACK_LOCALSREF, 0), // TODO - OP(SH_S_ASSIGN_CALLSYS19, 0), // TODO - OP(SH_S_ASSIGN_STR0, 0), // TODO - OP(SH_SASSIGN_LOCALSREF, 0), // TODO - OP(SH_STRUCTREF_SASSIGN_LOCALSREF, 0), // TODO - OP(SH_LOCALSREF_EMPTY, 0), // TODO - OP(SH_GLOBAL_APUSHBACK_LOCALSREF, 0), // TODO - OP(SH_STRUCT_APUSHBACK_LOCALSREF, 0), // TODO - OP(SH_STRUCTSREF_EMPTY, 0), // TODO - OP(SH_GLOBALSREF_EMPTY, 0), // TODO - OP(SH_SASSIGN_STRUCTSREF, 0), // TODO - OP(SH_SASSIGN_GLOBALSREF, 0), // TODO - OP(SH_STRUCTSREF_NE_STR0, 0), // TODO - OP(SH_GLOBALSREF_NE_STR0, 0), // TODO - OP(SH_LOC_LT_IMM_OR_LOC_GE_IMM, 0), // TODO - OP(A_SORT_MEM, 0), // TODO - OP(DG_ADD, 0), // TODO - OP(DG_SET, 0), // TODO - OP(DG_CALL, 0), // TODO - OP(DG_NUMOF, 0), // TODO - OP(DG_EXIST, 0), // TODO - OP(DG_ERASE, 0), // TODO - OP(DG_CLEAR, 0), // TODO - OP(DG_COPY, 0), // TODO - OP(DG_ASSIGN, 0), // TODO - OP(DG_PLUSA, 0), // TODO - OP(DG_POP, 0), // TODO - OP(DG_NEW_FROM_METHOD, 0), // TODO - OP(DG_MINUSA, 0), // TODO - OP(DG_CALLBEGIN, 0), // TODO - OP(DG_NEW, 0), // TODO - OP(DG_STR_TO_METHOD, 0), // TODO + TODO ( A_SORT_MEM, 0 ), + TODO ( DG_ADD, 0 ), + TODO ( DG_SET, 0 ), + TODO ( DG_CALL, 0 ), + TODO ( DG_NUMOF, 0 ), + TODO ( DG_EXIST, 0 ), + TODO ( DG_ERASE, 0 ), + TODO ( DG_CLEAR, 0 ), + TODO ( DG_COPY, 0 ), + TODO ( DG_ASSIGN, 0 ), + TODO ( DG_PLUSA, 0 ), + TODO ( DG_POP, 0 ), + TODO ( DG_NEW_FROM_METHOD, 0 ), + TODO ( DG_MINUSA, 0 ), + TODO ( DG_CALLBEGIN, 0 ), + TODO ( DG_NEW, 0 ), + TODO ( DG_STR_TO_METHOD, 0 ), };