File: ASLBase.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 (238 lines) | stat: -rw-r--r-- 9,286 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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
(******************************************************************************)
(*                           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, ARM Ltd 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.              *)
(******************************************************************************)
(* Authors:                                                                   *)
(* Hadrien Renaud, University College London, UK.                             *)
(******************************************************************************)
(* Disclaimer:                                                                *)
(* This material covers both ASLv0 (viz, the existing ASL pseudocode language *)
(* which appears in the Arm Architecture Reference Manual) and ASLv1, a new,  *)
(* experimental, and as yet unreleased version of ASL.                        *)
(* This material is work in progress, more precisely at pre-Alpha quality as  *)
(* per Arm’s quality standards.                                               *)
(* In particular, this means that it would be premature to base any           *)
(* production tool development on this material.                              *)
(* However, any feedback, question, query and feature request would be most   *)
(* welcome; those can be sent to Arm’s Architecture Formal Team Lead          *)
(* Jade Alglave <jade.alglave@arm.com>, or by raising issues or PRs to the    *)
(* herdtools7 github repository.                                              *)
(******************************************************************************)

module A64B = AArch64Base

(*****************************************************************************)
(*                                                                           *)
(*                               ASL preambule                               *)
(*                                                                           *)
(*****************************************************************************)

module Scope = struct
  type t =
    | Local of Asllib.AST.identifier * Asllib.AST.uid
        (** Local scope of a function given by its name and an uid of the call *)
    | Global of bool
        (** Global runtime scope, with whether it was during initialization or not *)

  let equal s1 s2 =
    match (s1, s2) with
    | Global _, Global _ -> true
    | Global _, _ | _, Global _ -> false
    | Local (n1, i1), Local (n2, i2) -> i1 == i2 && String.equal n1 n2

  let compare s1 s2 =
    match (s1, s2) with
    | Global _, Global _ -> 0
    | Global _, _ -> -1
    | _, Global _ -> 1
    | Local (n1, i1), Local (n2, i2) ->
        let n = Int.compare i1 i2 in
        if n != 0 then n else String.compare n1 n2

  let to_string = function
    | Global _ -> ""
    | Local (enclosure, call_nb) -> Printf.sprintf "%s.%d." enclosure call_nb

  let main = ("main", 0)
  let global ~init = Global init
  let default = Global false

  let new_local =
    let tbl = Hashtbl.create 64 in
    fun name ->
      let index = try Hashtbl.find tbl name with Not_found -> 0 in
      Hashtbl.replace tbl name (index + 1);
      Local (name, index)
end

let arch_reg_to_int =
  let rec index_of elt pos li =
    match li with
    | [] -> raise Not_found
    | h :: _ when compare elt h = 0 -> pos
    | _ :: t -> index_of elt (pos + 1) t
  in
  fun r -> index_of r 0 AArch64Base.gprs

(*****************************************************************************)
(*                                                                           *)
(*                             Implem of archBase                            *)
(*                                                                           *)
(*****************************************************************************)

(* Who am I ? *)
let arch = Archs.asl
let base_type = A64B.base_type
let endian = A64B.endian

(***********************************************)
(* Basic arch types and their basic operations *)
(***********************************************)

type reg = ASLLocalId of Scope.t * Asllib.AST.identifier | ArchReg of A64B.reg

let pp_reg = function
  | ASLLocalId (scope, x) -> Scope.to_string scope ^ x
  | ArchReg r -> A64B.pp_reg r

let is_local = function ASLLocalId _ -> true | _ -> false
let is_pc = function ArchReg A64B.PC -> true | _ -> false
let to_arch_reg = function ASLLocalId _ -> assert false | ArchReg r -> r
let to_reg r = ArchReg r

let parse_local_id =
  let ( let* ) = Option.bind in
  let ( and* ) o1 o2 =
    match (o1, o2) with Some x1, Some x2 -> Some (x1, x2) | _ -> None
  in
  let find_opt n s =
    try Some (Str.matched_group n s) with Not_found -> None
  in
  let regexp =
    Str.regexp {|\([A-Za-z0-9_-]+\)\.\([0-9]+\)\.\([A-Za-z0-9_-]+\)|}
  in
  fun s ->
    if Str.string_match regexp s 0 then
      let* x1 = find_opt 1 s and* x2 = find_opt 2 s and* x3 = find_opt 3 s in
      Some (ASLLocalId (Scope.Local (x1, int_of_string x2), x3))
    else Some (ASLLocalId (Scope.default, s))

