aboutsummaryrefslogtreecommitdiff
path: root/pu2/pu2.c
diff options
context:
space:
mode:
Diffstat (limited to 'pu2/pu2.c')
-rw-r--r--pu2/pu2.c905
1 files changed, 393 insertions, 512 deletions
diff --git a/pu2/pu2.c b/pu2/pu2.c
index fd436a3..ed7a5ea 100644
--- a/pu2/pu2.c
+++ b/pu2/pu2.c
@@ -1,8 +1,11 @@
#define _POSIX_C_SOURCE 200809L
-#include "pu2.out.c"
//
-#include <errno.h>
+#include "../pu3/pu3.cpu.c"
+//
+#include <ctype.h>
#include <libgen.h>
+#include <limits.h>
+#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -10,16 +13,18 @@
#include <time.h>
#include <unistd.h>
-typedef char *string;
-typedef unsigned char byte;
-typedef byte bool;
+#pragma clang diagnostic ignored "-Wparentheses"
+#pragma clang diagnostic ignored "-Wreturn-type"
+#pragma clang diagnostic ignored "-Wempty-body"
+#pragma clang diagnostic error "-Wimplicit-function-declaration"
+
const bool true = 1;
const bool false = 0;
-string read_file(string path, int *out_size) {
- FILE *f = fopen(path, "rb");
- string buf;
- int size;
+string read_file(string path, uint32_t *out_size) {
+ FILE *f = fopen(path, "rb");
+ string buf;
+ uint32_t size;
if (!f) return NULL;
fseek(f, 0, SEEK_END);
size = ftell(f);
@@ -55,8 +60,8 @@ string canonicalize(string input) {
return NULL;
}
- int absolute = (buf[ 0 ] == '/');
- char *saveptr;
+ uint32_t absolute = (buf[ 0 ] == '/');
+ char *saveptr;
for (tok = strtok_r(buf, "/", &saveptr); tok; tok = strtok_r(NULL, "/", &saveptr)) {
if (!strcmp(tok, ".")) continue;
else if (!strcmp(tok, "..")) {
@@ -103,11 +108,11 @@ string canonicalize(string input) {
return out;
}
-error_debug(string fail_point, string code, int sz) {
- int error_pos = (int) (fail_point - code);
- int i;
+error_debug(string fail_point, string code, uint32_t sz) {
+ uint32_t error_pos = (uint32_t) (fail_point - code);
+ uint32_t i;
- int line = 1, col = 1;
+ uint32_t line = 1, col = 1;
for (i = 0; i < error_pos && i < sz; i++) {
if (code[ i ] == '\n') {
line++;
@@ -117,14 +122,14 @@ error_debug(string fail_point, string code, int sz) {
}
}
- int line_start = error_pos;
+ uint32_t line_start = error_pos;
while (line_start > 0 && code[ line_start - 1 ] != '\n') { line_start--; }
- int line_end = error_pos;
+ uint32_t line_end = error_pos;
while (line_end < sz && code[ line_end ] != '\n' && code[ line_end ] != '\0') { line_end++; }
- int tmp = line;
- int lineno_width = 1;
+ uint32_t tmp = line;
+ uint32_t lineno_width = 1;
while (tmp >= 10) {
lineno_width++;
tmp /= 10;
@@ -165,10 +170,10 @@ long powi(long x, unsigned n) {
}
typedef struct {
- int pid;
- int ring_level;
- int *memory;
- int mem_size;
+ uint32_t pid;
+ uint32_t ring_level;
+
+ pu3_ctx context;
struct {
bool spawn_process : 1;
@@ -181,16 +186,19 @@ emu_process processes[ pid_count ]; // maximum process count
bool process_occupied[ pid_count ];
struct emu_return {
- bool time_finished;
- int e_code;
-} emu(int time_slice, int pid) {
+ bool time_finished;
+ uint32_t e_code;
+} emu(uint32_t time_slice, uint32_t pid) {
process_occupied[ pid ] = true;
emu_process process = processes[ pid ];
- int *m = process.memory;
+ uint32_t *m = process.context.memory.memory_u32;
while (1) {
- int remaining_time = pu2(time_slice, m, process.mem_size);
- int e_code = m[ 0 ];
+ process.context.time_slice = time_slice;
+ uint32_t remaining_time = pu3(process.context);
+ uint32_t e_code = m[ 0 ];
+
+ // printf("exit code: %i\n", e_code);
if (remaining_time <= 0 && time_slice != -1) {
// process_occupied[ pid ] = false;
@@ -202,12 +210,12 @@ struct emu_return {
}
// handle hardware interrupts
- int int_code = m[ 1 ];
+ uint32_t int_code = m[ 1 ];
// 0: output string
if (int_code == 0) {
- int ptr = m[ 2 ];
- int size = m[ 3 ], i = 0;
+ uint32_t ptr = m[ 2 ];
+ uint32_t size = m[ 3 ], i = 0;
while (size--) putchar(m[ ptr++ ]);
}
@@ -219,9 +227,9 @@ struct emu_return {
// 2: arithmetics unit
else if (int_code == 2) {
- int op = m[ 2 ];
- int val1 = m[ 3 ];
- int val2 = m[ 4 ];
+ uint32_t op = m[ 2 ];
+ uint32_t val1 = m[ 3 ];
+ uint32_t val2 = m[ 4 ];
m[ 2 ] = 0;
@@ -254,16 +262,16 @@ struct emu_return {
// permission features
else if (int_code == 3) {
- int op = m[ 2 ];
+ uint32_t op = m[ 2 ];
if (op == 0) {
// spawn process
- int target_ring = m[ 10 ];
- int memory_start = m[ 11 ];
- int memory_length = m[ 12 ];
- int can_spawn_processes = m[ 13 ];
- int can_make_syscalls = m[ 14 ];
- int max_time_limit = m[ 15 ];
+ uint32_t target_ring = m[ 10 ];
+ uint32_t memory_start = m[ 11 ];
+ uint32_t memory_length = m[ 12 ];
+ uint32_t can_spawn_processes = m[ 13 ];
+ uint32_t can_make_syscalls = m[ 14 ];
+ uint32_t max_time_limit = m[ 15 ];
if (target_ring < process.ring_level) {
// error - process cannot spawn a process on a lower ring level
@@ -278,7 +286,7 @@ struct emu_return {
goto HAD_ERROR;
}
- int new_pid = 0;
+ uint32_t new_pid = 0;
for (new_pid = 0; new_pid < pid_count; new_pid++) {
if (!process_occupied[ new_pid ]) goto FOUND;
@@ -289,20 +297,19 @@ struct emu_return {
goto HAD_ERROR;
FOUND:;
-
- int *new_process_memory = calloc(memory_length, sizeof(int));
+ pu3_ctx *__ctx = init_pu3();
process_occupied[ new_pid ] = true;
processes[ new_pid ]
= (emu_process) { .pid = new_pid,
.ring_level = target_ring,
- .memory = new_process_memory,
- .mem_size = memory_length,
+ .context = *__ctx,
.permissions = { .make_syscall = !!can_make_syscalls,
.spawn_process = !!can_spawn_processes } };
// copy memory
- memcpy(new_process_memory, m + memory_start, memory_length * sizeof(int));
+ memcpy(
+ __ctx->memory.memory_u32, m + memory_start, memory_length * sizeof(uint32_t));
// run process
struct emu_return result = emu(max_time_limit, new_pid);
@@ -314,8 +321,8 @@ struct emu_return {
m[ 5 ] = result.time_finished;
} else if (op == 1) {
// resume process pid (if it's halted)
- int process_pid = m[ 10 ];
- int max_time_limit = m[ 11 ];
+ uint32_t process_pid = m[ 10 ];
+ uint32_t max_time_limit = m[ 11 ];
if (!process_occupied[ process_pid ]) {
// error - process is not running, start/initialize it first
@@ -338,10 +345,10 @@ struct emu_return {
m[ 4 ] = result.time_finished;
} else if (op == 2) {
// read memory from another process
- int process_pid = m[ 10 ];
- int memory_address = m[ 11 ];
- int read_length = m[ 12 ];
- int target_location = m[ 13 ];
+ uint32_t process_pid = m[ 10 ];
+ uint32_t memory_address = m[ 11 ];
+ uint32_t read_length = m[ 12 ];
+ uint32_t target_location = m[ 13 ];
if (processes[ process_pid ].ring_level < processes[ pid ].ring_level
|| processes[ pid ].ring_level > 3) {
@@ -351,17 +358,18 @@ struct emu_return {
}
// copy information
- int *memory = processes[ process_pid ].memory;
- memcpy(m + target_location, memory + memory_address, read_length * sizeof(int));
+ uint32_t *memory = processes[ process_pid ].context.memory.memory_u32;
+ memcpy(
+ m + target_location, memory + memory_address, read_length * sizeof(uint32_t));
// done!
m[ 2 ] = 0;
} else if (op == 3) {
// write memory to target process
- int process_pid = m[ 10 ];
- int memory_address = m[ 11 ];
- int write_length = m[ 12 ];
- int target_location = m[ 13 ];
+ uint32_t process_pid = m[ 10 ];
+ uint32_t memory_address = m[ 11 ];
+ uint32_t write_length = m[ 12 ];
+ uint32_t target_location = m[ 13 ];
if (processes[ process_pid ].ring_level < processes[ pid ].ring_level
|| processes[ pid ].ring_level > 3) {
@@ -371,8 +379,9 @@ struct emu_return {
}
// write information
- int *memory = processes[ process_pid ].memory;
- memcpy(memory + memory_address, m + target_location, write_length * sizeof(int));
+ uint32_t *memory = processes[ process_pid ].context.memory.memory_u32;
+ memcpy(
+ memory + memory_address, m + target_location, write_length * sizeof(uint32_t));
// done!
m[ 2 ] = 0;
@@ -400,18 +409,11 @@ skip_space(string *I) {
}
// IR parser for pu2's as2
-// clang-format off
-struct {
- int hlt, imm, lod, str, swp, add, sub, and, not, acc, a2u, u2a, b2u, u2b, nop, cb1, cb2, cb3, cb4;
-} opcode = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18
-};
-// clang-format on
// use this instead of strdup'ing and allocating extra storage!
typedef struct {
- int len;
- string ref;
+ uint32_t len;
+ string ref;
} slice_t;
typedef struct {
@@ -420,8 +422,8 @@ typedef struct {
} entry_t;
typedef struct {
- slice_t name;
- int location;
+ slice_t name;
+ uint32_t location;
} label_t;
typedef struct {
@@ -430,9 +432,9 @@ typedef struct {
} macro_t;
typedef struct {
- slice_t name;
- int *replace_location; // where to put the resolved address
- string init_I;
+ slice_t name;
+ pu3_inst_t *replace_location; // where to put the resolved address
+ string init_I;
} label_delegated_t;
clean_slice_ref(slice_t *val) { free(val->ref); }
@@ -465,7 +467,7 @@ clean_slice_ref(slice_t *val) { free(val->ref); }
#define readd() ((used == new.len) ? (new.ref = realloc(new.ref, new.len *= 2)) : 0)
#define scanvalue() \
({ /* value scanner! numbers, characters, strings, variable derefs. */ \
- int value; \
+ uint32_t value; \
if (isdigit(*I)) { \
value = strtol(I, &I, 10); \
} else if (*I == '\'') { \
@@ -473,9 +475,9 @@ clean_slice_ref(slice_t *val) { free(val->ref); }
value = *I++; \
checkskip('\'', "couldn't find closing quote on character"); \
} else if (*I == '"') { \
- string str_start = ++I; \
- bool T = false; \
- int str_len = 0; \
+ string str_start = ++I; \
+ bool T = false; \
+ uint32_t str_len = 0; \
while (*I != '"' || T) { \
if (*I == '\\') { \
T = !T; \
@@ -486,11 +488,11 @@ clean_slice_ref(slice_t *val) { free(val->ref); }
} \
I++; \
str_len++; \
- int *dest_start = pointers.data -= str_len + 1; \
- int y; \
+ uint32_t *dest_start = pointers.data -= str_len + 1; \
+ uint32_t y; \
for (y = 0; y < str_len - 1; y++) { dest_start[ y ] = str_start[ y ]; } \
pointers.data[ -1 ] = 0; \
- value = pointers.data - storage.assembly_target; \
+ value = pointers.data - (uint32_t *) storage.assembly_target; \
} else if (*I == '&') { \
I++; \
string starting_I = I; \
@@ -503,7 +505,7 @@ clean_slice_ref(slice_t *val) { free(val->ref); }
})
#define scanvar() \
({ /* memory scanner! finds @10, var_name */ \
- int value; \
+ uint32_t value; \
if (*I == '@') { \
if (!isdigit(*++I)) run_err(I - 1, "expected memory index"); \
value = strtol(I, &I, 10); \
@@ -518,87 +520,36 @@ clean_slice_ref(slice_t *val) { free(val->ref); }
#define varqual(F) ((F) == '@' || isalpha(F) || (F) == '_')
#define litqual(F) (isdigit(F) || (F) == '\'' || (F) == '"' || (F) == '&')
-#define p_cat(a, b) a##b
-#define cat(a, b) p_cat(a, b)
-
-#define not_subpart_1(__a)
-#define not_subpart_(__a) __a
-#define not(val, ...) cat(not_subpart_, __VA_OPT__(1))(val)
-#define op(mode, ...) emit(opcode.mode, not(0, __VA_ARGS__) __VA_ARGS__)
-
-#define store() (op(acc, 1), op(str))
-#define swap() op(swp)
-#define imm(value) op(imm, value)
-#define load() op(lod)
-#define imm_in_mem(__mem, __imm) (imm(__mem), op(cb3, __imm))
-#define mov_mem_mem(__mem1, __mem2) (imm(__mem1), op(cb4, __mem2))
-#define mem_in_a(__mem) op(cb2, __mem)
-#define a_in_mem(__mem) op(cb1, __mem)
-#define deref_a() (op(b2u), swap(), load(), op(u2b))
-
-wowie() { op(acc); }
-
-#define check_stack() (0)
-#define perf_sp(__op) \
- (mem_in_a(storage.stack_pointer), \
- op(acc, 1), \
- op(u2b), \
- op(__op), \
- a_in_mem(storage.stack_pointer))
-#define inc_sp() perf_sp(add)
-#define dec_sp() perf_sp(sub)
-
-#define push_imm(__imm) (mem_in_a(storage.stack_pointer), op(cb3, __imm), dec_sp())
-#define push_mem(__mem) (mem_in_a(storage.stack_pointer), op(cb4, __mem), dec_sp())
-#define pop_stack_a() (inc_sp(), mem_in_a(storage.stack_pointer), deref_a())
-// #define pop_stack_mem(__mem)
-
-#define perform_op(operation) \
- ({ \
- mem_in_a(mem2_index); \
- swap(); \
- mem_in_a(mem_index); \
- op(operation); \
- swap(); \
- imm(mem_index); \
- store(); \
- })
-
string ERR;
string ERR_code;
struct ir2_pointers {
- int *code;
- int *data;
- int *stack;
- int stack_pointer;
+ pu3_inst_t *code;
+ uint32_t *data;
+ pu3_inst_t *stack;
+ uint32_t stack_pointer;
} pointers;
-init_ir2(int *target_mem, int max_size) {
- static const int starting_code = 5000;
+uint32_t init_ir2(pu3_inst_t *target_mem, pu3_inst_t max_size) {
+ static const pu3_inst_t starting_code = 5000;
- pointers.stack = &target_mem[ 4998 ]; // stack is downward growing
- pointers.stack_pointer = 4999; // stack pointer
- pointers.code = &target_mem[ starting_code ]; // code pointer
- pointers.data = &target_mem[ max_size - 1 ]; // data grows downwards
+ pointers.stack = &target_mem[ 4998 ]; // stack is downward growing
+ pointers.stack_pointer = 4999; // stack pointer
+ pointers.code = &target_mem[ starting_code ]; // code pointer
+ pointers.data = (uint32_t *) &target_mem[ max_size - 1 ]; // data grows downwards
return starting_code;
}
-__attribute__((always_inline)) emit(int op, int val) {
- *pointers.code++ = op;
- *pointers.code++ = val;
-}
-
-int ir2_depth = 0;
+uint32_t ir2_depth = 0;
#define space skip_space(&I)
-bool has_jump_warned = false;
+// bool has_jump_warned = false;
bool has_useless_if_warned = false;
bool has_false_while_warned = false;
__ir2_get_var_loc(slice_t name, label_t variables[ 1 << 11 ], string error_I, string init_I) {
- int j;
+ uint32_t j;
for (j = 0; j < 1 << 11; j++) {
label_t cur = variables[ j ];
if (cur.name.ref == NULL) break;
@@ -610,13 +561,45 @@ __ir2_get_var_loc(slice_t name, label_t variables[ 1 << 11 ], string error_I, st
}
typedef struct {
- int *assembly_target;
+ pu3_inst_t *assembly_target;
macro_t *macros;
label_t *labels;
label_delegated_t *forward_refs;
label_t *variables;
} ir2_storage;
+// #define IR2_INIT_COMPILE_TIME
+
+const int SPARES_LOC = 1005;
+
+#define write(inst) (*pointers.code++ = inst)
+#define get(__opcode, lhs, rhs) build_inst(false, false, opcode.__opcode, lhs, rhs)
+#define getde(__opcode, lhs, rhs) build_inst(false, true, opcode.__opcode, lhs, rhs)
+#define getrev(__opcode, lhs, rhs) build_inst(true, false, opcode.__opcode, lhs, rhs)
+#define getderev(__opcode, lhs, rhs) build_inst(true, true, opcode.__opcode, lhs, rhs)
+
+inline void mov_mem_mem(uint32_t indexL, uint32_t indexR) {
+ if (indexR > UINT16_MAX) {
+ // some trickery
+ write(getderev(mov, indexR, SPARES_LOC)); // *spare = *indexR
+ write(getde(mov, indexL, SPARES_LOC)); // *indexL = *spare
+ } else {
+ write(getde(mov, indexL, indexR)); // *indexL = *indexR
+ }
+}
+
+inline void halt() { write(get(hlt, 0, 0)); }
+inline void set_imm(uint32_t value) { write(getrev(mov, value, 0)); }
+inline void imm_in_mem(uint32_t addr, uint32_t value) {
+ if (value > UINT16_MAX) {
+ // more trickery
+ write(getrev(mov, value, SPARES_LOC)); // *spare = value
+ write(getde(mov, addr, SPARES_LOC)); // *addr = *spare
+ } else {
+ write(get(mov, addr, value)); // *addr = value
+ }
+}
+
string _ir2(string I, string filepath, ir2_storage storage) {
char T;
string init_I = I;
@@ -665,8 +648,8 @@ string _ir2(string I, string filepath, ir2_storage storage) {
slice_t name = scanword();
space;
- int *m_index = --pointers.data;
- int start_index = m_index - storage.assembly_target;
+ uint32_t *m_index = --pointers.data;
+ uint32_t start_index = m_index - (uint32_t *) storage.assembly_target;
if (*I == ':') {
I++;
@@ -683,8 +666,8 @@ string _ir2(string I, string filepath, ir2_storage storage) {
space;
}
-// comment out this flag to initialize values at runtime instead of compile-time
-#define IR2_INIT_COMPILE_TIME
+ // comment out this flag to initialize values at runtime instead of compile-time
+ // #define IR2_INIT_COMPILE_TIME
if (*I == ';') {
// no starter value, just initialize it to zero
@@ -705,7 +688,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
imm_in_mem(start_index, scanvalue());
#endif
} else if (varqual(*I)) { // memory address
- int mem_index = scanvar();
+ uint32_t mem_index = scanvar();
mov_mem_mem(start_index, mem_index);
} else {
run_err(I, "expected compile-time constant, variable or memory index");
@@ -715,7 +698,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
checkskip(';', "expected semicolon after variable value");
}
- int j;
+ uint32_t j;
for (j = 0; j < 1 << 11; j++) {
label_t cur = storage.variables[ j ];
@@ -760,8 +743,8 @@ string _ir2(string I, string filepath, ir2_storage storage) {
free(dir);
}
- int out_size;
- string text = read_file(full, &out_size);
+ uint32_t out_size;
+ string text = read_file(full, &out_size);
if (text == NULL) {
printf("failed to import \"%s\"\n", full);
perror("unable to use import");
@@ -795,8 +778,8 @@ string _ir2(string I, string filepath, ir2_storage storage) {
space;
- string before = I;
- int arg_count = strtol(I, &I, 10);
+ string before = I;
+ uint32_t arg_count = strtol(I, &I, 10);
if (I == before) {
run_err(I, "expected number (argument count) in macro definition parens");
}
@@ -813,7 +796,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
checkskip('{', "expected open curly bracket in macro body");
// find open space in macros
- int x;
+ uint32_t x;
for (x = 0; x < (1 << 9); x++) {
macro_t g = storage.macros[ x ];
if (g.data.key.ref == NULL) goto DONE;
@@ -834,7 +817,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
g->data.value.len = 0;
g->arg_count = arg_count;
- int dep = 0;
+ uint32_t dep = 0;
while (dep != 0 || *I != '}') {
if (*I == '{') dep++;
if (*I == '}') dep--;
@@ -851,12 +834,15 @@ string _ir2(string I, string filepath, ir2_storage storage) {
}
// emit exit calls
+ // wow, this was ooold code. had to patch quite a few things here.
if (strncmp("exit", I, 4) == 0 && !varqual(I[ 4 ])) {
I += 4;
+ space;
checkskip('(', "expected open paren on exit blob");
- string old = I;
- int value = strtol(I, &I, 10);
+ string old = I;
+ uint32_t value = strtol(I, &I, 10);
+ space;
if (old == I && *I != ')') {
run_err(I - 1, "invalid input to exit blob, expected number");
}
@@ -867,8 +853,8 @@ string _ir2(string I, string filepath, ir2_storage storage) {
checkskip(';', "expected semicolon after call");
// actually emit stuff
- if (old != I) imm(value);
- op(hlt);
+ if (old != I) set_imm(value);
+ halt();
continue;
}
@@ -886,7 +872,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
checkskip(';', "expected semicolon after system blob");
imm_in_mem(0, 2);
- op(hlt);
+ halt();
continue;
}
@@ -915,7 +901,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
while (lbdb->name.ref != NULL) {
label_t cur = *lbdb++;
if (cur.name.len == label.len && strncmp(cur.name.ref, label.ref, label.len) == 0) {
- imm_in_mem(7, cur.location);
+ write(get(jmp, cur.location, 0));
goto FINISH_JMP;
}
}
@@ -924,7 +910,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
// find delegations slot
label_delegated_t *del;
- int j;
+ uint32_t j;
for (j = 0; j < 1 << 10; j++) {
if (storage.forward_refs[ j ].name.ref == NULL) {
// found one!
@@ -940,7 +926,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
WRITE_DEL:
- imm_in_mem(7, 0xDEAD10C4); // DEADLOCK - placeholder for the resolver
+ write(get(jmp, 0xDEAD10C4, 0)); // DEADLOCK - placeholder for the resolver
del->replace_location = pointers.code - 1; // place of imm in code
del->name = label;
del->init_I = init_I;
@@ -958,7 +944,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
space;
checkskip('(', "expected open paren on %s blob", name);
space;
- int target_mem = scanvar();
+ uint32_t target_mem = scanvar();
space;
checkskip(
@@ -993,13 +979,9 @@ string _ir2(string I, string filepath, ir2_storage storage) {
label_t cur = *lbdb++;
if (cur.name.len == label.len && strncmp(cur.name.ref, label.ref, label.len) == 0) {
// emit j(n)z
- mem_in_a(target_mem);
- if (!was_jnz) op(not);
- op(a2u);
- imm(cur.location);
- swap();
- imm(7);
- op(str);
+ write(getderev(mov, SPARES_LOC, target_mem)); // *spare = *mem;
+ if (!was_jnz) write(get(not, SPARES_LOC, 0)); // *spare = !*spare;
+ write(getde(jnz, cur.location, SPARES_LOC)); // jmp(cur.location) if *spare;
goto FINISH_JNZ;
}
@@ -1009,7 +991,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
// find delegations slot
label_delegated_t *del;
- int j;
+ uint32_t j;
for (j = 0; j < 1 << 10; j++) {
if (storage.forward_refs[ j ].name.ref == NULL) {
// found one!
@@ -1026,14 +1008,11 @@ string _ir2(string I, string filepath, ir2_storage storage) {
WRITE_DEL_JNZ:
// emit j(n)z
- mem_in_a(target_mem);
- if (!was_jnz) op(not);
- op(a2u);
- imm(0xDEAD10C4); // DEADLOCK - placeholder for the resolver
- del->replace_location = pointers.code - 1; // place of imm in code
- swap();
- imm(7);
- op(str);
+ write(getderev(mov, SPARES_LOC, target_mem)); // *spare = *mem;
+ if (!was_jnz) write(get(not, SPARES_LOC, 0)); // *spare = !*spare;
+ write(getde(jnz, 0xDEAD10C4, SPARES_LOC)); // jmp(0xDEAD10C4) if *spare; // DEADLOCK -
+ // placeholder for the resolver
+ del->replace_location = pointers.code - 1; // place of jump in code
del->name = label;
del->init_I = init_I;
@@ -1058,7 +1037,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
}
// redundant if statement: always true / always false
- int value = strtol(I, &I, 10);
+ uint32_t value = strtol(I, &I, 10);
space;
checkskip(')', "expected closing paren after if statement argument");
space;
@@ -1071,13 +1050,14 @@ string _ir2(string I, string filepath, ir2_storage storage) {
struct ir2_pointers pointers_B = pointers;
// completely eliminate code generated in useless if statement
- int *m2 = calloc(S, sizeof(int));
- label_t *variables_G = calloc(1 << 5, sizeof(label_t));
- pointers.data = pointers.code = m2;
+ uint32_t *m2 = calloc(S, sizeof(uint32_t));
+ label_t *variables_G = calloc(1 << 5, sizeof(label_t));
+ pointers.data = m2;
+ pointers.code = (uint64_t *) m2;
ir2_storage useless_storage = storage;
useless_storage.variables = variables_G;
- useless_storage.assembly_target = m2;
+ useless_storage.assembly_target = (uint64_t *) m2;
// get new I location
string new_I = _ir2(I, filepath, useless_storage);
@@ -1104,27 +1084,26 @@ string _ir2(string I, string filepath, ir2_storage storage) {
space;
}
- int mem_index = scanvar();
+ uint32_t mem_index = scanvar();
space;
checkskip(')', "expected closing paren after if statement argument");
space;
checkskip('{', "expected opening bracket for if statement body");
space;
- mem_in_a(mem_index);
- if (!was_negated) op(not);
- op(a2u);
- imm(0xDEAD10C4); // DEADLOCK - placeholder for the patchback
- int *patchback = pointers.code - 1;
- swap();
- imm(7);
- op(str);
+ write(getderev(mov, SPARES_LOC, mem_index)); // *spare = *mem;
+ if (!was_negated) write(get(not, SPARES_LOC, 0)); // *spare = !*spare;
+ write(getde(jnz, 0xDEAD10C4, SPARES_LOC)); // jmp(cur.location) if *spare;
+ pu3_inst_t *patchback = pointers.code - 1;
// handle the code stuff
string new_I = _ir2(I, filepath, storage);
I = new_I;
- *patchback = pointers.code - storage.assembly_target; // patch the jump instruction
+ *patchback = getde(
+ jnz,
+ pointers.code - storage.assembly_target,
+ SPARES_LOC); // patch the jump instruction
continue;
}
@@ -1137,7 +1116,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
ir2_depth++;
if (isdigit(*I)) {
- int value = strtol(I, &I, 10);
+ uint32_t value = strtol(I, &I, 10);
space;
checkskip(')', "expected closing paren after while loop argument");
@@ -1158,12 +1137,13 @@ string _ir2(string I, string filepath, ir2_storage storage) {
struct ir2_pointers pointers_B = pointers;
// completely eliminate code generated in useless while loop
- int *m2 = calloc(S, sizeof(int));
- label_t *variables_G = calloc(1 << 5, sizeof(label_t));
- pointers.data = pointers.code = m2;
+ uint32_t *m2 = calloc(S, sizeof(uint32_t));
+ label_t *variables_G = calloc(1 << 5, sizeof(label_t));
+ pointers.data = m2;
+ pointers.code = (uint64_t *) m2;
ir2_storage useless_storage = storage;
- useless_storage.assembly_target = m2;
+ useless_storage.assembly_target = (uint64_t *) m2;
useless_storage.variables = variables_G;
// get new I location
@@ -1177,12 +1157,12 @@ string _ir2(string I, string filepath, ir2_storage storage) {
} else {
// run forever!
- int start = pointers.code - storage.assembly_target;
+ uint32_t start = pointers.code - storage.assembly_target;
string new_I = _ir2(I, filepath, storage);
I = new_I;
- imm_in_mem(7, start); // always jump back to the start
+ write(get(jmp, start, 0)); // always jump back to the start
}
continue;
@@ -1195,38 +1175,33 @@ string _ir2(string I, string filepath, ir2_storage storage) {
space;
}
- int mem_index = scanvar();
+ uint32_t mem_index = scanvar();
space;
checkskip(')', "expected closing paren after while loop condition");
space;
checkskip('{', "expected opening bracket for while loop body");
space;
- mem_in_a(mem_index);
- if (!was_negated) op(not);
- op(a2u);
- imm(0xDEAD10C4); // DEADLOCK - placeholder for the patchback
- int *patchback = pointers.code - 1;
- swap();
- imm(7);
- op(str);
+ write(getderev(mov, mem_index, SPARES_LOC));
+ if (!was_negated) write(get(not, SPARES_LOC, 0));
+ write(getde(jnz, 0xDEAD10C4, SPARES_LOC));
+ uint64_t *patchback = pointers.code - 1;
- int start_index = pointers.code - storage.assembly_target;
+ uint32_t start_index = pointers.code - storage.assembly_target;
// handle the code stuff
string new_I = _ir2(I, filepath, storage);
I = new_I;
- *patchback = pointers.code - storage.assembly_target; // patch the jump instruction
-
// check the condition and jump back if true
- mem_in_a(mem_index);
- if (was_negated) op(not);
- op(a2u);
- imm(start_index);
- swap();
- imm(7);
- op(str);
+ write(getderev(mov, mem_index, SPARES_LOC));
+ if (was_negated) write(get(not, SPARES_LOC, 0));
+ write(getde(jnz, start_index, SPARES_LOC));
+
+ *patchback = getde(
+ jnz,
+ pointers.code - storage.assembly_target,
+ SPARES_LOC); // patch the jump instruction
continue;
}
@@ -1241,7 +1216,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
I++;
// this is a label!
label_t *slot;
- int j;
+ uint32_t j;
for (j = 0; j < 1 << 10; j++) {
if (storage.labels[ j ].name.ref != NULL) {
if (storage.labels[ j ].name.len == name.len
@@ -1271,8 +1246,8 @@ string _ir2(string I, string filepath, ir2_storage storage) {
checkskip('(', "expected open paren after alphanumeric word (assuming this is a blob)");
space;
- slice_t arguments[ 1 << 7 ];
- int arg_count = 0;
+ slice_t arguments[ 1 << 7 ];
+ uint32_t arg_count = 0;
string fail_I = I;
@@ -1283,7 +1258,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
arguments[ arg_count ].len = 0;
arguments[ arg_count ].ref = I;
- int dep = 0;
+ uint32_t dep = 0;
while (dep != 0 || *I != ']') {
if (*I == '[') dep++;
if (*I == ']') dep--;
@@ -1320,7 +1295,7 @@ string _ir2(string I, string filepath, ir2_storage storage) {
// done reading blob! check it and parse macro :)
// find index
- int i;
+ uint32_t i;
for (i = 0; i < (1 << 9); i++) {
macro_t cur = storage.macros[ i ];
if (cur.data.key.len != name.len) continue;
@@ -1337,12 +1312,12 @@ string _ir2(string I, string filepath, ir2_storage storage) {
storage.macros[ i ].arg_count,
arg_count);
}
- slice_t target = storage.macros[ i ].data.value;
- string N = target.ref;
- string oldN = N;
- memslice_t new = { target.len, malloc(target.len) };
- int used = 0;
- bool needs_scan = true;
+ slice_t target = storage.macros[ i ].data.value;
+ string N = target.ref;
+ string oldN = N;
+ memslice_t new = { target.len, malloc(target.len) };
+ uint32_t used = 0;
+ bool needs_scan = true;
while (needs_scan) {
needs_scan = false;
@@ -1352,8 +1327,8 @@ string _ir2(string I, string filepath, ir2_storage storage) {
if (*N == '/' && isdigit(N[ 1 ])) {
N++;
- string old = N - 1;
- int index = strtol(N, &N, 10);
+ string old = N - 1;
+ uint32_t index = strtol(N, &N, 10);
if (index > arg_count) {
N--;
@@ -1404,23 +1379,27 @@ string _ir2(string I, string filepath, ir2_storage storage) {
if (!varqual(*I)) run_err(I, "expected memory index or variable after dereference");
}
- string starting_qual = I;
- int mem_index = scanvar();
+ string starting_qual = I;
+ uint32_t mem_index = scanvar();
space;
if (*I == '-' && I[ 1 ] == '-') { // decrement
I += 2;
space;
checkskip(';', "expected semicolon");
- mem_in_a(mem_index);
- if (lhs_deref) deref_a();
- op(acc, 1);
- op(u2b);
- op(sub);
- swap();
- if (lhs_deref) mem_in_a(mem_index);
- else { imm(mem_index); }
- store();
+
+ if (lhs_deref) {
+ // *spare = *mem;
+ // *spare = **spare;
+ // *spare--;
+ // *mem = *spare;
+ write(getderev(mov, mem_index, SPARES_LOC));
+ write(get(dmv, SPARES_LOC, 0));
+ write(get(dec, SPARES_LOC, 0));
+ write(getde(mov, mem_index, SPARES_LOC));
+ } else {
+ write(get(dec, mem_index, 0));
+ }
continue;
}
@@ -1429,15 +1408,19 @@ string _ir2(string I, string filepath, ir2_storage storage) {
I += 2;
space;
checkskip(';', "expected semicolon");
- mem_in_a(mem_index);
- if (lhs_deref) deref_a();
- op(acc, 1);
- op(u2b);
- op(add);
- swap();
- if (lhs_deref) mem_in_a(mem_index);
- else { imm(mem_index); }
- store();
+
+ if (lhs_deref) {
+ // *spare = *mem;
+ // *spare = **spare;
+ // *spare++;
+ // *mem = *spare;
+ write(getderev(mov, mem_index, SPARES_LOC));
+ write(get(dmv, SPARES_LOC, 0));
+ write(get(inc, SPARES_LOC, 0));
+ write(getde(mov, mem_index, SPARES_LOC));
+ } else {
+ write(get(inc, mem_index, 0));
+ }
continue;
}
@@ -1448,11 +1431,11 @@ string _ir2(string I, string filepath, ir2_storage storage) {
checkskip('=', "expected assigment after memory blob (hint: only +-&! are supported)");
space;
- if (mem_index == 7 && !has_jump_warned) {
- has_jump_warned = true;
- printf("\nwarn: writing to memory index 7 is equivalent to a jump\n");
- printf(" if this behavior is intended, use the jump blob instead.\n\n");
- }
+ // if (mem_index == 7 && !has_jump_warned) {
+ // has_jump_warned = true;
+ // printf("\nwarn: writing to memory index 7 is equivalent to a jump\n");
+ // printf(" if this behavior is intended, use the jump blob instead.\n\n");
+ // }
if (*I == '*' || varqual(*I)) {
bool rhs_deref = *I == '*';
@@ -1464,75 +1447,89 @@ string _ir2(string I, string filepath, ir2_storage storage) {
}
if ((lhs_deref || rhs_deref) && extra_op != '=') {
- run_err(expr_I, "dereferencing is not possible with arithmetic. (i was lazy)");
+ run_err(
+ expr_I, "dereferencing is not possible with arithmetic. (moon is lazy)");
}
- int mem2_index = scanvar();
+ uint32_t mem2_index = scanvar();
space;
if (extra_op == '=') {
if (lhs_deref) {
- // m[m[a]] = m[b]
- // m[m[a]] = m[m[b]]
- mem_in_a(mem2_index);
- if (rhs_deref) deref_a();
- swap();
- mem_in_a(mem_index);
- store();
+ // **a = *b;
+ // **a = **b;
+ write(getderev(mov, mem2_index, SPARES_LOC));
+ if (rhs_deref) write(getde(dmv, SPARES_LOC, 0));
+ write(getde(ddm, mem_index, SPARES_LOC));
} else {
if (rhs_deref) {
- // m[a] = m[m[b]]
- mem_in_a(mem2_index);
- deref_a();
- a_in_mem(mem_index);
+ // *a = **b
+ write(getderev(mov, mem2_index, SPARES_LOC));
+ write(getde(dmv, SPARES_LOC, 0));
+ write(getde(mov, mem_index, SPARES_LOC));
} else {
- // m[a] = m[b]
+ // *a = *b
mov_mem_mem(mem_index, mem2_index);
}
}
} else if (extra_op == '+') {
- perform_op(add);
+ if (mem2_index > UINT16_MAX) {
+ write(getderev(mov, mem2_index, SPARES_LOC));
+ write(getde(add, mem_index, SPARES_LOC));
+ } else {
+ write(getde(add, mem_index, mem2_index));
+ }
} else if (extra_op == '-') {
- perform_op(sub);
+ if (mem2_index > UINT16_MAX) {
+ write(getderev(mov, mem2_index, SPARES_LOC));
+ write(getde(sub, mem_index, SPARES_LOC));
+ } else {
+ write(getde(sub, mem_index, mem2_index));
+ }
} else if (extra_op == '&') {
- perform_op(and);
+ if (mem2_index > UINT16_MAX) {
+ write(getderev(mov, mem2_index, SPARES_LOC));
+ write(getde(and, mem_index, SPARES_LOC));
+ } else {
+ write(getde(and, mem_index, mem2_index));
+ }
} else if (extra_op == '!') {
// @1 != @2; (@1 = !@2)
- mem_in_a(mem2_index);
- op(not);
- swap();
- imm(mem_index);
- store();
+ if (mem2_index > UINT16_MAX) {
+ write(getderev(mov, mem2_index, SPARES_LOC));
+ write(getde(mov, mem_index, SPARES_LOC));
+ write(get(not, mem_index, 0));
+ } else {
+ write(getde(mov, mem_index, mem2_index));
+ write(get(not, mem_index, 0));
+ }
}
} else {
- int imm = scanvalue();
+ uint32_t imm = scanvalue();
if (extra_op == '=') {
imm_in_mem(mem_index, imm);
} else if (extra_op == '+') {
- imm(imm);
- swap();
- mem_in_a(mem_index);
- op(add);
- swap();
- imm(mem_index);
- store();
+ if (imm > UINT16_MAX) {
+ write(getrev(mov, imm, SPARES_LOC));
+ write(get(add, mem_index, SPARES_LOC));
+ } else {
+ write(get(add, mem_index, imm));
+ }
} else if (extra_op == '-') {
- imm(imm);
- swap();
- mem_in_a(mem_index);
- op(sub);
- swap();
- imm(mem_index);
- store();
+ if (imm > UINT16_MAX) {
+ write(getrev(mov, imm, SPARES_LOC));
+ write(get(sub, mem_index, SPARES_LOC));
+ } else {
+ write(get(sub, mem_index, imm));
+ }
} else if (extra_op == '&') {
- imm(imm);
- swap();
- mem_in_a(mem_index);
- op(and);
- swap();
- imm(mem_index);
- store();
+ if (imm > UINT16_MAX) {
+ write(getrev(mov, imm, SPARES_LOC));
+ write(get(and, mem_index, SPARES_LOC));
+ } else {
+ write(get(and, mem_index, imm));
+ }
} else if (extra_op == '!') {
// @1 != 5; (@1 = !5;)
imm_in_mem(mem_index, !imm);
@@ -1551,11 +1548,11 @@ string _ir2(string I, string filepath, ir2_storage storage) {
return I;
}
-ir2(string I, string filepath, int *assembly_target) {
- const int macros_n = 1 << 9;
- const int labels_n = 1 << 10;
- const int vars_n = 1 << 11;
- const int fwd_n = 1 << 10;
+ir2(string I, string filepath, pu3_inst_t *assembly_target) {
+ const uint32_t macros_n = 1 << 9;
+ const uint32_t labels_n = 1 << 10;
+ const uint32_t vars_n = 1 << 11;
+ const uint32_t fwd_n = 1 << 10;
macro_t *macros = calloc(macros_n, sizeof(*macros));
label_t *labels = calloc(labels_n, sizeof(*labels));
@@ -1577,13 +1574,13 @@ ir2(string I, string filepath, int *assembly_target) {
label_delegated_t cur = *curf++;
// find label
- int j;
+ uint32_t j;
for (j = 0; j < labels_n; j++) {
label_t clab = labels[ j ];
if (clab.name.len == cur.name.len
&& strncmp(clab.name.ref, cur.name.ref, cur.name.len) == 0) {
// found it!
- *cur.replace_location = clab.location;
+ set_dest_u32(*cur.replace_location, clab.location);
goto REP_DONE;
}
}
@@ -1600,164 +1597,68 @@ ir2(string I, string filepath, int *assembly_target) {
free(forward_refs);
}
-string op_names[] = { "hlt", "imm", "lod", "str", "swp", "add", "sub", "and", "not", "acc",
- "a2u", "u2a", "b2u", "u2b", "nop", "cb1", "cb2", "cb3", "cb4" };
-
-unsigned long long rdtsc(void) {
-#ifndef PU2_NO_ASM
- unsigned hi, lo;
- __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
- return ((unsigned long long) hi << 32) | lo;
-#else
- return 0;
-#endif
-}
-
-#ifndef PU2_BAD_CLOCK
-clock_t ntime() {
- struct timespec t;
- clock_gettime(CLOCK_MONOTONIC_RAW, &t);
-
- return t.tv_nsec + t.tv_sec * 1e9;
-}
-#else
-clock_t ntime() {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return tv.tv_sec * 1000000000 + tv.tv_usec * 1000;
-}
-#endif
-
-// bench: measure using clock()
-double bench_cycle(int instr, int *m, int mem_size) {
- int i;
- for (i = 16; i < S - 2; i += 2) {
- m[ i ] = instr;
- m[ i + 1 ] = 10;
- }
- m[ S - 2 ] = 0;
- m[ S - 1 ] = 0;
-
- m[ 7 ] = 16;
- c = 0;
-
- clock_t start = ntime();
- int wstart = rdtsc();
- pu2(-1, m, mem_size);
- int wend = rdtsc();
- clock_t end = ntime();
-
- double nanoseconds = (end - start);
- double inst_count = (double) m[ 7 ] / 2;
- double insts_per_ns = inst_count / nanoseconds;
- double insts_per_s = insts_per_ns * 1e9;
-
- printf(
- "%-8s | time: %.3fms | insts: %.0f (%li real) | ips: %.3fM inst/s\n",
- op_names[ instr ],
- nanoseconds / 1000000,
- inst_count,
- end - start,
- insts_per_ns * 1e3);
-
- return insts_per_s / 1e6; // return M inst/s
-}
-
-// bench2: measure using rdtsc
-double bench2_cycle(int instr, int *m, int mem_size) {
- unsigned long long start, end;
- double vminst_count, cpu_cycles;
- int i;
- for (i = 16; i < S - 2; i += 2) {
- m[ i ] = instr;
- m[ i + 1 ] = 5;
- }
- m[ S - 2 ] = 0;
- m[ S - 1 ] = 0;
- m[ 7 ] = 16;
- c = 0;
- start = rdtsc();
- pu2(-1, m, mem_size);
- end = rdtsc();
- cpu_cycles = (double) (end - start);
- vminst_count = (double) m[ 7 ] / 2;
- double cycles_per_inst = cpu_cycles / vminst_count;
-
- printf(
- "%-6s | cycles/inst: %8.3f | cycles: %14.0f | insts: %12.0f\n",
- op_names[ instr ],
- cycles_per_inst,
- cpu_cycles,
- vminst_count);
- return cycles_per_inst;
-}
-
-sleep_nano(int nanoseconds) {
- struct timespec req = { 0 };
- req.tv_sec = nanoseconds / 1000000000L; // Whole seconds
- req.tv_nsec = nanoseconds % 1000000000L; // Remaining nanoseconds
-
- // nanosleep might be interrupted, so loop until it completes
- while (nanosleep(&req, &req) == -1 && errno == EINTR) {
- continue; // Continue with remaining time if interrupted
- }
-}
-
-#ifdef PU2_OLD_CLANG
- #define inline() __attribute__((always_inline))
-#else
- #define inline() [[clang::always_inline]]
-#endif
+volatile long out;
-inline() sleep_micro(int microseconds) { sleep_nano(microseconds * 1e3); }
-inline() sleep_milli(int milliseconds) { sleep_nano(milliseconds * 1e6); }
-
-// benchmark: run target for all opcodes and print summary
-benchmark(double (*target)(int, int *, int), const char *mode_label, int *m, int mem_size) {
- double results[ 19 ];
- double sum = 0;
- int count = 0;
- int i;
-
- printf("\n=== pu2 benchmark (%s) ===\n", mode_label);
- printf("op | result details\n");
- printf("---------------------------------------------\n");
-
- for (i = 1; i < 19; i++) {
- // printf("running: %s\n", op_names[ i ]);
- results[ i ] = target(i, m, mem_size);
- sum += results[ i ];
- count++;
+void disassemble_pu3_inst(pu3_inst_t inst) {
+ byte op = get_scroll_byte(inst);
+ if (op > 15) {
+ printf("\033[1;31minvalid op\033[0m\n");
+ return;
}
- sum /= count;
-
- printf("---------------------------------------------\n");
-
- int start = rdtsc();
- sleep_milli(100);
- int end = rdtsc();
-
- double clock_speed_mhz = ((end - start) / 1e6) * 10;
-
- if (strcmp(mode_label, "time") == 0) {
- // printf("average : %.3f M inst/s\n", sum);
- printf("cpu clock : ~%.3f MHz (measured via rdtsc & msleep(100))\n", clock_speed_mhz);
- printf("vm clock (i/s) : %.3fMHz (ipn, higher is better)\n", sum);
- // printf("estimated : %.3f cycles per instruction (cpi, lower is better)\n",
- // clock_speed_mhz / sum);
- } else {
- // mode_label == "rdtsc"
- printf("average cycles/inst : %.3f cycles\n", sum);
- // printf("cpu clock : ~%.3f MHz (measured via rdtsc & msleep(100))\n",
- // clock_speed_mhz);
- printf("estimated ipc : %.3f (1 / cycles_per_inst, higher is better)\n", 1.0 / sum);
- // printf("estimated cpi : %.3f (cycles_per_inst, lower is better)\n", sum);
+ byte spare = get_spare(inst);
+ bool swap = (spare & 0x80);
+ bool deref = (spare & 0x40);
+ uint32_t dest = get_dest_u32(inst);
+ uint16_t data = get_data_u16(inst);
+ uint32_t lhs = swap ? data : (uint32_t) dest;
+ uint32_t rhs = swap ? (uint32_t) dest : data;
+
+ const char *name = op_names[ op ];
+ printf("\033[1;32m%-3s\033[0m ", name);
+
+ switch (op) {
+ case 0: // nop
+ if (deref) printf("\033[1;33m[\033[0m");
+ printf("\033[1;34m%i\033[0m", data);
+ if (deref) printf("\033[1;33m]\033[0m");
+ break;
+ case 1: // hlt
+ break;
+ case 5:
+ case 6:
+ case 11: // inc, dec, not
+ printf("\033[1;33m[\033[0m\033[1;34m%i\033[0m\033[1;33m]\033[0m", dest);
+ break;
+ case 12: // jmp
+ printf("\033[1;34m%i\033[0m", dest);
+ break;
+ case 14: // dmv
+ printf("\033[1;33m[\033[0m\033[1;34m%i\033[0m\033[1;33m]\033[0m", lhs);
+ break;
+ case 13: // jnz
+ printf("\033[1;34m%i\033[0m, ", lhs);
+ if (deref) printf("\033[1;33m[\033[0m");
+ printf("\033[1;34m%i\033[0m", rhs);
+ if (deref) printf("\033[1;33m]\033[0m");
+ break;
+ case 15: // ddm
+ printf("\033[1;33m[[\033[0m\033[1;34m%i\033[0m\033[1;33m]]\033[0m, ", lhs);
+ printf("\033[1;33m[\033[0m");
+ if (deref) printf("\033[1;33m[\033[0m");
+ printf("\033[1;34m%i\033[0m", rhs);
+ if (deref) printf("\033[1;33m]\033[0m");
+ printf("\033[1;33m]\033[0m");
+ break;
+ default: // mov, add, sub, mul, lsh, rsh, and
+ printf("\033[1;33m[\033[0m\033[1;34m%i\033[0m\033[1;33m]\033[0m, ", lhs);
+ if (deref) printf("\033[1;33m[\033[0m");
+ printf("\033[1;34m%i\033[0m", rhs);
+ if (deref) printf("\033[1;33m]\033[0m");
+ break;
}
- printf("=== end benchmark ===\n\n");
+ printf("\n");
}
-volatile long out;
-
main(int argc, char **argv) {
if (argc == 1) {
printf(
@@ -1769,70 +1670,50 @@ main(int argc, char **argv) {
return 1;
}
- int *assembly_target = calloc(S, sizeof(int));
+ pu3_ctx *__ctx = init_pu3();
+ pu3_ctx ctx = *__ctx;
if (strcmp(argv[ 1 ], "benchmark") == 0) {
- int *m = init_pu2();
- int mem_size = S;
- benchmark(bench_cycle, "time", m, mem_size);
-
- const long N = S / 2; // printably the same insts you report
- long sum = 0;
- unsigned aux;
- unsigned long long t0 = rdtsc();
- int C;
- for (C = 0; C < N; ++C) {
- sum += 1;
- __asm__ volatile("");
- }
- unsigned long long t1 = rdtsc();
- out = sum; // single volatile write to make sum observable
- printf(
- "(absolute max) N=%llu cycles=%llu cycles/iter=%.6f\n",
- (unsigned long long) N,
- (unsigned long long) (t1 - t0),
- (t1 - t0) / (double) N);
- // benchmark(bench2_cycle, "rdtsc");
+ pu3_benchmark();
exit(0);
}
- char *filename = argv[ 1 ];
- int file_size;
- string contents = read_file(filename, &file_size);
+ char *filename = argv[ 1 ];
+ uint32_t file_size;
+ string contents = read_file(filename, &file_size);
if (contents == NULL) {
perror("unable to open file");
exit(1);
}
- const int starting_code_ptr = init_ir2(assembly_target, S);
+ const uint32_t starting_code_ptr = init_ir2(ctx.memory.memory_u64, S);
- int o_size;
- long before = ntime();
- long cycles_bef = rdtsc();
- ir2(contents, filename, assembly_target);
- long cycles_aft = rdtsc();
- long after = ntime();
- assembly_target[ 7 ] = starting_code_ptr;
+ uint32_t o_size;
+ long before = ntime();
+ // long cycles_bef = rdtsc();
+ ir2(contents, filename, ctx.memory.memory_u64);
+ // long cycles_aft = rdtsc();
+ long after = ntime();
+ *ctx.pc = starting_code_ptr;
- /*int j = 0;
- for(j = 0; j < 64; j++) {
- printf("%i: %i %i\n", j, m[5000+j], m[5001+j]);
- j++;
- }*/
+ // uint32_t j = 0;
+ // for(j = 0; j < 32; j++) {
+ // printf("%i: ", j);
+ // disassemble_pu3_inst(ctx.memory.memory_u64[starting_code_ptr + j]);
+ // }
- // printf("assembly took %i milliseconds\n", (after - before)/1000);
+ printf("assembly took %li milliseconds\n", (after - before) / 1000);
free(contents);
- // int res_size = code - &m[ 4000 ];
+ // uint32_t res_size = code - &m[ 4000 ];
// run the kernel (ring zero) forever (time slice -1)
- int mem_size = S;
+ uint32_t mem_size = S;
// pid zero - kernel
processes[ 0 ]
- = (emu_process) { .mem_size = S,
- .memory = assembly_target,
+ = (emu_process) { .context = ctx,
.ring_level = 0,
.permissions = { .make_syscall = true, .spawn_process = true } };