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
adding shl shlx
to mul * imm
#1123
Conversation
First, you need to update the representation of memory addresses to support this at fiat-crypto/src/Assembly/Syntax.v Line 26 in e612a32
Presumably you want to change mem_extra_reg to be option (Z * REG) ?
Then you want to change printing of this at fiat-crypto/src/Assembly/Parse.v Lines 268 to 286 in e612a32
Then you want to update the parser combinator expression at fiat-crypto/src/Assembly/Parse.v Lines 173 to 189 in e612a32
probably changing fiat-crypto/src/Assembly/Parse.v Line 187 in e612a32
to something like ((strip_whitespace_around ("+" ||->{id} "-") ;; (parse_Z_arith_strict ;;L strip_whitespace_around "*")? ;; parse_REG)?) ;; Note that it's important to not have overlapping options for parsing whitespace, otherwise we end up with exponentially many possible parses. Roughly this line says "start with a + or - (and just give the fiat-crypto/src/Assembly/Parse.v Line 178 in e612a32
to pull out the + or - and the optional Z and the register and combine them into the right representation. Let me know if you have any trouble with this. |
Do you mean @andres-erbsen do you have thoughts on encoding this into the canonicalizer? Presumably we want a variant of fiat-crypto/src/Assembly/Symbolic.v Lines 1137 to 1152 in 77731c4
that uses something like Haskell's groupBy on node equality or something? Maybe we can add a "groups_by" typeclass like associative or identity, which says for each associative commutative operation how to turn an n-fold operation on identical arguments into a single operation on n and the argument? I guess we need a two-step version of grouping, where we decompose each argument that's a product into the number of copies that it is?
|
This one should be easy, just add a pass that unconditionally rewrites shifts by constants into multiplications
Are you sure this one isn't already handled? I think it should be handled already. (If not, what's the error message?) |
see commit 1ee484e;
I don't really understand the
yes, that's what I meant. My bad. For the rest, I'll have a go on the Memory-adjustments, and for the |
Should give a better error message for mit-plv#1123 (comment)
Could you rebase on top of #1125 and give me the error message after this? The |
@dderjoel |
Edit: full error in attached file
I must admit that I have trouble with the coq-version and ocaml versions on my system (or had, Can't really remember) And I am just happy that I can compile with But what that error means, is that the matches that I've put into the |
Should give a better error message for #1123 (comment)
That's roughly right, though you need to describe how it acts on concrete machine state rather than symbolic state. |
Hrm, I guess we explicitly disable this equivalence fiat-crypto/src/Assembly/Symbolic.v Lines 1140 to 1141 in e151e21
@andres-erbsen Do you know what's up with this? |
I've created #1127 to enable constfolding on mul, let's see how it works |
I think both of us would prefer if you take a stab at it, but either of us can probably help out if need be. |
I think I have something for the syntax and parsing ; but I am struggling with the parser combinator expression. When changing
The code there is:
Where would I add such a pass? That is not in the Assembly-part I assume. |
You want something like
It sounds like you already succeeded at the variable declaration part (adjusting the record). You put the data in
It should be added to the list fiat-crypto/src/Assembly/Symbolic.v Lines 1370 to 1394 in af618d3
|
okay, using
which, fair enough, makes sense. But the type cannot be non-option (i assume that mean optional) because there might not be an
But, probably unsurprisingly, that does not work. All this syntax is so confusing to me, and since you suggested the Prod.prod_beq, I think that this long approach is not the way to go anyway.
uff. I don't even know where to start there. I am having a hard time understanding what is going on in those passes. Are they all rewriting? I can't find any that looks like anything I'd need for this shl->mul rewrite, But also I don't know what I am looking for. And does it make a difference it it is |
You forgot to keep the
Yes
Try starting with this (untested): Definition shift_to_mul :=
fun e => match e with
ExprApp ((shl | shlx | shlZ) as o, [e'; ExprApp (const v, [])]) =>
let o' := match o with shl | shlx => mul 64%N | shlZ => mulZ | _ => o (* impossible *) end in
if Z.eqb v 0
then e'
else if Z.ltb 0 v
then ExprApp (o', [e'; ExprApp (const (2^v)%Z, [])])
else e | _ => e end.
Global Instance shift_to_mul_ok : Ok shift_to_mul_small.
Proof. t. cbn in *. firstorder (lia + eauto). Qed.
What's the difference between these two (in assembly land)?
What do you mean? |
I think you're right that it probably does not matter at this level, but you might need to add something that deals with the flags. The Ok proof will tell you whether or not you need to care; if you can prove Ok, then you're fine. |
I think I start to understand Okay. We have an issue then.
so the issue is, that the 4. makes My question is, if a So now I'm thinking to change the But then I think all this ends up being a bigger change, right? Do you have a better Idea? |
Just for completeness-sake:
I am not too sure about what Edit: the |
just adding this errors in
And the char's are the |
This sounds good to me, and I don't have a better idea. Perhaps the best way to do the parsing is to have five alternatives separated by
It's saying that |
okay, I removed the MEM-changes, I will create another PR for that, lets focus here on the shl-> mul rewrite. File "./src/Assembly/Symbolic.v", line 1381, characters 46-50: Also I cannot find any similar Proofs in the any other rewrites. None starts with |
We need to truncate the expression when there's a bitwidth to truncate it to
Co-authored-by: Jason Gross <jasongross9@gmail.com>
Co-authored-by: Jason Gross <jasongross9@gmail.com>
Co-authored-by: Jason Gross <jasongross9@gmail.com>
Co-authored-by: Jason Gross <jasongross9@gmail.com>
Co-authored-by: Jason Gross <jasongross9@gmail.com>
Co-authored-by: Jason Gross <jasongross9@gmail.com>
Wonderful. Thanks. I just built successfully from this commit, and I can confirm, that it does everything that I need. |
This adds two example files using different instructions to multiply by constants using lea / shl / shlx.
Also it enables the parser to parse those new instructions, but it is still unable to unify.
I think this is because it does not know that
a + a == 2*a == 2<<1
anda * 19 == a + 2 * (8a + a)
,a * 2 * 2 == a * 4
...Also I'd need some pointers to parse
MEM
with scaled index, i.e.[ reg + N * reg ]
; N being 2, 4, 8.