1 (* Copyright (C) 2009,2014 Matthew Fluet.
2 * Copyright (C) 2004-2007 Henry Cejtin, Matthew Fluet, Suresh
3 * Jagannathan, and Stephen Weeks.
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
9 functor WordX (S: WORD_X_STRUCTS): WORD_X =
14 val modulus: WordSize.t -> IntInf.t =
15 fn s => IntInf.<< (1, Bits.toWord (WordSize.bits s))
18 datatype t = T of {size: WordSize.t,
22 fun make (i: IntInf.t, s: WordSize.t) =
24 value = i mod modulus s}
32 val value = make #value
40 val m = modulus (size w)
47 val toInt = IntInf.toInt o toIntInf
49 fun toString w = concat ["0x", IntInf.format (toIntInf w, StringCvt.HEX)]
51 val layout = Layout.str o toString
53 fun zero s = make (0, s)
55 val hash = IntInf.hash o toIntInf
58 val make: (IntInf.t * Word.t -> IntInf.t) -> t * t -> t =
64 if v' >= Bits.toIntInf (WordSize.bits s)
66 else make (f (value w, Word.fromIntInf v'), s)
69 val lshift = make IntInf.<<
70 val >> = make IntInf.~>> (* OK because we know the value is positive. *)
73 fun equals (w, w') = WordSize.equals (size w, size w') andalso value w = value w'
75 fun fromChar (c: Char.t) = make (Int.toIntInf (Char.toInt c), WordSize.byte)
79 fun isAllOnes w = value w = modulus (size w) - 1
81 fun isOne w = 1 = value w
83 fun isZero w = 0 = value w
85 fun isNegOne w = ~1 = toIntInfX w
88 fun make f (s, sg) = fromIntInf (f (s, sg), s)
90 val max = make WordSize.max
91 val min = make WordSize.min
94 fun allOnes s = max (s, {signed = false})
97 fun make f (w, sg) = equals (w, f (size w, sg))
103 fun notb w = make (IntInf.notb (value w), size w)
105 fun one s = make (1, s)
107 fun toIntInfSg (w, {signed}) =
108 if signed then toIntInfX w else toIntInf w
110 fun resize (w, s) = make (toIntInf w, s)
112 fun resizeX (w, s) = make (toIntInfX w, s)
114 fun toChar (w: t): char = Char.fromInt (Int.fromIntInf (value w))
120 val b = WordSize.bits s
121 val shift = if shift > Bits.toIntInf b
123 else Word.fromIntInf shift
125 make (IntInf.~>> (toIntInfX w, shift), s)
128 fun rshift (w, w', {signed}) =
129 if signed then ~>> (w, w') else >> (w, w')
131 fun swap (i: IntInf.t, {hi: word, lo: word}) =
135 orb (~>> (i, lo), << (i mod << (1, lo), hi))
141 val b = WordSize.bits s
142 val shift = Word.fromIntInf (value w' mod Bits.toIntInf b)
144 make (swap (value w, {hi = shift, lo = Bits.toWord b - shift}), s)
150 val b = WordSize.bits s
151 val shift = Word.fromIntInf (value w' mod Bits.toIntInf b)
153 make (swap (value w, {hi = Bits.toWord b - shift, lo = shift}), s)
157 val make: ((IntInf.t * IntInf.t -> IntInf.t) * string) -> t * t -> t =
158 fn (f,name) => fn (w, w') =>
159 if WordSize.equals (size w, size w')
160 then make (f (value w, value w'), size w)
161 else Error.bug (concat ["WordX.", name])
163 val add = make (IntInf.+, "add")
164 val sub = make (IntInf.-, "sub")
165 val andb = make (IntInf.andb, "andb")
166 val orb = make (IntInf.orb, "orb")
167 val xorb = make (IntInf.xorb, "xorb")
170 fun neg w = make (~ (toIntInfX w), size w)
173 val make: ((IntInf.t * IntInf.t -> IntInf.t) * string) -> t * t * {signed: bool}-> t =
174 fn (f,name) => fn (w, w', s) =>
175 if WordSize.equals (size w, size w')
176 then make (f (toIntInfSg (w, s), toIntInfSg (w', s)), size w)
177 else Error.bug (concat ["WordX.", name])
179 val op div = make (IntInf.div, "div")
180 val op mod = make (IntInf.mod, "mod")
181 val mul = make (IntInf.*, "mul")
182 val quot = make (IntInf.quot, "quot")
183 val rem = make (IntInf.rem, "rem")
187 val make: ((IntInf.t * IntInf.t -> 'a) * string) -> t * t * {signed: bool} -> 'a =
188 fn (f,name) => fn (w, w', sg) =>
189 if WordSize.equals (size w, size w')
190 then f (toIntInfSg (w, sg), toIntInfSg (w', sg))
191 else Error.bug (concat ["WordX.", name])
193 val compare = make (IntInf.compare, "compare")
194 val lt = make (IntInf.<, "lt")
195 val le = make (IntInf.<=, "le")
196 val gt = make (IntInf.>, "gt")
197 val ge = make (IntInf.>=, "ge")
200 fun layoutSg {signed} = Layout.record [("signed", Bool.layout signed)]
202 val lt = Trace.trace3 ("WordX.lt", layout, layout, layoutSg, Bool.layout) lt