Skip to content

Commit 5906d25

Browse files
committed
Formalization of SIGNEXTEND and rule proofs
1 parent 16787ec commit 5906d25

File tree

5 files changed

+134
-0
lines changed

5 files changed

+134
-0
lines changed

test/formal/opcodes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,18 @@ def BYTE(i, x):
6464
BitVecVal(0, x.size()),
6565
(LShR(x, (x.size() - bit))) & 0xff
6666
)
67+
68+
def SIGNEXTEND(i, x):
69+
bitBV = i * 8 + 7
70+
bitInt = BV2Int(i) * 8 + 7
71+
test = BitVecVal(1, x.size()) << bitBV
72+
mask = test - 1
73+
return If(
74+
bitInt >= x.size(),
75+
x,
76+
If(
77+
(x & test) == 0,
78+
x & mask,
79+
x | ~mask
80+
)
81+
)

test/formal/signextend.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from rule import Rule
2+
from opcodes import *
3+
4+
"""
5+
Rule:
6+
1) SIGNEXTEND(A, X) -> X if A >= Pattern::WordSize / 8 - 1;
7+
8+
2) SIGNEXTEND(X, SIGNEXTEND(X, Y)) -> SIGNEXTEND(X, Y)
9+
10+
3) SIGNEXTEND(A, SIGNEXTEND(B, X)) -> SIGNEXTEND(min(A, B), X)
11+
"""
12+
13+
n_bits = 128
14+
15+
# Input vars
16+
X = BitVec('X', n_bits)
17+
Y = BitVec('Y', n_bits)
18+
A = BitVec('A', n_bits)
19+
B = BitVec('B', n_bits)
20+
21+
rule1 = Rule()
22+
# Requirements
23+
rule1.require(UGE(A, BitVecVal(n_bits // 8 - 1, n_bits)))
24+
rule1.check(SIGNEXTEND(A, X), X)
25+
26+
rule2 = Rule()
27+
rule2.check(
28+
SIGNEXTEND(X, SIGNEXTEND(X, Y)),
29+
SIGNEXTEND(X, Y)
30+
)
31+
32+
rule3 = Rule()
33+
rule3.check(
34+
SIGNEXTEND(A, SIGNEXTEND(B, X)),
35+
SIGNEXTEND(If(ULT(A, B), A, B), X)
36+
)
37+

test/formal/signextend_and.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from rule import Rule
2+
from opcodes import *
3+
4+
"""
5+
Rule:
6+
AND(A, SIGNEXTEND(B, X)) -> AND(A, X)
7+
given
8+
B < WordSize / 8 - 1 AND
9+
A & (1 << ((B + 1) * 8) - 1) == A
10+
"""
11+
12+
n_bits = 128
13+
14+
# Input vars
15+
X = BitVec('X', n_bits)
16+
A = BitVec('A', n_bits)
17+
B = BitVec('B', n_bits)
18+
19+
rule = Rule()
20+
# Requirements
21+
rule.require(ULT(B, BitVecVal(n_bits // 8 - 1, n_bits)))
22+
rule.require((A & ((BitVecVal(1, n_bits) << ((B + 1) * 8)) - 1)) == A)
23+
rule.check(
24+
AND(A, SIGNEXTEND(B, X)),
25+
AND(A, X)
26+
)

test/formal/signextend_shl.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from rule import Rule
2+
from opcodes import *
3+
4+
"""
5+
Rule:
6+
SHL(A, SIGNEXTEND(B, X)) -> SIGNEXTEND((A >> 3) + B, SHL(A, X))
7+
given return A & 7 == 0 AND A <= WordSize AND B <= WordSize / 8
8+
"""
9+
10+
n_bits = 256
11+
12+
# Input vars
13+
X = BitVec('X', n_bits)
14+
Y = BitVec('Y', n_bits)
15+
A = BitVec('A', n_bits)
16+
B = BitVec('B', n_bits)
17+
18+
rule = Rule()
19+
rule.require(A & 7 == 0)
20+
rule.require(ULE(A, n_bits))
21+
rule.require(ULE(B, n_bits / 8))
22+
rule.check(
23+
SHL(A, SIGNEXTEND(B, X)),
24+
SIGNEXTEND(LShR(A, 3) + B, SHL(A, X))
25+
)

test/formal/signextend_shr.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from rule import Rule
2+
from opcodes import *
3+
4+
"""
5+
Rule:
6+
SIGNEXTEND(A, SHR(B, X)) -> SAR(B, X)
7+
given
8+
B % 8 == 0 AND
9+
A <= WordSize AND
10+
B <= wordSize AND
11+
(WordSize - B) / 8 == A + 1
12+
"""
13+
14+
n_bits = 256
15+
16+
# Input vars
17+
X = BitVec('X', n_bits)
18+
Y = BitVec('Y', n_bits)
19+
A = BitVec('A', n_bits)
20+
B = BitVec('B', n_bits)
21+
22+
rule = Rule()
23+
rule.require(B % 8 == 0)
24+
rule.require(ULE(A, n_bits))
25+
rule.require(ULE(B, n_bits))
26+
rule.require((BitVecVal(n_bits, n_bits) - B) / 8 == A + 1)
27+
rule.check(
28+
SIGNEXTEND(A, SHR(B, X)),
29+
SAR(B, X)
30+
)
31+

0 commit comments

Comments
 (0)