File: extendScalar.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 (181 lines) | stat: -rw-r--r-- 6,150 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
(****************************************************************************)
(*                           the diy toolsuite                              *)
(*                                                                          *)
(* Jade Alglave, University College London, UK.                             *)
(* Luc Maranget, INRIA Paris-Rocquencourt, France.                          *)
(*                                                                          *)
(* Copyright 2024-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.            *)
(****************************************************************************)

(** Extend a scalar module by wide scalars *)

module
  Make
    (Narrow:Scalar.S)
    (Wide:WideScalar.S)
    (Translate:
       sig
         val promote : Narrow.t -> Wide.t
         val demote : Wide.t -> Narrow.t
       end) : Scalar.S =
  struct
    type t = Narrow of Narrow.t | Wide of Wide.t

    let machsize = Narrow.machsize

    let zero = Narrow Narrow.zero
    let unique_zero = false (* Wide also have a zero *)
    let one = Narrow Narrow.one

    let s_true = one
    let s_false = zero

    (*****************)
    (* One arguments *)
    (*****************)

    let to_narrow f i = Narrow (f i)

    let choose fn fw = function
      | Narrow i -> fn i
      | Wide i -> fw i

    let map fn fw = function
      | Narrow i -> Narrow (fn i)
      | Wide i -> Wide (fw i)

    let of_string = to_narrow Narrow.of_string
    let pp hexa = choose (Narrow.pp hexa)  Wide.pp
    let pp_unsigned hexa = choose (Narrow.pp_unsigned hexa)  Wide.pp

    let of_int = to_narrow Narrow.of_int
    and to_int = choose Narrow.to_int Wide.to_int

    let of_int64 = to_narrow Narrow.of_int64
    and to_int64 = choose Narrow.to_int64 Wide.to_int64

    let as_bool = function
      | Narrow i -> Narrow.as_bool i
      | Wide i -> Warn.fatal "as_bool on wide scalar '%s'" @@ Wide.pp i

    let printable = map Narrow.printable Misc.identity

    let compare s1 s2 = match s1,s2 with
      | Narrow i1,Narrow i2 -> Narrow.compare i1 i2
      | Wide i1,Wide i2 -> Wide.compare i1 i2
      | Narrow _,Wide _ -> -1
      | Wide _,Narrow _ -> +1

    let unsigned_compare s1 s2 = match s1,s2 with
      | Narrow i1,Narrow i2 -> Narrow.unsigned_compare i1 i2
      | Wide i1,Wide i2 -> Wide.compare i1 i2
      | Narrow _,Wide _ -> -1
      | Wide _,Narrow _ -> +1

    let equal s1 s2 = match s1,s2 with
      | Narrow i1,Narrow i2 -> Narrow.equal i1 i2
      | Wide i1,Wide i2 -> Wide.equal i1 i2
      | (Narrow _,Wide _)
      | (Wide _,Narrow _)
        -> false

    (*****************)
    (* Two arguments *)
    (*****************)

    (* Notice: implicit promotion to wider scalar, if needed *)

    let map2 fn fw s1 s2 = match s1,s2 with
      | Narrow i1,Narrow i2 -> Narrow (fn i1 i2)
      | Wide i1,Wide i2 -> Wide (fw i1 i2)
      | Narrow i1,Wide i2 -> Wide (fw (Translate.promote i1) i2)
      | Wide i1,Narrow i2 -> Wide (fw i1 (Translate.promote i2))

(* Implicit demotion and promotion for operations not
 * implemented by the wider scalars.
 * IN practice, this will apply to arithmetics.
 *)

    let widePromote i = Wide (Translate.promote i)

    let map2DemotePromote fn s1 s2 = match s1,s2 with
      | Narrow i1,Narrow i2 -> Narrow (fn i1 i2)
      | Wide i1,Narrow i2 ->
         fn (Translate.demote i1) i2 |> widePromote
      | Narrow i1,Wide i2 ->
         fn i1 (Translate.demote i2) |> widePromote
      | Wide i1,Wide i2 ->
         fn (Translate.demote i1) (Translate.demote i2)
         |> widePromote


    let choose2 fn fw s1 s2 = match s1,s2 with
      | Narrow i1,Narrow i2 ->  fn  i1 i2
      | Wide i1,Wide i2 -> fw i1 i2
      | Narrow i1,Wide i2 -> fw (Translate.promote i1) i2
      | Wide i1,Narrow i2 -> fw i1 (Translate.promote i2)

    let no_tag = Warn.fatal "operation %s non-existent for wide integers"
    let no_op2 tag _ _ = no_tag tag
    let no_op tag _ = no_tag tag

    let add = map2DemotePromote Narrow.add
    and sub = map2DemotePromote Narrow.sub
    and mul = map2DemotePromote Narrow.mul
    and div = map2DemotePromote Narrow.div
    and rem = map2DemotePromote Narrow.rem
    and logor = map2 Narrow.logor Wide.logor
    and logand = map2 Narrow.logand Wide.logand
    and logxor = map2 Narrow.logxor Wide.logxor
    and lognot = map Narrow.lognot Wide.lognot
    and abs = map Narrow.abs Misc.identity


    let mapIntArg fn fw s1 k =
      map (fun i -> fn i k) (fun i -> fw i k) s1

    let shift_left =
      mapIntArg Narrow.shift_left Wide.shift_left
    and shift_right_logical =
      mapIntArg Narrow.shift_right_logical Wide.shift_right
    and shift_right_arithmetic =
      mapIntArg
        Narrow.shift_right_arithmetic
        (no_op2 "shift_right_arithmetic")

    let bit_at k = map (Narrow.bit_at k) (Wide.bit_at k)
    let addk s k = match s with
      | Narrow i -> Narrow (Narrow.addk i k)
      | Wide i ->
         Narrow.addk (Translate.demote i) k
         |> widePromote

    let lt = choose2 Narrow.lt Wide.lt
    and le = choose2 Narrow.le Wide.le

    let mask sz = map (Narrow.mask sz) (Wide.mask sz)
    and sxt sz = map (Narrow.sxt sz) (fun _ -> no_tag "sxt")

    let get_tag = choose Narrow.get_tag (no_op "get_tag")
    and set_tag tag = map (Narrow.set_tag tag) (no_op "set_tag")

    (****************)
    (* Translations *)
    (****************)

    let promote = function
      | Narrow x -> Wide (Translate.promote x)
      | Wide _ as x -> x

    and demote = function
      | Narrow _ as x -> x
      | Wide x -> Narrow (Translate.demote x)

  end