diff options
Diffstat (limited to 'pu2/pu2.c')
| -rw-r--r-- | pu2/pu2.c | 905 |
1 files changed, 393 insertions, 512 deletions
@@ -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 } }; |
