Skip to content

Commit 1ba8318

Browse files
committed
Extended the logic-helper
1 parent 69e5464 commit 1ba8318

17 files changed

Lines changed: 1004 additions & 47 deletions

ENCODING.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Ternary ISA Encoding Notes
2+
3+
This file sketches how the new helpers (TBRANCH/TMUX/TMAJ/TNET, etc.) might be encoded in a future ternary ISA that favors tryte-aligned opcodes and asynchronous control.
4+
5+
## Tryte-friendly Opcode Layout
6+
7+
Balanced ternary instructions can pack more information per opcode than binary. A 6-trit “tryte” can be divided into:
8+
9+
- **2 trits**: data width tag
10+
- **2 trits**: instruction family (e.g., logic, control, neural)
11+
- **2 trits**: immediate flags / predicate bits
12+
13+
For example, TBRANCH and TMUX can share the same family slot (control) but use different predicate bits to indicate whether the instruction targets code or data. This layout keeps the decoder simple and lets the hardware dispatch a full control triple in one cycle.
14+
15+
| Tryte Field | Value (balanced ternary) | Meaning |
16+
|-------------|--------------------------|---------|
17+
| Width | `-1` / `0` / `+1` | selects 32/64/128 trit widths |
18+
| Family | `-1` / `0` / `+1` | logic / control / arithmetic |
19+
| Flags | `-1` / `0` / `+1` | condition inversion / speculation bits |
20+
21+
A `TBRANCH` instruction can carry three relative offsets/labels plus a flag that enables speculative dispatch, while `TMUX` uses the same control bits to choose among data paths.
22+
23+
## Async Control Handshake
24+
25+
Following Setun’s clockless transitions, the ternary branch path can be modeled as a handshake:
26+
27+
1. A ternary condition trit is produced by the comparison logic.
28+
2. The arbiter observes the trit and activates one of three ready signals (negative/zero/positive).
29+
3. The pipeline selects the matching target tag (one of the triple encoded next to the opcode).
30+
4. Speculative bits indicate whether the branch outcome should be confirmed in a later cycle or aborted.
31+
32+
Because ternary conditions expose sign symmetry, `TSIGNJMP`/`TMUX` can reuse the same handshake: the runtime helper returns the chosen target (or data lane) immediately, and an arbiter verifies the trit feeds through to the next cycle before committing.
33+
34+
## TNN-Ready Units
35+
36+
Vectorized primitives such as `TMAJ` and `TNET` benefit from this encoding because they can receive their operand tag, width, and mask in a single tryte. For example, a `TNET` instruction on a 128-trit register might set the width field to `+1`, the family to `+1` (neural), and use the flags to toggle “fold-over” behavior for training-aware rounding.
37+
38+
These sketches guide future ASIC/FPGA work; the runtime helpers and skeleton demos mirror the same semantics in software.

MASTER_ISA.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ focuses on instructions whose semantics *literally require* a three-valued persp
116116
- Tryte-friendly opcodes: reserve 6 trits per slot (e.g., 2 trits for vector width, 2 trits for the instruction family, 2 trits for immediates/flags). Instructions such as `TBRANCH`, `TMAJ`, and `TMULADD` can live in a single tryte with built-in width tags so the hardware decoder can dispatch without binary prefix tables.
117117
- Async branch support: follow Setun’s clockless transitions by treating `TBRANCH`/`TSIGNJMP` as micro-instructions that grab a condition trit and target triple simultaneously, avoiding the binary flag expansion. Documenting this early helps map the runtime helpers to future hardware that may signal targets through a branch arbiter rather than the normal program counter updates.
118118
- Async control handshake: model hardware such that the condition feed (ternary condition register) produces one of three ready signals, and an arbiter selects the matching target label/offset in the same cycle. `TBRANCH` should therefore expose a triple-target field plus a flag that indicates whether the jump is speculative; software helpers can mirror that by returning the chosen target value so forward progress can be verified even before hardware support arrives.
119+
- For a concrete tryte encoding, see `ENCODING.md`, which lays out the 6-trit fields for family/tag/flags (including how TBRANCH/TMUX/TMAJ/TNET slot into those fields) and explains how the async arbiter consumes the flag field as a readiness handshake.
119120

120121
## Next steps
121122

