Skip to content
Snippets Groups Projects
Commit ed7ae376 authored by Michal Privoznik's avatar Michal Privoznik
Browse files

01: Fixup & extend vm_regs example


Firstly, registers are set to fixed-width integers instead of
variable int. Secondly, a new instruction is added
(OP_JMP_REL_EQUAL), and lastly, the example program is updated.

Signed-off-by: default avatarMichal Privoznik <mprivozn@redhat.com>
parent 8bcca7e7
No related branches found
No related tags found
No related merge requests found
......@@ -3,4 +3,4 @@
all: vm_regs
%: %.c
$(CC) -std=c99 -ggdb -O0 -Wall -pedantic $< -o $@
$(CC) -std=c99 -ggdb -O0 -Wall -Werror=switch -Werror=switch-enum -pedantic $< -o $@
#include <stdio.h>
#include <inttypes.h>
typedef enum {
A = 0,
......@@ -19,6 +20,7 @@ typedef enum {
OP_JMP_REL,
OP_JMP_REL_NEGATIVE,
OP_JMP_REL_NOT_EQUAL,
OP_JMP_REL_EQUAL,
OP_LOAD,
OP_MOV,
OP_XCHG,
......@@ -28,7 +30,7 @@ typedef enum {
} OpCode;
static void
set_flags(int value, int *flags_register)
set_flags(int16_t value, uint8_t *flags_register)
{
int new_flags = 0;
......@@ -41,90 +43,70 @@ set_flags(int value, int *flags_register)
}
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_LOAD, A, 0,
int16_t program[] = {
OP_LOAD, A, 255,
OP_LOAD, B, 0,
OP_PRINT, A,
OP_ADD_VALUE, 3,
OP_XCHG, A, B,
OP_ADD_VALUE, 1,
OP_TEST, 10,
OP_XCHG, A, B,
OP_JMP_REL_NOT_EQUAL, -16,
OP_ADD, B, A,
OP_ADD_VALUE, A, -1,
OP_TEST, A, 0,
OP_JMP_REL_NOT_EQUAL, -11,
OP_PRINT, B,
OP_HALT
};
int registers[4] = { 0 };
int flags_register = 0;
int *ip = program;
int16_t registers[4] = { 0 };
uint8_t flags_register = 0;
uint16_t *ip = (uint16_t *) program;
while (1) {
OpCode op = *ip++;
switch (op) {
case OP_LOAD: {
int idx = *ip++;
int16_t 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);
int16_t idx = *ip++;
int16_t val = registers[*ip++];
registers[idx] += val;
set_flags(registers[idx], &flags_register);
break;
}
case OP_ADD_VALUE: {
int val = *ip++;
registers[A] += val;
/* TODO */
break;
}
case OP_JMP_REL: {
int val = *ip++;
ip += val;
/* TODO */
break;
}
case OP_NOP: {
break;
}
case OP_TEST: {
int val = *ip++;
int new_val = val - registers[A];
set_flags(new_val, &flags_register);
/* TODO */
break;
}
case OP_JMP_REL_NOT_EQUAL: {
int val = *ip++;
if (!(flags_register & FLAG_ZERO)) {
ip += val;
}
/* TODO */
break;
}
case OP_JMP_REL_NEGATIVE: {
int val = *ip++;
if (!(flags_register & FLAG_NEGATIVE)) {
ip += val;
}
/* TODO */
break;
}
case OP_JMP_REL_EQUAL: {
/* TODO */
break;
}
case OP_MOV: {
int dst = *ip++;
int src = *ip++;
registers[dst] = registers[src];
/* TODO */
break;
}
case OP_XCHG: {
int r1 = *ip++;
int r2 = *ip++;
int tmp = registers[r1];
registers[r1] = registers[r2];
registers[r2] = tmp;
/* TODO */
break;
}
case OP_PRINT:
......@@ -133,7 +115,7 @@ int main() {
case OP_HALT:
return 0;
default:
fprintf(stderr, "Unknown instruction %d\n", *ip);
fprintf(stderr, "Unknown instruction %" PRId16 "\n", *ip);
return -1;
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment