Skip to content

Commit a18718e

Browse files
committed
Implement CLZ opcode
This also bumps the Solidity version used in tests to be able to compile an example with CLZ
1 parent d28f99c commit a18718e

File tree

14 files changed

+58
-85
lines changed

14 files changed

+58
-85
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
## Added
1111
- We support RPC in equivalence checking now
12+
- New opcode: CLZ
1213

1314
## Fixed
1415
- Fix incorrect simplification rule for `PEq (Lit 1) (IsZero (LT a b))`

flake.lock

Lines changed: 19 additions & 77 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
inputs = {
55
flake-utils.url = "github:numtide/flake-utils";
66
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
7-
foundry.url = "github:shazow/foundry.nix/stable";
7+
foundry = {
8+
url = "github:shazow/foundry.nix/stable";
9+
inputs.nixpkgs.follows = "nixpkgs";
10+
inputs.flake-utils.follows = "flake-utils";
11+
};
812
solidity = {
913
url = "github:argotorg/solidity/8a97fa7a1db1ec509221ead6fea6802c684ee887";
1014
flake = false;
@@ -24,6 +28,7 @@
2428
solc-pkgs = {
2529
url = "github:hellwolf/solc.nix";
2630
inputs.nixpkgs.follows = "nixpkgs";
31+
inputs.flake-utils.follows = "flake-utils";
2732
};
2833
};
2934

@@ -35,7 +40,7 @@
3540
overlays = [solc-pkgs.overlay];
3641
config = { allowBroken = true; };
3742
});
38-
solc = (solc-pkgs.mkDefault pkgs pkgs.solc_0_8_26);
43+
solc = (solc-pkgs.mkDefault pkgs pkgs.solc_0_8_31);
3944
testDeps = [
4045
solc
4146
foundry.defaultPackage.${system}

src/EVM.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ exec1 conf = do
425425
OpShl -> {-# SCC "OpShl" #-} stackOp2 g_verylow Expr.shl
426426
OpShr -> {-# SCC "OpShr" #-} stackOp2 g_verylow Expr.shr
427427
OpSar -> {-# SCC "OpSar" #-} stackOp2 g_verylow Expr.sar
428+
OpClz -> {-# SCC "OpClz" #-} stackOp1 g_low Expr.clz
428429

429430
-- more accurately referred to as KECCAK
430431
OpSha3 -> {-# SCC "OpSha3" #-}

src/EVM/Assembler.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ assemble os = V.fromList $ concatMap go os
4242
OpShl -> [LitByte 0x1B]
4343
OpShr -> [LitByte 0x1C]
4444
OpSar -> [LitByte 0x1D]
45+
OpClz -> [LitByte 0x1E]
4546
OpSha3 -> [LitByte 0x20]
4647
OpAddress -> [LitByte 0x30]
4748
OpBalance -> [LitByte 0x31]

src/EVM/Expr.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ sar = op2 SAR (\x y ->
202202
else
203203
fromIntegral $ shiftR asSigned (fromIntegral x))
204204

205+
clz :: Expr EWord -> Expr EWord
206+
clz = op1 CLZ (\x -> if x == 0 then 256 else fromIntegral $ countLeadingZeros x)
207+
205208

206209
-- Props
207210

@@ -1236,6 +1239,9 @@ simplifyNoLitToKeccak e = untilFixpoint (mapExpr go) e
12361239
| a == (Lit 0) = v
12371240
| v == (Lit 0) = v
12381241
| otherwise = sar a v
1242+
go (CLZ v)
1243+
| v == (Lit 0) = Lit 256
1244+
| otherwise = clz v
12391245

12401246
-- Bitwise AND & OR. These MUST preserve bitwise equivalence
12411247
go (And a b)

src/EVM/Format.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,7 @@ formatExpr = go
662662
SHL a b -> fmt "SHL" [a, b]
663663
SHR a b -> fmt "SHR" [a, b]
664664
SAR a b -> fmt "SAR" [a, b]
665+
CLZ a -> fmt "CLZ" [a]
665666

666667
e@Origin -> T.pack (show e)
667668
e@Coinbase -> T.pack (show e)

src/EVM/Op.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ intToOpName a =
4545
0x1b -> "SHL"
4646
0x1c -> "SHR"
4747
0x1d -> "SAR"
48+
0x1e -> "CLZ"
4849
0x20 -> "SHA3"
4950
0x30 -> "ADDRESS"
5051
--
@@ -206,6 +207,7 @@ opString (i, o) = let showPc x | x < 0x10 = '0' : showHex x ""
206207
OpShl -> "SHL"
207208
OpShr -> "SHR"
208209
OpSar -> "SAR"
210+
OpClz -> "CLZ"
209211
OpSha3 -> "SHA3"
210212
OpAddress -> "ADDRESS"
211213
OpBalance -> "BALANCE"
@@ -305,6 +307,7 @@ getOp x = case x of
305307
0x1b -> OpShl
306308
0x1c -> OpShr
307309
0x1d -> OpSar
310+
0x1e -> OpClz
308311
0x20 -> OpSha3
309312
0x30 -> OpAddress
310313
0x31 -> OpBalance

src/EVM/SMT.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ exprToSMT = \case
478478
SHL a b -> op2 "bvshl" b a
479479
SHR a b -> op2 "bvlshr" b a
480480
SAR a b -> op2 "bvashr" b a
481+
CLZ a -> op1 "clz" a
481482
SEx a b -> op2 "signext" a b
482483
Div a b -> op2CheckZero "bvudiv" a b
483484
SDiv a b -> op2CheckZero "bvsdiv" a b

src/EVM/SMT/SMTLIB.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ prelude = SMT2 src mempty mempty
2929
]) <> [(SMTComment "slot -> value"), SMTCommand "(define-sort Storage () (Array Word Word))"]
3030
<> (fmap SMTCommand [
3131
"(declare-fun keccak (Buf Word) Word)",
32-
"(declare-fun sha256 (Buf Word) Word)"
32+
"(declare-fun sha256 (Buf Word) Word)",
33+
"(declare-fun clz (Word) Word)"
3334
])
3435
macros = fmap SMTCommand [
3536
"(define-fun max ((a (_ BitVec 256)) (b (_ BitVec 256))) (_ BitVec 256) (ite (bvult a b) b a))",

0 commit comments

Comments
 (0)