@@ -124,3 +125,7 @@ focuses on instructions whose semantics *literally require* a three-valued persp
124125
2. Choose a canonical helper prefix (`__ternary` by default) and append the new operations to that ABI.
125126
3. Prototype the quantization/branch helpers in `runtime_skeleton/` so plugin tests can depend on them.
126127
4. Sketch hardware encodings (tryte/6-trit opcodes) once the semantics settle.
128+
5. Expand t128/runtime coverage (and tests) so the helper list scales beyond t64 and the TMUX/TNET paths used in the skeleton can be verified on larger registers (**Completed**).
129+
- The reference runtime now defines all t128 helpers (including TMUX/TNET/TEQUIV/TXOR) via `_BitInt(256)` encode/decode helpers and exposes them through `include/ternary_runtime.h`.
130+
- The runtime skeleton mirrors the same helpers so the minimal implementation delivers the ISA contracts and the TMUX/TNET demo can run across t128 lanes.
131+
- Focused tests (`tests/test_logic_helpers.c`, `runtime_skeleton/test_runtime_skeleton.c`) cover the t128 helpers and `tools/check_helper_docs.py` keeps documentation in lockstep.

README.md

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,13 @@ For testing without the plugin, the header provides C implementations of all ter
175175
Packed ternary types use a 2-bit encoding per trit (00 = -1, 01 = 0, 10 = +1).
176176
Define `TERNARY_USE_BUILTIN_TYPES` before including the header when compiling with
177177
`-fplugin-arg-ternary_plugin-types` to avoid typedef conflicts.
178-
Helper/runtime support is currently provided for t32/t64 only; t128 requires
179-
custom runtime implementations. The reference runtime uses 64-bit logical
180-
conversion helpers, so t64 correctness is limited to values that fit in int64.
178+
Helper/runtime support now covers t32/t64 and t128 (when `_BitInt(256)` support
179+
is available). The reference runtime, headers, and skeleton expose the full
180+
helper set—TMUX/TNET/TEQUIV/TXOR included—for t128_math paths, and the
181+
corresponding tests (`tests/test_logic_helpers.c`, `runtime_skeleton/test_runtime_skeleton.c`)
182+
exercise those helpers so their semantics are verified on wider ternary
183+
registers. Run `tools/check_helper_docs.py` after ABI changes to keep the helper
184+
list in sync.
181185

182186
For example:
183187

@@ -200,8 +204,8 @@ gcc -fplugin=./ternary_plugin.so -fplugin-arg-ternary_plugin-lower -Iinclude -c
200204

201205
For a minimal out-of-line runtime, use the reference implementation in `runtime/ternary_runtime.c`
202206
with the public header `include/ternary_runtime.h`. It implements the same packed 2-bit-trit
203-
semantics as the helpers (t32/t64) and is intended as a starting point for a real ISA-backed
204-
library. Packed helpers for t128 are not provided in this reference runtime.
207+
semantics as the helpers (t32/t64) and now surfaces the t128 helpers when `_BitInt(256)`
208+
support exists so ISA-backed runtimes can prototype on the wider register set.
205209

206210
Example build:
207211

@@ -261,6 +265,17 @@ make test CXX=g++-15 CC=gcc-15
261265

262266
`make test` now also compiles `tests/test_literals.c` (ensuring literal helpers + promotions compile) and `test_ternary.c` with `-fplugin-arg-ternary_plugin-dump-gimple` so Phase 3 coverage exercises the dump/trace flags.
263267

268+
### Extended helper ABI
269+
270+
In addition to the core helper ABI described in `SPECIFICATION.md`, the roadmap now exposes the ternary-only helpers used by the TMUX/TNET/TNN demo and the runtime/reference implementations:
271+
272+
- `__ternary_tmux_t32` / `__ternary_tmux_t64` / `__ternary_tmux_t128`
273+
- `__ternary_tequiv_t32` / `__ternary_tequiv_t64` / `__ternary_tequiv_t128`
274+
- `__ternary_txor_t32` / `__ternary_txor_t64` / `__ternary_txor_t128`
275+
- `__ternary_tnet_t32` / `__ternary_tnet_t64` / `__ternary_tnet_t128`
276+
277+
These helpers are exercised by the runtime skeleton demo (`runtime_skeleton/run_tnn_demo.sh`), which now builds and runs a tiny ternary neural network pipeline across t32/t64/t128 helper implementations and TMUX-driven routing logic.
278+
264279
## Description
265280

