Skip to content

Commit ab4af3c

Browse files
authored
Merge pull request #2037 from JasonGross/shld
Add support for shld
2 parents 83f84f9 + 2c04184 commit ab4af3c

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

src/Assembly/Symbolic.v

+6
Original file line numberDiff line numberDiff line change
@@ -4335,6 +4335,12 @@ Definition SymexNormalInstruction {opts : symbolic_options_computed_opt} {descr:
43354335
v <- Symeval (or s@(shr s@(lo, cnt), shl s@(hi, cnt')));
43364336
_ <- SetOperand dst v;
43374337
HavocFlags
4338+
| shld, [hi as dst; lo; cnt] =>
4339+
let cnt := andZ@(cnt, (PreApp (const (Z.of_N s-1)%Z) nil)) in
4340+
let cnt' := addZ@(Z.of_N s, PreApp negZ [cnt]) in
4341+
v <- Symeval (or s@(shr s@(lo, cnt'), shl s@(hi, cnt)));
4342+
_ <- SetOperand dst v;
4343+
HavocFlags
43384344
| inc, [dst] =>
43394345
v <- Symeval (add s@(dst, PreARG 1%Z));
43404346
o <- Symeval (addoverflow s@(dst, PreARG 1%Z));

src/Assembly/WithBedrock/Semantics.v

+17
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,23 @@ Definition DenoteNormalInstruction (st : machine_state) (instr : NormalInstructi
327327
let st := if cnt =? 1 then SetFlag st OF signchange else st in
328328
let st := SetFlag st CF (Z.testbit l (cnt-1)) in
329329
Some (HavocFlag st AF)
330+
| shld, [dst as hi; lo; cnt] =>
331+
lv <- DenoteOperand sa s st lo;
332+
hv <- DenoteOperand sa s st hi;
333+
cnt <- DenoteOperand sa s st cnt;
334+
let l := Z.lor lv (Z.shiftl hv (Z.of_N s)) in
335+
let l_shifted := Z.shiftl l (Z.land cnt (Z.of_N s-1)) in
336+
let l_shifted_hi := Z.shiftr l_shifted (Z.of_N s) in
337+
let v := Z.land l_shifted_hi (Z.ones (Z.of_N s)) in
338+
st <- SetOperand sa s st dst v;
339+
if cnt =? 0 then Some st else
340+
if Z.of_N s <? cnt then Some (HavocFlags st) else
341+
let st := HavocFlagsFromResult s st l in
342+
let signchange := xorb (signed s hv <? 0)%Z (signed s v <? 0)%Z in
343+
(* Note: IA-32 SDM does not make it clear what sign change is in question *)
344+
let st := if cnt =? 1 then SetFlag st OF signchange else st in
345+
let st := SetFlag st CF (Z.testbit hv (Z.of_N s - cnt)) in
346+
Some (HavocFlag st AF)
330347
| (and | xor | or) as opc, [dst; src] =>
331348
let f := match opc with and => Z.land | xor => Z.lxor | _ => Z.lor end in
332349
v1 <- DenoteOperand sa s st dst;

src/Assembly/WithBedrock/SymbolicProofs.v

+13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ From Coq Require Import Lia.
33
Require Import Crypto.Util.ZUtil.Tactics.PullPush.
44
From Coq Require Import NArith.
55
From Coq Require Import ZArith.
6+
Require Import Crypto.Util.ZUtil.Testbit.
67
Require Import Crypto.AbstractInterpretation.ZRange.
78
Require Import Crypto.Util.ErrorT.
89
Import Coq.Lists.List. (* [map] is [List.map] not [ErrorT.map] *)
@@ -1343,6 +1344,18 @@ Proof using Type.
13431344
3: enough (0 <= Z.land v3 (Z.of_N n - 1)) by lia; eapply Z.land_nonneg; right.
13441345
1,2,3:pose_operation_size_cases; intuition (subst; cbn; clear; lia). }
13451346

1347+
Unshelve. all : match goal with H : context[Syntax.shld] |- _ => idtac | _ => shelve end; shelve_unifiable.
1348+
{ repeat match goal with H : ?x = Some _, H' : ?x = Some _ |- _ => rewrite H' in *; Option.inversion_option end.
1349+
progress subst.
1350+
replace (Z.land (Z.of_N n) (Z.ones (Z.of_N n))) with (Z.of_N n)
1351+
by (rewrite Z.land_ones, Z.mod_small; try split; try lia; apply Zpow_facts.Zpower2_lt_lin; lia).
1352+
assert (0 <= Z.of_N n - 1) by (pose_operation_size_cases; intuition (subst; cbn; clear; lia)).
1353+
rewrite <- !Z.shiftl_opp_r.
1354+
rewrite !Z.shiftl_lor.
1355+
rewrite <- !Z.land_lor_distr_l, <- Z.land_assoc, Z.land_diag.
1356+
rewrite !Z.shiftl_shiftl by (try apply Z.land_nonneg; lia).
1357+
f_equal; f_equal; f_equal; try lia. }
1358+
13461359
Unshelve. all : match goal with H : context[Syntax.shlx] |- _ => idtac | _ => shelve end; shelve_unifiable.
13471360
{ rewrite <- Z.land_assoc.
13481361
f_equal; f_equal; [].

0 commit comments

Comments
 (0)