File size: 17,564 Bytes
9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 0e9783b 9ad95e5 | 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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | import RV32.SimAux
/-!
# RV32.SimStep
One IR step is simulated by the lowered RISC-V code, for every instruction and every outcome
(`next`, `halted`, `trapped`). This is the case analysis over the whole instruction set that the
whole-program theorem iterates.
Every instruction that grows the data stack or the auxiliary stack, and every `call`, first checks
for room and exits with `overflow` when the stack is full. So `sim_exec` has no capacity hypothesis: the code either
simulates the IR step, or the state lacks the headroom `Fits` describes and the code overflows.
-/
namespace WordDialect
namespace RV32
open Reg
/-- Headroom for one step: room to push one data word, two return addresses. worth of
stack, and one auxiliary word. -/
def Fits (c : Cfg) (s : State 32) : Prop :=
c.dBase + 4 * (s.dstack.length + 1) ≤ c.dEnd ∧ s.rstack.length + 2 ≤ c.rcap ∧
c.aBase + 4 * (s.astack.length + 1) ≤ c.aEnd
/-- What simulating an IR outcome means on the RISC-V side. -/
def Sim (c : Cfg) (p : Prog 32) (code : List (Instr Nat)) (x : M) : Outcome 32 → Prop
| .next s' => ∃ x', RSteps code x x' ∧ Rel c p s' x'
| .halted s' => ∃ x', RExec code x (.halted x') ∧ Rel0 c p s' x'
| .trapped t => RExec code x (.trapped t)
theorem shape1 {l : List W} (h : 1 ≤ l.length) : ∃ a d, l = a :: d := by
cases l with
| nil => simp at h
| cons a d => exact ⟨a, d, rfl⟩
theorem shape2 {l : List W} (h : 2 ≤ l.length) : ∃ b a d, l = b :: a :: d := by
cases l with
| nil => simp at h
| cons b l =>
cases l with
| nil => simp at h
| cons a d => exact ⟨b, a, d, rfl⟩
theorem shape3 {l : List W} (h : 3 ≤ l.length) : ∃ cc y v d, l = cc :: y :: v :: d := by
cases l with
| nil => simp at h
| cons cc l =>
cases l with
| nil => simp at h
| cons y l =>
cases l with
| nil => simp at h
| cons v d => exact ⟨cc, y, v, d, rfl⟩
theorem lowerInstr_uf (L : Layout) (base : Nat) (off : Nat → Nat) (g : Facts) (i : WordDialect.Instr 32)
(h : 0 < i.pops) :
∃ rest, lowerInstr L base off g i = uf L (need g i.pops) base ++ rest ∧ i.pops ≤ 3 := by
cases i <;> first
| exact ⟨_, rfl, by simp [Instr.pops]⟩
| exact ⟨_, List.append_assoc _ _ _, by simp [Instr.pops]⟩
| exact absurd h (by simp [Instr.pops])
theorem Rel0.setPc {c : Cfg} {p : Prog 32} {s : State 32} {x : M} (h : Rel0 c p s x) (n : Nat) :
Rel0 c p { s with pc := n } x :=
{ s1 := h.s1, s2 := h.s2, s3 := h.s3, s4 := h.s4, s5 := h.s5, s6 := h.s6,
stack := h.stack, regs := h.regs, mem := h.mem, rs := h.rs, aux := h.aux, irvalid := h.irvalid,
xvalid := h.xvalid, capD := h.capD, capR := h.capR, capA := h.capA }
section Step
variable {c : Cfg} {p : Prog 32} {s : State 32} {x : M} {L : Layout}
theorem sim_next {code : List (Instr Nat)} {s' : State 32}
(h : ∃ x', RSteps code x x' ∧ Rel c p s' x') : Sim c p code x (.next s') := h
theorem sim_halted {code : List (Instr Nat)} {s' : State 32}
(h : ∃ x', RExec code x (.halted x') ∧ Rel0 c p s' x') : Sim c p code x (.halted s') := h
theorem sim_trapped {code : List (Instr Nat)} {t : Trap} (h : RExec code x (.trapped t)) :
Sim c p code x (.trapped t) := h
theorem rel_fall {i : WordDialect.Instr 32} (hi : p[s.pc]? = some i) {s' : State 32}
{x' : M} (h0 : Rel0 c p s' x') (hpc : x'.pc = offs c.facts p s.pc + isize (c.facts s.pc) i) :
Rel c p { s' with pc := s.pc + 1 } x' :=
⟨h0.setPc _, by rw [hpc, offs_succ c.facts hi]⟩
theorem sim_exec (hg : Geom c) (hL : L.dEnd = ofN c.dEnd) (hMs : L.memSize = c.M)
(hLd : L.dLim = ofN (c.dBase + 4)) (hLr : L.rGap = ofN (4 * c.rcap - 8))
(hLa : L.aEnd = ofN c.aEnd) (hLal : L.aLim = ofN (c.aBase + 4))
(hLf : L.facts = c.facts) (hsz : ∀ k, offs c.facts p k < 2 ^ 32) (hs : Rel c p s x)
(hgd : c.cert s.pc ≤ s.dstack.length) (hub : s.dstack.length ≤ c.ub s.pc)
{i : WordDialect.Instr 32} (hi : p[s.pc]? = some i)
(hreg : ∀ r, (i = .push r ∨ i = .pop r) → r < c.nregs) :
Sim c p (lowerProg L p) x (WordDialect.exec i s) ∨
(¬ Fits c s ∧ RExec (lowerProg L p) x .overflow) := by
have nfD : ¬ c.dBase + 4 * (s.dstack.length + 1) ≤ c.dEnd → ¬ Fits c s := fun h hf => h hf.1
have nfR : ¬ s.rstack.length + 2 ≤ c.rcap → ¬ Fits c s := fun h hf => h hf.2.1
have nfA : ¬ c.aBase + 4 * (s.astack.length + 1) ≤ c.aEnd → ¬ Fits c s := fun h hf => h hf.2.2
have hpc : x.pc = offs c.facts p s.pc := hs.2
have hs0 : Rel0 c p s x := hs.1
have hat := lowerProg_at L p s.pc i hi
rw [hLf] at hat
-- Where the stack may be full, the overflow guard is there: the bound left it out only where
-- one more word fits.
have hnov : ¬ c.dBase + 4 * (s.dstack.length + 1) ≤ c.dEnd → (c.facts s.pc).noOvf = false := by
intro hf
cases h : (c.facts s.pc).noOvf
· rfl
· exfalso; apply hf
simp only [Cfg.facts, decide_eq_true_eq] at h
unfold Cfg.dCap at h
omega
by_cases hk : s.dstack.length < i.pops
· rw [exec_underflow i s hk]
obtain ⟨rest, hlow, h3⟩ := lowerInstr_uf L (offs c.facts p s.pc) (offs c.facts p) (c.facts s.pc) i
(by omega)
rw [hlow] at hat
exact .inl <| sim_trapped (sim_uf_trap hg hs0 hL (by omega) h3 hgd hk hpc hat)
· have hk' : i.pops ≤ s.dstack.length := by omega
cases i with
| word w =>
by_cases hf : c.dBase + 4 * (s.dstack.length + 1) ≤ c.dEnd
rotate_left
· exact .inr ⟨nfD hf, sim_word_ovf (hnov hf) hg hs0 hpc w hLd hat hf⟩
obtain ⟨x', hst, h0, hpc'⟩ := sim_word_ok hg hs0 hpc w hLd hat hf
rw [exec_word]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| ptr q =>
by_cases hf : c.dBase + 4 * (s.dstack.length + 1) ≤ c.dEnd
rotate_left
· exact .inr ⟨nfD hf, sim_ptr_ovf (hnov hf) hg hs0 hpc q hLd hat hf⟩
obtain ⟨x', hst, h0, hpc'⟩ := sim_ptr_ok hg hs0 hpc q hLd hat hf
rw [exec_ptr]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| load =>
obtain ⟨a, d, hd⟩ := shape1 (by simpa [Instr.pops] using hk')
cases hm : s.mem.read? a with
| none =>
rw [exec_load_bad hd hm]
exact .inl <| sim_trapped (sim_load_trap hg hL hMs hs0 hpc hat hd hm)
| some v =>
obtain ⟨x', hst, h0, hpc'⟩ := sim_load_ok hg hL hMs hs0 hpc hat hd hm
rw [exec_load hd hm]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| store =>
obtain ⟨a, v, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
cases hm : s.mem.write? a v with
| none =>
rw [exec_store_bad hd hm]
exact .inl <| sim_trapped (sim_store_trap hg hL hMs hs0 hpc hat hd hm)
| some m =>
obtain ⟨x', hst, h0, hpc'⟩ := sim_store_ok hg hL hMs hs0 hpc hat hd hm
rw [exec_store hd hm]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| add =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_add_ok hg hL hs0 hpc hat hd
rw [exec_add hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| sub =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_sub_ok hg hL hs0 hpc hat hd
rw [exec_sub hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| mul =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_mul_ok hg hL hs0 hpc hat hd
rw [exec_mul hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| and =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_and_ok hg hL hs0 hpc hat hd
rw [exec_and hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| or =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_or_ok hg hL hs0 hpc hat hd
rw [exec_or hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| xor =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_xor_ok hg hL hs0 hpc hat hd
rw [exec_xor hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| shl =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_shl_ok hg hL hs0 hpc hat hd
rw [exec_shl hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| shr =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_shr_ok hg hL hs0 hpc hat hd
rw [exec_shr hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| rotl =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_rotl_ok hg hL hs0 hpc hat hd
rw [exec_rotl hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| rotr =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_rotr_ok hg hL hs0 hpc hat hd
rw [exec_rotr hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| cmp cd =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_cmp_ok cd hg hL hs0 hpc hat hd
rw [exec_cmp hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| div =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
by_cases hb : b = 0#32
· subst hb
rw [exec_div_zero hd]
exact .inl <| sim_trapped (sim_div_zero hg hL hs0 hpc hat hd)
· obtain ⟨x', hst, h0, hpc'⟩ := sim_div_ok hg hL hs0 hpc hat hd hb
rw [exec_div hd hb]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| sdiv =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
by_cases hb : b = 0#32
· subst hb
rw [exec_sdiv_zero hd]
exact .inl <| sim_trapped (sim_sdiv_zero hg hL hs0 hpc hat hd)
· obtain ⟨x', hst, h0, hpc'⟩ := sim_sdiv_ok hg hL hs0 hpc hat hd hb
rw [exec_sdiv hd hb]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| not =>
obtain ⟨a, d, hd⟩ := shape1 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_not_ok hg hL hs0 hpc hat hd
rw [exec_not hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| select =>
obtain ⟨cc, y, v, d, hd⟩ := shape3 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_select_ok hg hL hs0 hpc hat hd
rw [exec_select hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| jmp t =>
obtain ⟨x', hst, h0, hpc'⟩ := sim_jmp_ok hs0 hpc hat
exact .inl <| sim_next ⟨x', hst, h0.setPc _, hpc'⟩
| branch t =>
obtain ⟨a, d, hd⟩ := shape1 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_branch_ok hg hL hs0 hpc hat hd
by_cases hc : Word.isTrue a = true
· have e : WordDialect.exec (WordDialect.Instr.branch t) s = .next { s with pc := t, dstack := d } := by
simp [WordDialect.exec, hd, hc]
rw [e]
simp only [hc, if_true] at hpc'
exact .inl <| sim_next ⟨x', hst, h0.setPc _, hpc'⟩
· have hc' : Word.isTrue a = false := by simpa using hc
have e : WordDialect.exec (WordDialect.Instr.branch t) s = s.fall d := by simp [WordDialect.exec, hd, hc']
rw [e]
simp only [hc', Bool.false_eq_true, if_false] at hpc'
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| call t =>
have hret : offs c.facts p s.pc + isize (c.facts s.pc) (.call t : WordDialect.Instr 32) =
offs c.facts p (s.pc + 1) := by
rw [offs_succ c.facts hi]
by_cases hf : s.rstack.length + 2 ≤ c.rcap
rotate_left
· exact .inr ⟨nfR hf, sim_call_ovf hg hs0 hpc hLr hat hf⟩
obtain ⟨x', hst, h0, hpc'⟩ := sim_call_ok hg hs0 hpc hLr hat hret hf
exact .inl <| sim_next ⟨x', hst, h0.setPc _, hpc'⟩
| ret =>
cases hr : s.rstack with
| nil =>
have e : WordDialect.exec WordDialect.Instr.ret s = .trapped .returnUnderflow := by simp [WordDialect.exec, hr]
rw [e]
exact .inl <| sim_trapped (sim_ret_trap hs0 hpc hat hr)
| cons a rs =>
obtain ⟨x', hst, h0, hpc'⟩ := sim_ret_ok hg hs0 hpc hat hr (hsz a)
have e : WordDialect.exec WordDialect.Instr.ret s = .next { s with pc := a, rstack := rs } := by simp [WordDialect.exec, hr]
rw [e]
exact .inl <| sim_next ⟨x', hst, h0.setPc _, hpc'⟩
| push r =>
by_cases hf : c.dBase + 4 * (s.dstack.length + 1) ≤ c.dEnd
rotate_left
· exact .inr ⟨nfD hf, sim_push_ovf (hnov hf) hg hs0 hpc hLd hat hf⟩
obtain ⟨x', hst, h0, hpc'⟩ := sim_push_ok hg hs0 hpc (hreg r (Or.inl rfl)) hLd hat hf
rw [exec_push]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| pop r =>
obtain ⟨a, d, hd⟩ := shape1 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_pop_ok hg hL hs0 hpc (hreg r (Or.inr rfl)) hat hd
rw [exec_pop hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| dup =>
obtain ⟨a, d, hd⟩ := shape1 (by simpa [Instr.pops] using hk')
by_cases hf : c.dBase + 4 * (s.dstack.length + 1) ≤ c.dEnd
rotate_left
· exact .inr ⟨nfD hf, sim_dup_ovf (hnov hf) hg hL hs0 hpc hLd hat hd hf⟩
obtain ⟨x', hst, h0, hpc'⟩ := sim_dup_ok hg hL hs0 hpc hLd hat hd hf
rw [exec_dup hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| drop =>
obtain ⟨a, d, hd⟩ := shape1 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_drop_ok hg hL hs0 hpc hat hd
rw [exec_drop hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| swap =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_swap_ok hg hL hs0 hpc hat hd
rw [exec_swap hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| over =>
obtain ⟨b, a, d, hd⟩ := shape2 (by simpa [Instr.pops] using hk')
by_cases hf : c.dBase + 4 * (s.dstack.length + 1) ≤ c.dEnd
rotate_left
· exact .inr ⟨nfD hf, sim_over_ovf (hnov hf) hg hL hs0 hpc hLd hat hd hf⟩
obtain ⟨x', hst, h0, hpc'⟩ := sim_over_ok hg hL hs0 hpc hLd hat hd hf
rw [exec_over hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| rot =>
obtain ⟨cc, b, a, d, hd⟩ := shape3 (by simpa [Instr.pops] using hk')
obtain ⟨x', hst, h0, hpc'⟩ := sim_rot_ok hg hL hs0 hpc hat hd
rw [exec_rot hd]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| tor =>
obtain ⟨a, d, hd⟩ := shape1 (by simpa [Instr.pops] using hk')
by_cases hf : c.aBase + 4 * (s.astack.length + 1) ≤ c.aEnd
rotate_left
· exact .inr ⟨nfA hf, sim_tor_ovf hg hL hLal hs0 hpc hat (by simp [hd]) hf⟩
obtain ⟨x', hst, h0, hpc'⟩ := sim_tor_ok hg hL hLal hs0 hpc hat hd hf
have e : WordDialect.exec WordDialect.Instr.tor s =
.next { s with pc := s.pc + 1, dstack := d, astack := a :: s.astack } := by
simp [WordDialect.exec, hd]
rw [e]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| fromr =>
cases ha : s.astack with
| nil =>
have e : WordDialect.exec WordDialect.Instr.fromr s = .trapped .returnUnderflow := by
simp [WordDialect.exec, ha]
rw [e]
exact .inl <| sim_trapped (sim_fromr_trap hg hLa hs0 hpc hat ha)
| cons a as =>
by_cases hf : c.dBase + 4 * (s.dstack.length + 1) ≤ c.dEnd
rotate_left
· exact .inr ⟨nfD hf, sim_fromr_ovf (hnov hf) hg hLa hLd hs0 hpc hat (by simp [ha]) hf⟩
obtain ⟨x', hst, h0, hpc'⟩ := sim_fromr_ok hg hLa hLd hs0 hpc hat ha hf
have e : WordDialect.exec WordDialect.Instr.fromr s =
.next { s with pc := s.pc + 1, dstack := a :: s.dstack, astack := as } := by
simp [WordDialect.exec, ha]
rw [e]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| rfetch =>
cases ha : s.astack with
| nil =>
have e : WordDialect.exec WordDialect.Instr.rfetch s = .trapped .returnUnderflow := by
simp [WordDialect.exec, ha]
rw [e]
exact .inl <| sim_trapped (sim_rfetch_trap hg hLa hs0 hpc hat ha)
| cons a as =>
by_cases hf : c.dBase + 4 * (s.dstack.length + 1) ≤ c.dEnd
rotate_left
· exact .inr ⟨nfD hf, sim_rfetch_ovf (hnov hf) hg hLa hLd hs0 hpc hat (by simp [ha]) hf⟩
obtain ⟨x', hst, h0, hpc'⟩ := sim_rfetch_ok hg hLa hLd hs0 hpc hat ha hf
have e : WordDialect.exec WordDialect.Instr.rfetch s = s.fall (a :: s.dstack) := by
simp [WordDialect.exec, ha]
rw [e]
exact .inl <| sim_next ⟨x', hst, rel_fall hi h0 hpc'⟩
| halt =>
rw [exec_halt]
exact .inl <| sim_halted ⟨x, sim_halt hs0 hpc hat, hs0⟩
end Step
end RV32
end WordDialect
|