Interpreter - Incremental API changes
[rune.git] / libi / oper.c
1 /*
2  * OPER.C       - Internal operators
3  *
4  * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved.  See the  
5  *    COPYRIGHT file at the base of the distribution.
6  *
7  * We have to be careful with intermediate results here.  Most of these 
8  * functions can force the expressive functions to return pointers into 
9  * our temporary data space by passing NULL for the RefStor.  This works
10  * because the data for most of these operators does not contain pointers
11  * of any sort.
12  *
13  * NOTE ON _AG and _AGR.  _AG means 'Sign Agnostic', meaning that we will
14  * get the same result running the signed version of the operation as we
15  * would with an unsigned version, which reduces the number of functions
16  * generated by a lot.  AGR means only the right-hand side of a binary
17  * operator is agnostic (i.e. rshift), since most cpu's will mask the
18  * shift count.
19  */
20
21 #include "defs.h"
22
23 #define IHSIZE  64
24 #define IHMASK  (IHSIZE - 1)
25
26 typedef struct InternalOper {
27         const char      *op_Name;
28         ex_func_t       op_Func;
29         Type            *op_LType;
30         Type            *op_RType;
31         int             op_Mode;
32         string_t        op_Id;
33         struct InternalOper *op_HNext;
34 } InternalOper;
35
36 typedef int8_t          Int8;
37 typedef int16_t         Int16;
38 typedef int32_t         Int32;
39 typedef int64_t         Int64;
40
41 typedef u_int8_t        UInt8;
42 typedef u_int16_t       UInt16;
43 typedef u_int32_t       UInt32;
44 typedef u_int64_t       UInt64;
45
46 typedef float           Float32;
47 typedef double          Float64;
48 typedef long double     Float128;
49
50 #define GETDECLARATIONDATA(ct, d) \
51         getDeclarationData((ct), (d), (d)->d_Op, NULL, 0)
52
53 #define UNARY_OP(name, type, op)                                        \
54 static void *                                                           \
55 Oper ## name ## type(runctx_p ct, Exp *exp, RefStor **prs)              \
56 {                                                                       \
57         TmpStor *ts;                                                    \
58                                                                         \
59         ts = getExpTmpData(ct, exp);                                    \
60         ts->ts_ ## type =                                               \
61                 op *(type *)exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs); \
62         return(&ts->ts_ ## type);                                       \
63 }                                                                       \
64
65 #define UNARY_LVALUE_OP(name, type, op)                                 \
66 static void *                                                           \
67 Oper ## name ## type(runctx_p ct, Exp *exp, RefStor **prs)              \
68 {                                                                       \
69         void *s1;                                                       \
70                                                                         \
71         s1 = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);                \
72         op *(type *)s1;                                                 \
73         return(s1);                                                     \
74 }                                                                       \
75
76 #define BINARY_OP(name, ltype, rtype, op)                               \
77 static void *                                                           \
78 Oper ## name ## ltype ## rtype(runctx_p ct, Exp *exp, RefStor **prs)    \
79 {                                                                       \
80         ltype s1;                                                       \
81         TmpStor *ts;                                                    \
82                                                                         \
83         ts = getExpTmpData(ct, exp);                                    \
84         s1 = *(ltype *)exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);      \
85         ts->ts_ ## ltype =                                              \
86             s1 op *(rtype *)exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, prs); \
87         return(&ts->ts_ ## ltype);                                      \
88 }                                                                       \
89
90 #define BINARY_LVALUE_OP(name, ltype, rtype, op)                        \
91 static void *                                                           \
92 Oper ## name ## ltype ## rtype(runctx_p ct, Exp *exp, RefStor **prs)    \
93 {                                                                       \
94         void *s1;                                                       \
95         rtype s2;                                                       \
96         RefStor *rs = NULL;                                             \
97                                                                         \
98         s1 = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);                \
99         s2 = *(rtype *)exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, &rs);      \
100         *(ltype *)s1 op s2;                                             \
101         relsRefStor(rs);                                                \
102         return(s1);                                                     \
103 }                                                                       \
104
105 #define DCCONST_OP(name, ltype, rtype, op)                              \
106 static void *                                                           \
107 Oper ## name ## ltype ## rtype ## _DC(runctx_p ct, Exp *exp,            \
108                                       RefStor **prs __unused)           \
109 {                                                                       \
110         TmpStor *ts;                                                    \
111                                                                         \
112         ts = getExpTmpData(ct, exp);                                    \
113         ts->ts_ ## ltype =                                              \
114                 *(ltype *)GETDECLARATIONDATA(ct, exp->ex_Lhs->ex_Decl) op \
115                 *(rtype *)&exp->ex_Rhs->u;                              \
116         return(&ts->ts_ ## ltype);                                      \
117 }                                                                       \
118
119 /*
120  * BOOL_BINARY_OP() -   boolean result (e.g. comparisona and such)
121  *
122  *   Remember we have to always evaluate the lhs before the rhs
123  */
124 #define BOOL_BINARY_OP(name, ltype, rtype, op)                          \
125 static void *                                                           \
126 Oper ## name ## ltype ## rtype(runctx_p ct, Exp *exp, RefStor **prs)    \
127 {                                                                       \
128         TmpStor *ts;                                                    \
129         ltype s1;                                                       \
130                                                                         \
131         ts = getExpTmpData(ct, exp);                                    \
132         s1 = *(ltype *)exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);      \
133         ts->ts_Bool =                                                   \
134             s1 op *(rtype *)exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, prs); \
135         return(&ts->ts_Bool);                                           \
136 }
137
138 #define BOOL_DCCONST_OP(name, ltype, rtype, op)                         \
139 static void *                                                           \
140 Oper ## name ## ltype ## rtype ## _DC(runctx_p ct, Exp *exp,            \
141                                       RefStor **prs __unused)           \
142 {                                                                       \
143         TmpStor *ts;                                                    \
144                                                                         \
145         ts = getExpTmpData(ct, exp);                                    \
146         ts->ts_Bool =                                                   \
147                 *(ltype *)GETDECLARATIONDATA(ct, exp->ex_Lhs->ex_Decl) op \
148                 *(rtype *)&exp->ex_Rhs->u;                              \
149         return(&ts->ts_Bool);                                           \
150 }                                                                       \
151
152 #define UNARY_INTEGER_OP_TYPES(name, op)        \
153         UNARY_OP(name, Int8, op)                \
154         UNARY_OP(name, Int16, op)               \
155         UNARY_OP(name, Int32, op)               \
156         UNARY_OP(name, Int64, op)               \
157         UNARY_OP(name, UInt8, op)               \
158         UNARY_OP(name, UInt16, op)              \
159         UNARY_OP(name, UInt32, op)              \
160         UNARY_OP(name, UInt64, op)              \
161
162 #define UNARY_INTEGER_OP_TYPES_AG(name, op)     \
163         UNARY_OP(name, Int8, op)                \
164         UNARY_OP(name, Int16, op)               \
165         UNARY_OP(name, Int32, op)               \
166         UNARY_OP(name, Int64, op)               \
167
168 #define UNARY_OP_TYPES(name, op)                \
169         UNARY_INTEGER_OP_TYPES(name, op)        \
170         UNARY_OP(name, Float32, op)             \
171         UNARY_OP(name, Float64, op)             \
172         UNARY_OP(name, Float128, op)            \
173
174 #define UNARY_OP_TYPES_AG(name, op)             \
175         UNARY_INTEGER_OP_TYPES_AG(name, op)     \
176         UNARY_OP(name, Float32, op)             \
177         UNARY_OP(name, Float64, op)             \
178         UNARY_OP(name, Float128, op)            \
179
180 #define UNARY_LVALUE_OP_TYPES(name, op)         \
181         UNARY_LVALUE_OP(name, Int8, op)         \
182         UNARY_LVALUE_OP(name, Int16, op)        \
183         UNARY_LVALUE_OP(name, Int32, op)        \
184         UNARY_LVALUE_OP(name, Int64, op)        \
185         UNARY_LVALUE_OP(name, UInt8, op)        \
186         UNARY_LVALUE_OP(name, UInt16, op)       \
187         UNARY_LVALUE_OP(name, UInt32, op)       \
188         UNARY_LVALUE_OP(name, UInt64, op)       \
189         UNARY_LVALUE_OP(name, Float32, op)      \
190         UNARY_LVALUE_OP(name, Float64, op)      \
191         UNARY_LVALUE_OP(name, Float128, op)     \
192
193 #define UNARY_LVALUE_OP_TYPES_AG(name, op)      \
194         UNARY_LVALUE_OP(name, Int8, op)         \
195         UNARY_LVALUE_OP(name, Int16, op)        \
196         UNARY_LVALUE_OP(name, Int32, op)        \
197         UNARY_LVALUE_OP(name, Int64, op)        \
198         UNARY_LVALUE_OP(name, Float32, op)      \
199         UNARY_LVALUE_OP(name, Float64, op)      \
200         UNARY_LVALUE_OP(name, Float128, op)     \
201
202 #define BINARY_INTEGER_OP_TYPES(name, op)       \
203         BINARY_OP(name, Int8, Int8, op)         \
204         BINARY_OP(name, Int16, Int16, op)       \
205         BINARY_OP(name, Int32, Int32, op)       \
206         BINARY_OP(name, Int64, Int64, op)       \
207         BINARY_OP(name, UInt8, UInt8, op)       \
208         BINARY_OP(name, UInt16, UInt16, op)     \
209         BINARY_OP(name, UInt32, UInt32, op)     \
210         BINARY_OP(name, UInt64, UInt64, op)     \
211
212 #define BINARY_INTEGER_OP_TYPES_AG(name, op)    \
213         BINARY_OP(name, Int8, Int8, op)         \
214         BINARY_OP(name, Int16, Int16, op)       \
215         BINARY_OP(name, Int32, Int32, op)       \
216         BINARY_OP(name, Int64, Int64, op)       \
217
218 #define BINARY_INTEGER_OP_TYPES_ANYRHS(name, op)        \
219         BINARY_OP(name, Int8,   Int8, op)               \
220         BINARY_OP(name, Int16,  Int8, op)               \
221         BINARY_OP(name, Int32,  Int8, op)               \
222         BINARY_OP(name, Int64,  Int8, op)               \
223         BINARY_OP(name, UInt8,  Int8, op)               \
224         BINARY_OP(name, UInt16, Int8, op)               \
225         BINARY_OP(name, UInt32, Int8, op)               \
226         BINARY_OP(name, UInt64, Int8, op)               \
227                                                         \
228         BINARY_OP(name, Int8,   UInt8, op)              \
229         BINARY_OP(name, Int16,  UInt8, op)              \
230         BINARY_OP(name, Int32,  UInt8, op)              \
231         BINARY_OP(name, Int64,  UInt8, op)              \
232         BINARY_OP(name, UInt8,  UInt8, op)              \
233         BINARY_OP(name, UInt16, UInt8, op)              \
234         BINARY_OP(name, UInt32, UInt8, op)              \
235         BINARY_OP(name, UInt64, UInt8, op)              \
236                                                         \
237         BINARY_OP(name, Int8,   Int16, op)              \
238         BINARY_OP(name, Int16,  Int16, op)              \
239         BINARY_OP(name, Int32,  Int16, op)              \
240         BINARY_OP(name, Int64,  Int16, op)              \
241         BINARY_OP(name, UInt8,  Int16, op)              \
242         BINARY_OP(name, UInt16, Int16, op)              \
243         BINARY_OP(name, UInt32, Int16, op)              \
244         BINARY_OP(name, UInt64, Int16, op)              \
245                                                         \
246         BINARY_OP(name, Int8,   UInt16, op)             \
247         BINARY_OP(name, Int16,  UInt16, op)             \
248         BINARY_OP(name, Int32,  UInt16, op)             \
249         BINARY_OP(name, Int64,  UInt16, op)             \
250         BINARY_OP(name, UInt8,  UInt16, op)             \
251         BINARY_OP(name, UInt16, UInt16, op)             \
252         BINARY_OP(name, UInt32, UInt16, op)             \
253         BINARY_OP(name, UInt64, UInt16, op)             \
254                                                         \
255         BINARY_OP(name, Int8,   Int32, op)              \
256         BINARY_OP(name, Int16,  Int32, op)              \
257         BINARY_OP(name, Int32,  Int32, op)              \
258         BINARY_OP(name, Int64,  Int32, op)              \
259         BINARY_OP(name, UInt8,  Int32, op)              \
260         BINARY_OP(name, UInt16, Int32, op)              \
261         BINARY_OP(name, UInt32, Int32, op)              \
262         BINARY_OP(name, UInt64, Int32, op)              \
263                                                         \
264         BINARY_OP(name, Int8,   UInt32, op)             \
265         BINARY_OP(name, Int16,  UInt32, op)             \
266         BINARY_OP(name, Int32,  UInt32, op)             \
267         BINARY_OP(name, Int64,  UInt32, op)             \
268         BINARY_OP(name, UInt8,  UInt32, op)             \
269         BINARY_OP(name, UInt16, UInt32, op)             \
270         BINARY_OP(name, UInt32, UInt32, op)             \
271         BINARY_OP(name, UInt64, UInt32, op)             \
272                                                         \
273         BINARY_OP(name, Int8,   Int64, op)              \
274         BINARY_OP(name, Int16,  Int64, op)              \
275         BINARY_OP(name, Int32,  Int64, op)              \
276         BINARY_OP(name, Int64,  Int64, op)              \
277         BINARY_OP(name, UInt8,  Int64, op)              \
278         BINARY_OP(name, UInt16, Int64, op)              \
279         BINARY_OP(name, UInt32, Int64, op)              \
280         BINARY_OP(name, UInt64, Int64, op)              \
281                                                         \
282         BINARY_OP(name, Int8,   UInt64, op)             \
283         BINARY_OP(name, Int16,  UInt64, op)             \
284         BINARY_OP(name, Int32,  UInt64, op)             \
285         BINARY_OP(name, Int64,  UInt64, op)             \
286         BINARY_OP(name, UInt8,  UInt64, op)             \
287         BINARY_OP(name, UInt16, UInt64, op)             \
288         BINARY_OP(name, UInt32, UInt64, op)             \
289         BINARY_OP(name, UInt64, UInt64, op)             \
290
291 #define BINARY_INTEGER_OP_TYPES_ANYRHS_AGR(name, op)    \
292         BINARY_OP(name, Int8,   Int8, op)               \
293         BINARY_OP(name, Int16,  Int8, op)               \
294         BINARY_OP(name, Int32,  Int8, op)               \
295         BINARY_OP(name, Int64,  Int8, op)               \
296         BINARY_OP(name, UInt8,  Int8, op)               \
297         BINARY_OP(name, UInt16, Int8, op)               \
298         BINARY_OP(name, UInt32, Int8, op)               \
299         BINARY_OP(name, UInt64, Int8, op)               \
300                                                         \
301         BINARY_OP(name, Int8,   Int16, op)              \
302         BINARY_OP(name, Int16,  Int16, op)              \
303         BINARY_OP(name, Int32,  Int16, op)              \
304         BINARY_OP(name, Int64,  Int16, op)              \
305         BINARY_OP(name, UInt8,  Int16, op)              \
306         BINARY_OP(name, UInt16, Int16, op)              \
307         BINARY_OP(name, UInt32, Int16, op)              \
308         BINARY_OP(name, UInt64, Int16, op)              \
309                                                         \
310         BINARY_OP(name, Int8,   Int32, op)              \
311         BINARY_OP(name, Int16,  Int32, op)              \
312         BINARY_OP(name, Int32,  Int32, op)              \
313         BINARY_OP(name, Int64,  Int32, op)              \
314         BINARY_OP(name, UInt8,  Int32, op)              \
315         BINARY_OP(name, UInt16, Int32, op)              \
316         BINARY_OP(name, UInt32, Int32, op)              \
317         BINARY_OP(name, UInt64, Int32, op)              \
318                                                         \
319         BINARY_OP(name, Int8,   Int64, op)              \
320         BINARY_OP(name, Int16,  Int64, op)              \
321         BINARY_OP(name, Int32,  Int64, op)              \
322         BINARY_OP(name, Int64,  Int64, op)              \
323         BINARY_OP(name, UInt8,  Int64, op)              \
324         BINARY_OP(name, UInt16, Int64, op)              \
325         BINARY_OP(name, UInt32, Int64, op)              \
326         BINARY_OP(name, UInt64, Int64, op)              \
327
328
329 #define BINARY_INTEGER_OP_TYPES_ANYRHS_AG(name, op)     \
330         BINARY_OP(name, Int8,   Int8, op)               \
331         BINARY_OP(name, Int16,  Int8, op)               \
332         BINARY_OP(name, Int32,  Int8, op)               \
333         BINARY_OP(name, Int64,  Int8, op)               \
334                                                         \
335         BINARY_OP(name, Int8,   Int16, op)              \
336         BINARY_OP(name, Int16,  Int16, op)              \
337         BINARY_OP(name, Int32,  Int16, op)              \
338         BINARY_OP(name, Int64,  Int16, op)              \
339                                                         \
340         BINARY_OP(name, Int8,   Int32, op)              \
341         BINARY_OP(name, Int16,  Int32, op)              \
342         BINARY_OP(name, Int32,  Int32, op)              \
343         BINARY_OP(name, Int64,  Int32, op)              \
344                                                         \
345         BINARY_OP(name, Int8,   Int64, op)              \
346         BINARY_OP(name, Int16,  Int64, op)              \
347         BINARY_OP(name, Int32,  Int64, op)              \
348         BINARY_OP(name, Int64,  Int64, op)              \
349
350 #define BINARY_NUMERIC_OP_TYPES(name, op)               \
351         BINARY_INTEGER_OP_TYPES(name, op)               \
352         BINARY_OP(name, Float32, Float32, op)           \
353         BINARY_OP(name, Float64, Float64, op)           \
354         BINARY_OP(name, Float128, Float128, op)         \
355
356 #define BINARY_NUMERIC_OP_TYPES_AG(name, op)            \
357         BINARY_INTEGER_OP_TYPES_AG(name, op)            \
358         BINARY_OP(name, Float32, Float32, op)           \
359         BINARY_OP(name, Float64, Float64, op)           \
360         BINARY_OP(name, Float128, Float128, op)         \
361
362 #define BINARY_INTEGER_LVALUE_OP_TYPES(name, op)        \
363         BINARY_LVALUE_OP(name, Int8, Int8, op)          \
364         BINARY_LVALUE_OP(name, Int16, Int16, op)        \
365         BINARY_LVALUE_OP(name, Int32, Int32, op)        \
366         BINARY_LVALUE_OP(name, Int64, Int64, op)        \
367         BINARY_LVALUE_OP(name, UInt8, UInt8, op)        \
368         BINARY_LVALUE_OP(name, UInt16, UInt16, op)      \
369         BINARY_LVALUE_OP(name, UInt32, UInt32, op)      \
370         BINARY_LVALUE_OP(name, UInt64, UInt64, op)      \
371
372 #define BINARY_INTEGER_LVALUE_OP_TYPES_AG(name, op)     \
373         BINARY_LVALUE_OP(name, Int8, Int8, op)          \
374         BINARY_LVALUE_OP(name, Int16, Int16, op)        \
375         BINARY_LVALUE_OP(name, Int32, Int32, op)        \
376         BINARY_LVALUE_OP(name, Int64, Int64, op)        \
377
378 #define BINARY_INTEGER_LVALUE_OP_TYPES_ANYRHS(name, op) \
379         BINARY_LVALUE_OP(name, Int8,   Int8, op)        \
380         BINARY_LVALUE_OP(name, Int16,  Int8, op)        \
381         BINARY_LVALUE_OP(name, Int32,  Int8, op)        \
382         BINARY_LVALUE_OP(name, Int64,  Int8, op)        \
383         BINARY_LVALUE_OP(name, UInt8,  Int8, op)        \
384         BINARY_LVALUE_OP(name, UInt16, Int8, op)        \
385         BINARY_LVALUE_OP(name, UInt32, Int8, op)        \
386         BINARY_LVALUE_OP(name, UInt64, Int8, op)        \
387                                                         \
388         BINARY_LVALUE_OP(name, Int8,   UInt8, op)       \
389         BINARY_LVALUE_OP(name, Int16,  UInt8, op)       \
390         BINARY_LVALUE_OP(name, Int32,  UInt8, op)       \
391         BINARY_LVALUE_OP(name, Int64,  UInt8, op)       \
392         BINARY_LVALUE_OP(name, UInt8,  UInt8, op)       \
393         BINARY_LVALUE_OP(name, UInt16, UInt8, op)       \
394         BINARY_LVALUE_OP(name, UInt32, UInt8, op)       \
395         BINARY_LVALUE_OP(name, UInt64, UInt8, op)       \
396                                                         \
397         BINARY_LVALUE_OP(name, Int8,   Int16, op)       \
398         BINARY_LVALUE_OP(name, Int16,  Int16, op)       \
399         BINARY_LVALUE_OP(name, Int32,  Int16, op)       \
400         BINARY_LVALUE_OP(name, Int64,  Int16, op)       \
401         BINARY_LVALUE_OP(name, UInt8,  Int16, op)       \
402         BINARY_LVALUE_OP(name, UInt16, Int16, op)       \
403         BINARY_LVALUE_OP(name, UInt32, Int16, op)       \
404         BINARY_LVALUE_OP(name, UInt64, Int16, op)       \
405                                                         \
406         BINARY_LVALUE_OP(name, Int8,   UInt16, op)      \
407         BINARY_LVALUE_OP(name, Int16,  UInt16, op)      \
408         BINARY_LVALUE_OP(name, Int32,  UInt16, op)      \
409         BINARY_LVALUE_OP(name, Int64,  UInt16, op)      \
410         BINARY_LVALUE_OP(name, UInt8,  UInt16, op)      \
411         BINARY_LVALUE_OP(name, UInt16, UInt16, op)      \
412         BINARY_LVALUE_OP(name, UInt32, UInt16, op)      \
413         BINARY_LVALUE_OP(name, UInt64, UInt16, op)      \
414                                                         \
415         BINARY_LVALUE_OP(name, Int8,   Int32, op)       \
416         BINARY_LVALUE_OP(name, Int16,  Int32, op)       \
417         BINARY_LVALUE_OP(name, Int32,  Int32, op)       \
418         BINARY_LVALUE_OP(name, Int64,  Int32, op)       \
419         BINARY_LVALUE_OP(name, UInt8,  Int32, op)       \
420         BINARY_LVALUE_OP(name, UInt16, Int32, op)       \
421         BINARY_LVALUE_OP(name, UInt32, Int32, op)       \
422         BINARY_LVALUE_OP(name, UInt64, Int32, op)       \
423                                                         \
424         BINARY_LVALUE_OP(name, Int8,   UInt32, op)      \
425         BINARY_LVALUE_OP(name, Int16,  UInt32, op)      \
426         BINARY_LVALUE_OP(name, Int32,  UInt32, op)      \
427         BINARY_LVALUE_OP(name, Int64,  UInt32, op)      \
428         BINARY_LVALUE_OP(name, UInt8,  UInt32, op)      \
429         BINARY_LVALUE_OP(name, UInt16, UInt32, op)      \
430         BINARY_LVALUE_OP(name, UInt32, UInt32, op)      \
431         BINARY_LVALUE_OP(name, UInt64, UInt32, op)      \
432                                                         \
433         BINARY_LVALUE_OP(name, Int8,   Int64, op)       \
434         BINARY_LVALUE_OP(name, Int16,  Int64, op)       \
435         BINARY_LVALUE_OP(name, Int32,  Int64, op)       \
436         BINARY_LVALUE_OP(name, Int64,  Int64, op)       \
437         BINARY_LVALUE_OP(name, UInt8,  Int64, op)       \
438         BINARY_LVALUE_OP(name, UInt16, Int64, op)       \
439         BINARY_LVALUE_OP(name, UInt32, Int64, op)       \
440         BINARY_LVALUE_OP(name, UInt64, Int64, op)       \
441                                                         \
442         BINARY_LVALUE_OP(name, Int8,   UInt64, op)      \
443         BINARY_LVALUE_OP(name, Int16,  UInt64, op)      \
444         BINARY_LVALUE_OP(name, Int32,  UInt64, op)      \
445         BINARY_LVALUE_OP(name, Int64,  UInt64, op)      \
446         BINARY_LVALUE_OP(name, UInt8,  UInt64, op)      \
447         BINARY_LVALUE_OP(name, UInt16, UInt64, op)      \
448         BINARY_LVALUE_OP(name, UInt32, UInt64, op)      \
449         BINARY_LVALUE_OP(name, UInt64, UInt64, op)      \
450
451 #define BINARY_INTEGER_LVALUE_OP_TYPES_ANYRHS_AGR(name, op)     \
452         BINARY_LVALUE_OP(name, Int8,   Int8, op)        \
453         BINARY_LVALUE_OP(name, Int16,  Int8, op)        \
454         BINARY_LVALUE_OP(name, Int32,  Int8, op)        \
455         BINARY_LVALUE_OP(name, Int64,  Int8, op)        \
456         BINARY_LVALUE_OP(name, UInt8,  Int8, op)        \
457         BINARY_LVALUE_OP(name, UInt16, Int8, op)        \
458         BINARY_LVALUE_OP(name, UInt32, Int8, op)        \
459         BINARY_LVALUE_OP(name, UInt64, Int8, op)        \
460                                                         \
461         BINARY_LVALUE_OP(name, Int8,   Int16, op)       \
462         BINARY_LVALUE_OP(name, Int16,  Int16, op)       \
463         BINARY_LVALUE_OP(name, Int32,  Int16, op)       \
464         BINARY_LVALUE_OP(name, Int64,  Int16, op)       \
465         BINARY_LVALUE_OP(name, UInt8,  Int16, op)       \
466         BINARY_LVALUE_OP(name, UInt16, Int16, op)       \
467         BINARY_LVALUE_OP(name, UInt32, Int16, op)       \
468         BINARY_LVALUE_OP(name, UInt64, Int16, op)       \
469                                                         \
470         BINARY_LVALUE_OP(name, Int8,   Int32, op)       \
471         BINARY_LVALUE_OP(name, Int16,  Int32, op)       \
472         BINARY_LVALUE_OP(name, Int32,  Int32, op)       \
473         BINARY_LVALUE_OP(name, Int64,  Int32, op)       \
474         BINARY_LVALUE_OP(name, UInt8,  Int32, op)       \
475         BINARY_LVALUE_OP(name, UInt16, Int32, op)       \
476         BINARY_LVALUE_OP(name, UInt32, Int32, op)       \
477         BINARY_LVALUE_OP(name, UInt64, Int32, op)       \
478                                                         \
479         BINARY_LVALUE_OP(name, Int8,   Int64, op)       \
480         BINARY_LVALUE_OP(name, Int16,  Int64, op)       \
481         BINARY_LVALUE_OP(name, Int32,  Int64, op)       \
482         BINARY_LVALUE_OP(name, Int64,  Int64, op)       \
483         BINARY_LVALUE_OP(name, UInt8,  Int64, op)       \
484         BINARY_LVALUE_OP(name, UInt16, Int64, op)       \
485         BINARY_LVALUE_OP(name, UInt32, Int64, op)       \
486         BINARY_LVALUE_OP(name, UInt64, Int64, op)       \
487
488 #define BINARY_INTEGER_LVALUE_OP_TYPES_ANYRHS_AG(name, op)      \
489         BINARY_LVALUE_OP(name, Int8,   Int8, op)        \
490         BINARY_LVALUE_OP(name, Int16,  Int8, op)        \
491         BINARY_LVALUE_OP(name, Int32,  Int8, op)        \
492         BINARY_LVALUE_OP(name, Int64,  Int8, op)        \
493                                                         \
494         BINARY_LVALUE_OP(name, Int8,   Int16, op)       \
495         BINARY_LVALUE_OP(name, Int16,  Int16, op)       \
496         BINARY_LVALUE_OP(name, Int32,  Int16, op)       \
497         BINARY_LVALUE_OP(name, Int64,  Int16, op)       \
498                                                         \
499         BINARY_LVALUE_OP(name, Int8,   Int32, op)       \
500         BINARY_LVALUE_OP(name, Int16,  Int32, op)       \
501         BINARY_LVALUE_OP(name, Int32,  Int32, op)       \
502         BINARY_LVALUE_OP(name, Int64,  Int32, op)       \
503                                                         \
504         BINARY_LVALUE_OP(name, Int8,   Int64, op)       \
505         BINARY_LVALUE_OP(name, Int16,  Int64, op)       \
506         BINARY_LVALUE_OP(name, Int32,  Int64, op)       \
507         BINARY_LVALUE_OP(name, Int64,  Int64, op)       \
508
509 #define BINARY_NUMERIC_LVALUE_OP_TYPES(name, op)        \
510         BINARY_INTEGER_LVALUE_OP_TYPES(name, op)        \
511         BINARY_LVALUE_OP(name, Float32, Float32, op)    \
512         BINARY_LVALUE_OP(name, Float64, Float64, op)    \
513         BINARY_LVALUE_OP(name, Float128, Float128, op)  \
514
515 #define BINARY_NUMERIC_LVALUE_OP_TYPES_AG(name, op)     \
516         BINARY_INTEGER_LVALUE_OP_TYPES_AG(name, op)     \
517         BINARY_LVALUE_OP(name, Float32, Float32, op)    \
518         BINARY_LVALUE_OP(name, Float64, Float64, op)    \
519         BINARY_LVALUE_OP(name, Float128, Float128, op)  \
520                 
521 #define DCCONST_OP_TYPES(name, op)                      \
522         DCCONST_OP(name, Int8, Int8, op)                \
523         DCCONST_OP(name, Int32, Int32, op)              \
524         DCCONST_OP(name, Float64, Float64, op)          \
525
526 #define BOOL_BINARY_OP_TYPES(name, op)                  \
527         BOOL_BINARY_OP(name, Int8, Int8, op)            \
528         BOOL_BINARY_OP(name, Int16, Int16, op)          \
529         BOOL_BINARY_OP(name, Int32, Int32, op)          \
530         BOOL_BINARY_OP(name, Int64, Int64, op)          \
531         BOOL_BINARY_OP(name, UInt8, UInt8, op)          \
532         BOOL_BINARY_OP(name, UInt16, UInt16, op)        \
533         BOOL_BINARY_OP(name, UInt32, UInt32, op)        \
534         BOOL_BINARY_OP(name, UInt64, UInt64, op)        \
535         BOOL_BINARY_OP(name, Float32, Float32, op)      \
536         BOOL_BINARY_OP(name, Float64, Float64, op)      \
537         BOOL_BINARY_OP(name, Float128, Float128, op)    \
538
539 #define BOOL_BINARY_OP_TYPES_AG(name, op)               \
540         BOOL_BINARY_OP(name, Int8, Int8, op)            \
541         BOOL_BINARY_OP(name, Int16, Int16, op)          \
542         BOOL_BINARY_OP(name, Int32, Int32, op)          \
543         BOOL_BINARY_OP(name, Int64, Int64, op)          \
544         BOOL_BINARY_OP(name, Float32, Float32, op)      \
545         BOOL_BINARY_OP(name, Float64, Float64, op)      \
546         BOOL_BINARY_OP(name, Float128, Float128, op)    \
547
548 #define BOOL_DCCONST_OP_TYPES(name, op)                 \
549         BOOL_DCCONST_OP(name, Int8, Int8, op)           \
550         BOOL_DCCONST_OP(name, Int32, Int32, op)         \
551         BOOL_DCCONST_OP(name, Float64, Float64, op)     \
552
553 #define ARRAY_ELEMENT(name, ltype, rtype)               \
554         { .op_Name = "__" #name,                        \
555           .op_Func = Oper ## name ## ltype ## rtype,    \
556           .op_LType = &ltype ## Type,                   \
557           .op_RType = &rtype ## Type,                   \
558           .op_Mode = MODE_NORMAL        }               \
559
560 #define ARRAY_ELEMENT_AG(name, ltype, rtype)            \
561         { .op_Name = "__" #name,                        \
562           .op_Func = Oper ## name ## ltype ## rtype,    \
563           .op_LType = &ltype ## Type,                   \
564           .op_RType = &rtype ## Type,                   \
565           .op_Mode = MODE_NORMAL        },              \
566         { .op_Name = "__" #name,                        \
567           .op_Func = Oper ## name ## ltype ## rtype,    \
568           .op_LType = &U ## ltype ## Type,              \
569           .op_RType = &U ## rtype ## Type,              \
570           .op_Mode = MODE_NORMAL        }               \
571
572 #define ARRAY_ELEMENT_AGR(name, ltype, rtype)           \
573         { .op_Name = "__" #name,                        \
574           .op_Func = Oper ## name ## ltype ## rtype,    \
575           .op_LType = &ltype ## Type,                   \
576           .op_RType = &rtype ## Type,                   \
577           .op_Mode = MODE_NORMAL        },              \
578         { .op_Name = "__" #name,                        \
579           .op_Func = Oper ## name ## ltype ## rtype,    \
580           .op_LType = &ltype ## Type,                   \
581           .op_RType = &U ## rtype ## Type,              \
582           .op_Mode = MODE_NORMAL        }               \
583
584 #define UNARY_ARRAY_ELEMENT(name, ltype)                \
585         { .op_Name = "__" #name,                        \
586           .op_Func = Oper ## name ## ltype,             \
587           .op_LType = &ltype ## Type,                   \
588           .op_RType = NULL,                             \
589           .op_Mode = MODE_NORMAL        }               \
590
591 #define UNARY_ARRAY_ELEMENT_AG(name, ltype)             \
592         { .op_Name = "__" #name,                        \
593           .op_Func = Oper ## name ## ltype,             \
594           .op_LType = &ltype ## Type,                   \
595           .op_RType = NULL,                             \
596           .op_Mode = MODE_NORMAL        },              \
597         { .op_Name = "__" #name,                        \
598           .op_Func = Oper ## name ## ltype,             \
599           .op_LType = &U ## ltype ## Type,              \
600           .op_RType = NULL,                             \
601           .op_Mode = MODE_NORMAL        }               \
602
603 #define ARRAY_DC_ELEMENT(name, ltype, rtype)            \
604         { .op_Name = "__" #name,                        \
605           .op_Func = Oper ## name ## ltype ## rtype ## _DC, \
606           .op_LType = &ltype ## Type,                   \
607           .op_RType = &rtype ## Type,                   \
608           .op_Mode = MODE_DECLCONST     }               \
609
610 #define UNARY_ARRAY_INTEGER_TYPES(name)         \
611         UNARY_ARRAY_ELEMENT(name, Int8),        \
612         UNARY_ARRAY_ELEMENT(name, Int16),       \
613         UNARY_ARRAY_ELEMENT(name, Int32),       \
614         UNARY_ARRAY_ELEMENT(name, Int64),       \
615         UNARY_ARRAY_ELEMENT(name, UInt8),       \
616         UNARY_ARRAY_ELEMENT(name, UInt16),      \
617         UNARY_ARRAY_ELEMENT(name, UInt32),      \
618         UNARY_ARRAY_ELEMENT(name, UInt64)       \
619
620 #define UNARY_ARRAY_INTEGER_TYPES_AG(name)      \
621         UNARY_ARRAY_ELEMENT_AG(name, Int8),     \
622         UNARY_ARRAY_ELEMENT_AG(name, Int16),    \
623         UNARY_ARRAY_ELEMENT_AG(name, Int32),    \
624         UNARY_ARRAY_ELEMENT_AG(name, Int64)     \
625
626 #define UNARY_ARRAY_NUMERIC_TYPES(name)         \
627         UNARY_ARRAY_INTEGER_TYPES(name),        \
628         UNARY_ARRAY_ELEMENT(name, Float32),     \
629         UNARY_ARRAY_ELEMENT(name, Float64),     \
630         UNARY_ARRAY_ELEMENT(name, Float128)     \
631
632 #define UNARY_ARRAY_NUMERIC_TYPES_AG(name)      \
633         UNARY_ARRAY_INTEGER_TYPES_AG(name),     \
634         UNARY_ARRAY_ELEMENT(name, Float32),     \
635         UNARY_ARRAY_ELEMENT(name, Float64),     \
636         UNARY_ARRAY_ELEMENT(name, Float128)     \
637
638 #define ARRAY_INTEGER_TYPES(name)               \
639         ARRAY_ELEMENT(name, Int8, Int8),        \
640         ARRAY_ELEMENT(name, Int16, Int16),      \
641         ARRAY_ELEMENT(name, Int32, Int32),      \
642         ARRAY_ELEMENT(name, Int64, Int64),      \
643         ARRAY_ELEMENT(name, UInt8, UInt8),      \
644         ARRAY_ELEMENT(name, UInt16, UInt16),    \
645         ARRAY_ELEMENT(name, UInt32, UInt32),    \
646         ARRAY_ELEMENT(name, UInt64, UInt64)     \
647
648 #define ARRAY_INTEGER_TYPES_AG(name)            \
649         ARRAY_ELEMENT_AG(name, Int8, Int8),     \
650         ARRAY_ELEMENT_AG(name, Int16, Int16),   \
651         ARRAY_ELEMENT_AG(name, Int32, Int32),   \
652         ARRAY_ELEMENT_AG(name, Int64, Int64)    \
653
654 #define ARRAY_INTEGER_TYPES_ANYRHS(name)        \
655         ARRAY_ELEMENT(name, Int8,   Int8),      \
656         ARRAY_ELEMENT(name, Int16,  Int8),      \
657         ARRAY_ELEMENT(name, Int32,  Int8),      \
658         ARRAY_ELEMENT(name, Int64,  Int8),      \
659         ARRAY_ELEMENT(name, UInt8,  Int8),      \
660         ARRAY_ELEMENT(name, UInt16, Int8),      \
661         ARRAY_ELEMENT(name, UInt32, Int8),      \
662         ARRAY_ELEMENT(name, UInt64, Int8),      \
663                                                 \
664         ARRAY_ELEMENT(name, Int8,   UInt8),     \
665         ARRAY_ELEMENT(name, Int16,  UInt8),     \
666         ARRAY_ELEMENT(name, Int32,  UInt8),     \
667         ARRAY_ELEMENT(name, Int64,  UInt8),     \
668         ARRAY_ELEMENT(name, UInt8,  UInt8),     \
669         ARRAY_ELEMENT(name, UInt16, UInt8),     \
670         ARRAY_ELEMENT(name, UInt32, UInt8),     \
671         ARRAY_ELEMENT(name, UInt64, UInt8),     \
672                                                 \
673         ARRAY_ELEMENT(name, Int8,   Int16),     \
674         ARRAY_ELEMENT(name, Int16,  Int16),     \
675         ARRAY_ELEMENT(name, Int32,  Int16),     \
676         ARRAY_ELEMENT(name, Int64,  Int16),     \
677         ARRAY_ELEMENT(name, UInt8,  Int16),     \
678         ARRAY_ELEMENT(name, UInt16, Int16),     \
679         ARRAY_ELEMENT(name, UInt32, Int16),     \
680         ARRAY_ELEMENT(name, UInt64, Int16),     \
681                                                 \
682         ARRAY_ELEMENT(name, Int8,   UInt16),    \
683         ARRAY_ELEMENT(name, Int16,  UInt16),    \
684         ARRAY_ELEMENT(name, Int32,  UInt16),    \
685         ARRAY_ELEMENT(name, Int64,  UInt16),    \
686         ARRAY_ELEMENT(name, UInt8,  UInt16),    \
687         ARRAY_ELEMENT(name, UInt16, UInt16),    \
688         ARRAY_ELEMENT(name, UInt32, UInt16),    \
689         ARRAY_ELEMENT(name, UInt64, UInt16),    \
690                                                 \
691         ARRAY_ELEMENT(name, Int8,   Int32),     \
692         ARRAY_ELEMENT(name, Int16,  Int32),     \
693         ARRAY_ELEMENT(name, Int32,  Int32),     \
694         ARRAY_ELEMENT(name, Int64,  Int32),     \
695         ARRAY_ELEMENT(name, UInt8,  Int32),     \
696         ARRAY_ELEMENT(name, UInt16, Int32),     \
697         ARRAY_ELEMENT(name, UInt32, Int32),     \
698         ARRAY_ELEMENT(name, UInt64, Int32),     \
699                                                 \
700         ARRAY_ELEMENT(name, Int8,   UInt32),    \
701         ARRAY_ELEMENT(name, Int16,  UInt32),    \
702         ARRAY_ELEMENT(name, Int32,  UInt32),    \
703         ARRAY_ELEMENT(name, Int64,  UInt32),    \
704         ARRAY_ELEMENT(name, UInt8,  UInt32),    \
705         ARRAY_ELEMENT(name, UInt16, UInt32),    \
706         ARRAY_ELEMENT(name, UInt32, UInt32),    \
707         ARRAY_ELEMENT(name, UInt64, UInt32),    \
708                                                 \
709         ARRAY_ELEMENT(name, Int8,   Int64),     \
710         ARRAY_ELEMENT(name, Int16,  Int64),     \
711         ARRAY_ELEMENT(name, Int32,  Int64),     \
712         ARRAY_ELEMENT(name, Int64,  Int64),     \
713         ARRAY_ELEMENT(name, UInt8,  Int64),     \
714         ARRAY_ELEMENT(name, UInt16, Int64),     \
715         ARRAY_ELEMENT(name, UInt32, Int64),     \
716         ARRAY_ELEMENT(name, UInt64, Int64),     \
717                                                 \
718         ARRAY_ELEMENT(name, Int8,   UInt64),    \
719         ARRAY_ELEMENT(name, Int16,  UInt64),    \
720         ARRAY_ELEMENT(name, Int32,  UInt64),    \
721         ARRAY_ELEMENT(name, Int64,  UInt64),    \
722         ARRAY_ELEMENT(name, UInt8,  UInt64),    \
723         ARRAY_ELEMENT(name, UInt16, UInt64),    \
724         ARRAY_ELEMENT(name, UInt32, UInt64),    \
725         ARRAY_ELEMENT(name, UInt64, UInt64)     \
726
727 #define ARRAY_INTEGER_TYPES_ANYRHS_AGR(name)    \
728         ARRAY_ELEMENT_AGR(name, Int8,   Int8),  \
729         ARRAY_ELEMENT_AGR(name, Int16,  Int8),  \
730         ARRAY_ELEMENT_AGR(name, Int32,  Int8),  \
731         ARRAY_ELEMENT_AGR(name, Int64,  Int8),  \
732         ARRAY_ELEMENT_AGR(name, UInt8,  Int8),  \
733         ARRAY_ELEMENT_AGR(name, UInt16, Int8),  \
734         ARRAY_ELEMENT_AGR(name, UInt32, Int8),  \
735         ARRAY_ELEMENT_AGR(name, UInt64, Int8),  \
736                                                 \
737         ARRAY_ELEMENT_AGR(name, Int8,   Int16), \
738         ARRAY_ELEMENT_AGR(name, Int16,  Int16), \
739         ARRAY_ELEMENT_AGR(name, Int32,  Int16), \
740         ARRAY_ELEMENT_AGR(name, Int64,  Int16), \
741         ARRAY_ELEMENT_AGR(name, UInt8,  Int16), \
742         ARRAY_ELEMENT_AGR(name, UInt16, Int16), \
743         ARRAY_ELEMENT_AGR(name, UInt32, Int16), \
744         ARRAY_ELEMENT_AGR(name, UInt64, Int16), \
745                                                 \
746         ARRAY_ELEMENT_AGR(name, Int8,   Int32), \
747         ARRAY_ELEMENT_AGR(name, Int16,  Int32), \
748         ARRAY_ELEMENT_AGR(name, Int32,  Int32), \
749         ARRAY_ELEMENT_AGR(name, Int64,  Int32), \
750         ARRAY_ELEMENT_AGR(name, UInt8,  Int32), \
751         ARRAY_ELEMENT_AGR(name, UInt16, Int32), \
752         ARRAY_ELEMENT_AGR(name, UInt32, Int32), \
753         ARRAY_ELEMENT_AGR(name, UInt64, Int32), \
754                                                 \
755         ARRAY_ELEMENT_AGR(name, Int8,   Int64), \
756         ARRAY_ELEMENT_AGR(name, Int16,  Int64), \
757         ARRAY_ELEMENT_AGR(name, Int32,  Int64), \
758         ARRAY_ELEMENT_AGR(name, Int64,  Int64), \
759         ARRAY_ELEMENT_AGR(name, UInt8,  Int64), \
760         ARRAY_ELEMENT_AGR(name, UInt16, Int64), \
761         ARRAY_ELEMENT_AGR(name, UInt32, Int64), \
762         ARRAY_ELEMENT_AGR(name, UInt64, Int64)  \
763
764 #define ARRAY_INTEGER_TYPES_ANYRHS_AG(name)     \
765         ARRAY_ELEMENT_AG(name, Int8,   Int8),   \
766         ARRAY_ELEMENT_AG(name, Int16,  Int8),   \
767         ARRAY_ELEMENT_AG(name, Int32,  Int8),   \
768         ARRAY_ELEMENT_AG(name, Int64,  Int8),   \
769                                                 \
770         ARRAY_ELEMENT_AG(name, Int8,   Int16),  \
771         ARRAY_ELEMENT_AG(name, Int16,  Int16),  \
772         ARRAY_ELEMENT_AG(name, Int32,  Int16),  \
773         ARRAY_ELEMENT_AG(name, Int64,  Int16),  \
774                                                 \
775         ARRAY_ELEMENT_AG(name, Int8,   Int32),  \
776         ARRAY_ELEMENT_AG(name, Int16,  Int32),  \
777         ARRAY_ELEMENT_AG(name, Int32,  Int32),  \
778         ARRAY_ELEMENT_AG(name, Int64,  Int32),  \
779                                                 \
780         ARRAY_ELEMENT_AG(name, Int8,   Int64),  \
781         ARRAY_ELEMENT_AG(name, Int16,  Int64),  \
782         ARRAY_ELEMENT_AG(name, Int32,  Int64),  \
783         ARRAY_ELEMENT_AG(name, Int64,  Int64)   \
784
785 #define ARRAY_NUMERIC_TYPES(name)               \
786         ARRAY_INTEGER_TYPES(name),              \
787         ARRAY_ELEMENT(name, Float32, Float32),  \
788         ARRAY_ELEMENT(name, Float64, Float64),  \
789         ARRAY_ELEMENT(name, Float128, Float128) \
790
791 #define ARRAY_NUMERIC_TYPES_AG(name)            \
792         ARRAY_INTEGER_TYPES_AG(name),           \
793         ARRAY_ELEMENT(name, Float32, Float32),  \
794         ARRAY_ELEMENT(name, Float64, Float64),  \
795         ARRAY_ELEMENT(name, Float128, Float128) \
796
797 #define ARRAY_NUMERIC_DCCONST_TYPES(name)       \
798         ARRAY_DC_ELEMENT(name, Int8, Int8),     \
799         ARRAY_DC_ELEMENT(name, Int32, Int32),   \
800         ARRAY_DC_ELEMENT(name, Float64, Float64)\
801
802 UNARY_OP_TYPES_AG(not, !)
803 UNARY_OP_TYPES_AG(pos, +)
804 UNARY_OP_TYPES_AG(neg, -)
805 UNARY_INTEGER_OP_TYPES_AG(inv, ~)
806 UNARY_LVALUE_OP_TYPES_AG(plpl, ++)
807 UNARY_LVALUE_OP_TYPES_AG(mimi, --)
808
809 BINARY_NUMERIC_OP_TYPES_AG(add, +)
810 BINARY_NUMERIC_OP_TYPES_AG(sub, -)
811 BINARY_NUMERIC_OP_TYPES(mul, *)
812 BINARY_NUMERIC_OP_TYPES(div, /)
813 BINARY_INTEGER_OP_TYPES(mod, %)
814 BINARY_INTEGER_OP_TYPES_AG(and, &)
815 BINARY_INTEGER_OP_TYPES_AG(or, |)
816 BINARY_INTEGER_OP_TYPES_AG(xor, ^)
817 BINARY_INTEGER_OP_TYPES_ANYRHS_AG(lshift, <<)
818 BINARY_INTEGER_OP_TYPES_ANYRHS_AGR(rshift, >>)
819
820 BINARY_NUMERIC_LVALUE_OP_TYPES_AG(pluseq, +=)
821 BINARY_NUMERIC_LVALUE_OP_TYPES_AG(minuseq, -=)
822 BINARY_INTEGER_LVALUE_OP_TYPES_AG(andeq, &=)
823 BINARY_INTEGER_LVALUE_OP_TYPES_AG(oreq, |=)
824 BINARY_INTEGER_LVALUE_OP_TYPES_AG(xoreq, ^=)
825 BINARY_INTEGER_LVALUE_OP_TYPES_ANYRHS_AG(lshifteq, <<=)
826 BINARY_INTEGER_LVALUE_OP_TYPES_ANYRHS_AGR(rshifteq, >>=)
827
828 DCCONST_OP_TYPES(add, +)
829 DCCONST_OP_TYPES(sub, -)
830
831 BOOL_BINARY_OP_TYPES(lt, <)
832 BOOL_BINARY_OP_TYPES(lteq, <=)
833 BOOL_BINARY_OP_TYPES(gt, >)
834 BOOL_BINARY_OP_TYPES(gteq, >=)
835 BOOL_BINARY_OP_TYPES_AG(eqeq, ==)
836 BOOL_BINARY_OP_TYPES_AG(noteq, !=)
837
838 BOOL_DCCONST_OP_TYPES(lt, <)
839 BOOL_DCCONST_OP_TYPES(lteq, <=)
840 BOOL_DCCONST_OP_TYPES(gt, >)
841 BOOL_DCCONST_OP_TYPES(gteq, >=)
842 BOOL_DCCONST_OP_TYPES(eqeq, ==)
843 BOOL_DCCONST_OP_TYPES(noteq, !=)
844
845 /*
846  * Operptr_plplVoidPtr():       ++ptr
847  *
848  * Since our lhs is also our return storage we can simply pass the
849  * reference through without messing with it.
850  *
851  * Note that ex_Type may be void due to void optimizations.
852  */
853 static void *
854 Operptr_plplVoidPtr(runctx_p ct, Exp *exp, RefStor **prs)
855 {
856         PointerStor *lhs;
857         Type *type;
858
859         lhs = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);
860         /*
861          * NOTE! due to void optimization ex_Type may not be what we want.
862          * use the lhs type.
863          */
864         type = exp->ex_Lhs->ex_Type;
865         dassert_exp(exp, type->ty_Op == TY_PTRTO);
866         type = type->ty_PtrType.et_Type;
867
868         lhs->s_Addr += type->ty_Bytes;
869         return(lhs);
870 }
871
872 /*
873  * Operptr_plplVoidPtr():       --ptr
874  *
875  * Since our lhs is also our return storage we can simply pass the
876  * reference through without messing with it.
877  *
878  * Note that ex_Type may be void due to void optimizations.
879  */
880 static void *
881 Operptr_mimiVoidPtr(runctx_p ct, Exp *exp, RefStor **prs)
882 {
883         PointerStor *lhs;
884         Type *type;
885
886         lhs = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);
887         /*
888          * NOTE! due to void optimization ex_Type may not be what we want.
889          * use the lhs type.
890          */
891         type = exp->ex_Lhs->ex_Type;
892         dassert_exp(exp, type->ty_Op == TY_PTRTO);
893         type = type->ty_PtrType.et_Type;
894
895         lhs->s_Addr -= type->ty_Bytes;
896         return(lhs);
897 }
898
899 /*
900  * Operptr_addVoidPtrInt32():   ptr + N
901  *
902  * Since our lhs is also our return storage we can simply pass the
903  * reference through without messing with it. 
904  *
905  * Note that ex_Type may be void due to void optimizations.  Also, remember
906  * that the lhs must always be evaluated before the rhs to avoid blowing
907  * away overlapping temporary space.
908  */
909 static void *
910 Operptr_addVoidPtrInt32(runctx_p ct, Exp *exp, RefStor **prs)
911 {
912         PointerStor *lhs;
913         Type *type;
914         TmpStor *ts;
915         intptr_t count;
916
917         ts = getExpTmpData(ct, exp);
918         switch(exp->ex_Rhs->ex_Type->ty_Bytes) {
919         case sizeof(int32_t):
920                 count = *(int32_t *)exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, prs);
921                 break;
922         case sizeof(int64_t):
923                 count = *(int64_t *)exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, prs);
924                 break;
925         default:
926                 dassert_exp(exp, 0);
927                 count = 0;
928                 break;
929         }
930         lhs = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);
931         type = exp->ex_Lhs->ex_Type;
932         dassert_exp(exp, type->ty_Op == TY_PTRTO);
933         type = type->ty_PtrType.et_Type;
934
935         ts->ts_Pointer.s_Addr = lhs->s_Addr + type->ty_Bytes * count;
936         ts->ts_Pointer.s_Beg = lhs->s_Beg;
937         ts->ts_Pointer.s_End = lhs->s_End;
938         ts->ts_Pointer.s_RefStor = lhs->s_RefStor;
939         return(&ts->ts_Pointer);
940 }
941
942 /*
943  * Operptr_subVoidPtrInt32():   ptr - N
944  *
945  *      Since our lhs is also our return storage we can simply pass the
946  *      reference through without messing with it.  However, we must still
947  *      be careful to evaluate the result from the rhs first since we
948  *      reuse (*prs) for the lhs and the deref might blow away the rhs pointer.
949  *
950  *      Note that ex_Type may be void due to void optimizations.
951  */
952 static void *
953 Operptr_subVoidPtrInt32(runctx_p ct, Exp *exp, RefStor **prs)
954 {
955         PointerStor *lhs;
956         intptr_t count;
957         Type *type;
958         TmpStor *ts;
959
960         ts = getExpTmpData(ct, exp);
961         switch(exp->ex_Rhs->ex_Type->ty_Bytes) {
962         case sizeof(int32_t):
963                 count = *(int32_t *)exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, prs);
964                 break;
965         case sizeof(int64_t):
966                 count = *(int64_t *)exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, prs);
967                 break;
968         default:
969                 dassert_exp(exp, 0);
970                 count = 0;
971                 break;
972         }
973         lhs = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);
974         type = exp->ex_Lhs->ex_Type;
975         dassert_exp(exp, type->ty_Op == TY_PTRTO);
976         type = type->ty_PtrType.et_Type;
977
978         ts->ts_Pointer.s_Addr = lhs->s_Addr - type->ty_Bytes * count;
979         ts->ts_Pointer.s_Beg = lhs->s_Beg;
980         ts->ts_Pointer.s_End = lhs->s_End;
981         ts->ts_Pointer.s_RefStor = lhs->s_RefStor;
982         return(&ts->ts_Pointer);
983 }
984
985 /*
986  * Operptr_addVoidPtrInt32():   ptr + N
987  *
988  *      Since our lhs is also our return storage we can simply pass the
989  *      reference through without messing with it.  However, we must still
990  *      be careful to evaluate the result from the rhs first since we
991  *      reuse (*prs) for the lhs and the deref might blow away the rhs pointer.
992  *
993  *      Note that ex_Type may be void due to void optimizations.
994  */
995 static void *
996 Operptr_addVoidPtrInt32_DC(runctx_p ct, Exp *exp, RefStor **prs)
997 {
998         PointerStor *lhs;
999         Type *type;
1000         TmpStor *ts;
1001
1002         ts = getExpTmpData(ct, exp);
1003         lhs = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);
1004         type = exp->ex_Lhs->ex_Type;
1005         dassert_exp(exp, type->ty_Op == TY_PTRTO);
1006         type = type->ty_PtrType.et_Type;
1007
1008         ts->ts_Pointer.s_Beg = lhs->s_Beg;
1009         ts->ts_Pointer.s_End = lhs->s_End;
1010         ts->ts_Pointer.s_RefStor = lhs->s_RefStor;
1011
1012         switch(exp->ex_Rhs->ex_Type->ty_Bytes) {
1013         case sizeof(int32_t):
1014                 ts->ts_Pointer.s_Addr = lhs->s_Addr + 
1015                         type->ty_Bytes * *(int32_t *)&exp->ex_Rhs->u;
1016                 break;
1017         case sizeof(int64_t):
1018                 ts->ts_Pointer.s_Addr = lhs->s_Addr +
1019                         type->ty_Bytes * (intptr_t)*(int64_t *)&exp->ex_Rhs->u;
1020                 break;
1021         default:
1022                 dassert(0);
1023         }
1024         return(&ts->ts_Pointer);
1025 }
1026
1027 /*
1028  * Operptr_subVoidPtrInt32():   ptr + N
1029  *
1030  * Since our lhs is also our return storage we can simply pass the
1031  * reference through without messing with it.  However, we must still
1032  * be careful to evaluate the result from the rhs first since we
1033  * reuse (*prs) for the lhs and the deref might blow away the rhs pointer.
1034  *
1035  * Note that ex_Type may be void due to void optimizations.
1036  */
1037 static void *
1038 Operptr_subVoidPtrInt32_DC(runctx_p ct, Exp *exp, RefStor **prs)
1039 {
1040         PointerStor *lhs;
1041         Type *type;
1042         TmpStor *ts;
1043
1044         ts = getExpTmpData(ct, exp);
1045         lhs = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);
1046         /*
1047          * NOTE! due to void optimization ex_Type may not be what we want.
1048          * use the lhs type.
1049          */
1050         type = exp->ex_Lhs->ex_Type;
1051         dassert_exp(exp, type->ty_Op == TY_PTRTO);
1052         type = type->ty_PtrType.et_Type;
1053
1054         ts->ts_Pointer.s_Beg = lhs->s_Beg;
1055         ts->ts_Pointer.s_End = lhs->s_End;
1056         ts->ts_Pointer.s_RefStor = lhs->s_RefStor;
1057
1058         switch(exp->ex_Rhs->ex_Type->ty_Bytes) {
1059         case sizeof(int32_t):
1060                 ts->ts_Pointer.s_Addr =
1061                         lhs->s_Addr -
1062                         type->ty_Bytes * *(int32_t *)&exp->ex_Rhs->u;
1063                 break;
1064         case sizeof(int64_t):
1065                 ts->ts_Pointer.s_Addr =
1066                         lhs->s_Addr - 
1067                         type->ty_Bytes * (intptr_t)*(int64_t *)&exp->ex_Rhs->u;
1068                 break;
1069         default:
1070                 dassert(0);
1071         }
1072         return(&ts->ts_Pointer);
1073 }
1074
1075 /*
1076  * Operptr_subVoidPtrInt32():   ptr - ptr
1077  *
1078  *      In this case both lhs and rhs are pointers (which usually require a
1079  *      RefStor) and the return value is an integer.
1080  *
1081  *      Note that ex_Type may be void due to void optimizations.
1082  */
1083 static void *
1084 Operptr_ptr_subVoidPtrVoidPtr(runctx_p ct, Exp *exp, RefStor **prs __unused)
1085 {
1086         PointerStor *lhs;
1087         PointerStor *rhs;
1088         Type *type;
1089         TmpStor *ts;
1090         RefStor *rs = NULL;
1091
1092         /*
1093          * lhs becomes invalid when we resolve rhs, but we are not accessing
1094          * the contents of the pointers so it doesn't matter.
1095          */
1096         ts = getExpTmpData(ct, exp);
1097         lhs = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, &rs);
1098         lhs = (void *)lhs->s_Addr;
1099         rhs = exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, &rs);
1100         rhs = (void *)rhs->s_Addr;
1101         relsRefStor(rs);
1102
1103         type = exp->ex_Lhs->ex_Type;
1104         switch(type->ty_Op) {
1105         case TY_PTRTO:
1106                 type = type->ty_PtrType.et_Type;
1107                 break;
1108         case TY_REFTO:
1109                 /*
1110                  * XXX/YYY require that the types match exactly
1111                  */
1112                 type = type->ty_RefType.et_Type;
1113                 break;
1114         default:
1115                 dassert_exp(exp, 0);
1116         }
1117
1118         if (type->ty_Bytes)
1119                 ts->ts_Int64 = ((char *)lhs - (char *)rhs) / type->ty_Bytes;
1120         else
1121                 ts->ts_Int64 = 0;
1122         return(&ts->ts_Int64);
1123 }
1124
1125 /*
1126  * BINARY_PTR_CMP():    ptr <op> ptr
1127  *
1128  *      In this case both lhs and rhs are pointers (which usually require a
1129  *      RefStor) and the return value is an integer.
1130  *
1131  *      Note that the lhs/rhs may be pointers or reference types
1132  *      (also pointers), or a mix of the two.
1133  *
1134  *      Note that ex_Type may be void due to void optimizations.
1135  */
1136 #define BINARY_PTR_CMP(name, op)                                        \
1137 static void *                                                           \
1138 Oper ## name ## VoidRefVoidRef(runctx_p ct, Exp *exp, RefStor **prs)    \
1139 {                                                                       \
1140         PointerStor *s1;                                                \
1141         PointerStor *s2;                                                \
1142         TmpStor *ts;                                                    \
1143                                                                         \
1144         s1 = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);                \
1145         s1 = (void *)s1->s_Addr;                                        \
1146         s2 = exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, prs);                \
1147         s2 = (void *)s2->s_Addr;                                        \
1148                                                                         \
1149         ts = getExpTmpData(ct, exp);                                    \
1150         ts->ts_Bool = (char *)s1 op (char *)s2;                         \
1151         return(&ts->ts_Bool);                                           \
1152 }                                                                       \
1153
1154 BINARY_PTR_CMP(ptr_eqeq, ==)
1155 BINARY_PTR_CMP(ptr_noteq, !=)
1156 BINARY_PTR_CMP(ptr_lt, <)
1157 BINARY_PTR_CMP(ptr_lteq, <=)
1158 BINARY_PTR_CMP(ptr_gt, >)
1159 BINARY_PTR_CMP(ptr_gteq, >=)
1160
1161 static InternalOper IOpAry[] = {
1162         UNARY_ARRAY_NUMERIC_TYPES_AG(not),
1163         UNARY_ARRAY_NUMERIC_TYPES_AG(pos),
1164         UNARY_ARRAY_NUMERIC_TYPES_AG(neg),
1165         UNARY_ARRAY_NUMERIC_TYPES_AG(plpl),
1166         UNARY_ARRAY_NUMERIC_TYPES_AG(mimi),
1167         UNARY_ARRAY_INTEGER_TYPES_AG(inv),
1168
1169         ARRAY_NUMERIC_TYPES_AG(add),
1170         ARRAY_NUMERIC_DCCONST_TYPES(add),
1171         ARRAY_NUMERIC_DCCONST_TYPES(sub),
1172         ARRAY_NUMERIC_TYPES_AG(sub),
1173         ARRAY_NUMERIC_TYPES(mul),
1174         ARRAY_NUMERIC_TYPES(div),
1175         ARRAY_INTEGER_TYPES(mod),
1176         ARRAY_INTEGER_TYPES_AG(and),
1177         ARRAY_INTEGER_TYPES_AG(or),
1178         ARRAY_INTEGER_TYPES_AG(xor),
1179         ARRAY_INTEGER_TYPES_ANYRHS_AG(lshift),
1180         ARRAY_INTEGER_TYPES_ANYRHS_AGR(rshift),
1181
1182         ARRAY_NUMERIC_TYPES_AG(pluseq),
1183         ARRAY_NUMERIC_TYPES_AG(minuseq),
1184         ARRAY_INTEGER_TYPES_AG(andeq),
1185         ARRAY_INTEGER_TYPES_AG(oreq),
1186         ARRAY_INTEGER_TYPES_AG(xoreq),
1187         ARRAY_INTEGER_TYPES_ANYRHS_AG(lshifteq),
1188         ARRAY_INTEGER_TYPES_ANYRHS_AGR(rshifteq),
1189
1190         ARRAY_NUMERIC_TYPES(lt),
1191         ARRAY_NUMERIC_TYPES(lteq),
1192         ARRAY_NUMERIC_TYPES(gt),
1193         ARRAY_NUMERIC_TYPES(gteq),
1194         ARRAY_NUMERIC_TYPES_AG(eqeq),
1195         ARRAY_NUMERIC_TYPES_AG(noteq),
1196
1197         ARRAY_NUMERIC_DCCONST_TYPES(lt),
1198         ARRAY_NUMERIC_DCCONST_TYPES(lteq),
1199         ARRAY_NUMERIC_DCCONST_TYPES(gt),
1200         ARRAY_NUMERIC_DCCONST_TYPES(gteq),
1201         ARRAY_NUMERIC_DCCONST_TYPES(eqeq),
1202         ARRAY_NUMERIC_DCCONST_TYPES(noteq),
1203
1204         /*
1205          * Pointer operators (FUTURE, MAYBE)
1206          */
1207         UNARY_ARRAY_ELEMENT(ptr_plpl, VoidPtr),
1208         UNARY_ARRAY_ELEMENT(ptr_mimi, VoidPtr),
1209         ARRAY_ELEMENT(ptr_add, VoidPtr, Int32),
1210         ARRAY_ELEMENT(ptr_sub, VoidPtr, Int32),
1211         ARRAY_ELEMENT(ptr_ptr_sub, VoidPtr, VoidPtr),
1212
1213         ARRAY_ELEMENT(ptr_eqeq, VoidRef, VoidRef),
1214         ARRAY_ELEMENT(ptr_noteq, VoidRef, VoidRef),
1215         ARRAY_ELEMENT(ptr_lt, VoidRef, VoidRef),
1216         ARRAY_ELEMENT(ptr_lteq, VoidRef, VoidRef),
1217         ARRAY_ELEMENT(ptr_gt, VoidRef, VoidRef),
1218         ARRAY_ELEMENT(ptr_gteq, VoidRef, VoidRef),
1219
1220         ARRAY_DC_ELEMENT(ptr_add, VoidPtr, Int32),
1221         ARRAY_DC_ELEMENT(ptr_sub, VoidPtr, Int32)
1222 };
1223
1224 static InternalOper *IOpHash[IHSIZE];
1225
1226 static __inline
1227 int
1228 iopHash(string_t id)
1229 {
1230         return(((int)(intptr_t)id >> 5) & IHMASK);
1231 }
1232
1233 void
1234 InternalOperatorInit(void)
1235 {
1236         size_t i;
1237
1238         for (i = 0; i < arysize(IOpAry); ++i) {
1239                 InternalOper *op;
1240                 string_t id;
1241
1242                 op = &IOpAry[i];
1243                 id = StrTableAlloc(op->op_Name, strlen(op->op_Name), 0);
1244                 InternalOper **pop = &IOpHash[iopHash(id)];
1245
1246                 op->op_HNext = *pop;
1247                 op->op_Id = id;
1248                 *pop = op;
1249         }
1250 }
1251
1252 ex_func_t
1253 InternalOperatorLookup(Exp *exp, int mode)
1254 {
1255         string_t id = exp->ex_Decl->d_Id;
1256         Type *ltype = exp->ex_Lhs->ex_Type;
1257         Type *rtype = (exp->ex_Rhs) ? exp->ex_Rhs->ex_Type : NULL;
1258         InternalOper *op = IOpHash[iopHash(id)];
1259
1260         for (op = IOpHash[iopHash(id)]; op; op = op->op_HNext) {
1261                 if (op->op_Id != id || (op->op_Mode & mode) == 0)
1262                         continue;
1263                 if (rtype == NULL && op->op_RType)
1264                         continue;
1265                 if (rtype && op->op_RType == NULL)
1266                         continue;
1267                 if (op->op_LType->ty_Op == TY_PTRTO ||
1268                     op->op_LType->ty_Op == TY_REFTO) {
1269                         if (ltype->ty_Op != TY_PTRTO &&
1270                             ltype->ty_Op != TY_REFTO)
1271                                 continue;
1272                 } else if (MatchType(op->op_LType, ltype) >
1273                            SG_COMPAT_SUBCLASS) {
1274                         continue;
1275                 }
1276                 if (rtype) {
1277                         if (op->op_RType->ty_Op == TY_PTRTO ||
1278                             op->op_RType->ty_Op == TY_REFTO) {
1279                                 if (rtype->ty_Op != TY_PTRTO &&
1280                                     rtype->ty_Op != TY_REFTO)
1281                                         continue;
1282                         } else if (MatchType(op->op_RType, rtype) >
1283                                    SG_COMPAT_SUBCLASS) {
1284                                 continue;
1285                         }
1286                 }
1287                 return(op->op_Func);
1288         }
1289         return(NULL);
1290 }