Commit | Line | Data |
---|---|---|
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 | ||
8 | functor WordSize (S: WORD_SIZE_STRUCTS): WORD_SIZE = | |
9 | struct | |
10 | ||
11 | open S | |
12 | ||
13 | datatype t = T of Bits.t | |
14 | ||
15 | fun bits (T b) = b | |
16 | ||
17 | val toString = Bits.toString o bits | |
18 | ||
19 | fun compare (s, s') = Bits.compare (bits s, bits s') | |
20 | ||
21 | val {equals, ...} = Relation.compare compare | |
22 | ||
23 | fun 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 | ||
28 | fun isValidSize (i: int) = | |
29 | (1 <= i andalso i <= 32) orelse i = 64 | |
30 | ||
31 | val byte = fromBits (Bits.inByte) | |
32 | ||
33 | fun bigIntInfWord () = fromBits (Control.Target.Size.mplimb ()) | |
34 | fun cint () = fromBits (Control.Target.Size.cint ()) | |
35 | fun cpointer () = fromBits (Control.Target.Size.cpointer ()) | |
36 | fun cptrdiff () = fromBits (Control.Target.Size.cptrdiff ()) | |
37 | fun csize () = fromBits (Control.Target.Size.csize ()) | |
38 | fun objptr () = fromBits (Control.Target.Size.objptr ()) | |
39 | fun objptrHeader () = fromBits (Control.Target.Size.header ()) | |
40 | fun seqIndex () = fromBits (Control.Target.Size.seqIndex ()) | |
41 | fun smallIntInfWord () = objptr () | |
42 | val bool = fromBits (Bits.fromInt 32) | |
43 | val compareRes = fromBits (Bits.fromInt 32) | |
44 | val shiftArg = fromBits (Bits.fromInt 32) | |
45 | val word8 = fromBits (Bits.fromInt 8) | |
46 | val word16 = fromBits (Bits.fromInt 16) | |
47 | val word32 = fromBits (Bits.fromInt 32) | |
48 | val word64 = fromBits (Bits.fromInt 64) | |
49 | ||
50 | val allVector = Vector.tabulate (65, fn i => | |
51 | if isValidSize i | |
52 | then SOME (fromBits (Bits.fromInt i)) | |
53 | else NONE) | |
54 | ||
55 | val all: t list = Vector.toList (Vector.keepAllMap (allVector, fn so => so)) | |
56 | ||
57 | val prims = List.map ([8, 16, 32, 64], fromBits o Bits.fromInt) | |
58 | ||
59 | val 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 | ||
67 | fun 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 | ||
84 | val bytes: t -> Bytes.t = Bits.toBytes o bits | |
85 | ||
86 | fun cardinality s = IntInf.<< (1, Bits.toWord (bits s)) | |
87 | ||
88 | fun 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 | ||
98 | val min = #1 o range | |
99 | val max = #2 o range | |
100 | ||
101 | fun isInRange (s, i, sg) = | |
102 | let | |
103 | val (min, max) = range (s, sg) | |
104 | in | |
105 | min <= i andalso i <= max | |
106 | end | |
107 | ||
108 | datatype prim = W8 | W16 | W32 | W64 | |
109 | ||
110 | fun 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 | ||
118 | fun prim s = | |
119 | case primOpt s of | |
120 | NONE => Error.bug "WordSize.prim" | |
121 | | SOME p => p | |
122 | ||
123 | end |