Browse Source

Change bank storage to use I32 instead of Glyph

master
cancel 6 years ago
parent
commit
ae77f67400
  1. 68
      bank.c
  2. 18
      bank.h
  3. 137
      sim.c

68
bank.c

@ -1,16 +1,9 @@
#include "bank.h"
#include <inttypes.h>
#define ORCA_BANK_ENTRY_HEADER (sizeof(U32) + sizeof(U8))
#define ORCA_BANK_ENTRY_ALIGN sizeof(Bank_entry)
ORCA_FORCE_STATIC_INLINE
Usz bank_entry_padding(Usz glyph_count) {
return ORCA_BANK_ENTRY_ALIGN -
(ORCA_BANK_ENTRY_HEADER + glyph_count) % ORCA_BANK_ENTRY_ALIGN;
}
ORCA_FORCE_STATIC_INLINE
Usz bank_entry_size(Usz glyph_count) {
return ORCA_BANK_ENTRY_HEADER + glyph_count + bank_entry_padding(glyph_count);
Usz bank_entry_size(Usz num_vals) {
return sizeof(Bank_entry) + sizeof(I32) * num_vals;
}
void bank_init(Bank* bank) {
@ -21,7 +14,7 @@ void bank_init(Bank* bank) {
void bank_deinit(Bank* bank) { free(bank->data); }
void bank_enlarge_to(Bank* bank, Usz bytes) {
Usz new_cap = bytes < 256 ? 256 : orca_round_up_power2(bytes);
Usz new_cap = bytes < 512 ? 512 : orca_round_up_power2(bytes);
bank->data = realloc(bank->data, new_cap);
bank->capacity = new_cap;
}
@ -36,35 +29,38 @@ void bank_reserve(Bank* bank, Usz entries, Usz avg_count) {
}
Usz bank_append(Bank* restrict bank, Usz cur_size, Usz index,
Glyph* restrict glyphs, Usz glyph_count) {
I32 const* restrict vals, Usz vals_count) {
assert(index <= ORCA_BANK_INDEX_MAX);
assert(glyph_count <= ORCA_BANK_ENTRY_GLYPHS_MAX);
assert(vals_count <= ORCA_BANK_ENTRY_VALS_MAX);
// no overflow check
Usz new_size = cur_size + bank_entry_size(glyph_count);
Usz new_size = cur_size + bank_entry_size(vals_count);
if (new_size > bank->capacity)
bank_enlarge_to(bank, new_size);
char* data = bank->data + cur_size;
Bank_entry* entry =
(Bank_entry*)ORCA_ASSUME_ALIGNED(data, ORCA_BANK_ENTRY_ALIGN);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
entry->index = (U32)index;
entry->size = (U8)glyph_count;
data += ORCA_BANK_ENTRY_HEADER;
memcpy(data, glyphs, glyph_count);
#ifndef NDEBUG
Usz padding = bank_entry_padding(glyph_count);
memset(data + glyph_count, 0x1c, padding);
#endif
entry->count = (U32)vals_count;
#pragma GCC diagnostic pop
I32* restrict out_vals =
(I32*)ORCA_ASSUME_ALIGNED(data + ORCA_BANK_ENTRY_HEADER, sizeof(I32));
for (size_t i = 0; i < vals_count; ++i) {
out_vals[i] = vals[i];
}
// memcpy(data, vals, vals_count * sizeof(I32));
return new_size;
}
Usz bank_read(char const* bank_data, Usz bank_size,
Bank_cursor* restrict cursor, Usz index, Glyph* restrict dest,
Usz bank_read(char const* restrict bank_data, Usz bank_size,
Bank_cursor* restrict cursor, Usz index, I32* restrict dest,
Usz dest_count) {
assert(index <= ORCA_BANK_INDEX_MAX);
Usz offset = *cursor;
Bank_entry* entry;
Usz entry_index;
Usz entry_size;
Usz entry_count;
Usz num_to_copy;
next:
@ -75,22 +71,26 @@ next:
entry_index = entry->index;
if (entry_index > index)
goto fail;
entry_size = entry->size;
entry_count = entry->count;
if (entry_index < index) {
offset +=
ORCA_BANK_ENTRY_HEADER + entry_size + bank_entry_padding(entry_size);
offset += bank_entry_size(entry_count);
goto next;
}
num_to_copy = dest_count < entry_size ? dest_count : entry_size;
memcpy(dest, bank_data + offset + ORCA_BANK_ENTRY_HEADER, num_to_copy);
if (num_to_copy < dest_count)
memset(dest, '.', dest_count - num_to_copy);
*cursor = offset + ORCA_BANK_ENTRY_HEADER + entry_size +
bank_entry_padding(entry_size);
num_to_copy = dest_count < entry_count ? dest_count : entry_count;
I32 const* src = (I32 const*)ORCA_ASSUME_ALIGNED(
bank_data + offset + ORCA_BANK_ENTRY_HEADER, sizeof(I32));
Usz i = 0;
for (; i < num_to_copy; ++i) {
dest[i] = src[i];
}
for (; i < dest_count; ++i) {
dest[i] = 0;
}
*cursor = offset + ORCA_BANK_ENTRY_HEADER + entry_count * sizeof(I32);
return num_to_copy;
fail:
memset(dest, '.', dest_count);
memset(dest, 0, dest_count * sizeof(I32));
*cursor = offset;
return 0;
}

18
bank.h

@ -2,8 +2,8 @@
#include "base.h"
typedef struct {
U32 index;
U8 size;
U32 index : 28;
U32 count : 4;
} Bank_entry;
typedef struct {
@ -13,17 +13,19 @@ typedef struct {
typedef size_t Bank_cursor;
#define ORCA_BANK_INDEX_MAX UINT32_MAX
#define ORCA_BANK_ENTRY_GLYPHS_MAX UINT8_MAX
#define ORCA_BANK_ENTRY_HEADER sizeof(Bank_entry)
#define ORCA_BANK_ENTRY_ALIGN sizeof(Bank_entry)
#define ORCA_BANK_INDEX_MAX ((size_t)UINT32_C(0x0FFFFFFF))
#define ORCA_BANK_ENTRY_VALS_MAX ((size_t)UINT32_C(0xF))
void bank_init(Bank* bank);
void bank_deinit(Bank* bank);
void bank_enlarge_to(Bank* bank, Usz bytes);
void bank_reserve_average(Bank* bank, Usz num_entries, Usz avg_glyph_count);
void bank_reserve_average(Bank* bank, Usz num_entries, Usz avg_entry_count);
static inline void bank_cursor_reset(Bank_cursor* cursor) { *cursor = 0; }
Usz bank_append(Bank* restrict bank, Usz cur_size, Usz index,
Glyph* restrict glyphs, Usz glyph_count);
Usz bank_read(char const* bank_data, Usz bank_size,
Bank_cursor* restrict cursor, Usz index, Glyph* restrict dest,
I32 const* restrict vals, Usz vals_count);
Usz bank_read(char const* restrict bank_data, Usz bank_size,
Bank_cursor* restrict cursor, Usz index, I32* restrict dest,
Usz dest_count);

137
sim.c

@ -87,23 +87,23 @@ typedef struct {
// static may cause warning if programmer doesn't use bank storage
void oper_bank_store(Oper_bank_write_params* bank_params, Usz width, Usz y,
Usz x, Glyph* restrict glyphs, Usz num_glyphs) {
assert(num_glyphs > 0);
Usz x, I32* restrict vals, Usz num_vals) {
assert(num_vals > 0);
Usz index = y * width + x;
assert(index < ORCA_BANK_INDEX_MAX);
bank_params->size = bank_append(bank_params->bank, bank_params->size, index,
glyphs, num_glyphs);
bank_params->size =
bank_append(bank_params->bank, bank_params->size, index, vals, num_vals);
}
Usz oper_bank_load(Oper_bank_read_params* bank_params, Usz width, Usz y, Usz x,
Glyph* restrict out_glyphs, Usz out_count) {
I32* restrict out_vals, Usz out_count) {
Usz index = y * width + x;
assert(index < ORCA_BANK_INDEX_MAX);
return bank_read(bank_params->bank->data, bank_params->size,
&bank_params->cursor, index, out_glyphs, out_count);
&bank_params->cursor, index, out_vals, out_count);
}
ORCA_FORCE_STATIC_INLINE
Usz UCLAMP(Usz val, Usz min, Usz max) {
Usz usz_clamp(Usz val, Usz min, Usz max) {
if (val < min)
return min;
if (val > max)
@ -185,10 +185,10 @@ Usz UCLAMP(Usz val, Usz min, Usz max) {
mbuffer_poke_relative_flags_or(mbuffer, height, width, y, x, _delta_y, \
_delta_x, Mark_flag_lock)
#define STORE(_glyph_array) \
oper_bank_store(bank_params, width, y, x, _glyph_array, sizeof(_glyph_array))
#define LOAD(_glyph_array) \
oper_bank_load(bank_params, width, y, x, _glyph_array, sizeof(_glyph_array))
#define STORE(_i32_array) \
oper_bank_store(bank_params, width, y, x, _i32_array, sizeof(_i32_array) / sizeof(I32))
#define LOAD(_i32_array) \
oper_bank_load(bank_params, width, y, x, _i32_array, sizeof(_i32_array) / sizeof(I32))
#define IN Mark_flag_input
#define OUT Mark_flag_output
@ -480,50 +480,44 @@ END_PHASE
BEGIN_DUAL_PHASE_0(offset)
REALIZE_DUAL;
Usz read_y = 0;
Usz read_x = 1;
I32 coords[2];
coords[0] = 0; // y
coords[1] = 1; // x
if (DUAL_IS_ACTIVE) {
Glyph coords[2];
coords[0] = PEEK(0, -1);
coords[1] = PEEK(0, -2);
coords[0] = (I32)usz_clamp(INDEX(PEEK(0, -1)), 0, 16);
coords[1] = (I32)usz_clamp(INDEX(PEEK(0, -2)) + 1, 1, 16);
STORE(coords);
read_y = UCLAMP(INDEX(coords[0]), 0, 16);
read_x = UCLAMP(INDEX(coords[1]) + 1, 1, 16);
}
BEGIN_DUAL_PORTS
PORT(0, -1, IN | HASTE);
PORT(0, -2, IN | HASTE);
PORT((Isz)read_y, (Isz)read_x, IN);
PORT(coords[0], coords[1], IN);
PORT(1, 0, OUT);
END_PORTS
END_PHASE
BEGIN_DUAL_PHASE_1(offset)
REALIZE_DUAL;
STOP_IF_DUAL_INACTIVE;
Isz read_y = 0;
Isz read_x = 1;
Glyph coords[2];
if (LOAD(coords)) {
read_y = (Isz)UCLAMP(INDEX(coords[0]), 0, 16);
read_x = (Isz)UCLAMP(INDEX(coords[1]) + 1, 1, 16);
I32 coords[2];
if (!LOAD(coords)) {
coords[0] = 0;
coords[1] = 1;
}
POKE(1, 0, PEEK(read_y, read_x));
STUN(0, 1);
POKE(1, 0, PEEK(coords[0], coords[1]));
STUN(1, 0);
END_PHASE
BEGIN_DUAL_PHASE_0(push)
REALIZE_DUAL;
Usz write_val_x = 0;
I32 write_val_x[1];
write_val_x[0] = 0;
if (DUAL_IS_ACTIVE && IS_AWAKE) {
Glyph params[2];
params[0] = PEEK(0, -1); // len
params[1] = PEEK(0, -2); // key
STORE(params);
Usz len = UCLAMP(INDEX(params[0]), 1, 16);
Usz key = INDEX(params[1]);
write_val_x = key % len;
for (Usz i = 0; i < write_val_x; ++i) {
LOCK(1, (Isz)i);
Usz len = usz_clamp(INDEX(PEEK(0, -1)), 1, 16);
Usz key = INDEX(PEEK(0, -2));
write_val_x[0] = (I32)(key % len);
STORE(write_val_x);
for (Isz i = 0; i < write_val_x[0]; ++i) {
LOCK(1, i);
}
}
BEGIN_DUAL_PORTS
@ -535,29 +529,25 @@ BEGIN_DUAL_PHASE_0(push)
END_PHASE
BEGIN_DUAL_PHASE_1(push)
STOP_IF_NOT_BANGED;
Usz write_val_x = 0;
Glyph params[2];
if (LOAD(params)) {
Usz len = UCLAMP(INDEX(params[0]), 1, 16);
Usz key = INDEX(params[1]);
write_val_x = key % len;
I32 write_val_x[1];
if (!LOAD(write_val_x)) {
write_val_x[0] = 0;
}
POKE(1, (Isz)write_val_x, PEEK(0, 1));
POKE(1, write_val_x[0], PEEK(0, 1));
END_PHASE
BEGIN_DUAL_PHASE_0(track)
PSEUDO_DUAL;
Usz read_val_x = 1;
Isz read_val_x = 1;
if (IS_AWAKE) {
Glyph params[2];
params[0] = PEEK(0, -1); // len
params[1] = PEEK(0, -2); // key
STORE(params);
Usz len = UCLAMP(INDEX(params[0]), 1, 16);
Usz key = INDEX(params[1]);
read_val_x = key % len + 1;
for (Usz i = 0; i < read_val_x; ++i) {
LOCK(0, (Isz)(i + 1));
Usz len = usz_clamp(INDEX(PEEK(0, -1)), 1, 16);
Usz key = INDEX(PEEK(0, -2));
read_val_x = (Isz)(key % len + 1);
I32 ival[1];
ival[0] = (I32)read_val_x;
STORE(ival);
for (Isz i = 0; i < read_val_x; ++i) {
LOCK(0, i + 1);
}
}
BEGIN_DUAL_PORTS
@ -568,14 +558,11 @@ BEGIN_DUAL_PHASE_0(track)
END_PORTS
END_PHASE
BEGIN_DUAL_PHASE_1(track)
Usz read_val_x = 1;
Glyph params[2];
if (LOAD(params)) {
Usz len = UCLAMP(INDEX(params[0]), 1, 16);
Usz key = INDEX(params[1]);
read_val_x = key % len + 1;
I32 ival[1];
if (!LOAD(ival)) {
ival[0] = 1;
}
POKE(1, 0, PEEK(0, (Isz)read_val_x));
POKE(1, 0, PEEK(0, ival[0]));
STUN(1, 0);
END_PHASE
@ -626,34 +613,30 @@ END_PHASE
BEGIN_DUAL_PHASE_0(teleport)
REALIZE_DUAL;
Usz write_y = 0;
Usz write_x = 1;
I32 coords[2];
coords[0] = 0; // y
coords[1] = 1; // x
if (DUAL_IS_ACTIVE) {
Glyph coords[2];
coords[0] = PEEK(0, -1);
coords[1] = PEEK(0, -2);
coords[0] = (I32)usz_clamp(INDEX(PEEK(0, -1)), 0, 16);
coords[1] = (I32)usz_clamp(INDEX(PEEK(0, -2)), 1, 16);
STORE(coords);
write_y = UCLAMP(INDEX(coords[0]), 0, 16);
write_x = UCLAMP(INDEX(coords[1]), 1, 16);
}
BEGIN_DUAL_PORTS
PORT(0, -1, IN | HASTE);
PORT(0, -2, IN | HASTE);
PORT(1, 0, IN);
PORT((Isz)write_y, (Isz)write_x, OUT | NONLOCKING);
PORT(coords[0], coords[1], OUT | NONLOCKING);
END_PORTS
END_PHASE
BEGIN_DUAL_PHASE_1(teleport)
STOP_IF_NOT_BANGED;
Isz write_y = 0;
Isz write_x = 1;
Glyph coords[2];
if (LOAD(coords)) {
write_y = (Isz)UCLAMP(INDEX(coords[0]), 0, 16);
write_x = (Isz)UCLAMP(INDEX(coords[1]), 1, 16);
I32 coords[2];
if (!LOAD(coords)) {
coords[0] = 0;
coords[1] = 1;
}
POKE(write_y, write_x, PEEK(0, 1));
STUN(write_y, write_x);
POKE(coords[0], coords[1], PEEK(0, 1));
STUN(coords[0], coords[1]);
END_PHASE
//////// Run simulation

Loading…
Cancel
Save