1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
(****************************************************************************)
(* the diy toolsuite *)
(* *)
(* Jade Alglave, University College London, UK. *)
(* Luc Maranget, INRIA Paris-Rocquencourt, France. *)
(* *)
(* Copyright 2010-present Institut National de Recherche en Informatique et *)
(* en Automatique and the authors. All rights reserved. *)
(* *)
(* This software is governed by the CeCILL-B license under French law and *)
(* abiding by the rules of distribution of free software. You can use, *)
(* modify and/ or redistribute the software under the terms of the CeCILL-B *)
(* license as circulated by CEA, CNRS and INRIA at the following URL *)
(* "http://www.cecill.info". We also give a copy in LICENSE.txt. *)
(****************************************************************************)
module Make(O:MixOption.S)(A:Arch_tools.S) : sig
val merge : Name.t -> A.test -> Name.t -> A.test -> A.test
val append : Name.t -> A.test -> Name.t -> A.test -> A.test
val cat : Name.t -> A.test -> Name.t -> A.test -> A.test
end =
struct
open MiscParser
module Alpha = Alpha.Make(O)(A)
module MixPerm = MixPerm.Make(O)(A)
(* Merge of conditions *)
open ConstrGen
let or_cond c1 c2 = match c1,c2 with
| ExistsState e1,ExistsState e2 -> ExistsState (Or [e1;e2])
| ForallStates e1,ForallStates e2 -> ForallStates (Or [e1;e2])
| NotExistsState e1,NotExistsState e2 -> NotExistsState (And [e1;e2])
| _,_ ->
let p1 = prop_of c1
and p2 = prop_of c2 in
ExistsState (Or [p1;p2])
let and_cond c1 c2 = match c1,c2 with
| ExistsState e1,ExistsState e2 -> ExistsState (And [e1;e2])
| ForallStates e1,ForallStates e2 -> ForallStates (And [e1;e2])
| NotExistsState e1,NotExistsState e2 -> NotExistsState (Or [e1;e2])
| _,_ ->
let p1 = prop_of c1
and p2 = prop_of c2 in
ExistsState (And [p1;p2])
let choose_cond =
let open MixOption in
match O.cond with
| Cond.Or -> fun _ -> or_cond
| Cond.And -> fun _ -> and_cond
| Cond.Auto -> fun c -> c
| Cond.No -> fun _ _ _ -> ForallStates (And [])
(* merge of locations *)
(*******)
(* Mix *)
(*******)
let rec mix_list xs sx ys sy = match xs, ys with
| [],[] -> []
| x::rx, [] -> x::mix_list rx (sx-1) ys sy
| [],y::ry -> y::mix_list xs sx ry (sy-1)
| x::rx, y::ry ->
if Random.int(sx+sy) < sx then
x::mix_list rx (sx-1) ys sy
else
y::mix_list xs sx ry (sy-1)
let clean_code =
List.filter
(fun i -> match i with
| A.Nop -> false
| A.Label _
| A.Instruction _
| A.Symbolic _
| A.Macro _ -> true)
let mix_code c1 c2 =
let c1 = clean_code c1
and c2 = clean_code c2 in
mix_list c1 (List.length c1) c2 (List.length c2)
let rec mix_prog p1 p2 = match p1,p2 with
| ([],p)|(p,[]) -> p
| (p,c1)::p1,(_,c2)::p2 -> (p,mix_code c1 c2)::mix_prog p1 p2
let mix_cond = choose_cond or_cond
let merge _doc1 t1 doc2 t2 =
let t2 = MixPerm.perm doc2 t2 in
let t2 = Alpha.alpha doc2 t1 t2 in
{ t1 with
init = t1.init @ t2.init ;
prog = mix_prog t1.prog t2.prog ;
locations = t1.locations @ t2.locations ;
condition = mix_cond t1.condition t2.condition ; }
(**********)
(* Append *)
(**********)
let append_cond = choose_cond and_cond
let append_code c1 c2 = c1@c2
let rec append_prog p1 p2 = match p1,p2 with
| ([],p)|(p,[]) -> p
| (p,c1)::p1,(_,c2)::p2 -> (p,append_code c1 c2)::append_prog p1 p2
let rec replicate x n = if n <= 0 then [] else x::replicate x (n-1)
let rec add_end len = function
| [] -> replicate A.Nop len
| x::xs -> x::add_end (len-1) xs
let same_length prg =
let len =
List.fold_left (fun m (_,c) -> max m (List.length c)) 0 prg in
let prg =
List.map
(fun (p,c) -> p,add_end (len+1) c)
prg in
prg
let append _doc1 t1 doc2 t2 =
let t2 = MixPerm.perm doc2 t2 in
let t2 = Alpha.alpha doc2 t1 t2 in
{ t1 with
init = t1.init @ t2.init ;
prog = append_prog (same_length t1.prog) t2.prog ;
locations = t1.locations @ t2.locations ;
condition = append_cond t1.condition t2.condition ; }
(********************************************)
(* Just concatenate in horizontal direction *)
(********************************************)
let nprocs t = List.length t.prog
let shift_location k loc = match loc with
| A.Location_reg (i,r) -> A.Location_reg (i+k,r)
| A.Location_global _ -> loc
let shift_rloc k = ConstrGen.map_rloc (shift_location k)
let shift_state_atom k (loc,v) = shift_location k loc,v
let shift_state k = List.map (shift_state_atom k)
let shift_locations k =
let open LocationsItem in
List.map
(function
| Loc (l,v) -> Loc (shift_rloc k l,v)
| Fault ((i,lbls),x,ft) -> Fault ((i+k,lbls),x,ft))
let shift_atom k a = match a with
| LV (l,v) -> LV (shift_rloc k l,v)
| LL (a,b) -> LL (shift_location k a,shift_location k b)
| FF ((i,lbls),x,ft) -> FF ((i+k,lbls),x,ft)
let shift_constr k = ConstrGen.map_constr (shift_atom k)
let shift_prog k prog = List.map (fun ((i,ao,func),code) -> (i+k,ao,func),code) prog
let shift k t =
{ t with
init = shift_state k t.init;
locations = shift_locations k t.locations;
condition = shift_constr k t.condition;
prog = shift_prog k t.prog;
}
let cat _doc1 t1 doc2 t2 =
let t2 = Alpha.global doc2 t1 t2 in
let n1 = nprocs t1 in
let t2 = shift n1 t2 in
{ t1 with
init = t1.init @ t2.init ;
prog = t1.prog @ t2.prog ;
locations = t1.locations @ t2.locations ;
condition = append_cond t1.condition t2.condition ; }
end
|