266281
This plugin analyzes ternary conditional expressions in the code and can optionally
@@ -304,7 +319,27 @@ For helpers that literally need three-valued semantics (TMIN/TMAX, TIMPL/TLIMP,
304319
TMAJ, TQUANT, and the TNOT/TINV aliases), see `MASTER_ISA.md`. It documents how
305320
these instructions propagate “unknown” trits, when to use TINV as an inference
306321
alias, and the extended control-flow helpers (TBRANCH/TSIGNJMP) you can expose
307-
through `__ternary_*` before hardware encodings are sketched.
322+
through `__ternary_*` before hardware encodings are sketched (see `ENCODING.md`
323+
for the tryte field layout mentioned there).
324+
325+
### Helper symbol inventory
326+
327+
```
328+
__ternary_tbias_t32 __ternary_tbias_t64 __ternary_tbias_t128 __ternary_tbranch __ternary_tequiv_t32
329+
__ternary_tequiv_t64 __ternary_tequiv_t128 __ternary_tinv_t32 __ternary_tinv_t64 __ternary_tinv_t128
330+
__ternary_tlimp_t32 __ternary_tlimp_t64 __ternary_tlimp_t128 __ternary_tlimp_tv32 __ternary_tmaj_t32
331+
__ternary_tmaj_t64 __ternary_tmaj_t128 __ternary_tmaj_tv32 __ternary_tmax_t32 __ternary_tmax_t64
332+
__ternary_tmax_t128 __ternary_tmax_tv32 __ternary_tmin_t32 __ternary_tmin_t64 __ternary_tmin_t128
333+
__ternary_tmin_tv32 __ternary_tmuladd_t32 __ternary_tmuladd_t64 __ternary_tmuladd_t128 __ternary_tmux_t32
334+
__ternary_tmux_t64 __ternary_tmux_t128 __ternary_tnet_t32 __ternary_tnet_t64 __ternary_tnet_t128
335+
__ternary_tnormalize_t32 __ternary_tnormalize_t64 __ternary_tnormalize_t128 __ternary_tnot_t32
336+
__ternary_tnot_t64 __ternary_tnot_t128 __ternary_tquant_t32 __ternary_tquant_t64 __ternary_tquant_t128
337+
__ternary_tquant_tv32 __ternary_tround_t32 __ternary_tround_t64 __ternary_tround_t128 __ternary_tround_tv32
338+
__ternary_tsignjmp_t32 __ternary_tsignjmp_t64 __ternary_txor_t32 __ternary_txor_t64 __ternary_txor_t128
339+
```
340+
The expanded helper list now also covers ternary equivalence/XOR (`TEQUIV`/`TXOR`),
341+
TMUX-style data selectors, and the net-trit sum helper (`TNET`), so the roadmap,
342+
runtime, and docs all agree on the full ternary-only ISA surface.
308343

309344
### Control Flow Operations (brt/brf) - PLANNED
310345
- `brt Rc, label`: branch if Rc != 0 (ternary true)

SPECIFICATION.md

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ Branches use ternary conditions:
311311
- brt cond, label: branch if cond != 0
312312
- brf cond, label: branch if cond == 0
313313

