shithub: orca

Download patch

ref: ae77f67400e6cf57bcc27cbaa7d147e918ec7b28
parent: 6b535514907e4cf34e1a2faf624cbd36683ebdbe
author: cancel <cancel@cancel.fm>
date: Fri Nov 30 08:32:14 EST 2018

Change bank storage to use I32 instead of Glyph

--- a/bank.c
+++ b/bank.c
@@ -1,17 +1,10 @@
 #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;
+Usz bank_entry_size(Usz num_vals) {
+  return sizeof(Bank_entry) + sizeof(I32) * num_vals;
 }
-ORCA_FORCE_STATIC_INLINE
-Usz bank_entry_size(Usz glyph_count) {
-  return ORCA_BANK_ENTRY_HEADER + glyph_count + bank_entry_padding(glyph_count);
-}
 
 void bank_init(Bank* bank) {
   bank->data = NULL;
@@ -21,7 +14,7 @@
 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 @@
 }
 
 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 @@
   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;
 }
--- a/bank.h
+++ b/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 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);
--- a/sim.c
+++ b/sim.c
@@ -87,23 +87,23 @@
 
 // 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 @@
   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,20 +480,18 @@
 
 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
@@ -500,30 +498,26 @@
 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 @@
 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 @@
   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 @@
 
 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