-
Notifications
You must be signed in to change notification settings - Fork 72
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
Instruction delegation #1077
Comments
What would the binary example compile to? I can think of 3 ways: 1:
(Like now, just a different way to write it) 2:
(Saves one lookup) 3:
(Where I think we should aim for the 3rd translation! But is this easy to infer? If not, it might be better to have a more direct syntax? |
I had the last option in mind and don't think it's complicated. |
With the recent changes by @pacheco, we can extract our [memory machine](https://github.com/powdr-labs/powdr/blob/main/riscv/src/compiler.rs#L687-L841) as a separate machine and add it to the standard library. The result should be the same as calling the function linked above with `with_bootloader=false`, except that the memory alignment stuff is not inlined. For this reason, the machine is not yet used by the RISC-V machine, but it could be after #1077 is implemented. [This](eb320dc) shows the diff from what we have in `compiler.rs`. <!-- Please follow this protocol when creating or reviewing PRs in this repository: - Leave the PR as draft until review is required. - When reviewing a PR, every reviewer should assign themselves as soon as they start, so that other reviewers know the PR is covered. You should not be discouraged from reviewing a PR with assignees, but you will know it is not strictly needed. - Unless the PR is very small, help the reviewers by not making forced pushes, so that GitHub properly tracks what has been changed since the last review; use "merge" instead of "rebase". It can be squashed after approval. - Once the comments have been addressed, explicitly let the reviewer know the PR is ready again. -->
Let me try to fix it:
This would compile to 4 permutations (1 for the Did I understand this right? One question I have about this: Does that mean that we allow for assignments between assignment registers? I this case, we'd have to set |
How about this:
So the program has to run two instructions instead of one, but there are a lot fewer columns. I think allowing something like |
As discussed with @pacheco and @chriseth, as an alternative to instruction delegation, we can support links inside instruction definitions. To rewrite Chris' example: instr add X, Y -> Z {
link 1 ~> bin.add X, Y -> Z
}
instr sub X, Y -> Z {
link 1 ~> bin.sub X, Y -> Z
}
// Step 1: Make all constraints conditional on the instruction being active
link instr_add ~> bin.add X, Y -> Z
link instr_sub ~> bin.sub X, Y -> Z
// Step 2: Expand links
instr_add {0, X, Y, Z } is <sel> {bin.operation_id, bin.arg1, bin.arg2, bin.res};
instr_sub {1, X, Y, Z } is <sel> {bin.operation_id, bin.arg1, bin.arg2, bin.res};
// Step 3: Combine permutations / lookups if RHS is the same
(instr_add + instr_sub) {0 * instr_add + 1 * instr_sub, X, Y, Z } is <sel> {bin.operation_id, bin.arg1, bin.arg2, bin.res}; |
Implemented in #1439 |
Currently, we have no way to "invoke" an instruction from another instruction. This is especially important when an instruction uses a permutation, since we cannot just duplicate the called instruction's code in the calling instruction.
To solve this, the following syntax is proposed (the memory example is bad, because the memory machine can probably not be implemented like that, but also see the binary example below):
Here, the
madd
instruction calls both themop
and thewrap
instruction. In doing this, we can read two values from memory, add them (including wrapping the result) and write the result to memory again in the same step. This allows us to even use the same memory address for the written value since the memory machine knows that in one step, the write always comes last.Since the
mop
instruction does not have parameters, it is invoked as is. Thewrap
instruction has parameter and thus also needs two additional assignment registers different fromX
,Y
andZ
. In assembly-to-pil conversion, whenever we set the flag formadd
, we also set the flags formap
andwrap
(note that this could create problems with the "else" condition in the register update constraint).As an alternative, we could just allow the instructions in the body of the instruction definition, but I'm not sure how this would later work with translation via PIL.
Binary example:
The text was updated successfully, but these errors were encountered: