Download backend/arm64/A64/Micro.lean from Snapkitty/ai-free: direct link, hf CLI and curl.
- Browser
- Download file 13.5 kB
-
https://huggingface.co/Snapkitty/ai-free/resolve/main/backend/arm64/A64/Micro.lean
- Command line
-
hf download hf://Snapkitty/ai-free/backend/arm64/A64/Micro.lean
-
curl -L -o Micro.lean https://huggingface.co/Snapkitty/ai-free/resolve/main/backend/arm64/A64/Micro.lean
13.5 kB
| import A64.Seq | |
| /-! | |
| # A64.Micro | |
| Micro-lemmas: how single AArch64 instructions (and the push pair) act on a machine state related to | |
| an IR state by `Rel0`. Every IR-instruction simulation proof is a chain of these. | |
| -/ | |
| namespace WordDialect | |
| namespace A64 | |
| open Reg | |
| theorem ea_nat (a j : Nat) : ofN a + BitVec.ofInt 64 (8 * (j : Int)) = ofN (a + 8 * j) := by | |
| rw [show (8 * (j : Int)) = ((8 * j : Nat) : Int) by omega, BitVec.ofInt_natCast] | |
| exact ofN_add _ _ | |
| /-- Load stack slot `j` into a scratch register. -/ | |
| theorem ld_stack {c : Cfg} {p : Prog 64} {s : State 64} {x : M} (hs : Rel0 c p s x) | |
| {j : Nat} {v : W} (hj : s.dstack[j]? = some v) (rd : Reg) {disp : Int} | |
| (hd : disp = 8 * (j : Int)) : | |
| exec (.load rd Reg.x19 disp) x = .next (x.mov rd v) := by | |
| have hread := hs.stack j v hj | |
| simp only [exec, M.ea, hs.x19, hd, ea_nat] | |
| rw [hread] | |
| theorem mov_rel0 {c : Cfg} {p : Prog 64} {s : State 64} {x : M} (hs : Rel0 c p s x) (rd : Reg) | |
| (hr : rd ≠ x19 ∧ rd ≠ x20 ∧ rd ≠ x21 ∧ rd ≠ x22 ∧ rd ≠ x23 ∧ rd ≠ x24) (v : W) : | |
| Rel0 c p s (x.mov rd v) := by | |
| obtain ⟨h1, h2, h3, h4, h5, h6⟩ := hr | |
| refine hs.congr rfl ?_ ?_ ?_ ?_ ?_ ?_ <;> | |
| simp [M.mov, M.setReg, M.adv, Ne.symm h1, Ne.symm h2, Ne.symm h3, Ne.symm h4, Ne.symm h5, | |
| Ne.symm h6] | |
| theorem arith_rel0 {c : Cfg} {p : Prog 64} {s : State 64} {x : M} (hs : Rel0 c p s x) (rd : Reg) | |
| (hr : rd ≠ x19 ∧ rd ≠ x20 ∧ rd ≠ x21 ∧ rd ≠ x22 ∧ rd ≠ x23 ∧ rd ≠ x24) (v : W) : | |
| Rel0 c p s (x.arith rd v) := by | |
| obtain ⟨h1, h2, h3, h4, h5, h6⟩ := hr | |
| refine hs.congr rfl ?_ ?_ ?_ ?_ ?_ ?_ <;> | |
| simp [M.arith, M.setReg, Ne.symm h1, Ne.symm h2, Ne.symm h3, Ne.symm h4, Ne.symm h5, | |
| Ne.symm h6] | |
| theorem flags_rel0 {c : Cfg} {p : Prog 64} {s : State 64} {x : M} (hs : Rel0 c p s x) | |
| (f : Option Flags) (q : Nat) : Rel0 c p s { x with flags := f, pc := q } := | |
| hs.congr rfl rfl rfl rfl rfl rfl rfl | |
| /-- Store a register into stack slot `j`: the relation holds for the stack with that slot replaced. -/ | |
| theorem st_stack {c : Cfg} {p : Prog 64} {s : State 64} {x : M} (hg : Geom c) (hs : Rel0 c p s x) | |
| {j : Nat} (hj : j < s.dstack.length) (rs : Reg) {disp : Int} (hd : disp = 8 * (j : Int)) : | |
| ∃ mem', exec (.store Reg.x19 disp rs) x = .next { x.adv with mem := mem' } ∧ | |
| Rel0 c p { s with dstack := s.dstack.set j (x.regs rs) } { x.adv with mem := mem' } := by | |
| have hcap := hs.capD | |
| have hcapR := hs.capR | |
| have hdE := hg.dEnd_lt | |
| have hA : c.dBase ≤ c.dEnd - 8 * s.dstack.length + 8 * j := by omega | |
| have hA' : c.dEnd - 8 * s.dstack.length + 8 * j < c.dEnd := by omega | |
| have hvalid := hs.xvalid.1 _ hA hA' | |
| obtain ⟨mem', hw⟩ : ∃ m', x.mem.write? (ofN (c.dEnd - 8 * s.dstack.length + 8 * j)) (x.regs rs) | |
| = some m' := by simp [Memory.write?, hvalid] | |
| refine ⟨mem', ?_, ?_⟩ | |
| · simp only [exec, M.ea, hs.x19, hd, ea_nat]; rw [hw] | |
| · have hlen : (s.dstack.set j (x.regs rs)).length = s.dstack.length := by simp | |
| have hAlt : c.dEnd - 8 * s.dstack.length + 8 * j < 2 ^ 64 := by omega | |
| refine { x19 := ?_, x20 := ?_, x21 := ?_, x22 := ?_, x23 := ?_, x24 := ?_, stack := ?_, | |
| regs := ?_, mem := ?_, rs := ?_, aux := ?_, irvalid := hs.irvalid, xvalid := ?_, | |
| capD := ?_, capR := hs.capR, capA := hs.capA } | |
| · simpa [M.adv, hlen] using hs.x19 | |
| · simpa [M.adv] using hs.x20 | |
| · simpa [M.adv] using hs.x21 | |
| · simpa [M.adv] using hs.x22 | |
| · simpa [M.adv] using hs.x23 | |
| · simpa [M.adv] using hs.x24 | |
| · intro i w hi | |
| simp only [hlen] | |
| have hik : i < s.dstack.length := by | |
| have := (List.getElem?_eq_some_iff.mp hi).1; simpa using this | |
| by_cases hij : i = j | |
| · subst hij | |
| have h1 : (s.dstack.set i (x.regs rs))[i]? = some (x.regs rs) := by simp [hj] | |
| rw [h1] at hi | |
| cases hi | |
| rw [read_write_nat hw hAlt hAlt]; simp | |
| · rw [List.getElem?_set_ne (Ne.symm hij)] at hi | |
| have hne : c.dEnd - 8 * s.dstack.length + 8 * j ≠ c.dEnd - 8 * s.dstack.length + 8 * i := by | |
| omega | |
| rw [read_write_nat hw hAlt (by omega)] | |
| simp only [hne, ite_false] | |
| exact hs.stack i w hi | |
| · intro r hr | |
| have hrf := hg.rf_lt | |
| have hne : c.dEnd - 8 * s.dstack.length + 8 * j ≠ c.rf + 8 * r := by | |
| rcases hg.dS_F with h | h <;> omega | |
| rw [read_write_nat hw hAlt (by omega)] | |
| simp only [hne, ite_false] | |
| exact hs.regs r hr | |
| · intro a ha | |
| have hmb := hg.mb_lt | |
| have hne : c.dEnd - 8 * s.dstack.length + 8 * j ≠ c.mb + 8 * a := by | |
| rcases hg.dS_M with h | h <;> omega | |
| rw [read_write_nat hw hAlt (by omega)] | |
| simp only [hne, ite_false] | |
| exact hs.mem a ha | |
| · intro i a hi | |
| have hsp := hg.sp0_lt | |
| have hrc := hg.rcap_le | |
| have hi' : i < s.rstack.length := by | |
| by_cases hh : i < s.rstack.length | |
| · exact hh | |
| · have hn : s.rstack.length ≤ i := by omega | |
| rw [List.getElem?_eq_none hn] at hi; simp at hi | |
| have hne : c.dEnd - 8 * s.dstack.length + 8 * j ≠ | |
| c.sp0 - 8 * s.rstack.length + 8 * i := by | |
| rcases hg.dS_K with h | h <;> omega | |
| have hkr : 8 * s.rstack.length ≤ c.sp0 := by omega | |
| have hB : c.sp0 - 8 * s.rstack.length + 8 * i < 2 ^ 64 := by omega | |
| rw [read_write_nat hw hAlt hB] | |
| simp only [hne, ite_false] | |
| exact hs.rs i a hi | |
| · exact aux_write_other hg.aEnd_lt hs.capA hs.aux hw hAlt (by rcases hg.dS_A with h | h <;> omega) | |
| · have := Memory.write?_valid hw | |
| show RegionsValid c mem'.valid | |
| rw [this]; exact hs.xvalid | |
| · simpa [hlen] using hcap | |
| /-- Adjust the stack pointer upward by `n` words (popping `n` elements). -/ | |
| theorem adj_drop {c : Cfg} {p : Prog 64} {s : State 64} {x : M} (hg : Geom c) (hs : Rel0 c p s x) | |
| {n : Nat} (hn : n ≤ s.dstack.length) {δ : Int} (hd : δ = 8 * (n : Int)) : | |
| exec (.addImm Reg.x19 δ) x = .next (x.arith Reg.x19 (ofN (c.dEnd - 8 * (s.dstack.length - n)))) ∧ | |
| Rel0 c p { s with dstack := s.dstack.drop n } | |
| (x.arith Reg.x19 (ofN (c.dEnd - 8 * (s.dstack.length - n)))) := by | |
| have hcap := hs.capD | |
| have hval : x.regs Reg.x19 + BitVec.ofInt 64 δ = ofN (c.dEnd - 8 * (s.dstack.length - n)) := by | |
| rw [hs.x19, hd, ea_nat]; congr 1; omega | |
| refine ⟨by simp only [exec, hval], ?_⟩ | |
| refine { x19 := ?_, x20 := ?_, x21 := ?_, x22 := ?_, x23 := ?_, x24 := ?_, stack := ?_, | |
| regs := ?_, mem := ?_, rs := ?_, aux := hs.aux, irvalid := hs.irvalid, xvalid := ?_, | |
| capD := ?_, capR := hs.capR, capA := hs.capA } | |
| · simp [M.arith, M.setReg] | |
| · simpa [M.arith, M.setReg] using hs.x20 | |
| · simpa [M.arith, M.setReg] using hs.x21 | |
| · simpa [M.arith, M.setReg] using hs.x22 | |
| · simpa [M.arith, M.setReg] using hs.x23 | |
| · simpa [M.arith, M.setReg] using hs.x24 | |
| · intro i w hi | |
| simp only [List.length_drop] | |
| rw [List.getElem?_drop] at hi | |
| have := hs.stack (n + i) w hi | |
| have e : c.dEnd - 8 * (s.dstack.length - n) + 8 * i = | |
| c.dEnd - 8 * s.dstack.length + 8 * (n + i) := by omega | |
| simp only [M.arith, M.setReg] | |
| rw [e]; exact this | |
| · exact hs.regs | |
| · exact hs.mem | |
| · exact hs.rs | |
| · exact hs.xvalid | |
| · simp only [List.length_drop]; omega | |
| theorem ea_neg8 {a : Nat} (h : 8 ≤ a) : ofN a + BitVec.ofInt 64 (-8) = ofN (a - 8) := by | |
| have : BitVec.ofInt 64 (-8) = -(ofN 8) := by | |
| rw [show (-8 : Int) = -((8 : Nat) : Int) by omega, BitVec.ofInt_neg, BitVec.ofInt_natCast] | |
| rfl | |
| rw [this, ← BitVec.sub_eq_add_neg, ofN_sub h] | |
| /-- A write inside the data-stack region leaves the register-file, IR-memory and return-stack | |
| views unchanged. -/ | |
| theorem others_write {c : Cfg} {p : Prog 64} {s : State 64} {x : M} (hg : Geom c) | |
| (hs : Rel0 c p s x) {A : Nat} {v : W} {mem' : Memory 64} (hA1 : c.dBase ≤ A) (hA2 : A < c.dEnd) | |
| (hw : x.mem.write? (ofN A) v = some mem') : | |
| RegRel c mem' s.regs ∧ MemRel c mem' s.mem ∧ RsRel c p mem' s.rstack ∧ | |
| AuxRel c mem' s.astack := by | |
| have hdE := hg.dEnd_lt | |
| have hAlt : A < 2 ^ 64 := by omega | |
| have hcapR := hs.capR | |
| have hrc := hg.rcap_le | |
| have hsp := hg.sp0_lt | |
| refine ⟨?_, ?_, ?_, aux_write_other hg.aEnd_lt hs.capA hs.aux hw hAlt | |
| (by rcases hg.dS_A with h | h <;> omega)⟩ | |
| · intro r hr | |
| have hrf := hg.rf_lt | |
| have hne : A ≠ c.rf + 8 * r := by rcases hg.dS_F with h | h <;> omega | |
| rw [read_write_nat hw hAlt (by omega)] | |
| simp only [hne, ite_false] | |
| exact hs.regs r hr | |
| · intro a ha | |
| have hmb := hg.mb_lt | |
| have hne : A ≠ c.mb + 8 * a := by rcases hg.dS_M with h | h <;> omega | |
| rw [read_write_nat hw hAlt (by omega)] | |
| simp only [hne, ite_false] | |
| exact hs.mem a ha | |
| · intro i a hi | |
| have hi' : i < s.rstack.length := by | |
| by_cases hh : i < s.rstack.length | |
| · exact hh | |
| · have hn : s.rstack.length ≤ i := by omega | |
| rw [List.getElem?_eq_none hn] at hi; simp at hi | |
| have hkr : 8 * s.rstack.length ≤ c.sp0 := by omega | |
| have hB : c.sp0 - 8 * s.rstack.length + 8 * i < 2 ^ 64 := by omega | |
| have hne : A ≠ c.sp0 - 8 * s.rstack.length + 8 * i := by rcases hg.dS_K with h | h <;> omega | |
| rw [read_write_nat hw hAlt hB] | |
| simp only [hne, ite_false] | |
| exact hs.rs i a hi | |
| /-- `addImm x19, -8; store [x19], rs` pushes the value of `rs`. -/ | |
| theorem push_pair {c : Cfg} {p : Prog 64} {s : State 64} {x : M} {code : List (Instr Nat)} | |
| (hg : Geom c) (hs : Rel0 c p s x) (rs : Reg) (hrs : rs ≠ x19) | |
| (hfit : c.dBase + 8 * (s.dstack.length + 1) ≤ c.dEnd) | |
| (hat : AAt code x.pc [.addImm Reg.x19 (-8), .store Reg.x19 0 rs]) : | |
| ∃ x', ASteps code x x' ∧ | |
| Rel0 c p { s with dstack := x.regs rs :: s.dstack } x' ∧ x'.pc = x.pc + 2 ∧ | |
| (∀ r, r ≠ x19 → x'.regs r = x.regs r) := by | |
| obtain ⟨h1, h2, _⟩ := hat | |
| have hcap := hs.capD | |
| have hdE := hg.dEnd_lt | |
| have hA1 : c.dBase ≤ c.dEnd - 8 * (s.dstack.length + 1) := by omega | |
| have hA2 : c.dEnd - 8 * (s.dstack.length + 1) < c.dEnd := by omega | |
| have hAlt : c.dEnd - 8 * (s.dstack.length + 1) < 2 ^ 64 := by omega | |
| -- step 1: x19 := x19 - 8 | |
| have hval : x.regs Reg.x19 + BitVec.ofInt 64 (-8) = ofN (c.dEnd - 8 * (s.dstack.length + 1)) := by | |
| rw [hs.x19, ea_neg8 (by omega)] | |
| congr 1 | |
| have e1 : exec (.addImm Reg.x19 (-8)) x = .next (x.arith Reg.x19 (ofN (c.dEnd - 8 * (s.dstack.length + 1)))) := by | |
| simp only [exec, hval] | |
| obtain ⟨x1, hx1⟩ : ∃ x1, x1 = x.arith Reg.x19 (ofN (c.dEnd - 8 * (s.dstack.length + 1))) := ⟨_, rfl⟩ | |
| rw [← hx1] at e1 | |
| have hst1 : step code x = .next x1 := by rw [astep_of_fetch h1, e1] | |
| -- step 2: store [x19], rs | |
| have hr15 : x1.regs Reg.x19 = ofN (c.dEnd - 8 * (s.dstack.length + 1)) := by simp [hx1, M.arith, M.setReg] | |
| have hrsv : x1.regs rs = x.regs rs := by simp [hx1, M.arith, M.setReg, hrs] | |
| have hvalid := hs.xvalid.1 _ hA1 hA2 | |
| obtain ⟨mem', hw⟩ : ∃ m', x.mem.write? (ofN (c.dEnd - 8 * (s.dstack.length + 1))) (x.regs rs) = some m' := by | |
| simp [Memory.write?, hvalid] | |
| have e2 : exec (.store Reg.x19 0 rs) x1 = .next { x1.adv with mem := mem' } := by | |
| have : x1.mem = x.mem := by simp [hx1, M.arith, M.setReg] | |
| simp only [exec, M.ea, hr15, hrsv, this] | |
| have h0 : ofN (c.dEnd - 8 * (s.dstack.length + 1)) + BitVec.ofInt 64 0 = ofN (c.dEnd - 8 * (s.dstack.length + 1)) := by | |
| simp | |
| rw [h0, hw] | |
| have hpc1 : x1.pc = x.pc + 1 := by simp [hx1, M.arith, M.setReg] | |
| have hst2 : step code x1 = .next { x1.adv with mem := mem' } := by | |
| rw [astep_of_fetch (m := x1) (by rw [hpc1]; exact h2), e2] | |
| refine ⟨{ x1.adv with mem := mem' }, (ASteps.single hst1).trans (ASteps.single hst2), ?_, ?_, ?_⟩ | |
| · have ⟨hrg, hmm, hrr, hax⟩ := others_write hg hs hA1 hA2 hw | |
| have hlen : (x.regs rs :: s.dstack).length = s.dstack.length + 1 := by simp | |
| refine { x19 := ?_, x20 := ?_, x21 := ?_, x22 := ?_, x23 := ?_, x24 := ?_, stack := ?_, | |
| regs := hrg, mem := hmm, rs := hrr, aux := hax, irvalid := hs.irvalid, xvalid := ?_, | |
| capD := ?_, capR := hs.capR, capA := hs.capA } | |
| · simpa [hlen, M.adv, hx1, M.arith, M.setReg] using rfl | |
| · simpa [M.adv, hx1, M.arith, M.setReg] using hs.x20 | |
| · simpa [M.adv, hx1, M.arith, M.setReg] using hs.x21 | |
| · simpa [M.adv, hx1, M.arith, M.setReg] using hs.x22 | |
| · simpa [M.adv, hx1, M.arith, M.setReg] using hs.x23 | |
| · simpa [M.adv, hx1, M.arith, M.setReg] using hs.x24 | |
| · intro i w hi | |
| simp only [hlen] | |
| cases i with | |
| | zero => | |
| simp at hi; subst hi | |
| rw [show c.dEnd - 8 * (s.dstack.length + 1) + 8 * 0 = c.dEnd - 8 * (s.dstack.length + 1) by omega, | |
| read_write_nat hw hAlt hAlt]; simp | |
| | succ i => | |
| simp only [List.getElem?_cons_succ] at hi | |
| have hik : i < s.dstack.length := by | |
| have := (List.getElem?_eq_some_iff.mp hi).1; simpa using this | |
| have hB : c.dEnd - 8 * (s.dstack.length + 1) + 8 * (i + 1) < 2 ^ 64 := by omega | |
| have hne : c.dEnd - 8 * (s.dstack.length + 1) ≠ c.dEnd - 8 * (s.dstack.length + 1) + 8 * (i + 1) := by omega | |
| rw [read_write_nat hw hAlt hB] | |
| simp only [hne, ite_false] | |
| have e : c.dEnd - 8 * (s.dstack.length + 1) + 8 * (i + 1) = c.dEnd - 8 * s.dstack.length + 8 * i := by omega | |
| rw [e]; exact hs.stack i w hi | |
| · have := Memory.write?_valid hw | |
| show RegionsValid c mem'.valid | |
| rw [this]; exact hs.xvalid | |
| · simpa [hlen] using hfit | |
| · simp [M.adv, hpc1] | |
| · intro r hr | |
| simp [M.adv, hx1, M.arith, M.setReg, hr] | |
| end A64 | |
| end WordDialect | |