Domain structure

UXSTM is organized around a domain model: each domain is a typed ISA block (e.g., BIT, INT, WINT, FP, DP/WDP for data-parallel, CR) that can be included or omitted to build a processor profile for a target workload. Inside each domain, UXSTM uses a repeatable domain template: two operand stacks plus two ISA-visible register resources. The result is a uniform execution contract for compilers/JITs and a clean mechanism to configure “universal” cores without changing the fundamental programming model.

The domain template is intentionally stack-first: the canonical operand/result interface is the top of stack (TOS), consistent with well-known stack-execution specifications.

1. Domain Template: Architectural Elements

A UXSTM domain is defined by the following ISA-visible elements:

  1. M-stack (Main) — primary evaluation stack (LIFO)
  2. S-stack (Staging) — secondary staging/assist stack (LIFO)
  3. Constant register bank — fast access to frequently used literals (e.g., 0, 1, etc.)
  4. Pinned register bank — anchored registers for “hot” values / globals / descriptors

All four exist to support one execution principle: operations remain defined over stack tops; registers are auxiliary mechanisms to reduce friction and traffic, not a replacement for stack semantics.

2. M-stack (Main): Full-Function Execution Surface

Definition. The M-stack is the domain’s primary evaluation stack. Most domain operations are specified in terms of TOS semantics:

  • operands are taken from the top entries of M-stack (unless an instruction explicitly states otherwise),
  • results are pushed back onto M-stack.

Scope. The M-stack supports the complete functional envelope of the domain, including:

  • Memory transfers: explicit load/store-style transfers that inject/extract values into/from the stack-based flow,
  • Core compute: arithmetic, logical operations, comparisons, and other domain-defined transforms,
  • Bit operations: where the domain includes them.

Why this matters. Making the M-stack the “full surface” ensures the architecture remains canonically stack-executed and predictable: the compiler/JIT can reason about execution as “stack in → op → stack out”, and the ISA contract does not devolve into a hidden register machine.

3. S-stack (Staging): Decoupled Prepare Path

Definition. The S-stack is a secondary operand stack intended for staging and servicing, not for replacing the main evaluation flow.

Intended usage. The S-stack exists to handle work that is useful to overlap with M-stack compute or expensive to express as deep-stack manipulation on M.

  • Memory-oriented preparation: preloading, buffering, and preparing operands while the M-stack performs compute,
  • Lightweight primitives: small bit-ops, inc/dec, and similar low-cost transformations that support preparation workflows,
  • Hot-value holding: keeping frequently used values close (in S or pinned regs) to avoid deep-stack rearrangements on M (e.g., avoiding repeated deep SWAP/DUP-style patterns).

Core idea. S-stack is a second architectural surface. This decoupling is a key lever for reducing stack traffic and enabling higher instruction-level overlap at the core scheduler level.

4. Constant Register Bank: Fast Literals

Definition. The constant registers are an ISA-visible bank that provides frequent literals without repeatedly encoding immediates.

Why constant registers exist

  • Code density / decode simplicity: frequently used constants appear across code; providing them as architectural constants can reduce repeated immediate encoding and can keep common instruction patterns compact.
  • Lower stack churn: instead of “push literal → use → discard”, constants can be accessed with minimal stack traffic.

5. Pinned Register Bank: Anchored “Hot” Values and Globals

Definition. Pinned registers are an ISA-visible bank of registers intended to hold values that should remain anchored across instruction sequences—values that would otherwise sit deep in the stacks or require repeated shuffling.

Primary purposes.

  • Hot operands: frequently reused operands that would otherwise generate deep-stack pressure,
  • Descriptors / handles / pointers: stable references used repeatedly in a block or across a VM execution loop,
  • Global-like state: selected “global variables” or runtime state that benefits from being consistently accessible,
  • Loop invariants / masks: values that should not be repeatedly reconstructed or moved.

Why pinned registers fit a stack-first ISA. In a pure stack machine, frequent reuse can lead to:

  • deep-stack growth,
  • repeated rearrangement to bring values to TOS.

Pinned registers provide stable anchors that reduce this rearrangement while keeping the canonical operand interface stack-based.

6. Destructive vs Non-destructive Instruction Forms

UXSTM allows instructions to be specified in either of two semantic forms:

6.1 Destructive (consuming)

  • operands are popped from the designated stack(s),
  • the operation is performed,
  • the result is pushed.

This is the canonical stack-machine behavior (“consume → produce”).

6.2 Non-destructive (preserving)

  • operands are read from TOS without popping (peek semantics),
  • the operation is performed,
  • the result is pushed while preserving the source operands.

Why both forms are valuable.

  • Non-destructive forms can reduce explicit duplication and rearrangement sequences (fewer “copy-to-top” patterns),
  • They offer a more direct mapping for VM/JIT idioms that repeatedly reference the same TOS values while accumulating derived results,
  • They provide a controlled trade-off between instruction count and stack traffic.

The UXSTM domain template is built around a simple contract: two operand stacks (Main and Staging) plus constant and pinned register banks, while keeping execution defined over stack tops. M-stack provides the full evaluation surface (including explicit memory transfers and compute), and S-stack provides a decoupled preparation surface that reduces main-stack traffic and enables explicit overlap of staging with computation. Constant registers reduce repeated literal materialization, and pinned registers anchor hot values and runtime state without abandoning a stack-first ISA. Together, these mechanisms make domains composable building blocks for configuring universal cores across workloads, while preserving a strict and predictable execution model.

See Also: