Import Debian changes 20180207-1
[hcoop/debian/mlton.git] / mlton / atoms / word-size.fun
CommitLineData
7f918cf1
CE
1(* Copyright (C) 2004-2007 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 *
4 * MLton is released under a BSD-style license.
5 * See the file MLton-LICENSE for details.
6 *)
7
8functor WordSize (S: WORD_SIZE_STRUCTS): WORD_SIZE =
9struct
10
11open S
12
13datatype t = T of Bits.t
14
15fun bits (T b) = b
16
17val toString = Bits.toString o bits
18
19fun compare (s, s') = Bits.compare (bits s, bits s')
20
21val {equals, ...} = Relation.compare compare
22
23fun fromBits (b: Bits.t): t =
24 if Bits.>= (b, Bits.zero)
25 then T b
26 else Error.bug (concat ["WordSize.fromBits: strange word size: ", Bits.toString b])
27
28fun isValidSize (i: int) =
29 (1 <= i andalso i <= 32) orelse i = 64
30
31val byte = fromBits (Bits.inByte)
32
33fun bigIntInfWord () = fromBits (Control.Target.Size.mplimb ())
34fun cint () = fromBits (Control.Target.Size.cint ())
35fun cpointer () = fromBits (Control.Target.Size.cpointer ())
36fun cptrdiff () = fromBits (Control.Target.Size.cptrdiff ())
37fun csize () = fromBits (Control.Target.Size.csize ())
38fun objptr () = fromBits (Control.Target.Size.objptr ())
39fun objptrHeader () = fromBits (Control.Target.Size.header ())
40fun seqIndex () = fromBits (Control.Target.Size.seqIndex ())
41fun smallIntInfWord () = objptr ()
42val bool = fromBits (Bits.fromInt 32)
43val compareRes = fromBits (Bits.fromInt 32)
44val shiftArg = fromBits (Bits.fromInt 32)
45val word8 = fromBits (Bits.fromInt 8)
46val word16 = fromBits (Bits.fromInt 16)
47val word32 = fromBits (Bits.fromInt 32)
48val word64 = fromBits (Bits.fromInt 64)
49
50val allVector = Vector.tabulate (65, fn i =>
51 if isValidSize i
52 then SOME (fromBits (Bits.fromInt i))
53 else NONE)
54
55val all: t list = Vector.toList (Vector.keepAllMap (allVector, fn so => so))
56
57val prims = List.map ([8, 16, 32, 64], fromBits o Bits.fromInt)
58
59val memoize: (t -> 'a) -> t -> 'a =
60 fn f =>
61 let
62 val v = Vector.map (allVector, fn opt => Option.map (opt, f))
63 in
64 fn s => valOf (Vector.sub (v, Bits.toInt (bits s)))
65 end
66
67fun roundUpToPrim s =
68 let
69 val bits = Bits.toInt (bits s)
70 val bits =
71 if bits <= 8
72 then 8
73 else if bits <= 16
74 then 16
75 else if bits <= 32
76 then 32
77 else if bits = 64
78 then 64
79 else Error.bug "WordSize.roundUpToPrim"
80 in
81 fromBits (Bits.fromInt bits)
82 end
83
84val bytes: t -> Bytes.t = Bits.toBytes o bits
85
86fun cardinality s = IntInf.<< (1, Bits.toWord (bits s))
87
88fun range (s, {signed}) =
89 if signed
90 then
91 let
92 val pow = IntInf.<< (1, Bits.toWord (bits s) - 0w1)
93 in
94 (~ pow, pow - 1)
95 end
96 else (0, cardinality s - 1)
97
98val min = #1 o range
99val max = #2 o range
100
101fun isInRange (s, i, sg) =
102 let
103 val (min, max) = range (s, sg)
104 in
105 min <= i andalso i <= max
106 end
107
108datatype prim = W8 | W16 | W32 | W64
109
110fun primOpt (s: t): prim option =
111 case Bits.toInt (bits s) of
112 8 => SOME W8
113 | 16 => SOME W16
114 | 32 => SOME W32
115 | 64 => SOME W64
116 | _ => NONE
117
118fun prim s =
119 case primOpt s of
120 NONE => Error.bug "WordSize.prim"
121 | SOME p => p
122
123end