+static void
+_load_const(jit_state_t *_jit, jit_int32_t reg, jit_word_t value)
+{
+ if (_jitc->consts.vector.offset >= _jitc->consts.vector.length) {
+ jit_word_t new_size = _jitc->consts.vector.length *
+ 2 * sizeof(jit_word_t);
+ jit_realloc((jit_pointer_t *)&_jitc->consts.vector.instrs,
+ _jitc->consts.vector.length * sizeof(jit_word_t), new_size);
+ jit_realloc((jit_pointer_t *)&_jitc->consts.vector.values,
+ _jitc->consts.vector.length * sizeof(jit_word_t), new_size);
+ _jitc->consts.vector.length *= 2;
+ }
+ _jitc->consts.vector.instrs[_jitc->consts.vector.offset] = _jit->pc.w;
+ _jitc->consts.vector.values[_jitc->consts.vector.offset] = value;
+ ++_jitc->consts.vector.offset;
+ /* Resolve later the pc relative address */
+ put_const(value);
+ AUIPC(reg, 0);
+ ADDI(reg, reg, 0);
+ LD(reg, reg, 0);
+}
+
+static jit_word_t
+hash_const(jit_word_t value)
+{
+ const jit_uint8_t *ptr;
+ jit_word_t i, key;
+ for (i = key = 0, ptr = (jit_uint8_t *)&value; i < 4; ++i)
+ key = (key << (key & 1)) ^ ptr[i];
+ return (key);
+
+}
+
+static void
+_put_const(jit_state_t *_jit, jit_word_t value)
+{
+ jit_word_t key;
+ jit_const_t *entry;
+
+ /* Check if already inserted in table */
+ key = hash_const(value) % _jitc->consts.hash.size;
+ for (entry = _jitc->consts.hash.table[key]; entry; entry = entry->next) {
+ if (entry->value == value)
+ return;
+ }
+
+ /* Check if need to increase pool size */
+ if (_jitc->consts.pool.list->next == NULL) {
+ jit_const_t *list;
+ jit_word_t offset;
+ jit_word_t new_size = (_jitc->consts.pool.length + 1) *
+ sizeof(jit_const_t*);
+ jit_realloc((jit_pointer_t *)&_jitc->consts.pool.ptr,
+ _jitc->consts.pool.length * sizeof(jit_const_t*), new_size);
+ jit_alloc((jit_pointer_t *)
+ _jitc->consts.pool.ptr + _jitc->consts.pool.length,
+ 1024 * sizeof(jit_const_t));
+ list = _jitc->consts.pool.ptr[_jitc->consts.pool.length];
+ _jitc->consts.pool.list->next = list;
+ for (offset = 0; offset < 1023; ++offset, ++list)
+ list->next = list + 1;
+ list->next = NULL;
+ ++_jitc->consts.pool.length;
+ }
+
+ /* Rehash if more than 75% used table */
+ if (_jitc->consts.hash.count > (_jitc->consts.hash.size / 4) * 3) {
+ jit_word_t i, k;
+ jit_const_t *next;
+ jit_const_t **table;
+ jit_alloc((jit_pointer_t *)&table,
+ _jitc->consts.hash.size * 2 * sizeof(jit_const_t *));
+ for (i = 0; i < _jitc->consts.hash.size; ++i) {
+ for (entry = _jitc->consts.hash.table[i]; entry; entry = next) {
+ next = entry->next;
+ k = hash_const(entry->value) % (_jitc->consts.hash.size * 2);
+ entry->next = table[k];
+ table[k] = entry;
+ }
+ }
+ jit_free((jit_pointer_t *)&_jitc->consts.hash.table);
+ _jitc->consts.hash.size *= 2;
+ _jitc->consts.hash.table = table;
+ }
+
+ /* Insert in hash */
+ entry = _jitc->consts.pool.list;
+ _jitc->consts.pool.list = entry->next;
+ ++_jitc->consts.hash.count;
+ entry->value = value;
+ entry->next = _jitc->consts.hash.table[key];
+ _jitc->consts.hash.table[key] = entry;
+}
+
+static jit_word_t
+_get_const(jit_state_t *_jit, jit_word_t value)
+{
+ jit_word_t key;
+ jit_const_t *entry;
+ key = hash_const(value) % _jitc->consts.hash.size;
+ for (entry = _jitc->consts.hash.table[key]; entry; entry = entry->next) {
+ if (entry->value == value)
+ return (entry->address);
+ }
+ /* Only the final patch should call get_const() */
+ abort();
+}
+