314+
Hardware implementers can reference `ENCODING.md` for the tryte field layout that packs the
315+
conditional helpers (TBRANCH/TMUX) plus the family/flag bits used by the async arbiter described in `MASTER_ISA.md`.
316+
314317
Ternary-aware helpers like `tbranch` and `tsignjmp` (see `MASTER_ISA.md`) allow
315318
three-way control-flow selection or sign-directed jumps without chaining binary
316319
flags, matching Setun’s triple-transition model.
@@ -418,6 +421,25 @@ helper implementations can be shared between plugin tests and downstream runtime
418421
`__ternary_xor_t32`, `__ternary_xor_t64`, `__ternary_shl_t32`, `__ternary_shl_t64`,
419422
`__ternary_shr_t32`, `__ternary_shr_t64`, `__ternary_rol_t32`, `__ternary_rol_t64`,
420423
`__ternary_ror_t32`, `__ternary_ror_t64`.
424+
- **Packed ternary logic helpers** (AI-friendly semantics):
425+
`__ternary_tmin_t32`, `__ternary_tmin_t64`, `__ternary_tmax_t32`, `__ternary_tmax_t64`,
426+
`__ternary_tmaj_t32`, `__ternary_tmaj_t64`, `__ternary_tlimp_t32`, `__ternary_tlimp_t64`,
427+
`__ternary_tquant_t32`, `__ternary_tquant_t64`, `__ternary_tquant_tv32`,
428+
`__ternary_tnot_t32`, `__ternary_tnot_t64`, `__ternary_tmuladd_t32`,
429+
`__ternary_tmuladd_t64`, `__ternary_tround_t32`, `__ternary_tround_t64`,
430+
`__ternary_tround_tv32`, `__ternary_tnormalize_t32`, `__ternary_tnormalize_t64`,
431+
`__ternary_tbias_t32`, `__ternary_tbias_t64`, `__ternary_tmux_t32`,
432+
`__ternary_tmux_t64`, `__ternary_tequiv_t32`, `__ternary_tequiv_t64`,
433+
`__ternary_txor_t32`, `__ternary_txor_t64`, `__ternary_tnet_t32`,
434+
`__ternary_tnet_t64`.
435+
- **Packed ternary logic helpers (t128, when `_BitInt(256)` is available)**:
436+
`__ternary_tmin_t128`, `__ternary_tmax_t128`, `__ternary_tmaj_t128`,
437+
`__ternary_tlimp_t128`, `__ternary_tquant_t128`, `__ternary_tnot_t128`,
438+
`__ternary_tinv_t128`, `__ternary_tmuladd_t128`, `__ternary_tround_t128`,
439+
`__ternary_tnormalize_t128`, `__ternary_tbias_t128`, `__ternary_tmux_t128`,
440+
`__ternary_tequiv_t128`, `__ternary_txor_t128`, `__ternary_tnet_t128`.
441+
- **Ternary control helpers**: `__ternary_tbranch`, `__ternary_tsignjmp_t32`,
442+
`__ternary_tsignjmp_t64`.
421443
- **Packed ternary comparisons (ternary results)**: `__ternary_cmplt_t32`, `__ternary_cmplt_t64`,
422444
`__ternary_cmpeq_t32`, `__ternary_cmpeq_t64`, `__ternary_cmpgt_t32`, `__ternary_cmpgt_t64`,
423445
`__ternary_cmpneq_t32`, `__ternary_cmpneq_t64`.
@@ -473,10 +495,18 @@ packed 2-bit trit encoding (00 = -1, 01 = 0, 10 = +1).
473495
- Shift/rotate builtin lowering (t32/t64)
474496
- Conversion builtin lowering (tb2t, tt2b, t2f, f2t)
475497

498+
### Extended helper ABI
499+
500+
- Three-way selector helpers: `__ternary_tmux_t32`, `__ternary_tmux_t64`, `__ternary_tmux_t128`.
501+
- Kleene equivalence helpers: `__ternary_tequiv_t32`, `__ternary_tequiv_t64`, `__ternary_tequiv_t128`.
502+
- Ternary-exclusive-or helpers: `__ternary_txor_t32`, `__ternary_txor_t64`, `__ternary_txor_t128`.
503+
- Net-sum helpers: `__ternary_tnet_t32`, `__ternary_tnet_t64`, `__ternary_tnet_t128`.
504+
- Demonstrated via the TMUX/TNET/TNN runtime skeleton demo, including t32/t64/t128 workloads.
505+
476506
### Known Limitations
477507
- GCC 15 API compatibility may still require adjustments
478-
- Packed ternary helpers currently cover t32/t64 only (no big-int support for t128)
479-
- Reference runtime/helpers do not implement t128 operations
508+
- Packed ternary helpers require `__BITINT_MAXWIDTH__ >= 256` for native `t128_t`; fallback paths mirror the two-`t64_t` layout.
509+
- Reference runtime/helpers only simulate t128 operations when the compiler exposes `_BitInt(256)` support.
480510

481511
## Future Extensions
482512

include/ternary_helpers.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
#include <stdint.h>
1616
#include <stdarg.h>
17+
#define TERNARY_PLUGIN_SKIP_BT_STR
18+
#include "ternary_plugin.h"
19+
#undef TERNARY_PLUGIN_SKIP_BT_STR
1720

