@fluffylabs/anan-as 1.2.0-69743c7 → 1.2.0-ef04361
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/dist/bin/src/trace-replay.js +2 -2
- package/dist/build/compiler-inline.js +1 -1
- package/dist/build/compiler.wasm +0 -0
- package/dist/build/debug-inline.js +1 -1
- package/dist/build/debug-raw-inline.js +1 -1
- package/dist/build/debug-raw.d.ts +34 -98
- package/dist/build/debug-raw.js +51 -105
- package/dist/build/debug-raw.wasm +0 -0
- package/dist/build/debug.d.ts +34 -98
- package/dist/build/debug.js +53 -112
- package/dist/build/debug.wasm +0 -0
- package/dist/build/js/assembly/api-debugger.d.ts +55 -0
- package/dist/build/js/assembly/api-debugger.js +245 -0
- package/dist/build/js/assembly/api-internal.d.ts +13 -0
- package/dist/build/js/assembly/api-internal.js +192 -0
- package/dist/build/js/assembly/api-types.d.ts +45 -0
- package/dist/build/js/assembly/api-types.js +53 -0
- package/dist/build/js/assembly/api-utils.d.ts +71 -0
- package/dist/build/js/assembly/api-utils.js +206 -0
- package/dist/build/js/assembly/arguments.d.ts +44 -0
- package/dist/build/js/assembly/arguments.js +164 -0
- package/dist/build/js/assembly/codec.d.ts +24 -0
- package/dist/build/js/assembly/codec.js +139 -0
- package/dist/build/js/assembly/gas-costs.d.ts +6 -0
- package/dist/build/js/assembly/gas-costs.js +39 -0
- package/dist/build/js/assembly/gas.d.ts +16 -0
- package/dist/build/js/assembly/gas.js +23 -0
- package/dist/build/js/assembly/index-shared.d.ts +4 -0
- package/dist/build/js/assembly/index-shared.js +4 -0
- package/dist/build/js/assembly/instructions/bit.d.ts +11 -0
- package/dist/build/js/assembly/instructions/bit.js +53 -0
- package/dist/build/js/assembly/instructions/branch.d.ts +17 -0
- package/dist/build/js/assembly/instructions/branch.js +120 -0
- package/dist/build/js/assembly/instructions/jump.d.ts +5 -0
- package/dist/build/js/assembly/instructions/jump.js +21 -0
- package/dist/build/js/assembly/instructions/load.d.ts +17 -0
- package/dist/build/js/assembly/instructions/load.js +134 -0
- package/dist/build/js/assembly/instructions/logic.d.ts +10 -0
- package/dist/build/js/assembly/instructions/logic.js +47 -0
- package/dist/build/js/assembly/instructions/math.d.ts +28 -0
- package/dist/build/js/assembly/instructions/math.js +225 -0
- package/dist/build/js/assembly/instructions/misc.d.ts +6 -0
- package/dist/build/js/assembly/instructions/misc.js +22 -0
- package/dist/build/js/assembly/instructions/mov.d.ts +6 -0
- package/dist/build/js/assembly/instructions/mov.js +35 -0
- package/dist/build/js/assembly/instructions/outcome.d.ts +30 -0
- package/dist/build/js/assembly/instructions/outcome.js +63 -0
- package/dist/build/js/assembly/instructions/rot.d.ts +15 -0
- package/dist/build/js/assembly/instructions/rot.js +66 -0
- package/dist/build/js/assembly/instructions/set.d.ts +7 -0
- package/dist/build/js/assembly/instructions/set.js +36 -0
- package/dist/build/js/assembly/instructions/shift.d.ts +19 -0
- package/dist/build/js/assembly/instructions/shift.js +121 -0
- package/dist/build/js/assembly/instructions/store.d.ts +17 -0
- package/dist/build/js/assembly/instructions/store.js +101 -0
- package/dist/build/js/assembly/instructions/utils.d.ts +23 -0
- package/dist/build/js/assembly/instructions/utils.js +75 -0
- package/dist/build/js/assembly/instructions-exe.d.ts +2 -0
- package/dist/build/js/assembly/instructions-exe.js +245 -0
- package/dist/build/js/assembly/instructions.d.ts +11 -0
- package/dist/build/js/assembly/instructions.js +252 -0
- package/dist/build/js/assembly/interpreter.d.ts +29 -0
- package/dist/build/js/assembly/interpreter.js +229 -0
- package/dist/build/js/assembly/math.d.ts +8 -0
- package/dist/build/js/assembly/math.js +14 -0
- package/dist/build/js/assembly/memory-page.d.ts +38 -0
- package/dist/build/js/assembly/memory-page.js +68 -0
- package/dist/build/js/assembly/memory.d.ts +82 -0
- package/dist/build/js/assembly/memory.js +386 -0
- package/dist/build/js/assembly/portable.d.ts +24 -0
- package/dist/build/js/assembly/portable.js +362 -0
- package/dist/build/js/assembly/program-build.d.ts +2 -0
- package/dist/build/js/assembly/program-build.js +104 -0
- package/dist/build/js/assembly/program.d.ts +78 -0
- package/dist/build/js/assembly/program.js +284 -0
- package/dist/build/js/assembly/registers.d.ts +6 -0
- package/dist/build/js/assembly/registers.js +9 -0
- package/dist/build/js/assembly/spi.d.ts +92 -0
- package/dist/build/js/assembly/spi.js +152 -0
- package/dist/build/js/portable/bootstrap.d.ts +1 -0
- package/dist/build/js/portable/bootstrap.js +5 -0
- package/dist/build/js/portable/index.d.ts +4 -0
- package/dist/build/js/portable/index.js +6 -0
- package/dist/build/js/portable-bundle.js +4309 -0
- package/dist/build/release-inline.js +1 -1
- package/dist/build/release-mini-inline.js +1 -1
- package/dist/build/release-mini.d.ts +34 -98
- package/dist/build/release-mini.js +53 -112
- package/dist/build/release-mini.wasm +0 -0
- package/dist/build/release-stub-inline.js +1 -1
- package/dist/build/release-stub.d.ts +34 -98
- package/dist/build/release-stub.js +53 -112
- package/dist/build/release-stub.wasm +0 -0
- package/dist/build/release.d.ts +34 -98
- package/dist/build/release.js +53 -112
- package/dist/build/release.wasm +0 -0
- package/dist/build/test-inline.js +1 -1
- package/dist/build/test.wasm +0 -0
- package/dist/test/test-w3f-common.js +126 -0
- package/dist/test/test-w3f-portable.js +5 -0
- package/dist/test/test-w3f.js +3 -120
- package/package.json +11 -4
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MaybePageFault } from "../memory";
|
|
2
|
+
import { hostCall, ok, okOrFault, panic } from "./outcome";
|
|
3
|
+
import { reg } from "./utils";
|
|
4
|
+
const faultRes = new MaybePageFault();
|
|
5
|
+
// INVALID
|
|
6
|
+
export const INVALID = (r) => panic(r);
|
|
7
|
+
// TRAP
|
|
8
|
+
export const trap = (r) => panic(r);
|
|
9
|
+
// FALLTHROUGH
|
|
10
|
+
export const fallthrough = (r) => ok(r);
|
|
11
|
+
// ECALLI
|
|
12
|
+
export const ecalli = (r, args) => hostCall(r, args.a);
|
|
13
|
+
// SBRK
|
|
14
|
+
export const sbrk = (r, args, registers, memory) => {
|
|
15
|
+
const res = memory.sbrk(faultRes, u32(registers[reg(args.a)]));
|
|
16
|
+
// out of memory
|
|
17
|
+
if (faultRes.isFault) {
|
|
18
|
+
return okOrFault(r, faultRes);
|
|
19
|
+
}
|
|
20
|
+
registers[reg(args.b)] = res;
|
|
21
|
+
return ok(r);
|
|
22
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { InstructionRun } from "./outcome";
|
|
2
|
+
export declare const move_reg: InstructionRun;
|
|
3
|
+
export declare const cmov_iz_imm: InstructionRun;
|
|
4
|
+
export declare const cmov_nz_imm: InstructionRun;
|
|
5
|
+
export declare const cmov_iz: InstructionRun;
|
|
6
|
+
export declare const cmov_nz: InstructionRun;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ok } from "./outcome";
|
|
2
|
+
import { reg, u32SignExtend } from "./utils";
|
|
3
|
+
// MOVE_REG
|
|
4
|
+
export const move_reg = (r, args, registers) => {
|
|
5
|
+
registers[reg(args.b)] = registers[reg(args.a)];
|
|
6
|
+
return ok(r);
|
|
7
|
+
};
|
|
8
|
+
// CMOV_IZ_IMM
|
|
9
|
+
export const cmov_iz_imm = (r, args, registers) => {
|
|
10
|
+
if (registers[reg(args.a)] === u64(0)) {
|
|
11
|
+
registers[reg(args.b)] = u32SignExtend(args.c);
|
|
12
|
+
}
|
|
13
|
+
return ok(r);
|
|
14
|
+
};
|
|
15
|
+
// CMOV_NZ_IMM
|
|
16
|
+
export const cmov_nz_imm = (r, args, registers) => {
|
|
17
|
+
if (registers[reg(args.a)] !== u64(0)) {
|
|
18
|
+
registers[reg(args.b)] = u32SignExtend(args.c);
|
|
19
|
+
}
|
|
20
|
+
return ok(r);
|
|
21
|
+
};
|
|
22
|
+
// CMOV_IZ
|
|
23
|
+
export const cmov_iz = (r, args, registers) => {
|
|
24
|
+
if (registers[reg(args.a)] === u64(0)) {
|
|
25
|
+
registers[reg(args.c)] = registers[reg(args.b)];
|
|
26
|
+
}
|
|
27
|
+
return ok(r);
|
|
28
|
+
};
|
|
29
|
+
// CMOV_NZ
|
|
30
|
+
export const cmov_nz = (r, args, registers) => {
|
|
31
|
+
if (registers[reg(args.a)] !== u64(0)) {
|
|
32
|
+
registers[reg(args.c)] = registers[reg(args.b)];
|
|
33
|
+
}
|
|
34
|
+
return ok(r);
|
|
35
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Args } from "../arguments";
|
|
2
|
+
import { MaybePageFault, Memory } from "../memory";
|
|
3
|
+
import { Registers } from "../registers";
|
|
4
|
+
export type InstructionRun = (o: OutcomeData, args: Args, registers: Registers, memory: Memory) => OutcomeData;
|
|
5
|
+
export declare enum Result {
|
|
6
|
+
PANIC = 0,
|
|
7
|
+
FAULT = 1,
|
|
8
|
+
FAULT_ACCESS = 2,
|
|
9
|
+
HOST = 3
|
|
10
|
+
}
|
|
11
|
+
export declare enum Outcome {
|
|
12
|
+
Ok = 0,
|
|
13
|
+
StaticJump = 1,
|
|
14
|
+
DynamicJump = 2,
|
|
15
|
+
Result = 3
|
|
16
|
+
}
|
|
17
|
+
export declare class OutcomeData {
|
|
18
|
+
outcome: Outcome;
|
|
19
|
+
staticJump: i32;
|
|
20
|
+
dJump: u32;
|
|
21
|
+
result: Result;
|
|
22
|
+
exitCode: u32;
|
|
23
|
+
}
|
|
24
|
+
export declare function status(r: OutcomeData, result: Result): OutcomeData;
|
|
25
|
+
export declare function staticJump(r: OutcomeData, offset: i32): OutcomeData;
|
|
26
|
+
export declare function dJump(r: OutcomeData, address: u32): OutcomeData;
|
|
27
|
+
export declare function ok(r: OutcomeData): OutcomeData;
|
|
28
|
+
export declare function panic(r: OutcomeData): OutcomeData;
|
|
29
|
+
export declare function hostCall(r: OutcomeData, id: u32): OutcomeData;
|
|
30
|
+
export declare function okOrFault(r: OutcomeData, pageFault: MaybePageFault): OutcomeData;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export var Result;
|
|
2
|
+
(function (Result) {
|
|
3
|
+
Result[Result["PANIC"] = 0] = "PANIC";
|
|
4
|
+
Result[Result["FAULT"] = 1] = "FAULT";
|
|
5
|
+
Result[Result["FAULT_ACCESS"] = 2] = "FAULT_ACCESS";
|
|
6
|
+
Result[Result["HOST"] = 3] = "HOST";
|
|
7
|
+
})(Result || (Result = {}));
|
|
8
|
+
export var Outcome;
|
|
9
|
+
(function (Outcome) {
|
|
10
|
+
Outcome[Outcome["Ok"] = 0] = "Ok";
|
|
11
|
+
Outcome[Outcome["StaticJump"] = 1] = "StaticJump";
|
|
12
|
+
Outcome[Outcome["DynamicJump"] = 2] = "DynamicJump";
|
|
13
|
+
Outcome[Outcome["Result"] = 3] = "Result";
|
|
14
|
+
})(Outcome || (Outcome = {}));
|
|
15
|
+
// @unmanaged
|
|
16
|
+
export class OutcomeData {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.outcome = Outcome.Ok;
|
|
19
|
+
this.staticJump = 0;
|
|
20
|
+
this.dJump = 0;
|
|
21
|
+
this.result = Result.PANIC;
|
|
22
|
+
this.exitCode = 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function status(r, result) {
|
|
26
|
+
r.outcome = Outcome.Result;
|
|
27
|
+
r.result = result;
|
|
28
|
+
return r;
|
|
29
|
+
}
|
|
30
|
+
export function staticJump(r, offset) {
|
|
31
|
+
r.outcome = Outcome.StaticJump;
|
|
32
|
+
r.staticJump = offset;
|
|
33
|
+
return r;
|
|
34
|
+
}
|
|
35
|
+
export function dJump(r, address) {
|
|
36
|
+
r.outcome = Outcome.DynamicJump;
|
|
37
|
+
r.dJump = address;
|
|
38
|
+
return r;
|
|
39
|
+
}
|
|
40
|
+
export function ok(r) {
|
|
41
|
+
r.outcome = Outcome.Ok;
|
|
42
|
+
r.dJump = 0;
|
|
43
|
+
return r;
|
|
44
|
+
}
|
|
45
|
+
export function panic(r) {
|
|
46
|
+
return status(r, Result.PANIC);
|
|
47
|
+
}
|
|
48
|
+
export function hostCall(r, id) {
|
|
49
|
+
r.outcome = Outcome.Result;
|
|
50
|
+
r.result = Result.HOST;
|
|
51
|
+
r.exitCode = id;
|
|
52
|
+
return r;
|
|
53
|
+
}
|
|
54
|
+
export function okOrFault(r, pageFault) {
|
|
55
|
+
if (pageFault.isFault) {
|
|
56
|
+
r.outcome = Outcome.Result;
|
|
57
|
+
// not accessible memory does not result in `FAULT`, but rather goes straight to TRAP
|
|
58
|
+
// yet in gas calculations we still subtract 1, unlike TRAP, but like FAULT.
|
|
59
|
+
r.result = pageFault.isAccess ? Result.FAULT_ACCESS : Result.FAULT;
|
|
60
|
+
r.exitCode = pageFault.fault;
|
|
61
|
+
}
|
|
62
|
+
return r;
|
|
63
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { InstructionRun } from "./outcome";
|
|
2
|
+
export declare const rot_r_64_imm: InstructionRun;
|
|
3
|
+
export declare const rot_r_64_imm_alt: InstructionRun;
|
|
4
|
+
export declare const rot_r_32_imm: InstructionRun;
|
|
5
|
+
export declare const rot_r_32_imm_alt: InstructionRun;
|
|
6
|
+
export declare const rot_l_64: InstructionRun;
|
|
7
|
+
export declare const rot_l_32: InstructionRun;
|
|
8
|
+
export declare const rot_r_64: InstructionRun;
|
|
9
|
+
export declare const rot_r_32: InstructionRun;
|
|
10
|
+
export declare namespace math {
|
|
11
|
+
function rot_r(v: u64, shift: u64): u64;
|
|
12
|
+
function rot_r_32(v: u32, shift: u32): u32;
|
|
13
|
+
function rot_l(v: u64, shift: u64): u64;
|
|
14
|
+
function rot_l_32(v: u32, shift: u32): u32;
|
|
15
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { portable } from "../portable";
|
|
2
|
+
import { ok } from "./outcome";
|
|
3
|
+
import { reg, u32SignExtend } from "./utils";
|
|
4
|
+
// ROT_R_64_IMM
|
|
5
|
+
export const rot_r_64_imm = (r, args, regs) => {
|
|
6
|
+
regs[reg(args.b)] = math.rot_r(regs[reg(args.a)], u32SignExtend(args.c));
|
|
7
|
+
return ok(r);
|
|
8
|
+
};
|
|
9
|
+
// ROT_R_64_IMM_ALT
|
|
10
|
+
export const rot_r_64_imm_alt = (r, args, regs) => {
|
|
11
|
+
regs[reg(args.b)] = math.rot_r(u32SignExtend(args.c), regs[reg(args.a)]);
|
|
12
|
+
return ok(r);
|
|
13
|
+
};
|
|
14
|
+
// ROT_R_32_IMM
|
|
15
|
+
export const rot_r_32_imm = (r, args, regs) => {
|
|
16
|
+
regs[reg(args.b)] = u32SignExtend(math.rot_r_32(u32(regs[reg(args.a)]), u32(args.c)));
|
|
17
|
+
return ok(r);
|
|
18
|
+
};
|
|
19
|
+
// ROT_R_32_IMM_ALT
|
|
20
|
+
export const rot_r_32_imm_alt = (r, args, regs) => {
|
|
21
|
+
regs[reg(args.b)] = u32SignExtend(math.rot_r_32(u32(args.c), u32(regs[reg(args.a)])));
|
|
22
|
+
return ok(r);
|
|
23
|
+
};
|
|
24
|
+
// ROT_L_64
|
|
25
|
+
export const rot_l_64 = (r, args, regs) => {
|
|
26
|
+
regs[reg(args.c)] = math.rot_l(regs[reg(args.b)], regs[reg(args.a)]);
|
|
27
|
+
return ok(r);
|
|
28
|
+
};
|
|
29
|
+
// ROT_L_32
|
|
30
|
+
export const rot_l_32 = (r, args, regs) => {
|
|
31
|
+
regs[reg(args.c)] = u32SignExtend(math.rot_l_32(u32(regs[reg(args.b)]), u32(regs[reg(args.a)])));
|
|
32
|
+
return ok(r);
|
|
33
|
+
};
|
|
34
|
+
// ROT_R_64
|
|
35
|
+
export const rot_r_64 = (r, args, regs) => {
|
|
36
|
+
regs[reg(args.c)] = math.rot_r(regs[reg(args.b)], regs[reg(args.a)]);
|
|
37
|
+
return ok(r);
|
|
38
|
+
};
|
|
39
|
+
// ROT_R_32
|
|
40
|
+
export const rot_r_32 = (r, args, regs) => {
|
|
41
|
+
regs[reg(args.c)] = u32SignExtend(math.rot_r_32(u32(regs[reg(args.b)]), u32(regs[reg(args.a)])));
|
|
42
|
+
return ok(r);
|
|
43
|
+
};
|
|
44
|
+
export var math;
|
|
45
|
+
(function (math) {
|
|
46
|
+
// @inline
|
|
47
|
+
function rot_r(v, shift) {
|
|
48
|
+
return portable.rotr_u64(v, shift);
|
|
49
|
+
}
|
|
50
|
+
math.rot_r = rot_r;
|
|
51
|
+
// @inline
|
|
52
|
+
function rot_r_32(v, shift) {
|
|
53
|
+
return portable.rotr_u32(v, shift);
|
|
54
|
+
}
|
|
55
|
+
math.rot_r_32 = rot_r_32;
|
|
56
|
+
// @inline
|
|
57
|
+
function rot_l(v, shift) {
|
|
58
|
+
return portable.rotl_u64(v, shift);
|
|
59
|
+
}
|
|
60
|
+
math.rot_l = rot_l;
|
|
61
|
+
// @inline
|
|
62
|
+
function rot_l_32(v, shift) {
|
|
63
|
+
return portable.rotl_u32(v, shift);
|
|
64
|
+
}
|
|
65
|
+
math.rot_l_32 = rot_l_32;
|
|
66
|
+
})(math || (math = {}));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { InstructionRun } from "./outcome";
|
|
2
|
+
export declare const set_lt_u_imm: InstructionRun;
|
|
3
|
+
export declare const set_lt_s_imm: InstructionRun;
|
|
4
|
+
export declare const set_gt_u_imm: InstructionRun;
|
|
5
|
+
export declare const set_gt_s_imm: InstructionRun;
|
|
6
|
+
export declare const set_lt_u: InstructionRun;
|
|
7
|
+
export declare const set_lt_s: InstructionRun;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ok } from "./outcome";
|
|
2
|
+
import { reg, u32SignExtend } from "./utils";
|
|
3
|
+
// SET_LT_U_IMM
|
|
4
|
+
export const set_lt_u_imm = (r, args, registers) => {
|
|
5
|
+
const cond = registers[reg(args.a)] < u64(u32SignExtend(args.c));
|
|
6
|
+
registers[reg(args.b)] = cond ? u64(1) : u64(0);
|
|
7
|
+
return ok(r);
|
|
8
|
+
};
|
|
9
|
+
// SET_LT_S_IMM
|
|
10
|
+
export const set_lt_s_imm = (r, args, registers) => {
|
|
11
|
+
const cond = i64(registers[reg(args.a)]) < i64(u32SignExtend(args.c));
|
|
12
|
+
registers[reg(args.b)] = cond ? u64(1) : u64(0);
|
|
13
|
+
return ok(r);
|
|
14
|
+
};
|
|
15
|
+
// SET_GT_U_IMM
|
|
16
|
+
export const set_gt_u_imm = (r, args, registers) => {
|
|
17
|
+
const cond = registers[reg(args.a)] > u64(u32SignExtend(args.c));
|
|
18
|
+
registers[reg(args.b)] = cond ? u64(1) : u64(0);
|
|
19
|
+
return ok(r);
|
|
20
|
+
};
|
|
21
|
+
// SET_GT_S_IMM
|
|
22
|
+
export const set_gt_s_imm = (r, args, registers) => {
|
|
23
|
+
const cond = i64(registers[reg(args.a)]) > i64(u32SignExtend(args.c));
|
|
24
|
+
registers[reg(args.b)] = cond ? u64(1) : u64(0);
|
|
25
|
+
return ok(r);
|
|
26
|
+
};
|
|
27
|
+
// SET_LT_U
|
|
28
|
+
export const set_lt_u = (r, args, registers) => {
|
|
29
|
+
registers[reg(args.c)] = registers[reg(args.b)] < registers[reg(args.a)] ? u64(1) : u64(0);
|
|
30
|
+
return ok(r);
|
|
31
|
+
};
|
|
32
|
+
// SET_LT_S
|
|
33
|
+
export const set_lt_s = (r, args, registers) => {
|
|
34
|
+
registers[reg(args.c)] = i64(registers[reg(args.b)]) < i64(registers[reg(args.a)]) ? u64(1) : u64(0);
|
|
35
|
+
return ok(r);
|
|
36
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { InstructionRun } from "./outcome";
|
|
2
|
+
export declare const shlo_l_imm_32: InstructionRun;
|
|
3
|
+
export declare const shlo_r_imm_32: InstructionRun;
|
|
4
|
+
export declare const shar_r_imm_32: InstructionRun;
|
|
5
|
+
export declare const shlo_l_imm_alt_32: InstructionRun;
|
|
6
|
+
export declare const shlo_r_imm_alt_32: InstructionRun;
|
|
7
|
+
export declare const shar_r_imm_alt_32: InstructionRun;
|
|
8
|
+
export declare const shlo_l_imm: InstructionRun;
|
|
9
|
+
export declare const shlo_r_imm: InstructionRun;
|
|
10
|
+
export declare const shar_r_imm: InstructionRun;
|
|
11
|
+
export declare const shlo_l_imm_alt: InstructionRun;
|
|
12
|
+
export declare const shlo_r_imm_alt: InstructionRun;
|
|
13
|
+
export declare const shar_r_imm_alt: InstructionRun;
|
|
14
|
+
export declare const shlo_l_32: InstructionRun;
|
|
15
|
+
export declare const shlo_r_32: InstructionRun;
|
|
16
|
+
export declare const shar_r_32: InstructionRun;
|
|
17
|
+
export declare const shlo_l: InstructionRun;
|
|
18
|
+
export declare const shlo_r: InstructionRun;
|
|
19
|
+
export declare const shar_r: InstructionRun;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { ok } from "./outcome";
|
|
2
|
+
import { reg, u32SignExtend } from "./utils";
|
|
3
|
+
const MAX_SHIFT_64 = 64;
|
|
4
|
+
const MAX_SHIFT_32 = 32;
|
|
5
|
+
// SHLO_L_IMM_32
|
|
6
|
+
export const shlo_l_imm_32 = (r, args, registers) => {
|
|
7
|
+
const shift = u32(args.c % MAX_SHIFT_32);
|
|
8
|
+
const value = u32(registers[reg(args.a)]);
|
|
9
|
+
registers[reg(args.b)] = u32SignExtend(value << shift);
|
|
10
|
+
return ok(r);
|
|
11
|
+
};
|
|
12
|
+
// SHLO_R_IMM_32
|
|
13
|
+
export const shlo_r_imm_32 = (r, args, registers) => {
|
|
14
|
+
const shift = u32(args.c % MAX_SHIFT_32);
|
|
15
|
+
const value = u32(registers[reg(args.a)]);
|
|
16
|
+
registers[reg(args.b)] = u32SignExtend(value >>> shift);
|
|
17
|
+
return ok(r);
|
|
18
|
+
};
|
|
19
|
+
// SHAR_R_IMM_32
|
|
20
|
+
export const shar_r_imm_32 = (r, args, registers) => {
|
|
21
|
+
const shift = u32(args.c % MAX_SHIFT_32);
|
|
22
|
+
const value = u32SignExtend(u32(registers[reg(args.a)]));
|
|
23
|
+
registers[reg(args.b)] = u64(i64(value) >> i64(shift));
|
|
24
|
+
return ok(r);
|
|
25
|
+
};
|
|
26
|
+
// SHLO_L_IMM_ALT_32
|
|
27
|
+
export const shlo_l_imm_alt_32 = (r, args, registers) => {
|
|
28
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
29
|
+
registers[reg(args.b)] = u32SignExtend(args.c << shift);
|
|
30
|
+
return ok(r);
|
|
31
|
+
};
|
|
32
|
+
// SHLO_R_IMM_ALT_32
|
|
33
|
+
export const shlo_r_imm_alt_32 = (r, args, registers) => {
|
|
34
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
35
|
+
registers[reg(args.b)] = u32SignExtend(args.c >>> shift);
|
|
36
|
+
return ok(r);
|
|
37
|
+
};
|
|
38
|
+
// SHAR_R_IMM_ALT_32
|
|
39
|
+
export const shar_r_imm_alt_32 = (r, args, registers) => {
|
|
40
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
41
|
+
const imm = u32SignExtend(args.c);
|
|
42
|
+
registers[reg(args.b)] = u32SignExtend(u32(i64(imm) >> i64(shift)));
|
|
43
|
+
return ok(r);
|
|
44
|
+
};
|
|
45
|
+
// SHLO_L_IMM
|
|
46
|
+
export const shlo_l_imm = (r, args, registers) => {
|
|
47
|
+
const shift = u32(args.c % MAX_SHIFT_64);
|
|
48
|
+
registers[reg(args.b)] = u64(registers[reg(args.a)] << u64(shift));
|
|
49
|
+
return ok(r);
|
|
50
|
+
};
|
|
51
|
+
// SHLO_R_IMM
|
|
52
|
+
export const shlo_r_imm = (r, args, registers) => {
|
|
53
|
+
const shift = u32(args.c % MAX_SHIFT_64);
|
|
54
|
+
registers[reg(args.b)] = registers[reg(args.a)] >> u64(shift);
|
|
55
|
+
return ok(r);
|
|
56
|
+
};
|
|
57
|
+
// SHAR_R_IMM
|
|
58
|
+
export const shar_r_imm = (r, args, registers) => {
|
|
59
|
+
const shift = u32(args.c % MAX_SHIFT_64);
|
|
60
|
+
const value = i64(registers[reg(args.a)]);
|
|
61
|
+
registers[reg(args.b)] = u64(value >> i64(shift));
|
|
62
|
+
return ok(r);
|
|
63
|
+
};
|
|
64
|
+
// SHLO_L_IMM_ALT
|
|
65
|
+
export const shlo_l_imm_alt = (r, args, registers) => {
|
|
66
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
67
|
+
registers[reg(args.b)] = u64(u32SignExtend(args.c) << i64(shift));
|
|
68
|
+
return ok(r);
|
|
69
|
+
};
|
|
70
|
+
// SHLO_R_IMM_ALT
|
|
71
|
+
export const shlo_r_imm_alt = (r, args, registers) => {
|
|
72
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
73
|
+
registers[reg(args.b)] = u64(u32SignExtend(args.c)) >> u64(shift);
|
|
74
|
+
return ok(r);
|
|
75
|
+
};
|
|
76
|
+
// SHAR_R_IMM_ALT
|
|
77
|
+
export const shar_r_imm_alt = (r, args, registers) => {
|
|
78
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
79
|
+
const value = u32SignExtend(args.c);
|
|
80
|
+
registers[reg(args.b)] = u32SignExtend(u32(value >> i64(shift)));
|
|
81
|
+
return ok(r);
|
|
82
|
+
};
|
|
83
|
+
// SHLO_L_32
|
|
84
|
+
export const shlo_l_32 = (r, args, registers) => {
|
|
85
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
86
|
+
const value = u32(registers[reg(args.b)]);
|
|
87
|
+
registers[reg(args.c)] = u32SignExtend(value << shift);
|
|
88
|
+
return ok(r);
|
|
89
|
+
};
|
|
90
|
+
// SHLO_R_32
|
|
91
|
+
export const shlo_r_32 = (r, args, registers) => {
|
|
92
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
93
|
+
const value = u32(registers[reg(args.b)]);
|
|
94
|
+
registers[reg(args.c)] = u32SignExtend(value >>> shift);
|
|
95
|
+
return ok(r);
|
|
96
|
+
};
|
|
97
|
+
// SHAR_R_32
|
|
98
|
+
export const shar_r_32 = (r, args, registers) => {
|
|
99
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
100
|
+
const regValue = u32SignExtend(u32(registers[reg(args.b)]));
|
|
101
|
+
registers[reg(args.c)] = u32SignExtend(u32(i64(regValue) >> i64(shift)));
|
|
102
|
+
return ok(r);
|
|
103
|
+
};
|
|
104
|
+
// SHLO_L
|
|
105
|
+
export const shlo_l = (r, args, registers) => {
|
|
106
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
107
|
+
registers[reg(args.c)] = u64(registers[reg(args.b)] << u64(shift));
|
|
108
|
+
return ok(r);
|
|
109
|
+
};
|
|
110
|
+
// SHLO_R
|
|
111
|
+
export const shlo_r = (r, args, registers) => {
|
|
112
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
113
|
+
registers[reg(args.c)] = registers[reg(args.b)] >> u64(shift);
|
|
114
|
+
return ok(r);
|
|
115
|
+
};
|
|
116
|
+
// SHAR_R
|
|
117
|
+
export const shar_r = (r, args, registers) => {
|
|
118
|
+
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
119
|
+
registers[reg(args.c)] = u64(i64(registers[reg(args.b)]) >> i64(shift));
|
|
120
|
+
return ok(r);
|
|
121
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { InstructionRun } from "./outcome";
|
|
2
|
+
export declare const store_imm_u8: InstructionRun;
|
|
3
|
+
export declare const store_imm_u16: InstructionRun;
|
|
4
|
+
export declare const store_imm_u32: InstructionRun;
|
|
5
|
+
export declare const store_imm_u64: InstructionRun;
|
|
6
|
+
export declare const store_u8: InstructionRun;
|
|
7
|
+
export declare const store_u16: InstructionRun;
|
|
8
|
+
export declare const store_u32: InstructionRun;
|
|
9
|
+
export declare const store_u64: InstructionRun;
|
|
10
|
+
export declare const store_imm_ind_u8: InstructionRun;
|
|
11
|
+
export declare const store_imm_ind_u16: InstructionRun;
|
|
12
|
+
export declare const store_imm_ind_u32: InstructionRun;
|
|
13
|
+
export declare const store_imm_ind_u64: InstructionRun;
|
|
14
|
+
export declare const store_ind_u8: InstructionRun;
|
|
15
|
+
export declare const store_ind_u16: InstructionRun;
|
|
16
|
+
export declare const store_ind_u32: InstructionRun;
|
|
17
|
+
export declare const store_ind_u64: InstructionRun;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { MaybePageFault } from "../memory";
|
|
2
|
+
import { portable } from "../portable";
|
|
3
|
+
import { okOrFault } from "./outcome";
|
|
4
|
+
import { reg, u32SignExtend } from "./utils";
|
|
5
|
+
const faultRes = new MaybePageFault();
|
|
6
|
+
// Helper function to compute effective address from base register and signed 32-bit offset
|
|
7
|
+
function effectiveAddress(registers, baseReg, offset) {
|
|
8
|
+
return u32(portable.u64_add(registers[reg(u64(baseReg))], u32SignExtend(offset)));
|
|
9
|
+
}
|
|
10
|
+
// STORE_IMM_U8
|
|
11
|
+
export const store_imm_u8 = (r, args, _registers, memory) => {
|
|
12
|
+
const address = args.a;
|
|
13
|
+
memory.setU8(faultRes, address, (args.b & 0xff));
|
|
14
|
+
return okOrFault(r, faultRes);
|
|
15
|
+
};
|
|
16
|
+
// STORE_IMM_U16
|
|
17
|
+
export const store_imm_u16 = (r, args, _registers, memory) => {
|
|
18
|
+
const address = args.a;
|
|
19
|
+
memory.setU16(faultRes, address, (args.b & 65535));
|
|
20
|
+
return okOrFault(r, faultRes);
|
|
21
|
+
};
|
|
22
|
+
// STORE_IMM_U32
|
|
23
|
+
export const store_imm_u32 = (r, args, _registers, memory) => {
|
|
24
|
+
const address = args.a;
|
|
25
|
+
memory.setU32(faultRes, address, args.b);
|
|
26
|
+
return okOrFault(r, faultRes);
|
|
27
|
+
};
|
|
28
|
+
// STORE_IMM_U64
|
|
29
|
+
export const store_imm_u64 = (r, args, _registers, memory) => {
|
|
30
|
+
const address = args.a;
|
|
31
|
+
memory.setU64(faultRes, address, u32SignExtend(args.b));
|
|
32
|
+
return okOrFault(r, faultRes);
|
|
33
|
+
};
|
|
34
|
+
// STORE_U8
|
|
35
|
+
export const store_u8 = (r, args, registers, memory) => {
|
|
36
|
+
memory.setU8(faultRes, args.b, (registers[reg(args.a)] & u64(0xff)));
|
|
37
|
+
return okOrFault(r, faultRes);
|
|
38
|
+
};
|
|
39
|
+
// STORE_U16
|
|
40
|
+
export const store_u16 = (r, args, registers, memory) => {
|
|
41
|
+
memory.setU16(faultRes, args.b, (registers[reg(args.a)] & u64(65535)));
|
|
42
|
+
return okOrFault(r, faultRes);
|
|
43
|
+
};
|
|
44
|
+
// STORE_U32
|
|
45
|
+
export const store_u32 = (r, args, registers, memory) => {
|
|
46
|
+
memory.setU32(faultRes, args.b, u32(registers[reg(args.a)]));
|
|
47
|
+
return okOrFault(r, faultRes);
|
|
48
|
+
};
|
|
49
|
+
// STORE_U64
|
|
50
|
+
export const store_u64 = (r, args, registers, memory) => {
|
|
51
|
+
memory.setU64(faultRes, args.b, registers[reg(args.a)]);
|
|
52
|
+
return okOrFault(r, faultRes);
|
|
53
|
+
};
|
|
54
|
+
// STORE_IMM_IND_U8
|
|
55
|
+
export const store_imm_ind_u8 = (r, args, registers, memory) => {
|
|
56
|
+
const address = effectiveAddress(registers, args.a, args.b);
|
|
57
|
+
memory.setU8(faultRes, address, (args.c & 0xff));
|
|
58
|
+
return okOrFault(r, faultRes);
|
|
59
|
+
};
|
|
60
|
+
// STORE_IMM_IND_U16
|
|
61
|
+
export const store_imm_ind_u16 = (r, args, registers, memory) => {
|
|
62
|
+
const address = effectiveAddress(registers, args.a, args.b);
|
|
63
|
+
memory.setU16(faultRes, address, (args.c & 65535));
|
|
64
|
+
return okOrFault(r, faultRes);
|
|
65
|
+
};
|
|
66
|
+
// STORE_IMM_IND_U32
|
|
67
|
+
export const store_imm_ind_u32 = (r, args, registers, memory) => {
|
|
68
|
+
const address = effectiveAddress(registers, args.a, args.b);
|
|
69
|
+
memory.setU32(faultRes, address, args.c);
|
|
70
|
+
return okOrFault(r, faultRes);
|
|
71
|
+
};
|
|
72
|
+
// STORE_IMM_IND_U64
|
|
73
|
+
export const store_imm_ind_u64 = (r, args, registers, memory) => {
|
|
74
|
+
const address = effectiveAddress(registers, args.a, args.b);
|
|
75
|
+
memory.setU64(faultRes, address, u32SignExtend(args.c));
|
|
76
|
+
return okOrFault(r, faultRes);
|
|
77
|
+
};
|
|
78
|
+
// STORE_IND_U8
|
|
79
|
+
export const store_ind_u8 = (r, args, registers, memory) => {
|
|
80
|
+
const address = effectiveAddress(registers, args.a, args.c);
|
|
81
|
+
memory.setU8(faultRes, address, (registers[reg(args.b)] & u64(0xff)));
|
|
82
|
+
return okOrFault(r, faultRes);
|
|
83
|
+
};
|
|
84
|
+
// STORE_IND_U16
|
|
85
|
+
export const store_ind_u16 = (r, args, registers, memory) => {
|
|
86
|
+
const address = effectiveAddress(registers, args.a, args.c);
|
|
87
|
+
memory.setU16(faultRes, address, (registers[reg(args.b)] & u64(65535)));
|
|
88
|
+
return okOrFault(r, faultRes);
|
|
89
|
+
};
|
|
90
|
+
// STORE_IND_U32
|
|
91
|
+
export const store_ind_u32 = (r, args, registers, memory) => {
|
|
92
|
+
const address = effectiveAddress(registers, args.a, args.c);
|
|
93
|
+
memory.setU32(faultRes, address, u32(registers[reg(args.b)]));
|
|
94
|
+
return okOrFault(r, faultRes);
|
|
95
|
+
};
|
|
96
|
+
// STORE_IND_U64
|
|
97
|
+
export const store_ind_u64 = (r, args, registers, memory) => {
|
|
98
|
+
const address = effectiveAddress(registers, args.a, args.c);
|
|
99
|
+
memory.setU64(faultRes, address, registers[reg(args.b)]);
|
|
100
|
+
return okOrFault(r, faultRes);
|
|
101
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multiply two unsigned 64-bit numbers and take the upper 64-bits of the result.
|
|
3
|
+
*
|
|
4
|
+
* The result of multiplication is a 128-bits number and we are only interested in the part that lands in the upper 64-bits.
|
|
5
|
+
* For example (for 32-bit case) if we multiply `0xffffffff * 0xffffffff`, we get:
|
|
6
|
+
|
|
7
|
+
* | 32-bits | 32-bits |
|
|
8
|
+
* +------------+------------+
|
|
9
|
+
* | upper | lower |
|
|
10
|
+
* | 0xfffffffe | 0x00000001 |
|
|
11
|
+
*
|
|
12
|
+
* So `0xfffffffe` is returned.
|
|
13
|
+
*/
|
|
14
|
+
export declare function mulUpperUnsigned(a: u64, b: u64): u64;
|
|
15
|
+
/**
|
|
16
|
+
* Same as [mulUpperUnsigned] but treat the arguments as signed (two-complement) 64-bit numbers and the result alike.
|
|
17
|
+
*/
|
|
18
|
+
export declare function mulUpperSigned(a: i64, b: i64): u64;
|
|
19
|
+
export declare function mulUpperSignedUnsigned(a: i64, b: u64): u64;
|
|
20
|
+
export declare function u8SignExtend(v: u8): i64;
|
|
21
|
+
export declare function u16SignExtend(v: u16): i64;
|
|
22
|
+
export declare function u32SignExtend(v: u32): i64;
|
|
23
|
+
export declare function reg(v: u64): u32;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { portable } from "../portable";
|
|
2
|
+
import { NO_OF_REGISTERS } from "../registers";
|
|
3
|
+
/**
|
|
4
|
+
* Multiply two unsigned 64-bit numbers and take the upper 64-bits of the result.
|
|
5
|
+
*
|
|
6
|
+
* The result of multiplication is a 128-bits number and we are only interested in the part that lands in the upper 64-bits.
|
|
7
|
+
* For example (for 32-bit case) if we multiply `0xffffffff * 0xffffffff`, we get:
|
|
8
|
+
|
|
9
|
+
* | 32-bits | 32-bits |
|
|
10
|
+
* +------------+------------+
|
|
11
|
+
* | upper | lower |
|
|
12
|
+
* | 0xfffffffe | 0x00000001 |
|
|
13
|
+
*
|
|
14
|
+
* So `0xfffffffe` is returned.
|
|
15
|
+
*/
|
|
16
|
+
export function mulUpperUnsigned(a, b) {
|
|
17
|
+
const aHigh = a >> u64(32);
|
|
18
|
+
const aLow = a & u64(4294967295);
|
|
19
|
+
const bHigh = b >> u64(32);
|
|
20
|
+
const bLow = b & u64(4294967295);
|
|
21
|
+
const lowLow = portable.u64_mul(aLow, bLow);
|
|
22
|
+
const lowHigh = portable.u64_mul(aLow, bHigh);
|
|
23
|
+
const highLow = portable.u64_mul(aHigh, bLow);
|
|
24
|
+
const highHigh = portable.u64_mul(aHigh, bHigh);
|
|
25
|
+
const carry = portable.u64_add(portable.u64_add(lowLow >> u64(32), lowHigh & u64(4294967295)), highLow & u64(4294967295));
|
|
26
|
+
return portable.u64_add(portable.u64_add(portable.u64_add(highHigh, lowHigh >> u64(32)), highLow >> u64(32)), carry >> u64(32));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Same as [mulUpperUnsigned] but treat the arguments as signed (two-complement) 64-bit numbers and the result alike.
|
|
30
|
+
*/
|
|
31
|
+
export function mulUpperSigned(a, b) {
|
|
32
|
+
let isResultNegative = false;
|
|
33
|
+
let aAbs = a;
|
|
34
|
+
let bAbs = b;
|
|
35
|
+
if (a < i64(0)) {
|
|
36
|
+
isResultNegative = !isResultNegative;
|
|
37
|
+
aAbs = portable.u64_add(~a, i64(1));
|
|
38
|
+
}
|
|
39
|
+
if (b < i64(0)) {
|
|
40
|
+
isResultNegative = !isResultNegative;
|
|
41
|
+
bAbs = portable.u64_add(~b, i64(1));
|
|
42
|
+
}
|
|
43
|
+
if (isResultNegative) {
|
|
44
|
+
const upper = mulUpperUnsigned(aAbs, bAbs);
|
|
45
|
+
const lower = portable.u64_mul(aAbs, bAbs);
|
|
46
|
+
return portable.u64_add(~upper, lower === u64(0) ? u64(1) : u64(0));
|
|
47
|
+
}
|
|
48
|
+
return mulUpperUnsigned(aAbs, bAbs);
|
|
49
|
+
}
|
|
50
|
+
export function mulUpperSignedUnsigned(a, b) {
|
|
51
|
+
if (a < i64(0)) {
|
|
52
|
+
const aAbs = portable.u64_add(~a, u64(1));
|
|
53
|
+
const upper = mulUpperUnsigned(aAbs, b);
|
|
54
|
+
const lower = portable.u64_mul(aAbs, b);
|
|
55
|
+
return portable.u64_add(~upper, lower === u64(0) ? u64(1) : u64(0));
|
|
56
|
+
}
|
|
57
|
+
return mulUpperUnsigned(a, b);
|
|
58
|
+
}
|
|
59
|
+
// @inline
|
|
60
|
+
export function u8SignExtend(v) {
|
|
61
|
+
// u64 wrap ensures unsigned representation in JS BigInt (no-op in AS)
|
|
62
|
+
return u64(i64(i32(i16(i8(v)))));
|
|
63
|
+
}
|
|
64
|
+
// @inline
|
|
65
|
+
export function u16SignExtend(v) {
|
|
66
|
+
return u64(i64(i32(i16(v))));
|
|
67
|
+
}
|
|
68
|
+
// @inline
|
|
69
|
+
export function u32SignExtend(v) {
|
|
70
|
+
return u64(i64(i32(v)));
|
|
71
|
+
}
|
|
72
|
+
// @inline
|
|
73
|
+
export function reg(v) {
|
|
74
|
+
return v >= u64(NO_OF_REGISTERS) ? NO_OF_REGISTERS - 1 : u32(v);
|
|
75
|
+
}
|