Skip to content
Snippets Groups Projects
vm_regs.c 1.71 KiB
Newer Older
Michal Privoznik's avatar
Michal Privoznik committed
#include <stdio.h>

typedef enum {
    A = 0,
    B,
} Registers;

typedef enum {
    FLAG_ZERO       = 1,
    FLAG_NEGATIVE   = 1 << 1,
} Flags;

typedef enum {
    OP_ADD,
    OP_ADD_VALUE,
    OP_HALT,
    OP_JMP_REL,
    OP_LOAD,
    OP_NOP,
    OP_PRINT,
} OpCode;

static void
set_flags(int value, int *flags_register)
{
    if (value == 0)
        *flags_register |= FLAG_ZERO;
    if (value < 0)
        *flags_register |= FLAG_NEGATIVE;
}

int main() {
    int program[] = {
        OP_LOAD, A, 3,
        OP_LOAD, B, 5,
        OP_ADD, B,
        OP_PRINT, A,
        OP_LOAD, B, 1,
        OP_ADD, B,
        OP_PRINT, A,
        /*
        OP_ADD_VALUE, 2,
        OP_NOP,
        OP_JMP_REL, -5,
        */
        OP_HALT
    };

    int registers[2] = { 0 };
    int flags_register = 0;
    int *ip = program;

    while (1) {
        OpCode op = *ip++;
        switch (op) {
        case OP_LOAD: {
            int idx = *ip++;
            registers[idx] = *ip++;
            set_flags(registers[idx], &flags_register);
            break;
        }
        case OP_ADD: {
            int val = registers[*ip++];
            registers[A] += val;
            set_flags(registers[A], &flags_register);
            break;
        }
        case OP_ADD_VALUE: {
            /* TODO */
            break;
        }
        case OP_JMP_REL: {
            /* TODO */
            break;
        }
        case OP_NOP: {
            /* TODO */
            break;
        }
        case OP_PRINT:
            printf("%d\n", registers[*ip++]);
            break;
        case OP_HALT:
            return 0;
        default:
            fprintf(stderr, "Unknown instruction %d\n", *ip);
            return -1;
        }
    }

    return 0;
}