-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmulh.lean
More file actions
95 lines (87 loc) · 2.89 KB
/
mulh.lean
File metadata and controls
95 lines (87 loc) · 2.89 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
import OpenvmFv.RV32D.Auxiliaries
import OpenvmFv.Fundamentals.Execution
namespace PureSpec
structure MulhInput where
-- operands
r1_val : BitVec 32
r2_val : BitVec 32
rd : Fin 32
-- registers
PC : BitVec 32
structure MulhOutput where
-- registers
nextPC : BitVec 32
rd : Option (Finset.Icc 1 31 × BitVec 32)
def execute_MULH_mulh_pure (input : MulhInput) : MulhOutput := {
nextPC := input.PC + 4#32
rd := if h: input.rd = 0
then .none
else .some (
⟨
input.rd.val,
by apply Finset.mem_Icc.mpr; omega
⟩,
(execute_MUL_pure input.r1_val input.r2_val .MULH)
)
: MulhOutput
}
lemma execute_MULH_mulh_pure_equiv
(mulh_input : MulhInput)
(r1 r2 rd: regidx)
(h_input_r1: read_xreg (regidx_to_fin r1) state = EStateM.Result.ok (mulh_input.r1_val) state)
(h_input_r2: read_xreg (regidx_to_fin r2) state = EStateM.Result.ok (mulh_input.r2_val) state)
(h_input_rd: mulh_input.rd = regidx_to_fin rd)
(h_input_pc: state.regs.get? Register.PC = .some mulh_input.PC)
:
(
do
Sail.writeReg Register.nextPC (Sail.BitVec.addInt (← Sail.readReg Register.PC) 4)
LeanRV32D.Functions.execute (instruction.MUL (r2, r1, rd, { result_part := VectorHalf.High, signed_rs1 := .Signed, signed_rs2 := .Signed }))
) state =
let mulh_output := execute_MULH_mulh_pure mulh_input
(do
Sail.writeReg Register.nextPC mulh_output.nextPC
match mulh_output.rd with
| .some (rd, rd_val) => write_xreg rd rd_val
| .none => pure ()
pure (ExecutionResult.Retire_Success ())
) state
:= by
simp [
readReg_succ h_input_pc,
writeReg_state_success,
LeanRV32D.Functions.execute,
execute_MUL'
]
rewrite [rX_read_xreg_equiv _ r1 (regidx_to_fin r1) (by simp [regidx_to_fin])]
rewrite [read_xreg_write_other_reg_state _ h_input_r1 reg_of_fin_neq_nextPC]
simp
rewrite [rX_read_xreg_equiv _ r2 (regidx_to_fin r2) (by simp [regidx_to_fin])]
rewrite [read_xreg_write_other_reg_state _ h_input_r2 reg_of_fin_neq_nextPC]
simp [
execute_MUL_pure,
execute_MULH_mulh_pure,
mop_of_mul_op
]
obtain ⟨rd⟩ := rd
by_cases h_zero: rd = 0
. rewrite [h_zero, wX_write_xreg_zero_equiv]
simp
rewrite [dite_cond_eq_true]
. simp
. simp [h_input_rd, h_zero, regidx_to_fin]
. have h_inc := regidx_non_zero h_zero
apply Finset.mem_Icc.mp at h_inc
obtain ⟨h_low, h_high⟩ := h_inc
rewrite [
wX_write_xreg_non_zero_equiv _ _
(regidx.Regidx rd)
⟨(regidx_to_fin (regidx.Regidx rd)).val, Finset.mem_Icc.mpr ⟨h_low, h_high⟩⟩
(by simp [regidx_to_fin])
]
simp [regidx_to_fin]
rewrite [dite_cond_eq_false]
. simp [h_input_rd, regidx_to_fin]
. simp [regidx_to_fin] at *
omega
end PureSpec