lots of portability changes (#1405)
[ghc-hetmet.git] / compiler / utils / FastTypes.lhs
1 %
2 % (c) The University of Glasgow, 2000-2006
3 %
4 \section{Fast integers, etc... booleans moved to FastBool for using panic}
5
6 \begin{code}
7
8 --Even if the optimizer could handle boxed arithmetic equally well,
9 --this helps automatically check the sources to make sure that
10 --it's only used in an appropriate pattern of efficiency.
11 --(it also makes `let`s and `case`s stricter...)
12
13 module FastTypes (
14     FastInt, _ILIT, iBox, iUnbox,
15     (+#), (-#), (*#), quotFastInt, negateFastInt,
16     --quotRemFastInt is difficult because unboxed values can't
17     --be tupled, but unboxed tuples aren't portable.  Just use
18     -- nuisance boxed quotRem and rely on optimization.
19     (==#), (/=#), (<#), (<=#), (>=#), (>#),
20     minFastInt, maxFastInt,
21     --prefer to distinguish operations, not types, between
22     --signed and unsigned.
23     --left-shift is the same for 'signed' and 'unsigned' numbers
24     shiftLFastInt,
25     --right-shift isn't the same for negative numbers (ones with
26     --the highest-order bit '1').  If you don't care because the
27     --number you're shifting is always nonnegative, use the '_' version
28     --which should just be the fastest one.
29     shiftR_FastInt,
30     --"L' = logical or unsigned shift; 'A' = arithmetic or signed shift
31     shiftRLFastInt, shiftRAFastInt,
32     bitAndFastInt, bitOrFastInt,
33     --add more operations to this file as you need them
34
35     --note, fastChr is "unsafe"Chr: it doesn't check for
36     --character values above the range of Unicode
37     FastChar, _CLIT, cBox, cUnbox, fastOrd, fastChr, eqFastChar,
38
39     FastPtr, pBox, pUnbox, castFastPtr
40   ) where
41
42 #define COMPILING_FAST_STRING
43 #include "HsVersions.h"
44
45 #if defined(__GLASGOW_HASKELL__)
46
47 -- Import the beggars
48 import GHC.Exts
49
50 type FastInt = Int#
51
52 --in case it's a macro, don't lexically feed an argument!
53 --e.g. #define _ILIT(x) (x#) , #define _ILIT(x) (x :: FastInt)
54 _ILIT = \(I# x) -> x
55 --perhaps for accomodating caseless-leading-underscore treatment,
56 --something like _iLIT or iLIT would be better?
57
58 iBox x = I# x
59 iUnbox (I# x) = x
60 quotFastInt   = quotInt#
61 negateFastInt = negateInt#
62
63 --I think uncheckedIShiftL# and uncheckedIShiftRL# are the same
64 --as uncheckedShiftL# and uncheckedShiftRL# ...
65 --should they be used? How new are they?
66 --They existed as far back as GHC 6.0 at least...
67 shiftLFastInt x y = uncheckedIShiftL# x y
68 shiftR_FastInt x y = uncheckedIShiftRL# x y
69 shiftRLFastInt x y = uncheckedIShiftRL# x y
70 shiftRAFastInt x y = uncheckedIShiftRA# x y
71 --{-# INLINE shiftLNonnegativeFastInt #-}
72 --{-# INLINE shiftRNonnegativeFastInt #-}
73 --shiftLNonnegativeFastInt n p = word2Int#((int2Word# n) `uncheckedShiftL#` p)
74 --shiftRNonnegativeFastInt n p = word2Int#((int2Word# n) `uncheckedShiftRL#` p)
75 bitAndFastInt x y = word2Int# (and# (int2Word# x) (int2Word# y))
76 bitOrFastInt x y = word2Int# (or# (int2Word# x) (int2Word# y))
77
78 type FastChar = Char#
79 _CLIT = \(C# c) -> c
80 cBox c = C# c
81 cUnbox (C# c) = c
82 fastOrd c = ord# c
83 fastChr x = chr# x
84 eqFastChar a b = eqChar# a b
85
86 --note that the type-parameter doesn't provide any safety
87 --when it's a synonym, but as long as we keep it compiling
88 --with and without __GLASGOW_HASKELL__ defined, it's fine.
89 type FastPtr a = Addr#
90 pBox p = Ptr p
91 pUnbox (Ptr p) = p
92 castFastPtr p = p
93
94 #else /* ! __GLASGOW_HASKELL__ */
95
96 import Data.Char (ord, chr)
97
98 import Data.Bits
99 import Data.Word (Word) --is it a good idea to assume this exists too?
100 --does anyone need shiftRLFastInt? (apparently yes.)
101
102 import Foreign.Ptr
103
104 type FastInt = Int
105 _ILIT x = x
106 iBox x = x
107 iUnbox x = x
108 (+#) = (+)
109 (-#) = (-)
110 (*#) = (*)
111 quotFastInt   = quot
112 --quotRemFastInt = quotRem
113 negateFastInt = negate
114 (==#) = (==)
115 (/=#) = (/=)
116 (<#)  = (<)
117 (<=#) = (<=)
118 (>=#) = (>=)
119 (>#)  = (>)
120 shiftLFastInt = shiftL
121 shiftR_FastInt = shiftR
122 shiftRAFastInt = shiftR
123 shiftRLFastInt n p = fromIntegral (shiftR (fromIntegral n :: Word) p)
124 --shiftLFastInt n p = n * (2 ^ p)
125 --assuming quot-Int is faster and the
126 --same for nonnegative arguments than div-Int
127 --shiftR_FastInt n p = n `quot` (2 ^ p)
128 --shiftRAFastInt n p = n `div` (2 ^ p)
129 --I couldn't figure out how to implement without Word nor Bits
130 --shiftRLFastInt n p = fromIntegral ((fromIntegral n :: Word) `quot` (2 ^ (fromIntegral p :: Word)))
131
132 bitAndFastInt = (.&.)
133 bitOrFastInt = (.|.)
134
135 type FastBool = Bool
136 fastBool x = x
137 isFastTrue x = x
138 -- make sure these are as strict as the unboxed version,
139 -- so that the performance characteristics match
140 fastOr False False = False
141 fastOr _ _ = True
142 fastAnd True True = True
143 fastAnd _ _ = False
144
145 type FastChar = Char
146 _CLIT c = c
147 cBox c = c
148 cUnbox c = c
149 fastOrd = ord
150 fastChr = chr  --or unsafeChr if there was a standard location for it
151 eqFastChar = (==)
152
153 type FastPtr a = Ptr a
154 pBox p = p
155 pUnbox p = p
156 castFastPtr = castPtr
157
158 --These are among the type-signatures necessary for !ghc to compile
159 -- but break ghc (can't give a signature for an import...)
160 --Note that the comparisons actually do return Bools not FastBools.
161 (+#), (-#), (*#) :: FastInt -> FastInt -> FastInt
162 (==#), (/=#), (<#), (<=#), (>=#), (>#) :: FastInt -> FastInt -> Bool
163
164 #endif /* ! __GLASGOW_HASKELL__ */
165
166 minFastInt, maxFastInt :: FastInt -> FastInt -> FastInt
167 minFastInt x y = if x <# y then x else y
168 maxFastInt x y = if x <# y then y else x
169
170 -- type-signatures will improve the non-ghc-specific versions
171 -- and keep things accurate (and ABLE to compile!)
172 _ILIT :: Int -> FastInt
173 iBox :: FastInt -> Int
174 iUnbox :: Int -> FastInt
175
176 quotFastInt :: FastInt -> FastInt -> FastInt
177 negateFastInt :: FastInt -> FastInt
178 shiftLFastInt, shiftR_FastInt, shiftRAFastInt, shiftRLFastInt
179    :: FastInt -> FastInt -> FastInt
180 bitAndFastInt, bitOrFastInt :: FastInt -> FastInt -> FastInt
181
182 _CLIT :: Char -> FastChar
183 cBox :: FastChar -> Char
184 cUnbox :: Char -> FastChar
185 fastOrd :: FastChar -> FastInt
186 fastChr :: FastInt -> FastChar
187 eqFastChar :: FastChar -> FastChar -> Bool
188
189 pBox :: FastPtr a -> Ptr a
190 pUnbox :: Ptr a -> FastPtr a
191 castFastPtr :: FastPtr a -> FastPtr b
192
193 \end{code}