-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlh.lean
More file actions
109 lines (95 loc) · 3.48 KB
/
lh.lean
File metadata and controls
109 lines (95 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import OpenvmFv.RV32D.Auxiliaries
namespace PureSpec
structure LhInput where
-- operands
r1 : BitVec 5
imm : BitVec 12
rd : BitVec 5
-- registers
r1_val : BitVec 32
PC : BitVec 32
-- memory
data0 : BitVec 8
data1 : BitVec 8
structure LhOutput where
-- registers
nextPC : BitVec 32
rd : Option (Finset.Icc 1 31 × BitVec 32)
private lemma range (bv : BitVec 5) (h : bv ≠ 0)
: bv.toNat ∈ Finset.Icc 1 31
:= by
apply Finset.mem_Icc.mpr
obtain ⟨x: Fin 32⟩ := bv
fin_cases x <;> simp_all
def execute_LOADH_pure (input : LhInput) : LhOutput := {
nextPC := input.PC + 4#32
rd := if h: input.rd = 0
then .none
else .some (
⟨
input.rd.toNat,
range input.rd h
⟩,
(BitVec.signExtend 32 (input.data1 ++ input.data0))
)
: LhOutput
}
def lh_state_assumptions
(i : LhInput)
(state : PreSail.SequentialState RegisterType Sail.trivialChoiceSource)
: Prop :=
state.regs.get? Register.PC = .some i.PC ∧
LeanRV32D.Functions.rX_bits (regidx.Regidx i.r1) state = EStateM.Result.ok i.r1_val state ∧
state.mem[i.r1_val.toNat + (BitVec.signExtend 32 i.imm).toNat]? = .some i.data0 ∧
state.mem[(i.r1_val.toNat + (BitVec.signExtend 32 i.imm).toNat) + 1]? = .some i.data1 ∧
i.r1_val.toNat + (BitVec.signExtend 32 i.imm).toNat < OpenVM_address_space_size ∧
(2 : ℤ) ∣ i.r1_val.toNat + (BitVec.signExtend 32 i.imm).toNat
set_option maxHeartbeats 0 in
lemma execute_LOADH_pure_equiv
(input : LhInput)
(risc_v_assumptions : RISC_V_assumptions state mstatus pmaRegion misa mseccfg)
(h_opcode_assumptions : lh_state_assumptions input state)
:
(
do
Sail.writeReg Register.nextPC (Sail.BitVec.addInt (← Sail.readReg Register.PC) 4)
LeanRV32D.Functions.execute (instruction.LOAD (
input.imm,
regidx.Regidx input.r1,
regidx.Regidx input.rd,
false,
2
))
) state =
let output := execute_LOADH_pure input
(do
Sail.writeReg Register.nextPC output.nextPC
match output.rd with
| .some (rd, rd_val) => write_xreg rd rd_val
| .none => pure ()
pure (ExecutionResult.Retire_Success ())
) state
:= by
have next_gma := RISC_V_assumptions_invariant_under_pc_increment risc_v_assumptions (val := input.PC + 4#32)
unfold lh_state_assumptions at h_opcode_assumptions
simp [
Sail.readReg,
PreSail.readReg,
writeReg_state_success,
LeanRV32D.Functions.execute,
*
]
have h_r1_val := rX_bits_write_other_reg_state (val := input.PC + 4#32) h_opcode_assumptions.2.1 reg_of_fin_neq_nextPC
obtain ⟨ h_priv, h_mprv, h_pma_regions, h_pma_base, h_pma_size, h_pma_readable, h_pma_writable, h_pma_misaligned, h_htif, h_misa, h_mseccfg ⟩ := next_gma
have := arithmetic_helper (a := input.r1_val.toNat) (b := (BitVec.signExtend 32 input.imm).toNat) (by grind)
simp [LeanRV32D.Functions.execute_LOAD, LeanRV32D.Functions.vmem_read, EStateM.map, *]
simp [LeanRV32D.Functions.vmem_read_addr, ExceptT.run, *]
rw [if_pos (by omega)]; simp [*]
rw [if_neg (by omega)]
simp [write_reg_state, execute_LOADH_pure, *]
split_ifs with h_rd
. simp [LeanRV32D.Functions.wX_bits, LeanRV32D.Functions.wX, *]
. let r : Finset.Icc 1 31 := ⟨input.rd.toNat, range input.rd h_rd⟩
rewrite [ wX_write_xreg_non_zero_equiv _ _ _ r (by simp [r])]
grind
end PureSpec