diff options
| author | Shaked Flur | 2017-05-24 16:19:27 +0100 |
|---|---|---|
| committer | Shaked Flur | 2017-05-24 16:19:27 +0100 |
| commit | 9cffd54c6170f8a5cdcc6e54cb9077b62bf6a284 (patch) | |
| tree | 3c94e563409844e8685714cbe331748c9ddd0fe6 /src | |
| parent | fffcaaa390eaf03db689d0f108cc00653a41885d (diff) | |
added the exmem effect for AArch64 store-exclusive
Diffstat (limited to 'src')
| -rw-r--r-- | src/ast.ml | 1 | ||||
| -rw-r--r-- | src/gen_lib/prompt.lem | 6 | ||||
| -rw-r--r-- | src/gen_lib/state.lem | 30 | ||||
| -rw-r--r-- | src/initial_check.ml | 1 | ||||
| -rw-r--r-- | src/lem_interp/interp.lem | 3 | ||||
| -rw-r--r-- | src/lem_interp/interp_ast.lem | 1 | ||||
| -rw-r--r-- | src/lem_interp/interp_inter_imp.lem | 45 | ||||
| -rw-r--r-- | src/lem_interp/interp_interface.lem | 9 | ||||
| -rw-r--r-- | src/lem_interp/interp_utilities.lem | 2 | ||||
| -rw-r--r-- | src/lem_interp/pretty_interp.ml | 1 | ||||
| -rw-r--r-- | src/lem_interp/printing_functions.ml | 2 | ||||
| -rw-r--r-- | src/lem_interp/run_interp_model.ml | 4 | ||||
| -rw-r--r-- | src/lem_interp/sail_impl_base.lem | 5 | ||||
| -rw-r--r-- | src/lexer.mll | 1 | ||||
| -rw-r--r-- | src/parse_ast.ml | 1 | ||||
| -rw-r--r-- | src/parser.mly | 4 | ||||
| -rw-r--r-- | src/pretty_print_common.ml | 1 | ||||
| -rw-r--r-- | src/pretty_print_lem.ml | 4 | ||||
| -rw-r--r-- | src/pretty_print_lem_ast.ml | 1 | ||||
| -rw-r--r-- | src/pretty_print_t_ascii.ml | 1 | ||||
| -rw-r--r-- | src/type_internal.ml | 5 | ||||
| -rw-r--r-- | src/type_internal.mli | 1 |
22 files changed, 88 insertions, 41 deletions
@@ -119,6 +119,7 @@ base_effect_aux = (* effect *) | BE_rmem (* read memory *) | BE_wmem (* write memory *) | BE_eamem (* signal effective address for writing memory *) + | BE_exmem (* determine if a store-exclusive (ARM) is going to succeed *) | BE_wmv (* write memory, sending only value *) | BE_barr (* memory barrier *) | BE_depend (* dynamic footprint *) diff --git a/src/gen_lib/prompt.lem b/src/gen_lib/prompt.lem index dd97541f..426b0811 100644 --- a/src/gen_lib/prompt.lem +++ b/src/gen_lib/prompt.lem @@ -11,6 +11,7 @@ let rec bind m f = match m with | Read_mem descr k -> Read_mem descr (fun v -> let (o,opt) = k v in (bind o f,opt)) | Read_reg descr k -> Read_reg descr (fun v -> let (o,opt) = k v in (bind o f,opt)) | Write_memv descr k -> Write_memv descr (fun v -> let (o,opt) = k v in (bind o f,opt)) + | Excl_res k -> Excl_res (fun v -> let (o,opt) = k v in (bind o f,opt)) | Write_ea descr o_s -> Write_ea descr (let (o,opt) = o_s in (bind o f,opt)) | Barrier descr o_s -> Barrier descr (let (o,opt) = o_s in (bind o f,opt)) | Footprint o_s -> Footprint (let (o,opt) = o_s in (bind o f,opt)) @@ -40,6 +41,11 @@ let read_mem dir rk addr sz = (Done bitv,Nothing) in Read_mem (rk,addr,sz) k +val excl_result : unit -> M bool +let excl_result () = + let k successful = (return successful,Nothing) in + Excl_res k + val write_mem_ea : write_kind -> vector bitU -> integer -> M unit let write_mem_ea wk addr sz = let addr = address_lifted_of_bitv addr in diff --git a/src/gen_lib/state.lem b/src/gen_lib/state.lem index 0dfd10d7..ddd30eda 100644 --- a/src/gen_lib/state.lem +++ b/src/gen_lib/state.lem @@ -66,7 +66,11 @@ let read_mem dir read_kind addr sz state = then [(Left value, <| state with last_exclusive_operation_was_load = true |>)] else [(Left value, state)] - +val excl_result : unit -> M bool +let excl_result () state = + let success = + (Left true, <| state with last_exclusive_operation_was_load = false |>) in + (Left false, state) :: if state.last_exclusive_operation_was_load then [success] else [] val write_mem_ea : write_kind -> vector bitU -> integer -> M unit let write_mem_ea write_kind addr sz state = @@ -83,29 +87,7 @@ let write_mem_val v state = let addresses_with_value = List.zip addrs v in let memstate = List.foldl (fun mem (addr,v) -> Map.insert addr v mem) state.memstate addresses_with_value in - - let is_exclusive = match write_kind with - | Sail_impl_base.Write_plain -> false - | Sail_impl_base.Write_tag -> failwith "Write_tag not implemented" - | Sail_impl_base.Write_tag_conditional -> failwith "Write_tag_conditional not implemented" - | Sail_impl_base.Write_conditional -> true - | Sail_impl_base.Write_release -> false - | Sail_impl_base.Write_exclusive -> true - | Sail_impl_base.Write_exclusive_release -> true - end in - - if is_exclusive - then - let success = - (Left true, <| state with memstate = memstate; - last_exclusive_operation_was_load = false |>) in - let failure = - (Left false, <| state with last_exclusive_operation_was_load = false |>) in - if state.last_exclusive_operation_was_load - then [failure;success] - else [failure] - else [(Left true, <| state with memstate = memstate |>)] - + [(Left true, <| state with memstate = memstate |>)] val read_reg : register -> M (vector bitU) diff --git a/src/initial_check.ml b/src/initial_check.ml index 82cc6b7c..a0d4d312 100644 --- a/src/initial_check.ml +++ b/src/initial_check.ml @@ -280,6 +280,7 @@ and to_ast_effects (k_env : kind Envmap.t) (e : Parse_ast.atyp) : Ast.effect = | Parse_ast.BE_wmem -> BE_wmem | Parse_ast.BE_wmv -> BE_wmv | Parse_ast.BE_eamem -> BE_eamem + | Parse_ast.BE_exmem -> BE_exmem | Parse_ast.BE_depend -> BE_depend | Parse_ast.BE_undef -> BE_undef | Parse_ast.BE_unspec -> BE_unspec diff --git a/src/lem_interp/interp.lem b/src/lem_interp/interp.lem index 24f624e3..4de1e869 100644 --- a/src/lem_interp/interp.lem +++ b/src/lem_interp/interp.lem @@ -359,6 +359,7 @@ type action = | Write_mem of id * value * maybe (nat * nat) * value | Write_ea of id * value | Write_memv of id * value * value + | Excl_res of id * value | Barrier of id * value | Footprint of id * value | Nondet of list (exp tannot) * tag @@ -2242,6 +2243,8 @@ and interp_main mode t_level l_env l_mem (E_aux exp (l,annot)) = mk_hole_frame (Write_mem (id_of_string name_ext) v Nothing wv) else if has_eamem_effect effects then mk_thunk_frame (Write_ea (id_of_string name_ext) v) + else if has_exmem_effect effects + then mk_thunk_frame (Excl_res (id_of_string name_ext) v) else if has_wmv_effect effects then let (wv,v) = match v with diff --git a/src/lem_interp/interp_ast.lem b/src/lem_interp/interp_ast.lem index 64fb14b2..6091e8b1 100644 --- a/src/lem_interp/interp_ast.lem +++ b/src/lem_interp/interp_ast.lem @@ -121,6 +121,7 @@ type base_effect_aux = (* effect *) | BE_rmem (* read memory *) | BE_wmem (* write memory *) | BE_eamem (* signal effective address for writing memory *) + | BE_exmem (* determine if a store-exclusive (ARM) is going to succeed *) | BE_wmv (* write memory, sending only value *) | BE_barr (* memory barrier *) | BE_depend (* dynamic footprint *) diff --git a/src/lem_interp/interp_inter_imp.lem b/src/lem_interp/interp_inter_imp.lem index 72bf0bcc..3e71ba37 100644 --- a/src/lem_interp/interp_inter_imp.lem +++ b/src/lem_interp/interp_inter_imp.lem @@ -430,6 +430,8 @@ let rec interp_to_value_helper arg ivh_mode err_str instr direction registers ev (Ivh_error (Interp_interface.Internal_error ("Write memory request in a " ^ errk_str)), events_out) | (Interp.Action (Interp.Write_ea _ _) _,_,_) -> (Ivh_error (Interp_interface.Internal_error ("Write ea request in a " ^ errk_str)), events_out) + | (Interp.Action (Interp.Excl_res _ _) _,_,_) -> + (Ivh_error (Interp_interface.Internal_error ("Exclusive result request in a " ^ errk_str)), events_out) | (Interp.Action (Interp.Write_memv _ _ _) _,_,_) -> (Ivh_error (Interp_interface.Internal_error ("Write memory value request in a " ^ errk_str)), events_out) | _ -> (Ivh_error (Interp_interface.Internal_error ("Non expected action in a " ^ errk_str)), events_out) @@ -443,19 +445,19 @@ let call_external_functions direction outcome = | Just f -> Just (f value) end | _ -> Nothing end -let build_context defs reads writes write_eas write_vals barriers externs = +let build_context defs reads writes write_eas write_vals barriers excl_res externs = (*TODO add externs to to_top_env*) match Interp.to_top_env call_external_functions defs with | (_,((Interp.Env _ _ dir _ _ _ _ _) as context)) -> Context context (if Interp.is_inc(dir) then D_increasing else D_decreasing) - reads writes write_eas write_vals barriers externs end + reads writes write_eas write_vals barriers excl_res externs end let translate_address top_level end_flag thunk_name registers address = let (Address bytes i) = address in let mode = make_mode true false in let int_mode = mode.internal_mode in - let (Context top_env direction _ _ _ _ _ _) = top_level in + let (Context top_env direction _ _ _ _ _ _ _) = top_level in let intern_val = intern_mem_value mode direction (memory_value_of_address end_flag address) in let val_str = Interp.string_of_value intern_val in let (arg,_) = Interp.to_exp int_mode Interp.eenv intern_val in @@ -499,7 +501,7 @@ let intern_instruction direction (name,parms) = let instruction_analysis top_level end_flag thunk_name regn_to_reg_details registers instruction = let mode = make_mode true false in let int_mode = mode.internal_mode in - let (Context top_env direction _ _ _ _ _ _) = top_level in + let (Context top_env direction _ _ _ _ _ _ _) = top_level in let intern_val = intern_instruction direction instruction in let val_str = Interp.string_of_value intern_val in let (arg,_) = Interp.to_exp int_mode Interp.eenv intern_val in @@ -641,7 +643,7 @@ end let interp_value_to_instr_external top_level instr = - let (Context (Interp.Env _ instructions _ _ _ _ _ _) _ _ _ _ _ _ _) = top_level in + let (Context (Interp.Env _ instructions _ _ _ _ _ _) _ _ _ _ _ _ _ _) = top_level in match instr with | Interp.V_ctor (Id_aux (Id i) _) _ _ parm -> match (find_instruction i instructions) with @@ -666,7 +668,7 @@ let interp_value_to_instr_external top_level instr = let decode_to_instruction top_level registers value : instruction_or_decode_error = let mode = make_interpreter_mode true false in - let (Context ((Interp.Env _ instructions _ _ _ _ _ _) as top_env) direction _ _ _ _ _ _) = top_level in + let (Context ((Interp.Env _ instructions _ _ _ _ _ _) as top_env) direction _ _ _ _ _ _ _) = top_level in let intern_val = intern_opcode direction value in let val_str = Interp.string_of_value intern_val in let (arg,_) = Interp.to_exp mode Interp.eenv intern_val in @@ -703,7 +705,7 @@ end let decode_to_istate (top_level:context) registers (value:opcode) : i_state_or_error = - let (Context top_env _ _ _ _ _ _ _) = top_level in + let (Context top_env _ _ _ _ _ _ _ _) = top_level in match decode_to_instruction top_level registers value with | IDE_instr instr instrv -> let mode = make_interpreter_mode true false in @@ -718,7 +720,7 @@ let decode_to_istate (top_level:context) registers (value:opcode) : i_state_or_e let instr_external_to_interp_value top_level instr = - let (Context _ direction _ _ _ _ _ _) = top_level in + let (Context _ direction _ _ _ _ _ _ _) = top_level in let (name,parms) = instr in let get_value (_,typ,v) = @@ -745,7 +747,7 @@ let instr_external_to_interp_value top_level instr = val instruction_to_istate : context -> instruction -> instruction_state let instruction_to_istate (top_level:context) (((name, parms) as instr):instruction) : instruction_state = let mode = make_interpreter_mode true false in - let (Context top_env _ _ _ _ _ _ _) = top_level in + let (Context top_env _ _ _ _ _ _ _ _) = top_level in let ast_node = fst (Interp.to_exp mode Interp.eenv (instr_external_to_interp_value top_level instr)) in (IState (Interp.Thunk_frame @@ -755,7 +757,7 @@ let instruction_to_istate (top_level:context) (((name, parms) as instr):instruct top_level) let rec interp_to_outcome mode context thunk = - let (Context _ direction mem_reads mem_writes mem_write_eas mem_write_vals barriers spec_externs) = context in + let (Context _ direction mem_reads mem_writes mem_write_eas mem_write_vals barriers excl_res spec_externs) = context in let internal_direction = if direction = D_increasing then Interp.IInc else Interp.IDec in match thunk () with | (Interp.Value _,lm,le) -> (Done,lm) @@ -813,7 +815,15 @@ let rec interp_to_outcome mode context thunk = Write_ea write_k (Address_lifted location address_int) length tracking (IState next_state context) else Error "Memory address for write is not 64 bits" | _ -> Error ("Memory function " ^ i ^ " to signal impending write, not found") end, lm) - | Interp.Write_memv (Id_aux (Id i) _) address_val write_val -> + | Interp.Excl_res (Id_aux (Id i) _) loc_val -> + (match excl_res with + | (Just (i', ER return)) -> + Excl_res (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) + | _ -> Error ("Exclusive result function, not provided") end, lm) + | Interp.Write_memv (Id_aux (Id i) _) address_val write_val -> (match List.lookup i mem_write_vals with | (Just (MV parmf return)) -> let (value, v_tracking) = @@ -899,7 +909,7 @@ end (*ie_loop returns a tuple of event list, and a tuple ofinternal interpreter memory, bool to indicate normal or exceptional termination*) let rec ie_loop mode register_values (IState interp_state context) = - let (Context _ direction externs reads writes write_eas write_vals barriers) = context in + let (Context _ direction externs reads writes write_eas write_vals barriers excl_res) = context in let unknown_reg size = <| rv_bits = (List.replicate size Bitl_unknown); rv_start = 0; @@ -935,6 +945,11 @@ let rec ie_loop mode register_values (IState interp_state context) = | (Write_ea write_k loc length tracking i_state, _) -> let (events,analysis_data) = ie_loop mode register_values i_state in ((E_write_ea write_k loc length tracking)::events,analysis_data) + | (Excl_res i_state_fun, _) -> + let (events,analysis_data) = ie_loop mode register_values (i_state_fun true) in + let (events',analysis_data) = ie_loop mode register_values (i_state_fun false) in + (*TODO: consider if lm and lm should be merged*) + (E_excl_res :: (events ++ events'), analysis_data) | (Write_memv opt_address value tracking i_state_fun, _) -> let (events,analysis_data) = ie_loop mode register_values (i_state_fun true) in let (events',analysis_data) = ie_loop mode register_values (i_state_fun false) in @@ -995,6 +1010,8 @@ let rec outcome_to_outcome pp_instruction_state mode = failwith "Write_mem not supported anymore" | Interp_interface.Write_ea wk addr size _ state -> Sail_impl_base.Write_ea (wk,addr,size) (state_to_outcome_s mode state) + | Interp_interface.Excl_res k -> + Sail_impl_base.Excl_res (fun v -> state_to_outcome_s mode (k v)) | Interp_interface.Write_memv _ mv _ k -> Sail_impl_base.Write_memv mv (fun v -> state_to_outcome_s mode (k v)) | Interp_interface.Barrier bk state -> @@ -1078,6 +1095,7 @@ let instruction_kind_of_event : event -> maybe instruction_kind = function | E_read_mem rk _ _ _ -> Just (IK_mem_read rk) | E_write_mem wk _ _ _ _ _ -> Just (IK_mem_write wk) | E_write_ea wk _ _ _ -> Just (IK_mem_write wk) + | E_excl_res -> Nothing | E_write_memv _ _ _ -> Nothing | E_barrier bk -> Just (IK_barrier bk) | E_footprint -> Nothing @@ -1093,6 +1111,7 @@ let regs_in_of_event : event -> list reg_name = function | E_read_mem _ _ _ _ -> [] | E_write_mem _ _ _ _ _ _ -> [] | E_write_ea _ _ _ _ -> [] + | E_excl_res -> [] | E_write_memv _ _ _ -> [] | E_barrier _ -> [] | E_footprint -> [] @@ -1106,6 +1125,7 @@ let regs_out_of_event : event -> list reg_name = function | E_read_mem _ _ _ _ -> [] | E_write_mem _ _ _ _ _ _ -> [] | E_write_ea _ _ _ _ -> [] + | E_excl_res -> [] | E_write_memv _ _ _ -> [] | E_barrier _ -> [] | E_footprint -> [] @@ -1123,6 +1143,7 @@ let regs_feeding_memory_access_address_of_event : event -> list reg_name = funct | E_write_mem _ _ _ None _ _ -> [] | E_write_ea wk _ _ (Just rs) -> rs | E_write_ea wk _ _ None -> [] + | E_excl_res -> [] | E_write_memv _ _ _ -> [] | E_barrier bk -> [] | E_footprint -> [] diff --git a/src/lem_interp/interp_interface.lem b/src/lem_interp/interp_interface.lem index 3ef6abb8..77572de9 100644 --- a/src/lem_interp/interp_interface.lem +++ b/src/lem_interp/interp_interface.lem @@ -185,11 +185,13 @@ type memory_write = MW of write_kind * memory_parameter_transformer * (maybe (in and memory_writes = list (string * memory_write) and memory_write_val = MV of optional_memory_transformer * (maybe (instruction_state -> bool -> instruction_state)) and memory_write_vals = list (string * memory_write_val) +and excl_res_t = ER of maybe (instruction_state -> bool -> instruction_state) +and excl_res = maybe (string * excl_res_t) (* Definition information needed to run an instruction *) and context = Context of Interp.top_level * direction * - memory_reads * memory_writes * memory_write_eas * memory_write_vals * barriers * external_functions + memory_reads * memory_writes * memory_write_eas * memory_write_vals * barriers * excl_res * external_functions (* An instruction in flight *) and instruction_state = IState of interpreter_state * context @@ -204,6 +206,9 @@ type outcome = | Write_mem of write_kind * address_lifted * nat * maybe (list reg_name) * memory_value * maybe (list reg_name) * (bool -> instruction_state) +(* Request the result of store-exclusive *) +| Excl_res of (bool -> instruction_state) + (* Tell the system a write is imminent, at address lifted tainted by register list, of size nat *) | Write_ea of write_kind * address_lifted * nat * maybe (list reg_name) * instruction_state @@ -248,7 +253,7 @@ type outcome = (* Functions to build up the initial state for interpretation *) -val build_context : specification -> memory_reads -> memory_writes -> memory_write_eas -> memory_write_vals -> barriers -> external_functions -> context +val build_context : specification -> memory_reads -> memory_writes -> memory_write_eas -> memory_write_vals -> barriers -> excl_res -> external_functions -> context val initial_instruction_state : context -> string -> list register_value -> instruction_state (* string is a function name, list of value are the parameters to that function *) diff --git a/src/lem_interp/interp_utilities.lem b/src/lem_interp/interp_utilities.lem index 86042d61..2c338ff7 100644 --- a/src/lem_interp/interp_utilities.lem +++ b/src/lem_interp/interp_utilities.lem @@ -119,6 +119,7 @@ let rec has_effect which efcts = | (BE_wmem,BE_wmem) -> true | (BE_wmv,BE_wmv) -> true | (BE_eamem,BE_eamem) -> true + | (BE_exmem,BE_exmem) -> true | (BE_barr,BE_barr) -> true | (BE_undef,BE_undef) -> true | (BE_unspec,BE_unspec) -> true @@ -131,6 +132,7 @@ let has_rmem_effect = has_effect BE_rmem let has_barr_effect = has_effect BE_barr let has_wmem_effect = has_effect BE_wmem let has_eamem_effect = has_effect BE_eamem +let has_exmem_effect = has_effect BE_exmem let has_wmv_effect = has_effect BE_wmv let has_depend_effect = has_effect BE_depend diff --git a/src/lem_interp/pretty_interp.ml b/src/lem_interp/pretty_interp.ml index 7d182258..855658b4 100644 --- a/src/lem_interp/pretty_interp.ml +++ b/src/lem_interp/pretty_interp.ml @@ -125,6 +125,7 @@ let doc_effect (BE_aux (e,_)) = | BE_wmem -> "wmem" | BE_wmv -> "wmv" | BE_eamem -> "eamem" + | BE_exmem -> "exmem" | BE_barr -> "barr" | BE_depend -> "depend" | BE_undef -> "undef" diff --git a/src/lem_interp/printing_functions.ml b/src/lem_interp/printing_functions.ml index 4922a59a..01c828dd 100644 --- a/src/lem_interp/printing_functions.ml +++ b/src/lem_interp/printing_functions.ml @@ -434,6 +434,8 @@ let rec format_events = function " Write_ea at " ^ (memory_value_to_string E_big_endian location) ^ ", based on registers " ^ format_tracking tracking ^ " across " ^ (string_of_int length) ^ " bytes\n" ^ (format_events events) + | E_excl_res::events -> + " Excl_res\n" ^ (format_events events) | (E_write_memv(_, value, v_tracking))::events -> " Write_memv of " ^ (memory_value_to_string E_big_endian value) ^ ", based on registers " ^ format_tracking v_tracking ^ "\n" ^ diff --git a/src/lem_interp/run_interp_model.ml b/src/lem_interp/run_interp_model.ml index 8be5354a..600699ec 100644 --- a/src/lem_interp/run_interp_model.ml +++ b/src/lem_interp/run_interp_model.ml @@ -377,6 +377,10 @@ let run | Write_ea1(_,(Address_lifted(location,_)), size,_,next) -> show "write_announce" (memory_value_to_string !default_endian location) left ((string_of_int size) ^ " bytes"); (step next, env, next) + | Excl_res1(next_thunk) -> + show "exclusive_result" "" "" ""; + let next = next_thunk true in + (step next,env',next) | Barrier1(bkind,next) -> show "mem_barrier" "" "" ""; (step next, env, next) diff --git a/src/lem_interp/sail_impl_base.lem b/src/lem_interp/sail_impl_base.lem index 02d53896..fad04a51 100644 --- a/src/lem_interp/sail_impl_base.lem +++ b/src/lem_interp/sail_impl_base.lem @@ -780,6 +780,7 @@ type event = | E_read_mem of read_kind * address_lifted * nat * maybe (list reg_name) | E_write_mem of write_kind * address_lifted * nat * maybe (list reg_name) * memory_value * maybe (list reg_name) | E_write_ea of write_kind * address_lifted * nat * maybe (list reg_name) +| E_excl_res | E_write_memv of maybe address_lifted * memory_value * maybe (list reg_name) | E_barrier of barrier_kind | E_footprint @@ -797,6 +798,7 @@ let eventCompare e1 e2 = compare ((wk1,v1,i1),(tr1,v1',tr1')) ((wk2,v2,i2),(tr2,v2',tr2')) | (E_write_ea wk1 a1 i1 tr1, E_write_ea wk2 a2 i2 tr2) -> compare (wk1, (a1, i1, tr1)) (wk2, (a2, i2, tr2)) + | (E_excl_res, E_excl_res) -> EQ | (E_write_memv _ mv1 tr1, E_write_memv _ mv2 tr2) -> compare (mv1,tr1) (mv2,tr2) | (E_barrier bk1, E_barrier bk2) -> compare bk1 bk2 | (E_read_reg r1, E_read_reg r2) -> compare r1 r2 @@ -806,6 +808,7 @@ let eventCompare e1 e2 = | (E_read_mem _ _ _ _, _) -> LT | (E_write_mem _ _ _ _ _ _, _) -> LT | (E_write_ea _ _ _ _, _) -> LT + | (E_excl_res, _) -> LT | (E_write_memv _ _ _, _) -> LT | (E_barrier _, _) -> LT | (E_read_reg _, _) -> LT @@ -839,6 +842,8 @@ type outcome 'a = | Read_mem of (read_kind * address_lifted * nat) * (memory_value -> with_aux (outcome 'a)) (* Tell the system a write is imminent, at address lifted, of size nat *) | Write_ea of (write_kind * address_lifted * nat) * (with_aux (outcome 'a)) + (* Request the result of store-exclusive *) + | Excl_res of (bool -> with_aux (outcome 'a)) (* Request to write memory at last signalled address. Memory value should be 8 times the size given in ea signal *) | Write_memv of memory_value * (bool -> with_aux (outcome 'a)) diff --git a/src/lexer.mll b/src/lexer.mll index 98c9098d..921be112 100644 --- a/src/lexer.mll +++ b/src/lexer.mll @@ -120,6 +120,7 @@ let kw_table = ("wmem", (fun x -> Wmem)); ("wmv", (fun x -> Wmv)); ("eamem", (fun x -> Eamem)); + ("exmem", (fun x -> Exmem)); ("undef", (fun x -> Undef)); ("unspec", (fun x -> Unspec)); ("nondet", (fun x -> Nondet)); diff --git a/src/parse_ast.ml b/src/parse_ast.ml index 2e72761e..68ebbf9b 100644 --- a/src/parse_ast.ml +++ b/src/parse_ast.ml @@ -80,6 +80,7 @@ base_effect_aux = (* effect *) | BE_wmem (* write memory *) | BE_wmv (* write memory value *) | BE_eamem (* address for write signaled *) + | BE_exmem (* determine if a store-exclusive (ARM) is going to succeed *) | BE_barr (* memory barrier *) | BE_depend (* dynmically dependent footprint *) | BE_undef (* undefined-instruction exception *) diff --git a/src/parser.mly b/src/parser.mly index d172f61b..fce6ff9d 100644 --- a/src/parser.mly +++ b/src/parser.mly @@ -132,7 +132,7 @@ let make_vector_sugar order_set is_inc typ typ1 = %token Enumerate Else Exit Extern False Forall Foreach Function_ If_ In IN Inc Let_ Member Nat Order %token Pure Rec Register Return Scattered Sizeof Struct Switch Then True TwoStarStar Type TYPE Typedef %token Undefined Union With Val -%token Barr Depend Rreg Wreg Rmem Wmem Wmv Eamem Undef Unspec Nondet Escape +%token Barr Depend Rreg Wreg Rmem Wmem Wmv Eamem Exmem Undef Unspec Nondet Escape /* Avoid shift/reduce conflict - see right_atomic_exp rule */ @@ -315,6 +315,8 @@ effect: { efl BE_wmv } | Eamem { efl BE_eamem } + | Exmem + { efl BE_exmem } | Undef { efl BE_undef } | Unspec diff --git a/src/pretty_print_common.ml b/src/pretty_print_common.ml index e90d9cf1..51cf070b 100644 --- a/src/pretty_print_common.ml +++ b/src/pretty_print_common.ml @@ -91,6 +91,7 @@ let doc_effect (BE_aux (e,_)) = | BE_wmem -> "wmem" | BE_wmv -> "wmv" | BE_eamem -> "eamem" + | BE_exmem -> "exmem" | BE_barr -> "barr" | BE_depend -> "depend" | BE_escape -> "escape" diff --git a/src/pretty_print_lem.ml b/src/pretty_print_lem.ml index b55685f4..a436cf90 100644 --- a/src/pretty_print_lem.ml +++ b/src/pretty_print_lem.ml @@ -125,8 +125,8 @@ let effectful (Effect_aux (eff,_)) = List.exists (fun (BE_aux (eff,_)) -> match eff with - | BE_rreg | BE_wreg | BE_rmem | BE_wmem | BE_eamem | BE_wmv - | BE_barr | BE_depend | BE_nondet | BE_escape -> true + | BE_rreg | BE_wreg | BE_rmem | BE_wmem | BE_eamem | BE_exmem + | BE_wmv | BE_barr | BE_depend | BE_nondet | BE_escape -> true | _ -> false) effs diff --git a/src/pretty_print_lem_ast.ml b/src/pretty_print_lem_ast.ml index 03b8bdf5..268aeb2f 100644 --- a/src/pretty_print_lem_ast.ml +++ b/src/pretty_print_lem_ast.ml @@ -184,6 +184,7 @@ and pp_format_base_effect_lem (BE_aux(e,l)) = | BE_wmem -> "BE_wmem" | BE_wmv -> "BE_wmv" | BE_eamem -> "BE_eamem" + | BE_exmem -> "BE_exmem" | BE_barr -> "BE_barr" | BE_depend -> "BE_depend" | BE_undef -> "BE_undef" diff --git a/src/pretty_print_t_ascii.ml b/src/pretty_print_t_ascii.ml index 79897f4b..1494ca0a 100644 --- a/src/pretty_print_t_ascii.ml +++ b/src/pretty_print_t_ascii.ml @@ -99,6 +99,7 @@ and pp_format_base_effect_ascii (BE_aux(e,l)) = | BE_wmem -> "wmem" | BE_wmv -> "wmv" | BE_eamem -> "eamem" + | BE_exmem -> "exmem" | BE_barr -> "barr" | BE_depend -> "depend" | BE_undef -> "undef" diff --git a/src/type_internal.ml b/src/type_internal.ml index 2eaef407..45630d3e 100644 --- a/src/type_internal.ml +++ b/src/type_internal.ml @@ -385,6 +385,7 @@ and ef_to_string (Ast.BE_aux(b,l)) = | Ast.BE_wmem -> "wmem" | Ast.BE_wmv -> "wmv" | Ast.BE_eamem -> "eamem" + | Ast.BE_exmem -> "exmem" | Ast.BE_barr -> "barr" | Ast.BE_undef -> "undef" | Ast.BE_depend -> "depend" @@ -3084,6 +3085,9 @@ let compare_effect (BE_aux(e1,_)) (BE_aux(e2,_)) = | (BE_eamem,BE_eamem) -> 0 | (BE_eamem,_) -> -1 | (_,BE_eamem) -> 1 + | (BE_exmem,BE_exmem) -> 0 + | (BE_exmem,_) -> -1 + | (_,BE_exmem) -> 1 | (BE_barr,BE_barr) -> 0 | (BE_barr,_) -> 1 | (_,BE_barr) -> -1 @@ -3141,6 +3145,7 @@ let has_wreg_effect = has_effect (BE_aux(BE_wreg, Parse_ast.Unknown)) let has_rmem_effect = has_effect (BE_aux(BE_rmem, Parse_ast.Unknown)) let has_wmem_effect = has_effect (BE_aux(BE_wmem, Parse_ast.Unknown)) let has_eamem_effect = has_effect (BE_aux(BE_eamem, Parse_ast.Unknown)) +let has_exmem_effect = has_effect (BE_aux(BE_exmem, Parse_ast.Unknown)) let has_memv_effect = has_effect (BE_aux(BE_wmv, Parse_ast.Unknown)) let has_lret_effect = has_effect (BE_aux(BE_lret, Parse_ast.Unknown)) diff --git a/src/type_internal.mli b/src/type_internal.mli index 4912585a..f6f196a9 100644 --- a/src/type_internal.mli +++ b/src/type_internal.mli @@ -250,6 +250,7 @@ val has_wreg_effect : effect -> bool val has_rmem_effect : effect -> bool val has_wmem_effect : effect -> bool val has_eamem_effect : effect -> bool +val has_exmem_effect : effect -> bool val has_memv_effect : effect -> bool val has_lret_effect : effect -> bool |
