diff options
Diffstat (limited to 'src/lem_interp/interp_inter_imp.lem')
| -rw-r--r-- | src/lem_interp/interp_inter_imp.lem | 133 |
1 files changed, 107 insertions, 26 deletions
diff --git a/src/lem_interp/interp_inter_imp.lem b/src/lem_interp/interp_inter_imp.lem index 14a286cb..19d41f8c 100644 --- a/src/lem_interp/interp_inter_imp.lem +++ b/src/lem_interp/interp_inter_imp.lem @@ -1,5 +1,6 @@ import Interp import Interp_lib +import Instruction_extractor open import Interp_ast open import Interp_interface open import Pervasives @@ -27,7 +28,7 @@ end let intern_value v = match v with | Bitvector bs inc fst -> Interp.V_vector fst inc (to_bits bs) - | Bytevector bys inc fst -> Interp.V_vector fst inc + | Bytevector bys -> Interp.V_vector 0 true (to_bits (List.reverse (List.concat (List.map (fun n -> boolListFrombitSeq 8 (bitSeqFromInteger (Just 8) (integerFromNat n))) bys)))) | Unknown -> Interp.V_unknown @@ -40,18 +41,33 @@ let extern_reg r slice = match (r,slice) with | (Interp.SubReg (Id_aux (Id x) _) (Interp.Reg (Id_aux (Id y) _) _) (BF_aux(BF_single i) _),Nothing) -> Reg_field x y (i,i) end -let extern_value mode for_mem v = match v with +let rec extern_value mode for_mem v = match v with + | Interp.V_track v regs -> + let (external_v,_) = extern_value mode for_mem v in + (external_v, + if (for_mem && mode.Interp.track_values) + then (Just (List.map (fun r -> extern_reg r Nothing) regs)) + else Nothing) | Interp.V_vector fst inc bits -> if for_mem - then (Bytevector (List.reverse (to_bytes (from_bits bits))) inc fst, Nothing) + then (Bytevector (List.reverse (to_bytes (from_bits bits))), Nothing) else (Bitvector (from_bits bits) inc fst, Nothing) - | Interp.V_track (Interp.V_vector fst inc bits) regs -> + | Interp.V_lit (L_aux L_zero _) -> if for_mem - then (Bytevector (List.reverse (to_bytes (from_bits bits))) inc fst, - if (mode.Interp.track_values) - then (Just (List.map (fun r -> extern_reg r Nothing) regs)) - else Nothing) - else (Bitvector (from_bits bits) inc fst, Nothing) + then (Bytevector [0],Nothing) + else (Bitvector [false] true 0, Nothing) + | Interp.V_lit (L_aux L_false _) -> + if for_mem + then (Bytevector [0],Nothing) + else (Bitvector [false] true 0, Nothing) + | Interp.V_lit (L_aux L_one _) -> + if for_mem + then (Bytevector [1],Nothing) + else (Bitvector [true] true 0, Nothing) + | Interp.V_lit (L_aux L_true _) -> + if for_mem + then (Bytevector [1],Nothing) + else (Bitvector [true] true 0, Nothing) | _ -> (Unknown,Nothing) end @@ -81,17 +97,55 @@ let memory_functions = match length with | Interp.V_lit (L_aux (L_num len) _) -> let (v,regs) = extern_value mode true location in - (v,len,regs) end end))); + (v,len,regs) + | Interp.V_track (Interp.V_lit (L_aux (L_num len) _)) size_regs -> + let (v,loc_regs) = extern_value mode true location in + match loc_regs with + | Nothing -> (v,len,Just (List.map (fun r -> extern_reg r Nothing) size_regs)) + | Just loc_regs -> (v,len,Just (loc_regs++(List.map (fun r -> extern_reg r Nothing) size_regs))) + end end end))); + ("MEMr_reserve", (Just(Read_reserve),Nothing, + (fun mode v -> match v with + | Interp.V_tuple [location;length] -> + match length with + | Interp.V_lit (L_aux (L_num len) _) -> + let (v,regs) = extern_value mode true location in + (v,len,regs) + | Interp.V_track (Interp.V_lit (L_aux (L_num len) _)) size_regs -> + let (v,loc_regs) = extern_value mode true location in + match loc_regs with + | Nothing -> (v,len,Just (List.map (fun r -> extern_reg r Nothing) size_regs)) + | Just loc_regs -> (v,len,Just (loc_regs++(List.map (fun r -> extern_reg r Nothing) size_regs))) + end end end))); ("MEMw", (Nothing, Just(Write_plain), (fun mode v -> match v with | Interp.V_tuple [location;length] -> match length with | Interp.V_lit (L_aux (L_num len) _) -> let (v,regs) = extern_value mode true location in - (v,len,regs) end end))); + (v,len,regs) + | Interp.V_track (Interp.V_lit (L_aux (L_num len) _)) size_regs -> + let (v,loc_regs) = extern_value mode true location in + match loc_regs with + | Nothing -> (v,len,Just (List.map (fun r -> extern_reg r Nothing) size_regs)) + | Just loc_regs -> (v,len,Just (loc_regs++(List.map (fun r -> extern_reg r Nothing) size_regs))) + end end end))); + ("MEMw_conditional", (Nothing, Just(Write_conditional), + (fun mode v -> match v with + | Interp.V_tuple [location;length] -> + match length with + | Interp.V_lit (L_aux (L_num len) _) -> + let (v,regs) = extern_value mode true location in + (v,len,regs) + | Interp.V_track (Interp.V_lit (L_aux (L_num len) _)) size_regs -> + let (v,loc_regs) = extern_value mode true location in + match loc_regs with + | Nothing -> (v,len,Just (List.map (fun r -> extern_reg r Nothing) size_regs)) + | Just loc_regs -> (v,len,Just (loc_regs++(List.map (fun r -> extern_reg r Nothing) size_regs))) + end end end))); ] -let rec interp_to_value_helper thunk = +let rec interp_to_value_helper arg instr thunk = match thunk() with | Interp.Value value -> (Just value,Nothing) | Interp.Error l msg -> (Nothing, Just (Internal_error msg)) @@ -99,20 +153,36 @@ let rec interp_to_value_helper thunk = match List.lookup i external_functions with | Nothing -> (Nothing, Just (Internal_error ("External function not available " ^ i))) | Just f -> - interp_to_value_helper (fun _ -> Interp.resume (make_mode true false) stack (Just (f value))) + interp_to_value_helper arg instr (fun _ -> Interp.resume (make_mode true false) stack (Just (f value))) end | Interp.Action (Interp.Exit (E_aux e _)) _ -> match e with - | E_id (Id_aux (Id "unsupported_instruction") _) -> (Nothing,Just Unsupported_instruction_error) - | E_id (Id_aux (Id "no_matching_pattern") _) -> (Nothing,Just Not_an_instruction_error) + | E_id (Id_aux (Id "unsupported_instruction") _) -> (Nothing,Just (Unsupported_instruction_error instr)) + | E_id (Id_aux (Id "no_matching_pattern") _) -> (Nothing,Just (Not_an_instruction_error arg)) end | _ -> (Nothing, Just (Internal_error "Memory or register requested in decode")) end +let rec find_instruction i = function + | [] -> Nothing + | Skipped::instrs -> find_instruction i instrs + | ((Instruction_extractor.Instr_form name parms effects) as instr)::instrs -> + if i = name + then Just instr + else find_instruction i instrs +end + +let migrate_typ = function + | Instruction_extractor.IBit -> Bit + | Instruction_extractor.IBitvector len -> Bvector len + | Instruction_extractor.IOther -> Other +end + let decode_to_istate top_level value = let mode = make_mode true false in let (arg,_) = Interp.to_exp mode Interp.eenv (intern_value value) in - let (instr_decoded,error) = interp_to_value_helper + let (Interp.Env _ instructions _ _ _ _ _) = top_level in + let (instr_decoded,error) = interp_to_value_helper value ("",[],[]) (fun _ -> Interp.resume (make_mode true false) (Interp.Thunk_frame @@ -120,8 +190,18 @@ let decode_to_istate top_level value = top_level Interp.eenv Interp.emem Interp.Top) Nothing) in match (instr_decoded,error) with | (Just instr, _) -> + let instr_external = match instr with + | Interp.V_ctor (Id_aux (Id i) _) _ parm -> + match (find_instruction i instructions) with + | Just(Instruction_extractor.Instr_form name parms effects) -> + match (parm,parms) with + | (Interp.V_lit (L_aux L_unit _),[]) -> (name, [], effects) + | (value,[(p_name,ie_typ)]) -> (name, [(p_name,(migrate_typ ie_typ),fst(extern_value mode false value))], effects) + | (Interp.V_tuple vals,parms) -> + (name, (Interp.map2 (fun value (p_name,ie_typ) -> (p_name,(migrate_typ ie_typ),fst(extern_value mode false value))) vals parms), effects) + end end end in let (arg,_) = Interp.to_exp mode Interp.eenv instr in - let (instr_decoded,error) = interp_to_value_helper + let (instr_decoded,error) = interp_to_value_helper value instr_external (fun _ -> Interp.resume (make_mode true false) (Interp.Thunk_frame @@ -130,12 +210,13 @@ let decode_to_istate top_level value = match (instr_decoded,error) with | (Just instr,_) -> let (arg,_) = Interp.to_exp mode Interp.eenv instr in - Instr (Interp.Thunk_frame + Instr instr_external + (Interp.Thunk_frame (E_aux (E_app (Id_aux (Id "execute") Interp_ast.Unknown) [arg]) (Interp_ast.Unknown,Nothing)) top_level Interp.eenv Interp.emem Interp.Top) - | (Nothing, Just err) -> err + | (Nothing, Just err) -> Decode_error err end - | (Nothing, Just err) -> err + | (Nothing, Just err) -> Decode_error err end let rec interp_to_outcome mode thunk = @@ -163,8 +244,8 @@ let rec interp_to_outcome mode thunk = match List.lookup i memory_functions with | (Just (_,Just write_k,f)) -> let (location, length, tracking) = (f mode loc_val) in - let (value, val_tracking) = (extern_value mode true write_val) in - Write_mem write_k location length tracking value val_tracking (fun b -> next_state) + let (value, v_tracking) = (extern_value mode true write_val) in + Write_mem write_k location length tracking value v_tracking (fun b -> next_state) | _ -> Error ("Memory " ^ i ^ " function with write kind not found") end | Interp.Barrier (Id_aux (Id i) _) lval -> @@ -202,8 +283,8 @@ let rec ie_loop mode i_state = (E_write_reg reg value)::(ie_loop mode i_state) | Read_mem read_k loc length tracking i_state_fun -> (E_read_mem read_k loc length tracking)::(ie_loop mode (i_state_fun Unknown)) - | Write_mem write_k loc length l_track value v_track i_state_fun -> - (E_write_mem write_k loc length l_track value v_track)::(ie_loop mode (i_state_fun true)) + | Write_mem write_k loc length tracking value v_tracking i_state_fun -> + (E_write_mem write_k loc length tracking value v_tracking)::(ie_loop mode (i_state_fun true)) | Internal _ _ next -> (ie_loop mode next) end ;; @@ -222,9 +303,9 @@ let rec rr_ie_loop mode i_state = | Read_mem read_k loc length tracking i_state_fun -> let (events,outcome) = (rr_ie_loop mode (i_state_fun Unknown)) in (((E_read_mem read_k loc length tracking)::events),outcome) - | Write_mem write_k loc length l_track value v_track i_state_fun -> + | Write_mem write_k loc length tracking value v_tracking i_state_fun -> let (events,outcome) = (rr_ie_loop mode (i_state_fun true)) in - (((E_write_mem write_k loc length l_track value v_track)::events),outcome) + (((E_write_mem write_k loc length tracking value v_tracking)::events),outcome) | Internal _ _ next -> (rr_ie_loop mode next) end ;; |