1821
#ifdef __cplusplus
1922
extern "C" {
@@ -871,6 +874,57 @@ static inline int __ternary_cmp_t64(t64_t a, t64_t b) {
871874
if (va > vb) return 1;
872875
return 0;
873876
}
877+
878+
/* Extended helper declarations that mirror the runtime implementations. */
879+
extern t32_t __ternary_tmin_t32(t32_t a, t32_t b);
880+
extern t32_t __ternary_tmax_t32(t32_t a, t32_t b);
881+
extern t32_t __ternary_tmaj_t32(t32_t a, t32_t b, t32_t c);
882+
extern t32_t __ternary_tlimp_t32(t32_t antecedent, t32_t consequent);
883+
extern t32_t __ternary_tquant_t32(float value, float threshold);
884+
extern t32_t __ternary_tnot_t32(t32_t a);
885+
extern t32_t __ternary_tinv_t32(t32_t a);
886+
extern t32_t __ternary_tmuladd_t32(t32_t a, t32_t b, t32_t c);
887+
extern t32_t __ternary_tround_t32(t32_t a, unsigned drop);
888+
extern t32_t __ternary_tnormalize_t32(t32_t a);
889+
extern t32_t __ternary_tbias_t32(t32_t a, int64_t bias);
890+
extern t32_t __ternary_tmux_t32(t32_t sel, t32_t neg, t32_t zero, t32_t pos);
891+
extern t32_t __ternary_tequiv_t32(t32_t a, t32_t b);
892+
extern t32_t __ternary_txor_t32(t32_t a, t32_t b);
893+
extern int __ternary_tnet_t32(t32_t a);
894+
895+
extern t64_t __ternary_tmin_t64(t64_t a, t64_t b);
896+
extern t64_t __ternary_tmax_t64(t64_t a, t64_t b);
897+
extern t64_t __ternary_tmaj_t64(t64_t a, t64_t b, t64_t c);
898+
extern t64_t __ternary_tlimp_t64(t64_t antecedent, t64_t consequent);
899+
extern t64_t __ternary_tquant_t64(double value, double threshold);
900+
extern t64_t __ternary_tnot_t64(t64_t a);
901+
extern t64_t __ternary_tinv_t64(t64_t a);
902+
extern t64_t __ternary_tmuladd_t64(t64_t a, t64_t b, t64_t c);
903+
extern t64_t __ternary_tround_t64(t64_t a, unsigned drop);
904+
extern t64_t __ternary_tnormalize_t64(t64_t a);
905+
extern t64_t __ternary_tbias_t64(t64_t a, int64_t bias);
906+
extern t64_t __ternary_tmux_t64(t64_t sel, t64_t neg, t64_t zero, t64_t pos);
907+
extern t64_t __ternary_tequiv_t64(t64_t a, t64_t b);
908+
extern t64_t __ternary_txor_t64(t64_t a, t64_t b);
909+
extern int __ternary_tnet_t64(t64_t a);
910+
911+
#if defined(__BITINT_MAXWIDTH__) && __BITINT_MAXWIDTH__ >= 256 && !defined(__cplusplus)
912+
extern t128_t __ternary_tmin_t128(t128_t a, t128_t b);
913+
extern t128_t __ternary_tmax_t128(t128_t a, t128_t b);
914+
extern t128_t __ternary_tmaj_t128(t128_t a, t128_t b, t128_t c);
915+
extern t128_t __ternary_tlimp_t128(t128_t antecedent, t128_t consequent);
916+
extern t128_t __ternary_tquant_t128(double value, double threshold);
917+
extern t128_t __ternary_tnot_t128(t128_t a);
918+
extern t128_t __ternary_tinv_t128(t128_t a);
919+
extern t128_t __ternary_tmuladd_t128(t128_t a, t128_t b, t128_t c);
920+
extern t128_t __ternary_tround_t128(t128_t a, unsigned drop);
921+
extern t128_t __ternary_tnormalize_t128(t128_t a);
922+
extern t128_t __ternary_tbias_t128(t128_t a, int64_t bias);
923+
extern t128_t __ternary_tmux_t128(t128_t sel, t128_t neg, t128_t zero, t128_t pos);
924+
extern t128_t __ternary_tequiv_t128(t128_t a, t128_t b);
925+
extern t128_t __ternary_txor_t128(t128_t a, t128_t b);
926+
extern int __ternary_tnet_t128(t128_t a);
927+
#endif
874928
#ifdef __cplusplus
875929
}
876930
#endif

