1 /* operator.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* defintion of operators */
8 /* */
9 /*****************************************************************************/
10
11 #include <math.h>
12
13 #include "stdinc.h"
14 #include "errmsg.h"
15 #include "asmdef.h"
16 #include "asmerr.h"
17 #include "asmpars.h"
18 #include "asmrelocs.h"
19 #include "operator.h"
20
21 #define PromoteLValFlags() \
22 do \
23 { \
24 if (pErg->Typ != TempNone) \
25 { \
26 pErg->Flags |= (pLVal->Flags & eSymbolFlags_Promotable); \
27 pErg->AddrSpaceMask |= pLVal->AddrSpaceMask; \
28 if (pErg->DataSize == eSymbolSizeUnknown) pErg->DataSize = pLVal->DataSize; \
29 } \
30 } \
31 while (0)
32
33 #define PromoteLRValFlags() \
34 do \
35 { \
36 if (pErg->Typ != TempNone) \
37 { \
38 pErg->Flags |= ((pLVal->Flags | pRVal->Flags) & eSymbolFlags_Promotable); \
39 pErg->AddrSpaceMask |= pLVal->AddrSpaceMask | pRVal->AddrSpaceMask; \
40 if (pErg->DataSize == eSymbolSizeUnknown) pErg->DataSize = pLVal->DataSize; \
41 if (pErg->DataSize == eSymbolSizeUnknown) pErg->DataSize = pRVal->DataSize; \
42 } \
43 } \
44 while (0)
45
DummyOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)46 static void DummyOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
47 {
48 UNUSED(pLVal);
49 UNUSED(pRVal);
50 UNUSED(pErg);
51 }
52
OneComplOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)53 static void OneComplOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
54 {
55 UNUSED(pLVal);
56 pErg->Typ = TempInt;
57 pErg->Contents.Int = ~(pRVal->Contents.Int);
58 PromoteLValFlags();
59 }
60
ShLeftOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)61 static void ShLeftOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
62 {
63 pErg->Typ = TempInt;
64 pErg->Contents.Int = pLVal->Contents.Int << pRVal->Contents.Int;
65 PromoteLRValFlags();
66 }
67
ShRightOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)68 static void ShRightOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
69 {
70 pErg->Typ = TempInt;
71 pErg->Contents.Int = pLVal->Contents.Int >> pRVal->Contents.Int;
72 PromoteLRValFlags();
73 }
74
BitMirrorOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)75 static void BitMirrorOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
76 {
77 int z;
78
79 if ((pRVal->Contents.Int < 1) || (pRVal->Contents.Int > 32)) WrError(ErrNum_OverRange);
80 else
81 {
82 pErg->Typ = TempInt;
83 pErg->Contents.Int = (pLVal->Contents.Int >> pRVal->Contents.Int) << pRVal->Contents.Int;
84 pRVal->Contents.Int--;
85 for (z = 0; z <= pRVal->Contents.Int; z++)
86 {
87 if ((pLVal->Contents.Int & (1 << (pRVal->Contents.Int - z))) != 0)
88 pErg->Contents.Int |= (1 << z);
89 }
90 }
91 PromoteLRValFlags();
92 }
93
BinAndOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)94 static void BinAndOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
95 {
96 pErg->Typ = TempInt;
97 pErg->Contents.Int = pLVal->Contents.Int & pRVal->Contents.Int;
98 PromoteLRValFlags();
99 }
100
BinOrOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)101 static void BinOrOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
102 {
103 pErg->Typ = TempInt;
104 pErg->Contents.Int = pLVal->Contents.Int | pRVal->Contents.Int;
105 PromoteLRValFlags();
106 }
107
BinXorOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)108 static void BinXorOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
109 {
110 pErg->Typ = TempInt;
111 pErg->Contents.Int = pLVal->Contents.Int ^ pRVal->Contents.Int;
112 PromoteLRValFlags();
113 }
114
PotOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)115 static void PotOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
116 {
117 LargeInt HVal;
118
119 switch (pErg->Typ = pLVal->Typ)
120 {
121 case TempInt:
122 if (pRVal->Contents.Int < 0) pErg->Contents.Int = 0;
123 else
124 {
125 pErg->Contents.Int = 1;
126 while (pRVal->Contents.Int > 0)
127 {
128 if (pRVal->Contents.Int & 1)
129 pErg->Contents.Int *= pLVal->Contents.Int;
130 pRVal->Contents.Int >>= 1;
131 if (pRVal->Contents.Int != 0)
132 pLVal->Contents.Int *= pLVal->Contents.Int;
133 }
134 }
135 break;
136 case TempFloat:
137 if (pRVal->Contents.Float == 0.0)
138 pErg->Contents.Float = 1.0;
139 else if (pLVal->Contents.Float == 0.0)
140 pErg->Contents.Float = 0.0;
141 else if (pLVal->Contents.Float > 0)
142 pErg->Contents.Float = pow(pLVal->Contents.Float, pRVal->Contents.Float);
143 else if ((fabs(pRVal->Contents.Float) <= ((double)MaxLongInt)) && (floor(pRVal->Contents.Float) == pRVal->Contents.Float))
144 {
145 HVal = (LongInt) floor(pRVal->Contents.Float + 0.5);
146 if (HVal < 0)
147 {
148 pLVal->Contents.Float = 1 / pLVal->Contents.Float;
149 HVal = -HVal;
150 }
151 pErg->Contents.Float = 1.0;
152 while (HVal > 0)
153 {
154 if ((HVal & 1) == 1)
155 pErg->Contents.Float *= pLVal->Contents.Float;
156 pLVal->Contents.Float *= pLVal->Contents.Float;
157 HVal >>= 1;
158 }
159 }
160 else
161 {
162 WrError(ErrNum_InvArgPair);
163 pErg->Typ = TempNone;
164 }
165 break;
166 default:
167 break;
168 }
169 PromoteLRValFlags();
170 }
171
MultOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)172 static void MultOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
173 {
174 switch (pErg->Typ = pLVal->Typ)
175 {
176 case TempInt:
177 pErg->Contents.Int = pLVal->Contents.Int * pRVal->Contents.Int;
178 break;
179 case TempFloat:
180 pErg->Contents.Float = pLVal->Contents.Float * pRVal->Contents.Float;
181 break;
182 default:
183 break;
184 }
185 PromoteLRValFlags();
186 }
187
DivOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)188 static void DivOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
189 {
190 switch (pLVal->Typ)
191 {
192 case TempInt:
193 if (pRVal->Contents.Int == 0) WrError(ErrNum_DivByZero);
194 else
195 {
196 pErg->Typ = TempInt;
197 pErg->Contents.Int = pLVal->Contents.Int / pRVal->Contents.Int;
198 }
199 break;
200 case TempFloat:
201 if (pRVal->Contents.Float == 0.0) WrError(ErrNum_DivByZero);
202 else
203 {
204 pErg->Typ = TempFloat;
205 pErg->Contents.Float = pLVal->Contents.Float / pRVal->Contents.Float;
206 }
207 default:
208 break;
209 }
210 PromoteLRValFlags();
211 }
212
ModOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)213 static void ModOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
214 {
215 if (pRVal->Contents.Int == 0) WrError(ErrNum_DivByZero);
216 else
217 {
218 pErg->Typ = TempInt;
219 pErg->Contents.Int = pLVal->Contents.Int % pRVal->Contents.Int;
220 }
221 PromoteLRValFlags();
222 }
223
AddOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)224 static void AddOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
225 {
226 pErg->Typ = TempNone;
227 switch (pLVal->Typ)
228 {
229 case TempInt:
230 switch (pRVal->Typ)
231 {
232 case TempInt:
233 pErg->Typ = TempInt;
234 pErg->Contents.Int = pLVal->Contents.Int + pRVal->Contents.Int;
235 pErg->Relocs = MergeRelocs(&(pLVal->Relocs), &(pRVal->Relocs), TRUE);
236 break;
237 case TempString:
238 {
239 LargeInt RIntVal = DynString2Int(&pRVal->Contents.Ascii);
240
241 if ((RIntVal >= 0) && Int2DynString(&pErg->Contents.Ascii, RIntVal + pLVal->Contents.Int))
242 pErg->Typ = TempString;
243 break;
244 }
245 default:
246 break;
247 }
248 break;
249 case TempFloat:
250 pErg->Typ = TempFloat;
251 if (TempFloat == pRVal->Typ)
252 pErg->Contents.Float = pLVal->Contents.Float + pRVal->Contents.Float;
253 break;
254 case TempString:
255 switch (pRVal->Typ)
256 {
257 case TempString:
258 DynString2DynString(&pErg->Contents.Ascii, &pLVal->Contents.Ascii);
259 DynStringAppendDynString(&pErg->Contents.Ascii, &pRVal->Contents.Ascii);
260 pErg->Typ = TempString;
261 break;
262 case TempInt:
263 {
264 LargeInt LIntVal = DynString2Int(&pLVal->Contents.Ascii);
265
266 if ((LIntVal >= 0) && Int2DynString(&pErg->Contents.Ascii, LIntVal + pRVal->Contents.Int))
267 pErg->Typ = TempString;
268 break;
269 }
270 default:
271 break;
272 }
273 break;
274 default:
275 break;
276 }
277 PromoteLRValFlags();
278 }
279
SubOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)280 static void SubOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
281 {
282 switch (pErg->Typ = pLVal->Typ)
283 {
284 case TempInt:
285 pErg->Contents.Int = pLVal->Contents.Int - pRVal->Contents.Int;
286 pErg->Relocs = MergeRelocs(&(pLVal->Relocs), &(pRVal->Relocs), FALSE);
287 break;
288 case TempFloat:
289 pErg->Contents.Float = pLVal->Contents.Float - pRVal->Contents.Float;
290 break;
291 default:
292 break;
293 }
294 PromoteLRValFlags();
295 }
296
LogNotOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)297 static void LogNotOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
298 {
299 UNUSED(pLVal);
300 pErg->Typ = TempInt;
301 pErg->Contents.Int = (pRVal->Contents.Int == 0) ? 1 : 0;
302 PromoteLValFlags();
303 }
304
LogAndOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)305 static void LogAndOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
306 {
307 pErg->Typ = TempInt;
308 pErg->Contents.Int = ((pLVal->Contents.Int != 0) && (pRVal->Contents.Int != 0)) ? 1 : 0;
309 PromoteLRValFlags();
310 }
311
LogOrOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)312 static void LogOrOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
313 {
314 pErg->Typ = TempInt;
315 pErg->Contents.Int = ((pLVal->Contents.Int != 0) || (pRVal->Contents.Int != 0)) ? 1 : 0;
316 PromoteLRValFlags();
317 }
318
LogXorOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)319 static void LogXorOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
320 {
321 pErg->Typ = TempInt;
322 pErg->Contents.Int = ((pLVal->Contents.Int != 0) != (pRVal->Contents.Int != 0)) ? 1 : 0;
323 PromoteLRValFlags();
324 }
325
EqOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)326 static void EqOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
327 {
328 pErg->Typ = TempInt;
329 switch (pLVal->Typ)
330 {
331 case TempInt:
332 pErg->Contents.Int = (pLVal->Contents.Int == pRVal->Contents.Int) ? 1 : 0;
333 break;
334 case TempFloat:
335 pErg->Contents.Int = (pLVal->Contents.Float == pRVal->Contents.Float) ? 1 : 0;
336 break;
337 case TempString:
338 pErg->Contents.Int = (DynStringCmp(&pLVal->Contents.Ascii, &pRVal->Contents.Ascii) == 0) ? 1 : 0;
339 break;
340 default:
341 break;
342 }
343 PromoteLRValFlags();
344 }
345
GtOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)346 static void GtOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
347 {
348 pErg->Typ = TempInt;
349 switch (pLVal->Typ)
350 {
351 case TempInt:
352 pErg->Contents.Int = (pLVal->Contents.Int > pRVal->Contents.Int) ? 1 : 0;
353 break;
354 case TempFloat:
355 pErg->Contents.Int = (pLVal->Contents.Float > pRVal->Contents.Float) ? 1 : 0;
356 break;
357 case TempString:
358 pErg->Contents.Int = (DynStringCmp(&pLVal->Contents.Ascii, &pRVal->Contents.Ascii) > 0) ? 1 : 0;
359 break;
360 default:
361 break;
362 }
363 PromoteLRValFlags();
364 }
365
LtOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)366 static void LtOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
367 {
368 pErg->Typ = TempInt;
369 switch (pLVal->Typ)
370 {
371 case TempInt:
372 pErg->Contents.Int = (pLVal->Contents.Int < pRVal->Contents.Int) ? 1 : 0;
373 break;
374 case TempFloat:
375 pErg->Contents.Int = (pLVal->Contents.Float < pRVal->Contents.Float) ? 1 : 0;
376 break;
377 case TempString:
378 pErg->Contents.Int = (DynStringCmp(&pLVal->Contents.Ascii, &pRVal->Contents.Ascii) < 0) ? 1 : 0;
379 break;
380 default:
381 break;
382 }
383 PromoteLRValFlags();
384 }
385
LeOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)386 static void LeOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
387 {
388 pErg->Typ = TempInt;
389 switch (pLVal->Typ)
390 {
391 case TempInt:
392 pErg->Contents.Int = (pLVal->Contents.Int <= pRVal->Contents.Int) ? 1 : 0;
393 break;
394 case TempFloat:
395 pErg->Contents.Int = (pLVal->Contents.Float <= pRVal->Contents.Float) ? 1 : 0;
396 break;
397 case TempString:
398 pErg->Contents.Int = (DynStringCmp(&pLVal->Contents.Ascii, &pRVal->Contents.Ascii) <= 0) ? 1 : 0;
399 break;
400 default:
401 break;
402 }
403 PromoteLRValFlags();
404 }
405
GeOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)406 static void GeOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
407 {
408 pErg->Typ = TempInt;
409 switch (pLVal->Typ)
410 {
411 case TempInt:
412 pErg->Contents.Int = (pLVal->Contents.Int >= pRVal->Contents.Int) ? 1 : 0;
413 break;
414 case TempFloat:
415 pErg->Contents.Int = (pLVal->Contents.Float >= pRVal->Contents.Float) ? 1 : 0;
416 break;
417 case TempString:
418 pErg->Contents.Int = (DynStringCmp(&pLVal->Contents.Ascii, &pRVal->Contents.Ascii) >= 0) ? 1 : 0;
419 break;
420 default:
421 break;
422 }
423 PromoteLRValFlags();
424 }
425
UneqOp(TempResult * pErg,TempResult * pLVal,TempResult * pRVal)426 static void UneqOp(TempResult *pErg, TempResult *pLVal, TempResult *pRVal)
427 {
428 pErg->Typ = TempInt;
429 switch (pLVal->Typ)
430 {
431 case TempInt:
432 pErg->Contents.Int = (pLVal->Contents.Int != pRVal->Contents.Int) ? 1 : 0;
433 break;
434 case TempFloat:
435 pErg->Contents.Int = (pLVal->Contents.Float != pRVal->Contents.Float) ? 1 : 0;
436 break;
437 case TempString:
438 pErg->Contents.Int = (DynStringCmp(&pLVal->Contents.Ascii, &pRVal->Contents.Ascii) != 0) ? 1 : 0;
439 break;
440 default:
441 break;
442 }
443 PromoteLRValFlags();
444 }
445
446 #define Int2Int (TempInt | (TempInt << 4) )
447 #define Float2Float (TempFloat | (TempFloat << 4) )
448 #define String2String (TempString | (TempString << 4))
449 #define Int2String (TempInt | (TempString << 4))
450 #define String2Int (TempString | (TempInt << 4) )
451
452 const Operator Operators[] =
453 {
454 {" " , 1 , False, 0, { 0, 0, 0, 0, 0 }, DummyOp},
455 {"~" , 1 , False, 1, { TempInt << 4, 0, 0, 0, 0 }, OneComplOp},
456 {"<<", 2 , True , 3, { Int2Int, 0, 0, 0, 0 }, ShLeftOp},
457 {">>", 2 , True , 3, { Int2Int, 0, 0, 0, 0 }, ShRightOp},
458 {"><", 2 , True , 4, { Int2Int, 0, 0, 0, 0 }, BitMirrorOp},
459 {"&" , 1 , True , 5, { Int2Int, 0, 0, 0, 0 }, BinAndOp},
460 {"|" , 1 , True , 6, { Int2Int, 0, 0, 0, 0 }, BinOrOp},
461 {"!" , 1 , True , 7, { Int2Int, 0, 0, 0, 0 }, BinXorOp},
462 {"^" , 1 , True , 8, { Int2Int, Float2Float, 0, 0, 0 }, PotOp},
463 {"*" , 1 , True , 11, { Int2Int, Float2Float, 0, 0, 0 }, MultOp},
464 {"/" , 1 , True , 11, { Int2Int, Float2Float, 0, 0, 0 }, DivOp},
465 {"#" , 1 , True , 11, { Int2Int, 0, 0, 0, 0 }, ModOp},
466 {"+" , 1 , True , 13, { Int2Int, Float2Float, String2String, Int2String, String2Int }, AddOp},
467 {"-" , 1 , True , 13, { Int2Int, Float2Float, 0, 0, 0 }, SubOp},
468 {"~~", 2 , False, 2, { TempInt << 4, 0, 0, 0, 0 }, LogNotOp},
469 {"&&", 2 , True , 15, { Int2Int, 0, 0, 0, 0 }, LogAndOp},
470 {"||", 2 , True , 16, { Int2Int, 0, 0, 0, 0 }, LogOrOp},
471 {"!!", 2 , True , 17, { Int2Int, 0, 0, 0, 0 }, LogXorOp},
472 {"=" , 1 , True , 23, { Int2Int, Float2Float, String2String, 0, 0 }, EqOp},
473 {"==", 2 , True , 23, { Int2Int, Float2Float, String2String, 0, 0 }, EqOp},
474 {">" , 1 , True , 23, { Int2Int, Float2Float, String2String, 0, 0 }, GtOp},
475 {"<" , 1 , True , 23, { Int2Int, Float2Float, String2String, 0, 0 }, LtOp},
476 {"<=", 2 , True , 23, { Int2Int, Float2Float, String2String, 0, 0 }, LeOp},
477 {">=", 2 , True , 23, { Int2Int, Float2Float, String2String, 0, 0 }, GeOp},
478 {"<>", 2 , True , 23, { Int2Int, Float2Float, String2String, 0, 0 }, UneqOp},
479 /* termination marker */
480 {NULL, 0 , False, 0, { 0, 0, 0, 0, 0 }, NULL}
481 },
482 /* minus may have one or two operands */
483 MinusMonadicOperator =
484 {
485 "-" ,1 , False, 13, { TempInt << 4, TempFloat << 4, 0, 0, 0 }, SubOp
486 };
487