Introduces shared mnemonics file. Adds assembler. Restructures makefile to build into bin/ folder.

This commit is contained in:
Felix Queißner 2016-06-30 16:55:54 +02:00
parent 5d1d274afd
commit 099e9da694
10 changed files with 2267 additions and 65 deletions

View file

@ -1,14 +1,22 @@
CC = gcc
all: explink expdump
all: explink expdump emulator as
explink: explink.c
$(CC) -g $^ -o explink
$(CC) -g -o bin/$@ $^
expdump: expdump.c
$(CC) -g $^ -o expdump
expdump: expdump.c mnemonics.c
$(CC) -g -o bin/$@ $^
emulator: emulator.c vm.c
$(CC) -g -o bin/$@ $^ -lSDL
as:
make -C as
test: exp
./exp -o test.exp $(ARGS)
hexdump -C test.exp
.PHONY: as

12
libvm/as/Makefile Normal file
View file

@ -0,0 +1,12 @@
all: as
as: as.c tokens.c ../mnemonics.c
gcc -g -o ../bin/$@ $^
tokens.c: tokens.y
flex -o $@ tokens.y

241
libvm/as/as.c Normal file
View file

@ -0,0 +1,241 @@
#include <stdbool.h>
#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include <stdint.h>
#include <ctype.h>
#include <string.h>
#include "tokens.h"
#include "../vm.h"
#include "../mnemonics.h"
struct llist
{
char name[128];
uint32_t value;
struct llist *next;
};
typedef struct llist llist_t;
void list_insert(llist_t **list, const char *name, uint32_t value)
{
llist_t *item = malloc(sizeof(struct llist));
strcpy(item->name, name);
item->value = value;
item->next = *list;
*list = item;
}
uint32_t list_find(llist_t **list, const char *name)
{
for(llist_t *it = *list; it != NULL; it = it->next)
{
if(strcmp(it->name, name) == 0) {
return it->value;
}
}
return -1;
}
void list_free(llist_t **list)
{
while((*list) != NULL)
{
llist_t *next = (*list)->next;
free(*list);
(*list) = next;
}
}
FILE *output;
int listSymbols = 0;
// current token
int tok;
void apply_modifiers(instruction_t *i)
{
while(tok == TOK_MOD)
{
printf("modifier, ");
tok = yylex();
}
}
// line format:
// TOK_LABEL? TOK_MOD* TOK_MNEMONIC TOK_MOD* ()? TOK_MOD* TOK_NEWLINE
void assemble()
{
uint32_t index = 0;
llist_t *labels = NULL;
llist_t *patches = NULL;
while(true)
{
tok = yylex();
if(tok == TOK_EOF) {
break;
}
if(tok == TOK_LABEL)
{
int len = strlen(yytext);
yytext[len - 1] = '\0'; // remove colon
list_insert(&labels, yytext, index);
tok = yylex();
}
if(tok != TOK_NEWLINE)
{
instruction_t current = { 0 };
apply_modifiers(&current);
if(tok != TOK_MNEMONIC)
{
fprintf(stderr, "Expected mnemonic!\n");
exit(1);
}
// Gather mnemonic to generate base instruction
for(int i = 0; ; i++)
{
if(mnemonics[i].name == NULL) {
fprintf(stderr, "Invalid mnemonic: %s\n", yytext);
exit(1);
}
else if(strcmp(mnemonics[i].name, yytext) == 0) {
current = mnemonics[i].instr;
break;
}
}
tok = yylex();
apply_modifiers(&current);
if(tok != TOK_NEWLINE)
{
switch(tok)
{
case TOK_INT:
current.argument = (uint32_t)atoi(yytext);
break;
case TOK_HEX:
current.argument = (uint32_t)strtol(yytext, NULL, 16);
break;
case TOK_CHAR:
current.argument = (uint32_t)yytext[1];
break;
case TOK_REFERENCE:
{
// insert patch here for deferred argument modification
// (yytext + 1) removes the leading @
list_insert(&patches, yytext + 1, index);
break;
}
default:
fprintf(stderr, "Invalid token detected: %d\n", tok);
exit(1);
}
tok = yylex();
apply_modifiers(&current);
}
if(tok != TOK_NEWLINE)
{
fprintf(stderr, "Invalid token detected: %d\n", tok);
exit(1);
}
// write command:
fwrite(&current, sizeof(instruction_t), 1, output);
// Increase command index by one
index += 1;
}
printf("NEXT\n");
}
if(listSymbols)
{
printf("Symbols:\n");
for(llist_t *it = labels; it != NULL; it = it->next)
{
printf("%s@%d\n", it->name, it->value);
}
}
printf("Patches:\n");
for(llist_t *it = patches; it != NULL; it = it->next)
{
uint32_t target = list_find(&labels, it->name);
// Seek to the target address
fseek(output, sizeof(instruction_t) * it->value + 4, SEEK_SET);
fwrite(&target, 1, sizeof(uint32_t), output);
printf("%d -> %d (%s)\n", it->value, target, it->name);
}
}
int main(int argc, char **argv)
{
output = stdout;
int c;
while ((c = getopt(argc, argv, "o:")) != -1)
{
switch (c)
{
case 'o':
{
FILE *f = fopen(optarg, "wb");
if(f == NULL) {
fprintf(stderr, "%f not found.\n", optarg);
abort();
}
if(output != stdout) {
fclose(output);
}
output = f;
break;
}
case '?':
if (optopt == 'o')
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint(optopt))
fprintf(stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf(stderr, "Unknown option character `\\x%02x'.\n", optopt);
return 1;
default:
abort();
}
}
for (int index = optind; index < argc; index++)
{
FILE *f = fopen(argv[index], "r");
if(f == NULL) {
fprintf(stderr, "%f not found.\n", optarg);
abort();
}
FILE *p = yyget_in();
if(p != NULL && p != stdin) {
fclose(p);
}
yyset_in(f);
break;
}
assemble();
FILE *p = yyget_in();
if(p != NULL && p != stdin) {
fclose(p);
}
return 0;
}