include/ternary_plugin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ typedef unsigned __int128 v2t64_t; // 2 x t64
1919
typedef unsigned __int128 v4t64_t; // 4 x t64
2020

2121
// Balanced-ternary string literals (requires runtime helpers)
22+
#ifndef TERNARY_PLUGIN_SKIP_BT_STR
2223
extern t32_t __ternary_bt_str_t32(const char *s);
2324
extern t64_t __ternary_bt_str_t64(const char *s);
25+
#endif
2426
#define T32_LITERAL(s) __ternary_bt_str_t32(s)
2527
#define T64_LITERAL(s) __ternary_bt_str_t64(s)
2628
#define __ternary(N) t##N##_t

include/ternary_runtime.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,21 @@ typedef int64_t ternary_cond_t;
1616
#ifndef TERNARY_USE_BUILTIN_TYPES
1717
typedef uint64_t t32_t; /* 32 trits -> 64 bits */
1818
typedef unsigned __int128 t64_t; /* 64 trits -> 128 bits */
19+
#if defined(__BITINT_MAXWIDTH__) && __BITINT_MAXWIDTH__ >= 256 && !defined(__cplusplus)
20+
typedef unsigned _BitInt(256) t128_t; /* 128 trits -> 256 bits */
21+
#endif
1922
typedef unsigned __int128 tv32_t; /* vector of 2 x t32_t (128 bits) */
2023
typedef struct { unsigned __int128 lo, hi; } tv64_t; /* vector of 2 x t64_t (256 bits) */
24+
#if defined(__BITINT_MAXWIDTH__) && __BITINT_MAXWIDTH__ >= 256 && !defined(__cplusplus)
2125
typedef struct { unsigned __int128 lo, hi; } tv128_t; /* vector of 2 x t128_t (512 bits) */
2226
#endif
27+
#endif
2328

2429
/* Varargs helpers for ternary packed types. */
2530
#define TERNARY_VA_ARG_T32(ap) ((t32_t)va_arg(ap, uint64_t))
2631
#define TERNARY_VA_ARG_T64(ap) ((t64_t)va_arg(ap, unsigned __int128))
2732

28-
/* Note: t128 helpers are not provided in this header. */
33+
/* t128 helpers are exposed when `_BitInt(256)` is available at compile time. */
2934

3035
/* Select helpers for standard types. */
3136
int __ternary_select_i8(TERNARY_COND_T cond, int true_val, int false_val);
@@ -143,6 +148,24 @@ t64_t __ternary_f2t64_t64(double v);
143148
int __ternary_cmp_t64(t64_t a, t64_t b);
144149
t64_t __ternary_bt_str_t64(const char *s);
145150

151+
#if defined(__BITINT_MAXWIDTH__) && __BITINT_MAXWIDTH__ >= 256 && !defined(__cplusplus)
152+
t128_t __ternary_tmin_t128(t128_t a, t128_t b);
153+
t128_t __ternary_tmax_t128(t128_t a, t128_t b);
154+
t128_t __ternary_tmaj_t128(t128_t a, t128_t b, t128_t c);
155+
t128_t __ternary_tlimp_t128(t128_t antecedent, t128_t consequent);
156+
t128_t __ternary_tquant_t128(double value, double threshold);
157+
t128_t __ternary_tnot_t128(t128_t a);
158+
t128_t __ternary_tinv_t128(t128_t a);
159+
t128_t __ternary_tmuladd_t128(t128_t a, t128_t b, t128_t c);
160+
t128_t __ternary_tround_t128(t128_t a, unsigned drop);
161+
t128_t __ternary_tnormalize_t128(t128_t a);
162+
t128_t __ternary_tbias_t128(t128_t a, int64_t bias);
163+
t128_t __ternary_tmux_t128(t128_t sel, t128_t neg, t128_t zero, t128_t pos);
164+
t128_t __ternary_tequiv_t128(t128_t a, t128_t b);
165+
t128_t __ternary_txor_t128(t128_t a, t128_t b);
166+
int __ternary_tnet_t128(t128_t a);
167+
#endif
168+
146169
/* Ternary-specific comparison operations for t64 (return ternary results) */
147170
t64_t __ternary_cmplt_t64(t64_t a, t64_t b);
148171
t64_t __ternary_cmpeq_t64(t64_t a, t64_t b);

0 commit comments

Comments
 (0)