remove temp code
This commit is contained in:
parent
f951b8a25e
commit
d482c8d814
202
src/vm/libc.c
202
src/vm/libc.c
|
|
@ -1,74 +1,16 @@
|
|||
#include "libc.h"
|
||||
|
||||
void memcopy(u8 *dest, const u8 *src, u32 n) {
|
||||
size_t i;
|
||||
size_t words;
|
||||
size_t bytes;
|
||||
size_t unroll;
|
||||
size_t remainder;
|
||||
u32 *d32;
|
||||
const u32 *s32;
|
||||
u8 *d8;
|
||||
const u8 *s8;
|
||||
void memcopy(void *to, void *from, u32 length) {
|
||||
u8 *src, *dest;
|
||||
if (to == nil || from == nil) return;
|
||||
|
||||
/* Fast path for small copies (common case) */
|
||||
if (n <= 8) {
|
||||
for (i = 0; i < n; i++) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check for word alignment (assuming 32-bit words) */
|
||||
if ((((size_t)dest) & 0x3) == 0 && (((size_t)src) & 0x3) == 0) {
|
||||
/* Both pointers are 4-byte aligned - copy by words */
|
||||
d32 = (u32 *)dest;
|
||||
s32 = (const u32 *)src;
|
||||
words = n / 4;
|
||||
bytes = n % 4;
|
||||
|
||||
/* Loop unrolling - 4x unroll for better performance */
|
||||
unroll = words / 4;
|
||||
remainder = words % 4;
|
||||
|
||||
for (i = 0; i < unroll; i++) {
|
||||
d32[0] = s32[0];
|
||||
d32[1] = s32[1];
|
||||
d32[2] = s32[2];
|
||||
d32[3] = s32[3];
|
||||
d32 += 4;
|
||||
s32 += 4;
|
||||
}
|
||||
|
||||
/* Handle remaining words */
|
||||
for (i = 0; i < remainder; i++) {
|
||||
*d32++ = *s32++;
|
||||
}
|
||||
|
||||
/* Handle trailing bytes */
|
||||
d8 = (u8 *)d32;
|
||||
s8 = (const u8 *)s32;
|
||||
for (i = 0; i < bytes; i++) {
|
||||
d8[i] = s8[i];
|
||||
}
|
||||
} else {
|
||||
/* Unaligned copy - byte by byte but with loop unrolling */
|
||||
unroll = n / 4;
|
||||
remainder = n % 4;
|
||||
|
||||
for (i = 0; i < unroll; i++) {
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[3] = src[3];
|
||||
dest += 4;
|
||||
src += 4;
|
||||
}
|
||||
|
||||
for (i = 0; i < remainder; i++) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
src = (u8 *)from;
|
||||
dest = (u8 *)to;
|
||||
|
||||
while (length-- > 0) {
|
||||
*(dest++) = *(src++);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
i32 strcopy(char *to, const char *from, u32 length) {
|
||||
|
|
@ -128,129 +70,3 @@ u32 strnlength(const char *str, u32 max_len) {
|
|||
}
|
||||
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 nat_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, original_frac_digits;
|
||||
char *end = temp + sizeof(temp) - 1;
|
||||
char *frac_start;
|
||||
*end = '\0';
|
||||
|
||||
negative = 0;
|
||||
if (value < 0) {
|
||||
negative = 1;
|
||||
value = -value;
|
||||
}
|
||||
|
||||
int_part = AS_NAT(value >> 16);
|
||||
frac_part = AS_NAT(value & 0xFFFF);
|
||||
|
||||
/* Convert fractional part to 5 decimal digits */
|
||||
original_frac_digits = (frac_part * 100000U) / 65536U;
|
||||
frac_digits = original_frac_digits;
|
||||
|
||||
if (frac_digits > 0) {
|
||||
/* Write fractional digits backwards */
|
||||
frac_start = write_digits_backwards(frac_digits, end, temp);
|
||||
|
||||
/* Remove trailing zeros by moving the start pointer */
|
||||
while (*(end - 1) == '0' && end > frac_start) {
|
||||
end--;
|
||||
}
|
||||
|
||||
/* If all fractional digits were zeros after removing trailing zeros,
|
||||
we need to add back one zero to represent the .0 */
|
||||
if (end == frac_start) {
|
||||
*--end = '0';
|
||||
}
|
||||
|
||||
/* Add decimal point */
|
||||
*--end = '.';
|
||||
} else if (frac_part > 0) {
|
||||
/* Handle case where original_frac_digits was rounded to 0 but frac_part was not 0 */
|
||||
/* This means we have a very small fractional part that should be represented as .0 */
|
||||
*--end = '0';
|
||||
*--end = '.';
|
||||
} else if (frac_part == 0) {
|
||||
/* No fractional part - just add .0 if we have an integer part */
|
||||
if (int_part != 0) {
|
||||
*--end = '0';
|
||||
*--end = '.';
|
||||
}
|
||||
}
|
||||
|
||||
if (int_part == 0 && frac_digits == 0 && frac_part == 0) {
|
||||
*--end = '0';
|
||||
} else {
|
||||
end = write_digits_backwards(int_part, end, temp);
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
*--end = '-';
|
||||
}
|
||||
|
||||
strcopy(buffer, end, temp + sizeof(temp) - end);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,6 @@ bool strleq(const char *s1, const char *s2, u32 length);
|
|||
i32 strcopy(char* to, const char *from, u32 length);
|
||||
u32 strlength(const char *str);
|
||||
u32 strnlength(const char *str, u32 max_len);
|
||||
void memcopy(u8 *dest, const u8 *src, u32 n);
|
||||
void nat_to_string(u32 value, char *buffer);
|
||||
void int_to_string(i32 value, char *buffer);
|
||||
void fixed_to_string(i32 value, char *buffer);
|
||||
void memcopy(void *to, void *from, u32 length);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
158
src/vm/vm.c
158
src/vm/vm.c
|
|
@ -1,9 +1,13 @@
|
|||
#include "vm.h"
|
||||
#include "common.h"
|
||||
#include "device.h"
|
||||
#include "fixed.h"
|
||||
#include "libc.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
#define MAX_LEN_INT32 11
|
||||
const char radix_set[11] = "0123456789";
|
||||
|
||||
#define COMPARE_AND_JUMP(type, op) \
|
||||
do { \
|
||||
i32 cond; \
|
||||
|
|
@ -198,37 +202,6 @@ bool step_vm(VM *vm) {
|
|||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
||||
return true;
|
||||
}
|
||||
case OP_MEMSET_32: {
|
||||
u32 i, start, end;
|
||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 count_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
||||
|
||||
u32 dest = frame->locals[dest_reg];
|
||||
u32 value = frame->locals[value_reg];
|
||||
u32 count = frame->locals[count_reg];
|
||||
|
||||
if (count == 0) {
|
||||
vm->flag = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
start = dest;
|
||||
end = dest + count;
|
||||
|
||||
if (start >= vm->mp || count > vm->mp || end > vm->mp) {
|
||||
vm->flag = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (i = start; i < end; i += 4) {
|
||||
write_u32(vm, memory, i, value);
|
||||
}
|
||||
|
||||
frame->locals[0] = dest;
|
||||
vm->flag = 1;
|
||||
return true;
|
||||
}
|
||||
case OP_LOAD_ABS_32: {
|
||||
u32 v, ptr;
|
||||
u8 dest;
|
||||
|
|
@ -465,6 +438,37 @@ bool step_vm(VM *vm) {
|
|||
write_u32(vm, memory, (ptr + offset), v);
|
||||
return true;
|
||||
}
|
||||
case OP_MEMSET_32: {
|
||||
u32 i, start, end;
|
||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 count_reg = read_u8(vm, code, vm->pc++);
|
||||
u8 dest_reg = read_u8(vm, code, vm->pc++);
|
||||
|
||||
u32 dest = frame->locals[dest_reg];
|
||||
u32 value = frame->locals[value_reg];
|
||||
u32 count = frame->locals[count_reg];
|
||||
|
||||
if (count == 0) {
|
||||
vm->flag = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
start = dest;
|
||||
end = dest + count;
|
||||
|
||||
if (start >= vm->mp || count > vm->mp || end > vm->mp) {
|
||||
vm->flag = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (i = start; i < end; i += 4) {
|
||||
write_u32(vm, memory, i, value);
|
||||
}
|
||||
|
||||
frame->locals[0] = dest;
|
||||
vm->flag = 1;
|
||||
return true;
|
||||
}
|
||||
case OP_MEMSET_16: {
|
||||
u32 i, start, end;
|
||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||
|
|
@ -928,45 +932,103 @@ bool step_vm(VM *vm) {
|
|||
COMPARE_AND_JUMP(i32, <=);
|
||||
}
|
||||
case OP_INT_TO_STRING: {
|
||||
u32 ptr;
|
||||
char buffer[MAX_LEN_INT32];
|
||||
i32 v;
|
||||
i32 n;
|
||||
u32 i = MAX_LEN_INT32;
|
||||
u8 dest, src1;
|
||||
char buffer[32];
|
||||
bool neg;
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
int_to_string(AS_INT(frame->locals[src1]), buffer);
|
||||
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
||||
frame->locals[dest] = ptr;
|
||||
v = AS_INT(frame->locals[src1]);
|
||||
n = v;
|
||||
neg = n < 0;
|
||||
|
||||
if (neg)
|
||||
n = -n;
|
||||
|
||||
do {
|
||||
buffer[--i] = radix_set[n % 10];
|
||||
n /= 10;
|
||||
} while (n > 0);
|
||||
if (neg)
|
||||
buffer[--i] = '-';
|
||||
/* Ensure at least one digit is written for 0 */
|
||||
if (v == 0)
|
||||
buffer[--i] = '0';
|
||||
|
||||
frame->locals[dest] = str_alloc(vm, frame, buffer + i, MAX_LEN_INT32 - i);
|
||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
||||
return true;
|
||||
}
|
||||
case OP_NAT_TO_STRING: {
|
||||
u32 ptr;
|
||||
char buffer[MAX_LEN_INT32];
|
||||
u32 v;
|
||||
u32 n;
|
||||
u32 i = MAX_LEN_INT32;
|
||||
u8 dest, src1;
|
||||
char buffer[32];
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
nat_to_string(frame->locals[src1], buffer);
|
||||
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
||||
frame->locals[dest] = ptr;
|
||||
v = AS_NAT(frame->locals[src1]);
|
||||
n = v;
|
||||
|
||||
do {
|
||||
buffer[--i] = radix_set[n % 10];
|
||||
n /= 10;
|
||||
} while (n > 0);
|
||||
/* Ensure at least one digit is written for 0 */
|
||||
if (v == 0)
|
||||
buffer[--i] = '0';
|
||||
/* Copy from buffer[i] to buffer + MAX_LEN_INT32 */
|
||||
frame->locals[dest] = str_alloc(vm, frame, buffer + i, MAX_LEN_INT32 - i);
|
||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
||||
return true;
|
||||
}
|
||||
case OP_REAL_TO_STRING: {
|
||||
u32 ptr;
|
||||
u8 dest, src1;
|
||||
char buffer[32];
|
||||
i32 q;
|
||||
u8 dest, src1, int_part, frac_part;
|
||||
u32 i = 0, j = 0;
|
||||
char buffer[12];
|
||||
src1 = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
fixed_to_string(AS_INT(frame->locals[src1]), buffer);
|
||||
ptr = str_alloc(vm, frame, buffer,
|
||||
strlength(buffer)); /* copy buffer to dest */
|
||||
frame->locals[dest] = ptr;
|
||||
|
||||
q = (i32)frame->locals[src1];
|
||||
if (q < 0) {
|
||||
buffer[i++] = '-';
|
||||
q = -q;
|
||||
}
|
||||
|
||||
int_part = q >> 16;
|
||||
frac_part = q & 0xFFFF;
|
||||
|
||||
if (int_part == 0) {
|
||||
buffer[i++] = radix_set[0];
|
||||
} else {
|
||||
char tmp[16];
|
||||
i32 tmp_i = 0;
|
||||
while (int_part > 0) {
|
||||
tmp[tmp_i++] = radix_set[int_part % 10];
|
||||
int_part /= 10;
|
||||
}
|
||||
while (tmp_i > 0) {
|
||||
buffer[i++] = tmp[--tmp_i];
|
||||
}
|
||||
}
|
||||
|
||||
buffer[i++] = '.';
|
||||
for (j = 0; j < 6; j++) {
|
||||
frac_part *= 10;
|
||||
buffer[i++] = radix_set[frac_part >> 16];
|
||||
frac_part &= 0xFFFF;
|
||||
}
|
||||
|
||||
frame->locals[dest] = str_alloc(vm, frame, buffer + i, 12 - i);
|
||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue