File: JavaSem.ml

package info (click to toggle)
herdtools7 7.58-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 19,732 kB
  • sloc: ml: 128,583; ansic: 3,827; makefile: 670; python: 407; sh: 212; awk: 14
file content (179 lines) | stat: -rw-r--r-- 7,639 bytes parent folder | download
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
(****************************************************************************)
(*                           the diy toolsuite                              *)
(*                                                                          *)
(* Jade Alglave, University College London, UK.                             *)
(* Luc Maranget, INRIA Paris-Rocquencourt, France.                          *)
(*                                                                          *)
(* Copyright 2015-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.            *)
(****************************************************************************)

(* Java instruction semantics *)

module
  Make
    (Conf:Sem.Config)
    (V:Value.S with type Cst.Instr.t = JavaBase.instruction and type arch_op = JavaBase.arch_op) = struct

	module Java = JavaArch_herd.Make(SemExtra.ConfigToArchConfig(Conf))(V)
	module Act = JavaAction.Make(Java)

	include SemExtra.Make(Conf)(Java)(Act)

	let barriers = []
	let isync = None

	let nat_sz = V.Cst.Scalar.machsize

	let atomic_pair_allowed e1 e2 = (e1.E.iiid == e2.E.iiid)

	module Mixed(SZ : ByteSize.S) = struct

      let (>>=)   = M.(>>=)
      let (>>*=)  = M.(>>*=)
      let (>>|)   = M.(>>|)
      let (>>!)   = M.(>>!)
      let (>>>)   = M.cseq
      let (>>>>)  = M.(>>>>)

      let no_mo = AccessModes.NA

      let read_loc is_data mo =
        M.read_loc is_data (fun loc v -> Act.Access (Dir.R, loc, v, mo, nat_sz))

      let  read_exchange is_data vstored mo =
        M.read_loc is_data (fun loc v -> Act.RMW (loc,v,vstored,mo,nat_sz))

      let read_reg is_data r ii =
        read_loc is_data no_mo (A.Location_reg (ii.A.proc,r)) ii

      let read_mem is_data mo a =
        read_loc is_data mo (A.Location_global a)

      let read_mem_atomic is_data a loc =
        M.read_loc is_data
          (fun loc v -> Act.Access (Dir.R, loc, v,  a, nat_sz))
          (A.Location_global loc)

      let read_mem_atomic_known is_data a loc v =
        M.read_loc is_data
          (fun loc _v -> Act.Access (Dir.R, loc, v,  a, nat_sz))
          (A.Location_global loc)

      let write_loc mo loc v ii =
        M.mk_singleton_es (Act.Access (Dir.W, loc, v, mo, nat_sz)) ii >>! v

      let write_reg r v ii = write_loc no_mo (A.Location_reg (ii.A.proc,r)) v ii
      let write_mem mo a  = write_loc mo (A.Location_global a)
      let write_mem_atomic a loc v ii =
        M.mk_singleton_es
          (Act.Access (Dir.W, A.Location_global loc, v, a, nat_sz)) ii >>! v

      let fetch_op op v am l ii =
          M.fetch op v
          (fun v vstored ->
            Act.RMW (A.Location_global l, v, vstored, am, nat_sz))
            ii

      let rec build_semantics_expr is_data e ii : V.v M.t =
        match e with
        | JavaBase.LoadReg reg -> read_reg is_data reg ii

        | JavaBase.LoadMem (vh, am) -> (read_reg is_data vh ii) >>=
                              (fun l -> read_mem is_data am l ii)

        | JavaBase.Const i -> M.unitT (V.maybevToV (ParsedConstant.intToV i))

        | JavaBase.Op (op, e1, e2) ->
              (build_semantics_expr is_data e1 ii >>|
              build_semantics_expr is_data e2 ii) >>= fun (v1, v2) ->
              M.op op v1 v2

        | JavaBase.Rmw (vh, (op, am), e) ->
              (read_reg is_data vh ii) >>|
              (build_semantics_expr true e ii) >>=
              (fun (l , v) -> fetch_op op v am l ii)

        | JavaBase.CAS (vh, (read_am, write_am), expect, dest) ->
              (read_reg is_data vh ii) >>= fun loc_vh ->
              (build_semantics_expr true expect ii) >>= fun v_expect ->
              (read_mem true read_am loc_vh ii) >>*= fun v_vh ->
              M.altT
                ((M.neqT v_vh v_expect) >>! v_vh)
                ((build_semantics_expr true dest ii) >>= fun v_dest ->
                    (M.mk_singleton_es
                    (Act.RMW (A.Location_global loc_vh,
                      v_expect, v_dest, 
                            (match read_am , write_am with
                              | AccessModes.Acquire, AccessModes.Plain -> read_am
                              | AccessModes.Plain, AccessModes.Release -> write_am
                              | _ -> write_am), nat_sz))
                    ii) >>! v_expect)

      let build_cond e ii =
        let open Op in
        let e = match e with
        | JavaBase.Op (_,_,_) -> e
        | _ -> JavaBase.Op (Ne,e,Java.Const 0) in
        build_semantics_expr false e ii

      let rec build_semantics test ii : (A.program_order_index * B.t) M.t =
        let ii =
            {ii with A.program_order_index = A.next_po_index ii.A.program_order_index} in

            match ii.A.inst with
            | JavaBase.StoreReg (reg, exp) -> (
                        (build_semantics_expr true exp ii) >>=
                        (fun v -> write_reg reg v ii) >>=
                        (fun _ -> M.unitT (ii.A.program_order_index, B.Next [])))
            | JavaBase.StoreMem (vh, am, e) -> (
                    (read_reg false vh ii) >>|
                    (build_semantics_expr true e ii) >>=
                    (fun (l, v) -> write_mem am l v ii) >>=
                    (fun _ -> M.unitT (ii.A.program_order_index, B.Next [])))
            | JavaBase.If (grd, thn, Some e) -> (
                    build_cond grd ii >>>> fun ret ->
                        let ii' = {
                            ii with A.program_order_index =
                            A.next_po_index ii.A.program_order_index;
                        } in
                        let then_branch = build_semantics test {ii' with A.inst = thn} in
                        let else_branch = build_semantics test {ii' with A.inst = e} in
                        M.choiceT ret then_branch else_branch
                )
            | JavaBase.If (grd, thn, None) -> (
                    build_cond grd ii >>>> fun ret ->
                        let ii' = {
                            ii with A.program_order_index =
                            A.next_po_index ii.A.program_order_index;
                        } in
                        let then_branch = build_semantics test {ii' with A.inst = thn} in
                        M.choiceT ret then_branch
                          (build_semantics_list test [] ii)
                )

            | JavaBase.Seq ins_lst ->
                    build_semantics_list test ins_lst ii
            | JavaBase.Fence mo -> M.mk_fence (Act.Fence mo) ii
                                    >>= fun _ -> M.unitT
                                  (ii.A.program_order_index, B.Next [])
            | _ -> assert false (* others are not implemented yet *)

    and build_semantics_list test insts ii =
        match insts with
        | [] -> M.unitT (ii.A.program_order_index, B.Next [])
        | hd :: tl ->
            let ii = {ii with A.inst = hd; } in
            (build_semantics test ii) >>> fun (prog_order, _branch) ->
                build_semantics_list test tl {ii with A.program_order_index = prog_order;}
    
    let spurious_setaf _ = assert false

    end
end