cleanup / prepwork for assembler.

This commit is contained in:
zongor 2025-09-20 12:49:01 -07:00
parent 2d72240652
commit 922959191d
10 changed files with 234 additions and 211 deletions

View File

@ -16,4 +16,7 @@ typedef int32_t i32;
#define USED(x) ((void)(x)) #define USED(x) ((void)(x))
#define AS_INT(v) ((i32)(v))
#define AS_UINT(v) ((u32)(v))
#endif #endif

View File

@ -50,9 +50,11 @@ typedef enum {
OP_STRLEN, /* strl : dest = length of str at src1 ptr */ OP_STRLEN, /* strl : dest = length of str at src1 ptr */
OP_STREQ, /* steq : dest = src1 ptr string == src2 ptr string */ OP_STREQ, /* steq : dest = src1 ptr string == src2 ptr string */
OP_STRCAT, /* scat : dest = ptr of src1 ptr string + src2 ptr string */ OP_STRCAT, /* scat : dest = ptr of src1 ptr string + src2 ptr string */
OP_STR_GET_CHAR, /* sgch : dest = ptr of src1 ptr string, src2 index of string */ OP_STR_GET_CHAR, /* sgch : dest = ptr of src1 ptr string, src2 index of string
*/
OP_STR_FIND_CHAR, /* sfch : dest = ptr of src1 ptr string, src2 uint8 char */ OP_STR_FIND_CHAR, /* sfch : dest = ptr of src1 ptr string, src2 uint8 char */
OP_STR_SLICE, /* ssli : dest = ptr of src1 ptr string, src2 start index, src3 end index */ OP_STR_SLICE, /* ssli : dest = ptr of src1 ptr string, src2 start index, src3
end index */
OP_INT_TO_STRING, /* itos : dest = src1 as str */ OP_INT_TO_STRING, /* itos : dest = src1 as str */
OP_UINT_TO_STRING, /* utos : dest = src1 as str */ OP_UINT_TO_STRING, /* utos : dest = src1 as str */
OP_REAL_TO_STRING, /* rtos : dest = src1 as str */ OP_REAL_TO_STRING, /* rtos : dest = src1 as str */
@ -120,17 +122,9 @@ typedef struct vm_s {
u8 memory[MEMORY_SIZE]; /* memory block */ u8 memory[MEMORY_SIZE]; /* memory block */
} VM; } VM;
#define AS_INT(v) ((i32)(v))
#define AS_UINT(v) ((u32)(v))
#define AS_FIXED(v) ((float)(i32)(v) / 65536.0f)
#define TO_FIXED(f) ((u32)((i32)( \
((f) >= 0.0f) ? ((f) * 65536.0f + 0.5f) : ((f) * 65536.0f - 0.5f) \
)))
#define read_u8(vm, location, addr) ((vm)->location[addr]) #define read_u8(vm, location, addr) ((vm)->location[addr])
#define read_u16(vm, location, addr) \ #define read_u16(vm, location, addr) \
(((uint16_t)(vm)->location[(addr)] << 8) | \ (((u16)(vm)->location[(addr)] << 8) | ((u16)(vm)->location[(addr) + 1]))
((uint16_t)(vm)->location[(addr) + 1]))
#define read_u32(vm, location, addr) \ #define read_u32(vm, location, addr) \
(((u32)(vm)->location[(addr)] << 24) | \ (((u32)(vm)->location[(addr)] << 24) | \
((u32)(vm)->location[(addr) + 1] << 16) | \ ((u32)(vm)->location[(addr) + 1] << 16) | \

104
src/str.c
View File

@ -42,3 +42,107 @@ u32 strnlen(const char *str, u32 max_len) {
} }
return i; return i;
} }
/* Static digit lookup table (0-9) */
const char digits[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
/* Writes decimal digits of 'value' backwards into 'buf_end' (inclusive),
stopping at 'buf_start'. Returns pointer to first written digit. */
char *write_digits_backwards(u32 value, char *buf_end, char *buf_start) {
char *p = buf_end;
if (value == 0) {
*--p = '0';
} else {
u32 num = value;
while (num && p > buf_start) {
*--p = digits[num % 10];
num /= 10;
}
}
return p;
}
void uint_to_string(u32 value, char *buffer) {
char temp[16];
char *start;
char *end = temp + sizeof(temp) - 1;
*end = '\0';
start = write_digits_backwards(value, end, temp);
strcopy(buffer, start, end - start + 1); /* +1 for null terminator */
}
void int_to_string(i32 value, char *buffer) {
char temp[17]; /* Extra space for '-' */
i32 negative = 0;
u32 abs_value;
char *end = temp + sizeof(temp) - 1;
*end = '\0';
if (value == (-2147483647 - 1)) { /* INT32_MIN */
strcopy(buffer, "-2147483648", 12);
return;
}
if (value == 0) {
*--end = '0';
} else {
if (value < 0) {
negative = 1;
abs_value = (u32)(-value);
} else {
abs_value = (u32)value;
}
end = write_digits_backwards(abs_value, end, temp);
if (negative) {
*--end = '-';
}
}
strcopy(buffer, end, temp + sizeof(temp) - end);
}
void fixed_to_string(i32 value, char *buffer) {
char temp[32];
i32 negative;
u32 int_part;
u32 frac_part, frac_digits;
char *end = temp + sizeof(temp) - 1;
*end = '\0';
negative = 0;
if (value < 0) {
negative = 1;
value = -value;
}
int_part = AS_UINT(value >> 16);
frac_part = AS_UINT(value & 0xFFFF);
/* Convert fractional part to 5 decimal digits */
frac_digits = (frac_part * 100000U) / 65536U;
/* Trim trailing zeros */
while (frac_digits > 0 && frac_digits % 10 == 0) {
frac_digits /= 10;
}
if (frac_digits > 0) {
end = write_digits_backwards(frac_digits, end, temp);
*--end = '.';
}
if (int_part == 0 && frac_digits == 0) {
*--end = '0';
} else {
end = write_digits_backwards(int_part, end, temp);
}
if (negative) {
*--end = '-';
}
strcopy(buffer, end, temp + sizeof(temp) - end);
}

View File

@ -6,5 +6,8 @@
i32 strcopy(char* to, const char *from, u32 length); i32 strcopy(char* to, const char *from, u32 length);
u32 strlen(const char* str); u32 strlen(const char* str);
bool streq(const char *s1, const char *s2); bool streq(const char *s1, const char *s2);
char *write_digits_backwards(u32 value, char *buf_end, char *buf_start);
void int_to_string(i32 value, char *buffer);
void fixed_to_string(i32 value, char *buffer);
#endif #endif

View File

@ -48,8 +48,7 @@ bool compile_internal_test(const char *filename, VM *vm) {
bool test_simple_compile(VM *vm) { bool test_simple_compile(VM *vm) {
u32 ptr; u32 ptr;
u32 newline_addr = /*u32 newline_addr = str_alloc(vm, &vm->frames[vm->fp], "\n", 2);*/
str_alloc(vm, &vm->frames[vm->fp], "\n", 2);
u32 terminal_path_addr = u32 terminal_path_addr =
str_alloc(vm, &vm->frames[vm->fp], "/dev/term/0", 12); str_alloc(vm, &vm->frames[vm->fp], "/dev/term/0", 12);
vm->code[vm->cp++] = OP_LOAD; vm->code[vm->cp++] = OP_LOAD;

View File

@ -3,6 +3,11 @@
#include "opcodes.h" #include "opcodes.h"
#define AS_FIXED(v) ((float)(i32)(v) / 65536.0f)
#define TO_FIXED(f) ((u32)((i32)( \
((f) >= 0.0f) ? ((f) * 65536.0f + 0.5f) : ((f) * 65536.0f - 0.5f) \
)))
/* Test function type definition */ /* Test function type definition */
typedef bool (*TestFunction)(VM *vm); typedef bool (*TestFunction)(VM *vm);

103
src/vm.c
View File

@ -488,106 +488,3 @@ bool step_vm(VM *vm) {
} }
return false; /* something bad happened */ return false; /* something bad happened */
} }
/* Static digit lookup table (0-9) */
const char digits[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
/* Writes decimal digits of 'value' backwards into 'buf_end' (inclusive),
stopping at 'buf_start'. Returns pointer to first written digit. */
char *write_digits_backwards(u32 value, char *buf_end, char *buf_start) {
char *p = buf_end;
if (value == 0) {
*--p = '0';
} else {
u32 num = value;
while (num && p > buf_start) {
*--p = digits[num % 10];
num /= 10;
}
}
return p;
}
void uint_to_string(u32 value, char *buffer) {
char temp[16];
char *start;
char *end = temp + sizeof(temp) - 1;
*end = '\0';
start = write_digits_backwards(value, end, temp);
strcopy(buffer, start, end - start + 1); /* +1 for null terminator */
}
void int_to_string(i32 value, char *buffer) {
char temp[17]; /* Extra space for '-' */
i32 negative = 0;
u32 abs_value;
char *end = temp + sizeof(temp) - 1;
*end = '\0';
if (value == (-2147483647 - 1)) { /* INT32_MIN */
strcopy(buffer, "-2147483648", 12);
return;
}
if (value == 0) {
*--end = '0';
} else {
if (value < 0) {
negative = 1;
abs_value = (u32)(-value);
} else {
abs_value = (u32)value;
}
end = write_digits_backwards(abs_value, end, temp);
if (negative) {
*--end = '-';
}
}
strcopy(buffer, end, temp + sizeof(temp) - end);
}
void fixed_to_string(i32 value, char *buffer) {
char temp[32];
i32 negative;
u32 int_part;
u32 frac_part, frac_digits;
char *end = temp + sizeof(temp) - 1;
*end = '\0';
negative = 0;
if (value < 0) {
negative = 1;
value = -value;
}
int_part = AS_UINT(value >> 16);
frac_part = AS_UINT(value & 0xFFFF);
/* Convert fractional part to 5 decimal digits */
frac_digits = (frac_part * 100000U) / 65536U;
/* Trim trailing zeros */
while (frac_digits > 0 && frac_digits % 10 == 0) {
frac_digits /= 10;
}
if (frac_digits > 0) {
end = write_digits_backwards(frac_digits, end, temp);
*--end = '.';
}
if (int_part == 0 && frac_digits == 0) {
*--end = '0';
} else {
end = write_digits_backwards(int_part, end, temp);
}
if (negative) {
*--end = '-';
}
strcopy(buffer, end, temp + sizeof(temp) - end);
}

View File

@ -1,29 +1,34 @@
.text
main: main:
lodi $0 35 load $0 35
pshi $0 push $0
call &fib call &fib
popi $0 pop $0
itos $1 $0 itos $1 $0
puts $1 load $2, &terminal_str
slen $4, $3
sysc DEVICE_WRITE, 3, $2 ; print(sum.toS())
halt halt
fib: fib:
popi $0 popi $0
lodi $1 2 load $1 2
lodi $2 &base_case lodi $2 &base_case
jlti $2 $0 $1 jlti $2 $0 $1
lodi $2 2 load $2 2
subi $4 $0 $3 subi $4 $0 $3
pshi $4 push $4
call &fib call &fib
lodi $2 1 load $2 1
subi $4 $0 $3 subi $4 $0 $3
pshi $4 push $4
call &fib call &fib
popi $4 pop $4
popi $5 pop $5
addi $6 $5 $4 addi $6 $5 $4
pshi $6 push $6
retn retn
base_case: base_case:
pshi $0 push $0
retn retn
.data
terminal_str: "/dev/term/0"

View File

@ -1,5 +1,11 @@
.text
hello: hello:
"nuqneH 'u'?" load $1 &hello_str
puts &hello load $2, &terminal_str
slen $4, $3
sysc DEVICE_WRITE, 3, $2 ; print(sum.toS())
halt halt
.data
terminal_str: "/dev/term/0"
hello_str: "nuqneH 'u'?"

View File

@ -1,7 +1,14 @@
.text
main: main:
loadu $0 1 limm $0 1.0
loadu $1 2 limm $1 2.0
addu $2 $1 $0 addu $2 $1 $0
utos $3 $2 utos $3 $2
puts $3 load $2, &terminal_str
slen $4, $3
sysc DEVICE_WRITE, 3, $2 ; print(sum.toS())
halt halt
.data
terminal_str: "/dev/term/0"