1835
libvm/as/tokens.c Normal file

File diff suppressed because it is too large Load diff

60
libvm/as/tokens.h Normal file
View file

@ -0,0 +1,60 @@
#pragma once
#include <stdio.h>
#define TOK_INVALID -1
#define TOK_EOF 0
#define TOK_INT 1
#define TOK_HEX 2
#define TOK_LABEL 3
#define TOK_MNEMONIC 4
#define TOK_MOD 5
#define TOK_NEWLINE 6
#define TOK_CHAR 7
#define TOK_REFERENCE 8
extern int yylineno;
extern char *yytext;
/** Get the current line number.
*
*/
int yyget_lineno (void);
/** Get the input stream.
*
*/
FILE *yyget_in (void);
/** Get the output stream.
*
*/
FILE *yyget_out (void);
/** Get the current token.
*
*/
char *yyget_text (void);
/** Set the current line number.
* @param _line_number line number
*
*/
void yyset_lineno (int _line_number );
/** Set the input stream. This does not discard the current
* input buffer.
* @param _in_str A readable stream.
*
* @see yy_switch_to_buffer
*/
void yyset_in (FILE * _in_str );
void yyset_out (FILE * _out_str );
int yyget_debug (void);
void yyset_debug (int _bdebug );
int yylex();

32
libvm/as/tokens.y Normal file
View file

@ -0,0 +1,32 @@
%{
#include "tokens.h"
#define RETURN(x,y) /* fprintf(stderr, "{" #x "}" y ); */ return x
%}
comment ;[^\n]*
whitespace [ \t]
newline [\n]
digit [0-9]
hexdigit [0-9a-fA-F]
intnum {digit}+
hexnum "0x"{hexdigit}+
mnemonic [a-zA-Z]+
labelname [a-zA-Z0-9_]+
label {labelname}":"
mod \[[^\]]+\]
character "'"."'"
ref @{labelname}
%%
{comment} ;
{hexnum} RETURN(TOK_HEX,);
{intnum} RETURN(TOK_INT,);
{whitespace} ;
{mnemonic} RETURN(TOK_MNEMONIC,);
{label} RETURN(TOK_LABEL,);
{mod} RETURN(TOK_MOD,);
{character} RETURN(TOK_CHAR, );
{ref} RETURN(TOK_REFERENCE, );
{newline} RETURN(TOK_NEWLINE, "\n");
. RETURN(TOK_INVALID,);
%%
// This is the end of the file
int yywrap() { return 1; }

View file

@ -1,12 +1,14 @@
#define _CRT_SECURE_NO_WARNINGS
#include <SDL.h>
#include <stdbool.h>
#include "vm.h"
#include "exp.h"
#if defined(_MSC_VER)
#include <SDL.h>
#undef main
#else
#include <SDL/SDL.h>
#endif
bool running = true;
@ -228,11 +230,13 @@ int main(int argc, char **argv)
return 0;
}
FILE * __cdecl __iob_func(void)
{
static FILE iob[3];
iob[0] = *stdin;
iob[1] = *stdout;
iob[2] = *stderr;
return iob;
}
/*#if defined(_MSC_VER)*/
/*FILE * __cdecl __iob_func(void)*/
/*{*/
/*static FILE iob[3];*/
/*iob[0] = *stdin;*/
/*iob[1] = *stdout;*/
/*iob[2] = *stderr;*/
/*return iob;*/
/*}*/
/*#endif*/

