Compare commits

..

2 Commits

Author SHA1 Message Date
b5c85cc39c make ADD work with uint8 2025-11-15 23:15:10 +05:30
0d7c248432 Added gitignore 2025-11-15 23:15:06 +05:30
3 changed files with 193 additions and 0 deletions

52
.gitignore vendored Normal file
View File

@@ -0,0 +1,52 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf

5
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"cSpell.words": [
"VMOP"
]
}

136
main.c Normal file
View File

@@ -0,0 +1,136 @@
#include <stdint.h>
#include <stdio.h>
#define REGISTER_SIZE (1 << 6) // 64 register , overkill IK
/*
the types are defined using the X macro patter in this order
(enum name, actual c type, the value used in the union)
*/
#define VM_TYPES \
X(UINT8, uint8_t, _uint8_val) \
X(UINT16, uint16_t, _uint16_val) \
X(UINT32, uint32_t, _uint32_val) \
X(UINT64, uint64_t, _uint64_val) \
X(PTR, uintptr_t, _uintptr_val)
#define VM_OPCODES \
X(OP_ADD, vm_add) \
X(OP_SET_REG, vm_set_reg) \
X(OP_PRINT, vm_print) \
X(OP_END, vm_end)
// given context pointer perform operations on the register
#define GET_REGISTER(CTX_P, IDX) (CTX_P)->registers[(IDX)]
#define SET_REGISTER(CTX_P, IDX, TYPE, VALUE) ((CTX_P)->registers[(IDX)].type = (TYPE), vm_set_value((CTX_P), (IDX), (TYPE), (VALUE)))
// clang-format off
typedef enum {
#define X(name, ctype, field) name,
VM_TYPES
#undef X
} VMTypes;
typedef enum {
#define X(op_name, op_func) op_name,
VM_OPCODES
#undef X
} VMOPCodes;
typedef struct {
VMTypes type;
union {
#define X(name, ctype, field) ctype field;
VM_TYPES
#undef X
} value;
} VMType;
typedef struct {
VMType registers[REGISTER_SIZE];
} VMCtx;
typedef void (*vm_op_func_t)(VMCtx *, uint8_t *, size_t *);
// clang-format on
void vm_set_value(VMCtx *ctx, size_t idx, VMTypes type, uintptr_t value) {
// clang-format off
switch(type) {
#define X(name, ctype, field) \
case name: { \
ctx->registers[idx].value.field = value; \
break; \
} \
VM_TYPES
#undef X
}
// clang-format on
}
void vm_add(VMCtx *ctx, uint8_t *program, size_t *pc) {
(*pc)++;
size_t op1_idx = program[(*pc)++];
size_t op2_idx = program[(*pc)++];
size_t dest_idx = program[(*pc)++];
vm_set_value(ctx, dest_idx, UINT8, GET_REGISTER(ctx, op1_idx).value._uint8_val + GET_REGISTER(ctx, op2_idx).value._uint8_val);
}
void vm_set_reg(VMCtx *ctx, uint8_t *program, size_t *pc) {
(*pc)++;
size_t idx = program[(*pc)++];
VMTypes type = (VMTypes)program[(*pc)++];
vm_set_value(ctx, idx, type, program[(*pc)++]);
}
void vm_print(VMCtx *ctx, uint8_t *program, size_t *pc) {
(*pc)++;
printf("vm_print %d\n", GET_REGISTER(ctx, program[(*pc)++]).value._uint8_val);
}
void vm_end(VMCtx *ctx, uint8_t *program, size_t *pc) {
(*pc)++;
}
// clang-format off
vm_op_func_t vm_funcs[] = {
#define X(op_name, op_func) [op_name] = op_func,
VM_OPCODES
#undef X
};
// clang-format on
void vm_eval(VMCtx *ctx, uint8_t *program) {
size_t pc = 0;
while (program[pc] != OP_END) {
// pc++;
vm_funcs[program[pc]](ctx, program, &pc);
}
}
int main() {
VMCtx ctx = {0};
// clang-format off
uint8_t program[] = {
OP_SET_REG, 0, UINT8, 35,
OP_SET_REG, 1, UINT8, 34,
OP_ADD, 0, 1, 2,
OP_PRINT, 2,
OP_END
};
// clang-format on
// SET_REGISTER(&ctx, 0, UINT8, 12);
// SET_REGISTER(&ctx, 1, UINT8, 15);
// printf("Add = %d\n", ctx.registers[0].value._uint8_val + ctx.registers[1].value._uint8_val);
vm_eval(&ctx, program);
return 0;
}