First code for StarForth v4 (JUSTIFICATION.md section 10, step 1): one node of the 32-instruction core as a C99 model, with cell width as a build parameter. - Node: P, A, B, F18 circular stacks (10 and 9 deep, D-2), word-addressed memory (D-1), 5% guard bands on every bounded list. - Instruction word: six 5-bit slots in 32 bits at every cell width. - Executor: all 32 opcodes of DECOMPOSITION.md 1.3. Cell arithmetic wraps explicitly; no signed overflow or implementation-defined shift. - Heat: per-opcode and per-call-target counters and the anti-clock, driven by instruction retirement (1.4, D-6 interim). - Slot packer and runner for tests, and a reference unsigned multiply in plain C99 with no 128-bit type. Tests run at 32- and 64-bit cells, and under ASan and UBSan. They cover every opcode and execute the first section 4 definitions (NIP SWAP OR NEGATE ROT 0< 0= 2DUP - U<) against the C operation each stands for. UM* as written in section 4 is exact only while u1 <= 2^(n-2). Two known failing cases are pinned in test_foundation.c until it is rewritten. DECOMPOSITION.md: record D-9, the instruction word is 32 bits at every cell width (ruled 2026-10-02). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
2.4 KiB
C
61 lines
2.4 KiB
C
/* cell.h -- v4 cell width as a build parameter.
|
|
*
|
|
* DECOMPOSITION.md D-5: the host node's cell width matches the host CPU
|
|
* (32 on a Zynq-7000 Cortex-A9, 64 on an aarch64 host). JUSTIFICATION.md
|
|
* section 5 makes this the second invariance axis: if K==1.0 holds across
|
|
* cell widths as well as across ISAs, the conservation law is shown not to
|
|
* depend on word size.
|
|
*
|
|
* The compiler capsule is written width-independent against these types.
|
|
* Nothing in v4 may assume a particular V4_CELL_BITS; if you find yourself
|
|
* wanting to, the code belongs in the host node, not the mesh.
|
|
*
|
|
* JUSTIFICATION.md section 5 also fixes the split that matters for the
|
|
* physics: heat and K arithmetic stay 64-bit on every host regardless of
|
|
* cell width, because they must not lose precision when the cell shrinks.
|
|
* That is why this header defines a separate v4_heat_t rather than reusing
|
|
* v4_cell.
|
|
*/
|
|
#ifndef V4_CELL_H
|
|
#define V4_CELL_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifndef V4_CELL_BITS
|
|
#error "V4_CELL_BITS must be defined to 32 or 64 (e.g. -DV4_CELL_BITS=32)."
|
|
#endif
|
|
|
|
#if V4_CELL_BITS == 32
|
|
typedef int32_t v4_cell;
|
|
typedef uint32_t v4_ucell;
|
|
#elif V4_CELL_BITS == 64
|
|
typedef int64_t v4_cell;
|
|
typedef uint64_t v4_ucell;
|
|
#else
|
|
#error "V4_CELL_BITS must be 32 or 64."
|
|
#endif
|
|
|
|
/* Physics/heat arithmetic width. Fixed at 64 by JUSTIFICATION.md section 5:
|
|
* "Heat and K arithmetic remain 64-bit (int64_t in C99 on every host; double
|
|
* cells on a 32-bit node). Changing only the payload width keeps the
|
|
* experiment clean: any difference in K can be attributed to cell width and
|
|
* not to lost precision." The C side is therefore always 64-bit; the
|
|
* double-cell framing is the 32-bit node's problem, not this type's. */
|
|
typedef int64_t v4_heat_t;
|
|
typedef uint64_t v4_uheat_t;
|
|
|
|
/* MSB -- the cell-width top-bit constant.
|
|
*
|
|
* DECOMPOSITION.md section 5.5 (RSHIFT) and section 5.7 (D2/) both call for
|
|
* "MSB, the cell-width top-bit constant" but never define it, which leaves a
|
|
* bit-width-dependent constant to be invented mid-arithmetic. It is defined
|
|
* here once, as a value with exactly the cell's sign bit set and nothing
|
|
* else, so that the sign-test idioms in those two words are width-correct by
|
|
* construction at 32 and at 64. */
|
|
#define V4_MSB (((v4_ucell)1) << (V4_CELL_BITS - 1))
|
|
|
|
/* All-ones, the width-correct "true". FORTH-79 uses -1 for TRUE. */
|
|
#define V4_ALL_ONES ((v4_cell)-1)
|
|
|
|
#endif /* V4_CELL_H */
|