improve performance for integers

This commit is contained in:
William Bell
2025-08-30 03:29:02 +01:00
parent 4fc28d3b76
commit 4f91bf48f3
16 changed files with 456 additions and 187 deletions

View File

@@ -131,27 +131,27 @@ loads a boolean into register 1
## OP_LOAD_NUMBER
loads a mpq_t number into memory
loads a mpq_t / int64 number into memory
1. the register to write to. (*)
1. is int64 (*)
1. the size of the numerator in the constant buffer.
1. the offset in the constant buffer of the numerator.
1. is integer. (*)
1. the size of the denominator in the constant buffer.
1. the offset in the constant buffer of the denominator.
## OP_LOAD_ADDITION_FUNCTION
## OP_COPY_TO_REGISTER
loads the addition function into register 1
copies the value from one register to another
## OP_LOAD_SUBTRACTION_FUNCTION
1. the register to copy from (*)
2. the register to write to (*)
loads the subtraction function into register 1
## OP_ADDITION
## OP_LOAD_MULTIPLY_FUNCTION
performs an addition between register A and register B, storing the result in register C
loads the multiply function into register 1
## OP_LOAD_DIVISION_FUNCTION
loads the division function into register 1
1. the register A (*)
2. the register B (*)
2. the register C (*)

View File

@@ -5,6 +5,7 @@
*/
#include "number.h"
#include "../../runtime/objects/number/number.h"
#include "../translator.h"
#include <gmp.h>
#include <stddef.h>
@@ -16,6 +17,13 @@ size_t translate_parsed_number(Translated *translated, mpq_t *number,
set_registers(translated, to_register + 1);
size_t start = push_instruction_byte(translated, OP_LOAD_NUMBER);
push_instruction_byte(translated, to_register);
int64_t i64;
uint8_t is_int64 = mpq_to_int64(*number, &i64);
push_instruction_byte(translated, is_int64);
if (is_int64) {
push_instruction_code(translated, i64);
return start;
}
size_t num_size;
void *num_data = mpz_export(NULL, &num_size, 1, 1, 0, 0, mpq_numref(*number));
size_t numerator_pos = arena_push(&translated->constants, num_data, num_size);

View File

@@ -6,42 +6,44 @@
#include "operation.h"
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
size_t translate_operation(Translated *translated, ParsedOperation *operation,
ArErr *err) {
set_registers(translated, 1);
uint64_t first;
switch (operation->operation) {
case TOKEN_PLUS:;
first = push_instruction_byte(translated, OP_LOAD_ADDITION_FUNCTION);
break;
case TOKEN_MINUS:
first = push_instruction_byte(translated, OP_LOAD_SUBTRACTION_FUNCTION);
break;
case TOKEN_STAR:
first = push_instruction_byte(translated, OP_LOAD_MULTIPLY_FUNCTION);
break;
case TOKEN_SLASH:
first = push_instruction_byte(translated, OP_LOAD_DIVISION_FUNCTION);
break;
default:
*err = create_err(operation->line, operation->column, operation->length,
translated->path, "Syntax Error", "unknown operation");
return 0;
}
push_instruction_byte(translated, OP_INIT_CALL);
push_instruction_code(translated, operation->to_operate_on.size);
for (size_t i = 0; i < operation->to_operate_on.size; i++) {
uint8_t registerA = translated->registerAssignment++;
uint8_t registerB = translated->registerAssignment++;
set_registers(translated, translated->registerAssignment);
uint64_t first = translate_parsed(translated, darray_get(&operation->to_operate_on, 0), err);
push_instruction_byte(translated, OP_COPY_TO_REGISTER);
push_instruction_byte(translated, 0);
push_instruction_byte(translated, registerA);
for (size_t i = 1; i < operation->to_operate_on.size; i++) {
translate_parsed(translated, darray_get(&operation->to_operate_on, i), err);
push_instruction_byte(translated, OP_INSERT_ARG);
push_instruction_code(translated, i);
push_instruction_byte(translated, OP_COPY_TO_REGISTER);
push_instruction_byte(translated, 0);
push_instruction_byte(translated, registerB);
switch (operation->operation) {
case TOKEN_PLUS:;
push_instruction_byte(translated, OP_ADDITION);
break;
case TOKEN_MINUS:;
push_instruction_byte(translated, OP_SUBTRACTION);
break;
default:
*err = create_err(operation->line, operation->column, operation->length,
translated->path, "Syntax Error", "unknown operation");
return 0;
}
push_instruction_byte(translated, registerA);
push_instruction_byte(translated, registerB);
push_instruction_byte(
translated, operation->to_operate_on.size - 1 == i ? 0 : registerA);
}
push_instruction_byte(translated, OP_SOURCE_LOCATION);
push_instruction_code(translated, operation->line);
push_instruction_code(translated, operation->column);
push_instruction_code(translated, operation->length);
push_instruction_byte(translated, OP_CALL);
push_instruction_byte(translated, OP_LOAD_NULL);
push_instruction_byte(translated, registerA);
push_instruction_byte(translated, OP_LOAD_NULL);
push_instruction_byte(translated, registerB);
translated->registerAssignment -= 2;
return first;
}

View File

@@ -86,6 +86,7 @@ Translated init_translator(char *path) {
Translated translated;
translated.path = path;
translated.registerCount = 1;
translated.registerAssignment = 1;
translated.return_jumps = NULL;
darray_init(&translated.bytecode, sizeof(uint8_t));
arena_init(&translated.constants);

View File

@@ -29,14 +29,13 @@ typedef enum {
OP_INSERT_ARG,
OP_CALL,
OP_SOURCE_LOCATION,
OP_LOAD_ACCESS_FUNCTION,
OP_LOAD_BOOL,
OP_LOAD_NUMBER,
OP_LOAD_ADDITION_FUNCTION,
OP_LOAD_SUBTRACTION_FUNCTION,
OP_LOAD_MULTIPLY_FUNCTION,
OP_LOAD_DIVISION_FUNCTION,
OP_ASSIGN
OP_ASSIGN,
OP_COPY_TO_REGISTER,
OP_ADDITION,
OP_SUBTRACTION,
OP_LOAD_ACCESS_FUNCTION
} OperationType;
void arena_resize(ConstantArena *arena, size_t new_size);