let parse_reg s =
  match (A64B.parse_reg s, s) with
  | Some r, _ -> Some (ArchReg r)
  | None, "NZCV" -> Some (ArchReg AArch64Base.NZCV)
  | None, _ -> parse_local_id s

(** A list of supported AArch64 registers. *)
let gregs = List.map fst AArch64Base.xregs

let reg_compare r1 r2 =
  match (r1, r2) with
  | ArchReg r1, ArchReg r2 -> A64B.reg_compare r1 r2
  | ASLLocalId (s1, x1), ASLLocalId (s2, x2) ->
      if String.equal x1 x2 then Scope.compare s1 s2 else String.compare x1 x2
  | ArchReg _, ASLLocalId _ -> 1
  | ASLLocalId _, ArchReg _ -> -1

let symb_reg_name = function
  | ASLLocalId _ -> None
  | ArchReg r -> A64B.symb_reg_name r

let symb_reg x = ArchReg (A64B.symb_reg x)
let type_reg _ = assert false

type barrier = A64B.barrier

let pp_barrier = A64B.pp_barrier
let barrier_compare = A64B.barrier_compare

type parsedInstruction = Asllib.AST.t
type instruction = Asllib.AST.t

let pp_instruction _ppmode ast = Asllib.PP.t_to_string ast
let dump_instruction a = pp_instruction PPMode.Ascii a
let dump_instruction_hash = Asllib.Serialize.t_to_string
let allowed_for_symb = List.map to_reg A64B.allowed_for_symb
let fold_regs _ ab _ = ab
let map_regs _ _ i = i
let fold_addrs _ a _ = a
let map_addrs _ i = i
let norm_ins i = i
let get_next _ = assert false
let is_valid _ = true

include Pseudo.Make (struct
  type ins = instruction
  type pins = parsedInstruction
  type reg_arg = reg

  let parsed_tr ast = ast
  let get_naccesses _ = -1
  let size_of_ins _ = 4
  let fold_labels k _f _i = k
  let map_labels _f i = i
end)

let get_macro _ = assert false
let hash_pteval _ = assert false

(*****************************************************************************)
(*                                                                           *)
(*                                 ASL Utils                                 *)
(*                                                                           *)
(*****************************************************************************)

let memoize f =
  let table = Hashtbl.create 17 in
  fun ?ast_type version s ->
    let k = (ast_type, version, s) in
    match Hashtbl.find_opt table k with
    | Some r -> r
    | None ->
        let r = f ?ast_type version s in
        let () = Hashtbl.add table k r in
        r

let do_build_ast_from_file ?ast_type version fname =
  match Asllib.Builder.from_file_multi_version ?ast_type version fname with
  | Error e -> raise (Misc.Fatal (Asllib.Error.error_to_string e))
  | Ok ast -> ast

let build_ast_from_file = memoize do_build_ast_from_file

let asl_generic_parser version lexer lexbuf =
  match
    Asllib.Builder.from_lexer_lexbuf ~ast_type:`Ast version lexer lexbuf
  with
  | Error e -> raise (Misc.Fatal (Asllib.Error.error_to_string e))
  | Ok ast -> ([ (0, None, MiscParser.Main) ], [ [ Instruction ast ] ], [])

let stmts_from_string s =
  let open Asllib in
  let lexbuf = Lexing.from_string s in
  let module Parser = Parser.Make(struct
    let allow_no_end_semicolon = false
  end) in
  let module Lexer = Lexer.Make(struct
    let allow_double_underscore = false
    let allow_unknown = false
  end) in
  try Parser.stmts Lexer.token lexbuf
  with e ->
    Warn.fatal "Internal parsing of \"%s\" failed with %s" s
      (Printexc.to_string e)

module Instr = Instr.No (struct
  type instr = instruction
end)