Import Upstream version 20180207
[hcoop/debian/mlton.git] / runtime / basis / Word / Word-ops.h
1
2 #define binary(kind, name, op) \
3 MLTON_CODEGEN_STATIC_INLINE \
4 Word##kind Word##kind##_##name (Word##kind w1, Word##kind w2) { \
5 return w1 op w2; \
6 }
7
8 #define bothBinary(size, name, op) \
9 binary (S##size, name, op) \
10 binary (U##size, name, op)
11
12 #define compare(kind, name, op) \
13 MLTON_CODEGEN_STATIC_INLINE \
14 Bool Word##kind##_##name (Word##kind w1, Word##kind w2) { \
15 return w1 op w2; \
16 }
17
18 #define bothCompare(size, name, op) \
19 compare (S##size, name, op) \
20 compare (U##size, name, op)
21
22 #define rol(size) \
23 MLTON_CODEGEN_STATIC_INLINE \
24 Word##size Word##size##_rol (Word##size w1, Word32 w2) { \
25 return (Word##size)(w1 >> (size - w2)) | (Word##size)(w1 << w2); \
26 }
27
28 #define ror(size) \
29 MLTON_CODEGEN_STATIC_INLINE \
30 Word##size Word##size##_ror (Word##size w1, Word32 w2) { \
31 return (Word##size)(w1 >> w2) | (Word##size)(w1 << (size - w2)); \
32 } \
33
34 #define shift(kind, name, op) \
35 MLTON_CODEGEN_STATIC_INLINE \
36 Word##kind Word##kind##_##name (Word##kind w1, Word32 w2) { \
37 return (Word##kind)(w1 op w2); \
38 }
39
40 #define unary(kind, name, op) \
41 MLTON_CODEGEN_STATIC_INLINE \
42 Word##kind Word##kind##_##name (Word##kind w) { \
43 return (Word##kind)(op w); \
44 }
45
46 #define misaligned(size) \
47 MLTON_CODEGEN_STATIC_INLINE \
48 Word##size##_t Word##size##_fetch (Ref(Word##size##_t) wp) { \
49 Word##size##_t w; \
50 memcpy(&w, wp, sizeof(Word##size##_t)); \
51 return w; \
52 } \
53 MLTON_CODEGEN_STATIC_INLINE \
54 void Word##size##_store (Ref(Word##size##_t) wp, Word##size##_t w) { \
55 memcpy(wp, &w, sizeof(Word##size##_t)); \
56 return; \
57 } \
58 MLTON_CODEGEN_STATIC_INLINE \
59 void Word##size##_move (Ref(Word##size##_t) dst, Ref(Word##size##_t) src) { \
60 memcpy(dst, src, sizeof(Word##size##_t)); \
61 return; \
62 }
63
64 #define all(size) \
65 binary (size, add, +) \
66 binary (size, andb, &) \
67 compare (size, equal, ==) \
68 bothCompare (size, ge, >=) \
69 bothCompare (size, gt, >) \
70 bothCompare (size, le, <=) \
71 shift (size, lshift, <<) \
72 bothCompare (size, lt, <) \
73 bothBinary (size, mul, *) \
74 unary (size, neg, -) \
75 unary (size, notb, ~) \
76 /* WordS<N>_quot and WordS<N>_rem can't be inlined with the C-codegen, \
77 * because the gcc optimizer sometimes produces incorrect results \
78 * when one of the arguments is a constant. \
79 */ \
80 MLTON_CODEGEN_WORDSQUOTREM_IMPL(binary (S##size, quot, /)) \
81 MLTON_CODEGEN_WORDSQUOTREM_IMPL(binary (S##size, rem, %)) \
82 binary (U##size, quot, /) \
83 binary (U##size, rem, %) \
84 binary (size, orb, |) \
85 rol(size) \
86 ror(size) \
87 /* WordS<N>_rshift isn't ANSI C, because ANSI doesn't guarantee sign \
88 * extension. We use it anyway cause it always seems to work. \
89 */ \
90 shift (S##size, rshift, >>) \
91 shift (U##size, rshift, >>) \
92 binary (size, sub, -) \
93 binary (size, xorb, ^)
94
95 all (8)
96 all (16)
97 all (32)
98 all (64)
99
100 misaligned(64)
101
102 #undef all
103 #undef misaligned
104 #undef unary
105 #undef shift
106 #undef ror
107 #undef rol
108 #undef bothCompare
109 #undef compare
110 #undef bothBinary
111 #undef binary