Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype for ahead-of-time decoding #519

Closed
wants to merge 15 commits into from

Conversation

matthiasgoergens
Copy link
Collaborator

@matthiasgoergens matthiasgoergens commented Nov 1, 2024

A prototype to show how this could look like. It doesn't pass the tests, yet.

Aurélien Nicolas and others added 3 commits October 31, 2024 15:36
@matthiasgoergens matthiasgoergens changed the title Prototype for doign ahead of time decoding Prototype for ahead-of-time decoding Nov 1, 2024
{
let rd = rd.unwrap_or_else(|| T::from(DecodedInstruction::RD_NULL));
InsnRecord([pc, opcode, rd, funct3, rs1, rs2, imm_internal])
pub fn new(pc: T, kind: T, rd: T, rs1: T, rs2: T, imm: T) -> Self {
Copy link
Collaborator

@naure naure Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merging opcode+funct3 into kind makes a lot of sense! Can you make a PR just for that?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In principle there could have been circuits that handle multiple kinds with a funct3 witness, but we are not doing that so it’s ok to remove it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank. Yes, I would advise against having such circuits. Just have a 'kind' field, and do all the opcode + funct3 + etc merging ahead of time when decoding, so that your circuits don't have to worry.

Merging opcode+funct3 into kind makes a lot of sense! Can you make a PR just for that?

I prepared one earlier #475

Specifically that's a prototype for how we can use structs with named fields instead of indices into an anonymous slice. I'd like to get that one in, and then make the merge of opcode+funct3 on top of that saner foundation.

The crux of that PR is to use repr(C) to get the struct laid out in order in memory, so we can treat it as a slice, when we need to. (But that trick is not strictly necessary, it just makes things easier to type out.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hoped that could be a simple PR? No need for a complete rewrite.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracked here: #533

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By itself that would be a set of reasonably simple PRs. I would have just hoped to do that after the refactor away from an anonymous slice towards named entries.

But I guess I can bite the bullet and deal with the merge conflicts on my side.

@@ -110,6 +105,37 @@ pub struct DecodedInstruction {
opcode: u32,
}

#[derive(Clone, Copy, Debug)]
pub struct DecodedInstruction {
pub kind: InsnKind,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strong personal aversion to this style. It’s a better practice to keep representation details private and expose public methods.

Copy link
Collaborator Author

@matthiasgoergens matthiasgoergens Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's exactly what we are doing here.

The representation that we keep private is incoming u32 word for the instruction.

Our public method just has a slightly more sophisticated return type than just a single number: we return essentially a tuple. We make this more readable by using a struct with named fields instead of a literal tuple.

(Think of it like returning a Result or an Option where you can also access the data type directly, because that is the interface.)

And to keep things even more simple we toss out the initials representation, and only keep what the method returned.

Copy link
Collaborator Author

@matthiasgoergens matthiasgoergens Nov 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That being said, if you really feel the need to emulate Java and slap a getter in front of everything, that's not a hill I need to die on for this specific use case.

(In general, pattern matching and borrow checking et al don't work well with the getters-style. So I would suggest to avoid it when possible, and only use it strictly when necessary; instead of reaching for it as your default style in a language like Rust.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you really feel the need to emulate Java and slap a getter in front of everything

I missed that one. That is not true and that would be silly.

There can be data containers (pub fields), in which case the module commits to the representation as simple & stable. That means other modules can write the fields directly with low risk of misunderstandings. If over time it becomes more complex then it's time to switch. Rarely the other way.

Yes it could have been that way. Whoever decided against at the time. It could be that way again if you want to spend the time.

@naure naure mentioned this pull request Nov 2, 2024
4 tasks
@matthiasgoergens
Copy link
Collaborator Author

Looks like this ain't gonna happen. Oh, well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants