1 /* code3206x.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4 /*                                                                           */
5 /* AS-Portierung                                                             */
6 /*                                                                           */
7 /* Codegenerator TMS320C6x                                                   */
8 /*                                                                           */
9 /*****************************************************************************/
10 
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14 #include "endian.h"
15 
16 #include "strutil.h"
17 #include "bpemu.h"
18 #include "nls.h"
19 #include "asmdef.h"
20 #include "asmsub.h"
21 #include "asmpars.h"
22 #include "asmcode.h"
23 #include "errmsg.h"
24 #include "ieeefloat.h"
25 #include "codepseudo.h"
26 #include "asmitree.h"
27 #include "codevars.h"
28 #include "nlmessages.h"
29 #include "as.rsc"
30 
31 /*---------------------------------------------------------------------------*/
32 
33 typedef enum
34 {
35   NoUnit, L1, L2, S1, S2, M1, M2, D1, D2, LastUnit, UnitCnt
36 } TUnit;
37 
38 #ifdef __cplusplus
39 # include "code3206x.hpp"
40 #endif
41 
42 typedef struct
43 {
44   LongInt OpCode;
45   LongInt SrcMask, SrcMask2, DestMask;
46   Byte CrossUsed; /* Bit 0 -->X1 benutzt, Bit 1 -->X2 benutzt */
47   Byte AddrUsed;  /* Bit 0 -->Addr1 benutzt, Bit 1 -->Addr2 benutzt
48                   Bit 2 -->LdSt1 benutzt, Bit 3 -->LdSt2 benutzt */
49   Byte LongUsed;  /* Bit 0 -->lange Quelle, Bit 1-->langes Ziel */
50   Boolean AbsBranch;
51   Boolean StoreUsed, LongSrc, LongDest;
52   TUnit U;
53 } InstrRec;
54 
55 typedef struct
56 {
57   LongInt Code;
58 } FixedOrder;
59 
60 typedef struct
61 {
62   LongInt Code;
63   Boolean WithImm;
64 } CmpOrder;
65 
66 typedef struct
67 {
68   LongInt Code;
69   LongInt Scale;
70 } MemOrder;
71 
72 typedef struct
73 {
74   LongInt Code;
75   Boolean DSign,SSign1,SSign2;
76   Boolean MayImm;
77 } MulOrder;
78 
79 typedef struct
80 {
81   const char *Name;
82   LongInt Code;
83   Boolean Rd,Wr;
84 } CtrlReg;
85 
86 static const char UnitNames[UnitCnt][3] =
87 {
88   "  ", "L1", "L2", "S1", "S2", "M1", "M2", "D1", "D2", "  "
89 };
90 
91 #define MaxParCnt 8
92 #define FirstUnit L1
93 
94 #define LinAddCnt 6
95 #define CmpCnt 5
96 #define MemCnt 8
97 #define MulCnt 20
98 #define CtrlCnt 13
99 
100 enum
101 {
102   ModNone = -1,
103   ModReg = 0,
104   ModLReg = 1,
105   ModImm = 2
106 };
107 
108 #define MModReg (1 << ModReg)
109 #define MModLReg (1 << ModLReg)
110 #define MModImm (1 << ModImm)
111 
112 static ShortInt AdrMode;
113 
114 static CPUVar CPU32060;
115 
116 static Boolean ThisPar, ThisCross, ThisStore, ThisAbsBranch;
117 static Byte ThisAddr, ThisLong;
118 static LongInt ThisSrc, ThisSrc2, ThisDest;
119 static LongInt Condition;
120 static TUnit ThisUnit;
121 static LongWord UnitFlag, ThisInst;
122 static Integer ParCnt;
123 static LongWord PacketAddr;
124 
125 static InstrRec *ParRecs;
126 
127 static FixedOrder *LinAddOrders;
128 static CmpOrder *CmpOrders;
129 static MemOrder *MemOrders;
130 static MulOrder *MulOrders;
131 static CtrlReg *CtrlRegs;
132 
133 /*-------------------------------------------------------------------------*/
134 
CheckOpt(char * Asc)135 static Boolean CheckOpt(char *Asc)
136 {
137   Boolean Flag, erg = True;
138   int l = strlen(Asc);
139 
140   if (!strcmp(Asc, "||"))
141     ThisPar = True;
142   else if ((*Asc == '[') && (Asc[l - 1] == ']'))
143   {
144     Asc++;
145     Asc[l - 2] = '\0';
146     l -= 2;
147     if (*Asc == '!')
148     {
149       Asc++;
150       l--;
151       Condition = 1;
152     }
153     else
154       Condition = 0;
155     Flag = True;
156     if (l != 2)
157       Flag = False;
158     else if (as_toupper(*Asc) == 'A')
159     {
160       if ((Asc[1] >= '1') && (Asc[1] <= '2'))
161         Condition += (Asc[1] - '0' + 3) << 1;
162       else
163         Flag = False;
164     }
165     else if (as_toupper(*Asc) == 'B')
166     {
167       if ((Asc[1] >= '0') && (Asc[1] <= '2'))
168         Condition += (Asc[1] - '0' + 1) << 1;
169       else
170         Flag = False;
171     }
172     if (!Flag)
173       WrXError(ErrNum_InvReg, Asc);
174     erg = Flag;
175   }
176   else
177     erg = False;
178 
179   return erg;
180 }
181 
ReiterateOpPart(void)182 static Boolean ReiterateOpPart(void)
183 {
184   char *p;
185   int z;
186 
187   if (!CheckOpt(OpPart.Str))
188     return False;
189 
190   if (ArgCnt<1)
191   {
192     WrError(ErrNum_WrongArgCnt);
193     return False;
194   }
195   p = FirstBlank(ArgStr[1].Str);
196   if (!p)
197   {
198     StrCompCopy(&OpPart, &ArgStr[1]);
199     for (z = 2; z <= ArgCnt; z++)
200       StrCompCopy(&ArgStr[z - 1], &ArgStr[z]);
201     ArgCnt--;
202   }
203   else
204   {
205     StrCompSplitLeft(&ArgStr[1], &OpPart, p);
206     KillPrefBlanksStrComp(&ArgStr[1]);
207   }
208   NLS_UpString(OpPart.Str);
209   p = strchr(OpPart.Str, '.');
210   if (!p)
211     *AttrPart.Str = '\0';
212   else
213   {
214     strcpy(AttrPart.Str, p + 1);
215     *p = '\0';
216   }
217   return True;
218 }
219 
220 /*-------------------------------------------------------------------------*/
221 
AddSrc(LongWord Reg)222 static void AddSrc(LongWord Reg)
223 {
224   LongWord Mask = 1 << Reg;
225 
226   if (!(ThisSrc & Mask))
227     ThisSrc |= Mask;
228   else
229     ThisSrc2 |= Mask;
230 }
231 
AddLSrc(LongWord Reg)232 static void AddLSrc(LongWord Reg)
233 {
234   AddSrc(Reg);
235   AddSrc(Reg + 1);
236   ThisLong |= 1;
237 }
238 
AddDest(LongWord Reg)239 static void AddDest(LongWord Reg)
240 {
241   ThisDest |= (1 << Reg);
242 }
243 
AddLDest(LongWord Reg)244 static void AddLDest(LongWord Reg)
245 {
246   ThisDest |= (3 << Reg);
247   ThisLong |= 2;
248 }
249 
FindReg(LongInt Mask)250 static LongInt FindReg(LongInt Mask)
251 {
252   int z;
253 
254   for (z = 0; z < 32; z++)
255   {
256     if (Mask & 1)
257       break;
258     Mask = Mask >> 1;
259   }
260   return z;
261 }
262 
RegName(LongInt Num)263 static char *RegName(LongInt Num)
264 {
265   static char s[5];
266 
267   Num &= 31;
268   as_snprintf(s, sizeof(s), "%c%ld", 'A' + (Num >> 4), (long) (Num & 15));
269   return s;
270 }
271 
DecodeSReg(char * Asc,LongWord * Reg,Boolean Quarrel)272 static Boolean DecodeSReg(char *Asc, LongWord *Reg, Boolean Quarrel)
273 {
274   char *end;
275   Byte RVal;
276   Boolean TFlag;
277 
278   TFlag = True;
279   switch (as_toupper(*Asc))
280   {
281     case 'A':
282       *Reg = 0; break;
283     case 'B':
284       *Reg = 16; break;
285     default:
286       TFlag = False;
287   }
288   if (TFlag)
289   {
290     RVal = strtol(Asc + 1, &end, 10);
291     if (*end != '\0')
292       TFlag = False;
293     else if
294       (RVal>15) TFlag = False;
295     else
296       *Reg += RVal;
297   }
298   if ((!TFlag) && (Quarrel))
299     WrXError(ErrNum_InvReg, Asc);
300   return TFlag;
301 }
302 
DecodeReg(char * Asc,LongWord * Reg,Boolean * PFlag,Boolean Quarrel)303 static Boolean DecodeReg(char *Asc, LongWord *Reg, Boolean *PFlag, Boolean Quarrel)
304 {
305   char *p;
306   LongWord NextReg;
307 
308   p = strchr(Asc, ':');
309   if (p == 0)
310   {
311     *PFlag = False;
312     return DecodeSReg(Asc, Reg, Quarrel);
313   }
314   else
315   {
316     *PFlag = True;
317     *p = '\0';
318     if (!DecodeSReg(Asc, &NextReg, Quarrel))
319       return False;
320     else if (!DecodeSReg(p + 1, Reg, Quarrel))
321      return False;
322     else if ((Odd(*Reg)) || (NextReg != (*Reg) + 1) || ((((*Reg) ^ NextReg) & 0x10) != 0))
323     {
324       if (Quarrel)
325         WrXError(ErrNum_InvRegPair, Asc);
326       return False;
327     }
328     else
329       return True;
330   }
331 }
332 
DecodeCtrlReg(char * Asc,LongWord * Erg,Boolean Write)333 static Boolean DecodeCtrlReg(char *Asc, LongWord *Erg, Boolean Write)
334 {
335   int z;
336 
337   for (z = 0; z < CtrlCnt; z++)
338     if (!as_strcasecmp(Asc, CtrlRegs[z].Name))
339     {
340       *Erg = CtrlRegs[z].Code;
341       return (Write && CtrlRegs[z].Wr) || ((!Write) && CtrlRegs[z].Rd);
342     }
343   return False;
344 }
345 
346 /* Was bedeutet das r-Feld im Adressoperanden mit kurzem Offset ???
347    und wie ist das genau mit der Skalierung gemeint ??? */
348 
DecodeMem(const tStrComp * pArg,LongWord * Erg,LongWord Scale)349 static Boolean DecodeMem(const tStrComp *pArg, LongWord *Erg, LongWord Scale)
350 {
351   LongInt DispAcc, Mode;
352   LongWord BaseReg, IndReg;
353   int l;
354   char Counter;
355   char *p, EmptyStr[] = "";
356   Boolean OK;
357   tStrComp Arg = *pArg, DispArg, RegArg;
358 
359   /* das muss da sein */
360 
361   if (*pArg->Str != '*')
362   {
363     WrError(ErrNum_InvAddrMode);
364     return False;
365   }
366   StrCompIncRefLeft(&Arg, 1);
367 
368   /* teilen */
369 
370   p = strchr(Arg.Str, '[');
371   Counter = ']';
372   if (!p)
373   {
374     p = strchr(Arg.Str, '(');
375     Counter = ')';
376   }
377   if (p)
378   {
379     if (Arg.Str[strlen(Arg.Str) - 1] != Counter)
380     {
381       WrError(ErrNum_InvAddrMode);
382       return False;
383     }
384     StrCompSplitRef(&RegArg, &DispArg, &Arg, p);
385     StrCompShorten(&DispArg, 1);
386   }
387   else
388   {
389     RegArg = Arg;
390     StrCompMkTemp(&DispArg, EmptyStr);
391   }
392 
393   /* Registerfeld entschluesseln */
394 
395   l = strlen(RegArg.Str);
396   Mode = 1; /* Default ist *+R */
397   if (*RegArg.Str == '+')
398   {
399     StrCompIncRefLeft(&RegArg, 1);
400     Mode = 1;
401     if (*RegArg.Str == '+')
402     {
403       StrCompIncRefLeft(&RegArg, 1);
404       Mode = 9;
405     }
406   }
407   else if (*RegArg.Str == '-')
408   {
409     StrCompIncRefLeft(&RegArg, 1);
410     Mode = 0;
411     if (*RegArg.Str == '-')
412     {
413       StrCompIncRefLeft(&RegArg, 1);
414       Mode = 8;
415     }
416   }
417   else if (RegArg.Str[l - 1] == '+')
418   {
419     if (RegArg.Str[l - 2] != '+')
420     {
421       WrError(ErrNum_InvAddrMode);
422       return False;
423     }
424     StrCompShorten(&RegArg, 2);
425     Mode = 11;
426   }
427   else if (RegArg.Str[l - 1] == '-')
428   {
429     if (RegArg.Str[l - 2] != '-')
430     {
431       WrError(ErrNum_InvAddrMode);
432       return False;
433     }
434     StrCompShorten(&RegArg, 2);
435     Mode = 10;
436   }
437   if (!DecodeSReg(RegArg.Str, &BaseReg, False))
438   {
439     WrStrErrorPos(ErrNum_InvReg, &RegArg);
440     return False;
441   }
442   AddSrc(BaseReg);
443 
444   /* kein Offsetfeld ? --> Skalierungsgroesse bei Autoinkrement/De-
445      krement, sonst 0 */
446 
447   if (*DispArg.Str == '\0')
448     DispAcc = (Mode < 2) ? 0 : Scale;
449 
450   /* Register als Offsetfeld? Dann Bit 2 in Modus setzen */
451 
452   else if (DecodeSReg(DispArg.Str, &IndReg, False))
453   {
454     if ((IndReg ^ BaseReg) > 15)
455     {
456       WrError(ErrNum_InvAddrMode);
457       return False;
458     }
459     Mode += 4;
460     AddSrc(DispAcc = IndReg);
461   }
462 
463   /* ansonsten normaler Offset */
464 
465   else
466   {
467     tSymbolFlags Flags;
468 
469     DispAcc = EvalStrIntExpressionWithFlags(&DispArg, UInt15, &OK, &Flags);
470     if (!OK)
471       return False;
472     if (mFirstPassUnknown(Flags))
473       DispAcc &= 7;
474     if (Counter  ==  ')')
475     {
476       if (DispAcc % Scale != 0)
477       {
478         WrError(ErrNum_NotAligned);
479         return False;
480       }
481       else
482        DispAcc /= Scale;
483     }
484   }
485 
486   /* Benutzung des Adressierers markieren */
487 
488   ThisAddr |= (BaseReg > 15) ? 2 : 1;
489 
490   /* Wenn Offset>31, muessen wir Variante 2 benutzen */
491 
492   if (((Mode & 4) == 0) && (DispAcc > 31))
493   {
494     if ((BaseReg < 0x1e) || (Mode != 1)) WrError(ErrNum_InvAddrMode);
495     else
496     {
497       *Erg = ((DispAcc & 0x7fff) << 8) + ((BaseReg & 1) << 7) + 12;
498       return True;
499     }
500   }
501 
502   else
503   {
504     *Erg = (BaseReg << 18) + ((DispAcc & 0x1f) << 13) + (Mode << 9)
505          + ((BaseReg & 0x10) << 3) + 4;
506     return True;
507   }
508 
509   return False;
510 }
511 
DecodeAdr(const tStrComp * pArg,Byte Mask,Boolean Signed,LongWord * AdrVal)512 static Boolean DecodeAdr(const tStrComp *pArg, Byte Mask, Boolean Signed, LongWord *AdrVal)
513 {
514   Boolean OK;
515 
516   AdrMode = ModNone;
517 
518   if (DecodeReg(pArg->Str, AdrVal, &OK, False))
519   {
520     AdrMode = (OK) ? ModLReg : ModReg;
521   }
522   else
523   {
524     *AdrVal = Signed ?
525               EvalStrIntExpression(pArg, SInt5, &OK) & 0x1f :
526               EvalStrIntExpression(pArg, UInt5, &OK);
527     if (OK)
528       AdrMode = ModImm;
529   }
530 
531   if ((AdrMode != ModNone) && (((1 << AdrMode) & Mask) == 0))
532   {
533     WrError(ErrNum_InvAddrMode);
534     AdrMode = ModNone;
535     return False;
536   }
537   else return True;
538 }
539 
ChkUnit(LongWord Reg,TUnit U1,TUnit U2)540 static Boolean ChkUnit(LongWord Reg, TUnit U1, TUnit U2)
541 {
542   UnitFlag = Ord(Reg>15);
543   if (ThisUnit == NoUnit)
544   {
545     ThisUnit = (Reg>15) ? U2 : U1;
546     return True;
547   }
548   else if (((ThisUnit == U1) && (Reg < 16)) || ((ThisUnit == U2) && (Reg>15)))
549     return True;
550   else
551   {
552     WrError(ErrNum_UndefAttr);
553     return False;
554   }
555 }
556 
UnitCode(char c)557 static TUnit UnitCode(char c)
558 {
559   switch (c)
560   {
561     case 'L': return L1;
562     case 'S': return S1;
563     case 'D': return D1;
564     case 'M': return M1;
565     default: return NoUnit;
566   }
567 }
568 
UnitUsed(TUnit TestUnit)569 static Boolean UnitUsed(TUnit TestUnit)
570 {
571   Integer z;
572 
573   for (z = 0; z < ParCnt; z++)
574     if (ParRecs[z].U == TestUnit)
575       return True;
576 
577   return False;
578 }
579 
IsCross(LongWord Reg)580 static Boolean IsCross(LongWord Reg)
581 {
582   return (Reg >> 4) != UnitFlag;
583 }
584 
SetCross(LongWord Reg)585 static void SetCross(LongWord Reg)
586 {
587   ThisCross = ((Reg >> 4) != UnitFlag);
588 }
589 
DecideUnit(LongWord Reg,const char * Units)590 static Boolean DecideUnit(LongWord Reg, const char *Units)
591 {
592   Integer z;
593   TUnit TestUnit;
594 
595   if (ThisUnit == NoUnit)
596   {
597     z = 0;
598     while ((Units[z] != '\0') && (ThisUnit == NoUnit))
599     {
600       TestUnit = UnitCode(Units[z]);
601       if (Reg >= 16) TestUnit++;
602       if (!UnitUsed(TestUnit))
603         ThisUnit = TestUnit;
604       z++;
605     }
606     if (ThisUnit == NoUnit)
607     {
608       ThisUnit = UnitCode(*Units);
609       if (Reg > 16)
610         TestUnit++;
611     }
612   }
613   UnitFlag = (ThisUnit - FirstUnit) & 1;
614   if (IsCross(Reg))
615   {
616     WrError(ErrNum_UndefAttr);
617     return False;
618   }
619   else
620     return True;
621 }
622 
SwapReg(LongWord * r1,LongWord * r2)623 static void SwapReg(LongWord *r1, LongWord *r2)
624 {
625   LongWord tmp;
626 
627   tmp = (*r1);
628   *r1 = (*r2);
629   *r2 = tmp;
630 }
631 
DecodePseudo(void)632 static Boolean DecodePseudo(void)
633 {
634   Boolean OK;
635   int z, cnt;
636   TempResult t;
637   LongInt Size;
638 
639   if (Memo("SINGLE"))
640   {
641     if (ChkArgCnt(1, ArgCntMax))
642     {
643       OK = True;
644       for (z = 0; z < ArgCnt; z++)
645       {
646         t.Contents.Float = EvalStrFloatExpression(&ArgStr[z + 1], Float32, &OK);
647         if (!OK)
648           break;
649         Double_2_ieee4(t.Contents.Float, (Byte *) (DAsmCode + z), BigEndian);
650       }
651       if (OK) CodeLen = ArgCnt << 2;
652     }
653     return True;
654   }
655 
656   if (Memo("DOUBLE"))
657   {
658     if (ChkArgCnt(1, ArgCntMax))
659     {
660       int z2;
661 
662       OK = True;
663       for (z = 0; z < ArgCnt; z++)
664       {
665         z2 = z << 1;
666         t.Contents.Float = EvalStrFloatExpression(&ArgStr[z + 1], Float64, &OK);
667         if (!OK)
668           break;
669         Double_2_ieee8(t.Contents.Float, (Byte *) (DAsmCode + z2), BigEndian);
670         if (!BigEndian)
671         {
672           DAsmCode[z2 + 2] = DAsmCode[z2 + 0];
673           DAsmCode[z2 + 0] = DAsmCode[z2 + 1];
674           DAsmCode[z2 + 1] = DAsmCode[z2 + 2];
675         }
676       }
677       if (OK)
678         CodeLen = ArgCnt << 3;
679     }
680     return True;
681   }
682 
683   if (Memo("DATA"))
684   {
685     if (ChkArgCnt(1, ArgCntMax))
686     {
687       OK = True;
688       cnt = 0;
689       for (z = 1; z <= ArgCnt; z++)
690        if (OK)
691        {
692          EvalStrExpression(&ArgStr[z], &t);
693          switch (t.Typ)
694          {
695            case TempString:
696            {
697              unsigned z2;
698 
699             if (MultiCharToInt(&t, 4))
700               goto ToInt;
701 
702              for (z2 = 0; z2 < t.Contents.Ascii.Length; z2++)
703              {
704                if ((z2 & 3) == 0) DAsmCode[cnt++] = 0;
705                DAsmCode[cnt - 1] +=
706                   (((LongWord)CharTransTable[((usint)t.Contents.Ascii.Contents[z2]) & 0xff])) << (8 * (3 - (z2 & 3)));
707              }
708              break;
709            }
710            case TempInt:
711            ToInt:
712 #ifdef HAS64
713              if (!RangeCheck(t.Contents.Int, Int32))
714              {
715                OK = False;
716                WrError(ErrNum_OverRange);
717              }
718              else
719 #endif
720                DAsmCode[cnt++] = t.Contents.Int;
721              break;
722            case TempFloat:
723              if (!FloatRangeCheck(t.Contents.Float, Float32))
724              {
725                OK = False;
726                WrError(ErrNum_OverRange);
727              }
728              else
729              {
730                Double_2_ieee4(t.Contents.Float, (Byte *) (DAsmCode + cnt), BigEndian);
731                cnt++;
732              }
733              break;
734            default:
735              OK = False;
736          }
737        }
738       if (OK)
739         CodeLen = cnt << 2;
740     }
741     return True;
742   }
743 
744   if (Memo("BSS"))
745   {
746     if (ChkArgCnt(1, 1))
747     {
748       tSymbolFlags Flags;
749 
750       Size = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt24, &OK, &Flags);
751       if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
752       if (OK && !mFirstPassUnknown(Flags))
753       {
754         DontPrint = True;
755         if (!Size) WrError(ErrNum_NullResMem);
756         CodeLen = Size;
757         BookKeeping();
758       }
759     }
760     return True;
761   }
762 
763   return False;
764 }
765 
766 
CodeL(LongWord OpCode,LongWord Dest,LongWord Src1,LongWord Src2)767 static Boolean CodeL(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
768 {
769   ThisInst = 0x18 + (OpCode << 5) + (UnitFlag << 1) + (Ord(ThisCross) << 12)
770                   + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
771   return True;
772 }
773 
CodeM(LongWord OpCode,LongWord Dest,LongWord Src1,LongWord Src2)774 static Boolean CodeM(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
775 {
776   ThisInst = 0x00 + (OpCode << 7) + (UnitFlag << 1) + (Ord(ThisCross) << 12)
777                   + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
778   return True;
779 }
780 
CodeS(LongWord OpCode,LongWord Dest,LongWord Src1,LongWord Src2)781 static Boolean CodeS(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
782 {
783   ThisInst = 0x20 + (OpCode << 6) + (UnitFlag << 1) + (Ord(ThisCross) << 12)
784                   + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
785   return True;
786 }
787 
CodeD(LongWord OpCode,LongWord Dest,LongWord Src1,LongWord Src2)788 static Boolean CodeD(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2)
789 {
790   ThisInst = 0x40 + (OpCode << 7) + (UnitFlag << 1)
791                   + (Dest << 23) + (Src2 << 18) + (Src1 << 13);
792   return True;
793 }
794 
795 /*-------------------------------------------------------------------------*/
796 
797 static Boolean __erg;
798 
DecodeIDLE(Word Index)799 static void DecodeIDLE(Word Index)
800 {
801   UNUSED(Index);
802 
803   if (!ChkArgCnt(0, 0));
804   else if ((ThisCross) || (ThisUnit != NoUnit)) WrError(ErrNum_UndefAttr);
805   else
806   {
807     ThisInst = 0x0001e000;
808     __erg = True;
809   }
810 }
811 
DecodeNOP(Word Index)812 static void DecodeNOP(Word Index)
813 {
814   LongInt Count;
815   Boolean OK;
816   UNUSED(Index);
817 
818   if (!ChkArgCnt(0, 1));
819   else if ((ThisCross) || (ThisUnit != NoUnit)) WrError(ErrNum_UndefAttr);
820   else
821   {
822     if (ArgCnt == 0)
823     {
824       OK = True;
825       Count = 0;
826     }
827     else
828     {
829       tSymbolFlags Flags;
830 
831       Count = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt4, &OK, &Flags);
832       Count = mFirstPassUnknown(Flags) ? 0 : Count - 1;
833       OK = ChkRange(Count, 0, 8);
834     }
835     if (OK)
836     {
837       ThisInst = Count << 13;
838       __erg = True;
839     }
840   }
841 }
842 
DecodeMul(Word Index)843 static void DecodeMul(Word Index)
844 {
845   LongWord DReg, S1Reg, S2Reg;
846   MulOrder *POrder = MulOrders + Index;
847 
848   if (ChkArgCnt(3, 3))
849   {
850     if ((DecodeAdr(&ArgStr[3], MModReg, POrder->DSign, &DReg))
851      && (ChkUnit(DReg, M1, M2)))
852     {
853       if (DecodeAdr(&ArgStr[2], MModReg, POrder->SSign2, &S2Reg))
854       {
855         AddSrc(S2Reg);
856         DecodeAdr(&ArgStr[1], (POrder->MayImm ? MModImm : 0) + MModReg, POrder->SSign1, &S1Reg);
857         switch (AdrMode)
858         {
859           case ModReg:
860             if ((ThisCross) && (!IsCross(S2Reg)) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
861             else if ((IsCross(S2Reg)) && (IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
862             else
863             {
864               if (IsCross(S1Reg))
865                 SwapReg(&S1Reg, &S2Reg);
866               SetCross(S2Reg);
867               AddSrc(S1Reg);
868               __erg = CodeM(POrder->Code, DReg, S1Reg, S2Reg);
869             }
870             break;
871           case ModImm:
872             __erg = Memo("MPY") ?
873                     CodeM(POrder->Code - 1, DReg, S1Reg, S2Reg) :
874                     CodeM(POrder->Code + 3, DReg, S1Reg, S2Reg);
875             break;
876         }
877       }
878     }
879   }
880 }
881 
DecodeMemO(Word Index)882 static void DecodeMemO(Word Index)
883 {
884   LongWord DReg, S1Reg;
885   MemOrder *POrder = MemOrders + Index;
886   Boolean OK, IsStore;
887 
888   if (ChkArgCnt(2, 2))
889   {
890     const tStrComp *pArg1, *pArg2;
891 
892     IsStore = (*OpPart.Str) == 'S';
893     pArg1 = IsStore ? &ArgStr[2] : &ArgStr[1];
894     pArg2 = IsStore ? &ArgStr[1] : &ArgStr[2];
895     if (IsStore)
896       ThisStore = True;
897     if (DecodeAdr(pArg2, MModReg, False, &DReg))
898     {
899       if (IsStore)
900         AddSrc(DReg);
901       ThisAddr |= (DReg > 15) ? 8 : 4;
902       /* Zielregister 4 Takte verzoegert, nicht als Dest eintragen */
903       OK = DecodeMem(pArg1, &S1Reg, POrder->Scale);
904       if (OK)
905       {
906         OK = (S1Reg & 8) ?
907              ChkUnit(0x1e, D1, D2) :
908              ChkUnit((S1Reg >> 18) & 31, D1, D2);
909       }
910       if (OK)
911       {
912         ThisInst = S1Reg + (DReg << 23) + (POrder->Code << 4)
913                  + ((DReg & 16) >> 3);
914         __erg = True;
915       }
916     }
917   }
918 }
919 
DecodeSTP(Word Index)920 static void DecodeSTP(Word Index)
921 {
922   LongWord S2Reg;
923   UNUSED(Index);
924 
925   if (ChkArgCnt(1, 1)
926    && ChkUnit(0x10, S1, S2))
927   {
928     if (DecodeAdr(&ArgStr[1], MModReg, False, &S2Reg))
929     {
930       if ((ThisCross) || (S2Reg < 16)) WrError(ErrNum_InvAddrMode);
931       else
932       {
933         AddSrc(S2Reg);
934         __erg = CodeS(0x0c, 0, 0, S2Reg);
935       }
936     }
937   }
938 }
939 
DecodeABS(Word Index)940 static void DecodeABS(Word Index)
941 {
942   Boolean DPFlag, S1Flag;
943   LongWord DReg, S1Reg;
944   UNUSED(Index);
945 
946   if (ChkArgCnt(2, 2)
947    && DecodeReg(ArgStr[2].Str, &DReg, &DPFlag, True)
948    && ChkUnit(DReg, L1, L2)
949    && DecodeReg(ArgStr[1].Str, &S1Reg, &S1Flag, True))
950   {
951     if (DPFlag != S1Flag) WrError(ErrNum_InvAddrMode);
952     else if ((ThisCross) && ((S1Reg >> 4) == UnitFlag)) WrError(ErrNum_InvAddrMode);
953     else
954     {
955       SetCross(S1Reg);
956       if (DPFlag)
957       {
958         __erg = CodeL(0x38, DReg, 0, S1Reg);
959         AddLSrc(S1Reg);
960         AddLDest(DReg);
961       }
962       else
963       {
964         __erg = CodeL(0x1a, DReg, 0, S1Reg);
965         AddSrc(S1Reg);
966         AddDest(DReg);
967       }
968     }
969   }
970 }
971 
DecodeADD(Word Index)972 static void DecodeADD(Word Index)
973 {
974   LongWord S1Reg, S2Reg, DReg;
975   Boolean OK;
976   UNUSED(Index);
977 
978   if (ChkArgCnt(3, 3))
979   {
980     DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
981     UnitFlag = DReg >> 4;
982     switch (AdrMode)
983     {
984       case ModLReg:      /* ADD ?,?,long */
985         AddLDest(DReg);
986         DecodeAdr(&ArgStr[1], MModReg + MModLReg + MModImm, True, &S1Reg);
987         switch (AdrMode)
988         {
989           case ModReg:    /* ADD int,?,long */
990             AddSrc(S1Reg);
991             DecodeAdr(&ArgStr[2], MModReg + MModLReg, True, &S2Reg);
992             switch (AdrMode)
993             {
994               case ModReg: /* ADD int,int,long */
995                 if (ChkUnit(DReg, L1, L2))
996                 {
997                   if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
998                   else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
999                   else
1000                   {
1001                     AddSrc(S2Reg);
1002                     if (IsCross(S1Reg))
1003                       SwapReg(&S1Reg, &S2Reg);
1004                     SetCross(S2Reg);
1005                     __erg = CodeL(0x23, DReg, S1Reg, S2Reg);
1006                   }
1007                 }
1008                 break;
1009               case ModLReg:/* ADD int,long,long */
1010                 if (ChkUnit(DReg, L1, L2))
1011                 {
1012                   if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1013                   else if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
1014                   else
1015                   {
1016                     AddLSrc(S2Reg);
1017                     SetCross(S1Reg);
1018                     __erg = CodeL(0x21, DReg, S1Reg, S2Reg);
1019                   }
1020                 }
1021                 break;
1022             }
1023             break;
1024           case ModLReg:   /* ADD long,?,long */
1025             AddLSrc(S1Reg);
1026             DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
1027             switch (AdrMode)
1028             {
1029               case ModReg: /* ADD long,int,long */
1030                 if (ChkUnit(DReg, L1, L2))
1031                 {
1032                   if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1033                   else if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1034                   else
1035                   {
1036                     AddSrc(S2Reg);
1037                     SetCross(S2Reg);
1038                     __erg = CodeL(0x21, DReg, S2Reg, S1Reg);
1039                   }
1040                 }
1041                 break;
1042               case ModImm: /* ADD long,imm,long */
1043                 if (ChkUnit(DReg, L1, L2))
1044                 {
1045                   if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1046                   else if (ThisCross) WrError(ErrNum_InvAddrMode);
1047                   else
1048                     __erg = CodeL(0x20, DReg, S2Reg, S1Reg);
1049                 }
1050                 break;
1051              }
1052              break;
1053            case ModImm:    /* ADD imm,?,long */
1054              if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
1055              {         /* ADD imm,long,long */
1056                if (ChkUnit(DReg, L1, L2))
1057                {
1058                  if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1059                  else if (ThisCross) WrError(ErrNum_InvAddrMode);
1060                  else
1061                  {
1062                    AddLSrc(S2Reg);
1063                    __erg = CodeL(0x20, DReg, S1Reg, S2Reg);
1064                  }
1065                }
1066              }
1067              break;
1068         }
1069         break;
1070       case ModReg:       /* ADD ?,?,int */
1071         AddDest(DReg);
1072         DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
1073         switch (AdrMode)
1074         {
1075           case ModReg:    /* ADD int,?,int */
1076             AddSrc(S1Reg);
1077             DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
1078             switch (AdrMode)
1079             {
1080               case ModReg: /* ADD int,int,int */
1081                 AddSrc(S2Reg);
1082                 if (((DReg ^ S1Reg) > 15) && ((DReg ^ S2Reg)>15)) WrError(ErrNum_InvAddrMode);
1083                 else if ((ThisCross) && ((DReg ^ S1Reg) < 16) && ((DReg ^ S2Reg) < 15)) WrError(ErrNum_InvAddrMode);
1084                 else
1085                 {
1086                   if ((S1Reg ^ DReg) > 15)
1087                     SwapReg(&S1Reg, &S2Reg);
1088                   OK = DecideUnit(DReg, ((S2Reg ^ DReg)>15) ? "LS" : "LSD");
1089                   if (OK)
1090                   {
1091                     switch (ThisUnit)
1092                     {
1093                       case L1: case L2: /* ADD.Lx int,int,int */
1094                         __erg = CodeL(0x03, DReg, S1Reg, S2Reg);
1095                         break;
1096                       case S1: case S2: /* ADD.Sx int,int,int */
1097                         __erg = CodeS(0x07, DReg, S1Reg, S2Reg);
1098                         break;
1099                       case D1: case D2: /* ADD.Dx int,int,int */
1100                         __erg = CodeD(0x10, DReg, S1Reg, S2Reg);
1101                         break;
1102                       default:
1103                         WrError(ErrNum_CannotUseUnit);
1104                     }
1105                   }
1106                 }
1107                 break;
1108               case ModImm: /* ADD int,imm,int */
1109                 if ((ThisCross) && ((S1Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1110                 else
1111                 {
1112                   SetCross(S1Reg);
1113                   if (DecideUnit(DReg, "LS"))
1114                     switch (ThisUnit)
1115                     {
1116                       case L1: case L2:
1117                         __erg = CodeL(0x02, DReg, S2Reg, S1Reg);
1118                         break;
1119                       case S1: case S2:
1120                         __erg = CodeS(0x06, DReg, S2Reg, S1Reg);
1121                         break;
1122                       default:
1123                         WrError(ErrNum_CannotUseUnit);
1124                     }
1125                 }
1126                 break;
1127             }
1128             break;
1129           case ModImm:   /* ADD imm,?,int */
1130             if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
1131             {
1132               AddSrc(S2Reg);
1133               if ((ThisCross) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1134               else
1135               {
1136                 SetCross(S2Reg);
1137                 if (DecideUnit(DReg, "LS"))
1138                   switch (ThisUnit)
1139                   {
1140                     case L1: case L2:
1141                       __erg = CodeL(0x02, DReg, S1Reg, S2Reg);
1142                       break;
1143                     case S1: case S2:
1144                       __erg = CodeS(0x06, DReg, S1Reg, S2Reg);
1145                       break;
1146                     default:
1147                       WrError(ErrNum_CannotUseUnit);
1148                   }
1149               }
1150             }
1151             break;
1152         }
1153         break;
1154     }
1155   }
1156 }
1157 
DecodeADDU(Word Index)1158 static void DecodeADDU(Word Index)
1159 {
1160   LongWord DReg, S1Reg, S2Reg;
1161   UNUSED(Index);
1162 
1163   if (ChkArgCnt(3, 3))
1164   {
1165     DecodeAdr(&ArgStr[3], MModReg + MModLReg, False, &DReg);
1166     switch (AdrMode)
1167     {
1168       case ModReg:      /* ADDU ?,?,int */
1169         if (ChkUnit(DReg, D1, D2))
1170         {
1171           AddDest(DReg);
1172           DecodeAdr(&ArgStr[1], MModReg + MModImm, False, &S1Reg);
1173           switch (AdrMode)
1174           {
1175             case ModReg: /* ADDU int,?,int */
1176               if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1177               else
1178               {
1179                 AddSrc(S1Reg);
1180                 if (DecodeAdr(&ArgStr[2], MModImm, False, &S2Reg))
1181                  __erg = CodeD(0x12, DReg, S2Reg, S1Reg);
1182               }
1183               break;
1184             case ModImm: /* ADDU imm,?,int */
1185               if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
1186               {
1187                 if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1188                 else
1189                 {
1190                   AddSrc(S2Reg);
1191                   __erg = CodeD(0x12, DReg, S1Reg, S2Reg);
1192                 }
1193               }
1194               break;
1195           }
1196         }
1197         break;
1198       case ModLReg:     /* ADDU ?,?,long */
1199         if (ChkUnit(DReg, L1, L2))
1200         {
1201           AddLDest(DReg);
1202           DecodeAdr(&ArgStr[1], MModReg + MModLReg, False, &S1Reg);
1203           switch (AdrMode)
1204           {
1205             case ModReg: /* ADDU int,?,long */
1206               AddSrc(S1Reg);
1207               DecodeAdr(&ArgStr[2], MModReg + MModLReg, False, &S2Reg);
1208               switch (AdrMode)
1209               {
1210                 case ModReg: /* ADDU int,int,long */
1211                   if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1212                   else if ((ThisCross) && (((S1Reg ^ DReg) < 16) && ((S2Reg ^ DReg) < 16))) WrError(ErrNum_InvAddrMode);
1213                   else
1214                   {
1215                     if ((S1Reg ^ DReg) > 15)
1216                       SwapReg(&S1Reg, &S2Reg);
1217                     SetCross(S2Reg);
1218                     __erg = CodeL(0x2b, DReg, S1Reg, S2Reg);
1219                   }
1220                   break;
1221                 case ModLReg: /* ADDU int,long,long */
1222                   if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1223                   else if ((ThisCross) && ((S1Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1224                   else
1225                   {
1226                     AddLSrc(S2Reg);
1227                     SetCross(S1Reg);
1228                     __erg = CodeL(0x29, DReg, S1Reg, S2Reg);
1229                   }
1230                   break;
1231               }
1232               break;
1233             case ModLReg:
1234               if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1235               else
1236               {
1237                 AddLSrc(S1Reg);
1238                 if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
1239                 {
1240                   if ((ThisCross) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1241                   else
1242                   {
1243                     AddSrc(S2Reg); SetCross(S2Reg);
1244                     __erg = CodeL(0x29, DReg, S2Reg, S1Reg);
1245                   }
1246                 }
1247               }
1248               break;
1249           }
1250         }
1251         break;
1252     }
1253   }
1254 }
1255 
DecodeSUB(Word Index)1256 static void DecodeSUB(Word Index)
1257 {
1258   LongWord DReg, S1Reg, S2Reg;
1259   Boolean OK;
1260   UNUSED(Index);
1261 
1262   if (ChkArgCnt(3, 3))
1263   {
1264     DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
1265     switch (AdrMode)
1266     {
1267       case ModReg:
1268         AddDest(DReg);
1269         DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
1270         switch (AdrMode)
1271         {
1272           case ModReg:
1273             AddSrc(S1Reg);
1274             DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
1275             switch (AdrMode)
1276             {
1277               case ModReg:
1278                if ((ThisCross) && ((S1Reg ^ DReg) < 16) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1279                else if (((S1Reg ^ DReg) > 15) && ((S2Reg ^ DReg) > 15)) WrError(ErrNum_InvAddrMode);
1280                else
1281                {
1282                  AddSrc(S2Reg);
1283                  ThisCross = ((S1Reg ^ DReg) > 15) || ((S2Reg ^ DReg) > 15);
1284                  if ((S1Reg ^ DReg) > 15) OK = DecideUnit(DReg, "L");
1285                  else if ((S2Reg ^ DReg) > 15) OK = DecideUnit(DReg, "LS");
1286                  else OK = DecideUnit(DReg, "LSD");
1287                  if (OK)
1288                    switch (ThisUnit)
1289                    {
1290                      case L1: case L2:
1291                        if ((S1Reg ^ DReg) > 15) __erg = CodeL(0x17, DReg, S1Reg, S2Reg);
1292                        else __erg = CodeL(0x07, DReg, S1Reg, S2Reg);
1293                        break;
1294                      case S1: case S2:
1295                        __erg = CodeS(0x17, DReg, S1Reg, S2Reg);
1296                        break;
1297                      case D1: case D2:
1298                        __erg = CodeD(0x11, DReg, S2Reg, S1Reg);
1299                        break;
1300                      default:
1301                        WrError(ErrNum_CannotUseUnit);
1302                    }
1303                }
1304                break;
1305               case ModImm:
1306                if (ChkUnit(DReg, D1, D2))
1307                {
1308                  if ((ThisCross) || ((S1Reg ^ DReg) > 15)) WrError(ErrNum_InvAddrMode);
1309                  else __erg = CodeD(0x13, DReg, S2Reg, S1Reg);
1310                }
1311                break;
1312             }
1313             break;
1314           case ModImm:
1315             if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
1316             {
1317               if ((ThisCross) && ((S2Reg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1318               else
1319               {
1320                 AddSrc(S2Reg);
1321                 if (DecideUnit(DReg, "LS"))
1322                   switch (ThisUnit)
1323                   {
1324                     case L1: case L2:
1325                       __erg = CodeL(0x06, DReg, S1Reg, S2Reg);
1326                       break;
1327                     case S1: case S2:
1328                       __erg = CodeS(0x16, DReg, S1Reg, S2Reg);
1329                       break;
1330                     default:
1331                       WrError(ErrNum_CannotUseUnit);
1332                   }
1333               }
1334             }
1335             break;
1336         }
1337         break;
1338       case ModLReg:
1339         AddLDest(DReg);
1340         if (ChkUnit(DReg, L1, L2))
1341         {
1342           DecodeAdr(&ArgStr[1], MModImm + MModReg, True, &S1Reg);
1343           switch (AdrMode)
1344           {
1345             case ModImm:
1346               if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
1347               {
1348                 if ((ThisCross) || (/*NOT*/ IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1349                 else
1350                 {
1351                   AddLSrc(S2Reg);
1352                   __erg = CodeL(0x24, DReg, S1Reg, S2Reg);
1353                 }
1354               }
1355               break;
1356             case ModReg:
1357               AddSrc(S1Reg);
1358               if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
1359               {
1360                 if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1361                 else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1362                 else
1363                 {
1364                   AddSrc(S2Reg);
1365                   ThisCross = (IsCross(S1Reg)) || (IsCross(S2Reg));
1366                   /* what did I do here? */
1367                   __erg = IsCross(S1Reg) ?
1368                           CodeL(0x37, DReg, S1Reg, S2Reg) :
1369                           CodeL(0x47, DReg, S1Reg, S2Reg);
1370                 }
1371               }
1372               break;
1373           }
1374         }
1375         break;
1376     }
1377   }
1378 }
1379 
DecodeSUBU(Word Index)1380 static void DecodeSUBU(Word Index)
1381 {
1382   LongWord S1Reg, S2Reg, DReg;
1383   UNUSED(Index);
1384 
1385   if (ChkArgCnt(3, 3)
1386    && DecodeAdr(&ArgStr[3], MModLReg, False, &DReg)
1387    && ChkUnit(DReg, L1, L2))
1388   {
1389     AddLDest(DReg);
1390     if (DecodeAdr(&ArgStr[1], MModReg, False, &S1Reg))
1391     {
1392       AddSrc(S1Reg);
1393       if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
1394       {
1395         if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1396         else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1397         else
1398         {
1399           AddSrc(S2Reg);
1400           ThisCross = IsCross(S1Reg) || IsCross(S2Reg);
1401           __erg = IsCross(S1Reg) ?
1402                   CodeL(0x3f, DReg, S1Reg, S2Reg) :
1403                   CodeL(0x2f, DReg, S1Reg, S2Reg);
1404         }
1405       }
1406     }
1407   }
1408 }
1409 
DecodeSUBC(Word Index)1410 static void DecodeSUBC(Word Index)
1411 {
1412   LongWord DReg, S1Reg, S2Reg;
1413   UNUSED(Index);
1414 
1415   if (ChkArgCnt(3, 3)
1416    && DecodeAdr(&ArgStr[3], MModReg, False, &DReg)
1417    && ChkUnit(DReg, L1, L2))
1418   {
1419     AddLDest(DReg);
1420     if (DecodeAdr(&ArgStr[1], MModReg, False, &S1Reg))
1421     {
1422       if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
1423       {
1424         if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1425         else if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1426         else
1427         {
1428           AddSrc(S2Reg);
1429           SetCross(S2Reg);
1430           __erg = CodeL(0x4b, DReg, S1Reg, S2Reg);
1431         }
1432       }
1433     }
1434   }
1435 }
1436 
DecodeLinAdd(Word Index)1437 static void DecodeLinAdd(Word Index)
1438 {
1439   LongWord DReg, S1Reg, S2Reg;
1440   FixedOrder *POrder = LinAddOrders + Index;
1441 
1442   if (!ChkArgCnt(3, 3));
1443   else if (ThisCross) WrError(ErrNum_InvAddrMode);
1444   else
1445   {
1446     if ((DecodeAdr(&ArgStr[3], MModReg, True, &DReg))
1447      && (ChkUnit(DReg, D1, D2)))
1448     {
1449       AddDest(DReg);
1450       if (DecodeAdr(&ArgStr[1], MModReg, True, &S2Reg))
1451       {
1452         if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1453         else
1454         {
1455           AddSrc(S2Reg);
1456           DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
1457           switch (AdrMode)
1458           {
1459             case ModReg:
1460               if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1461               else
1462               {
1463                 AddSrc(S1Reg);
1464                 __erg = CodeD(POrder->Code, DReg, S1Reg, S2Reg);
1465               }
1466               break;
1467             case ModImm:
1468               __erg = CodeD(POrder->Code + 2, DReg, S1Reg, S2Reg);
1469               break;
1470           }
1471         }
1472       }
1473     }
1474   }
1475 }
1476 
DecodeADDK(Word Index)1477 static void DecodeADDK(Word Index)
1478 {
1479   LongInt Value;
1480   LongWord DReg;
1481   Boolean OK;
1482   UNUSED(Index);
1483 
1484   if (ChkArgCnt(2, 2)
1485    && DecodeAdr(&ArgStr[2], MModReg, False, &DReg)
1486    && ChkUnit(DReg, S1, S2))
1487   {
1488     AddDest(DReg);
1489     Value = EvalStrIntExpression(&ArgStr[1], SInt16, &OK);
1490     if (OK)
1491     {
1492       ThisInst = 0x50 + (UnitFlag << 1) + ((Value & 0xffff) << 7) + (DReg << 23);
1493       __erg = True;
1494     }
1495   }
1496 }
1497 
DecodeADD2_SUB2(Word Index)1498 static void DecodeADD2_SUB2(Word Index)
1499 {
1500   LongWord DReg, S1Reg, S2Reg;
1501   Boolean OK;
1502 
1503   Index = (Index << 5) + 1;
1504   if (ChkArgCnt(3, 3)
1505    && DecodeAdr(&ArgStr[3], MModReg, True, &DReg)
1506    && ChkUnit(DReg, S1, S2))
1507   {
1508     AddDest(DReg);
1509     if (DecodeAdr(&ArgStr[1], MModReg, True, &S1Reg))
1510     {
1511       AddSrc(S1Reg);
1512       if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
1513       {
1514         if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1515         else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1516         else
1517         {
1518           OK = True; AddSrc(S2Reg);
1519           if (IsCross(S1Reg))
1520           {
1521             if (Index > 1)
1522             {
1523               WrError(ErrNum_InvAddrMode);
1524               OK = False;
1525             }
1526             else SwapReg(&S1Reg, &S2Reg);
1527           }
1528           if (OK)
1529           {
1530             SetCross(S2Reg);
1531             __erg = CodeS(Index, DReg, S1Reg, S2Reg);
1532           }
1533         }
1534       }
1535     }
1536   }
1537 }
1538 
DecodeMV(Word Index)1539 static void DecodeMV(Word Index)
1540 {
1541   LongWord SReg, DReg;
1542   UNUSED(Index);
1543 
1544   /* MV src,dst == ADD 0,src,dst */
1545 
1546   if (ChkArgCnt(2, 2))
1547   {
1548     DecodeAdr(&ArgStr[2], MModReg + MModLReg, True, &DReg);
1549     UnitFlag = DReg >> 4;
1550     switch (AdrMode)
1551     {
1552       case ModLReg:      /* MV ?,long */
1553         AddLDest(DReg);
1554         if (DecodeAdr(&ArgStr[1], MModLReg, True, &SReg))
1555         {                 /* MV long,long */
1556           if (ChkUnit(DReg, L1, L2))
1557           {
1558             if (IsCross(SReg)) WrError(ErrNum_InvAddrMode);
1559             else if (ThisCross) WrError(ErrNum_InvAddrMode);
1560             else
1561             {
1562               AddLSrc(SReg);
1563               __erg = CodeL(0x20, DReg, 0, SReg);
1564             }
1565           }
1566         }
1567         break;
1568 
1569       case ModReg:       /* MV ?,int */
1570         AddDest(DReg);
1571         if (DecodeAdr(&ArgStr[1], MModReg, True, &SReg))
1572         {
1573           AddSrc(SReg);
1574           if ((ThisCross) && ((SReg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1575           else
1576           {
1577             SetCross(SReg);
1578             if (DecideUnit(DReg, "LSD"))
1579               switch (ThisUnit)
1580               {
1581                 case L1: case L2:
1582                   __erg = CodeL(0x02, DReg, 0, SReg);
1583                   break;
1584                 case S1: case S2:
1585                   __erg = CodeS(0x06, DReg, 0, SReg);
1586                   break;
1587                 case D1: case D2:
1588                   __erg = CodeD(0x12, DReg, 0, SReg);
1589                   break;
1590                 default:
1591                   WrError(ErrNum_CannotUseUnit);
1592               }
1593           }
1594         }
1595         break;
1596     }
1597   }
1598 }
1599 
DecodeNEG(Word Index)1600 static void DecodeNEG(Word Index)
1601 {
1602   LongWord DReg, SReg;
1603   UNUSED(Index);
1604 
1605   /* NEG src,dst == SUB 0,src,dst */
1606 
1607   if (ChkArgCnt(2, 2))
1608   {
1609     DecodeAdr(&ArgStr[2], MModReg + MModLReg, True, &DReg);
1610     switch (AdrMode)
1611     {
1612       case ModReg:
1613         AddDest(DReg);
1614         if (DecodeAdr(&ArgStr[1], MModReg, True, &SReg))
1615         {
1616           if ((ThisCross) && ((SReg ^ DReg) < 16)) WrError(ErrNum_InvAddrMode);
1617           else
1618           {
1619             AddSrc(SReg);
1620             if (DecideUnit(DReg, "LS"))
1621               switch (ThisUnit)
1622               {
1623                 case L1: case L2:
1624                   __erg = CodeL(0x06, DReg, 0, SReg);
1625                   break;
1626                 case S1: case S2:
1627                   __erg = CodeS(0x16, DReg, 0, SReg);
1628                   break;
1629                 default:
1630                   WrError(ErrNum_CannotUseUnit);
1631               }
1632           }
1633         }
1634         break;
1635       case ModLReg:
1636         AddLDest(DReg);
1637         if (ChkUnit(DReg, L1, L2))
1638         {
1639           if (DecodeAdr(&ArgStr[1], MModLReg, True, &SReg))
1640           {
1641             if ((ThisCross) || (IsCross(SReg))) WrError(ErrNum_InvAddrMode);
1642             else
1643             {
1644               AddLSrc(SReg);
1645               __erg = CodeL(0x24, DReg, 0, SReg);
1646             }
1647           }
1648         }
1649         break;
1650     }
1651   }
1652 }
1653 
DecodeLogic(Word Index)1654 static void DecodeLogic(Word Index)
1655 {
1656   LongWord S1Reg, S2Reg, DReg;
1657   LongWord Code1, Code2;
1658   Boolean OK, WithImm;
1659 
1660   Code1 = Lo(Index);
1661   Code2 = Hi(Index);
1662 
1663   if (ChkArgCnt(3, 3))
1664   {
1665     if (DecodeAdr(&ArgStr[3], MModReg, True, &DReg))
1666     {
1667       AddDest(DReg);
1668       DecodeAdr(&ArgStr[1], MModImm + MModReg, True, &S1Reg);
1669       WithImm = False;
1670       switch (AdrMode)
1671       {
1672         case ModImm:
1673           OK = DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg);
1674           if (OK) AddSrc(S2Reg);
1675           WithImm = True;
1676           break;
1677         case ModReg:
1678           AddSrc(S1Reg);
1679           OK = DecodeAdr(&ArgStr[2], MModImm + MModReg, True, &S2Reg);
1680           switch (AdrMode)
1681           {
1682             case ModImm:
1683               SwapReg(&S1Reg, &S2Reg);
1684               WithImm = True;
1685               break;
1686             case ModReg:
1687               AddSrc(S2Reg);
1688               WithImm = False;
1689               break;
1690             default:
1691               OK = False;
1692           }
1693           break;
1694         default:
1695           OK = False;
1696       }
1697       if ((OK) && (DecideUnit(DReg, "LS")))
1698       {
1699         if ((!WithImm) && (IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1700         else if ((ThisCross) && (!IsCross(S2Reg)) && ((WithImm) || (!IsCross(S1Reg)))) WrError(ErrNum_InvAddrMode);
1701         else
1702         {
1703           if ((!WithImm) && (IsCross(S1Reg)))
1704             SwapReg(&S1Reg, &S2Reg);
1705           SetCross(S2Reg);
1706           switch (ThisUnit)
1707           {
1708             case L1: case L2:
1709               __erg = CodeL(Code1 - Ord(WithImm), DReg, S1Reg, S2Reg);
1710               break;
1711             case S1: case S2:
1712               __erg = CodeS(Code2 - Ord(WithImm), DReg, S1Reg, S2Reg);
1713               break;
1714             default:
1715               WrError(ErrNum_CannotUseUnit);
1716           }
1717         }
1718       }
1719     }
1720   }
1721 }
1722 
DecodeNOT(Word Index)1723 static void DecodeNOT(Word Index)
1724 {
1725   LongWord SReg, DReg;
1726 
1727   UNUSED(Index);
1728 
1729   /* NOT src,dst == XOR -1,src,dst */
1730 
1731   if (ChkArgCnt(2, 2))
1732   {
1733     if (DecodeAdr(&ArgStr[2], MModReg, True, &DReg))
1734     {
1735       AddDest(DReg);
1736       if (DecodeAdr(&ArgStr[1], MModReg, True, &SReg))
1737       {
1738         AddSrc(SReg);
1739         if (DecideUnit(DReg, "LS"))
1740         {
1741           if ((ThisCross) && (!IsCross(SReg))) WrError(ErrNum_InvAddrMode);
1742           else
1743           {
1744             SetCross(SReg);
1745             switch (ThisUnit)
1746             {
1747               case L1: case L2:
1748                 __erg = CodeL(0x6e, DReg, 0x1f, SReg);
1749                 break;
1750               case S1: case S2:
1751                 __erg = CodeS(0x0a, DReg, 0x1f, SReg);
1752                 break;
1753               default:
1754                 WrError(ErrNum_CannotUseUnit);
1755             }
1756           }
1757         }
1758       }
1759     }
1760   }
1761 }
1762 
DecodeZERO(Word Index)1763 static void DecodeZERO(Word Index)
1764 {
1765   LongWord DReg;
1766   UNUSED(Index);
1767 
1768   /* ZERO dst == SUB dst,dst,dst */
1769 
1770   if (ChkArgCnt(1, 1))
1771   {
1772     DecodeAdr(&ArgStr[1], MModReg + MModLReg, True, &DReg);
1773     if ((ThisCross) || (IsCross(DReg))) WrError(ErrNum_InvAddrMode);
1774     else
1775       switch (AdrMode)
1776       {
1777         case ModReg:
1778           AddDest(DReg);
1779           AddSrc(DReg);
1780           if (DecideUnit(DReg, "LSD"))
1781             switch (ThisUnit)
1782             {
1783               case L1: case L2:
1784                 __erg = CodeL(0x17, DReg, DReg, DReg);
1785                 break;
1786               case S1: case S2:
1787                 __erg = CodeS(0x17, DReg, DReg, DReg);
1788                 break;
1789               case D1: case D2:
1790                 __erg = CodeD(0x11, DReg, DReg, DReg);
1791                 break;
1792               default:
1793                 WrError(ErrNum_CannotUseUnit);
1794             }
1795           break;
1796         case ModLReg:
1797           AddLDest(DReg);
1798           AddLSrc(DReg);
1799           if (ChkUnit(DReg, L1, L2))
1800             __erg = CodeL(0x37, DReg, DReg, DReg);
1801           break;
1802       }
1803   }
1804 }
1805 
DecodeCLR_EXT_EXTU_SET(Word Code)1806 static void DecodeCLR_EXT_EXTU_SET(Word Code)
1807 {
1808   LongWord DReg, S1Reg, S2Reg, HReg;
1809   Boolean OK, IsEXT = (Code == 0x2f48);
1810 
1811   if (ChkArgCnt(3, 4))
1812   {
1813     if ((DecodeAdr(&ArgStr[ArgCnt], MModReg, IsEXT, &DReg))
1814      && (ChkUnit(DReg, S1, S2)))
1815     {
1816       AddDest(DReg);
1817       if (DecodeAdr(&ArgStr[1], MModReg, IsEXT, &S2Reg))
1818       {
1819         AddSrc(S2Reg);
1820         if (ArgCnt == 3)
1821         {
1822           if (DecodeAdr(&ArgStr[2], MModReg, False, &S1Reg))
1823           {
1824             if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
1825             else if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1826             else
1827             {
1828               SetCross(S2Reg);
1829               __erg = CodeS(Hi(Code), DReg, S1Reg, S2Reg);
1830             }
1831           }
1832         }
1833         else if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1834         else
1835         {
1836           S1Reg = EvalStrIntExpression(&ArgStr[2], UInt5, &OK);
1837           if (OK)
1838           {
1839             HReg = EvalStrIntExpression(&ArgStr[3], UInt5, &OK);
1840             if (OK)
1841             {
1842               ThisInst = (DReg << 23) + (S2Reg << 18) + (S1Reg << 13)
1843                        + (HReg << 8) + (UnitFlag << 1) + Lo(Code);
1844               __erg = True;
1845             }
1846           }
1847         }
1848       }
1849     }
1850   }
1851 }
1852 
DecodeCmp(Word Index)1853 static void DecodeCmp(Word Index)
1854 {
1855   const CmpOrder *pOrder = CmpOrders + Index;
1856   LongWord DReg, S1Reg, S2Reg;
1857 
1858   if (ChkArgCnt(3, 3)
1859    && DecodeAdr(&ArgStr[3], MModReg, False, &DReg)
1860    && ChkUnit(DReg, L1, L2))
1861   {
1862     AddDest(DReg);
1863     DecodeAdr(&ArgStr[1], MModReg + MModImm, pOrder->WithImm, &S1Reg);
1864     switch (AdrMode)
1865     {
1866       case ModReg:
1867         AddSrc(S1Reg);
1868         DecodeAdr(&ArgStr[2], MModReg + MModLReg, pOrder->WithImm, &S2Reg);
1869         switch (AdrMode)
1870         {
1871           case ModReg:
1872             if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1873             else if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1874             else
1875             {
1876               AddSrc(S2Reg);
1877               if (IsCross(S1Reg)) SwapReg(&S1Reg, &S2Reg);
1878               SetCross(S2Reg);
1879               __erg = CodeL(pOrder->Code + 3, DReg, S1Reg, S2Reg);
1880             }
1881             break;
1882           case ModLReg:
1883             if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
1884             else if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
1885             else
1886             {
1887               AddLSrc(S2Reg); SetCross(S1Reg);
1888               __erg = CodeL(pOrder->Code + 1, DReg, S1Reg, S2Reg);
1889             }
1890             break;
1891         }
1892         break;
1893       case ModImm:
1894         DecodeAdr(&ArgStr[2], MModReg + MModLReg, pOrder->WithImm, &S2Reg);
1895         switch (AdrMode)
1896         {
1897           case ModReg:
1898             if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1899             else
1900             {
1901               AddSrc(S2Reg); SetCross(S2Reg);
1902               __erg = CodeL(pOrder->Code + 2, DReg, S1Reg, S2Reg);
1903             }
1904             break;
1905           case ModLReg:
1906             if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1907             else
1908             {
1909               AddLSrc(S2Reg);
1910               __erg = CodeL(pOrder->Code, DReg, S1Reg, S2Reg);
1911             }
1912             break;
1913         }
1914        break;
1915     }
1916   }
1917 }
1918 
DecodeLMBD(Word Code)1919 static void DecodeLMBD(Word Code)
1920 {
1921   LongWord DReg, S1Reg, S2Reg;
1922   UNUSED(Code);
1923 
1924   if (ChkArgCnt(3, 3)
1925    && DecodeAdr(&ArgStr[3], MModReg, False, &DReg)
1926    && ChkUnit(DReg, L1, L2))
1927   {
1928     AddDest(DReg);
1929     if (DecodeAdr(&ArgStr[2], MModReg, False, &S2Reg))
1930     {
1931       if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1932       else
1933       {
1934         SetCross(S2Reg);
1935         if (DecodeAdr(&ArgStr[1], MModImm + MModReg, False, &S1Reg))
1936         {
1937           if (AdrMode == ModReg)
1938             AddSrc(S1Reg);
1939           __erg = CodeL(0x6a + Ord(AdrMode == ModImm), DReg, S1Reg, S2Reg);
1940         }
1941       }
1942     }
1943   }
1944 }
1945 
DecodeNORM(Word Code)1946 static void DecodeNORM(Word Code)
1947 {
1948   LongWord DReg, S2Reg;
1949 
1950   UNUSED(Code);
1951 
1952   if (ChkArgCnt(2, 2)
1953    && DecodeAdr(&ArgStr[2], MModReg, False, &DReg)
1954    && ChkUnit(DReg, L1, L2))
1955   {
1956     AddDest(DReg);
1957     DecodeAdr(&ArgStr[1], MModReg + MModLReg, True, &S2Reg);
1958     switch (AdrMode)
1959     {
1960       case ModReg:
1961         if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1962         else
1963         {
1964           SetCross(S2Reg); AddSrc(S2Reg);
1965           __erg = CodeL(0x63, DReg, 0, S2Reg);
1966         }
1967         break;
1968       case ModLReg:
1969         if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
1970         else
1971         {
1972           AddLSrc(S2Reg);
1973           __erg = CodeL(0x60, DReg, 0, S2Reg);
1974         }
1975         break;
1976     }
1977   }
1978 }
1979 
DecodeSADD(Word Code)1980 static void DecodeSADD(Word Code)
1981 {
1982   LongWord DReg, S1Reg, S2Reg;
1983 
1984   UNUSED(Code);
1985 
1986   if (ChkArgCnt(3, 3)
1987    && DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg)
1988    && ChkUnit(DReg, L1, L2))
1989   {
1990     switch (AdrMode)
1991     {
1992       case ModReg:
1993         AddDest(DReg);
1994         DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
1995         switch (AdrMode)
1996         {
1997           case ModReg:
1998             AddSrc(S1Reg);
1999             DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
2000             switch (AdrMode)
2001             {
2002               case ModReg:
2003                if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2004                else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2005                else
2006                {
2007                  AddSrc(S2Reg);
2008                  if (IsCross(S1Reg)) SwapReg(&S1Reg, &S2Reg);
2009                  SetCross(S2Reg);
2010                  __erg = CodeL(0x13, DReg, S1Reg, S2Reg);
2011                }
2012                break;
2013               case ModImm:
2014                if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
2015                else
2016                {
2017                  SetCross(S1Reg);
2018                  __erg = CodeL(0x12, DReg, S2Reg, S1Reg);
2019                }
2020                break;
2021             }
2022             break;
2023           case ModImm:
2024             if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
2025             {
2026               if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2027               else
2028               {
2029                 SetCross(S2Reg);
2030                 __erg = CodeL(0x12, DReg, S1Reg, S2Reg);
2031               }
2032             }
2033             break;
2034         }
2035         break;
2036       case ModLReg:
2037         AddLDest(DReg);
2038         DecodeAdr(&ArgStr[1], MModReg + MModLReg + MModImm, True, &S1Reg);
2039         switch (AdrMode)
2040         {
2041           case ModReg:
2042             AddSrc(S1Reg);
2043             if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
2044             {
2045               if ((ThisCross) && (!IsCross(S1Reg))) WrError(ErrNum_InvAddrMode);
2046               else
2047               {
2048                 AddLSrc(S2Reg); SetCross(S1Reg);
2049                 __erg = CodeL(0x31, DReg, S1Reg, S2Reg);
2050               }
2051             }
2052             break;
2053           case ModLReg:
2054             if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2055             else
2056             {
2057               AddLSrc(S1Reg);
2058               DecodeAdr(&ArgStr[2], MModReg + MModImm, True, &S2Reg);
2059               switch (AdrMode)
2060               {
2061                 case ModReg:
2062                   if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2063                   else
2064                   {
2065                     AddSrc(S2Reg); SetCross(S2Reg);
2066                     __erg = CodeL(0x31, DReg, S2Reg, S1Reg);
2067                   }
2068                   break;
2069                 case ModImm:
2070                   __erg = CodeL(0x30, DReg, S2Reg, S1Reg);
2071                   break;
2072               }
2073             }
2074             break;
2075           case ModImm:
2076             if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
2077             {
2078               if (IsCross(S2Reg)) WrError(ErrNum_InvAddrMode);
2079               else
2080               {
2081                 AddLSrc(S2Reg);
2082                 __erg = CodeL(0x30, DReg, S1Reg, S2Reg);
2083               }
2084             }
2085             break;
2086         }
2087         break;
2088     }
2089   }
2090 }
2091 
DecodeSAT(Word Code)2092 static void DecodeSAT(Word Code)
2093 {
2094   LongWord DReg, S2Reg;
2095 
2096   UNUSED(Code);
2097 
2098   if (ChkArgCnt(2, 2)
2099    && DecodeAdr(&ArgStr[2], MModReg, True, &DReg)
2100    && ChkUnit(DReg, L1, L2))
2101   {
2102     AddDest(DReg);
2103     if (DecodeAdr(&ArgStr[1], MModLReg, True, &S2Reg))
2104     {
2105       if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2106       else
2107       {
2108         AddLSrc(S2Reg);
2109         __erg = CodeL(0x40, DReg, 0, S2Reg);
2110       }
2111     }
2112   }
2113 }
2114 
DecodeMVC(Word Code)2115 static void DecodeMVC(Word Code)
2116 {
2117   LongWord S1Reg, CReg;
2118 
2119   UNUSED(Code);
2120 
2121   if ((ThisUnit != NoUnit) && (ThisUnit != S2)) WrError(ErrNum_InvAddrMode);
2122   else if (ChkArgCnt(2, 2))
2123   {
2124     int z;
2125 
2126     z = 0;
2127     ThisUnit = S2;
2128     UnitFlag = 1;
2129     if (DecodeCtrlReg(ArgStr[1].Str, &CReg, False))
2130       z = 2;
2131     else if (DecodeCtrlReg(ArgStr[2].Str, &CReg, True))
2132       z = 1;
2133     else
2134       WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
2135     if (z > 0)
2136     {
2137       if (DecodeAdr(&ArgStr[z], MModReg, False, &S1Reg))
2138       {
2139         if ((ThisCross) && ((z == 2) || (IsCross(S1Reg)))) WrError(ErrNum_InvAddrMode);
2140         else
2141         {
2142           if (z == 1)
2143           {
2144             AddSrc(S1Reg);
2145             SetCross(S1Reg);
2146             __erg = CodeS(0x0e, CReg, 0, S1Reg);
2147           }
2148           else
2149           {
2150             AddDest(S1Reg);
2151             __erg = CodeS(0x0f, S1Reg, 0, CReg);
2152           }
2153         }
2154       }
2155     }
2156   }
2157 }
2158 
DecodeMVK(Word Code)2159 static void DecodeMVK(Word Code)
2160 {
2161   LongWord DReg, S1Reg;
2162   Boolean OK;
2163 
2164   if (ChkArgCnt(2, 2))
2165   {
2166     if (DecodeAdr(&ArgStr[2], MModReg, True, &DReg))
2167      if (ChkUnit(DReg, S1, S2))
2168      {
2169        if (Memo("MVKLH"))
2170          S1Reg = EvalStrIntExpression(&ArgStr[1], Int16, &OK);
2171        else if (Memo("MVKL"))
2172          S1Reg = EvalStrIntExpression(&ArgStr[1], SInt16, &OK);
2173        else
2174          S1Reg = EvalStrIntExpression(&ArgStr[1], Int32, &OK);
2175        if (OK)
2176        {
2177          AddDest(DReg);
2178          ThisInst = (DReg << 23) + (((S1Reg >> Hi(Code)) & 0xffff) << 7) + (UnitFlag << 1) + Lo(Code);
2179          __erg = True;
2180        }
2181      }
2182   }
2183 }
2184 
DecodeSHL(Word Code)2185 static void DecodeSHL(Word Code)
2186 {
2187   LongWord DReg, S1Reg, S2Reg;
2188 
2189   UNUSED(Code);
2190 
2191   if (ChkArgCnt(3, 3))
2192   {
2193     DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
2194     if ((AdrMode != ModNone) && (ChkUnit(DReg, S1, S2)))
2195      switch (AdrMode)
2196      {
2197        case ModReg:
2198          AddDest(DReg);
2199          if (DecodeAdr(&ArgStr[1], MModReg, True, &S2Reg))
2200          {
2201            if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2202            else
2203            {
2204              AddSrc(S2Reg);
2205              SetCross(S2Reg);
2206              DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
2207              switch (AdrMode)
2208              {
2209                case ModReg:
2210                  if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2211                  else
2212                  {
2213                    AddSrc(S1Reg);
2214                    __erg = CodeS(0x33, DReg, S1Reg, S2Reg);
2215                  }
2216                  break;
2217                case ModImm:
2218                  __erg = CodeS(0x32, DReg, S1Reg, S2Reg);
2219                  break;
2220              }
2221            }
2222          }
2223          break;
2224        case ModLReg:
2225          AddLDest(DReg);
2226          DecodeAdr(&ArgStr[1], MModReg + MModLReg, True, &S2Reg);
2227          switch (AdrMode)
2228          {
2229            case ModReg:
2230              if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2231              else
2232              {
2233                AddSrc(S2Reg); SetCross(S2Reg);
2234                DecodeAdr(&ArgStr[2], MModImm + MModReg, False, &S1Reg);
2235                switch (AdrMode)
2236                {
2237                  case ModReg:
2238                    if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2239                    else
2240                    {
2241                      AddSrc(S1Reg);
2242                      __erg = CodeS(0x13, DReg, S1Reg, S2Reg);
2243                    }
2244                    break;
2245                  case ModImm:
2246                    __erg = CodeS(0x12, DReg, S1Reg, S2Reg);
2247                    break;
2248                }
2249              }
2250              break;
2251            case ModLReg:
2252              if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2253              else
2254              {
2255                AddLSrc(S2Reg);
2256                DecodeAdr(&ArgStr[2], MModImm + MModReg, False, &S1Reg);
2257                switch (AdrMode)
2258                {
2259                  case ModReg:
2260                    if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2261                    else
2262                    {
2263                      AddSrc(S1Reg);
2264                      __erg = CodeS(0x31, DReg, S1Reg, S2Reg);
2265                    }
2266                    break;
2267                  case ModImm:
2268                    __erg = CodeS(0x30, DReg, S1Reg, S2Reg);
2269                    break;
2270                }
2271              }
2272              break;
2273          }
2274          break;
2275       }
2276   }
2277 }
2278 
DecodeSHR_SHRU(Word Code)2279 static void DecodeSHR_SHRU(Word Code)
2280 {
2281   LongWord DReg, S1Reg, S2Reg;
2282   Boolean HasSign = Code != 0;
2283 
2284   if (ChkArgCnt(3, 3))
2285   {
2286     DecodeAdr(&ArgStr[3], MModReg + MModLReg, HasSign, &DReg);
2287     if ((AdrMode != ModNone) && (ChkUnit(DReg, S1, S2)))
2288      switch (AdrMode)
2289      {
2290        case ModReg:
2291          AddDest(DReg);
2292          if (DecodeAdr(&ArgStr[1], MModReg, HasSign, &S2Reg))
2293          {
2294            if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2295            else
2296            {
2297              AddSrc(S2Reg); SetCross(S2Reg);
2298              DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
2299              switch (AdrMode)
2300              {
2301                case ModReg:
2302                  if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2303                  else
2304                  {
2305                    AddSrc(S1Reg);
2306                    __erg = CodeS(0x27 + Code, DReg, S1Reg, S2Reg);
2307                  }
2308                  break;
2309                case ModImm:
2310                  __erg = CodeS(0x26 + Code, DReg, S1Reg, S2Reg);
2311                  break;
2312              }
2313            }
2314          }
2315          break;
2316        case ModLReg:
2317          AddLDest(DReg);
2318          if (DecodeAdr(&ArgStr[1], MModLReg, HasSign, &S2Reg))
2319          {
2320            if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2321            else
2322            {
2323              AddLSrc(S2Reg);
2324              DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
2325              switch (AdrMode)
2326              {
2327                case ModReg:
2328                  if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2329                  else
2330                  {
2331                    AddSrc(S1Reg);
2332                    __erg = CodeS(0x25 + Code, DReg, S1Reg, S2Reg);
2333                  }
2334                  break;
2335                case ModImm:
2336                  __erg = CodeS(0x24 + Code, DReg, S1Reg, S2Reg);
2337                  break;
2338              }
2339            }
2340          }
2341          break;
2342      }
2343   }
2344 }
2345 
DecodeSSHL(Word Code)2346 static void DecodeSSHL(Word Code)
2347 {
2348   LongWord DReg, S1Reg, S2Reg;
2349 
2350   UNUSED(Code);
2351 
2352   if (ChkArgCnt(3, 3))
2353   {
2354     if (DecodeAdr(&ArgStr[3], MModReg, True, &DReg))
2355      if (ChkUnit(DReg, S1, S2))
2356      {
2357        AddDest(DReg);
2358        if (DecodeAdr(&ArgStr[1], MModReg, True, &S2Reg))
2359        {
2360          if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2361          else
2362          {
2363            AddSrc(S2Reg); SetCross(S2Reg);
2364            DecodeAdr(&ArgStr[2], MModReg + MModImm, False, &S1Reg);
2365            switch (AdrMode)
2366            {
2367              case ModReg:
2368                if (IsCross(S1Reg)) WrError(ErrNum_InvAddrMode);
2369                else
2370                {
2371                  AddSrc(S1Reg);
2372                  __erg = CodeS(0x23, DReg, S1Reg, S2Reg);
2373                }
2374                break;
2375              case ModImm:
2376                __erg = CodeS(0x22, DReg, S1Reg, S2Reg);
2377                break;
2378            }
2379          }
2380        }
2381      }
2382   }
2383 }
2384 
DecodeSSUB(Word Code)2385 static void DecodeSSUB(Word Code)
2386 {
2387   LongWord DReg, S1Reg, S2Reg;
2388 
2389   UNUSED(Code);
2390 
2391   if (ChkArgCnt(3, 3))
2392   {
2393     DecodeAdr(&ArgStr[3], MModReg + MModLReg, True, &DReg);
2394     if ((AdrMode != ModNone) && (ChkUnit(DReg, L1, L2)))
2395      switch (AdrMode)
2396      {
2397        case ModReg:
2398         AddDest(DReg);
2399         DecodeAdr(&ArgStr[1], MModReg + MModImm, True, &S1Reg);
2400         switch (AdrMode)
2401         {
2402           case ModReg:
2403             AddSrc(S1Reg);
2404             if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
2405             {
2406               if ((ThisCross) && (!IsCross(S1Reg)) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2407               else if ((IsCross(S1Reg)) && (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2408               else if (IsCross(S1Reg))
2409               {
2410                 ThisCross = True;
2411                 __erg = CodeL(0x1f, DReg, S1Reg, S2Reg);
2412               }
2413               else
2414               {
2415                 SetCross(S2Reg);
2416                 __erg = CodeL(0x0f, DReg, S1Reg, S2Reg);
2417               }
2418             }
2419             break;
2420           case ModImm:
2421             if (DecodeAdr(&ArgStr[2], MModReg, True, &S2Reg))
2422             {
2423               if ((ThisCross) && (!IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2424               else
2425               {
2426                 AddSrc(S2Reg); SetCross(S2Reg);
2427                 __erg = CodeL(0x0e, DReg, S1Reg, S2Reg);
2428               }
2429             }
2430             break;
2431         }
2432         break;
2433        case ModLReg:
2434         AddLDest(DReg);
2435          if (DecodeAdr(&ArgStr[1], MModImm, True, &S1Reg))
2436          {
2437            if (DecodeAdr(&ArgStr[2], MModLReg, True, &S2Reg))
2438            {
2439              if ((ThisCross) || (IsCross(S2Reg))) WrError(ErrNum_InvAddrMode);
2440              else
2441              {
2442                AddLSrc(S2Reg);
2443                __erg = CodeL(0x2c, DReg, S1Reg, S2Reg);
2444              }
2445            }
2446          }
2447          break;
2448      }
2449   }
2450 }
2451 
2452 /* Spruenge */
2453 
DecodeB(Word Code)2454 static void DecodeB(Word Code)
2455 {
2456   LongWord S2Reg, Code1;
2457   LongInt Dist;
2458   Boolean WithImm, OK;
2459 
2460   UNUSED(Code);
2461 
2462   if (ArgCnt != 1) WrError(ErrNum_InvAddrMode);
2463   else if (ThisCross) WrError(ErrNum_InvAddrMode);
2464   else if ((ThisUnit != NoUnit) && (ThisUnit != S1) && (ThisUnit != S2)) WrError(ErrNum_InvAddrMode);
2465   else
2466   {
2467     OK = True;
2468     S2Reg = 0;
2469     WithImm = False;
2470     Code1 = 0;
2471     if (!as_strcasecmp(ArgStr[1].Str, "IRP"))
2472     {
2473       Code1 = 0x03;
2474       S2Reg = 0x06;
2475     }
2476     else if (!as_strcasecmp(ArgStr[1].Str, "NRP"))
2477     {
2478       Code1 = 0x03;
2479       S2Reg = 0x07;
2480     }
2481     else if (DecodeReg(ArgStr[1].Str, &S2Reg, &OK, False))
2482     {
2483       if (OK) WrError(ErrNum_InvAddrMode);
2484       OK = !OK;
2485       Code1 = 0x0d;
2486     }
2487     else
2488       WithImm = OK = True;
2489     if (OK)
2490     {
2491       if (WithImm)
2492       {
2493         tSymbolFlags Flags;
2494 
2495         if (ThisUnit == NoUnit)
2496           ThisUnit = (UnitUsed(S1)) ? S2 : S1;
2497         UnitFlag = Ord(ThisUnit == S2);
2498 
2499         /* branches relative to fetch packet */
2500 
2501         Dist = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags) - (PacketAddr & (~31));
2502         if (OK)
2503         {
2504           if ((Dist & 3) != 0) WrError(ErrNum_NotAligned);
2505           else if (!mSymbolQuestionable(Flags) && ((Dist > 0x3fffff) || (Dist < -0x400000))) WrError(ErrNum_JmpDistTooBig);
2506           else
2507           {
2508             ThisInst = 0x10 + ((Dist & 0x007ffffc) << 5) + (UnitFlag << 1);
2509             ThisAbsBranch = True;
2510             __erg = True;
2511           }
2512         }
2513       }
2514       else
2515       {
2516         if (ChkUnit(0x10, S1, S2))
2517         {
2518           SetCross(S2Reg);
2519           __erg = CodeS(Code1, 0, 0, S2Reg);
2520         }
2521       }
2522     }
2523   }
2524 }
2525 
DecodeInst(void)2526 static Boolean DecodeInst(void)
2527 {
2528   __erg = False;
2529 
2530   /* ueber Tabelle: */
2531 
2532   if (LookupInstTable(InstTable, OpPart.Str))
2533     return __erg;
2534 
2535   WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
2536   return False;
2537 }
2538 
ChkPacket(void)2539 static void ChkPacket(void)
2540 {
2541   LongWord EndAddr, Mask;
2542   LongInt z, z1, z2;
2543   Integer RegReads[32];
2544   char TestUnit[4];
2545   int BranchCnt;
2546 
2547   /* nicht ueber 8er-Grenze */
2548 
2549   EndAddr = PacketAddr + ((ParCnt << 2) - 1);
2550   if ((PacketAddr >> 5) != (EndAddr >> 5))
2551     WrError(ErrNum_PackCrossBoundary);
2552 
2553   /* doppelte Units,Crosspaths,Adressierer,Zielregister */
2554 
2555   for (z1 = 0; z1 < ParCnt; z1++)
2556     for (z2 = z1 + 1; z2 < ParCnt; z2++)
2557       if ((ParRecs[z1].OpCode >> 28) == (ParRecs[z2].OpCode >> 28))
2558       {
2559         /* doppelte Units */
2560 
2561         if ((ParRecs[z1].U != NoUnit) && (ParRecs[z1].U == ParRecs[z2].U))
2562           WrXError(ErrNum_UnitMultipleUsed, UnitNames[ParRecs[z1].U]);
2563 
2564         /* Crosspaths */
2565 
2566         z = ParRecs[z1].CrossUsed & ParRecs[z2].CrossUsed;
2567         if (z != 0)
2568         {
2569           *TestUnit = z + '0';
2570           TestUnit[1] = 'X';
2571           TestUnit[2] = '\0';
2572           WrXError(ErrNum_UnitMultipleUsed, TestUnit);
2573         }
2574 
2575         z = ParRecs[z1].AddrUsed & ParRecs[z2].AddrUsed;
2576 
2577         /* Adressgeneratoren */
2578 
2579         if ((z & 1) == 1) WrXError(ErrNum_UnitMultipleUsed, "Addr. A");
2580         if ((z & 2) == 2) WrXError(ErrNum_UnitMultipleUsed, "Addr. B");
2581 
2582         /* Hauptspeicherpfade */
2583 
2584         if ((z & 4) == 4) WrXError(ErrNum_UnitMultipleUsed, "LdSt. A");
2585         if ((z & 8) == 8) WrXError(ErrNum_UnitMultipleUsed, "LdSt. B");
2586 
2587         /* ueberlappende Zielregister */
2588 
2589         z = ParRecs[z1].DestMask & ParRecs[z2].DestMask;
2590         if (z != 0)
2591           WrXError(ErrNum_OverlapDests, RegName(FindReg(z)));
2592 
2593         if ((ParRecs[z1].U & 1) == (ParRecs[z2].U & 1))
2594         {
2595           TestUnit[0] = ParRecs[z1].U - NoUnit - 1 + 'A';
2596           TestUnit[1] = '\0';
2597 
2598           /* mehrere Long-Reads */
2599 
2600           if ((ParRecs[z1].LongSrc) && (ParRecs[z2].LongSrc))
2601             WrXError(ErrNum_MultipleLongRead, TestUnit);
2602 
2603           /* mehrere Long-Writes */
2604 
2605           if ((ParRecs[z1].LongDest) && (ParRecs[z2].LongDest))
2606             WrXError(ErrNum_MultipleLongWrite, TestUnit);
2607 
2608           /* Long-Read mit Store */
2609 
2610           if ((ParRecs[z1].StoreUsed) && (ParRecs[z2].LongSrc))
2611             WrXError(ErrNum_LongReadWithStore, TestUnit);
2612           if ((ParRecs[z2].StoreUsed) && (ParRecs[z1].LongSrc))
2613             WrXError(ErrNum_LongReadWithStore, TestUnit);
2614         }
2615       }
2616 
2617   for (z2 = 0; z2 < 32; z2++)
2618     RegReads[z2] = 0;
2619   for (z1 = 0; z1 < ParCnt; z1++)
2620   {
2621     Mask = 1;
2622     for (z2 = 0; z2 < 32; z2++)
2623     {
2624       if ((ParRecs[z1].SrcMask & Mask) != 0)
2625         RegReads[z2]++;
2626       if ((ParRecs[z1].SrcMask2 & Mask) != 0)
2627         RegReads[z2]++;
2628       Mask = Mask << 1;
2629     }
2630   }
2631 
2632   /* Register mehr als 4mal gelesen */
2633 
2634   for (z1 = 0; z1 < 32; z1++)
2635     if (RegReads[z1] > 4)
2636       WrXError(ErrNum_TooManyRegisterReads, RegName(z1));
2637 
2638   /* more than one branch to an absolute address */
2639 
2640   BranchCnt = 0;
2641   for (z1 = 0; z1 < ParCnt; z1++)
2642     if (ParRecs[z1].AbsBranch)
2643       BranchCnt++;
2644   if (BranchCnt > 1)
2645     WrError(ErrNum_TooManyBranchesInExPacket);
2646 }
2647 
MakeCode_3206X(void)2648 static void MakeCode_3206X(void)
2649 {
2650   CodeLen = 0; DontPrint = False;
2651 
2652   /* zu ignorierendes */
2653 
2654   if ((*OpPart.Str == '\0') && (*LabPart.Str == '\0'))
2655     return;
2656 
2657   /* Pseudoanweisungen */
2658 
2659   if (DecodePseudo())
2660     return;
2661 
2662   /* Flags zuruecksetzen */
2663 
2664   ThisPar = False;
2665     Condition = 0;
2666 
2667   /* Optionen aus Label holen */
2668 
2669   if (*LabPart.Str != '\0')
2670     if ((!strcmp(LabPart.Str, "||")) || (*LabPart.Str == '['))
2671      if (!CheckOpt(LabPart.Str))
2672        return;
2673 
2674   /* eventuell falsche Mnemonics verwerten */
2675 
2676   if (!strcmp(OpPart.Str, "||"))
2677     if (!ReiterateOpPart())
2678       return;
2679   if (*OpPart.Str == '[')
2680     if (!ReiterateOpPart())
2681       return;
2682 
2683   if (Memo(""))
2684     return;
2685 
2686   /* Attribut auswerten */
2687 
2688   ThisUnit = NoUnit;
2689   ThisCross = False;
2690   if (*AttrPart.Str)
2691   {
2692     if (as_toupper(AttrPart.Str[strlen(AttrPart.Str) - 1]) == 'X')
2693     {
2694       ThisCross = True;
2695       AttrPart.Str[strlen(AttrPart.Str) - 1] = '\0';
2696     }
2697     if (*AttrPart.Str == '\0') ThisUnit = NoUnit;
2698     else
2699       for (; ThisUnit != LastUnit; ThisUnit++)
2700         if (!as_strcasecmp(AttrPart.Str, UnitNames[ThisUnit]))
2701           break;
2702     if (ThisUnit == LastUnit)
2703     {
2704       WrError(ErrNum_UndefAttr);
2705       return;
2706     }
2707     if (((ThisUnit == D1) || (ThisUnit == D2)) && (ThisCross))
2708     {
2709       WrError(ErrNum_InvAddrMode);
2710       return;
2711     }
2712   }
2713 
2714   /* falls nicht parallel, vorherigen Stack durchpruefen und verwerfen */
2715 
2716   if ((!ThisPar) && (ParCnt > 0))
2717   {
2718     ChkPacket();
2719     ParCnt = 0;
2720     PacketAddr = EProgCounter();
2721   }
2722 
2723   /* dekodieren */
2724 
2725   ThisSrc = 0;
2726   ThisSrc2 = 0;
2727   ThisDest = 0;
2728   ThisAddr = 0;
2729   ThisStore = ThisAbsBranch = False;
2730   ThisLong = 0;
2731   if (!DecodeInst())
2732     return;
2733 
2734   /* einsortieren */
2735 
2736   ParRecs[ParCnt].OpCode = (Condition << 28) + ThisInst;
2737   ParRecs[ParCnt].U = ThisUnit;
2738   if (ThisCross)
2739     switch (ThisUnit)
2740     {
2741       case L1: case S1: case M1: case D1:
2742         ParRecs[ParCnt].CrossUsed = 1;
2743         break;
2744       default:
2745         ParRecs[ParCnt].CrossUsed = 2;
2746     }
2747   else
2748     ParRecs[ParCnt].CrossUsed = 0;
2749   ParRecs[ParCnt].AddrUsed = ThisAddr;
2750   ParRecs[ParCnt].SrcMask = ThisSrc;
2751   ParRecs[ParCnt].SrcMask2 = ThisSrc2;
2752   ParRecs[ParCnt].DestMask = ThisDest;
2753   ParRecs[ParCnt].LongSrc = ((ThisLong & 1) == 1);
2754   ParRecs[ParCnt].LongDest = ((ThisLong & 2) == 2);
2755   ParRecs[ParCnt].StoreUsed = ThisStore;
2756   ParRecs[ParCnt].AbsBranch = ThisAbsBranch;
2757   ParCnt++;
2758 
2759   /* wenn mehr als eine Instruktion, Ressourcenkonflikte abklopfen und
2760     vorherige Instruktion zuruecknehmen */
2761 
2762   if (ParCnt > 1)
2763   {
2764     RetractWords(4);
2765     DAsmCode[CodeLen >> 2] = ParRecs[ParCnt - 2].OpCode | 1;
2766     CodeLen += 4;
2767   }
2768 
2769   /* aktuelle Instruktion auswerfen: fuer letzte kein Parallelflag setzen */
2770 
2771   DAsmCode[CodeLen >> 2] = ParRecs[ParCnt - 1].OpCode;
2772   CodeLen += 4;
2773 }
2774 
2775 /*-------------------------------------------------------------------------*/
2776 
AddLinAdd(const char * NName,LongInt NCode)2777 static void AddLinAdd(const char *NName, LongInt NCode)
2778 {
2779   if (InstrZ >= LinAddCnt) exit(255);
2780   LinAddOrders[InstrZ].Code = NCode;
2781   AddInstTable(InstTable, NName, InstrZ++, DecodeLinAdd);
2782 }
2783 
AddCmp(const char * NName,LongInt NCode)2784 static void AddCmp(const char *NName, LongInt NCode)
2785 {
2786   if (InstrZ >= CmpCnt) exit(255);
2787   CmpOrders[InstrZ].WithImm = NName[strlen(NName) - 1] != 'U';
2788   CmpOrders[InstrZ].Code = NCode;
2789   AddInstTable(InstTable, NName, InstrZ++, DecodeCmp);
2790 }
2791 
AddMem(const char * NName,LongInt NCode,LongInt NScale)2792 static void AddMem(const char *NName, LongInt NCode, LongInt NScale)
2793 {
2794   if (InstrZ >= MemCnt) exit(255);
2795   MemOrders[InstrZ].Code = NCode;
2796   MemOrders[InstrZ].Scale = NScale;
2797   AddInstTable(InstTable,NName, InstrZ++, DecodeMemO);
2798 }
2799 
AddMul(const char * NName,LongInt NCode,Boolean NDSign,Boolean NSSign1,Boolean NSSign2,Boolean NMay)2800 static void AddMul(const char *NName, LongInt NCode,
2801                    Boolean NDSign, Boolean NSSign1, Boolean NSSign2, Boolean NMay)
2802 {
2803   if (InstrZ >= MulCnt) exit(255);
2804   MulOrders[InstrZ].Code = NCode;
2805   MulOrders[InstrZ].DSign = NDSign;
2806   MulOrders[InstrZ].SSign1 = NSSign1;
2807   MulOrders[InstrZ].SSign2 = NSSign2;
2808   MulOrders[InstrZ].MayImm = NMay;
2809   AddInstTable(InstTable, NName, InstrZ++, DecodeMul);
2810 }
2811 
AddCtrl(const char * NName,LongInt NCode,Boolean NWr,Boolean NRd)2812 static void AddCtrl(const char *NName, LongInt NCode,
2813                     Boolean NWr, Boolean NRd)
2814 {
2815   if (InstrZ >= CtrlCnt) exit(255);
2816   CtrlRegs[InstrZ].Name = NName;
2817   CtrlRegs[InstrZ].Code = NCode;
2818   CtrlRegs[InstrZ].Wr = NWr;
2819   CtrlRegs[InstrZ++].Rd = NRd;
2820 }
2821 
InitFields(void)2822 static void InitFields(void)
2823 {
2824   InstTable = CreateInstTable(203);
2825 
2826   AddInstTable(InstTable, "IDLE", 0, DecodeIDLE);
2827   AddInstTable(InstTable, "NOP", 0, DecodeNOP);
2828   AddInstTable(InstTable, "STP", 0, DecodeSTP);
2829   AddInstTable(InstTable, "ABS", 0, DecodeABS);
2830   AddInstTable(InstTable, "ADD", 0, DecodeADD);
2831   AddInstTable(InstTable, "ADDU", 0, DecodeADDU);
2832   AddInstTable(InstTable, "SUB", 0, DecodeSUB);
2833   AddInstTable(InstTable, "SUBU", 0, DecodeSUBU);
2834   AddInstTable(InstTable, "SUBC", 0, DecodeSUBC);
2835   AddInstTable(InstTable, "ADDK", 0, DecodeADDK);
2836   AddInstTable(InstTable, "ADD2", 0, DecodeADD2_SUB2);
2837   AddInstTable(InstTable, "SUB2", 1, DecodeADD2_SUB2);
2838   AddInstTable(InstTable, "AND", 0x1f7b, DecodeLogic);
2839   AddInstTable(InstTable, "OR", 0x1b7f, DecodeLogic);
2840   AddInstTable(InstTable, "XOR", 0x0b6f, DecodeLogic);
2841   AddInstTable(InstTable, "MV", 0, DecodeMV);
2842   AddInstTable(InstTable, "NEG", 0, DecodeNEG);
2843   AddInstTable(InstTable, "NOT", 0, DecodeNOT);
2844   AddInstTable(InstTable, "ZERO", 0, DecodeZERO);
2845   AddInstTable(InstTable, "CLR",  0x3fc8, DecodeCLR_EXT_EXTU_SET);
2846   AddInstTable(InstTable, "EXT",  0x2f48, DecodeCLR_EXT_EXTU_SET);
2847   AddInstTable(InstTable, "EXTU", 0x2b08, DecodeCLR_EXT_EXTU_SET);
2848   AddInstTable(InstTable, "SET",  0x3b88, DecodeCLR_EXT_EXTU_SET);
2849   AddInstTable(InstTable, "LMBD", 0, DecodeLMBD);
2850   AddInstTable(InstTable, "NORM", 0, DecodeNORM);
2851   AddInstTable(InstTable, "SADD", 0, DecodeSADD);
2852   AddInstTable(InstTable, "SAT", 0, DecodeSAT);
2853   AddInstTable(InstTable, "MVC", 0, DecodeMVC);
2854   AddInstTable(InstTable, "MVKL", 0x0028, DecodeMVK);
2855   AddInstTable(InstTable, "MVK", 0x0028, DecodeMVK);
2856   AddInstTable(InstTable, "MVKH", 0x1068, DecodeMVK);
2857   AddInstTable(InstTable, "MVKLH", 0x0068, DecodeMVK);
2858   AddInstTable(InstTable, "SHL", 0, DecodeSHL);
2859   AddInstTable(InstTable, "SHR", 16, DecodeSHR_SHRU);
2860   AddInstTable(InstTable, "SHRU", 0, DecodeSHR_SHRU);
2861   AddInstTable(InstTable, "SSHL", 0, DecodeSSHL);
2862   AddInstTable(InstTable, "SSUB", 0, DecodeSSUB);
2863   AddInstTable(InstTable, "B", 0, DecodeB);
2864 
2865   LinAddOrders = (FixedOrder *) malloc(sizeof(FixedOrder)*LinAddCnt); InstrZ = 0;
2866   AddLinAdd("ADDAB", 0x30); AddLinAdd("ADDAH", 0x34); AddLinAdd("ADDAW", 0x38);
2867   AddLinAdd("SUBAB", 0x31); AddLinAdd("SUBAH", 0x35); AddLinAdd("SUBAW", 0x39);
2868 
2869   CmpOrders = (CmpOrder *) malloc(sizeof(CmpOrder)*CmpCnt); InstrZ = 0;
2870   AddCmp("CMPEQ", 0x50); AddCmp("CMPGT", 0x44); AddCmp("CMPGTU", 0x4c);
2871   AddCmp("CMPLT", 0x54); AddCmp("CMPLTU", 0x5c);
2872 
2873   MemOrders = (MemOrder *) malloc(sizeof(MemOrder)*MemCnt); InstrZ = 0;
2874   AddMem("LDB", 2, 1);  AddMem("LDH", 4, 2);  AddMem("LDW", 6, 4);
2875   AddMem("LDBU", 1, 1); AddMem("LDHU", 0, 2); AddMem("STB", 3, 1);
2876   AddMem("STH", 5, 2);  AddMem("STW", 7, 4);
2877 
2878   MulOrders = (MulOrder *) malloc(sizeof(MulOrder)*MulCnt); InstrZ = 0;
2879   AddMul("MPY"    , 0x19, True , True , True , True );
2880   AddMul("MPYU"   , 0x1f, False, False, False, False);
2881   AddMul("MPYUS"  , 0x1d, True , False, True , False);
2882   AddMul("MPYSU"  , 0x1b, True , True , False, True );
2883   AddMul("MPYH"   , 0x01, True , True , True , False);
2884   AddMul("MPYHU"  , 0x07, False, False, False, False);
2885   AddMul("MPYHUS" , 0x05, True , False, True , False);
2886   AddMul("MPYHSU" , 0x03, True , True , False, False);
2887   AddMul("MPYHL"  , 0x09, True , True , True , False);
2888   AddMul("MPYHLU" , 0x0f, False, False, False, False);
2889   AddMul("MPYHULS", 0x0d, True , False, True , False);
2890   AddMul("MPYHSLU", 0x0b, True , True , False, False);
2891   AddMul("MPYLH"  , 0x11, True , True , True , False);
2892   AddMul("MPYLHU" , 0x17, False, False, False, False);
2893   AddMul("MPYLUHS", 0x15, True , False, True , False);
2894   AddMul("MPYLSHU", 0x13, True , True , False, False);
2895   AddMul("SMPY"   , 0x1a, True , True , True , False);
2896   AddMul("SMPYHL" , 0x0a, True , True , True , False);
2897   AddMul("SMPYLH" , 0x12, True , True , True , False);
2898   AddMul("SMPYH"  , 0x02, True , True , True , False);
2899 
2900   CtrlRegs = (CtrlReg *) malloc(sizeof(CtrlReg)*CtrlCnt); InstrZ = 0;
2901   AddCtrl("AMR"    ,  0, True , True );
2902   AddCtrl("CSR"    ,  1, True , True );
2903   AddCtrl("IFR"    ,  2, False, True );
2904   AddCtrl("ISR"    ,  2, True , False);
2905   AddCtrl("ICR"    ,  3, True , False);
2906   AddCtrl("IER"    ,  4, True , True );
2907   AddCtrl("ISTP"   ,  5, True , True );
2908   AddCtrl("IRP"    ,  6, True , True );
2909   AddCtrl("NRP"    ,  7, True , True );
2910   AddCtrl("IN"     ,  8, False, True );
2911   AddCtrl("OUT"    ,  9, True , True );
2912   AddCtrl("PCE1"   , 16, False, True );
2913   AddCtrl("PDATA_O", 15, True , True );
2914 }
2915 
DeinitFields(void)2916 static void DeinitFields(void)
2917 {
2918   DestroyInstTable(InstTable);
2919   free(LinAddOrders);
2920   free(CmpOrders);
2921   free(MemOrders);
2922   free(MulOrders);
2923   free(CtrlRegs);
2924 }
2925 
2926 /*------------------------------------------------------------------------*/
2927 
IsDef_3206X(void)2928 static Boolean IsDef_3206X(void)
2929 {
2930   return (!strcmp(LabPart.Str, "||")) || (*LabPart.Str == '[');
2931 }
2932 
SwitchFrom_3206X(void)2933 static void SwitchFrom_3206X(void)
2934 {
2935   if (ParCnt > 1)
2936     ChkPacket();
2937   DeinitFields();
2938   if (ParRecs)
2939   {
2940     free(ParRecs);
2941     ParRecs = NULL;
2942   }
2943 }
2944 
Chk34Arg(void)2945 static Boolean Chk34Arg(void)
2946 {
2947   return (ArgCnt >= 3);
2948 }
2949 
SwitchTo_3206X(void)2950 static void SwitchTo_3206X(void)
2951 {
2952   TurnWords = False;
2953   ConstMode = ConstModeIntel;
2954   SetIsOccupiedFnc = Chk34Arg;
2955 
2956   PCSymbol = "$";
2957   HeaderID = 0x47;
2958   NOPCode = 0x00000000;
2959   DivideChars = ",";
2960   HasAttrs = True;
2961   AttrChars = ".";
2962 
2963   ValidSegs = 1 << SegCode;
2964   Grans[SegCode] = 1; ListGrans[SegCode] = 4; SegInits[SegCode] = 0;
2965   SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
2966 
2967   MakeCode = MakeCode_3206X;
2968   IsDef = IsDef_3206X;
2969   SwitchFrom = SwitchFrom_3206X;
2970   ParRecs = (InstrRec*)malloc(sizeof(InstrRec) * MaxParCnt);
2971   InitFields();
2972 
2973   ParCnt = 0;
2974   PacketAddr = 0;
2975 }
2976 
code3206x_init(void)2977 void code3206x_init(void)
2978 {
2979   CPU32060 = AddCPU("32060", SwitchTo_3206X);
2980 }
2981