@amritk/nish-x86_64-linux 0.32.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL.md +10 -8
- package/bin/nish +0 -0
- package/package.json +1 -1
- package/runtime/core.d.ts +83 -6
- package/runtime/core.mjs +90 -0
- package/runtime/nish.d.ts +83 -6
- package/runtime/nish.h +27 -4
- package/runtime/runtime-chacha20.c +366 -0
- package/scripts/build.sh +12 -9
- package/std/README.md +2 -1
- package/std/crypto/bcrypt-batch.ts +702 -0
- package/std/net/http1-codec.ts +81 -41
- package/std/net/http1-server.ts +62 -47
package/INSTALL.md
CHANGED
|
@@ -254,8 +254,8 @@ routes are
|
|
|
254
254
|
# on the musl host, with its own clang and the runtime from this repository
|
|
255
255
|
clang app.ll runtime/runtime.c runtime/runtime-os.c runtime/runtime-parallel.c \
|
|
256
256
|
runtime/runtime-cross.c runtime/runtime-host.c runtime/runtime-net.c \
|
|
257
|
-
runtime/runtime-simd.c runtime/runtime-aes.c runtime/runtime-sha256.c runtime/runtime-
|
|
258
|
-
runtime/runtime-bytes.c runtime/runtime-checksum.c runtime/runtime-sandbox.c \
|
|
257
|
+
runtime/runtime-simd.c runtime/runtime-aes.c runtime/runtime-sha256.c runtime/runtime-chacha20.c \
|
|
258
|
+
runtime/runtime-term.c runtime/runtime-bytes.c runtime/runtime-checksum.c runtime/runtime-sandbox.c \
|
|
259
259
|
runtime/runtime-shm.c runtime/runtime-region.c -lm -o app
|
|
260
260
|
```
|
|
261
261
|
|
|
@@ -392,7 +392,7 @@ it into `build/seed/`; `NISH_BOOTSTRAP=<path>` names one you already have and
|
|
|
392
392
|
skips the download. §2a has what the build does with it.
|
|
393
393
|
|
|
394
394
|
The published package ships `bin/` (the `nish` command, which is a launcher),
|
|
395
|
-
`runtime/` (the C runtime —
|
|
395
|
+
`runtime/` (the C runtime — sixteen translation units, the wasm subset and their
|
|
396
396
|
header — and `runtime/sqlite/`, SQLite's vendored source),
|
|
397
397
|
`scripts/build.sh` (the link pipeline), `std/` (the standard library) and
|
|
398
398
|
`docs/AI.md` (the rules card). The
|
|
@@ -405,14 +405,14 @@ working directory — and the binary runs from inside its own platform package
|
|
|
405
405
|
for exactly that reason.
|
|
406
406
|
|
|
407
407
|
Building the IR yourself rather than through `--link` means naming the runtime
|
|
408
|
-
on the `clang` line, and it is
|
|
408
|
+
on the `clang` line, and it is sixteen files:
|
|
409
409
|
|
|
410
410
|
```bash
|
|
411
411
|
clang app.ll runtime/runtime.c runtime/runtime-os.c runtime/runtime-parallel.c \
|
|
412
412
|
runtime/runtime-cross.c runtime/runtime-host.c runtime/runtime-net.c \
|
|
413
|
-
runtime/runtime-simd.c runtime/runtime-aes.c runtime/runtime-sha256.c runtime/runtime-
|
|
414
|
-
runtime/runtime-bytes.c runtime/runtime-checksum.c runtime/runtime-sandbox.c \
|
|
415
|
-
runtime/runtime-shm.c -lm -o app
|
|
413
|
+
runtime/runtime-simd.c runtime/runtime-aes.c runtime/runtime-sha256.c runtime/runtime-chacha20.c \
|
|
414
|
+
runtime/runtime-term.c runtime/runtime-bytes.c runtime/runtime-checksum.c runtime/runtime-sandbox.c \
|
|
415
|
+
runtime/runtime-shm.c runtime/runtime-region.c -lm -o app
|
|
416
416
|
```
|
|
417
417
|
|
|
418
418
|
`runtime.c` is the part every program touches — the arena, strings, arrays,
|
|
@@ -427,7 +427,9 @@ entropy, file times and signals, `runtime-net.c` the sockets of `nish:net`,
|
|
|
427
427
|
`runtime-simd.c` and `runtime-aes.c` the vector text search and AES-GCM,
|
|
428
428
|
`runtime-sha256.c` the SHA-256 block kernel `nish/crypto/sha256` hands its
|
|
429
429
|
blocks to on a CPU with the SHA instructions (`NISH_SHA256=soft` keeps the
|
|
430
|
-
portable path), `runtime-
|
|
430
|
+
portable path), `runtime-chacha20.c` the ChaCha20 keystream `nish/crypto/chacha20poly1305`
|
|
431
|
+
hands a message of 256 bytes or more to on a CPU with AVX2 or NEON (`NISH_CHACHA20=soft`
|
|
432
|
+
keeps the portable path), `runtime-term.c` the stdin reads and terminal calls of `nish:term`,
|
|
431
433
|
`runtime-bytes.c` the byte-class runs of `nish/bytes`, which `nish/json` steps
|
|
432
434
|
over, `runtime-checksum.c` the CRC-32 kernels of `nish/compress/checksum`,
|
|
433
435
|
`runtime-sandbox.c` the confinement a `--sandbox` build applies, and
|
package/bin/nish
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/runtime/core.d.ts
CHANGED
|
@@ -16,14 +16,30 @@ import type { f32, f64, i32, u16, u32, u8 } from "./core/numbers.js";
|
|
|
16
16
|
* `nish` does, but lets `===` and `<` through, which `nish` refuses. Under
|
|
17
17
|
* Node it is a typed array made once and never written after.
|
|
18
18
|
*/
|
|
19
|
-
export interface u8x16 { readonly __nishSimd: "u8x16"; readonly __lane: u8 }
|
|
20
|
-
export interface u16x8 { readonly __nishSimd: "u16x8"; readonly __lane: u16 }
|
|
21
|
-
export interface i32x4 { readonly __nishSimd: "i32x4"; readonly __lane: i32 }
|
|
22
|
-
export interface u32x4 { readonly __nishSimd: "u32x4"; readonly __lane: u32 }
|
|
23
|
-
export interface f32x4 { readonly __nishSimd: "f32x4"; readonly __lane: f32 }
|
|
24
|
-
export interface f64x2 { readonly __nishSimd: "f64x2"; readonly __lane: f64 }
|
|
19
|
+
export interface u8x16 { readonly __nishSimd: "u8x16"; readonly __lane: u8; readonly __mask: mask8x16 }
|
|
20
|
+
export interface u16x8 { readonly __nishSimd: "u16x8"; readonly __lane: u16; readonly __mask: mask16x8 }
|
|
21
|
+
export interface i32x4 { readonly __nishSimd: "i32x4"; readonly __lane: i32; readonly __mask: mask32x4 }
|
|
22
|
+
export interface u32x4 { readonly __nishSimd: "u32x4"; readonly __lane: u32; readonly __mask: mask32x4 }
|
|
23
|
+
export interface f32x4 { readonly __nishSimd: "f32x4"; readonly __lane: f32; readonly __mask: mask32x4 }
|
|
24
|
+
export interface f64x2 { readonly __nishSimd: "f64x2"; readonly __lane: f64; readonly __mask: mask64x2 }
|
|
25
25
|
/** Any of the six. */
|
|
26
26
|
export type SimdVector = u8x16 | u16x8 | i32x4 | u32x4 | f32x4 | f64x2;
|
|
27
|
+
/** The four with integer lanes. */
|
|
28
|
+
export type IntegerVector = u8x16 | u16x8 | i32x4 | u32x4;
|
|
29
|
+
/** The two with float lanes. */
|
|
30
|
+
export type FloatVector = f32x4 | f64x2;
|
|
31
|
+
/**
|
|
32
|
+
* One boolean per lane, which a lane-wise compare answers. Under Node an
|
|
33
|
+
* array of booleans. `nish` keeps a mask in a local, a parameter or a
|
|
34
|
+
* return of a function the module keeps, and nowhere else; it has no
|
|
35
|
+
* constructor.
|
|
36
|
+
*/
|
|
37
|
+
export interface mask8x16 { readonly __nishMask: "mask8x16" }
|
|
38
|
+
export interface mask16x8 { readonly __nishMask: "mask16x8" }
|
|
39
|
+
export interface mask32x4 { readonly __nishMask: "mask32x4" }
|
|
40
|
+
export interface mask64x2 { readonly __nishMask: "mask64x2" }
|
|
41
|
+
/** Any of the four. */
|
|
42
|
+
export type SimdMask = mask8x16 | mask16x8 | mask32x4 | mask64x2;
|
|
27
43
|
/** One value per lane, lane 0 first. */
|
|
28
44
|
export declare function u8x16(
|
|
29
45
|
a0: u8, a1: u8, a2: u8, a3: u8, a4: u8, a5: u8, a6: u8, a7: u8,
|
|
@@ -54,3 +70,64 @@ export declare function store<V extends SimdVector>(v: V, xs: V["__lane"][], i:
|
|
|
54
70
|
export declare function extract<V extends SimdVector>(v: V, k: i32): V["__lane"];
|
|
55
71
|
/** A new vector: `v` with lane `k` set to `x`. */
|
|
56
72
|
export declare function replace<V extends SimdVector>(v: V, k: i32, x: V["__lane"]): V;
|
|
73
|
+
/** Float lane arithmetic, lane by lane. An integer lane's form wraps. */
|
|
74
|
+
export declare function add<V extends FloatVector>(a: V, b: V): V;
|
|
75
|
+
export declare function sub<V extends FloatVector>(a: V, b: V): V;
|
|
76
|
+
export declare function mul<V extends FloatVector>(a: V, b: V): V;
|
|
77
|
+
export declare function div<V extends FloatVector>(a: V, b: V): V;
|
|
78
|
+
export declare function sqrt<V extends FloatVector>(a: V): V;
|
|
79
|
+
/** Integer lane arithmetic, wrapping at the lane width. */
|
|
80
|
+
export declare function addWrapping<V extends IntegerVector>(a: V, b: V): V;
|
|
81
|
+
export declare function subWrapping<V extends IntegerVector>(a: V, b: V): V;
|
|
82
|
+
export declare function mulWrapping<V extends IntegerVector>(a: V, b: V): V;
|
|
83
|
+
/** Negation and absolute value of float lanes: the sign bit. */
|
|
84
|
+
export declare function neg<V extends FloatVector>(a: V): V;
|
|
85
|
+
export declare function abs<V extends FloatVector>(a: V): V;
|
|
86
|
+
/** The lesser and the greater lane: a float NaN lane answers NaN. */
|
|
87
|
+
export declare function min<V extends SimdVector>(a: V, b: V): V;
|
|
88
|
+
export declare function max<V extends SimdVector>(a: V, b: V): V;
|
|
89
|
+
/** Bitwise, on integer lanes or lane by lane on two masks. */
|
|
90
|
+
export declare function and<V extends IntegerVector | SimdMask>(a: V, b: V): V;
|
|
91
|
+
export declare function or<V extends IntegerVector | SimdMask>(a: V, b: V): V;
|
|
92
|
+
export declare function xor<V extends IntegerVector | SimdMask>(a: V, b: V): V;
|
|
93
|
+
export declare function not<V extends IntegerVector | SimdMask>(a: V): V;
|
|
94
|
+
/** Lane-wise compares, answering the vector's mask. A float compare is ordered (`ne` unordered). */
|
|
95
|
+
export declare function eq<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
96
|
+
export declare function ne<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
97
|
+
export declare function lt<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
98
|
+
export declare function le<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
99
|
+
export declare function gt<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
100
|
+
export declare function ge<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
101
|
+
/** Lane `k` of `a` where lane `k` of `m` is set, else of `b`. */
|
|
102
|
+
export declare function select<V extends SimdVector>(m: V["__mask"], a: V, b: V): V;
|
|
103
|
+
/** Whether any lane, or every lane, is set. */
|
|
104
|
+
export declare function any(m: SimdMask): boolean;
|
|
105
|
+
export declare function all(m: SimdMask): boolean;
|
|
106
|
+
/** Lane `k`'s flag in bit `k`. */
|
|
107
|
+
export declare function bitmask(m: SimdMask): i32;
|
|
108
|
+
/**
|
|
109
|
+
* The lanes added: a `u8x16` or `u16x8` in an `i32`, a float vector in lane
|
|
110
|
+
* order. An `i32x4` or `u32x4` total is `sumWrapping`.
|
|
111
|
+
*/
|
|
112
|
+
export declare function sum(v: u8x16 | u16x8): i32;
|
|
113
|
+
export declare function sum(v: f32x4): f32;
|
|
114
|
+
export declare function sum(v: f64x2): f64;
|
|
115
|
+
export declare function sumWrapping(v: i32x4): i32;
|
|
116
|
+
export declare function sumWrapping(v: u32x4): u32;
|
|
117
|
+
/** Lanes picked from `a` then `b` by integer-literal indices, one per lane. */
|
|
118
|
+
export declare function shuffle<V extends SimdVector>(a: V, b: V, ...lanes: i32[]): V;
|
|
119
|
+
/**
|
|
120
|
+
* Shifts and rotates by an integer-literal count below the lane width:
|
|
121
|
+
* `shr` is logical on an unsigned lane and arithmetic on an `i32` lane.
|
|
122
|
+
*/
|
|
123
|
+
export declare function shl<V extends IntegerVector>(v: V, count: i32): V;
|
|
124
|
+
export declare function shr<V extends IntegerVector>(v: V, count: i32): V;
|
|
125
|
+
export declare function rotl<V extends IntegerVector>(v: V, count: i32): V;
|
|
126
|
+
export declare function rotr<V extends IntegerVector>(v: V, count: i32): V;
|
|
127
|
+
/** The same sixteen bytes read as another vector type. */
|
|
128
|
+
export declare function asU8x16(v: SimdVector): u8x16;
|
|
129
|
+
export declare function asU16x8(v: SimdVector): u16x8;
|
|
130
|
+
export declare function asI32x4(v: SimdVector): i32x4;
|
|
131
|
+
export declare function asU32x4(v: SimdVector): u32x4;
|
|
132
|
+
export declare function asF32x4(v: SimdVector): f32x4;
|
|
133
|
+
export declare function asF64x2(v: SimdVector): f64x2;
|
package/runtime/core.mjs
CHANGED
|
@@ -120,3 +120,93 @@ export function replace(v, k, x) {
|
|
|
120
120
|
out[k] = x;
|
|
121
121
|
return out;
|
|
122
122
|
}
|
|
123
|
+
|
|
124
|
+
// ---- `nish:simd` lane operations ---------------------------------------------
|
|
125
|
+
// Each answers a fresh vector of its operands' type, and the typed array does
|
|
126
|
+
// the wrapping: a `u8` sum stored into a `Uint8Array` keeps its low byte, as
|
|
127
|
+
// `add <16 x i8>` does. A mask is an array of booleans, one a lane. `f32`
|
|
128
|
+
// arithmetic rounds once, through the array, which for `+ - * /` and `sqrt` is
|
|
129
|
+
// the single rounding the native lane does: the double result of two floats
|
|
130
|
+
// rounds to the same float. `Math.min` and `Math.max` are `llvm.minimum` and
|
|
131
|
+
// `llvm.maximum`: a NaN lane answers NaN and -0 orders below +0.
|
|
132
|
+
|
|
133
|
+
const simdLanes = (a, f) => {
|
|
134
|
+
const out = new a.constructor(a.length);
|
|
135
|
+
for (let j = 0; j < a.length; j++) out[j] = f(a[j], j);
|
|
136
|
+
return out;
|
|
137
|
+
};
|
|
138
|
+
const simdMask = (a, f) => {
|
|
139
|
+
const out = new Array(a.length);
|
|
140
|
+
for (let j = 0; j < a.length; j++) out[j] = f(a[j], j);
|
|
141
|
+
return out;
|
|
142
|
+
};
|
|
143
|
+
const simdBits = (a) => a.BYTES_PER_ELEMENT * 8;
|
|
144
|
+
|
|
145
|
+
export const add = (a, b) => simdLanes(a, (x, j) => x + b[j]);
|
|
146
|
+
export const sub = (a, b) => simdLanes(a, (x, j) => x - b[j]);
|
|
147
|
+
export const mul = (a, b) => simdLanes(a, (x, j) => x * b[j]);
|
|
148
|
+
export const div = (a, b) => simdLanes(a, (x, j) => x / b[j]);
|
|
149
|
+
export const neg = (a) => simdLanes(a, (x) => -x);
|
|
150
|
+
export const abs = (a) => simdLanes(a, (x) => Math.abs(x));
|
|
151
|
+
export const sqrt = (a) => simdLanes(a, (x) => Math.sqrt(x));
|
|
152
|
+
// A typed array wraps on store, so the integer forms share the float bodies.
|
|
153
|
+
export const addWrapping = (a, b) => simdLanes(a, (x, j) => x + b[j]);
|
|
154
|
+
export const subWrapping = (a, b) => simdLanes(a, (x, j) => x - b[j]);
|
|
155
|
+
// A 32-bit product loses its low bits as a double; `Math.imul` keeps them.
|
|
156
|
+
export const mulWrapping = (a, b) => simdLanes(a, (x, j) => (simdBits(a) === 32 ? Math.imul(x, b[j]) : x * b[j]));
|
|
157
|
+
export const min = (a, b) => simdLanes(a, (x, j) => Math.min(x, b[j]));
|
|
158
|
+
export const max = (a, b) => simdLanes(a, (x, j) => Math.max(x, b[j]));
|
|
159
|
+
|
|
160
|
+
/** `and`, `or`, `xor` and `not` take an integer vector or a mask. */
|
|
161
|
+
export const and = (a, b) => (Array.isArray(a) ? simdMask(a, (x, j) => x && b[j]) : simdLanes(a, (x, j) => x & b[j]));
|
|
162
|
+
export const or = (a, b) => (Array.isArray(a) ? simdMask(a, (x, j) => x || b[j]) : simdLanes(a, (x, j) => x | b[j]));
|
|
163
|
+
export const xor = (a, b) => (Array.isArray(a) ? simdMask(a, (x, j) => x !== b[j]) : simdLanes(a, (x, j) => x ^ b[j]));
|
|
164
|
+
export const not = (a) => (Array.isArray(a) ? simdMask(a, (x) => !x) : simdLanes(a, (x) => ~x));
|
|
165
|
+
|
|
166
|
+
// `ne` is the unordered compare: a NaN lane is unequal to everything.
|
|
167
|
+
export const eq = (a, b) => simdMask(a, (x, j) => x === b[j]);
|
|
168
|
+
export const ne = (a, b) => simdMask(a, (x, j) => x !== b[j]);
|
|
169
|
+
export const lt = (a, b) => simdMask(a, (x, j) => x < b[j]);
|
|
170
|
+
export const le = (a, b) => simdMask(a, (x, j) => x <= b[j]);
|
|
171
|
+
export const gt = (a, b) => simdMask(a, (x, j) => x > b[j]);
|
|
172
|
+
export const ge = (a, b) => simdMask(a, (x, j) => x >= b[j]);
|
|
173
|
+
|
|
174
|
+
export const select = (m, a, b) => simdLanes(a, (x, j) => (m[j] ? x : b[j]));
|
|
175
|
+
export const any = (m) => m.some((x) => x);
|
|
176
|
+
export const all = (m) => m.every((x) => x);
|
|
177
|
+
export const bitmask = (m) => m.reduce((bits, x, j) => (x ? bits | (1 << j) : bits), 0);
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* `sum`: a float vector's lanes added first to last from -0, rounding each
|
|
181
|
+
* step as `llvm.vector.reduce.fadd` does; a `u8` or `u16` vector's, which
|
|
182
|
+
* cannot overflow an `i32`.
|
|
183
|
+
*/
|
|
184
|
+
export const sum = (a) => {
|
|
185
|
+
let acc = -0;
|
|
186
|
+
for (const x of a) acc = a instanceof Float32Array ? Math.fround(acc + x) : acc + x;
|
|
187
|
+
return acc;
|
|
188
|
+
};
|
|
189
|
+
/** `sumWrapping`: a 32-bit vector's lanes added modulo 2^32. */
|
|
190
|
+
export const sumWrapping = (a) => {
|
|
191
|
+
let acc = 0;
|
|
192
|
+
for (const x of a) acc = (acc + x) | 0;
|
|
193
|
+
return a instanceof Uint32Array ? acc >>> 0 : acc;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
/** `shuffle(a, b, ...lanes)`: lane `k` of the 2N lanes `a` then `b`. */
|
|
197
|
+
export const shuffle = (a, b, ...lanes) => simdLanes(a, (_, j) => (lanes[j] < a.length ? a[lanes[j]] : b[lanes[j] - a.length]));
|
|
198
|
+
|
|
199
|
+
// A count is a constant below the lane width, so `x >>> (w - k)` is a real
|
|
200
|
+
// shift; at k = 0 and w = 32 JavaScript's count wraps to 0, and the `|` keeps x.
|
|
201
|
+
export const shl = (a, k) => simdLanes(a, (x) => x << k);
|
|
202
|
+
export const shr = (a, k) => simdLanes(a, (x) => (a instanceof Int32Array ? x >> k : x >>> k));
|
|
203
|
+
export const rotl = (a, k) => simdLanes(a, (x) => (x << k) | (x >>> (simdBits(a) - k)));
|
|
204
|
+
export const rotr = (a, k) => simdLanes(a, (x) => (x >>> k) | (x << (simdBits(a) - k)));
|
|
205
|
+
|
|
206
|
+
const simdAs = (Lanes) => (v) => new Lanes(v.buffer.slice(v.byteOffset, v.byteOffset + 16));
|
|
207
|
+
export const asU8x16 = simdAs(Uint8Array);
|
|
208
|
+
export const asU16x8 = simdAs(Uint16Array);
|
|
209
|
+
export const asI32x4 = simdAs(Int32Array);
|
|
210
|
+
export const asU32x4 = simdAs(Uint32Array);
|
|
211
|
+
export const asF32x4 = simdAs(Float32Array);
|
|
212
|
+
export const asF64x2 = simdAs(Float64Array);
|
package/runtime/nish.d.ts
CHANGED
|
@@ -856,14 +856,30 @@ declare module "nish:simd" {
|
|
|
856
856
|
* `nish` does, but lets `===` and `<` through, which `nish` refuses. Under
|
|
857
857
|
* Node it is a typed array made once and never written after.
|
|
858
858
|
*/
|
|
859
|
-
export interface u8x16 { readonly __nishSimd: "u8x16"; readonly __lane: u8 }
|
|
860
|
-
export interface u16x8 { readonly __nishSimd: "u16x8"; readonly __lane: u16 }
|
|
861
|
-
export interface i32x4 { readonly __nishSimd: "i32x4"; readonly __lane: i32 }
|
|
862
|
-
export interface u32x4 { readonly __nishSimd: "u32x4"; readonly __lane: u32 }
|
|
863
|
-
export interface f32x4 { readonly __nishSimd: "f32x4"; readonly __lane: f32 }
|
|
864
|
-
export interface f64x2 { readonly __nishSimd: "f64x2"; readonly __lane: f64 }
|
|
859
|
+
export interface u8x16 { readonly __nishSimd: "u8x16"; readonly __lane: u8; readonly __mask: mask8x16 }
|
|
860
|
+
export interface u16x8 { readonly __nishSimd: "u16x8"; readonly __lane: u16; readonly __mask: mask16x8 }
|
|
861
|
+
export interface i32x4 { readonly __nishSimd: "i32x4"; readonly __lane: i32; readonly __mask: mask32x4 }
|
|
862
|
+
export interface u32x4 { readonly __nishSimd: "u32x4"; readonly __lane: u32; readonly __mask: mask32x4 }
|
|
863
|
+
export interface f32x4 { readonly __nishSimd: "f32x4"; readonly __lane: f32; readonly __mask: mask32x4 }
|
|
864
|
+
export interface f64x2 { readonly __nishSimd: "f64x2"; readonly __lane: f64; readonly __mask: mask64x2 }
|
|
865
865
|
/** Any of the six. */
|
|
866
866
|
export type SimdVector = u8x16 | u16x8 | i32x4 | u32x4 | f32x4 | f64x2;
|
|
867
|
+
/** The four with integer lanes. */
|
|
868
|
+
export type IntegerVector = u8x16 | u16x8 | i32x4 | u32x4;
|
|
869
|
+
/** The two with float lanes. */
|
|
870
|
+
export type FloatVector = f32x4 | f64x2;
|
|
871
|
+
/**
|
|
872
|
+
* One boolean per lane, which a lane-wise compare answers. Under Node an
|
|
873
|
+
* array of booleans. `nish` keeps a mask in a local, a parameter or a
|
|
874
|
+
* return of a function the module keeps, and nowhere else; it has no
|
|
875
|
+
* constructor.
|
|
876
|
+
*/
|
|
877
|
+
export interface mask8x16 { readonly __nishMask: "mask8x16" }
|
|
878
|
+
export interface mask16x8 { readonly __nishMask: "mask16x8" }
|
|
879
|
+
export interface mask32x4 { readonly __nishMask: "mask32x4" }
|
|
880
|
+
export interface mask64x2 { readonly __nishMask: "mask64x2" }
|
|
881
|
+
/** Any of the four. */
|
|
882
|
+
export type SimdMask = mask8x16 | mask16x8 | mask32x4 | mask64x2;
|
|
867
883
|
/** One value per lane, lane 0 first. */
|
|
868
884
|
export function u8x16(
|
|
869
885
|
a0: u8, a1: u8, a2: u8, a3: u8, a4: u8, a5: u8, a6: u8, a7: u8,
|
|
@@ -894,6 +910,67 @@ declare module "nish:simd" {
|
|
|
894
910
|
export function extract<V extends SimdVector>(v: V, k: i32): V["__lane"];
|
|
895
911
|
/** A new vector: `v` with lane `k` set to `x`. */
|
|
896
912
|
export function replace<V extends SimdVector>(v: V, k: i32, x: V["__lane"]): V;
|
|
913
|
+
/** Float lane arithmetic, lane by lane. An integer lane's form wraps. */
|
|
914
|
+
export function add<V extends FloatVector>(a: V, b: V): V;
|
|
915
|
+
export function sub<V extends FloatVector>(a: V, b: V): V;
|
|
916
|
+
export function mul<V extends FloatVector>(a: V, b: V): V;
|
|
917
|
+
export function div<V extends FloatVector>(a: V, b: V): V;
|
|
918
|
+
export function sqrt<V extends FloatVector>(a: V): V;
|
|
919
|
+
/** Integer lane arithmetic, wrapping at the lane width. */
|
|
920
|
+
export function addWrapping<V extends IntegerVector>(a: V, b: V): V;
|
|
921
|
+
export function subWrapping<V extends IntegerVector>(a: V, b: V): V;
|
|
922
|
+
export function mulWrapping<V extends IntegerVector>(a: V, b: V): V;
|
|
923
|
+
/** Negation and absolute value of float lanes: the sign bit. */
|
|
924
|
+
export function neg<V extends FloatVector>(a: V): V;
|
|
925
|
+
export function abs<V extends FloatVector>(a: V): V;
|
|
926
|
+
/** The lesser and the greater lane: a float NaN lane answers NaN. */
|
|
927
|
+
export function min<V extends SimdVector>(a: V, b: V): V;
|
|
928
|
+
export function max<V extends SimdVector>(a: V, b: V): V;
|
|
929
|
+
/** Bitwise, on integer lanes or lane by lane on two masks. */
|
|
930
|
+
export function and<V extends IntegerVector | SimdMask>(a: V, b: V): V;
|
|
931
|
+
export function or<V extends IntegerVector | SimdMask>(a: V, b: V): V;
|
|
932
|
+
export function xor<V extends IntegerVector | SimdMask>(a: V, b: V): V;
|
|
933
|
+
export function not<V extends IntegerVector | SimdMask>(a: V): V;
|
|
934
|
+
/** Lane-wise compares, answering the vector's mask. A float compare is ordered (`ne` unordered). */
|
|
935
|
+
export function eq<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
936
|
+
export function ne<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
937
|
+
export function lt<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
938
|
+
export function le<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
939
|
+
export function gt<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
940
|
+
export function ge<V extends SimdVector>(a: V, b: V): V["__mask"];
|
|
941
|
+
/** Lane `k` of `a` where lane `k` of `m` is set, else of `b`. */
|
|
942
|
+
export function select<V extends SimdVector>(m: V["__mask"], a: V, b: V): V;
|
|
943
|
+
/** Whether any lane, or every lane, is set. */
|
|
944
|
+
export function any(m: SimdMask): boolean;
|
|
945
|
+
export function all(m: SimdMask): boolean;
|
|
946
|
+
/** Lane `k`'s flag in bit `k`. */
|
|
947
|
+
export function bitmask(m: SimdMask): i32;
|
|
948
|
+
/**
|
|
949
|
+
* The lanes added: a `u8x16` or `u16x8` in an `i32`, a float vector in lane
|
|
950
|
+
* order. An `i32x4` or `u32x4` total is `sumWrapping`.
|
|
951
|
+
*/
|
|
952
|
+
export function sum(v: u8x16 | u16x8): i32;
|
|
953
|
+
export function sum(v: f32x4): f32;
|
|
954
|
+
export function sum(v: f64x2): f64;
|
|
955
|
+
export function sumWrapping(v: i32x4): i32;
|
|
956
|
+
export function sumWrapping(v: u32x4): u32;
|
|
957
|
+
/** Lanes picked from `a` then `b` by integer-literal indices, one per lane. */
|
|
958
|
+
export function shuffle<V extends SimdVector>(a: V, b: V, ...lanes: i32[]): V;
|
|
959
|
+
/**
|
|
960
|
+
* Shifts and rotates by an integer-literal count below the lane width:
|
|
961
|
+
* `shr` is logical on an unsigned lane and arithmetic on an `i32` lane.
|
|
962
|
+
*/
|
|
963
|
+
export function shl<V extends IntegerVector>(v: V, count: i32): V;
|
|
964
|
+
export function shr<V extends IntegerVector>(v: V, count: i32): V;
|
|
965
|
+
export function rotl<V extends IntegerVector>(v: V, count: i32): V;
|
|
966
|
+
export function rotr<V extends IntegerVector>(v: V, count: i32): V;
|
|
967
|
+
/** The same sixteen bytes read as another vector type. */
|
|
968
|
+
export function asU8x16(v: SimdVector): u8x16;
|
|
969
|
+
export function asU16x8(v: SimdVector): u16x8;
|
|
970
|
+
export function asI32x4(v: SimdVector): i32x4;
|
|
971
|
+
export function asU32x4(v: SimdVector): u32x4;
|
|
972
|
+
export function asF32x4(v: SimdVector): f32x4;
|
|
973
|
+
export function asF64x2(v: SimdVector): f64x2;
|
|
897
974
|
}
|
|
898
975
|
|
|
899
976
|
declare module "nish:io" {
|
package/runtime/nish.h
CHANGED
|
@@ -10,15 +10,16 @@
|
|
|
10
10
|
* clock, `nish_platform` / `nish_arch` — and runtime-parallel.c, runtime-host.c,
|
|
11
11
|
* runtime-net.c, runtime-simd.c (the byte searches that read a vector at a
|
|
12
12
|
* time), runtime-aes.c (AES-GCM on the CPU's AES instructions),
|
|
13
|
-
* runtime-sha256.c (SHA-256 on the CPU's SHA instructions), runtime-
|
|
13
|
+
* runtime-sha256.c (SHA-256 on the CPU's SHA instructions), runtime-chacha20.c
|
|
14
|
+
* (ChaCha20's keystream on AVX2 or NEON vectors), runtime-checksum.c
|
|
14
15
|
* (CRC-32 on its carry-less multiply or CRC instructions) and runtime-term.c
|
|
15
16
|
* (stdin and the terminal, `nish:term`) split off
|
|
16
17
|
* the same way since. They are separate so that each carries its own measured
|
|
17
18
|
* code-size ceiling (docs/wp7-runtime.md, "Runtime additions and budget"); a
|
|
18
19
|
* host links all of them, which `scripts/build.sh` does for you when handed
|
|
19
|
-
* runtime.c, runtime-aes.c, runtime-sha256.c and runtime-checksum.c
|
|
20
|
-
* compiler calls their kernels from std/crypto/aes.ts,
|
|
21
|
-
* std/compress/checksum.ts, so `scripts/build.sh` pairs each of them with
|
|
20
|
+
* runtime.c, runtime-aes.c, runtime-sha256.c, runtime-chacha20.c and runtime-checksum.c
|
|
21
|
+
* included: the compiler calls their kernels from std/crypto/aes.ts,
|
|
22
|
+
* std/crypto/sha256.ts, std/crypto/chacha20poly1305.ts and std/compress/checksum.ts, so `scripts/build.sh` pairs each of them with
|
|
22
23
|
* runtime.c and `src/run-cache.ts` caches them like the others. `tests/run.js` checks that every runtime function
|
|
23
24
|
* declared in runtime.ts has a prototype in this file.
|
|
24
25
|
*
|
|
@@ -400,6 +401,28 @@ int32_t nish_sha256_hw(void);
|
|
|
400
401
|
guard, so the caller's fallback panics as the Nish function does. `w` (u32[],
|
|
401
402
|
the message schedule the Nish code fills) is neither read nor written. */
|
|
402
403
|
int32_t nish_sha256_compress(nish_array *h, const nish_array *w, const nish_array *src, int32_t at);
|
|
404
|
+
/* ---- ChaCha20 on vectors ----------------------------------------------------
|
|
405
|
+
* runtime/runtime-chacha20.c: eight blocks at once on AVX2 and four in 128-bit
|
|
406
|
+
* vectors on x86-64, four in NEON on AArch64. The compiler calls the kernel in
|
|
407
|
+
* place of std/crypto/chacha20poly1305.ts's private `chacha20XorInto`, behind
|
|
408
|
+
* `nish_chacha20_hw`, and calls the Nish function itself when either answers 0.
|
|
409
|
+
* Constant time in the key, the nonce and the data. */
|
|
410
|
+
/* 1 when this process runs the kernel, 0 when it runs the Nish code. Resolved
|
|
411
|
+
on the first call and fixed from then on: `NISH_CHACHA20=soft` pins 0; unset,
|
|
412
|
+
`hw` or any other value is the best this machine has: CPUID's AVX2 with the
|
|
413
|
+
OS saving the YMM registers (XGETBV) on x86-64, NEON on AArch64. Always 0 on
|
|
414
|
+
other targets, wasm32 among them. */
|
|
415
|
+
int32_t nish_chacha20_hw(void);
|
|
416
|
+
/* RFC 8439 §2.4's encryption of src[srcAt..srcAt + len) (u8[]) into
|
|
417
|
+
dst[dstAt..dstAt + len) (u8[]) under the ChaCha20 state state[0..16) (u32[]),
|
|
418
|
+
whose block counter state[12] advances one per 64-byte block, as
|
|
419
|
+
`chacha20XorInto` does; 1 when it ran. Answers 0 and writes nothing when
|
|
420
|
+
state.len < 16, len < 256, an offset is negative, a window is outside its
|
|
421
|
+
array, or the windows overlap without being the same bytes, so the Nish
|
|
422
|
+
function runs as it would have. The keystream it makes is wiped before it
|
|
423
|
+
returns; the state is the caller's. */
|
|
424
|
+
int32_t nish_chacha20_xor(nish_array *state, const nish_array *src, int32_t src_at, int32_t len, nish_array *dst,
|
|
425
|
+
int32_t dst_at);
|
|
403
426
|
/* ---- CRC-32 on the CPU's carry-less multiply or CRC instructions ---------
|
|
404
427
|
* runtime/runtime-checksum.c: PCLMULQDQ folding on x86-64, the ARMv8 CRC32
|
|
405
428
|
* instructions on AArch64. The compiler calls the kernel in
|