vericert.hls.RTLBlockInstr
RTLBlock Instructions
Instruction Definition
Definition node := positive.
Inductive instr : Type :=
| RBnop : instr
| RBop : option pred_op -> operation -> list reg -> reg -> instr
| RBload : option pred_op -> memory_chunk -> addressing -> list reg -> reg -> instr
| RBstore : option pred_op -> memory_chunk -> addressing -> list reg -> reg -> instr
| RBsetpred : option pred_op -> condition -> list reg -> predicate -> instr.
Control-Flow Instruction Definition
Inductive cf_instr : Type :=
| RBcall : signature -> reg + ident -> list reg -> reg -> node -> cf_instr
| RBtailcall : signature -> reg + ident -> list reg -> cf_instr
| RBbuiltin : external_function -> list (builtin_arg reg) ->
builtin_res reg -> node -> cf_instr
| RBcond : condition -> list reg -> node -> node -> cf_instr
| RBjumptable : reg -> list node -> cf_instr
| RBreturn : option reg -> cf_instr
| RBgoto : node -> cf_instr
| RBpred_cf : pred_op -> cf_instr -> cf_instr -> cf_instr.
Fixpoint successors_instr (i : cf_instr) : list node :=
match i with
| RBcall sig ros args res s => s :: nil
| RBtailcall sig ros args => nil
| RBbuiltin ef args res s => s :: nil
| RBcond cond args ifso ifnot => ifso :: ifnot :: nil
| RBjumptable arg tbl => tbl
| RBreturn optarg => nil
| RBgoto n => n :: nil
| RBpred_cf p c1 c2 => concat (successors_instr c1 :: successors_instr c2 :: nil)
end.
Definition max_reg_instr (m: positive) (i: instr) :=
match i with
| RBnop => m
| RBop p op args res =>
fold_left Pos.max args (Pos.max res m)
| RBload p chunk addr args dst =>
fold_left Pos.max args (Pos.max dst m)
| RBstore p chunk addr args src =>
fold_left Pos.max args (Pos.max src m)
| RBsetpred p' c args p =>
fold_left Pos.max args m
end.
Fixpoint max_reg_cfi (m : positive) (i : cf_instr) :=
match i with
| RBcall sig (inl r) args res s =>
fold_left Pos.max args (Pos.max r (Pos.max res m))
| RBcall sig (inr id) args res s =>
fold_left Pos.max args (Pos.max res m)
| RBtailcall sig (inl r) args =>
fold_left Pos.max args (Pos.max r m)
| RBtailcall sig (inr id) args =>
fold_left Pos.max args m
| RBbuiltin ef args res s =>
fold_left Pos.max (params_of_builtin_args args)
(fold_left Pos.max (params_of_builtin_res res) m)
| RBcond cond args ifso ifnot => fold_left Pos.max args m
| RBjumptable arg tbl => Pos.max arg m
| RBreturn None => m
| RBreturn (Some arg) => Pos.max arg m
| RBgoto n => m
| RBpred_cf p c1 c2 => Pos.max (max_reg_cfi m c1) (max_reg_cfi m c2)
end.
Definition regset := Regmap.t val.
Definition predset := PMap.t bool.
Definition eval_predf (pr: predset) (p: pred_op) :=
sat_predicate p (fun x => pr !! (Pos.of_nat x)).
#[global]
Instance eval_predf_Proper : Proper (eq ==> equiv ==> eq) eval_predf.
#[local] Open Scope pred_op.
Lemma eval_predf_Pand :
forall ps p p',
eval_predf ps (p ∧ p') = eval_predf ps p && eval_predf ps p'.
Lemma eval_predf_Por :
forall ps p p',
eval_predf ps (p ∨ p') = eval_predf ps p || eval_predf ps p'.
Lemma eval_predf_pr_equiv :
forall p ps ps',
(forall x, ps !! x = ps' !! x) ->
eval_predf ps p = eval_predf ps' p.
Fixpoint init_regs (vl: list val) (rl: list reg) {struct rl} : regset :=
match rl, vl with
| r1 :: rs, v1 :: vs => Regmap.set r1 v1 (init_regs vs rs)
| _, _ => Regmap.init Vundef
end.
Instruction State
- is_rs This is the current state of the registers.
- is_ps This is the current state of the predicate registers, which is in a separate namespace and area compared to the standard registers in is_rs.
- is_mem The current state of the memory.
Section DEFINITION.
Context {bblock_body: Type}.
Record bblock : Type := mk_bblock {
bb_body: bblock_body;
bb_exit: cf_instr
}.
Definition code: Type := PTree.t bblock.
Record function: Type := mkfunction {
fn_sig: signature;
fn_params: list reg;
fn_stacksize: Z;
fn_code: code;
fn_entrypoint: node
}.
Definition fundef := AST.fundef function.
Definition program := AST.program fundef unit.
Definition funsig (fd: fundef) :=
match fd with
| Internal f => fn_sig f
| External ef => ef_sig ef
end.
Inductive stackframe : Type :=
| Stackframe:
forall (res: reg)
(f: function)
(sp: val)
(pc: node)
(rs: regset)
(pr: predset),
stackframe.
Inductive state : Type :=
| State:
forall (stack: list stackframe)
(f: function)
(sp: val)
(pc: node)
(rs: regset)
(pr: predset)
(m: mem),
state
| Callstate:
forall (stack: list stackframe)
(f: fundef)
(args: list val)
(m: mem),
state
| Returnstate:
forall (stack: list stackframe)
(v: val)
(m: mem),
state.
End DEFINITION.
Section RELSEM.
Context {bblock_body : Type}.
Definition genv := Genv.t (@fundef bblock_body) unit.
Context (ge: genv).
Definition find_function
(ros: reg + ident) (rs: regset) : option fundef :=
match ros with
| inl r => Genv.find_funct ge rs#r
| inr symb =>
match Genv.find_symbol ge symb with
| None => None
| Some b => Genv.find_funct_ptr ge b
end
end.
Inductive eval_pred: option pred_op -> instr_state -> instr_state -> instr_state -> Prop :=
| eval_pred_true:
forall i i' p,
eval_predf (is_ps i) p = true ->
eval_pred (Some p) i i' i'
| eval_pred_false:
forall i i' p,
eval_predf (is_ps i) p = false ->
eval_pred (Some p) i i' i
| eval_pred_none:
forall i i', eval_pred None i i' i.
Inductive step_instr: val -> instr_state -> instr -> instr_state -> Prop :=
| exec_RBnop:
forall sp ist,
step_instr sp ist RBnop ist
| exec_RBop:
forall op v res args rs m sp p ist pr,
eval_operation ge sp op rs##args m = Some v ->
eval_pred p (mk_instr_state rs pr m) (mk_instr_state (rs#res <- v) pr m) ist ->
step_instr sp (mk_instr_state rs pr m) (RBop p op args res) ist
| exec_RBload:
forall addr rs args a chunk m v dst sp p pr ist,
eval_addressing ge sp addr rs##args = Some a ->
Mem.loadv chunk m a = Some v ->
eval_pred p (mk_instr_state rs pr m) (mk_instr_state (rs#dst <- v) pr m) ist ->
step_instr sp (mk_instr_state rs pr m) (RBload p chunk addr args dst) ist
| exec_RBstore:
forall addr rs args a chunk m src m' sp p pr ist,
eval_addressing ge sp addr rs##args = Some a ->
Mem.storev chunk m a rs#src = Some m' ->
eval_pred p (mk_instr_state rs pr m) (mk_instr_state rs pr m') ist ->
step_instr sp (mk_instr_state rs pr m) (RBstore p chunk addr args src) ist
| exec_RBsetpred:
forall sp rs pr m p c b args p' ist,
Op.eval_condition c rs##args m = Some b ->
eval_pred p' (mk_instr_state rs pr m) (mk_instr_state rs (pr#p <- b) m) ist ->
step_instr sp (mk_instr_state rs pr m) (RBsetpred p' c args p) ist.
Inductive step_cf_instr: state -> cf_instr -> trace -> state -> Prop :=
| exec_RBcall:
forall s f sp rs m res fd ros sig args pc pc' pr,
find_function ros rs = Some fd ->
funsig fd = sig ->
step_cf_instr (State s f sp pc rs pr m) (RBcall sig ros args res pc')
E0 (Callstate (Stackframe res f sp pc' rs pr :: s) fd rs##args m)
| exec_RBtailcall:
forall s f stk rs m sig ros args fd m' pc pr,
find_function ros rs = Some fd ->
funsig fd = sig ->
Mem.free m stk 0 f.(fn_stacksize) = Some m' ->
step_cf_instr (State s f (Vptr stk Ptrofs.zero) pc rs pr m) (RBtailcall sig ros args)
E0 (Callstate s fd rs##args m')
| exec_RBbuiltin:
forall s f sp rs m ef args res pc' vargs t vres m' pc pr,
eval_builtin_args ge (fun r => rs#r) sp m args vargs ->
external_call ef ge vargs m t vres m' ->
step_cf_instr (State s f sp pc rs pr m) (RBbuiltin ef args res pc')
t (State s f sp pc' (regmap_setres res vres rs) pr m')
| exec_RBcond:
forall s f sp rs m cond args ifso ifnot b pc pc' pr,
eval_condition cond rs##args m = Some b ->
pc' = (if b then ifso else ifnot) ->
step_cf_instr (State s f sp pc rs pr m) (RBcond cond args ifso ifnot)
E0 (State s f sp pc' rs pr m)
| exec_RBjumptable:
forall s f sp rs m arg tbl n pc pc' pr,
rs#arg = Vint n ->
list_nth_z tbl (Int.unsigned n) = Some pc' ->
step_cf_instr (State s f sp pc rs pr m) (RBjumptable arg tbl)
E0 (State s f sp pc' rs pr m)
| exec_RBreturn:
forall s f stk rs m or pc m' pr,
Mem.free m stk 0 f.(fn_stacksize) = Some m' ->
step_cf_instr (State s f (Vptr stk Ptrofs.zero) pc rs pr m) (RBreturn or)
E0 (Returnstate s (regmap_optget or Vundef rs) m')
| exec_RBgoto:
forall s f sp pc rs pr m pc',
step_cf_instr (State s f sp pc rs pr m) (RBgoto pc') E0 (State s f sp pc' rs pr m)
| exec_RBpred_cf:
forall s f sp pc rs pr m cf1 cf2 st' p t,
step_cf_instr (State s f sp pc rs pr m) (if eval_predf pr p then cf1 else cf2) t st' ->
step_cf_instr (State s f sp pc rs pr m) (RBpred_cf p cf1 cf2) t st'.
End RELSEM.