2026-01-04 18:36:33 +00:00
|
|
|
#include <blue/core/btree.h>
|
2026-01-13 22:37:43 +00:00
|
|
|
#include <mie/ctx.h>
|
2026-01-14 09:45:14 +00:00
|
|
|
#include <mie/dialect/builtin.h>
|
2026-01-04 18:36:33 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
struct int_width_cache_entry {
|
|
|
|
|
b_btree_node e_node;
|
|
|
|
|
struct mie_int e_value;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct int_width_cache {
|
|
|
|
|
b_btree_node c_node;
|
|
|
|
|
size_t c_width;
|
|
|
|
|
b_btree c_ints;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct mie_int_cache {
|
|
|
|
|
b_btree c_widths;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static B_BTREE_DEFINE_SIMPLE_INSERT(
|
|
|
|
|
struct int_width_cache, c_node, c_width, put_width_cache);
|
|
|
|
|
static B_BTREE_DEFINE_SIMPLE_GET(
|
|
|
|
|
struct int_width_cache, size_t, c_node, c_width, get_width_cache);
|
|
|
|
|
|
|
|
|
|
static B_BTREE_DEFINE_SIMPLE_INSERT(
|
|
|
|
|
struct int_width_cache_entry, e_node, e_value.i_val.v_small, put_int);
|
|
|
|
|
static B_BTREE_DEFINE_SIMPLE_GET(
|
|
|
|
|
struct int_width_cache_entry, uint64_t, e_node, e_value.i_val.v_small,
|
|
|
|
|
get_int);
|
|
|
|
|
|
|
|
|
|
static struct int_width_cache *int_width_cache_create(size_t width)
|
|
|
|
|
{
|
|
|
|
|
struct int_width_cache *out = malloc(sizeof *out);
|
|
|
|
|
if (!out) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
|
|
|
|
|
|
out->c_width = width;
|
|
|
|
|
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void int_width_cache_destroy(struct int_width_cache *cache)
|
|
|
|
|
{
|
|
|
|
|
b_btree_node *cur = b_btree_first(&cache->c_ints);
|
|
|
|
|
while (cur) {
|
|
|
|
|
b_btree_node *next = b_btree_next(cur);
|
|
|
|
|
b_btree_delete(&cache->c_ints, cur);
|
|
|
|
|
|
|
|
|
|
struct int_width_cache_entry *entry
|
|
|
|
|
= b_unbox(struct int_width_cache_entry, cur, e_node);
|
|
|
|
|
free(entry);
|
|
|
|
|
|
|
|
|
|
cur = next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(cache);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct int_width_cache_entry *int_width_cache_entry_create(
|
|
|
|
|
struct mie_ctx *ctx, size_t width, size_t value)
|
|
|
|
|
{
|
|
|
|
|
struct int_width_cache_entry *out = malloc(sizeof *out);
|
|
|
|
|
if (!out) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
|
|
2026-01-13 22:37:43 +00:00
|
|
|
out->e_value.i_base.a_def
|
2026-01-14 09:45:14 +00:00
|
|
|
= mie_ctx_get_attribute_definition(ctx, "builtin", "int");
|
2026-01-04 18:36:33 +00:00
|
|
|
out->e_value.i_val.v_small = value;
|
2026-01-14 09:45:14 +00:00
|
|
|
out->e_value.i_type = mie_ctx_get_int_type(ctx, width);
|
2026-01-13 22:37:43 +00:00
|
|
|
if (!out->e_value.i_type) {
|
2026-01-04 18:36:33 +00:00
|
|
|
free(out);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_int_cache *mie_int_cache_create(void)
|
|
|
|
|
{
|
|
|
|
|
struct mie_int_cache *out = malloc(sizeof *out);
|
|
|
|
|
if (!out) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mie_int_cache_destroy(struct mie_int_cache *cache)
|
|
|
|
|
{
|
|
|
|
|
b_btree_node *cur = b_btree_first(&cache->c_widths);
|
|
|
|
|
while (cur) {
|
|
|
|
|
b_btree_node *next = b_btree_next(cur);
|
|
|
|
|
b_btree_delete(&cache->c_widths, cur);
|
|
|
|
|
|
|
|
|
|
struct int_width_cache *width_cache
|
|
|
|
|
= b_unbox(struct int_width_cache, cur, c_node);
|
|
|
|
|
int_width_cache_destroy(width_cache);
|
|
|
|
|
|
|
|
|
|
cur = next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(cache);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_int *mie_int_cache_get(
|
|
|
|
|
struct mie_int_cache *cache, struct mie_ctx *ctx, size_t value,
|
|
|
|
|
size_t bit_width)
|
|
|
|
|
{
|
|
|
|
|
struct int_width_cache *width_cache
|
|
|
|
|
= get_width_cache(&cache->c_widths, bit_width);
|
|
|
|
|
if (!width_cache) {
|
|
|
|
|
width_cache = int_width_cache_create(bit_width);
|
|
|
|
|
|
|
|
|
|
if (!width_cache) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
put_width_cache(&cache->c_widths, width_cache);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct int_width_cache_entry *entry = get_int(&width_cache->c_ints, value);
|
|
|
|
|
if (!entry) {
|
|
|
|
|
entry = int_width_cache_entry_create(ctx, bit_width, value);
|
|
|
|
|
|
|
|
|
|
if (!entry) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
put_int(&width_cache->c_ints, entry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &entry->e_value;
|
|
|
|
|
}
|