vericert.hls.HTLgenspec
#[local] Hint Resolve Maps.PTree.elements_keys_norepet : htlspec.
#[local] Hint Resolve Maps.PTree.elements_correct : htlspec.
Remark bind_inversion:
forall (A B: Type) (f: mon A) (g: A -> mon B)
(y: B) (s1 s3: st) (i: st_incr s1 s3),
bind f g s1 = OK y s3 i ->
exists x, exists s2, exists i1, exists i2,
f s1 = OK x s2 i1 /\ g x s2 = OK y s3 i2.
Remark bind2_inversion:
forall (A B C: Type) (f: mon (A*B)) (g: A -> B -> mon C)
(z: C) (s1 s3: st) (i: st_incr s1 s3),
bind2 f g s1 = OK z s3 i ->
exists x, exists y, exists s2, exists i1, exists i2,
f s1 = OK (x, y) s2 i1 /\ g x y s2 = OK z s3 i2.
Relational specification of the translation
Inductive tr_instr (fin rtrn st stk : reg) : RTL.instruction -> stmnt -> stmnt -> Prop :=
| tr_instr_Inop :
forall n,
Z.pos n <= Int.max_unsigned ->
tr_instr fin rtrn st stk (RTL.Inop n) Vskip (state_goto st n)
| tr_instr_Iop :
forall n op args dst s s' e i,
Z.pos n <= Int.max_unsigned ->
translate_instr op args s = OK e s' i ->
tr_instr fin rtrn st stk (RTL.Iop op args dst n) (Vnonblock (Vvar dst) e) (state_goto st n)
| tr_instr_Icond :
forall n1 n2 cond args s s' i c,
Z.pos n1 <= Int.max_unsigned ->
Z.pos n2 <= Int.max_unsigned ->
translate_condition cond args s = OK c s' i ->
tr_instr fin rtrn st stk (RTL.Icond cond args n1 n2) Vskip (state_cond st c n1 n2)
| tr_instr_Ireturn_None :
tr_instr fin rtrn st stk (RTL.Ireturn None) (Vseq (block fin (Vlit (ZToValue 1%Z)))
(block rtrn (Vlit (ZToValue 0%Z)))) Vskip
| tr_instr_Ireturn_Some :
forall r,
tr_instr fin rtrn st stk (RTL.Ireturn (Some r))
(Vseq (block fin (Vlit (ZToValue 1%Z))) (block rtrn (Vvar r))) Vskip
| tr_instr_Iload :
forall mem addr args s s' i c dst n,
Z.pos n <= Int.max_unsigned ->
translate_arr_access mem addr args stk s = OK c s' i ->
tr_instr fin rtrn st stk (RTL.Iload mem addr args dst n) (nonblock dst c) (state_goto st n)
| tr_instr_Istore :
forall mem addr args s s' i c src n,
Z.pos n <= Int.max_unsigned ->
translate_arr_access mem addr args stk s = OK c s' i ->
tr_instr fin rtrn st stk (RTL.Istore mem addr args src n) (Vnonblock c (Vvar src))
(state_goto st n).
#[local] Hint Constructors tr_instr : htlspec.
Inductive tr_code (c : RTL.code) (pc : RTL.node) (i : RTL.instruction) (stmnts trans : PTree.t stmnt)
(fin rtrn st stk : reg) : Prop :=
tr_code_intro :
forall s t,
c!pc = Some i ->
stmnts!pc = Some s ->
trans!pc = Some t ->
tr_instr fin rtrn st stk i s t ->
tr_code c pc i stmnts trans fin rtrn st stk.
#[local] Hint Constructors tr_code : htlspec.
Inductive tr_module (f : RTL.function) : module -> Prop :=
tr_module_intro :
forall data control fin rtrn st stk stk_len m start rst clk scldecls arrdecls r_en r_u_en r_addr r_wr_en r_d_in r_d_out,
m = (mkmodule f.(RTL.fn_params)
data
control
f.(RTL.fn_entrypoint)
st fin rtrn start rst clk scldecls arrdecls
(mk_ram stk_len stk r_en r_u_en r_addr r_wr_en r_d_in r_d_out)) ->
(forall pc i, Maps.PTree.get pc f.(RTL.fn_code) = Some i ->
tr_code f.(RTL.fn_code) pc i data control fin rtrn st stk) ->
stk_len = Z.to_nat (f.(RTL.fn_stacksize) / 4) ->
Z.modulo (f.(RTL.fn_stacksize)) 4 = 0 ->
0 <= f.(RTL.fn_stacksize) < Integers.Ptrofs.modulus ->
st = ((RTL.max_reg_function f) + 1)%positive ->
fin = ((RTL.max_reg_function f) + 2)%positive ->
rtrn = ((RTL.max_reg_function f) + 3)%positive ->
stk = ((RTL.max_reg_function f) + 4)%positive ->
start = ((RTL.max_reg_function f) + 5)%positive ->
rst = ((RTL.max_reg_function f) + 6)%positive ->
clk = ((RTL.max_reg_function f) + 7)%positive ->
r_en = ((RTL.max_reg_function f) + 8)%positive ->
r_u_en = ((RTL.max_reg_function f) + 9)%positive ->
r_addr = ((RTL.max_reg_function f) + 10)%positive ->
r_wr_en = ((RTL.max_reg_function f) + 11)%positive ->
r_d_in = ((RTL.max_reg_function f) + 12)%positive ->
r_d_out = ((RTL.max_reg_function f) + 13)%positive ->
tr_module f m.
#[local] Hint Constructors tr_module : htlspec.
Lemma create_reg_datapath_trans :
forall sz s s' x i iop,
create_reg iop sz s = OK x s' i ->
s.(st_datapath) = s'.(st_datapath).
#[local] Hint Resolve create_reg_datapath_trans : htlspec.
Lemma create_reg_controllogic_trans :
forall sz s s' x i iop,
create_reg iop sz s = OK x s' i ->
s.(st_controllogic) = s'.(st_controllogic).
#[local] Hint Resolve create_reg_controllogic_trans : htlspec.
Lemma declare_reg_datapath_trans :
forall sz s s' x i iop r,
declare_reg iop r sz s = OK x s' i ->
s.(st_datapath) = s'.(st_datapath).
#[local] Hint Resolve create_reg_datapath_trans : htlspec.
Lemma declare_reg_controllogic_trans :
forall sz s s' x i iop r,
declare_reg iop r sz s = OK x s' i ->
s.(st_controllogic) = s'.(st_controllogic).
#[local] Hint Resolve create_reg_controllogic_trans : htlspec.
Lemma declare_reg_freshreg_trans :
forall sz s s' x i iop r,
declare_reg iop r sz s = OK x s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve declare_reg_freshreg_trans : htlspec.
Lemma create_arr_datapath_trans :
forall sz ln s s' x i iop,
create_arr iop sz ln s = OK x s' i ->
s.(st_datapath) = s'.(st_datapath).
#[local] Hint Resolve create_arr_datapath_trans : htlspec.
Lemma create_arr_controllogic_trans :
forall sz ln s s' x i iop,
create_arr iop sz ln s = OK x s' i ->
s.(st_controllogic) = s'.(st_controllogic).
#[local] Hint Resolve create_arr_controllogic_trans : htlspec.
Lemma get_refl_x :
forall s s' x i,
get s = OK x s' i ->
s = x.
#[local] Hint Resolve get_refl_x : htlspec.
Lemma get_refl_s :
forall s s' x i,
get s = OK x s' i ->
s = s'.
#[local] Hint Resolve get_refl_s : htlspec.
Lemma collect_controllogic_trans :
forall A f l cs cs' ci,
(forall s s' x i y, f y s = OK x s' i -> s.(st_controllogic) = s'.(st_controllogic)) ->
@HTLMonadExtra.collectlist A f l cs = OK tt cs' ci -> cs.(st_controllogic) = cs'.(st_controllogic).
Lemma collect_datapath_trans :
forall A f l cs cs' ci,
(forall s s' x i y, f y s = OK x s' i -> s.(st_datapath) = s'.(st_datapath)) ->
@HTLMonadExtra.collectlist A f l cs = OK tt cs' ci -> cs.(st_datapath) = cs'.(st_datapath).
Lemma collect_freshreg_trans :
forall A f l cs cs' ci,
(forall s s' x i y, f y s = OK x s' i -> s.(st_freshreg) = s'.(st_freshreg)) ->
@HTLMonadExtra.collectlist A f l cs = OK tt cs' ci -> cs.(st_freshreg) = cs'.(st_freshreg).
Lemma collect_declare_controllogic_trans :
forall io n l s s' i,
HTLMonadExtra.collectlist (fun r : reg => declare_reg io r n) l s = OK tt s' i ->
s.(st_controllogic) = s'.(st_controllogic).
Lemma collect_declare_datapath_trans :
forall io n l s s' i,
HTLMonadExtra.collectlist (fun r : reg => declare_reg io r n) l s = OK tt s' i ->
s.(st_datapath) = s'.(st_datapath).
Lemma collect_declare_freshreg_trans :
forall io n l s s' i,
HTLMonadExtra.collectlist (fun r : reg => declare_reg io r n) l s = OK tt s' i ->
s.(st_freshreg) = s'.(st_freshreg).
Lemma translate_eff_addressing_freshreg_trans :
forall op args s r s' i,
translate_eff_addressing op args s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve translate_eff_addressing_freshreg_trans : htlspec.
Lemma translate_comparison_freshreg_trans :
forall op args s r s' i,
translate_comparison op args s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve translate_comparison_freshreg_trans : htlspec.
Lemma translate_comparisonu_freshreg_trans :
forall op args s r s' i,
translate_comparisonu op args s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve translate_comparisonu_freshreg_trans : htlspec.
Lemma translate_comparison_imm_freshreg_trans :
forall op args s r s' i n,
translate_comparison_imm op args n s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve translate_comparison_imm_freshreg_trans : htlspec.
Lemma translate_comparison_immu_freshreg_trans :
forall op args s r s' i n,
translate_comparison_immu op args n s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve translate_comparison_immu_freshreg_trans : htlspec.
Lemma translate_condition_freshreg_trans :
forall op args s r s' i,
translate_condition op args s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve translate_condition_freshreg_trans : htlspec.
Lemma translate_instr_freshreg_trans :
forall op args s r s' i,
translate_instr op args s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve translate_instr_freshreg_trans : htlspec.
Lemma translate_arr_access_freshreg_trans :
forall mem addr args st s r s' i,
translate_arr_access mem addr args st s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve translate_arr_access_freshreg_trans : htlspec.
Lemma add_instr_freshreg_trans :
forall n n' st s r s' i,
add_instr n n' st s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve add_instr_freshreg_trans : htlspec.
Lemma add_branch_instr_freshreg_trans :
forall n n0 n1 e s r s' i,
add_branch_instr e n n0 n1 s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve add_branch_instr_freshreg_trans : htlspec.
Lemma add_node_skip_freshreg_trans :
forall n1 n2 s r s' i,
add_node_skip n1 n2 s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve add_node_skip_freshreg_trans : htlspec.
Lemma add_instr_skip_freshreg_trans :
forall n1 n2 s r s' i,
add_instr_skip n1 n2 s = OK r s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve add_instr_skip_freshreg_trans : htlspec.
Lemma transf_instr_freshreg_trans :
forall fin ret st instr s v s' i,
transf_instr fin ret st instr s = OK v s' i ->
s.(st_freshreg) = s'.(st_freshreg).
#[local] Hint Resolve transf_instr_freshreg_trans : htlspec.
Lemma collect_trans_instr_freshreg_trans :
forall fin ret st l s s' i,
HTLMonadExtra.collectlist (transf_instr fin ret st) l s = OK tt s' i ->
s.(st_freshreg) = s'.(st_freshreg).
Lemma iter_expand_instr_spec :
forall l fin rtrn stack s s' i x c,
HTLMonadExtra.collectlist (transf_instr fin rtrn stack) l s = OK x s' i ->
list_norepet (List.map fst l) ->
(forall pc instr, In (pc, instr) l -> c!pc = Some instr) ->
(forall pc instr, In (pc, instr) l ->
c!pc = Some instr ->
tr_code c pc instr s'.(st_datapath) s'.(st_controllogic) fin rtrn s'.(st_st) stack).
#[local] Hint Resolve iter_expand_instr_spec : htlspec.
Lemma create_arr_inv : forall w x y z a b c d,
create_arr w x y z = OK (a, b) c d ->
y = b /\ a = z.(st_freshreg) /\ c.(st_freshreg) = Pos.succ (z.(st_freshreg)).
Lemma create_reg_inv : forall a b s r s' i,
create_reg a b s = OK r s' i ->
r = s.(st_freshreg) /\ s'.(st_freshreg) = Pos.succ (s.(st_freshreg)).
Theorem transl_module_correct :
forall f m,
transl_module f = Errors.OK m -> tr_module f m.