diff options
Diffstat (limited to 'src/lem_interp/interp_inter_imp.lem')
| -rw-r--r-- | src/lem_interp/interp_inter_imp.lem | 182 |
1 files changed, 98 insertions, 84 deletions
diff --git a/src/lem_interp/interp_inter_imp.lem b/src/lem_interp/interp_inter_imp.lem index da87842d..4a9964e2 100644 --- a/src/lem_interp/interp_inter_imp.lem +++ b/src/lem_interp/interp_inter_imp.lem @@ -9,13 +9,15 @@ open import Assert_extra val intern_reg_value : register_value -> Interp.value val intern_mem_value : direction -> memory_value -> Interp.value -val extern_reg_value : maybe nat -> Interp.value -> register_value +val extern_reg_value : Interp.i_direction -> maybe nat -> Interp.value -> register_value val extern_mem_value : interp_mode -> Interp.value -> (memory_value * maybe (list reg_name)) val extern_reg : Interp.reg_form -> maybe (nat * nat) -> reg_name let make_mode eager_eval tracking_values = <| Interp.eager_eval = eager_eval; Interp.track_values = tracking_values |>;; let tracking_dependencies mode = mode.Interp.track_values +let make_eager_mode mode = <| mode with Interp.eager_eval = true |>;; +let make_default_mode _ = <| Interp.eager_eval = false; Interp.track_values = false |>;; let bitl_to_ibit = function | Bitl_zero -> (Interp.V_lit (L_aux L_zero Interp_ast.Unknown)) @@ -84,6 +86,11 @@ let intern_direction = function | D_decreasing -> Interp.IDec end +let extern_direction = function + | Interp.IInc -> D_increasing + | Interp.IDec -> D_decreasing +end + let intern_opcode direction (Opcode v) = let bits = List.concatMap (fun (Byte(bits)) -> (List.map bit_to_ibit bits)) v in let direction = intern_direction direction in @@ -91,7 +98,7 @@ let intern_opcode direction (Opcode v) = let intern_reg_value v = match v with | <| rv_bits=[b] |> -> bitl_to_ibit b - | _ -> Interp.V_vector v.rv_start (intern_direction v.rv_dir) (bitls_to_ibits v.rv_bits) + | _ -> Interp.V_vector v.rv_start_internal (intern_direction v.rv_dir) (bitls_to_ibits v.rv_bits) end let intern_mem_value direction v = @@ -104,81 +111,76 @@ let intern_ifield_value direction v = let direction = intern_direction direction in Interp.V_vector (if Interp.is_inc direction then 0 else (List.length(bits) -1)) direction bits -(*let byte_list_of_integer size num = - if (num < 0) - then failwith "signed integer given to byte_list_of_integer" - else let internal_value = (Interp_lib.to_vec_inc - (Interp.V_tuple([Interp.V_lit(L_aux (L_num (size * 8)) Interp_ast.Unknown); - Interp.V_lit(L_aux (L_num num) Interp_ast.Unknown)]))) in - let num_check = Interp_lib.to_num Interp_lib.Unsigned internal_value in - match (num_check,internal_value) with - | (Interp.V_lit (L_aux (L_num n) _), Interp.V_vector _ _ bits) -> - if num = n - then (to_bytes (from_bits bits)) - else failwith "byte_list_of_integer given an integer larger than given size" - end -*) - let num_to_bits size kind num = (* num_to_bits needed in src_power_get/trans_sail.gen - rather than reengineer the generation, we include a wrapper here *) Interp_interface.bit_list_of_integer size num - -(* - match kind with - | Bitv -> Bitvector (match (Interp_lib.to_vec_inc - (Interp.V_tuple([Interp.V_lit(L_aux (L_num (integerFromNat size)) Interp_ast.Unknown); - Interp.V_lit(L_aux (L_num num) Interp_ast.Unknown)]))) with - | Interp.V_vector _ _ bits -> from_bits bits end) true 0 - | Bytev -> Bytevector (byte_list_of_integer (integerFromNat (size/8)) num) -end - -let integer_of_byte_list bytes = - let intv = intern_value (Bytevector bytes) in - match Interp_lib.to_num Interp_lib.Unsigned intv with - | Interp.V_lit (L_aux (L_num n) _) -> n - end -*) +let extern_slice (d:direction) (start:nat) ((i,j):(nat*nat)) = + match d with + | D_increasing -> (i,j) (*This is the case the thread/concurrecny model expects, so no change needed*) + | D_decreasing -> + let slice_i = start - i in + let slice_j = (i - j) + slice_i in + (slice_i,slice_j) + end let extern_reg r slice = match (r,slice) with - | (Interp.Reg (Id_aux (Id x) _) (Just(t,_,_,_)),Nothing) -> - Reg x (Interp.reg_size r) - | (Interp.Reg (Id_aux (Id x) _) (Just(t,_,_,_)),Just(i1,i2)) -> Reg_slice x (intFromNat i1, intFromNat i2) - | (Interp.SubReg (Id_aux (Id x) _) (Interp.Reg (Id_aux (Id y) _) _) (BF_aux(BF_single i) _),Nothing) -> - let i = intFromInteger i in - Reg_field y x (i,i) - | (Interp.SubReg (Id_aux (Id x) _) (Interp.Reg (Id_aux (Id y) _) _) (BF_aux(BF_range i j) _), Nothing) -> - Reg_field y x (intFromInteger i,intFromInteger j) - | (Interp.SubReg (Id_aux (Id x) _) (Interp.Reg (Id_aux (Id y) _) _) (BF_aux(BF_range i j) _), Just(i1,j1)) -> - Reg_f_slice y x (intFromInteger i,intFromInteger j) (intFromNat i1, intFromNat j1) + | (Interp.Reg (Id_aux (Id x) _) (Just(t,_,_,_)) dir,Nothing) -> + Reg x (Interp.reg_start_pos r) (Interp.reg_size r) (extern_direction dir) + | (Interp.Reg (Id_aux (Id x) _) (Just(t,_,_,_)) dir,Just(i1,i2)) -> + let start = Interp.reg_start_pos r in + let edir = extern_direction dir in + Reg_slice x start edir (extern_slice edir start (i1, i2)) + | (Interp.SubReg (Id_aux (Id x) _) ((Interp.Reg (Id_aux (Id y) _) _ dir) as main_r) (BF_aux(BF_single i) _),Nothing) -> + let i = natFromInteger i in + let start = Interp.reg_start_pos main_r in + let edir = extern_direction dir in + Reg_field y start edir x (extern_slice edir start (i,i)) + | (Interp.SubReg (Id_aux (Id x) _) ((Interp.Reg (Id_aux (Id y) _) _ dir) as main_r) (BF_aux(BF_range i j) _), Nothing) -> + let start = Interp.reg_start_pos main_r in + let edir = extern_direction dir in + Reg_field y start edir x (extern_slice edir start (natFromInteger i,natFromInteger j)) + | (Interp.SubReg (Id_aux (Id x) _) + ((Interp.Reg (Id_aux (Id y) _) _ dir) as main_r) (BF_aux(BF_range i j) _), Just(i1,j1)) -> + let start = Interp.reg_start_pos main_r in + let edir = extern_direction dir in + Reg_f_slice y start edir x (extern_slice edir start (natFromInteger i,natFromInteger j)) + (extern_slice edir start (i1, j1)) end -let rec extern_reg_value optional_start v = match v with - | Interp.V_track v regs -> extern_reg_value optional_start v - | Interp.V_vector fst dir bits -> - <| rv_bits=(bitls_from_ibits bits); - rv_dir=(if Interp.is_inc(dir) then D_increasing else D_decreasing); - rv_start=fst|> - | Interp.V_vector_sparse fst stop inc bits default -> - extern_reg_value optional_start (Interp_lib.fill_in_sparse v) +let rec extern_reg_value dir optional_start v = + let start = match optional_start with | Nothing -> 0 | Just i -> i end in + let is_inc = Interp.is_inc(dir) in + match v with + | Interp.V_track v regs -> extern_reg_value dir optional_start v + | Interp.V_vector fst dir bits -> + let is_inc = Interp.is_inc(dir) in + let width = List.length bits in + <| rv_bits=(bitls_from_ibits bits); + rv_dir=(if is_inc then D_increasing else D_decreasing); + rv_start=if is_inc then fst else (fst +1 - width); + rv_start_internal = fst; + |> + | Interp.V_vector_sparse fst stop inc bits default -> + extern_reg_value dir optional_start (Interp_lib.fill_in_sparse v) | Interp.V_lit (L_aux L_zero _) -> - let start = match optional_start with | Nothing -> 0 | Just i -> i end in - <| rv_bits=[Bitl_zero]; rv_dir=D_increasing; rv_start=start |> + <| rv_bits=[Bitl_zero]; rv_dir= if is_inc then D_increasing else D_decreasing; + rv_start= start; rv_start_internal=start |> | Interp.V_lit (L_aux L_false _) -> - let start = match optional_start with | Nothing -> 0 | Just i -> i end in - <| rv_bits=[Bitl_zero]; rv_dir=D_increasing; rv_start=start |> + <| rv_bits=[Bitl_zero]; rv_dir=if is_inc then D_increasing else D_decreasing; + rv_start=start; rv_start_internal = start |> | Interp.V_lit (L_aux L_one _) -> - let start = match optional_start with | Nothing -> 0 | Just i -> i end in - <| rv_bits=[Bitl_one]; rv_dir=D_increasing; rv_start=start |> + <| rv_bits=[Bitl_one]; rv_dir=if is_inc then D_increasing else D_decreasing; + rv_start=start; rv_start_internal = start |> | Interp.V_lit (L_aux L_true _) -> - let start = match optional_start with | Nothing -> 0 | Just i -> i end in - <| rv_bits=[Bitl_one]; rv_dir=D_increasing; rv_start=start |> + <| rv_bits=[Bitl_one]; rv_dir=if is_inc then D_increasing else D_decreasing; + rv_start=start; rv_start_internal = start |> | Interp.V_lit (L_aux L_undef _) -> - let start = match optional_start with | Nothing -> 0 | Just i -> i end in - <| rv_bits=[Bitl_undef]; rv_dir=D_increasing; rv_start=start |> + <| rv_bits=[Bitl_undef]; rv_dir=if is_inc then D_increasing else D_decreasing; + rv_start=start; rv_start_internal = start |> | Interp.V_unknown -> - let start = match optional_start with | Nothing -> 0 | Just i -> i end in - <| rv_bits=[Bitl_unknown]; rv_dir=D_increasing; rv_start=start |> + <| rv_bits=[Bitl_unknown]; rv_dir=if is_inc then D_increasing else D_decreasing; + rv_start=start; rv_start_internal = start |> end let rec extern_mem_value mode v = match v with @@ -416,14 +418,18 @@ let rec interp_to_outcome mode context thunk = | Interp.Write_reg reg_form slice value -> let optional_start = match slice with | Just (st1,st2) -> if (st1=st2) then Just st1 else Nothing | _ -> Nothing end in - Write_reg (extern_reg reg_form slice) (extern_reg_value optional_start value) (IState next_state context) + Write_reg (extern_reg reg_form slice) + (extern_reg_value internal_direction optional_start value) (IState next_state context) | Interp.Read_mem (Id_aux (Id i) _) value slice -> match List.lookup i mem_reads with | (Just (MR read_k f)) -> let (location, length, tracking) = (f mode value) in if (List.length location) = 8 - then Read_mem read_k (Address_lifted location) length tracking - (fun v -> IState (Interp.add_answer_to_stack next_state (intern_mem_value direction v)) context) + then let address_int = match (maybe_all (List.map byte_of_byte_lifted location)) with + | Just bs -> Just (integer_of_byte_list bs) + | _ -> Nothing end in + Read_mem read_k (Address_lifted location address_int) length tracking + (fun v -> IState (Interp.add_answer_to_stack next_state (intern_mem_value direction v)) context) else Error ("Memory address on read is not 64 bits") | _ -> Error ("Memory " ^ i ^ " function with read kind not found") end @@ -433,9 +439,12 @@ let rec interp_to_outcome mode context thunk = let (location, length, tracking) = (f mode loc_val) in let (value, v_tracking) = (extern_mem_value mode write_val) in if (List.length location) = 8 - then Write_mem write_k (Address_lifted location) - length tracking value v_tracking - (fun b -> + then let address_int = match (maybe_all (List.map byte_of_byte_lifted location)) with + | Just bs -> Just (integer_of_byte_list bs) + | _ -> Nothing end in + Write_mem write_k (Address_lifted location address_int) + length tracking value v_tracking + (fun b -> match return with | Nothing -> (IState (Interp.add_answer_to_stack next_state Interp.unitv) context) | Just return_bool -> return_bool (IState next_state context) b end) @@ -472,40 +481,44 @@ let interp mode (IState interp_state context) = interp_to_outcome mode context (fun _ -> Interp.resume mode interp_state Nothing) (*TODO: Only find some sub piece matches, need to look for field/slice sub pieces*) +(*TODO immediate: this will be impacted by need to change slicing *) let rec find_reg_name reg = function | [] -> Nothing | (reg_name,v)::registers -> match (reg,reg_name) with - | (Reg i size, Reg n size2) -> if i = n && size = size2 then (Just v) else find_reg_name reg registers - | (Reg_slice i (p1,p2), Reg n _) -> - if i = n then (Just (slice_reg_value v (natFromInt p1) (natFromInt p2))) else find_reg_name reg registers - | (Reg_field i f (p1,p2), Reg n _) -> - if i = n then (Just (slice_reg_value v (natFromInt p1) (natFromInt p2))) else find_reg_name reg registers - | (Reg_slice i (p1,p2), Reg_slice n (p3,p4)) -> + | (Reg i start size dir, Reg n start2 size2 dir2) -> + if i = n && size = size2 then (Just v) else find_reg_name reg registers + | (Reg_slice i _ _ (p1,p2), Reg n _ _ _) -> + if i = n then (Just (slice_reg_value v p1 p2)) else find_reg_name reg registers + | (Reg_field i _ _ f (p1,p2), Reg n _ _ _) -> + if i = n then (Just (slice_reg_value v p1 p2)) else find_reg_name reg registers + | (Reg_slice i _ _ (p1,p2), Reg_slice n _ _ (p3,p4)) -> if i=n then if p1=p3 && p2 = p4 then (Just v) - else if p1>=p3 && p2<= p4 then (Just (slice_reg_value v (natFromInt p1) (natFromInt p2))) + else if p1>=p3 && p2<= p4 then (Just (slice_reg_value v p1 p2)) else find_reg_name reg registers else find_reg_name reg registers - | (Reg_field i f _,Reg_field n fn _) -> + | (Reg_field i _ _ f _,Reg_field n _ _ fn _) -> if i=n && f = fn then (Just v) else find_reg_name reg registers - | (Reg_f_slice i f _ (p1,p2), Reg_f_slice n fn _ (p3,p4)) -> + | (Reg_f_slice i _ _ f _ (p1,p2), Reg_f_slice n _ _ fn _ (p3,p4)) -> if i=n && f=fn && p1=p3 && p2=p3 then (Just v) else find_reg_name reg registers | _ -> find_reg_name reg registers end end +(*Update slice potentially here*) let reg_size = function - | Reg i size -> size - | Reg_slice i (p1,p2) -> natFromInt (if p1 < p2 then (p2-p1 +1) else (p1-p2 +1)) - | Reg_field i f (p1,p2) -> natFromInt (if p1 < p2 then (p2-p1 +1) else (p1-p2 +1)) - | Reg_f_slice i f _ (p1,p2) -> natFromInt (if p1 < p2 then p2-p1 +1 else p1-p2+1) + | Reg i _ size _ -> size + | Reg_slice i _ _ (p1,p2) -> if p1 < p2 then (p2-p1 +1) else (p1-p2 +1) + | Reg_field i _ _ f (p1,p2) -> if p1 < p2 then (p2-p1 +1) else (p1-p2 +1) + | Reg_f_slice i _ _ f _ (p1,p2) -> if p1 < p2 then p2-p1 +1 else p1-p2+1 end let rec ie_loop mode register_values (IState interp_state context) = let (Context _ direction externs reads writes barriers) = context in let unknown_reg size = <| rv_bits = (List.replicate size Bitl_unknown); - rv_start = (if direction = D_increasing then 0 else (size-1)); + rv_start = 0; + rv_start_internal = (if direction = D_increasing then 0 else (size-1)); rv_dir = direction |> in let unknown_mem size = List.replicate size (Byte_lifted (List.replicate 8 Bitl_unknown)) in match interp mode (IState interp_state context) with @@ -538,7 +551,8 @@ let rec rr_ie_loop mode i_state = let (IState _ (Context _ direction _ _ _ _)) = i_state in let unknown_reg size = <| rv_bits = (List.replicate size Bitl_unknown); - rv_start = (if direction=D_increasing then 0 else (size-1)); + rv_start = 0; + rv_start_internal = (if direction=D_increasing then 0 else (size-1)); rv_dir = direction |> in let unknown_mem size = List.replicate size (Byte_lifted (List.replicate 8 Bitl_unknown)) in match (interp mode i_state) with |