View file

@ -22,54 +22,7 @@
#define DEBUG_VAL(x) fprintf(stderr, #x " = %d\n", x)
struct PredefinedCmd
{
const char *name;
instruction_t instr;
};
struct PredefinedCmd namedCommands[] =
{
{ "nop",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "push",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "drop",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "dup",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_PEEK, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "jmp",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_JUMP } },
{ "jmpi",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_JUMP } },
{ "ret",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_JUMP } },
{ "load",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_ZERO, VM_CMD_LOAD, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "loadi",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_LOAD, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "store",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_POP, VM_CMD_STORE, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "storei",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_STORE, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "get",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_ZERO, VM_CMD_GET, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "geti",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_GET, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "set",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_POP, VM_CMD_SET, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "seti",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_SET, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "bpget",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_BPGET, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "bpset",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_BPSET, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "spget",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_SPGET, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "spset",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_SPSET, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "cpget",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_CPGET, 1, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "add",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "sub",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 1, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "cmp",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 1, VM_FLAG_YES, VM_OUTPUT_DISCARD } },
{ "mul",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 2, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "div",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 3, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "mod",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 4, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "and",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 5, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "or",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 6, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "xor",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 7, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "not",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_MATH, 8, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "rol",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 9, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "ror",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 10, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "asl",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 11, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "asr",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 12, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "shl",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 13, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "shr",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 14, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "syscall",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_SYSCALL, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "hwio",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_HWIO, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
};
#include "mnemonics.h"
const char *commandStrings[] =
{
@ -112,12 +65,12 @@ void disassemble(instruction_t *list, uint32_t count, uint32_t base, FILE *f)
fprintf(f, "%8X: ", base + i);
struct PredefinedCmd *knownInstruction = NULL;
const mnemonic_t *knownInstruction = NULL;
for (int j = 0; j < sizeof(namedCommands) / sizeof(struct PredefinedCmd); j++)
for (int j = 0; mnemonics[j].name != NULL; j++)
{
if (memcmp(&instr, &namedCommands[j].instr, sizeof(instruction_t) - sizeof(uint32_t)) == 0) {
knownInstruction = &namedCommands[j];
if (memcmp(&instr, &mnemonics[j].instr, sizeof(instruction_t) - sizeof(uint32_t)) == 0) {
knownInstruction = &mnemonics[j];
break;
}
}

44
libvm/mnemonics.c Normal file
View file

@ -0,0 +1,44 @@
#include "mnemonics.h"
const mnemonic_t mnemonics[] =
{
{ "nop",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "push",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "drop",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "dup",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_PEEK, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "jmp",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_JUMP } },
{ "jmpi",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_JUMP } },
{ "ret",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_COPY, 0, VM_FLAG_NO, VM_OUTPUT_JUMP } },
{ "load",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_ZERO, VM_CMD_LOAD, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "loadi",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_LOAD, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "store",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_POP, VM_CMD_STORE, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "storei",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_STORE, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "get",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_ZERO, VM_CMD_GET, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "geti",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_GET, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "set",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ARG, VM_INPUT_POP, VM_CMD_SET, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "seti",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_SET, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "bpget",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_BPGET, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "bpset",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_BPSET, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "spget",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_SPGET, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "spset",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_SPSET, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "cpget",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_CPGET, 1, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "add",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 0, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "sub",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 1, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "cmp",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 1, VM_FLAG_YES, VM_OUTPUT_DISCARD } },
{ "mul",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 2, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "div",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 3, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "mod",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 4, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "and",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 5, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "or",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 6, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "xor",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 7, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "not",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_ZERO, VM_CMD_MATH, 8, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "rol",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 9, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "ror",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 10, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "asl",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 11, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "asr",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 12, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "shl",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 13, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "shr",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_POP, VM_INPUT_POP, VM_CMD_MATH, 14, VM_FLAG_NO, VM_OUTPUT_PUSH } },
{ "syscall",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_SYSCALL, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ "hwio",{ VM_EXEC_X, VM_EXEC_X, VM_INPUT_ZERO, VM_INPUT_ZERO, VM_CMD_HWIO, 0, VM_FLAG_NO, VM_OUTPUT_DISCARD } },
{ NULL, {0} }, // stop marker
};

13
libvm/mnemonics.h Normal file
View file

@ -0,0 +1,13 @@
#pragma once
#include "vm.h"
struct mnemonic
{
const char *name;
instruction_t instr;
};
typedef struct mnemonic mnemonic_t;
extern const mnemonic_t mnemonics[];