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

18
bank.h

@ -2,8 +2,8 @@
#include "base.h" #include "base.h"
typedef struct { typedef struct {
U32 index; U32 index : 28;
U8 size; U32 count : 4;
} Bank_entry; } Bank_entry;
typedef struct { typedef struct {
@ -13,17 +13,19 @@ typedef struct {
typedef size_t Bank_cursor; typedef size_t Bank_cursor;
#define ORCA_BANK_INDEX_MAX UINT32_MAX #define ORCA_BANK_ENTRY_HEADER sizeof(Bank_entry)
#define ORCA_BANK_ENTRY_GLYPHS_MAX UINT8_MAX #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_init(Bank* bank);
void bank_deinit(Bank* bank); void bank_deinit(Bank* bank);
void bank_enlarge_to(Bank* bank, Usz bytes); 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; } static inline void bank_cursor_reset(Bank_cursor* cursor) { *cursor = 0; }
Usz bank_append(Bank* restrict bank, Usz cur_size, Usz index, Usz bank_append(Bank* restrict bank, Usz cur_size, Usz index,
Glyph* restrict glyphs, Usz glyph_count); I32 const* restrict vals, Usz vals_count);
Usz bank_read(char const* bank_data, Usz bank_size, Usz bank_read(char const* restrict bank_data, Usz bank_size,
Bank_cursor* restrict cursor, Usz index, Glyph* restrict dest, Bank_cursor* restrict cursor, Usz index, I32* restrict dest,
Usz dest_count); Usz dest_count);

137
sim.c

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

Loading…
Cancel
Save