diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gen_lib/sail_values.lem | 18 | ||||
| -rw-r--r-- | src/gen_lib/vector.lem | 6 | ||||
| -rw-r--r-- | src/pretty_print.ml | 89 | ||||
| -rw-r--r-- | src/rewriter.ml | 48 |
4 files changed, 117 insertions, 44 deletions
diff --git a/src/gen_lib/sail_values.lem b/src/gen_lib/sail_values.lem index 4d74976b..33b8444e 100644 --- a/src/gen_lib/sail_values.lem +++ b/src/gen_lib/sail_values.lem @@ -3,16 +3,18 @@ open import State open import Vector open import Arch +type i = integer + let length l = integerFromNat (length l) -let has_undef (V bs _ _) = List.any (function U -> true | _ -> false end) bs +let has_undef (V bs _ _) = List.any (function Undef -> true | _ -> false end) bs let most_significant (V bs _ _) = let (b :: _) = bs in b let bitwise_not_bit = function | I -> O | O -> I - | _ -> U + | _ -> Undef end let (~) = bitwise_not_bit @@ -23,8 +25,8 @@ let bitwise_not (V bs start is_inc) = let bool_to_bit b = if b then I else O let bitwise_binop_bit op = function - | (U,_) -> U (*Do we want to do this or to respect | of I and & of B0 rules?*) - | (_,U) -> U (*Do we want to do this or to respect | of I and & of B0 rules?*) + | (Undef,_) -> Undef (*Do we want to do this or to respect | of I and & of B0 rules?*) + | (_,Undef) -> Undef (*Do we want to do this or to respect | of I and & of B0 rules?*) | (x,y) -> bool_to_bit (op (to_bool x) (to_bool y)) end @@ -131,7 +133,7 @@ let to_vec_inc = to_vec true let to_vec_dec = to_vec false let to_vec_undef is_inc (len : integer) = - V (replicate (natFromInteger len) U) (if is_inc then 0 else len-1) is_inc + V (replicate (natFromInteger len) Undef) (if is_inc then 0 else len-1) is_inc let to_vec_inc_undef = to_vec_undef true let to_vec_dec_undef = to_vec_undef false @@ -289,7 +291,7 @@ let rec arith_op_vec_no0 (op : integer -> integer -> integer) sign size (((V _ s end in if representable then to_vec is_inc (act_size,n') - else V (List.replicate (natFromInteger act_size) U) start is_inc + else V (List.replicate (natFromInteger act_size) Undef) start is_inc let mod_vec = arith_op_vec_no0 integerMod false 1 let quot_vec = arith_op_vec_no0 integerDiv false 1 @@ -313,8 +315,8 @@ let arith_op_overflow_no0_vec op sign size (((V _ start is_inc) as l),r) = if representable then (to_vec is_inc (act_size,n'),to_vec is_inc (act_size + 1,n_u')) else - (V (List.replicate (natFromInteger act_size) U) start is_inc, - V (List.replicate (natFromInteger (act_size + 1)) U) start is_inc) in + (V (List.replicate (natFromInteger act_size) Undef) start is_inc, + V (List.replicate (natFromInteger (act_size + 1)) Undef) start is_inc) in let overflow = if representable then O else I in (correct_size_num,overflow,most_significant one_more) diff --git a/src/gen_lib/vector.lem b/src/gen_lib/vector.lem index 5e78e010..9efae768 100644 --- a/src/gen_lib/vector.lem +++ b/src/gen_lib/vector.lem @@ -1,6 +1,6 @@ open import Pervasives -type bit = O | I | U +type bit = O | I | Undef type vector 'a = V of list 'a * integer * bool let rec nth xs (n : integer) = match (n,xs) with @@ -28,11 +28,11 @@ let make_indexed_vector_reg entries default start length = V (List.foldl replace (replicate length v) entries) start let make_indexed_vector_bit entries default start length = - let default = match default with Nothing -> U | Just v -> v end in + let default = match default with Nothing -> Undef | Just v -> v end in V (List.foldl replace (replicate length default) entries) start let make_bitvector_undef length = - V (replicate length U) 0 true + V (replicate length Undef) 0 true let vector_concat (V bs start is_inc) (V bs' _ _) = V (bs ++ bs') start is_inc diff --git a/src/pretty_print.ml b/src/pretty_print.ml index 02fc62a5..6b1b364a 100644 --- a/src/pretty_print.ml +++ b/src/pretty_print.ml @@ -1886,11 +1886,11 @@ let doc_lit_lem in_pat (L_aux(l,_)) = | L_true -> "I" | L_num i -> let ipp = string_of_int i in - (if i < 0 then "((0"^ipp^") : integer)" - else "("^ipp^" : integer)") + (if i < 0 then "((0"^ipp^") : i)" + else "("^ipp^" : i)") | L_hex n -> failwith "Shouldn't happen" (*"(num_to_vec " ^ ("0x" ^ n) ^ ")" (*shouldn't happen*)*) | L_bin n -> failwith "Shouldn't happen" (*"(num_to_vec " ^ ("0b" ^ n) ^ ")" (*shouldn't happen*)*) - | L_undef -> "U" + | L_undef -> "Undef" | L_string s -> "\"" ^ s ^ "\"") (* typ_doc is the doc for the type being quantified *) @@ -2012,22 +2012,35 @@ let doc_exp_lem, doc_let_lem = | E_app(f,args) -> (match f with (* temporary hack to make the loop body a function of the temporary variables *) - | Id_aux ((Id (("foreach_inc" | "foreach_dec") as loopf),_)) -> + | Id_aux ((Id (("foreach_inc" | "foreach_dec" | + "foreachM_inc" | "foreachM_dec" ) as loopf),_)) -> let call = doc_id_lem in - let [id;indices;body;E_aux (E_tuple vars,_) as e5] = args in - let vars = List.map (fun (E_aux (E_id (Id_aux (Id name,_)),_)) -> string name) vars in - let varspp = - match vars with - | [v] -> v - | _ -> parens (separate comma vars) in - (prefix 2 1) - (parens ((separate space) [string loopf;exp indices;exp e5])) - (parens - ((prefix 1 1) - (separate space [string "fun";exp id;varspp;arrow]) - (exp body) - ) - ) + let [id;indices;body;e5] = args in + (match e5 with + | E_aux (E_tuple vars,_) -> + let vars = List.map (fun (E_aux (E_id (Id_aux (Id name,_)),_)) -> string name) vars in + let varspp = + match vars with + | [v] -> v + | _ -> parens (separate comma vars) in + (prefix 2 1) + (parens ((separate space) [string loopf;exp indices;exp e5])) + (parens + ((prefix 1 1) + (separate space [string "fun";exp id;varspp;arrow]) + (top_exp false body) + ) + ) + | E_aux (E_lit (L_aux (L_unit,_)),_) -> + (prefix 2 1) + (parens ((separate space) [string loopf;exp indices;exp e5])) + (parens + ((prefix 1 1) + (separate space [string "fun";exp id;string "_";arrow]) + (top_exp false body) + ) + ) + ) | _ -> (match annot with | Base (_,Constructor _,_,_,_,_) -> @@ -2416,31 +2429,44 @@ let reg_decls (Defs defs) = [],[]) in let regs_pp = - (prefix 2 1) - (separate space [string "type";string "register";equals]) - ((separate_map space (fun (reg,_) -> pipe ^^ space ^^ string reg) regs) - ^^ space ^^ pipe ^^ space ^^ string "UndefinedReg of integer" ^^ - pipe ^^ space ^^ string "RegisterPair of register * register") in + if regs = [] then + string "type register = NO_REGISTERS" + else + (prefix 2 1) + (separate space [string "type";string "register";equals]) + ((separate_map space (fun (reg,_) -> pipe ^^ space ^^ string reg) regs) + ^^ space ^^ pipe ^^ space ^^ string "UndefinedReg of integer" ^^ + pipe ^^ space ^^ string "RegisterPair of register * register") in let regfields_pp = + if rsranges = [] then + string "type register_field = | NO_REGISTER_FIELDS" + else (prefix 2 1) (separate space [string "type";string "register_field";equals]) (separate_map space (fun (fname,tname,_,_) -> pipe ^^ space ^^ string (tname ^ "_" ^ fname)) rsranges) in let regfieldsbit_pp = + if rsbits = [] then + string "type register_field_bit = | NO_REGISTER_FIELD_BITS" + else (prefix 2 1) (separate space [string "type";string "register_field_bit";equals]) (separate_map space (fun (fname,tname,_) -> pipe ^^ space ^^ string (tname ^ "_" ^ fname)) rsbits) in let regalias_pp = + if regaliases = [] then empty else (separate_map (break 1)) (fun (name1,(name2,name3)) -> separate space [string "let";string name1;equals;string "RegisterPair";string name2;string name3]) regaliases in let state_pp = + if regs = [] then + string "type state = EMPTY_STATE" + else (prefix 2 1) (separate space [string "type";string "state";equals]) (anglebars @@ -2450,6 +2476,9 @@ let reg_decls (Defs defs) = )) in let length_pp = + if regs = [] then + string "length_reg _ = (0 : integer)" + else (separate space [string "val";string "length_reg";colon;string "register";arrow;string "integer"]) ^/^ (prefix 2 1) @@ -2471,6 +2500,9 @@ let reg_decls (Defs defs) = let field_indices_pp = + if rsranges = [] then + string "let field_indices _ = ((0 : integer),(0 : integer))" + else (prefix 2 1) ((separate space) [string "let";string "field_indices"; colon;string "register_field";arrow;string "(integer * integer)"; @@ -2485,7 +2517,10 @@ let reg_decls (Defs defs) = ) ^/^ string "end" ^^ hardline ) in -let field_index_bit_pp = + let field_index_bit_pp = + if rsbits = [] then + string "let field_index_bit _ = (0 : integer)" + else (prefix 2 1) ((separate space) [string "let";string "field_index_bit"; colon;string "register_field_bit";arrow;string "integer"; @@ -2501,6 +2536,9 @@ let field_index_bit_pp = let read_regstate_pp = + if regs = [] then + string "let read_regstate _ _ -> Vector 0 0 true" + else (prefix 2 1) (separate space [string "let rec";string "read_regstate";string "s";equals;string "function"]) ( @@ -2515,6 +2553,9 @@ let field_index_bit_pp = string "end" ^^ hardline ) in let write_regstate_pp = + if regs = [] then + string "let write_regstate _ _ _ -> EMPTY_STATE" + else (prefix 2 1) (separate space [string "let rec";string "write_regstate";string "s";string "reg";string "v"; equals;string "match reg with"]) diff --git a/src/rewriter.ml b/src/rewriter.ml index c7e6986b..1761bcc5 100644 --- a/src/rewriter.ml +++ b/src/rewriter.ml @@ -24,6 +24,8 @@ let fresh_name () = let current = !fresh_name_counter in let () = fresh_name_counter := (current + 1) in current +let reset_fresh_name_counter () = + fresh_name_counter := 0 let geteffs_annot (_,t) = match t with | Base (_,_,_,_,effs,_) -> effs @@ -344,7 +346,8 @@ let rewrite_lexp rewriters map (LEXP_aux(lexp,(l,annot))) = | LEXP_field (lexp,id) -> rewrap (LEXP_field (rewriters.rewrite_lexp rewriters map lexp,id)) let rewrite_fun rewriters (FD_aux (FD_function(recopt,tannotopt,effectopt,funcls),(l,fdannot))) = - let rewrite_funcl (FCL_aux (FCL_Funcl(id,pat,exp),(l,annot))) = + let rewrite_funcl (FCL_aux (FCL_Funcl(id,pat,exp),(l,annot))) = + let _ = reset_fresh_name_counter () in (*let _ = Printf.eprintf "Rewriting function %s, pattern %s\n" (match id with (Id_aux (Id i,_)) -> i) (Pretty_print.pat_to_string pat) in*) let map = get_map_tannot fdannot in @@ -736,7 +739,11 @@ let remove_vector_concat_pat pat = let subv = E_aux (E_vector_subrange (E_aux (E_id rootid,rannot),index i,index j),cannot) in let typ = (Parse_ast.Unknown,simple_annot {t = Tid "unit"}) in let letbind = LB_val_implicit (P_aux (P_id child,cannot),subv) in - (LB_aux (letbind,typ), (fun body -> E_aux (E_let (LB_aux (letbind,cannot),body),typ))) in + let (Id_aux (Id rootname,_)) = rootid in + let (Id_aux (Id childname,_)) = child in + (LB_aux (letbind,typ), + (fun body -> E_aux (E_let (LB_aux (letbind,cannot),body),typ)), + (rootname,childname)) in let p_aux = function | ((P_as (P_aux (P_vector_concat pats,rannot'),rootid),decls),rannot) -> @@ -747,12 +754,12 @@ let remove_vector_concat_pat pat = (* if we see a named vector pattern, remove the name and remember to declare it later *) | P_as (P_aux (p,cannot),cname) -> - let (lb,decl) = letbind_vec (rootid,rannot) (cname,cannot) (pos,pos + length - 1) in - (pos + length, pat_acc @ [P_aux (p,cannot)], decl_acc @ [(lb,decl)]) + let (lb,decl,info) = letbind_vec (rootid,rannot) (cname,cannot) (pos,pos + length - 1) in + (pos + length, pat_acc @ [P_aux (p,cannot)], decl_acc @ [((lb,decl),info)]) (* if we see a P_id variable, remember to declare it later *) | P_id cname -> - let (lb,decl) = letbind_vec (rootid,rannot) (cname,cannot) (pos,pos + length - 1) in - (pos + length, pat_acc @ [P_aux (P_id cname,cannot)], decl_acc @ [(lb,decl)]) + let (lb,decl,info) = letbind_vec (rootid,rannot) (cname,cannot) (pos,pos + length - 1) in + (pos + length, pat_acc @ [P_aux (P_id cname,cannot)], decl_acc @ [((lb,decl),info)]) (* normal vector patterns are fine *) | _ -> (pos + length, pat_acc @ [P_aux (p,cannot)],decl_acc) ) (* non-vector patterns aren't *) @@ -792,7 +799,30 @@ let remove_vector_concat_pat pat = let (pat,decls) = fold_pat unname_vector_concat_elements pat in - let (letbinds,decls) = List.split decls in + let decls = + let module S = Set.Make(String) in + + let roots_needed = + List.fold_right + (fun (_,(rootid,childid)) roots_needed -> + if S.mem childid roots_needed then + (* let _ = print_endline rootid in *) + S.add rootid roots_needed + else if String.length childid >= 3 && String.sub childid 0 2 = String.sub "__v" 0 2 then + roots_needed + else + S.add rootid roots_needed + ) decls S.empty in + List.filter + (fun (_,(_,childid)) -> + S.mem childid roots_needed || + String.length childid < 3 || + not (String.sub childid 0 2 = String.sub "__v" 0 2)) + decls in + + let (letbinds,decls) = + let (decls,_) = List.split decls in + List.split decls in let decls = List.fold_left (fun f g x -> f (g x)) (fun b -> b) decls in @@ -1315,7 +1345,7 @@ and n_exp (exp : 'a exp) (k : 'a exp -> 'a exp) : 'a exp = | E_internal_plet _ -> failwith "E_internal_plet should not be here yet" -let rewrite_defs_a_normalise = +let rewrite_defs_a_normalise = let rewrite_exp _ _ e = let e = remove_blocks e in n_exp_term (effectful e) e in @@ -1325,7 +1355,7 @@ let rewrite_defs_a_normalise = ; rewrite_let = rewrite_let ; rewrite_lexp = rewrite_lexp ; rewrite_fun = rewrite_fun - ; rewrite_def = rewrite_def + ; rewrite_def = (fun rws def -> let _ = reset_fresh_name_counter () in rewrite_def rws def) ; rewrite_defs = rewrite_defs_base } |
