Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

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