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