optimizations
This commit is contained in:
parent
025acce1c6
commit
431d09656b
|
|
@ -24,10 +24,11 @@ u32 syscall(u32 id, u32 size, u32 mem_ptr) {
|
||||||
USED(size);
|
USED(size);
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case SYSCALL_CONSOLE_WRITE: {
|
case SYSCALL_CONSOLE_WRITE: {
|
||||||
u32 size = *(u32 *)(mem + mem_ptr);
|
u32 size_ptr = mem[mem_ptr];
|
||||||
u32 ptr = mem_ptr + 4;
|
u32 size = mem[size_ptr];
|
||||||
|
u8 *ptr = &mem[size_ptr + 4];
|
||||||
for (u32 i = 0; i < size; i++) {
|
for (u32 i = 0; i < size; i++) {
|
||||||
putchar(mem[ptr + i]);
|
putchar(*(ptr++));
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -77,7 +78,7 @@ void test_fibonacci() {
|
||||||
code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 35);
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 0, 35);
|
||||||
code[cp++] = ENCODE_B(OP_PUSH, 0, 0);
|
code[cp++] = ENCODE_B(OP_PUSH, 0, 0);
|
||||||
code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, fib);
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 1, fib);
|
||||||
code[cp++] = ENCODE_A(OP_CALL, 1, 9, 2);
|
code[cp++] = ENCODE_A(OP_CALL, 1, (9 * 4), (2 * 4));
|
||||||
/* print */
|
/* print */
|
||||||
code[cp++] = ENCODE_A(OP_INT_TO_STR, 3, 2, 0);
|
code[cp++] = ENCODE_A(OP_INT_TO_STR, 3, 2, 0);
|
||||||
code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_CONSOLE_WRITE, 1, 3);
|
code[cp++] = ENCODE_A(OP_SYSCALL, SYSCALL_CONSOLE_WRITE, 1, 3);
|
||||||
|
|
@ -91,11 +92,11 @@ void test_fibonacci() {
|
||||||
code[cp++] = ENCODE_B(OP_LOAD_IMM, 3, 2);
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 3, 2);
|
||||||
code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3);
|
code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3);
|
||||||
code[cp++] = ENCODE_B(OP_PUSH, 4, 0);
|
code[cp++] = ENCODE_B(OP_PUSH, 4, 0);
|
||||||
code[cp++] = ENCODE_A(OP_CALL, 8, 9, 5);
|
code[cp++] = ENCODE_A(OP_CALL, 8, (9 * 4), (5 * 4));
|
||||||
code[cp++] = ENCODE_B(OP_LOAD_IMM, 3, 1);
|
code[cp++] = ENCODE_B(OP_LOAD_IMM, 3, 1);
|
||||||
code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3);
|
code[cp++] = ENCODE_A(OP_SUB_INT, 4, 0, 3);
|
||||||
code[cp++] = ENCODE_B(OP_PUSH, 4, 0);
|
code[cp++] = ENCODE_B(OP_PUSH, 4, 0);
|
||||||
code[cp++] = ENCODE_A(OP_CALL, 8, 9, 6);
|
code[cp++] = ENCODE_A(OP_CALL, 8, (9 * 4), (6 * 4));
|
||||||
code[cp++] = ENCODE_A(OP_ADD_INT, 7, 6, 5);
|
code[cp++] = ENCODE_A(OP_ADD_INT, 7, 6, 5);
|
||||||
code[cp++] = ENCODE_B(OP_RETURN, 7, 0);
|
code[cp++] = ENCODE_B(OP_RETURN, 7, 0);
|
||||||
code[cp++] = ENCODE_B(OP_RETURN, 0, 0);
|
code[cp++] = ENCODE_B(OP_RETURN, 0, 0);
|
||||||
|
|
|
||||||
13
vm/libc.c
13
vm/libc.c
|
|
@ -1,10 +1,15 @@
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
|
|
||||||
void mcpy(u8 *to, const u8 *from, u32 length) {
|
void mcpy(void *to, void *from, u32 length) {
|
||||||
u32 i;
|
u32 i = 0;
|
||||||
|
u8 *src, *dest;
|
||||||
if (to == nil || from == nil) return;
|
if (to == nil || from == nil) return;
|
||||||
for (i = 0; i < length; i++) {
|
|
||||||
to[i] = from[i];
|
src = (u8 *)from;
|
||||||
|
dest = (u8 *)to;
|
||||||
|
|
||||||
|
while (length > (i++)) {
|
||||||
|
*(dest++) = *(src++);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ typedef float f32;
|
||||||
#define FLOAT_TO_REAL(v) (((i32)(v)) * 65536.0f)
|
#define FLOAT_TO_REAL(v) (((i32)(v)) * 65536.0f)
|
||||||
#define REAL_TO_FLOAT(v) (((f32)(v)) / 65536.0f)
|
#define REAL_TO_FLOAT(v) (((f32)(v)) / 65536.0f)
|
||||||
|
|
||||||
void mcpy(u8 *dest, const u8 *src, u32 n);
|
void mcpy(void *dest, void *src, u32 n);
|
||||||
i32 scpy(char* to, const char *from, u32 length);
|
i32 scpy(char* to, const char *from, u32 length);
|
||||||
bool seq(const char *s1, const char *s2);
|
bool seq(const char *s1, const char *s2);
|
||||||
bool sleq(const char *s1, const char *s2, u32 length);
|
bool sleq(const char *s1, const char *s2, u32 length);
|
||||||
|
|
|
||||||
59
vm/vm.c
59
vm/vm.c
|
|
@ -16,16 +16,14 @@ u8 *mem; /* memory */
|
||||||
#define MIN_INT32 -2147483648
|
#define MIN_INT32 -2147483648
|
||||||
const char radix_set[11] = "0123456789";
|
const char radix_set[11] = "0123456789";
|
||||||
|
|
||||||
u32 str_alloc(const char *str, u32 length) {
|
u32 str_alloc(char *str, u32 length) {
|
||||||
u32 str_addr = mp;
|
u32 str_addr = mp;
|
||||||
u32 i = 0;
|
u8 *ptr = &mem[mp];
|
||||||
mp += 4;
|
mcpy(ptr, &length, sizeof(u32));
|
||||||
while (i < length) {
|
ptr += 4;
|
||||||
mem[mp++] = str[i++];
|
mcpy(ptr, str, length);
|
||||||
}
|
ptr[length] = '\0';
|
||||||
mem[mp++] = '\0';
|
mp += 4 + length + 1;
|
||||||
|
|
||||||
WRITE_U32(str_addr, length);
|
|
||||||
return str_addr;
|
return str_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,37 +44,37 @@ bool step_vm() {
|
||||||
/* function to jump to */
|
/* function to jump to */
|
||||||
u32 fn_ptr = locals[dest];
|
u32 fn_ptr = locals[dest];
|
||||||
/* get mp in 'global indexing mode' */
|
/* get mp in 'global indexing mode' */
|
||||||
u32 gmp = mp / 4;
|
u32 *header = &globals[mp / 4];
|
||||||
/* reset child locals counter */
|
/* reset child locals counter */
|
||||||
lc = 0;
|
lc = 0;
|
||||||
/* push parents frame value to reset the heap to */
|
/* push parents frame value to reset the heap to */
|
||||||
globals[gmp] = fp;
|
(*header++) = fp;
|
||||||
/* push return address to child frame */
|
/* push return address to child frame */
|
||||||
globals[gmp + 1] = pc;
|
(*header++) = pc;
|
||||||
/* push local address to return the value to */
|
/* push local address to return the value to */
|
||||||
globals[gmp + 2] = fp + (src2 * 4);
|
(*header++) = fp + src2;
|
||||||
/* increase the mp to new size */
|
/* increase the mp to new size */
|
||||||
mp += FRAME_HEADER_SIZE;
|
mp += FRAME_HEADER_SIZE;
|
||||||
/* now set the frame pointer, where the locals start */
|
/* now set the frame pointer, where the locals start */
|
||||||
fp = mp;
|
fp = mp;
|
||||||
/* move mp forward by count many locals */
|
/* move mp forward by count many locals */
|
||||||
mp += (4 * src1);
|
mp += src1;
|
||||||
/* jump to dest_ptr */
|
/* jump to dest_ptr */
|
||||||
pc = fn_ptr;
|
pc = fn_ptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_RETURN: {
|
case OP_RETURN: {
|
||||||
DECODE_B(instruction)
|
DECODE_B(instruction)
|
||||||
u32 i, size = 0;
|
u32 size = 0;
|
||||||
u32 return_value = locals[dest];
|
u32 return_value = locals[dest];
|
||||||
bool is_ptr = (((u32)(1)) << 15) & imm;
|
bool is_ptr = (((u32)(1)) << 15) & imm;
|
||||||
bool replaces_value = (((u32)(1)) << 14) & imm;
|
bool replaces_value = (((u32)(1)) << 14) & imm;
|
||||||
|
|
||||||
/* reset mp to saved mp, use header size to get "real" start of frame */
|
/* reset mp to saved mp, use header size to get "real" start of frame */
|
||||||
u32 frame_start = (fp / 4) - 3;
|
u32 *frame_start = &globals[(fp / 4) - 3];
|
||||||
u32 parent_fp = globals[frame_start];
|
u32 parent_fp = *frame_start++;
|
||||||
u32 return_address = globals[frame_start + 1];
|
u32 return_address = *frame_start++;
|
||||||
u32 parent_local_return_address = globals[frame_start + 2];
|
u32 parent_local_return_address = *frame_start++;
|
||||||
|
|
||||||
USED(replaces_value);
|
USED(replaces_value);
|
||||||
/* reset memory to parents end of memory */
|
/* reset memory to parents end of memory */
|
||||||
|
|
@ -86,18 +84,15 @@ bool step_vm() {
|
||||||
|
|
||||||
if (is_ptr) {
|
if (is_ptr) {
|
||||||
/* copy value to end of mp if it is a pointer */
|
/* copy value to end of mp if it is a pointer */
|
||||||
WRITE_U32(parent_local_return_address, mp);
|
globals[parent_local_return_address/4] = mp;
|
||||||
size = READ_U32(return_value);
|
size = globals[return_value/4];
|
||||||
WRITE_U32(mp, size);
|
globals[mp/4] = size;
|
||||||
mp += 4;
|
mp += 4;
|
||||||
for (i = 0; i < size; i++) {
|
mcpy(&mem[mp], &mem[return_value], size);
|
||||||
u8 value = READ_U8(return_value + i);
|
mp += size;
|
||||||
WRITE_U8(mp, value);
|
|
||||||
mp++;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* otherwise just write the return value to its location */
|
/* otherwise just write the return value to its location */
|
||||||
WRITE_U32(parent_local_return_address, return_value);
|
mcpy(&mem[parent_local_return_address], &return_value, sizeof(u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* jump to parent frame */
|
/* jump to parent frame */
|
||||||
|
|
@ -120,7 +115,8 @@ bool step_vm() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_POP: {
|
case OP_POP: {
|
||||||
DECODE_C(instruction)
|
DECODE_B(instruction)
|
||||||
|
USED(dest);
|
||||||
USED(imm);
|
USED(imm);
|
||||||
mp -= 4;
|
mp -= 4;
|
||||||
lc--;
|
lc--;
|
||||||
|
|
@ -459,7 +455,10 @@ bool step_vm() {
|
||||||
MATH_OP_NO_CAST(^);
|
MATH_OP_NO_CAST(^);
|
||||||
}
|
}
|
||||||
case OP_JMP_IMM: {
|
case OP_JMP_IMM: {
|
||||||
DECODE_C(instruction)
|
u32 imm = (((u32)code[(pc) + 3] << 24) |
|
||||||
|
((u32)code[(pc) + 2] << 16) |
|
||||||
|
((u32)code[(pc) + 1] << 8) |
|
||||||
|
((u32)code[(pc)]));
|
||||||
pc = imm;
|
pc = imm;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue