2 * OPER.C - Internal operators
4 * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved. See the
5 * COPYRIGHT file at the base of the distribution.
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
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
24 #define IHMASK (IHSIZE - 1)
26 typedef struct InternalOper {
33 struct InternalOper *op_HNext;
37 typedef int16_t Int16;
38 typedef int32_t Int32;
39 typedef int64_t Int64;
41 typedef u_int8_t UInt8;
42 typedef u_int16_t UInt16;
43 typedef u_int32_t UInt32;
44 typedef u_int64_t UInt64;
46 typedef float Float32;
47 typedef double Float64;
48 typedef long double Float128;
50 #define GETDECLARATIONDATA(ct, d) \
51 getDeclarationData((ct), (d), (d)->d_Op, NULL, 0)
53 #define UNARY_OP(name, type, op) \
55 Oper ## name ## type(runctx_p ct, Exp *exp, RefStor **prs) \
59 ts = getExpTmpData(ct, exp); \
61 op *(type *)exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs); \
62 return(&ts->ts_ ## type); \
65 #define UNARY_LVALUE_OP(name, type, op) \
67 Oper ## name ## type(runctx_p ct, Exp *exp, RefStor **prs) \
71 s1 = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs); \
76 #define BINARY_OP(name, ltype, rtype, op) \
78 Oper ## name ## ltype ## rtype(runctx_p ct, Exp *exp, RefStor **prs) \
83 ts = getExpTmpData(ct, exp); \
84 s1 = *(ltype *)exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs); \
86 s1 op *(rtype *)exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, prs); \
87 return(&ts->ts_ ## ltype); \
90 #define BINARY_LVALUE_OP(name, ltype, rtype, op) \
92 Oper ## name ## ltype ## rtype(runctx_p ct, Exp *exp, RefStor **prs) \
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; \
105 #define DCCONST_OP(name, ltype, rtype, op) \
107 Oper ## name ## ltype ## rtype ## _DC(runctx_p ct, Exp *exp, \
108 RefStor **prs __unused) \
112 ts = getExpTmpData(ct, exp); \
114 *(ltype *)GETDECLARATIONDATA(ct, exp->ex_Lhs->ex_Decl) op \
115 *(rtype *)&exp->ex_Rhs->u; \
116 return(&ts->ts_ ## ltype); \
120 * BOOL_BINARY_OP() - boolean result (e.g. comparisona and such)
122 * Remember we have to always evaluate the lhs before the rhs
124 #define BOOL_BINARY_OP(name, ltype, rtype, op) \
126 Oper ## name ## ltype ## rtype(runctx_p ct, Exp *exp, RefStor **prs) \
131 ts = getExpTmpData(ct, exp); \
132 s1 = *(ltype *)exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs); \
134 s1 op *(rtype *)exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, prs); \
135 return(&ts->ts_Bool); \
138 #define BOOL_DCCONST_OP(name, ltype, rtype, op) \
140 Oper ## name ## ltype ## rtype ## _DC(runctx_p ct, Exp *exp, \
141 RefStor **prs __unused) \
145 ts = getExpTmpData(ct, exp); \
147 *(ltype *)GETDECLARATIONDATA(ct, exp->ex_Lhs->ex_Decl) op \
148 *(rtype *)&exp->ex_Rhs->u; \
149 return(&ts->ts_Bool); \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
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) \
553 #define ARRAY_ELEMENT(name, ltype, rtype) \
554 { .op_Name = "__" #name, \
555 .op_Func = Oper ## name ## ltype ## rtype, \
556 .op_LType = <ype ## Type, \
557 .op_RType = &rtype ## Type, \
558 .op_Mode = MODE_NORMAL } \
560 #define ARRAY_ELEMENT_AG(name, ltype, rtype) \
561 { .op_Name = "__" #name, \
562 .op_Func = Oper ## name ## ltype ## rtype, \
563 .op_LType = <ype ## 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 } \
572 #define ARRAY_ELEMENT_AGR(name, ltype, rtype) \
573 { .op_Name = "__" #name, \
574 .op_Func = Oper ## name ## ltype ## rtype, \
575 .op_LType = <ype ## 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 = <ype ## Type, \
581 .op_RType = &U ## rtype ## Type, \
582 .op_Mode = MODE_NORMAL } \
584 #define UNARY_ARRAY_ELEMENT(name, ltype) \
585 { .op_Name = "__" #name, \
586 .op_Func = Oper ## name ## ltype, \
587 .op_LType = <ype ## Type, \
589 .op_Mode = MODE_NORMAL } \
591 #define UNARY_ARRAY_ELEMENT_AG(name, ltype) \
592 { .op_Name = "__" #name, \
593 .op_Func = Oper ## name ## ltype, \
594 .op_LType = <ype ## Type, \
596 .op_Mode = MODE_NORMAL }, \
597 { .op_Name = "__" #name, \
598 .op_Func = Oper ## name ## ltype, \
599 .op_LType = &U ## ltype ## Type, \
601 .op_Mode = MODE_NORMAL } \
603 #define ARRAY_DC_ELEMENT(name, ltype, rtype) \
604 { .op_Name = "__" #name, \
605 .op_Func = Oper ## name ## ltype ## rtype ## _DC, \
606 .op_LType = <ype ## Type, \
607 .op_RType = &rtype ## Type, \
608 .op_Mode = MODE_DECLCONST } \
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) \
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) \
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) \
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) \
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) \
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) \
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), \
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), \
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), \
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), \
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), \
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), \
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), \
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) \
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), \
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), \
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), \
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) \
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), \
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), \
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), \
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) \
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) \
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) \
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)\
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, --)
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, >>)
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, >>=)
828 DCCONST_OP_TYPES(add, +)
829 DCCONST_OP_TYPES(sub, -)
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, !=)
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, !=)
846 * Operptr_plplVoidPtr(): ++ptr
848 * Since our lhs is also our return storage we can simply pass the
849 * reference through without messing with it.
851 * Note that ex_Type may be void due to void optimizations.
854 Operptr_plplVoidPtr(runctx_p ct, Exp *exp, RefStor **prs)
859 lhs = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);
861 * NOTE! due to void optimization ex_Type may not be what we want.
864 type = exp->ex_Lhs->ex_Type;
865 dassert_exp(exp, type->ty_Op == TY_PTRTO);
866 type = type->ty_PtrType.et_Type;
868 lhs->s_Addr += type->ty_Bytes;
873 * Operptr_plplVoidPtr(): --ptr
875 * Since our lhs is also our return storage we can simply pass the
876 * reference through without messing with it.
878 * Note that ex_Type may be void due to void optimizations.
881 Operptr_mimiVoidPtr(runctx_p ct, Exp *exp, RefStor **prs)
886 lhs = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);
888 * NOTE! due to void optimization ex_Type may not be what we want.
891 type = exp->ex_Lhs->ex_Type;
892 dassert_exp(exp, type->ty_Op == TY_PTRTO);
893 type = type->ty_PtrType.et_Type;
895 lhs->s_Addr -= type->ty_Bytes;
900 * Operptr_addVoidPtrInt32(): ptr + N
902 * Since our lhs is also our return storage we can simply pass the
903 * reference through without messing with it.
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.
910 Operptr_addVoidPtrInt32(runctx_p ct, Exp *exp, RefStor **prs)
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);
922 case sizeof(int64_t):
923 count = *(int64_t *)exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, prs);
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;
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);
943 * Operptr_subVoidPtrInt32(): ptr - N
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.
950 * Note that ex_Type may be void due to void optimizations.
953 Operptr_subVoidPtrInt32(runctx_p ct, Exp *exp, RefStor **prs)
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);
965 case sizeof(int64_t):
966 count = *(int64_t *)exp->ex_Rhs->ex_Func(ct, exp->ex_Rhs, prs);
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;
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);
986 * Operptr_addVoidPtrInt32(): ptr + N
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.
993 * Note that ex_Type may be void due to void optimizations.
996 Operptr_addVoidPtrInt32_DC(runctx_p ct, Exp *exp, RefStor **prs)
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;
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;
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;
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;
1024 return(&ts->ts_Pointer);
1028 * Operptr_subVoidPtrInt32(): ptr + N
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.
1035 * Note that ex_Type may be void due to void optimizations.
1038 Operptr_subVoidPtrInt32_DC(runctx_p ct, Exp *exp, RefStor **prs)
1044 ts = getExpTmpData(ct, exp);
1045 lhs = exp->ex_Lhs->ex_Func(ct, exp->ex_Lhs, prs);
1047 * NOTE! due to void optimization ex_Type may not be what we want.
1050 type = exp->ex_Lhs->ex_Type;
1051 dassert_exp(exp, type->ty_Op == TY_PTRTO);
1052 type = type->ty_PtrType.et_Type;
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;
1058 switch(exp->ex_Rhs->ex_Type->ty_Bytes) {
1059 case sizeof(int32_t):
1060 ts->ts_Pointer.s_Addr =
1062 type->ty_Bytes * *(int32_t *)&exp->ex_Rhs->u;
1064 case sizeof(int64_t):
1065 ts->ts_Pointer.s_Addr =
1067 type->ty_Bytes * (intptr_t)*(int64_t *)&exp->ex_Rhs->u;
1072 return(&ts->ts_Pointer);
1076 * Operptr_subVoidPtrInt32(): ptr - ptr
1078 * In this case both lhs and rhs are pointers (which usually require a
1079 * RefStor) and the return value is an integer.
1081 * Note that ex_Type may be void due to void optimizations.
1084 Operptr_ptr_subVoidPtrVoidPtr(runctx_p ct, Exp *exp, RefStor **prs __unused)
1093 * lhs becomes invalid when we resolve rhs, but we are not accessing
1094 * the contents of the pointers so it doesn't matter.
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;
1103 type = exp->ex_Lhs->ex_Type;
1104 switch(type->ty_Op) {
1106 type = type->ty_PtrType.et_Type;
1110 * XXX/YYY require that the types match exactly
1112 type = type->ty_RefType.et_Type;
1115 dassert_exp(exp, 0);
1119 ts->ts_Int64 = ((char *)lhs - (char *)rhs) / type->ty_Bytes;
1122 return(&ts->ts_Int64);
1126 * BINARY_PTR_CMP(): ptr <op> ptr
1128 * In this case both lhs and rhs are pointers (which usually require a
1129 * RefStor) and the return value is an integer.
1131 * Note that the lhs/rhs may be pointers or reference types
1132 * (also pointers), or a mix of the two.
1134 * Note that ex_Type may be void due to void optimizations.
1136 #define BINARY_PTR_CMP(name, op) \
1138 Oper ## name ## VoidRefVoidRef(runctx_p ct, Exp *exp, RefStor **prs) \
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; \
1149 ts = getExpTmpData(ct, exp); \
1150 ts->ts_Bool = (char *)s1 op (char *)s2; \
1151 return(&ts->ts_Bool); \
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, >=)
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),
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),
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),
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),
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),
1205 * Pointer operators (FUTURE, MAYBE)
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),
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),
1220 ARRAY_DC_ELEMENT(ptr_add, VoidPtr, Int32),
1221 ARRAY_DC_ELEMENT(ptr_sub, VoidPtr, Int32)
1224 static InternalOper *IOpHash[IHSIZE];
1228 iopHash(string_t id)
1230 return(((int)(intptr_t)id >> 5) & IHMASK);
1234 InternalOperatorInit(void)
1238 for (i = 0; i < arysize(IOpAry); ++i) {
1243 id = StrTableAlloc(op->op_Name, strlen(op->op_Name), 0);
1244 InternalOper **pop = &IOpHash[iopHash(id)];
1246 op->op_HNext = *pop;
1253 InternalOperatorLookup(Exp *exp, int mode)
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)];
1260 for (op = IOpHash[iopHash(id)]; op; op = op->op_HNext) {
1261 if (op->op_Id != id || (op->op_Mode & mode) == 0)
1263 if (rtype == NULL && op->op_RType)
1265 if (rtype && op->op_RType == NULL)
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)
1272 } else if (MatchType(op->op_LType, ltype) >
1273 SG_COMPAT_SUBCLASS) {
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)
1282 } else if (MatchType(op->op_RType, rtype) >
1283 SG_COMPAT_SUBCLASS) {
1287 return(op->op_Func);