Skip to content

Commit 2b3319c

Browse files
committed
Add instruction details
1 parent a791374 commit 2b3319c

File tree

3 files changed

+234
-71
lines changed

3 files changed

+234
-71
lines changed

src/components/Instructions/InstructionItem.tsx

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { mapInstructionsArgsByType, valueToNumeralSystem } from "./utils";
1+
import { argType, mapInstructionsArgsByType, valueToBinary, valueToNumeralSystem } from "./utils";
22
import classNames from "classnames";
33
import { getStatusColor } from "../Registers/utils";
44
import { ExpectedState, RegistersArray, Status } from "@/types/pvm";
@@ -86,7 +86,7 @@ export const InstructionItem = forwardRef(
8686
onClick(programRow);
8787
}, [programRow, onClick]);
8888

89-
const { backgroundColor, hasTooltip } = getHighlightStatus(workers, programRow, status);
89+
const { backgroundColor, hasOpacity } = getHighlightStatus(workers, programRow, status);
9090

9191
const renderContent = () => {
9292
return (
@@ -143,8 +143,16 @@ export const InstructionItem = forwardRef(
143143
style={{ borderTop: programRow.block.isStart ? "2px solid #bbb" : undefined }}
144144
>
145145
<span className="">
146-
{"args" in programRow &&
147-
mapInstructionsArgsByType(programRow.args, numeralSystem, programRow.counter)}
146+
{"args" in programRow && (
147+
<span
148+
dangerouslySetInnerHTML={{
149+
__html:
150+
mapInstructionsArgsByType(programRow.args, numeralSystem, programRow.counter)
151+
?.map((instruction) => instruction.value)
152+
.join(", ") ?? "",
153+
}}
154+
/>
155+
)}
148156
</span>
149157
</TableCell>
150158
</>
@@ -153,7 +161,67 @@ export const InstructionItem = forwardRef(
153161
);
154162
};
155163

156-
return hasTooltip ? (
164+
const renderTooltipContentInstructionInfo = () => {
165+
return (
166+
<div>
167+
<div className="flex flex-row bg-white">
168+
<div>
169+
<div className="font-mono text-xs text-gray-500 pl-1 pb-1">opcode</div>
170+
<div className="border-r-2 border-red-400 ">
171+
<div className="font-mono text-md tracking-[0.2rem] bg-red-200 pl-1 text-right">
172+
{valueToBinary(programRow.instructionCode, 8)}
173+
</div>
174+
<div className="font-mono text-xs p-1 font-bold">
175+
{valueToNumeralSystem(programRow.instructionCode, numeralSystem)}
176+
</div>
177+
</div>
178+
</div>
179+
180+
{"args" in programRow &&
181+
mapInstructionsArgsByType(programRow.args, numeralSystem, programRow.counter)?.map(
182+
(instruction, index) => (
183+
<div key={index}>
184+
<div className="font-mono text-xs text-gray-500 pl-1 pb-1 lowercase">{instruction.type}</div>
185+
<div
186+
className={classNames(
187+
"border-r-2",
188+
{ "border-violet-400": instruction.type === argType.REGISTER },
189+
{ "border-green-300": instruction.type !== argType.REGISTER },
190+
)}
191+
>
192+
<div
193+
className={classNames(
194+
"font-mono text-md tracking-[0.2rem] pl-1",
195+
{
196+
"bg-violet-200": instruction.type === argType.REGISTER,
197+
},
198+
{ "bg-green-100": instruction.type !== argType.REGISTER },
199+
)}
200+
>
201+
{valueToBinary(
202+
instruction.value,
203+
instruction.type === argType.EXTENDED_WIDTH_IMMEDIATE ? 16 : 8,
204+
)}
205+
</div>
206+
<div
207+
className={classNames("text-xs p-1", {
208+
"font-sans": instruction.type === argType.REGISTER,
209+
"font-mono": instruction.type !== argType.REGISTER,
210+
})}
211+
dangerouslySetInnerHTML={{
212+
__html: instruction.value,
213+
}}
214+
/>
215+
</div>
216+
</div>
217+
),
218+
)}
219+
</div>
220+
</div>
221+
);
222+
};
223+
224+
return hasOpacity ? (
157225
<TooltipProvider>
158226
<Tooltip>
159227
<TooltipTrigger asChild>{renderContent()}</TooltipTrigger>
@@ -172,7 +240,12 @@ export const InstructionItem = forwardRef(
172240
</Tooltip>
173241
</TooltipProvider>
174242
) : (
175-
renderContent()
243+
<TooltipProvider>
244+
<Tooltip>
245+
<TooltipTrigger asChild>{renderContent()}</TooltipTrigger>
246+
<TooltipContent side="bottom">{renderTooltipContentInstructionInfo()}</TooltipContent>
247+
</Tooltip>
248+
</TooltipProvider>
176249
);
177250
},
178251
);
@@ -197,7 +270,7 @@ function getHighlightStatus(workers: WorkerState[], programRow: ProgramRow, stat
197270

198271
return {
199272
backgroundColor,
200-
hasTooltip: bgOpacity > 0 && bgOpacity < 1,
273+
hasOpacity: bgOpacity > 0 && bgOpacity < 1,
201274
};
202275
}
203276

src/components/Instructions/utils.tsx

Lines changed: 153 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -15,84 +15,173 @@ export const valueToNumeralSystem = (
1515
: (value ?? 0).toString().padStart(padStartVal, "0");
1616
};
1717

18-
export const mapInstructionsArgsByType = (args: Args | null, numeralSystem: NumeralSystem, counter: number) => {
18+
export const valueToBinary = (value?: number | bigint | string, padStartVal: number = 0): string => {
19+
return ((Number(value) ?? 0) >>> 0).toString(2).padStart(padStartVal, "0");
20+
};
21+
22+
export enum argType {
23+
IMMEDIATE = "IMMEDIATE",
24+
OFFSET = "OFFSET",
25+
REGISTER = "REGISTER",
26+
EXTENDED_WIDTH_IMMEDIATE = "EXTENDED_WIDTH_IMMEDIATE",
27+
}
28+
29+
export const mapInstructionsArgsByType = (
30+
args: Args | null,
31+
numeralSystem: NumeralSystem,
32+
counter: number,
33+
):
34+
| {
35+
type: argType;
36+
value: string | number;
37+
}[]
38+
| null => {
1939
switch (args?.type) {
2040
case ArgumentType.NO_ARGUMENTS:
21-
return "";
41+
return [];
2242
case ArgumentType.ONE_IMMEDIATE:
23-
return <span>{valueToNumeralSystem(args.immediateDecoder.getI64(), numeralSystem)}</span>;
43+
return [{ type: argType.IMMEDIATE, value: valueToNumeralSystem(args.immediateDecoder.getI64(), numeralSystem) }];
2444
case ArgumentType.TWO_IMMEDIATES:
25-
return (
26-
<span>
27-
{valueToNumeralSystem(args?.firstImmediateDecoder.getI64(), numeralSystem)},{" "}
28-
{valueToNumeralSystem(args?.secondImmediateDecoder.getI64(), numeralSystem)}
29-
</span>
30-
);
45+
return [
46+
{
47+
type: argType.IMMEDIATE,
48+
value: valueToNumeralSystem(args?.firstImmediateDecoder.getI64(), numeralSystem),
49+
},
50+
{
51+
type: argType.IMMEDIATE,
52+
value: valueToNumeralSystem(args?.secondImmediateDecoder.getI64(), numeralSystem),
53+
},
54+
];
3155
case ArgumentType.ONE_OFFSET:
32-
return <span>{valueToNumeralSystem(args?.nextPc - counter, numeralSystem)}</span>;
56+
return [{ type: argType.OFFSET, value: valueToNumeralSystem(args?.nextPc - counter, numeralSystem) }];
3357
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE:
34-
return (
35-
<span>
36-
ω<sub>{args?.registerIndex}</sub>, {valueToNumeralSystem(args.immediateDecoder.getI64(), numeralSystem)}
37-
</span>
38-
);
58+
return [
59+
{
60+
type: argType.REGISTER,
61+
value: `ω<sub>${args?.registerIndex}</sub>`,
62+
},
63+
{
64+
type: argType.IMMEDIATE,
65+
value: valueToNumeralSystem(args.immediateDecoder.getI64(), numeralSystem),
66+
},
67+
];
3968
case ArgumentType.ONE_REGISTER_TWO_IMMEDIATES:
40-
return (
41-
<span>
42-
ω<sub>{args?.registerIndex}</sub>, {valueToNumeralSystem(args?.firstImmediateDecoder.getI64(), numeralSystem)}
43-
, {valueToNumeralSystem(args?.secondImmediateDecoder.getI64(), numeralSystem)}
44-
</span>
45-
);
69+
return [
70+
{
71+
type: argType.REGISTER,
72+
value: `ω<sub>${args?.registerIndex}</sub>`,
73+
},
74+
{
75+
type: argType.IMMEDIATE,
76+
value: valueToNumeralSystem(args?.firstImmediateDecoder.getI64(), numeralSystem),
77+
},
78+
{
79+
type: argType.IMMEDIATE,
80+
value: valueToNumeralSystem(args?.secondImmediateDecoder.getI64(), numeralSystem),
81+
},
82+
];
4683
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET:
47-
return (
48-
<span>
49-
ω<sub>{args?.registerIndex}</sub>, {valueToNumeralSystem(args?.immediateDecoder.getI64(), numeralSystem)},{" "}
50-
{valueToNumeralSystem(args?.nextPc - counter, numeralSystem)}
51-
</span>
52-
);
84+
return [
85+
{
86+
type: argType.REGISTER,
87+
value: `ω<sub>${args?.registerIndex}</sub>`,
88+
},
89+
{
90+
type: argType.IMMEDIATE,
91+
value: valueToNumeralSystem(args?.immediateDecoder.getI64(), numeralSystem),
92+
},
93+
{
94+
type: argType.OFFSET,
95+
value: valueToNumeralSystem(args?.nextPc - counter, numeralSystem),
96+
},
97+
];
5398
case ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE:
54-
return (
55-
<span>
56-
ω<sub>{args?.registerIndex}</sub>, {valueToNumeralSystem(args?.immediateDecoder.getValue(), numeralSystem)}
57-
</span>
58-
);
99+
return [
100+
{
101+
type: argType.REGISTER,
102+
value: `ω<sub>${args?.registerIndex}</sub>`,
103+
},
104+
{
105+
type: argType.EXTENDED_WIDTH_IMMEDIATE,
106+
value: valueToNumeralSystem(args?.immediateDecoder.getValue(), numeralSystem),
107+
},
108+
];
59109
case ArgumentType.TWO_REGISTERS:
60-
return (
61-
<span>
62-
ω<sub>{args?.firstRegisterIndex}</sub>, ω<sub>{args?.secondRegisterIndex}</sub>
63-
</span>
64-
);
110+
return [
111+
{
112+
type: argType.REGISTER,
113+
value: `ω<sub>${args?.firstRegisterIndex}</sub>`,
114+
},
115+
{
116+
type: argType.REGISTER,
117+
value: `ω<sub>${args?.secondRegisterIndex}</sub>`,
118+
},
119+
];
65120
case ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE:
66-
return (
67-
<span>
68-
ω<sub>{args?.firstRegisterIndex}</sub>, ω<sub>{args?.secondRegisterIndex}</sub>,{" "}
69-
{valueToNumeralSystem(args?.immediateDecoder.getI64(), numeralSystem)}
70-
</span>
71-
);
121+
return [
122+
{
123+
type: argType.REGISTER,
124+
value: `ω<sub>${args?.firstRegisterIndex}</sub>`,
125+
},
126+
{
127+
type: argType.REGISTER,
128+
value: `ω<sub>${args?.secondRegisterIndex}</sub>`,
129+
},
130+
{
131+
type: argType.IMMEDIATE,
132+
value: valueToNumeralSystem(args?.immediateDecoder.getI64(), numeralSystem),
133+
},
134+
];
72135
case ArgumentType.TWO_REGISTERS_ONE_OFFSET:
73-
return (
74-
<span>
75-
ω<sub>{args?.firstRegisterIndex}</sub>, ω<sub>{args?.secondRegisterIndex}</sub>,{" "}
76-
{valueToNumeralSystem(args?.nextPc - counter, numeralSystem)}
77-
</span>
78-
);
136+
return [
137+
{
138+
type: argType.REGISTER,
139+
value: `ω<sub>${args?.firstRegisterIndex}</sub>`,
140+
},
141+
{
142+
type: argType.REGISTER,
143+
value: `ω<sub>${args?.secondRegisterIndex}</sub>`,
144+
},
145+
{
146+
type: argType.OFFSET,
147+
value: valueToNumeralSystem(args?.nextPc - counter, numeralSystem),
148+
},
149+
];
79150
case ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES:
80-
return (
81-
<span>
82-
ω<sub>{args?.firstRegisterIndex}</sub>, ω<sub>{args?.secondRegisterIndex}</sub>,{" "}
83-
{valueToNumeralSystem(args?.firstImmediateDecoder.getI64(), numeralSystem)},{" "}
84-
{valueToNumeralSystem(args?.secondImmediateDecoder.getI64(), numeralSystem)}
85-
</span>
86-
);
151+
return [
152+
{
153+
type: argType.REGISTER,
154+
value: `ω<sub>${args?.firstRegisterIndex}</sub>`,
155+
},
156+
{
157+
type: argType.REGISTER,
158+
value: `ω<sub>${args?.secondRegisterIndex}</sub>`,
159+
},
160+
{
161+
type: argType.IMMEDIATE,
162+
value: valueToNumeralSystem(args?.firstImmediateDecoder.getI64(), numeralSystem),
163+
},
164+
{
165+
type: argType.IMMEDIATE,
166+
value: valueToNumeralSystem(args?.secondImmediateDecoder.getI64(), numeralSystem),
167+
},
168+
];
87169
case ArgumentType.THREE_REGISTERS:
88-
return (
89-
<span>
90-
ω<sub>{args?.firstRegisterIndex}</sub>, ω<sub>{args?.secondRegisterIndex}</sub>, ω
91-
<sub>{args?.thirdRegisterIndex}</sub>
92-
</span>
93-
);
94-
170+
return [
171+
{
172+
type: argType.REGISTER,
173+
value: `ω<sub>${args?.firstRegisterIndex}</sub>`,
174+
},
175+
{
176+
type: argType.REGISTER,
177+
value: `ω<sub>${args?.secondRegisterIndex}</sub>`,
178+
},
179+
{
180+
type: argType.REGISTER,
181+
value: `ω<sub>${args?.thirdRegisterIndex}</sub>`,
182+
},
183+
];
95184
default:
96-
return "err";
185+
return null;
97186
}
98187
};

src/context/NumeralSystem.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export enum NumeralSystem {
22
DECIMAL,
33
HEXADECIMAL,
4+
BINARY,
45
}

0 commit comments

Comments
 (0)