Skip to content

Commit

Permalink
Change instructions to 64-bit set (#244)
Browse files Browse the repository at this point in the history
* Change instructions to 64-bit set

* 64 bit pvm

* fix types

* Add new, 64-bit instruction set to knowledge base

* Fix some formulas; add graypaper links

* bump typeberry pvm

* update fib example and disable polkavm tests

* Update polkavm & spectool to 64-bit.

* Fix registers & examples.

* Disable the disassembler temporarily.

* Update run-program.spec.ts

Restore polkavm test

* Update typeberry.

* Update sbrkindex type.

* bump pvm

* Fix hex 64-bit display.

* bump pvm

* Fix hex registers display. Change default to hex.

* bump pvm

* set correct initial sbrk index

* bump pvm

---------

Co-authored-by: Mateusz Sikora <ms1qaz@gmail.com>
Co-authored-by: Tomasz Drwięga <tomusdrw@gmail.com>
Co-authored-by: Tomek Drwięga <tomusdrw@users.noreply.github.com>
  • Loading branch information
4 people authored Jan 2, 2025
1 parent bb87d71 commit f6df991
Show file tree
Hide file tree
Showing 26 changed files with 791 additions and 606 deletions.
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
"@reduxjs/toolkit": "^2.2.8",
"@tanstack/react-virtual": "^3.10.9",
"@typeberry/block": "^0.0.1-1a02906",
"@typeberry/pvm-debugger-adapter": "0.0.1-3eb6bed",
"@typeberry/spectool-wasm": "^0.13.0",
"@typeberry/pvm-debugger-adapter": "0.1.0-dc28f3f",
"@typeberry/spectool-wasm": "0.18.0",
"@uiw/react-codemirror": "^4.23.6",
"class-variance-authority": "^0.7.0",
"classnames": "^2.5.1",
Expand Down
2 changes: 1 addition & 1 deletion src/components/Instructions/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const valueToNumeralSystem = (
withPrefix: boolean = true,
): string => {
const stringValue =
typeof value === "bigint" ? BigInt.asUintN(32, value).toString(16) : ((value ?? 0) >>> 0).toString(16);
typeof value === "bigint" ? BigInt.asUintN(64, value).toString(16) : ((value ?? 0) >>> 0).toString(16);

return numeralSystem === NumeralSystem.HEXADECIMAL
? `${withPrefix ? "0x" : ""}${stringValue.padStart(padStartVal, "0")}`
Expand Down
18 changes: 10 additions & 8 deletions src/components/KnowledgeBase/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,16 @@ export const KnowledgeBase = ({ currentInstruction }: { currentInstruction: Curr
</div>
<p className="my-3">{currentInstructionFromKnowledgeBase?.description}</p>
<div className="flex mb-3 mr-3 justify-end">
<Button
size={"sm"}
onClick={() => {
window.open(currentInstructionFromKnowledgeBase?.linkInGrayPaperReader, "_blank");
}}
>
Open in GP
</Button>
{currentInstructionFromKnowledgeBase?.linkInGrayPaperReader && (
<Button
size={"sm"}
onClick={() => {
window.open(currentInstructionFromKnowledgeBase?.linkInGrayPaperReader, "_blank");
}}
>
Open in GP
</Button>
)}
</div>
</div>
);
Expand Down
3 changes: 2 additions & 1 deletion src/components/NumeralSystemSwitch/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { NumeralSystemContext } from "@/context/NumeralSystemContext";
import { NumeralSystem } from "@/context/NumeralSystem";

export const NumeralSystemSwitch = ({ className }: { className: string }) => {
const { setNumeralSystem } = useContext(NumeralSystemContext);
const { setNumeralSystem, numeralSystem } = useContext(NumeralSystemContext);

return (
<div className={`flex items-center space-x-2 ${className}`}>
<Label htmlFor="numerical-system-mode">DEC</Label>
<Switch
id="numerical-system-mode"
checked={numeralSystem === NumeralSystem.HEXADECIMAL}
onCheckedChange={(checked) => setNumeralSystem(checked ? NumeralSystem.HEXADECIMAL : NumeralSystem.DECIMAL)}
/>
<Label htmlFor="numerical-system-mode">HEX</Label>
Expand Down
14 changes: 9 additions & 5 deletions src/components/ProgramLoader/Assembly.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ function assemblyFromInputProgram(initialState: InitialState, program: number[])
if (program.length === 0) {
return DEFAULT_ASSEMBLY;
}

try {
const raw = disassemble(new Uint8Array(program));
const lines = raw.split("\n");
Expand Down Expand Up @@ -71,7 +72,7 @@ function assemblyFromInputProgram(initialState: InitialState, program: number[])
// now append initial registers
const registers: string[] = [];
for (const [idx, reg] of (initialState.regs ?? []).entries()) {
if (reg !== 0) {
if (BigInt(reg) !== 0n) {
registers.push(`pre: r${idx} = ${reg}`);
}
}
Expand Down Expand Up @@ -131,7 +132,9 @@ export const Assembly = ({
}
// we want to keep all of the old stuff to avoid re-rendering.
output.initial = newInitialState;
onProgramLoad(output);
// TODO [ToDr] Assembly for 64-bit is temporarily broken, so we don't trigger
// the `onProgramLoad` here.
// onProgramLoad(output);
setError(undefined);
} catch (e) {
if (e instanceof Error) {
Expand All @@ -149,8 +152,7 @@ export const Assembly = ({
setError(`${e}`);
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[onProgramLoad, program],
[onProgramLoad, program, initialState],
);

const [error, setError] = useState<string>();
Expand Down Expand Up @@ -193,8 +195,10 @@ export const Assembly = ({
className="h-full"
height="100%"
placeholder="Try writing some PolkaVM assembly code."
/* TODO [ToDr] Marking as readonly since the 64-bit assembly is not working correctly yet */
readOnly
value={assembly}
onChange={(value) => compile(value)}
onChange={compile}
/>
</div>
<div>
Expand Down
50 changes: 19 additions & 31 deletions src/components/ProgramLoader/Examples.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RegistersArray } from "@/types/pvm";
import { ProgramUploadFileOutput } from "./types";
import { Button } from "@/components/ui/button.tsx";

Expand All @@ -15,8 +16,8 @@ const programs: {
fibonacci: {
name: "Fibonacci sequence",
program: [
0, 0, 33, 4, 8, 1, 4, 9, 1, 5, 3, 0, 2, 119, 255, 7, 7, 12, 82, 138, 8, 152, 8, 82, 169, 5, 243, 82, 135, 4, 8, 4,
9, 17, 19, 0, 73, 147, 82, 213, 0,
0, 0, 33, 51, 8, 1, 51, 9, 1, 40, 3, 0, 121, 119, 255, 81, 7, 12, 100, 138, 170, 152, 8, 100, 169, 40, 243, 100,
135, 51, 8, 51, 9, 1, 50, 0, 73, 147, 82, 213, 0,
],
regs: [4294901760, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0],
pc: 0,
Expand All @@ -27,16 +28,17 @@ const programs: {
gameOfLife: {
name: "Conway's Game of Life",
program: [
0, 0, 129, 23, 62, 1, 3, 255, 0, 62, 1, 11, 255, 0, 62, 1, 19, 255, 0, 62, 1, 18, 255, 0, 62, 1, 9, 255, 0, 5,
233, 0, 4, 1, 255, 17, 2, 17, 1, 7, 17, 8, 223, 0, 4, 2, 255, 17, 2, 34, 1, 7, 18, 8, 241, 35, 19, 8, 8, 35, 3, 5,
47, 2, 51, 128, 0, 11, 52, 18, 68, 1, 15, 20, 1, 14, 44, 21, 2, 25, 50, 21, 3, 21, 5, 8, 7, 21, 3, 6, 5, 11, 2,
51, 128, 26, 3, 255, 0, 5, 205, 2, 51, 128, 26, 3, 5, 198, 4, 5, 82, 52, 4, 8, 64, 2, 68, 255, 73, 132, 7, 2, 119,
128, 0, 11, 118, 18, 102, 1, 8, 101, 5, 2, 68, 2, 73, 132, 7, 2, 119, 128, 0, 11, 118, 18, 102, 1, 8, 101, 5, 2,
68, 247, 73, 132, 7, 2, 119, 128, 0, 11, 118, 18, 102, 1, 8, 101, 5, 2, 68, 16, 73, 132, 7, 2, 119, 128, 0, 11,
118, 18, 102, 1, 8, 101, 5, 2, 68, 1, 73, 132, 7, 2, 119, 128, 0, 11, 118, 18, 102, 1, 8, 101, 5, 2, 68, 254, 73,
132, 7, 2, 119, 128, 0, 11, 118, 18, 102, 1, 8, 101, 5, 2, 68, 240, 73, 132, 7, 2, 119, 128, 0, 11, 118, 18, 102,
1, 8, 101, 5, 2, 68, 2, 73, 132, 7, 2, 119, 128, 0, 11, 118, 18, 102, 1, 8, 101, 5, 5, 60, 255, 4, 1, 17, 2, 19,
128, 0, 1, 18, 3, 50, 2, 17, 4, 7, 17, 64, 12, 255, 5, 240, 33, 132, 16, 146, 9, 153, 72, 138, 18, 17, 69, 137,
0, 0, 129, 23, 30, 1, 3, 255, 0, 30, 1, 11, 255, 0, 30, 1, 19, 255, 0, 30, 1, 18, 255, 0, 30, 1, 9, 255, 0, 40,
233, 0, 51, 1, 255, 1, 139, 17, 1, 81, 17, 8, 223, 0, 51, 2, 255, 1, 139, 34, 1, 81, 18, 8, 241, 140, 19, 8, 180,
35, 3, 40, 47, 139, 51, 128, 0, 114, 52, 122, 68, 1, 82, 20, 1, 14, 83, 21, 2, 25, 86, 21, 3, 21, 40, 8, 81, 21,
3, 6, 40, 11, 139, 51, 128, 70, 3, 255, 0, 40, 205, 139, 51, 128, 70, 3, 40, 198, 51, 5, 100, 52, 51, 8, 64, 139,
68, 255, 185, 132, 7, 139, 119, 128, 0, 114, 118, 122, 102, 1, 180, 101, 5, 139, 68, 2, 185, 132, 7, 139, 119,
128, 0, 114, 118, 122, 102, 1, 180, 101, 5, 139, 68, 247, 185, 132, 7, 139, 119, 128, 0, 114, 118, 122, 102, 1,
180, 101, 5, 139, 68, 16, 185, 132, 7, 139, 119, 128, 0, 114, 118, 122, 102, 1, 180, 101, 5, 139, 68, 1, 185, 132,
7, 139, 119, 128, 0, 114, 118, 122, 102, 1, 180, 101, 5, 139, 68, 254, 185, 132, 7, 139, 119, 128, 0, 114, 118,
122, 102, 1, 180, 101, 5, 139, 68, 240, 185, 132, 7, 139, 119, 128, 0, 114, 118, 122, 102, 1, 180, 101, 5, 139,
68, 2, 185, 132, 7, 139, 119, 128, 0, 114, 118, 122, 102, 1, 180, 101, 5, 40, 60, 255, 51, 1, 1, 139, 19, 128, 0,
118, 18, 112, 50, 139, 17, 4, 81, 17, 64, 12, 255, 40, 240, 33, 132, 16, 146, 9, 153, 72, 138, 18, 17, 69, 137,
82, 149, 36, 74, 146, 40, 73, 162, 36, 137, 146, 36, 74, 146, 40, 73, 162, 36, 137, 146, 52, 42, 33,
],
regs: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
Expand All @@ -53,7 +55,7 @@ const programs: {
},
branch: {
name: "Branch instruction",
program: [0, 0, 16, 4, 7, 210, 4, 7, 39, 210, 4, 6, 0, 4, 7, 239, 190, 173, 222, 17, 6],
program: [0, 0, 16, 51, 7, 210, 4, 81, 39, 210, 4, 6, 0, 51, 7, 239, 190, 173, 222, 17, 6],
regs: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
pc: 0,
pageMap: [],
Expand All @@ -62,7 +64,7 @@ const programs: {
},
add: {
name: "ADD instruction",
program: [0, 0, 3, 8, 135, 9, 1],
program: [0, 0, 3, 121, 121, 2, 1],
regs: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
pc: 0,
pageMap: [],
Expand All @@ -71,7 +73,7 @@ const programs: {
},
storeU16: {
name: "Store U16 instruction",
program: [0, 0, 5, 69, 7, 0, 0, 2, 1],
program: [0, 0, 7, 31, 3, 0, 0, 2, 52, 18, 1],
regs: [0, 0, 0, 0, 0, 0, 0, 305419896, 0, 0, 0, 0, 0],
pc: 0,
pageMap: [
Expand All @@ -87,21 +89,7 @@ const programs: {
empty: {
name: "Empty",
program: [0, 0, 0],
regs: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] as [
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
],
regs: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
pc: 0,
pageMap: [],
memory: [],
Expand All @@ -125,7 +113,7 @@ export const Examples = ({ onProgramLoad }: { onProgramLoad: (val: ProgramUpload
onClick={() => {
onProgramLoad({
initial: {
regs: programs[key].regs,
regs: programs[key].regs.map((x) => BigInt(x)) as RegistersArray,
pc: programs[key].pc,
pageMap: programs[key].pageMap,
memory: programs[key].memory,
Expand Down
2 changes: 1 addition & 1 deletion src/components/ProgramLoader/ProgramFileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export const ProgramFileUpload = ({
program: Array.from(code),
name: "custom",
initial: {
regs: Array.from(registers) as RegistersArray,
regs: Array.from(registers).map((x) => BigInt(x as number | bigint)) as RegistersArray,
pc: 0,
pageMap: [],
// TODO: map memory properly
Expand Down
2 changes: 2 additions & 0 deletions src/components/ProgramLoader/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { mapKeys, camelCase, pickBy } from "lodash";
import { ProgramUploadFileInput, ProgramUploadFileOutput } from "./types";
import { RegistersArray } from "@/types/pvm";

export function mapUploadFileInputToOutput(data: ProgramUploadFileInput): ProgramUploadFileOutput {
const camelCasedData = mapKeys(data, (_value: unknown, key: string) => camelCase(key));
Expand All @@ -20,5 +21,6 @@ export function mapUploadFileInputToOutput(data: ProgramUploadFileInput): Progra
// expected: mapKeys(expected, (_value: unknown, key) => camelCase(key.replace("expected", ""))) as unknown as ProgramUploadFileOutput["expected"],
};

result.initial.regs = result.initial.regs?.map((x) => BigInt(x as number | bigint)) as RegistersArray;
return result;
}
2 changes: 1 addition & 1 deletion src/components/PvmSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export const PvmSelect = () => {
id: value,
type: PvmTypes.WASM_URL,
params: {
url: path.join(url, "../", metadata.wasmBlobUrl32 || metadata.wasmBlobUrl),
url: path.join(url, "../", metadata.wasmBlobUrl),
lang,
},
},
Expand Down
29 changes: 15 additions & 14 deletions src/components/Registers/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ExpectedState, InitialState, RegistersArray, Status } from "@/types/pvm";
import { ReactNode, useContext } from "react";
import { NumeralSystem } from "@/context/NumeralSystem";
import { NumeralSystemContext } from "@/context/NumeralSystemContext";
import { valueToNumeralSystem } from "@/components/Instructions/utils.tsx";
import classNames from "classnames";
Expand Down Expand Up @@ -131,7 +130,7 @@ export const Registers = ({
<div className="border-2 rounded-md h-[70vh] overflow-auto">
<div className="p-3">
<div>
<div className="font-mono flex flex-col items-start">
<div className="font-mono flex flex-col items-start text-xs">
<div className="flex flex-row items-center justify-between w-full mb-2">
<p className="flex-[2]">PC</p>
{allowEditingPc ? (
Expand All @@ -140,13 +139,10 @@ export const Registers = ({
className="w-20 h-6 m-0 py-0 px-[4px] text-md border-white hover:border-input"
onChange={(e) => {
const value = e.target?.value;
const valueInDecimal =
numeralSystem === NumeralSystem.HEXADECIMAL ? `${parseInt(value, 16)}` : value;
const pcValue =
valueInDecimal && !Number.isNaN(parseInt(valueInDecimal)) ? parseInt(valueInDecimal) : 0;
const newValue = stringToNumber(value, Number);
onCurrentStateChange({
...currentState,
pc: pcValue,
pc: newValue,
});
}}
onKeyUp={(e) => {
Expand Down Expand Up @@ -205,14 +201,11 @@ export const Registers = ({
className="w-20 h-6 m-0 p-0"
onChange={(e) => {
const value = e.target?.value;
const valueInDecimal =
numeralSystem === NumeralSystem.HEXADECIMAL ? `${parseInt(value, 16)}` : value;
const regValue =
valueInDecimal && !Number.isNaN(parseInt(valueInDecimal)) ? parseInt(valueInDecimal) : "";
const newValue = stringToNumber(value, BigInt);
onCurrentStateChange({
...currentState,
regs: currentState.regs?.map((val: number, index: number) =>
index === regNo ? regValue : val,
regs: currentState.regs?.map((val: bigint, index: number) =>
index === regNo ? newValue : val,
) as InitialState["regs"],
});
}}
Expand All @@ -231,7 +224,7 @@ export const Registers = ({
propName="regs"
propNameIndex={regNo}
workers={workers}
padStartVal={numeralSystem ? 8 : 0}
padStartVal={numeralSystem ? 16 : 0}
/>
)}
</div>
Expand All @@ -242,3 +235,11 @@ export const Registers = ({
</div>
);
};

function stringToNumber<T>(value: string, cb: (x: string) => T): T {
try {
return cb(value);
} catch (_e) {
return cb("0");
}
}
2 changes: 1 addition & 1 deletion src/context/NumeralSystemProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { NumeralSystem } from "./NumeralSystem";
import { NumeralSystemContext } from "./NumeralSystemContext";

export const NumeralSystemProvider = ({ children }: { children: ReactNode }) => {
const [numeralSystem, setNumeralSystem] = useState(NumeralSystem.DECIMAL);
const [numeralSystem, setNumeralSystem] = useState(NumeralSystem.HEXADECIMAL);

return (
<NumeralSystemContext.Provider value={{ numeralSystem, setNumeralSystem }}>
Expand Down
Loading

0 comments on commit f6df991

Please sign in to comment.