1 /* motpseudo.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS                                                                        */
6 /*                                                                           */
7 /* Commonly Used Motorola-Style Pseudo Instructions                          */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 /*****************************************************************************
12  * Includes
13  *****************************************************************************/
14 
15 #include "stdinc.h"
16 #include <ctype.h>
17 #include <string.h>
18 #include <math.h>
19 #include <assert.h>
20 
21 #include "bpemu.h"
22 #include "endian.h"
23 #include "ieeefloat.h"
24 #include "strutil.h"
25 #include "asmdef.h"
26 #include "asmsub.h"
27 #include "asmpars.h"
28 #include "asmitree.h"
29 #include "asmallg.h"
30 #include "asmcode.h"
31 #include "errmsg.h"
32 
33 #include "motpseudo.h"
34 
35 /*****************************************************************************
36  * Local Variables
37  *****************************************************************************/
38 
39 static Boolean M16Turn = False;
40 
41 /*****************************************************************************
42  * Local Functions
43  *****************************************************************************/
44 
CutRep(tStrComp * pDest,const tStrComp * pSrc,LongInt * pErg,tSymbolFlags * pFlags)45 static Boolean CutRep(tStrComp *pDest, const tStrComp *pSrc, LongInt *pErg, tSymbolFlags *pFlags)
46 {
47   tStrComp Src = *pSrc;
48 
49   if (pFlags)
50     *pFlags = eSymbolFlag_None;
51   KillPrefBlanksStrCompRef(&Src);
52   if (*Src.Str != '[')
53   {
54     *pErg = 1;
55     *pDest = *pSrc;
56     return True;
57   }
58   else
59   {
60     tStrComp RepArg;
61     char *pEnd;
62     Boolean OK;
63 
64     pEnd = QuotPos(Src.Str + 1, ']');
65     if (!pEnd)
66     {
67       WrError(ErrNum_BrackErr);
68       return False;
69     }
70     else
71     {
72       StrCompSplitRef(&RepArg, pDest, &Src, pEnd);
73       StrCompIncRefLeft(&RepArg, 1);
74       *pErg = EvalStrIntExpressionWithFlags(&RepArg, Int32, &OK, pFlags);
75       return OK;
76     }
77   }
78 }
79 
PutByte(Byte Value)80 static void PutByte(Byte Value)
81 {
82   if ((ListGran() == 1) || (!(CodeLen & 1)))
83     BAsmCode[CodeLen] = Value;
84   else if (M16Turn)
85     WAsmCode[CodeLen >> 1] = (((Word)BAsmCode[CodeLen -1]) << 8) | Value;
86   else
87     WAsmCode[CodeLen >> 1] = (((Word)Value) << 8) | BAsmCode[CodeLen -1];
88   CodeLen++;
89 }
90 
DecodeMotoBYT(Word Index)91 void DecodeMotoBYT(Word Index)
92 {
93   UNUSED(Index);
94 
95   if (ChkArgCnt(1, ArgCntMax))
96   {
97     ShortInt SpaceFlag = -1;
98     tStrComp *pArg, Arg;
99     LongInt Rep;
100     Boolean OK = True;
101 
102     forallargs (pArg, OK)
103     {
104       if (!*pArg->Str)
105       {
106         OK = FALSE;
107         WrError(ErrNum_EmptyArgument);
108         break;
109       }
110 
111       OK = CutRep(&Arg, pArg, &Rep, NULL);
112       if (!OK)
113         break;
114 
115       if (!strcmp(Arg.Str, "?"))
116       {
117         if (SpaceFlag == 0)
118         {
119           WrError(ErrNum_MixDBDS);
120           OK = FALSE;
121         }
122         else
123         {
124           SpaceFlag = 1;
125           CodeLen += Rep;
126         }
127       }
128       else if (SpaceFlag == 1)
129       {
130         WrError(ErrNum_MixDBDS);
131         OK = FALSE;
132       }
133       else
134       {
135         TempResult t;
136 
137         SpaceFlag = 0;
138 
139         EvalStrExpression(&Arg, &t);
140         switch (t.Typ)
141         {
142           case TempInt:
143           ToInt:
144             if (!mFirstPassUnknownOrQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int8))
145             {
146               WrStrErrorPos(ErrNum_OverRange, &Arg);
147               OK = False;
148             }
149             else if (SetMaxCodeLen(CodeLen + Rep))
150             {
151               WrError(ErrNum_CodeOverflow);
152               OK = False;
153             }
154             else
155             {
156               LongInt z2;
157 
158               for (z2 = 0; z2 < Rep; z2++)
159                 PutByte(t.Contents.Int);
160             }
161             break;
162 
163           case TempFloat:
164             WrStrErrorPos(ErrNum_StringOrIntButFloat, &Arg);
165             OK = False;
166             break;
167 
168           case TempString:
169           {
170             int l;
171 
172             if (MultiCharToInt(&t, 1))
173               goto ToInt;
174 
175             l = t.Contents.Ascii.Length;
176             TranslateString(t.Contents.Ascii.Contents, l);
177 
178             if (SetMaxCodeLen(CodeLen + (Rep * l)))
179             {
180               WrError(ErrNum_CodeOverflow);
181               OK = False;
182             }
183             else
184             {
185               LongInt z2;
186               int z3;
187 
188               for (z2 = 0; z2 < Rep; z2++)
189                 for (z3 = 0; z3 < l; z3++)
190                   PutByte(t.Contents.Ascii.Contents[z3]);
191             }
192             break;
193           }
194 
195           default:
196             OK = False;
197             break;
198         }
199       }
200     }
201 
202     if (!OK)
203       CodeLen = 0;
204     else
205     {
206       if (SpaceFlag == 1)
207         DontPrint = True;
208       if (*LabPart.Str)
209         SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
210     }
211   }
212 }
213 
PutADR(Word Value)214 static void PutADR(Word Value)
215 {
216   if (ListGran() > 1)
217   {
218     WAsmCode[CodeLen >> 1] = Value;
219     CodeLen += 2;
220   }
221   else if (M16Turn)
222   {
223     BAsmCode[CodeLen++] = Hi(Value);
224     BAsmCode[CodeLen++] = Lo(Value);
225   }
226   else
227   {
228     BAsmCode[CodeLen++] = Lo(Value);
229     BAsmCode[CodeLen++] = Hi(Value);
230   }
231 }
232 
DecodeMotoADR(Word Index)233 void DecodeMotoADR(Word Index)
234 {
235   UNUSED(Index);
236 
237   if (ChkArgCnt(1, ArgCntMax))
238   {
239     tStrComp *pArg, Arg;
240     Boolean OK = True;
241     LongInt Rep;
242     ShortInt SpaceFlag = -1;
243 
244     forallargs (pArg, OK)
245     {
246       if (!*pArg->Str)
247       {
248         OK = FALSE;
249         WrError(ErrNum_EmptyArgument);
250         break;
251       }
252 
253       OK = CutRep(&Arg, pArg, &Rep, NULL);
254       if (!OK)
255         break;
256 
257       if (!strcmp(Arg.Str, "?"))
258       {
259         if (SpaceFlag == 0)
260         {
261           WrError(ErrNum_MixDBDS);
262           OK = False;
263         }
264         else
265         {
266           SpaceFlag = 1;
267           CodeLen += 2 * Rep;
268         }
269       }
270       else if (SpaceFlag == 1)
271       {
272         WrError(ErrNum_MixDBDS);
273         OK = False;
274       }
275       else
276       {
277         TempResult Res;
278         LongInt z2, Cnt;
279 
280         SpaceFlag = 0;
281         EvalStrExpression(&Arg, &Res);
282 
283         switch (Res.Typ)
284         {
285           case TempInt:
286           ToInt:
287             if (mFirstPassUnknown(Res.Flags))
288               Res.Contents.Int &= 0xffff;
289             if (!mSymbolQuestionable(Res.Flags) && !RangeCheck(Res.Contents.Int, Int16))
290             {
291               WrError(ErrNum_OverRange);
292               Res.Typ = TempNone;
293             }
294             Cnt = 1;
295             break;
296           case TempString:
297             if (MultiCharToInt(&Res, 2))
298               goto ToInt;
299             Cnt = Res.Contents.Ascii.Length;
300             TranslateString(Res.Contents.Ascii.Contents, Res.Contents.Ascii.Length);
301             break;
302           case TempFloat:
303             WrStrErrorPos(ErrNum_StringOrIntButFloat, &Arg);
304             /* fall-through */
305           default:
306             Res.Typ = TempNone;
307             Cnt = 0;
308             break;
309         }
310         if (TempNone == Res.Typ)
311         {
312           OK = False;
313           break;
314         }
315 
316         if (SetMaxCodeLen(CodeLen + ((Cnt * Rep) << 1)))
317         {
318           WrError(ErrNum_CodeOverflow);
319           OK = False;
320           break;
321         }
322 
323         for (z2 = 0; z2 < Rep; z2++)
324           switch (Res.Typ)
325           {
326             case TempInt:
327               PutADR(Res.Contents.Int);
328               break;
329             case TempString:
330             {
331               unsigned z3;
332 
333               for (z3 = 0; z3 < Res.Contents.Ascii.Length; z3++)
334                 PutADR(Res.Contents.Ascii.Contents[z3]);
335               break;
336             }
337             default:
338               break;
339           }
340       }
341     }
342 
343     if (!OK)
344       CodeLen = 0;
345     else
346     {
347       if (SpaceFlag)
348         DontPrint = True;
349       if (*LabPart.Str)
350         SetSymbolOrStructElemSize(&LabPart, eSymbolSize16Bit);
351     }
352   }
353 }
354 
DecodeFCC(Word Index)355 static void DecodeFCC(Word Index)
356 {
357   String SVal;
358   Boolean OK;
359   tStrComp *pArg, Arg;
360   int z3, l;
361   LongInt Rep,z2;
362   UNUSED(Index);
363 
364   if (ChkArgCnt(1, ArgCntMax))
365   {
366     OK = True;
367 
368     forallargs (pArg, OK)
369     {
370       if (!*pArg->Str)
371       {
372         OK = FALSE;
373         WrError(ErrNum_EmptyArgument);
374         break;
375       }
376 
377       OK = CutRep(&Arg, pArg, &Rep, NULL);
378       if (!OK)
379         break;
380 
381       EvalStrStringExpression(&Arg, &OK, SVal);
382       if (OK)
383       {
384         if (SetMaxCodeLen(CodeLen + Rep * strlen(SVal)))
385         {
386           WrError(ErrNum_CodeOverflow);
387           OK = False;
388         }
389         else
390         {
391           l = strlen(SVal);
392           TranslateString(SVal, l);
393           for (z2 = 0; z2 < Rep; z2++)
394             for (z3 = 0; z3 < l; z3++)
395               PutByte(SVal[z3]);
396         }
397       }
398     }
399 
400     if (!OK)
401       CodeLen = 0;
402     else if (*LabPart.Str)
403       SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
404   }
405 }
406 
DecodeMotoDFS(Word Index)407 void DecodeMotoDFS(Word Index)
408 {
409   UNUSED(Index);
410 
411   if (ChkArgCnt(1, 1))
412   {
413     Word HVal16;
414     Boolean OK;
415     tSymbolFlags Flags;
416 
417     HVal16 = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &OK, &Flags);
418     if (mFirstPassUnknown(Flags))
419       WrError(ErrNum_FirstPassCalc);
420     else if (OK)
421     {
422       DontPrint = True;
423       CodeLen = HVal16;
424       if (!HVal16)
425         WrError(ErrNum_NullResMem);
426       BookKeeping();
427       if (*LabPart.Str)
428         SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
429     }
430   }
431 }
432 
433 /*****************************************************************************
434  * Global Functions
435  *****************************************************************************/
436 
DecodeMotoPseudo(Boolean Turn)437 Boolean DecodeMotoPseudo(Boolean Turn)
438 {
439   static PInstTable InstTable = NULL;
440 
441   if (!InstTable)
442   {
443     InstTable = CreateInstTable(17);
444     AddInstTable(InstTable, "BYT", 0, DecodeMotoBYT);
445     AddInstTable(InstTable, "FCB", 0, DecodeMotoBYT);
446     AddInstTable(InstTable, "ADR", 0, DecodeMotoADR);
447     AddInstTable(InstTable, "FDB", 0, DecodeMotoADR);
448     AddInstTable(InstTable, "FCC", 0, DecodeFCC);
449     AddInstTable(InstTable, "DFS", 0, DecodeMotoDFS);
450     AddInstTable(InstTable, "RMB", 0, DecodeMotoDFS);
451   }
452 
453   M16Turn = Turn;
454   return LookupInstTable(InstTable, OpPart.Str);
455 }
456 
DigIns(char Ch,int Pos,Byte * pDest)457 static void DigIns(char Ch, int Pos, Byte *pDest)
458 {
459   int bytepos = Pos >> 1, bitpos = (Pos & 1) << 2;
460   Byte dig = Ch - '0';
461 
462   pDest[bytepos] |= (dig << bitpos);
463 }
464 
ConvertMotoFloatDec(Double F,Byte * pDest,Boolean NeedsBig)465 void ConvertMotoFloatDec(Double F, Byte *pDest, Boolean NeedsBig)
466 {
467   char s[30], Man[30], Exp[30];
468   char *pSplit;
469   int z, ManLen, ExpLen;
470   Byte epos;
471 
472   UNUSED(NeedsBig);
473 
474   /* convert to ASCII, split mantissa & exponent */
475 
476   as_snprintf(s, sizeof(s), "%0.16e", F);
477   pSplit = strchr(s, HexStartCharacter + ('e' - 'a'));
478   if (!pSplit)
479   {
480     strcpy(Man, s);
481     strcpy(Exp, "+0000");
482   }
483   else
484   {
485     *pSplit = '\0';
486     strcpy(Man, s);
487     strcpy(Exp, pSplit + 1);
488   }
489 
490   memset(pDest, 0, 12);
491 
492   /* handle mantissa sign */
493 
494   if (*Man == '-')
495   {
496     pDest[11] |= 0x80; strmov(Man, Man + 1);
497   }
498   else if (*Man == '+')
499     strmov(Man, Man + 1);
500 
501   /* handle exponent sign */
502 
503   if (*Exp == '-')
504   {
505     pDest[11] |= 0x40;
506     strmov(Exp, Exp + 1);
507   }
508   else if (*Exp == '+')
509     strmov(Exp, Exp + 1);
510 
511   /* integral part of mantissa (one digit) */
512 
513   DigIns(*Man, 16, pDest);
514   strmov(Man, Man + 2);
515 
516   /* truncate mantissa if we have more digits than we can represent */
517 
518   if (strlen(Man) > 16)
519     Man[16] = '\0';
520 
521   /* insert mantissa digits */
522 
523   ManLen = strlen(Man);
524   for (z = 0; z < ManLen; z++)
525     DigIns(Man[z], 15 - z, pDest);
526 
527   /* truncate exponent if we have more digits than we can represent - this should
528      never occur since an IEEE double is limited to ~1E308 and we have for digits */
529 
530   if (strlen(Exp) > 4)
531     strmov(Exp, Exp + strlen(Exp) - 4);
532 
533   /* insert exponent bits */
534 
535   ExpLen = strlen(Exp);
536   for (z = ExpLen - 1; z >= 0; z--)
537   {
538     epos = ExpLen - 1 - z;
539     if (epos == 3)
540       DigIns(Exp[z], 19, pDest);
541     else
542       DigIns(Exp[z], epos + 20, pDest);
543   }
544 
545   if (BigEndian)
546     WSwap(pDest, 12);
547 }
548 
EnterByte(LargeWord b)549 static void EnterByte(LargeWord b)
550 {
551   if (((CodeLen & 1) == 1) && (!BigEndian) && (ListGran() != 1))
552   {
553     BAsmCode[CodeLen    ] = BAsmCode[CodeLen - 1];
554     BAsmCode[CodeLen - 1] = b;
555   }
556   else
557   {
558     BAsmCode[CodeLen] = b;
559   }
560   CodeLen++;
561 }
562 
EnterWord(LargeWord w)563 static void EnterWord(LargeWord w)
564 {
565   if (ListGran() == 1)
566   {
567     BAsmCode[CodeLen    ] = Hi(w);
568     BAsmCode[CodeLen + 1] = Lo(w);
569   }
570   else
571     WAsmCode[CodeLen >> 1] = w;
572   CodeLen += 2;
573 }
574 
EnterPointer(LargeWord w)575 static void EnterPointer(LargeWord w)
576 {
577   EnterByte((w >> 16) & 0xff);
578   EnterByte((w >>  8) & 0xff);
579   EnterByte((w      ) & 0xff);
580 }
581 
EnterLWord(LargeWord l)582 static void EnterLWord(LargeWord l)
583 {
584   if (ListGran() == 1)
585   {
586     BAsmCode[CodeLen    ] = (l >> 24) & 0xff;
587     BAsmCode[CodeLen + 1] = (l >> 16) & 0xff;
588     BAsmCode[CodeLen + 2] = (l >>  8) & 0xff;
589     BAsmCode[CodeLen + 3] = (l      ) & 0xff;
590   }
591   else
592   {
593     WAsmCode[(CodeLen >> 1)    ] = (l >> 16) & 0xffff;
594     WAsmCode[(CodeLen >> 1) + 1] = (l      ) & 0xffff;
595   }
596   CodeLen += 4;
597 }
598 
EnterQWord(LargeWord q)599 static void EnterQWord(LargeWord q)
600 {
601   if (ListGran() == 1)
602   {
603 #ifdef HAS64
604     BAsmCode[CodeLen    ] = (q >> 56) & 0xff;
605     BAsmCode[CodeLen + 1] = (q >> 48) & 0xff;
606     BAsmCode[CodeLen + 2] = (q >> 40) & 0xff;
607     BAsmCode[CodeLen + 3] = (q >> 32) & 0xff;
608 #else
609     /* TempResult is LargeInt, so sign-extend */
610     BAsmCode[CodeLen    ] =
611     BAsmCode[CodeLen + 1] =
612     BAsmCode[CodeLen + 2] =
613     BAsmCode[CodeLen + 3] = (q & 0x80000000ul) ? 0xff : 0x00;
614 #endif
615     BAsmCode[CodeLen + 4] = (q >> 24) & 0xff;
616     BAsmCode[CodeLen + 5] = (q >> 16) & 0xff;
617     BAsmCode[CodeLen + 6] = (q >>  8) & 0xff;
618     BAsmCode[CodeLen + 7] = (q      ) & 0xff;
619   }
620   else
621   {
622 #ifdef HAS64
623     WAsmCode[(CodeLen >> 1)    ] = (q >> 48) & 0xffff;
624     WAsmCode[(CodeLen >> 1) + 1] = (q >> 32) & 0xffff;
625 #else
626     /* TempResult is LargeInt, so sign-extend */
627     WAsmCode[(CodeLen >> 1)    ] =
628     WAsmCode[(CodeLen >> 1) + 1] = (q & 0x80000000ul) ? 0xffff : 0x00;
629 #endif
630     WAsmCode[(CodeLen >> 1) + 2] = (q >> 16) & 0xffff;
631     WAsmCode[(CodeLen >> 1) + 3] = (q      ) & 0xffff;
632   }
633   CodeLen += 8;
634 }
635 
EnterIEEE2(Word * pField)636 static void EnterIEEE2(Word *pField)
637 {
638   if (ListGran() == 1)
639   {
640      BAsmCode[CodeLen    ] = Hi(pField[1]);
641      BAsmCode[CodeLen + 1] = Lo(pField[0]);
642   }
643   else
644   {
645     WAsmCode[(CodeLen >> 1)    ] = pField[0];
646   }
647   CodeLen += 2;
648 }
649 
EnterIEEE4(Word * pField)650 static void EnterIEEE4(Word *pField)
651 {
652   if (ListGran() == 1)
653   {
654      BAsmCode[CodeLen    ] = Hi(pField[1]);
655      BAsmCode[CodeLen + 1] = Lo(pField[1]);
656      BAsmCode[CodeLen + 2] = Hi(pField[0]);
657      BAsmCode[CodeLen + 3] = Lo(pField[0]);
658   }
659   else
660   {
661     WAsmCode[(CodeLen >> 1)    ] = pField[1];
662     WAsmCode[(CodeLen >> 1) + 1] = pField[0];
663   }
664   CodeLen += 4;
665 }
666 
EnterIEEE8(Word * pField)667 static void EnterIEEE8(Word *pField)
668 {
669   if (ListGran() == 1)
670   {
671     BAsmCode[CodeLen    ] = Hi(pField[3]);
672     BAsmCode[CodeLen + 1] = Lo(pField[3]);
673     BAsmCode[CodeLen + 2] = Hi(pField[2]);
674     BAsmCode[CodeLen + 3] = Lo(pField[2]);
675     BAsmCode[CodeLen + 4] = Hi(pField[1]);
676     BAsmCode[CodeLen + 5] = Lo(pField[1]);
677     BAsmCode[CodeLen + 6] = Hi(pField[0]);
678     BAsmCode[CodeLen + 7] = Lo(pField[0]);
679   }
680   else
681   {
682     WAsmCode[(CodeLen >> 1)    ] = pField[3];
683     WAsmCode[(CodeLen >> 1) + 1] = pField[2];
684     WAsmCode[(CodeLen >> 1) + 2] = pField[1];
685     WAsmCode[(CodeLen >> 1) + 3] = pField[0];
686   }
687   CodeLen += 8;
688 }
689 
EnterIEEE10(Word * pField)690 static void EnterIEEE10(Word *pField)
691 {
692   if (ListGran() == 1)
693   {
694     BAsmCode[CodeLen    ] = Hi(pField[4]);
695     BAsmCode[CodeLen + 1] = Lo(pField[4]);
696     BAsmCode[CodeLen + 2] = 0;
697     BAsmCode[CodeLen + 3] = 0;
698     BAsmCode[CodeLen + 4] = Hi(pField[3]);
699     BAsmCode[CodeLen + 5] = Lo(pField[3]);
700     BAsmCode[CodeLen + 6] = Hi(pField[2]);
701     BAsmCode[CodeLen + 7] = Lo(pField[2]);
702     BAsmCode[CodeLen + 8] = Hi(pField[1]);
703     BAsmCode[CodeLen + 9] = Lo(pField[1]);
704     BAsmCode[CodeLen +10] = Hi(pField[0]);
705     BAsmCode[CodeLen +11] = Lo(pField[0]);
706   }
707   else
708   {
709     WAsmCode[(CodeLen >> 1)    ] = pField[4];
710     WAsmCode[(CodeLen >> 1) + 1] = 0;
711     WAsmCode[(CodeLen >> 1) + 2] = pField[3];
712     WAsmCode[(CodeLen >> 1) + 3] = pField[2];
713     WAsmCode[(CodeLen >> 1) + 4] = pField[1];
714     WAsmCode[(CodeLen >> 1) + 5] = pField[0];
715   }
716   CodeLen += 12;
717 }
718 
EnterMotoFloatDec(Word * pField)719 static void EnterMotoFloatDec(Word *pField)
720 {
721   if (ListGran() == 1)
722   {
723     BAsmCode[CodeLen    ] = Hi(pField[5]);
724     BAsmCode[CodeLen + 1] = Lo(pField[5]);
725     BAsmCode[CodeLen + 2] = Hi(pField[4]);
726     BAsmCode[CodeLen + 3] = Lo(pField[4]);
727     BAsmCode[CodeLen + 4] = Hi(pField[3]);
728     BAsmCode[CodeLen + 5] = Lo(pField[3]);
729     BAsmCode[CodeLen + 6] = Hi(pField[2]);
730     BAsmCode[CodeLen + 7] = Lo(pField[2]);
731     BAsmCode[CodeLen + 8] = Hi(pField[1]);
732     BAsmCode[CodeLen + 9] = Lo(pField[1]);
733     BAsmCode[CodeLen +10] = Hi(pField[0]);
734     BAsmCode[CodeLen +11] = Lo(pField[0]);
735   }
736   else
737   {
738     WAsmCode[(CodeLen >> 1)    ] = pField[5];
739     WAsmCode[(CodeLen >> 1) + 1] = pField[4];
740     WAsmCode[(CodeLen >> 1) + 2] = pField[3];
741     WAsmCode[(CodeLen >> 1) + 3] = pField[2];
742     WAsmCode[(CodeLen >> 1) + 4] = pField[1];
743     WAsmCode[(CodeLen >> 1) + 5] = pField[0];
744   }
745   CodeLen += 12;
746 }
747 
Double_2_ieee2_wrap(Double Inp,Byte * pDest,Boolean BigEndian)748 static void Double_2_ieee2_wrap(Double Inp, Byte *pDest, Boolean BigEndian)
749 {
750   (void)Double_2_ieee2(Inp, pDest, BigEndian);
751 }
752 
AddMoto16PseudoONOFF(void)753 void AddMoto16PseudoONOFF(void)
754 {
755   AddONOFF("PADDING", &DoPadding, DoPaddingName, False);
756 }
757 
758 /*!------------------------------------------------------------------------
759  * \fn     GetWSize(tSymbolSize OpSize)
760  * \brief  return size in bytes of data type
761  * \param  OpSize data type
762  * \return size in bytes
763  * ------------------------------------------------------------------------ */
764 
GetWSize(tSymbolSize OpSize)765 static Word GetWSize(tSymbolSize OpSize)
766 {
767   switch (OpSize)
768   {
769     case eSymbolSize8Bit:
770       return 1;
771     case eSymbolSize16Bit:
772       return 2;
773     case eSymbolSize24Bit:
774       return 3;
775     case eSymbolSize32Bit:
776       return 4;
777     case eSymbolSize64Bit:
778       return 8;
779     case eSymbolSizeFloat32Bit:
780       return 4;
781     case eSymbolSizeFloat64Bit:
782       return 8;
783 
784     /* NOTE: Double_2_ieee10() creates 10 bytes, but WSize is set to 12 (two
785        padding bytes in binary representation).  This means that WSwap() will
786        swap 12 instead of 10 bytes, which doesn't hurt, since TurnField is
787        large enough and the two (garbage) bytes at the end will not be used
788        by EnterIEEE10() anyway: */
789 
790     case eSymbolSizeFloat96Bit:
791       return 12;
792     case eSymbolSizeFloatDec96Bit:
793       return 12;
794     case eSymbolSizeFloat16Bit:
795       return 2;
796     default:
797       return 0;
798   }
799 }
800 
801 /*!------------------------------------------------------------------------
802  * \fn     DecodeMotoDC(void)
803  * \brief  decode DC.x instruction
804  * ------------------------------------------------------------------------ */
805 
DecodeMotoDC(tSymbolSize OpSize,Boolean Turn)806 void DecodeMotoDC(tSymbolSize OpSize, Boolean Turn)
807 {
808   ShortInt SpaceFlag;
809   tStrComp *pArg, Arg;
810   LongInt z2, WSize, Rep = 0;
811   char *zp;
812   Boolean OK;
813   TempResult t;
814   tSymbolFlags Flags;
815   void (*EnterInt)(LargeWord) = NULL;
816   void (*ConvertFloat)(Double, Byte*, Boolean) = NULL;
817   void (*EnterFloat)(Word*) = NULL;
818   void (*Swap)(void*, int) = NULL;
819   IntType IntTypeEnum = UInt1;
820   FloatType FloatTypeEnum = Float32;
821   Boolean PadBeforeStart = Odd(EProgCounter()) && DoPadding && (OpSize != eSymbolSize8Bit);
822 
823   UNUSED(Turn);
824 
825   if (*LabPart.Str)
826     SetSymbolOrStructElemSize(&LabPart, OpSize);
827 
828   if (!ChkArgCnt(1, ArgCntMax))
829     return;
830 
831   if (OpSize < 0)
832     OpSize = eSymbolSize16Bit;
833 
834   WSize = GetWSize(OpSize);
835   switch (OpSize)
836   {
837     case eSymbolSize8Bit:
838       EnterInt = EnterByte;
839       IntTypeEnum = Int8;
840       break;
841     case eSymbolSize16Bit:
842       EnterInt = EnterWord;
843       IntTypeEnum = Int16;
844       break;
845     case eSymbolSize24Bit:
846       EnterInt = EnterPointer;
847       IntTypeEnum = Int24;
848       break;
849     case eSymbolSize32Bit:
850       EnterInt = EnterLWord;
851       IntTypeEnum = Int32;
852       break;
853     case eSymbolSize64Bit:
854       EnterInt = EnterQWord;
855 #ifdef HAS64
856       IntTypeEnum = Int64;
857 #else
858       IntTypeEnum = Int32;
859 #endif
860       break;
861     case eSymbolSizeFloat16Bit:
862       ConvertFloat = Double_2_ieee2_wrap;
863       EnterFloat = EnterIEEE2;
864       FloatTypeEnum = Float16;
865       Swap = WSwap;
866       break;
867     case eSymbolSizeFloat32Bit:
868       ConvertFloat = Double_2_ieee4;
869       EnterFloat = EnterIEEE4;
870       FloatTypeEnum = Float32;
871       Swap = DWSwap;
872       break;
873     case eSymbolSizeFloat64Bit:
874       ConvertFloat = Double_2_ieee8;
875       EnterFloat = EnterIEEE8;
876       FloatTypeEnum = Float64;
877       Swap = QWSwap;
878       break;
879 
880     /* NOTE: Double_2_ieee10() creates 10 bytes, but WSize is set to 12 (two
881        padding bytes in binary representation).  This means that WSwap() will
882        swap 12 instead of 10 bytes, which doesn't hurt, since TurnField is
883        large enough and the two (garbage) bytes at the end will not be used
884        by EnterIEEE10() anyway: */
885 
886     case eSymbolSizeFloat96Bit:
887       ConvertFloat = Double_2_ieee10;
888       EnterFloat = EnterIEEE10;
889       FloatTypeEnum = Float80;
890       Swap = WSwap;
891       break;
892     case eSymbolSizeFloatDec96Bit:
893       ConvertFloat = ConvertMotoFloatDec;
894       EnterFloat = EnterMotoFloatDec;
895       FloatTypeEnum = FloatDec;
896       break;
897     default:
898       break;
899   }
900 
901   OK = True;
902   SpaceFlag = -1;
903 
904   forallargs (pArg, OK)
905   {
906     if (!*pArg->Str)
907     {
908       OK = FALSE;
909       WrError(ErrNum_EmptyArgument);
910       break;
911     }
912 
913     OK = CutRep(&Arg, pArg, &Rep, &Flags);
914     if (!OK)
915       break;
916     if (mFirstPassUnknown(Flags))
917     {
918       OK = FALSE;
919       WrError(ErrNum_FirstPassCalc);
920       break;
921     }
922 
923     if (!strcmp(Arg.Str, "?"))
924     {
925       if (SpaceFlag == 0)
926       {
927         WrError(ErrNum_MixDBDS);
928         OK = FALSE;
929       }
930       else
931       {
932         if (PadBeforeStart)
933         {
934           InsertPadding(1, True);
935           PadBeforeStart = False;
936         }
937 
938         SpaceFlag = 1;
939         CodeLen += (Rep * WSize);
940       }
941     }
942     else if (SpaceFlag == 1)
943     {
944       WrError(ErrNum_MixDBDS);
945       OK = FALSE;
946     }
947     else
948     {
949       SpaceFlag = 0;
950 
951       if (PadBeforeStart)
952       {
953         InsertPadding(1, False);
954         PadBeforeStart = False;
955       }
956 
957       EvalStrExpression(&Arg, &t);
958 
959       switch (t.Typ)
960       {
961         case TempInt:
962         ToInt:
963           if (!EnterInt)
964           {
965             if (ConvertFloat && EnterFloat)
966             {
967               t.Contents.Float = t.Contents.Int;
968               t.Typ = TempFloat;
969               goto HandleFloat;
970             }
971             else
972             {
973               WrStrErrorPos(ErrNum_StringOrIntButFloat, pArg);
974               OK = False;
975             }
976           }
977           else if (!mFirstPassUnknownOrQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, IntTypeEnum))
978           {
979             WrError(ErrNum_OverRange);
980             OK = False;
981           }
982           else if (SetMaxCodeLen(CodeLen + (Rep * WSize)))
983           {
984             WrError(ErrNum_CodeOverflow);
985             OK = False;
986           }
987           else
988             for (z2 = 0; z2 < Rep; z2++)
989               EnterInt(t.Contents.Int);
990           break;
991         HandleFloat:
992         case TempFloat:
993           if ((!ConvertFloat) || (!EnterFloat))
994           {
995             WrStrErrorPos(ErrNum_StringOrIntButFloat, pArg);
996             OK = False;
997           }
998           else if (!FloatRangeCheck(t.Contents.Float, FloatTypeEnum))
999           {
1000             WrError(ErrNum_OverRange);
1001             OK = False;
1002           }
1003           else if (SetMaxCodeLen(CodeLen + (Rep * WSize)))
1004           {
1005             WrError(ErrNum_CodeOverflow);
1006             OK = False;
1007           }
1008           else
1009           {
1010             Word TurnField[8];
1011 
1012             ConvertFloat(t.Contents.Float, (Byte *) TurnField, BigEndian);
1013             if (BigEndian  && Swap)
1014               Swap((void*) TurnField, WSize);
1015             for (z2 = 0; z2 < Rep; z2++)
1016               EnterFloat(TurnField);
1017           }
1018           break;
1019         case TempString:
1020           if (MultiCharToInt(&t, (WSize < 8) ? WSize : 8))
1021             goto ToInt;
1022           if (!EnterInt)
1023           {
1024             if (ConvertFloat && EnterFloat)
1025             {
1026               if (SetMaxCodeLen(CodeLen + (Rep * WSize * t.Contents.Ascii.Length)))
1027               {
1028                 WrError(ErrNum_CodeOverflow);
1029                 OK = False;
1030               }
1031               else
1032               {
1033                 for (z2 = 0; z2 < Rep; z2++)
1034                   for (zp = t.Contents.Ascii.Contents; zp < t.Contents.Ascii.Contents + t.Contents.Ascii.Length; zp++)
1035                   {
1036                     Word TurnField[8];
1037 
1038                     ConvertFloat(CharTransTable[(usint) (*zp & 0xff)], (Byte *) TurnField, BigEndian);
1039                     if ((BigEndian)  && (Swap))
1040                       Swap((void*) TurnField, WSize);
1041                     EnterFloat(TurnField);
1042                   }
1043               }
1044             }
1045             else
1046             {
1047               WrError(ErrNum_FloatButString);
1048               OK = False;
1049             }
1050           }
1051           else if (SetMaxCodeLen(CodeLen + Rep * t.Contents.Ascii.Length))
1052           {
1053             WrError(ErrNum_CodeOverflow);
1054             OK = False;
1055           }
1056           else
1057             for (z2 = 0; z2 < Rep; z2++)
1058               for (zp = t.Contents.Ascii.Contents; zp < t.Contents.Ascii.Contents + t.Contents.Ascii.Length; EnterInt(CharTransTable[((usint) *(zp++)) & 0xff]));
1059           break;
1060         case TempNone:
1061           OK = False;
1062           break;
1063         default:
1064           assert(0);
1065       }
1066 
1067     }
1068   }
1069 
1070   /* purge results if an error occured */
1071 
1072   if (!OK) CodeLen = 0;
1073 
1074   /* just space reservation ? */
1075 
1076   else if (SpaceFlag == 1)
1077     DontPrint = True;
1078 }
1079 
DecodeMoto16Pseudo(tSymbolSize OpSize,Boolean Turn)1080 Boolean DecodeMoto16Pseudo(tSymbolSize OpSize, Boolean Turn)
1081 {
1082   LongInt NewPC, HVal;
1083   Boolean ValOK;
1084   tSymbolFlags Flags;
1085   Boolean PadBeforeStart;
1086 
1087   if (OpSize < 0)
1088     OpSize = eSymbolSize16Bit;
1089 
1090   PadBeforeStart = Odd(EProgCounter()) && DoPadding && (OpSize != eSymbolSize8Bit);
1091   if (*OpPart.Str != 'D')
1092     return False;
1093 
1094   if (Memo("DC"))
1095   {
1096     DecodeMotoDC(OpSize, Turn);
1097     return True;
1098   }
1099 
1100   if (Memo("DS"))
1101   {
1102     Word WSize = GetWSize(OpSize);
1103 
1104     if (ChkArgCnt(1, 1))
1105     {
1106       HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &Flags);
1107       if (mFirstPassUnknown(Flags))
1108         WrError(ErrNum_FirstPassCalc);
1109       if (ValOK && !mFirstPassUnknown(Flags))
1110       {
1111         Boolean OddSize = (eSymbolSize8Bit == OpSize) || (eSymbolSize24Bit == OpSize);
1112 
1113         if (PadBeforeStart)
1114         {
1115           InsertPadding(1, True);
1116           PadBeforeStart = False;
1117         }
1118 
1119         DontPrint = True;
1120 
1121         /* value of 0 means aligning the PC.  Doesn't make sense for bytes and 24 bit values */
1122 
1123         if ((HVal == 0) && !OddSize)
1124         {
1125           NewPC = EProgCounter() + WSize - 1;
1126           NewPC -= NewPC % WSize;
1127           CodeLen = NewPC - EProgCounter();
1128           if (CodeLen == 0)
1129           {
1130             DontPrint = False;
1131             if (WSize == 1)
1132               WrError(ErrNum_NullResMem);
1133           }
1134         }
1135         else
1136           CodeLen = HVal * WSize;
1137         if (DontPrint)
1138           BookKeeping();
1139       }
1140     }
1141     if (*LabPart.Str)
1142       SetSymbolOrStructElemSize(&LabPart, OpSize);
1143     return True;
1144   }
1145 
1146   return False;
1147 }
1148 
DecodeMoto16AttrSizeCore(char SizeSpec,tSymbolSize * pResult,Boolean Allow24)1149 static Boolean DecodeMoto16AttrSizeCore(char SizeSpec, tSymbolSize *pResult, Boolean Allow24)
1150 {
1151   switch (as_toupper(SizeSpec))
1152   {
1153     case 'B': *pResult = eSymbolSize8Bit; break;
1154     case 'W': *pResult = eSymbolSize16Bit; break;
1155     case 'L': *pResult = eSymbolSize32Bit; break;
1156     case 'Q': *pResult = eSymbolSize64Bit; break;
1157     case 'S': *pResult = eSymbolSizeFloat32Bit; break;
1158     case 'D': *pResult = eSymbolSizeFloat64Bit; break;
1159     case 'X': *pResult = eSymbolSizeFloat96Bit; break;
1160     case 'C': *pResult = eSymbolSizeFloat16Bit; break;
1161     case 'P': *pResult = Allow24 ? eSymbolSize24Bit : eSymbolSizeFloatDec96Bit; break;
1162     case '\0': break;
1163     default:
1164       return False;
1165   }
1166   return True;
1167 }
1168 
1169 /*!------------------------------------------------------------------------
1170  * \fn     DecodeMoto16AttrSize(char SizeSpec, tSymbolSize *pResult, Boolean Allow24)
1171  * \brief  decode Motorola-style operand size character
1172  * \param  SizeSpec size specifier character
1173  * \param  pResult returns result size
1174  * \param  Allow24 allow 'p' as specifier for 24 Bits (S12Z-specific)
1175  * \return True if decoded
1176  * ------------------------------------------------------------------------ */
1177 
DecodeMoto16AttrSize(char SizeSpec,tSymbolSize * pResult,Boolean Allow24)1178 Boolean DecodeMoto16AttrSize(char SizeSpec, tSymbolSize *pResult, Boolean Allow24)
1179 {
1180   if (!DecodeMoto16AttrSizeCore(SizeSpec, pResult, Allow24))
1181   {
1182     WrError(ErrNum_UndefAttr);
1183     return False;
1184   }
1185   return True;
1186 }
1187 
DecodeMoto16AttrSizeStr(const struct sStrComp * pSizeSpec,tSymbolSize * pResult,Boolean Allow24)1188 Boolean DecodeMoto16AttrSizeStr(const struct sStrComp *pSizeSpec, tSymbolSize *pResult, Boolean Allow24)
1189 {
1190   if ((strlen(pSizeSpec->Str) > 1)
1191    || !DecodeMoto16AttrSizeCore(*pSizeSpec->Str, pResult, Allow24))
1192   {
1193     WrStrErrorPos(ErrNum_UndefAttr, pSizeSpec);
1194     return False;
1195   }
1196   return True;
1197 }
1198