1121934Sharti(* ========================================================================= *)
2121934Sharti(* FILE          : coprocessorScript.sml                                     *)
3121934Sharti(* DESCRIPTION   : A collection of lemmas used to verify the coprocessor     *)
4121934Sharti(*                 instructions                                              *)
5121934Sharti(* AUTHOR        : (c) Anthony Fox, University of Cambridge                  *)
6121934Sharti(* DATE          : 2005                                                      *)
7121934Sharti(* ========================================================================= *)
8121934Sharti
9121934Sharti(* interactive use:
10121934Sharti  app load ["pred_setSimps", "wordsLib", "armLib",
11121934Sharti            "my_listTheory", "io_onestepTheory", "iclass_compLib",
12121934Sharti            "armTheory", "coreTheory", "lemmasTheory"];
13121934Sharti*)
14121934Sharti
15121934Shartiopen HolKernel boolLib bossLib;
16121934Shartiopen Q arithmeticTheory rich_listTheory wordsTheory;
17121934Shartiopen my_listTheory io_onestepTheory iclass_compLib armLib;
18121934Shartiopen armTheory coreTheory lemmasTheory;
19121934Sharti
20121934Shartival _ = new_theory "coprocessor";
21121934Sharti
22121934Sharti(* ------------------------------------------------------------------------- *)
23121934Sharti
24121934Shartiinfix \\ << >>
25121934Sharti
26121934Shartival op \\ = op THEN;
27121934Shartival op << = op THENL;
28121934Shartival op >> = op THEN1;
29131826Sharti
30121934Shartival Abbr = BasicProvers.Abbr;
31121934Shartifun Abbrev_wrap eqth =
32121934Sharti    EQ_MP (SYM (Thm.SPEC (concl eqth) markerTheory.Abbrev_def)) eqth;
33121934Sharti
34121934Shartival FST_COND_RAND = ISPEC `FST` COND_RAND;
35121934Shartival SND_COND_RAND = ISPEC `SND` COND_RAND;
36121934Sharti
37121934Shartival std_ss = bossLib.std_ss ++ boolSimps.LET_ss ++
38121934Sharti             rewrites [FST_COND_RAND,SND_COND_RAND];
39121934Sharti
40121934Shartival arith_ss = bossLib.arith_ss ++ boolSimps.LET_ss;
41121934Sharti
42121934Shartival SIZES_ss = wordsLib.SIZES_ss;
43121934Sharti
44121934Sharti(* ------------------------------------------------------------------------- *)
45121934Sharti
46121934Shartival BUSY_WAIT_LEM = prove(
47121934Sharti  `!t i. t < BUSY_WAIT (onfq,ooonfq,oniq,oooniq,cpsrf,cpsri,pipebabt) i /\
48121934Sharti        ~IS_RESET i t ==>
49121934Sharti     ?NFQ NIQ ABORT DATA. (i t = (T,ABORT,NFQ,NIQ,DATA,F,T)) /\ ~pipebabt /\
50121934Sharti         ((t = 0) ==> (PROJ_DATA (i 0) = DATA) /\
51121934Sharti              (cpsrf \/ ooonfq) /\
52121934Sharti              (cpsri \/ oooniq)) /\
53121934Sharti         ((t = 1) ==> (cpsrf \/ onfq) /\ (cpsri \/ oniq)) /\
54121934Sharti          (1 < t ==>  (cpsrf \/ PROJ_NFIQ (i (t - 2))) /\
55121934Sharti                      (cpsri \/ PROJ_NIRQ (i (t - 2))))`,
56121934Sharti  NTAC 2 STRIP_TAC
57121934Sharti    \\ REWRITE_TAC [BUSY_WAIT_def,BUSY_WAIT_DONE_def,CP_INTERRUPT_def]
58121934Sharti    \\ STRIP_TAC \\ IMP_RES_TAC whileTheory.LESS_LEAST \\ POP_ASSUM MP_TAC
59121934Sharti    \\ PAT_X_ASSUM `~IS_RESET i t` MP_TAC
60121934Sharti    \\ SIMP_TAC std_ss [IS_RESET_def,IS_BUSY_def,IS_ABSENT_def,IS_ABORT_def,
61121934Sharti         IS_IRQ_def,IS_FIQ_def]
62121934Sharti    \\ Cases_on `(t = 0)`
63121934Sharti    \\ Cases_on `(t = 1)`
64121934Sharti    \\ FULL_SIMP_TAC std_ss []
65121934Sharti    << [Cases_on_arm6inp `i 0`, Cases_on_arm6inp `i 1`,
66121934Sharti        Cases_on_arm6inp `i (t:num)`]
67121934Sharti    \\ ASM_SIMP_TAC arith_ss [PROJ_NRESET_def,PROJ_DATA_def,PROJ_CPB_def,
68121934Sharti         PROJ_CPA_def,PROJ_ABORT_def,PROJ_NFIQ_def,PROJ_NIRQ_def]);
69121934Sharti
70121934Shartival arm6state_inp = ``<|state := ARM6 (DP reg psr areg din alua alub dout)
71121934Sharti   (CTRL pipea pipeaval pipeb pipebval ireg iregval ointstart onewinst endinst
72121934Sharti      obaselatch opipebll nxtic nxtis nopc1 oorst resetlatch onfq ooonfq
73121934Sharti      oniq oooniq pipeaabt pipebabt iregabt2 dataabt2 aregn2 mrq2 nbw nrw
74121934Sharti      sctrlreg psrfb oareg mask orp oorp mul mul2 borrow2 mshift);
75121934Sharti    inp := (inp : num -> bool # bool # bool # bool # word32 # bool # bool)|>``;
76121934Sharti
77121934Shartival COPROC_BUSY_WAIT = store_thm("COPROC_BUSY_WAIT",
78121934Sharti  `!t x. Abbrev (x = (^arm6state_inp)) /\
79121934Sharti   DECODE_INST ireg IN {cdp_und; mrc; mcr; stc; ldc} /\
80121934Sharti   (aregn2 = 2w) /\
81121934Sharti   CONDITION_PASSED (NZCV (CPSR_READ psr)) ireg /\
82121934Sharti   Abbrev (i = (CPSR_READ psr) %% 7) /\
83121934Sharti   Abbrev (f = (CPSR_READ psr) %% 6) /\
84121934Sharti   Abbrev (b = BUSY_WAIT (onfq,ooonfq,oniq,oooniq,f,i,pipebabt) inp) /\
85121934Sharti   Abbrev (w = 1 + b) /\
86121934Sharti   Abbrev (x0 = SINIT INIT_ARM6 x) /\
87121934Sharti   (!t. t < w ==> ~IS_RESET inp t) ==> (t < w ==>
88121934Sharti   ?alua' alub' dout' obaselatch' nbw' nrw' psrfb' oareg' mask' orp' oorp'
89121934Sharti    mul' mul2' borrow2' mshift'.
90121934Sharti   ((FUNPOW (SNEXT NEXT_ARM6) t x0) = <| state := ARM6
91121934Sharti      (DP reg psr (REG_READ6 reg usr 15w) ireg alua' alub' dout')
92121934Sharti      (CTRL (if t = 0 then pipea else PROJ_DATA (inp 0)) T pipeb T ireg T
93121934Sharti         F (t = 0) (t = 0) obaselatch' (t = 0) (DECODE_INST ireg) t3
94121934Sharti         (~(t = 0) /\ DECODE_INST ireg IN {stc; ldc} /\ ~IS_BUSY inp (t - 1))
95121934Sharti         F F (if t = 0 then onfq else PROJ_NFIQ (inp (t - 1)))
96121934Sharti         (if t = 0 then ooonfq else
97121934Sharti            if t = 1 then onfq else PROJ_NFIQ (inp (t - 2)))
98121934Sharti         (if t = 0 then oniq else PROJ_NIRQ (inp (t - 1)))
99121934Sharti         (if t = 0 then oooniq else
100121934Sharti            if t = 1 then oniq else PROJ_NIRQ (inp (t - 2)))
101121934Sharti         (if t = 0 then pipeaabt else PROJ_ABORT (inp 0)) ((t = 0) /\ pipebabt)
102121934Sharti         (( t = 0) /\ iregabt2) ((t = 0) /\ dataabt2)
103121934Sharti         2w ((t = 0) /\ mrq2) nbw' nrw' sctrlreg psrfb' oareg'
104121934Sharti         mask' orp' oorp' mul' mul2' borrow2' mshift');
105121934Sharti       inp := ADVANCE t inp |>))`,
106121934Sharti  NTAC 3 STRIP_TAC \\ UNABBREV_TAC `b`
107121934Sharti    \\ ASM_SIMP_TAC (std_ss++STATE_INP_ss) [Abbr`x`,Abbr`x0`,Abbr`w`,
108121934Sharti         IS_BUSY_def,SINIT_def,INIT_ARM6_def,num2exception_exception2num,
109121934Sharti         IC_def,ABORTINST_def,NXTIC_def,DECODE_PSR_def]
110121934Sharti    \\ STRIP_TAC \\ Induct_on `t`
111121934Sharti    >> RW_TAC std_ss [FUNPOW,ADVANCE_ZERO]
112121934Sharti    \\ STRIP_TAC
113121934Sharti    \\ POP_ASSUM (fn th =>
114121934Sharti         `t < 1 + BUSY_WAIT (onfq,ooonfq,oniq,oooniq,f,i,pipebabt) inp /\
115121934Sharti          t < BUSY_WAIT (onfq,ooonfq,oniq,oooniq,f,i,pipebabt) inp`
116121934Sharti      by SIMP_TAC arith_ss [th])
117121934Sharti    \\ PAT_X_ASSUM `!x. a ==> b` IMP_RES_TAC
118121934Sharti    \\ PAT_X_ASSUM `a ==> b` IMP_RES_TAC
119121934Sharti    \\ SIMP_TAC arith_ss []
120121934Sharti    \\ ASM_SIMP_TAC (std_ss++STATE_INP_ss) [FUNPOW_SUC]
121121934Sharti    \\ POP_ASSUM (K ALL_TAC)
122121934Sharti    \\ ASM_SIMP_TAC (arith_ss++STATE_INP_ss)
123121934Sharti         [SNEXT_def,ADD1,GSYM io_onestepTheory.ADVANCE_COMP,ADVANCE_def]
124121934Sharti    \\ IMP_RES_TAC BUSY_WAIT_LEM \\ NTAC 2 (POP_ASSUM (K ALL_TAC))
125121934Sharti    \\ FULL_SIMP_TAC (std_ss++pred_setSimps.PRED_SET_ss++ICLASS_ss) []
126121934Sharti    \\ ASM_SIMP_TAC (std_ss++CDP_UND_ss++MRC_ss++MCR_ss++LDC_ss++STC_ss) []
127121934Sharti    \\ ASM_SIMP_TAC (std_ss++boolSimps.CONJ_ss++PBETA_ss)
128121934Sharti         [PROJ_NFIQ_def,PROJ_NIRQ_def,PROJ_CPB_def]
129121934Sharti    \\ Cases_on `t = 0` >> RW_TAC arith_ss [AREGN1_def,PROJ_ABORT_def]
130121934Sharti    \\ Cases_on `t = 1` \\ FULL_SIMP_TAC arith_ss
131121934Sharti         [AREGN1_def,PROJ_ABORT_def,state_arm6_11,dp_11,ctrl_11]);
132121934Sharti
133121934Shartilocal
134121934Sharti  val nc = armLib.tupleCases
135121934Sharti       ``(onfq,ooonfq,oniq,oooniq,cpsrf,cpsri,pipebabt) :
136121934Sharti          bool # bool # bool # bool # bool # bool # bool``
137121934Shartiin
138121934Sharti  fun Cases_on_x tm = FULL_STRUCT_CASES_TAC (SPEC tm nc)
139121934Shartiend;
140121934Sharti
141121934Shartival EXISTS_BUSY_WAIT = prove(
142121934Sharti  `!x i. i IN STRM_ARM6 ==> ?t. BUSY_WAIT_DONE x i t`,
143121934Sharti  STRIP_TAC \\ Cases_on_x `x`
144121934Sharti    \\ RW_TAC std_ss [IN_DEF,STRM_ARM6_def,BUSY_WAIT_DONE_def,CP_INTERRUPT_def]
145121934Sharti    \\ METIS_TAC []);
146121934Sharti
147121934Shartival LEAST_BETA = prove(`!n P. (LEAST n. P n) = $LEAST P`,
148121934Sharti  METIS_TAC [whileTheory.LEAST_DEF]);
149121934Sharti
150121934Shartival EXISTS_BUSY_WAIT_IMP_BUSY_WAIT_DONE = save_thm
151121934Sharti  ("EXISTS_BUSY_WAIT_IMP_BUSY_WAIT_DONE",
152121934Sharti   (SIMP_RULE std_ss [GSYM BUSY_WAIT_def,EXISTS_BUSY_WAIT,
153121934Sharti      (GSYM o SPECL [`n`,`BUSY_WAIT_DONE x i`]) LEAST_BETA] o
154121934Sharti    DISCH `i IN STRM_ARM6` o DISCH `Abbrev (t = $LEAST (BUSY_WAIT_DONE x i))` o
155121934Sharti    SIMP_RULE std_ss [DECIDE ``a /\ b ==> b``] o
156121934Sharti    SPECL [`BUSY_WAIT_DONE x i`,`BUSY_WAIT_DONE x i`]) whileTheory.LEAST_ELIM);
157121934Sharti
158121934Shartival BUSY_WAIT_COR = prove(
159121934Sharti  `!i t. i IN STRM_ARM6 /\
160121934Sharti     BUSY_WAIT_DONE (onfq,ooonfq,oniq,oooniq,cpsrf,cpsri,pipebabt) i t /\
161121934Sharti     ~IS_RESET i t ==>
162121934Sharti  ?ABORT NFQ NIQ DATA CPA CPB. (i t = (T,ABORT,NFQ,NIQ,DATA,CPA,CPB)) /\
163121934Sharti   ((CPA ==> CPB) /\
164121934Sharti    (CPB ==> CP_INTERRUPT (onfq,ooonfq,oniq,oooniq,cpsrf,cpsri,pipebabt) i t))`,
165121934Sharti  NTAC 2 STRIP_TAC
166121934Sharti    \\ SIMP_TAC std_ss [STRM_ARM6_def,BUSY_WAIT_DONE_def,IN_DEF,IS_RESET_def,
167121934Sharti         IS_ABSENT_def,IS_BUSY_def,IS_ABORT_def]
168121934Sharti    \\ STRIP_TAC \\ PAT_X_ASSUM `!t. PROJ_CPA (i t) ==> PROJ_CPB (i t)`
169121934Sharti         (SPEC_THEN `t` ASSUME_TAC)
170121934Sharti    \\ Cases_on `t = 0` \\ FULL_SIMP_TAC std_ss []
171121934Sharti    << [Cases_on_arm6inp `i 0`,  Cases_on_arm6inp `i (t:num)`]
172121934Sharti    \\ FULL_SIMP_TAC arith_ss [PROJ_NRESET_def,PROJ_DATA_def,PROJ_CPB_def,
173121934Sharti         PROJ_CPA_def,PROJ_ABORT_def]);
174121934Sharti
175121934Shartival EXISTS_AREGN = SIMP_RULE (std_ss++pred_setSimps.PRED_SET_ss) []
176121934Sharti  (prove(`?aregn:word3. ~(aregn IN {0w; 2w; 5w; 6w; 7w})`,
177121934Sharti    EXISTS_TAC `1w`
178121934Sharti      \\ SIMP_TAC (std_ss++pred_setSimps.PRED_SET_ss++SIZES_ss) [n2w_11]));
179121934Sharti
180121934Shartival FINISH_OFF3 =
181121934Sharti   Cases_on `CPB` \\ ASM_SIMP_TAC (std_ss++boolSimps.CONJ_ss) []
182121934Sharti     \\ RW_TAC (std_ss++SIZES_ss) [Abbr`ointstart'`,n2w_11]
183121934Sharti     \\ NTAC 2 (FULL_SIMP_TAC std_ss []) \\ POP_ASSUM_LIST (K ALL_TAC)
184121934Sharti     \\ PROVE_TAC [EXISTS_AREGN];
185121934Sharti
186121934Shartival COPROC_BUSY_WAIT2 = prove(
187121934Sharti  `!t x. Abbrev (x = (^arm6state_inp)) /\ inp IN STRM_ARM6 /\
188121934Sharti   DECODE_INST ireg IN {cdp_und; mrc; mcr; stc; ldc} /\
189121934Sharti   (aregn2 = 2w) /\
190121934Sharti   CONDITION_PASSED (NZCV (CPSR_READ psr)) ireg /\
191121934Sharti   Abbrev (i = (CPSR_READ psr) %% 7) /\
192121934Sharti   Abbrev (f = (CPSR_READ psr) %% 6) /\
193121934Sharti   Abbrev (nbs = DECODE_MODE ((4 >< 0) (CPSR_READ psr))) /\
194121934Sharti   Abbrev (b = BUSY_WAIT (onfq,ooonfq,oniq,oooniq,f,i,pipebabt) inp) /\
195121934Sharti   Abbrev (w = 1 + b) /\
196121934Sharti   Abbrev (x0 = SINIT INIT_ARM6 x) /\
197121934Sharti   (!t. t < w ==> ~IS_RESET inp t) ==>
198121934Sharti   ?alua' alub' dout' newinst obaselatch' pipeaabt' pipebabt' iregabt' dataabt'
199121934Sharti    aregn' mrq' nbw' nrw' psrfb' oareg' mask' orp' oorp'  mul' mul2' borrow2'
200121934Sharti    mshift'.
201121934Sharti    ~(aregn' IN {0w; 2w; 5w}) /\
202121934Sharti    ((aregn' = 7w) ==> ~f) /\ ((aregn' = 6w) ==> ~i) /\
203121934Sharti   (let ic = DECODE_INST ireg
204121934Sharti    and CPB = PROJ_CPB (inp b)
205121934Sharti    and ointstart' = CP_INTERRUPT (onfq,ooonfq,oniq,oooniq,f,i,pipebabt) inp b
206121934Sharti    in
207121934Sharti    let Rn = (19 >< 16) ireg
208121934Sharti    and offset = ((7 -- 0) ireg) << 2
209121934Sharti    and newinst = (ic = cdp_und) \/ CPB /\ ointstart' in
210121934Sharti    let nxtic = if newinst then
211121934Sharti         if ointstart' then swi_ex else DECODE_INST pipeb else ic in
212121934Sharti      FUNPOW (SNEXT NEXT_ARM6) w x0  =
213121934Sharti       <| state := ARM6 (DP (if CPB then reg else INC_PC reg) psr
214121934Sharti                (if CPB then REG_READ6 reg usr 15w
215121934Sharti                 else if ic IN {stc; ldc} then
216121934Sharti                   (if ~(ireg %% 24) then $K else if ireg %% 23 then $+ else $-)
217121934Sharti                      (REG_READ6 reg nbs Rn) offset
218121934Sharti                 else REG_READ6 reg usr 15w + 4w)
219121934Sharti                (if newinst then pipeb else ireg)
220121934Sharti                (if ic IN {stc; ldc} then REG_READ6 reg nbs Rn else alua')
221121934Sharti                (if ic IN {stc; ldc} then offset else alub') dout')
222121934Sharti           (CTRL (PROJ_DATA (inp 0)) T
223121934Sharti             (if newinst then PROJ_DATA (inp 0) else pipeb) T
224121934Sharti             (if newinst then pipeb else ireg) T
225121934Sharti             ointstart' newinst newinst obaselatch' newinst nxtic
226121934Sharti             (if newinst then t3 else
227121934Sharti                if (ic = mrc) \/ (ic = mcr) then t4 else tn)
228121934Sharti             (ic IN {stc; ldc} /\ ~CPB) F F (PROJ_NFIQ (inp b))
229121934Sharti             (if w = 1 then onfq else PROJ_NFIQ (inp (b - 1)))
230121934Sharti             (PROJ_NIRQ (inp b))
231121934Sharti             (if w = 1 then oniq else PROJ_NIRQ (inp (b - 1)))
232121934Sharti             pipeaabt' (if newinst then pipebabt' else pipebabt)
233121934Sharti             (if newinst then iregabt' else pipebabt) (newinst /\ dataabt')
234121934Sharti             (if ointstart' then aregn' else 2w) mrq' nbw' (~newinst /\ nrw')
235121934Sharti             sctrlreg psrfb' oareg'
236121934Sharti             (if newinst then MASK nxtic t3 mask' ARB else mask')
237121934Sharti             orp' oorp' mul' mul2' borrow2' mshift'); inp := ADVANCE w inp |>)`,
238121934Sharti  REPEAT STRIP_TAC
239121934Sharti    \\ RULE_ASSUM_TAC (SIMP_RULE std_ss [DECODE_PSR_def])
240121934Sharti    \\ `?t. t < w /\ (w = SUC t)` by SIMP_TAC arith_ss [Abbr`w`,ADD1]
241121934Sharti    \\ `b = t` by (UNABBREV_TAC `w` \\ DECIDE_TAC)
242121934Sharti    \\ POP_ASSUM SUBST_ALL_TAC \\ POP_ASSUM SUBST1_TAC
243121934Sharti    \\ RES_MP_TAC [`b:num` |-> `t:num`] COPROC_BUSY_WAIT
244121934Sharti    \\ POP_ASSUM IMP_RES_TAC
245121934Sharti    \\ ASM_SIMP_TAC (arith_ss++STATE_INP_ss) [FUNPOW_SUC]
246121934Sharti    \\ POP_ASSUM (K ALL_TAC)
247121934Sharti    \\ markerLib.RM_ABBREV_TAC "w"
248121934Sharti    \\ ABBREV_TAC `ointstart' =
249121934Sharti         CP_INTERRUPT (onfq,ooonfq,oniq,oooniq,f,i,pipebabt) inp t`
250121934Sharti    \\ IMP_RES_TAC EXISTS_BUSY_WAIT_IMP_BUSY_WAIT_DONE
251121934Sharti    \\ RES_TAC \\ IMP_RES_TAC BUSY_WAIT_COR \\ NTAC 9 (POP_ASSUM (K ALL_TAC ))
252121934Sharti    \\ `CPB ==> ointstart'` by ASM_SIMP_TAC std_ss [Abbr `ointstart'`]
253121934Sharti    \\ `(PROJ_CPB (inp t) = CPB) /\ (PROJ_CPA (inp t) = CPA)`
254121934Sharti    by ASM_SIMP_TAC std_ss [PROJ_CPB_def,PROJ_CPA_def]
255121934Sharti    \\ `~(t = 0) ==> ~pipebabt`
256121934Sharti    by (STRIP_TAC \\
257121934Sharti        `0 < BUSY_WAIT (onfq,ooonfq,oniq,oooniq,f,i,pipebabt) inp /\
258121934Sharti         ~IS_RESET inp 0` by ASM_SIMP_TAC arith_ss [] \\
259121934Sharti        METIS_TAC [BUSY_WAIT_LEM])
260121934Sharti    \\ `(t = 0) ==> (DATA = PROJ_DATA (inp 0))`
261121934Sharti    by (STRIP_TAC \\ FULL_SIMP_TAC std_ss [PROJ_DATA_def])
262121934Sharti    \\ ASM_SIMP_TAC (arith_ss++STATE_INP_ss) [SNEXT_def,ADD1,
263121934Sharti         GSYM io_onestepTheory.ADVANCE_COMP,ADVANCE_def,PROJ_CPB_def,
264121934Sharti         PROJ_NFIQ_def,PROJ_NIRQ_def]
265121934Sharti    \\ FULL_SIMP_TAC (std_ss++pred_setSimps.PRED_SET_ss++ICLASS_ss)
266121934Sharti         [PROJ_NRESET_def,IS_FIQ_def,IS_IRQ_def]
267121934Sharti    \\ ASM_SIMP_TAC (std_ss++CDP_UND_ss++MRC_ss++MCR_ss++LDC_ss++STC_ss) []
268121934Sharti    \\ ASM_SIMP_TAC (std_ss++boolSimps.CONJ_ss++PBETA_ss) []
269121934Sharti    \\ PAT_ABBREV_TAC `ointstart2 = CPA \/ q`
270121934Sharti    \\ `ointstart2 = ointstart'`
271121934Sharti    by (ASM_SIMP_TAC std_ss [Abbr `ointstart2`,Abbr `ointstart'`,
272121934Sharti          CP_INTERRUPT_def,IS_FIQ_def,IS_IRQ_def,IS_ABSENT_def,PROJ_CPA_def]
273121934Sharti            \\ Cases_on `t = 0` >> (FULL_SIMP_TAC std_ss [] \\
274121934Sharti                 POP_ASSUM_LIST (K ALL_TAC) \\ PROVE_TAC [])
275121934Sharti            \\ Cases_on `t = 1` \\ FULL_SIMP_TAC arith_ss [])
276121934Sharti    \\ POP_ASSUM SUBST1_TAC \\ POP_ASSUM (K ALL_TAC)
277121934Sharti    \\ ASM_SIMP_TAC (std_ss++boolSimps.CONJ_ss) [IF_NEG,TO_WRITE_READ6]
278121934Sharti    \\ FULL_SIMP_TAC (std_ss++ALU_ss) [state_arm6_11,ctrl_11,dp_11,LSL_ZERO,
279121934Sharti         LSL_TWO,ALUOUT_ALU_logic,ALUOUT_ADD,ALUOUT_SUB,AREGN1_def]
280121934Sharti    \\ (Cases_on `CPA` \\ FULL_SIMP_TAC std_ss
281121934Sharti         [CP_INTERRUPT_def,IS_ABSENT_def,IS_FIQ_def,IS_IRQ_def]
282121934Sharti    >> (SIMP_TAC (std_ss++boolSimps.LIFT_COND_ss++SIZES_ss) [n2w_11] \\
283121934Sharti          POP_ASSUM_LIST (K ALL_TAC) \\ METIS_TAC [])
284121934Sharti    \\ Cases_on `t = 0` >> FINISH_OFF3
285121934Sharti    \\ Cases_on `t = 1` \\ FINISH_OFF3));
286121934Sharti
287121934Shartival COPROC_BUSY_WAIT2 = save_thm("COPROC_BUSY_WAIT2",
288121934Sharti  (PairRules.PBETA_RULE o REWRITE_RULE [LET_THM]) COPROC_BUSY_WAIT2);
289121934Sharti
290121934Sharti(* ------------------------------------------------------------------------- *)
291121934Sharti
292121934Shartival lem = prove(
293121934Sharti  `!P b:num c. (!a. a < b ==> P a) /\ c <= b ==> (!a. a < c ==> P a)`,
294121934Sharti  RW_TAC arith_ss []);
295121934Sharti
296121934Shartival lem2 = prove(
297121934Sharti  `!ic. ic IN {stc; ldc} ==>
298121934Sharti         (ic IN {cdp_und; mrc; mcr; stc; ldc} /\
299121934Sharti          ~(ic = cdp_und) /\ ~(ic = mrc) /\ ~(ic = mcr))`,
300121934Sharti  RW_TAC (std_ss++pred_setSimps.PRED_SET_ss) []);
301121934Sharti
302121934Shartival BUSY_EXISTS = store_thm("BUSY_EXISTS",
303121934Sharti  `!inp b. inp IN STRM_ARM6 /\
304121934Sharti       Abbrev (b = BUSY_WAIT (onfq,ooonfq,oniq,oooniq,f,i,pipebabt) inp) /\
305121934Sharti       ~IS_BUSY inp b ==> ?n. IS_BUSY (ADVANCE b inp) n`,
306121934Sharti  RW_TAC arith_ss [IN_DEF,STRM_ARM6_def,ADVANCE_def,IS_BUSY_def]
307121934Sharti    \\ METIS_TAC [ADD_COMM,LESS_ADD]);
308121934Sharti
309121934Shartival BUSY_EXISTS_COR =
310121934Sharti  let val x = (SIMP_RULE std_ss [] o
311121934Sharti     DISCH `inp IN STRM_ARM6 /\
312121934Sharti       Abbrev (b = BUSY_WAIT (onfq,ooonfq,oniq,oooniq,f,i,pipebabt) inp) /\
313121934Sharti       ~IS_BUSY inp b` o
314121934Sharti     SPEC `\n. IS_BUSY (ADVANCE b inp) n`) whileTheory.LEAST_EXISTS
315121934Sharti  in
316121934Sharti    (GEN_ALL o SIMP_RULE std_ss [IS_BUSY_def,ADVANCE_def])
317121934Sharti      (MATCH_MP (METIS_PROVE [] ``(a ==> b) /\ (a ==> (b = c)) ==> (a ==> c)``)
318121934Sharti                (CONJ (SPECL [`inp`,`b`] BUSY_EXISTS) x))
319121934Sharti  end;
320121934Sharti
321121934Shartival CP_TRANSFER_LEM = prove(
322121934Sharti  `!p w' w b inp.
323121934Sharti         inp IN STRM_ARM6 /\
324121934Sharti         Abbrev (b = BUSY_WAIT (onfq,ooonfq,oniq,oooniq,f,i,pipebabt) inp) /\
325121934Sharti         ~PROJ_CPB (inp b) /\
326121934Sharti         Abbrev (w = w' + (LEAST n. IS_BUSY (ADVANCE b inp) n)) /\
327121934Sharti         Abbrev (w' = 1 + b) /\
328121934Sharti         (SUC p + w' <= w) /\ (!t. t < w ==> ~IS_RESET inp t) ==>
329121934Sharti     ?ABORT NFQ NIQ DATA CPA.
330121934Sharti        (inp (p + w') =
331121934Sharti           (T,ABORT,NFQ,NIQ,DATA,CPA /\ (SUC p + w' = w),SUC p + w' = w))`,
332121934Sharti  REPEAT STRIP_TAC \\ MAP_EVERY UNABBREV_TAC [`w`,`w'`]
333121934Sharti    \\ FULL_SIMP_TAC arith_ss []
334121934Sharti    \\ `b + (p + 1) < b + ((LEAST n. IS_BUSY (ADVANCE b inp) n) + 1)`
335121934Sharti    by DECIDE_TAC
336121934Sharti    \\ RES_TAC
337121934Sharti    \\ FULL_SIMP_TAC arith_ss [IS_RESET_def,IS_BUSY_def,ADVANCE_def]
338121934Sharti    \\ `PROJ_CPB (inp (b + LEAST n. PROJ_CPB (inp (b + n)))) /\
339121934Sharti        !n.  n < (LEAST n. PROJ_CPB (inp (b + n))) ==> ~PROJ_CPB (inp (b + n))`
340121934Sharti    by (NTAC 4 (POP_ASSUM (K ALL_TAC)) \\ IMP_RES_TAC BUSY_EXISTS_COR \\
341121934Sharti          ASM_SIMP_TAC std_ss [])
342121934Sharti    \\ ABBREV_TAC `l = LEAST n. PROJ_CPB (inp (b + n))`
343121934Sharti    \\ Cases_on `p + 1 < l`
344121934Sharti    << [
345121934Sharti      RES_TAC \\ `~PROJ_CPA (inp (b + (p + 1)))`
346121934Sharti         by (FULL_SIMP_TAC std_ss [IN_DEF,STRM_ARM6_def,
347121934Sharti               IS_ABSENT_def,IS_BUSY_def] \\ METIS_TAC []),
348121934Sharti        `p + 1 = l` by DECIDE_TAC \\ POP_ASSUM (SUBST_ALL_TAC o SYM)]
349121934Sharti    \\ Cases_on_arm6inp `inp (b + (p + 1))`
350121934Sharti    \\ FULL_SIMP_TAC arith_ss [PROJ_NRESET_def,PROJ_CPB_def,PROJ_CPA_def]);
351121934Sharti
352121934Shartival CP_TRANSFER_LEM0 = (SIMP_RULE arith_ss [] o SPEC `0`) CP_TRANSFER_LEM;
353121934Sharti
354121934Shartival finish_rws =
355121934Sharti  [REG_WRITE_WRITE,REG_WRITE_WRITE_PC,REG_READ_WRITE,ADD4_ADD4,
356121934Sharti   GSYM WORD_ADD_SUB_SYM,WORD_ADD_SUB,REWRITE_RULE [word_0] WORD_ADD_0];
357121934Sharti
358121934Shartival FINISH_OFF3 = let val
359121934Sharti  rw_tac = RW_TAC arith_ss ([Abbr`wb_addr`,Abbr`Rn`,GSYM WORD_ADD_SUB_ASSOC,
360121934Sharti             AC WORD_ADD_ASSOC WORD_ADD_COMM] @ finish_rws)
361121934Sharti in
362121934Sharti   REPEAT CONJ_TAC << [
363121934Sharti     rw_tac, rw_tac,
364121934Sharti     RW_TAC arith_ss [] \\ POP_ASSUM_LIST (K ALL_TAC) \\ PROVE_TAC [],
365121934Sharti     RW_TAC (arith_ss++SIZES_ss) [AREGN1_def,n2w_11]
366121934Sharti       \\ FULL_SIMP_TAC (std_ss++SIZES_ss) [n2w_11]
367121934Sharti       \\ POP_ASSUM_LIST (K ALL_TAC) \\ METIS_TAC [EXISTS_AREGN],
368121934Sharti     POP_ASSUM_LIST (K ALL_TAC) \\ METIS_TAC []]
369121934Sharti end;
370121934Sharti
371121934Shartival LDC_STC_THM = store_thm("LDC_STC_THM",
372121934Sharti  `!t x. Abbrev (x = (^arm6state_inp)) /\ inp IN STRM_ARM6 /\
373121934Sharti   DECODE_INST ireg IN {stc; ldc} /\
374121934Sharti   (aregn2 = 2w) /\
375121934Sharti   CONDITION_PASSED (NZCV (CPSR_READ psr)) ireg /\
376121934Sharti   Abbrev (i = (CPSR_READ psr) %% 7) /\
377121934Sharti   Abbrev (f = (CPSR_READ psr) %% 6) /\
378121934Sharti   Abbrev (nbs = DECODE_MODE ((4 >< 0) (CPSR_READ psr))) /\
379121934Sharti   Abbrev (b = BUSY_WAIT (onfq,ooonfq,oniq,oooniq,f,i,pipebabt) inp) /\
380121934Sharti   Abbrev (w = 1 + b + (LEAST n. IS_BUSY (ADVANCE b inp) n)) /\
381121934Sharti   Abbrev (x0 = SINIT INIT_ARM6 x) /\
382121934Sharti   (!t. t < w ==> ~IS_RESET inp t) /\
383121934Sharti   ~IS_BUSY inp b ==>
384121934Sharti   let CPB = PROJ_CPB (inp (w - 1)) in
385121934Sharti   let Rn = (19 >< 16) ireg
386121934Sharti   and offset = (7 -- 0) ireg << 2 in
387121934Sharti   let wb_addr = (if ireg %% 23 then $+ else $-) (REG_READ6 reg nbs Rn) offset
388121934Sharti   in
389121934Sharti     (1 + b < t /\ t <= w ==>
390121934Sharti        ?alua' alub' dout' newinst ointstart' obaselatch' onfq' ooonfq'
391121934Sharti         oniq' oooniq' pipeaabt' pipebabt' iregabt' dataabt' aregn' mrq' nbw'
392121934Sharti         nrw' psrfb' oareg' mask' orp' oorp'  mul' mul2' borrow2' mshift'.
393121934Sharti      ~(aregn' IN {0w; 2w; 5w}) /\
394121934Sharti      ((aregn' = 7w) ==> ~f) /\ ((aregn' = 6w) ==> ~i) /\
395121934Sharti      (let nxtic1 = if ointstart' then swi_ex else DECODE_INST pipeb in
396121934Sharti       FUNPOW (SNEXT NEXT_ARM6) t x0 =
397121934Sharti       <| state := ARM6
398121934Sharti         (DP (if ireg %% 21 /\ ~(Rn = 15w) then
399121934Sharti                REG_WRITE (INC_PC reg) nbs Rn wb_addr
400121934Sharti              else INC_PC reg) psr
401121934Sharti            (if t = w then REG_READ6 (INC_PC reg) nbs 15w else
402121934Sharti               (if ~(ireg %% 24) then $K else if ireg %% 23 then $+ else $-)
403121934Sharti                  (REG_READ6 reg nbs Rn + n2w (4 * (t - (b + 1)))) offset)
404121934Sharti            (if t = w then pipeb else ireg) (REG_READ6 reg nbs Rn) offset dout')
405121934Sharti         (CTRL (PROJ_DATA (inp 0)) T
406121934Sharti            (if t = w then PROJ_DATA (inp 0) else pipeb) T
407121934Sharti            (if t = w then pipeb else ireg) T ointstart' (t = w) (t = w)
408121934Sharti            obaselatch' (t = w) (if (t = w) then nxtic1 else DECODE_INST ireg)
409121934Sharti            (if (t = w) then t3 else tn) (~(t = w)) F F onfq' ooonfq'
410121934Sharti            oniq' oooniq' pipeaabt' pipebabt'
411121934Sharti            (if t = w then iregabt' else pipebabt') dataabt'
412121934Sharti            (if ointstart' then aregn' else 2w)
413121934Sharti            mrq' nbw' (~(t = w) /\ (DECODE_INST ireg = stc)) sctrlreg psrfb'
414121934Sharti            oareg' (if t = w then MASK nxtic1 t3 mask' ARB else mask')
415121934Sharti            orp' oorp' mul' mul2' borrow2' mshift'); inp := ADVANCE t inp |>))`,
416121934Sharti  REWRITE_TAC [DECODE_PSR_def] \\ REPEAT STRIP_TAC
417121934Sharti    \\ BasicProvers.LET_ELIM_TAC \\ SIMP_TAC std_ss [markerTheory.Abbrev_def]
418121934Sharti    \\ IMP_RES_TAC LESS_ADD
419121934Sharti    \\ `?w'. w' = 1 + b` by METIS_TAC []
420121934Sharti    \\ `w' <= w` by DECIDE_TAC
421121934Sharti    \\ `!t. t < w' ==> ~IS_RESET inp t`
422121934Sharti    by METIS_TAC [(BETA_RULE o SPEC `\t. ~IS_RESET inp t`) lem]
423121934Sharti    \\ `~PROJ_CPB (inp (w' - 1))`
424121934Sharti    by METIS_TAC [IS_BUSY_def,DECIDE ``!x. 1 + x - 1 = x``]
425121934Sharti    \\ `Abbrev (w' = 1 + b)`
426121934Sharti    by ASM_SIMP_TAC std_ss [Abbr`w`,markerTheory.Abbrev_def]
427121934Sharti    \\ IMP_RES_TAC lem2
428121934Sharti    \\ RES_MP_TAC [`w:num` |-> `w':num`] COPROC_BUSY_WAIT2
429121934Sharti    \\ PAT_X_ASSUM `p + (1 + d) = t` (SUBST_ALL_TAC o SYM)
430121934Sharti    \\ ONCE_REWRITE_TAC [onestepTheory.FUNPOW_COMP]
431121934Sharti    \\ markerLib.RM_ABBREV_TAC "w'"
432121934Sharti    \\ PAT_X_ASSUM `w' = 1 + d`
433121934Sharti         (fn th => (SUBST_ALL_TAC o SYM) th \\ (ASSUME_TAC o Abbrev_wrap) th)
434121934Sharti    \\ PAT_X_ASSUM `FUNPOW (SNEXT NEXT_ARM6) w' _ = _` SUBST1_TAC
435121934Sharti    \\ ASM_SIMP_TAC std_ss []
436121934Sharti    \\ Induct_on `p` >> FULL_SIMP_TAC arith_ss []
437121934Sharti    \\ REPEAT STRIP_TAC
438121934Sharti    \\ Cases_on `p = 0`
439121934Sharti    << [
440121934Sharti      FULL_SIMP_TAC (arith_ss++STATE_INP_ss) [numeralTheory.numeral_funpow,
441121934Sharti             SNEXT_def,GSYM io_onestepTheory.ADVANCE_COMP,ADVANCE_def]
442121934Sharti        \\ `(w' - 1 = b)` by ASM_SIMP_TAC arith_ss [Abbr`w'`]
443121934Sharti        \\ POP_ASSUM SUBST_ALL_TAC
444121934Sharti        \\ `0 < (LEAST n. PROJ_CPB (inp (b + n)))`
445121934Sharti        by FULL_SIMP_TAC arith_ss [Abbr`w`,IS_BUSY_def,ADVANCE_def]
446121934Sharti        \\ IMP_RES_TAC BUSY_EXISTS_COR \\ NTAC 3 (POP_ASSUM (K ALL_TAC))
447121934Sharti        \\ RES_MP_TAC [] CP_TRANSFER_LEM0
448121934Sharti        \\ FULL_SIMP_TAC (std_ss++pred_setSimps.PRED_SET_ss++ICLASS_ss) []
449121934Sharti        \\ ASM_SIMP_TAC (std_ss++LDC_ss++STC_ss) []
450121934Sharti        \\ ASM_SIMP_TAC (std_ss++boolSimps.CONJ_ss++PBETA_ss++ALU_ss)
451121934Sharti             [IF_NEG,TO_WRITE_READ6,LSL_ZERO,LSL_TWO,ALUOUT_ALU_logic,
452121934Sharti              ALUOUT_ADD,ALUOUT_SUB,METIS_PROVE [] ``a /\ b \/ a = a``]
453121934Sharti        \\ FULL_SIMP_TAC arith_ss [state_arm6_11,dp_11,ctrl_11,iseq_distinct]
454121934Sharti        \\ CONV_TAC (DEPTH_CONV EXISTS_AND_REORDER_CONV)
455121934Sharti        \\ FINISH_OFF3,
456121934Sharti      `w' < p + w' /\ p + w' <= w` by DECIDE_TAC
457121934Sharti        \\ PAT_X_ASSUM `q ==> r ==> s` IMP_RES_TAC
458121934Sharti        \\ ASM_SIMP_TAC (std_ss++STATE_INP_ss) [FUNPOW_SUC]
459121934Sharti        \\ POP_ASSUM (K ALL_TAC)
460121934Sharti        \\ ASM_SIMP_TAC (arith_ss++STATE_INP_ss)
461121934Sharti             [SNEXT_def,ADD1,GSYM io_onestepTheory.ADVANCE_COMP,ADVANCE_def]
462121934Sharti        \\ (RES_MP1_TAC [] CP_TRANSFER_LEM >> METIS_TAC [IS_BUSY_def])
463121934Sharti        \\ `(p + w' - b = p + 1) /\ (p + w' - (b + 1) = p)`
464121934Sharti        by ASM_SIMP_TAC arith_ss [Abbr`w'`]
465121934Sharti        \\ FULL_SIMP_TAC (std_ss++pred_setSimps.PRED_SET_ss++ICLASS_ss) []
466121934Sharti        \\ ASM_SIMP_TAC (std_ss++LDC_ss++STC_ss) []
467121934Sharti        \\ ASM_SIMP_TAC (std_ss++boolSimps.CONJ_ss++PBETA_ss++ALU_ss)
468121934Sharti             [IF_NEG,TO_WRITE_READ6,LSL_ZERO,LSL_TWO,ALUOUT_ALU_logic,
469121934Sharti              ALUOUT_ADD,ALUOUT_SUB,METIS_PROVE [] ``a /\ b \/ a = a``]
470121934Sharti        \\ FULL_SIMP_TAC arith_ss [state_arm6_11,dp_11,ctrl_11,ADD1,
471121934Sharti             LEFT_ADD_DISTRIB,GSYM word_add_n2w]
472121934Sharti        \\ CONV_TAC (DEPTH_CONV EXISTS_AND_REORDER_CONV)
473121934Sharti        \\ FINISH_OFF3]);
474121934Sharti
475121934Shartival NOT_INTERRUPT = GEN_ALL (prove(
476121934Sharti `!w b inp.
477121934Sharti     inp IN STRM_ARM6 /\
478121934Sharti     Abbrev (b = BUSY_WAIT x inp) /\
479121934Sharti     Abbrev (w = 1 + b + (LEAST n. IS_BUSY (ADVANCE b inp) n)) /\
480121934Sharti     ~IS_BUSY inp b ==>
481121934Sharti     1 + b < w`,
482121934Sharti  REPEAT STRIP_TAC \\ IMP_RES_TAC EXISTS_BUSY_WAIT_IMP_BUSY_WAIT_DONE
483121934Sharti    \\ Cases_on_x `x` \\ IMP_RES_TAC BUSY_EXISTS_COR
484121934Sharti    \\ Cases_on `(LEAST n. PROJ_CPB (inp (b + n))) = 0`
485121934Sharti    \\ FULL_SIMP_TAC arith_ss
486121934Sharti         [Abbr`w`,IS_BUSY_def,ADVANCE_def,BUSY_WAIT_DONE_def]));
487121934Sharti
488121934Shartival x = METIS_PROVE []
489121934Sharti  ``!a2 a9 a10 a13 a14.
490121934Sharti    (a2 /\ a9 /\ a10 /\ a13 ==> a14) ==>
491121934Sharti    ((a1 /\ a2 /\ a3 /\ a4 /\ a5 /\ a6 /\ a7 /\
492121934Sharti      a8 /\ a9 /\ a10 /\ a11 /\ a12 /\ a13 ==> (a14 ==> a15)) =
493121934Sharti     (a1 /\ a2 /\ a3 /\ a4 /\ a5 /\ a6 /\ a7 /\
494121934Sharti      a8 /\ a9 /\ a10 /\ a11 /\ a12 /\ a13 ==> a15))``;
495121934Sharti
496121934Shartival x2 = (GEN_ALL o REWRITE_RULE [NOT_INTERRUPT] o
497121934Sharti  SPECL [`inp IN STRM_ARM6`,`Abbrev (b = BUSY_WAIT x inp)`,
498121934Sharti         `Abbrev (w = 1 + b + (LEAST n. IS_BUSY (ADVANCE b inp) n))`,
499121934Sharti         `~IS_BUSY inp b`,`1 + b < w`]) x;
500121934Sharti
501121934Shartival LDC_STC_THM2 = save_thm("LDC_STC_THM2",
502121934Sharti  (SIMP_RULE std_ss [x2,LESS_EQ_REFL] o SPEC `w`) LDC_STC_THM);
503121934Sharti
504121934Sharti(* ------------------------------------------------------------------------- *)
505121934Sharti
506121934Shartival _ = export_theory();
507121934Sharti