Subversion Repositories pentevo

Rev

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

  1. /* coderx.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator Renesas RX                                                  */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <ctype.h>
  13. #include <string.h>
  14.  
  15. #include "nls.h"
  16. #include "strutil.h"
  17. #include "chunks.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmitree.h"
  22. #include "codevars.h"
  23. #include "codepseudo.h"
  24. #include "headids.h"
  25. #include "errmsg.h"
  26. #include "ieeefloat.h"
  27. #include "onoff_common.h"
  28. #include "intpseudo.h"
  29. #include "be_le.h"
  30.  
  31. #include "coderx.h"
  32.  
  33. /*---------------------------------------------------------------------------*/
  34.  
  35. /* Define this to use Renesas Assembler like pseudo instructions */
  36. #define COMPAT
  37.  
  38. /*---------------------------------------------------------------------------*/
  39.  
  40. typedef enum
  41. {
  42.         eRn,
  43.         eDRn,
  44.         eDRHn,
  45.         eDRLn,
  46.         eDCRn
  47. } tRegType;
  48.  
  49. typedef enum
  50. {
  51.         eRXv1,
  52.         eRXv2,
  53.         eRXv3
  54. } tInstSet;
  55.  
  56. typedef struct
  57. {
  58.         char Name[7];
  59.         tInstSet InstSet;
  60.         Boolean hasFloat;
  61.         Boolean hasDouble;
  62.         Word RegBank;
  63.         Boolean hasMVTIPL;
  64. } tCPUProps;
  65.  
  66. /*---------------------------------------------------------------------------*/
  67.  
  68. static const tCPUProps *pCurrCPUProps;
  69.  
  70. static tStrComp Temp1;
  71. static tStrComp Temp2;
  72.  
  73. /*---------------------------------------------------------------------------*/
  74.  
  75. static Boolean ChkNoAttr(void)
  76. {
  77.         if (AttrPart.str.p_str[0])
  78.         {
  79.                 WrError(ErrNum_UseLessAttr);
  80.                 return False;
  81.         }
  82.  
  83.         return True;
  84. }
  85.  
  86. static Boolean CheckSup(void)
  87. {
  88.         if (SupAllowed) return True;
  89.        
  90.         WrStrErrorPos(ErrNum_PrivOrder, &OpPart);
  91.         return False;
  92. }
  93.  
  94. static Boolean CheckV2(void)
  95. {
  96.         if (pCurrCPUProps->InstSet >= eRXv2) return True;
  97.  
  98.         WrError(ErrNum_InstructionNotSupported);
  99.         return False;
  100. }
  101.  
  102. static Boolean CheckV3(void)
  103. {
  104.         if (pCurrCPUProps->InstSet >= eRXv3) return True;
  105.  
  106.         WrError(ErrNum_InstructionNotSupported);
  107.         return False;
  108. }
  109.  
  110. static Boolean CheckFloat(void)
  111. {
  112.         if (pCurrCPUProps->hasFloat) return True;
  113.  
  114.         WrError(ErrNum_FPUNotEnabled);
  115.         return False;
  116. }
  117.  
  118. static Boolean CheckDouble(void)
  119. {
  120.         if (pCurrCPUProps->hasDouble) return True;
  121.  
  122.         WrError(ErrNum_FPUNotEnabled);
  123.         return False;
  124. }
  125.  
  126. static const char *DCReg[] = {
  127.         "DPSW",
  128.         "DCMR",
  129.         "DECNT",
  130.         "DEPC"
  131. };
  132.  
  133. static Boolean DecodeReg(const tStrComp *pArg, Byte *pResult, tRegType type)
  134. {
  135.         const char *str = pArg->str.p_str;
  136.         const int len = strlen(str);
  137.         int i;
  138.         int num = 16;
  139.  
  140.         switch (type)
  141.         {
  142.         case eRn:
  143.                 if (as_strncasecmp(str, "R", 1)) return False;
  144.                 i = 1;
  145.                 break;
  146.         case eDRn:
  147.                 if (as_strncasecmp(str, "DR", 2)) return False;
  148.                 i = 2;
  149.                 break;
  150.         case eDRHn:
  151.                 if (as_strncasecmp(str, "DRH", 3)) return False;
  152.                 i = 3;
  153.                 break;
  154.         case eDRLn:
  155.                 if (as_strncasecmp(str, "DRL", 3)) return False;
  156.                 i = 3;
  157.                 break;
  158.         case eDCRn:
  159.                 for (i = 0; i < 4; i++)
  160.                 {
  161.                         if (!as_strcasecmp(str, DCReg[i]))
  162.                         {
  163.                                 *pResult = i;
  164.                                 return True;
  165.                         }
  166.                 }
  167.                 if (as_strncasecmp(str, "DCR", 3)) return False;
  168.                 i = 3;
  169.                 num = 4;
  170.                 break;
  171.         default:
  172.                 return False;
  173.         }
  174.         *pResult = 0;
  175.         for (; i < len; i++)
  176.         {
  177.                 if (!isdigit(str[i])) return False;
  178.                 *pResult = *pResult * 10 + (str[i] - '0');
  179.         }
  180.  
  181.         return *pResult < num;
  182. }
  183.  
  184. static Boolean DecodeImm(const tStrComp *pArg, LongInt *pResult, tSymbolFlags *pFlags)
  185. {
  186.         const char *str = pArg->str.p_str;
  187.         tStrComp ImmArg;
  188.         Boolean ValOK;
  189.         tSymbolFlags flags;
  190.  
  191.         if (str[0] != '#') return False;
  192.  
  193.         StrCompRefRight(&ImmArg, pArg, 1);
  194.         *pResult = EvalStrIntExpressionWithFlags(&ImmArg, Int32, &ValOK, &flags);
  195.         if (pFlags) *pFlags = flags;
  196.  
  197.         return ValOK;
  198. }
  199.  
  200. static Byte ImmSize32(LongInt value, tSymbolFlags flags)
  201. {
  202.         if (mFirstPassUnknown(flags)) return 0x00;      /* Temporarily return maximum size */
  203.  
  204.         if ((value & 0xFFFFFF80) == 0xFFFFFF80 ||
  205.                 (value & 0xFFFFFF80) == 0x00000000) return 0x01;        /* SIMM:8 */
  206.  
  207.         if ((value & 0xFFFF8000) == 0xFFFF8000 ||
  208.                 (value & 0xFFFF8000) == 0x00000000) return 0x02;        /* SIMM:16 */
  209.  
  210.         if ((value & 0xFF800000) == 0xFF800000 ||
  211.                 (value & 0xFF800000) == 0x00000000) return 0x03;        /* SIMM:24 */
  212.  
  213.         return 0x00;    /* IMM:32 */
  214. }
  215.  
  216. static Byte ImmSize16(LongInt value, tSymbolFlags flags)
  217. {
  218.         if (mFirstPassUnknown(flags)) return 0x02;      /* Temporarily return maximum size */
  219.  
  220.         if ((value & 0xFFFFFF80) == 0xFFFFFF80 ||
  221.                 (value & 0xFFFFFF80) == 0x00000000) return 0x01;        /* SIMM:8 */
  222.  
  223.         return 0x02;    /* IMM:16 */
  224. }
  225.  
  226. static int ImmOut(int pos, Byte size, LongInt imm)
  227. {
  228.         int i;
  229.  
  230.         if (size == 0x00) size = 4;
  231.         for (i = 0; i < size; i++)
  232.         {
  233.                 BAsmCode[pos+i] = imm & 0xFF;
  234.                 imm >>= 8;
  235.         }
  236.         return pos + size;
  237. }
  238.  
  239. static Boolean DecodeIndirectADC(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags)
  240. {
  241.         const char *str = pArg->str.p_str;
  242.         const int len = strlen(str);
  243.         int pos;
  244.         Boolean ValOK;
  245.  
  246.         if (str[len-1] != ']') return False;
  247.         for (pos = len - 2; pos >= 0; pos--)
  248.         {
  249.                 if (str[pos] == '[') break;
  250.         }
  251.         if (pos < 0) return False;
  252.  
  253.         StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 2);
  254.         if (!DecodeReg(&Temp1, reg, eRn)) return False;
  255.  
  256.         if (pos == 0)
  257.         {
  258.                 *flags = eSymbolFlag_None;
  259.                 *disp = 0;
  260.                 return True;
  261.         }
  262.  
  263.         StrCompCopySub(&Temp1, pArg, 0, pos);
  264.         *disp = EvalStrIntExpressionWithFlags(&Temp1, UInt20, &ValOK, flags);
  265.  
  266.         return ValOK;
  267. }
  268.  
  269. static Byte DispSize(LongInt disp, tSymbolFlags flags, Byte scale)
  270. {
  271.         Byte size = 0;
  272.         Byte mask = scale - 1;
  273.  
  274.   UNUSED(flags);
  275.  
  276.         if (disp & mask)
  277.         {
  278.                 WrStrErrorPos(ErrNum_NotAligned, &ArgStr[1]);
  279.                 return 0;
  280.         }
  281.         disp /= scale;
  282.  
  283.         if (disp == 0) size = 0x00;
  284.         else if (disp < 0) size = 0xFF;
  285.         else if (disp < 256) size = 0x01;
  286.         else if (disp < 65536) size = 0x02;
  287.         else size = 0xFF;
  288.  
  289.         return size;
  290. }
  291.  
  292. static int DispOut(int pos, Byte size, LongInt disp, Byte scale)
  293. {
  294.         int i;
  295.  
  296.         disp /= scale;
  297.  
  298.         if (size > 0x02) size = 0x00;
  299.         for (i = 0; i < size; i++ )
  300.         {
  301.                 BAsmCode[pos+i] = disp & 0xFF;
  302.                 disp >>= 8;
  303.         }
  304.         return  pos + size;
  305. }
  306.  
  307. static Boolean DecodeIndirectADD(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags, Byte *memex, Byte *scale)
  308. {
  309.         const char *str = pArg->str.p_str;
  310.         const int len = strlen(str);
  311.  
  312.         if (len > 2 && str[len-2] == '.')
  313.         {
  314.                 switch (as_toupper(str[len-1]))
  315.                 {
  316.                 case 'B':
  317.                         *memex = 0x00;
  318.                         *scale = 1;
  319.                         break;
  320.                 case 'W':
  321.                         *memex = 0x01;
  322.                         *scale = 2;
  323.                         break;
  324.                 case 'L':
  325.                         *memex = 0x02;
  326.                         *scale = 4;
  327.                         break;
  328.                 default:
  329.                         return False;
  330.                 }
  331.                 StrCompCopySub(&Temp2, pArg, 0, len - 2);
  332.                 pArg = &Temp2;
  333.         }
  334.         else if (len > 3 && str[len-3] == '.' && as_toupper(str[len-2]) == 'U')
  335.         {
  336.                 switch (as_toupper(str[len-1]))
  337.                 {
  338.                 case 'B':
  339.                         *memex = 0x80;
  340.                         *scale = 1;
  341.                         break;
  342.                 case 'W':
  343.                         *memex = 0x03;
  344.                         *scale = 2;
  345.                         break;
  346.                 default:
  347.                         return False;
  348.                 }
  349.                 StrCompCopySub(&Temp2, pArg, 0, len - 3);
  350.                 pArg = &Temp2;
  351.         }
  352.  
  353.         return DecodeIndirectADC(pArg, reg, disp, flags);
  354. }
  355.  
  356. static Boolean DecodeFloat(const tStrComp *pArg, LongInt *pResult)
  357. {
  358.         const char *str = pArg->str.p_str;
  359.         tStrComp ImmArg;
  360.         TempResult temp;
  361.   Boolean Result = True;
  362.  
  363.         if (str[0] != '#') return False;
  364.  
  365.         StrCompRefRight(&ImmArg, pArg, 1);
  366.   as_tempres_ini(&temp);
  367.         EvalStrExpression(&ImmArg, &temp);
  368.         switch (temp.Typ)
  369.         {
  370.         case TempInt:
  371.                 *pResult = temp.Contents.Int;
  372.                 break;
  373.         case TempFloat:
  374.                 as_float_2_ieee4(temp.Contents.Float, (unsigned char *)pResult, False);
  375.     /* TODO: rework this - we should better pass in a byte array as pResult */
  376.     if (HostBigEndian)
  377.       DSwap(pResult, 4);
  378.                 break;
  379.         default:
  380.                 Result = False;
  381.         }
  382.   as_tempres_free(&temp);
  383.  
  384.         return Result;
  385. }
  386.  
  387. static Boolean DecodeIndirectL(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags)
  388. {
  389.         Boolean result;
  390.         Byte memex = 0x02;      /* L */
  391.         Byte scale;
  392.  
  393.         result = DecodeIndirectADD(pArg, reg, disp, flags, &memex, &scale);
  394.  
  395.         if (result && memex != 0x02) result = False;
  396.  
  397.         return result;
  398. }
  399.  
  400. static tSymbolSize DecodeAttrSize(void)
  401. {
  402.         switch (strlen(AttrPart.str.p_str))
  403.         {
  404.                 case 0:
  405.                         WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  406.                         return eSymbolSizeUnknown;
  407.                 case 1:
  408.                         switch (AttrPart.str.p_str[0])
  409.                         {
  410.                                 case 'B':
  411.                                         return eSymbolSize8Bit;
  412.                                 case 'W':
  413.                                         return eSymbolSize16Bit;
  414.                                 case 'L':
  415.                                         return eSymbolSize32Bit;
  416.                                 default:
  417.                                         WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  418.                                         return eSymbolSizeUnknown;
  419.                         }
  420.                 default:
  421.                         WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart);
  422.                         return eSymbolSizeUnknown;
  423.                 }
  424. }
  425.  
  426. static Boolean DecodeRelative(const tStrComp *pArg, Byte *reg, LongInt *disp, tSymbolFlags *flags)
  427. {       /* dsp:5[Rn] (R0-R7) */
  428.         const char *str = pArg->str.p_str;
  429.         const int len = strlen(str);
  430.         int pos;
  431.         Boolean ValOK;
  432.  
  433.         if (str[len-1] != ']') return False;
  434.         for (pos = len - 2; pos > 0; pos--)
  435.         {
  436.                 if (str[pos] == '[') break;
  437.         }
  438.         if (pos < 1) return False;
  439.  
  440.         StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 2);
  441.         if (!DecodeReg(&Temp1, reg, eRn)) return False;
  442.         if (*reg > 7) return False;
  443.  
  444.         StrCompCopySub(&Temp1, pArg, 0, pos);
  445.         *disp = EvalStrIntExpressionWithFlags(&Temp1, UInt20, &ValOK, flags);
  446.  
  447.         return ValOK;
  448. }
  449.  
  450. static int Size2Scale(Byte size)
  451. {
  452.         Byte scale;
  453.  
  454.         switch (size)
  455.         {
  456.         case 0x00:      /* B */
  457.                 scale = 1;
  458.                 break;
  459.         case 0x01:      /* W */
  460.                 scale = 2;
  461.                 break;
  462.         case 0x02:      /* L */
  463.                 scale = 4;
  464.                 break;
  465.         default:
  466.                 return -1;
  467.         }
  468.  
  469.         return scale;
  470. }
  471.  
  472. static Boolean ChkDisp5(Byte size, LongInt disp, tSymbolFlags flags)
  473. {
  474.         const int scale = Size2Scale(size);
  475.  
  476.         if (scale < 0) return False;
  477.        
  478.         if (!mFirstPassUnknown(flags))
  479.         {
  480.                 if (disp & (scale - 1))
  481.                 {
  482.                         WrError(ErrNum_AddrMustBeAligned);
  483.                         return False;
  484.                 }
  485.  
  486.                 if (disp / scale > 31 || disp < 0) return False;
  487.         }
  488.  
  489.         return True;
  490. }
  491.  
  492. static Byte DispSize5(Byte size, LongInt disp)
  493. {
  494.         const Byte scale = Size2Scale(size);
  495.  
  496.         return disp / scale;
  497. }
  498.  
  499. static Boolean DecodeIndexed(tStrComp *pArg, Byte *regi, Byte *regb)
  500. {       /* [Ri,Rb] */
  501.         const char *str = pArg->str.p_str;
  502.         const int len = strlen(str);
  503.         int pos;
  504.  
  505.         if (str[0] != '[' || str[len-1] != ']') return False;
  506.  
  507.         for (pos = 2; pos < len - 2; pos++)
  508.         {
  509.                 if (str[pos] == ',') break;
  510.         }
  511.  
  512.         StrCompCopySub(&Temp1, pArg, 1, pos - 1);
  513.         if (!DecodeReg(&Temp1, regi, eRn)) return False;
  514.  
  515.         StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 2);
  516.         if (!DecodeReg(&Temp1, regb, eRn)) return False;
  517.  
  518.         return True;
  519. }
  520.  
  521. static Boolean DecodeIncDec(tStrComp *pArg, Byte *reg, Byte *id)
  522. {       /* [Rn+] / [-Rn]] */
  523.         const char *str = pArg->str.p_str;
  524.         const int len = strlen(str);
  525.  
  526.         if (len < 5) return False;
  527.         if (str[0] != '[' || str[len-1] != ']') return False;
  528.  
  529.         if (str[len-2] == '+')
  530.         {
  531.                 *id = 0x00;
  532.                 StrCompCopySub(&Temp1, pArg, 1, len - 3);
  533.         }
  534.         else if (str[1] == '-')
  535.         {
  536.                 *id = 0x01;
  537.                 StrCompCopySub(&Temp1, pArg, 2, len - 3);
  538.         }
  539.         else return False;
  540.  
  541.         return DecodeReg(&Temp1, reg, eRn);
  542. }
  543.  
  544. static Boolean DecodeRegRange(tStrComp *pArg, Byte *range)
  545. {
  546.         const char *str = pArg->str.p_str;
  547.         const int len = strlen(str);
  548.         Byte reg1;
  549.         Byte reg2;
  550.         int pos;
  551.  
  552.         if (len < 5) return False;
  553.         for (pos = 2; pos < len - 2; pos++)
  554.         {
  555.                 if (str[pos] == '-') break;
  556.         }
  557.         if (pos >= len - 2) return False;
  558.  
  559.         StrCompCopySub(&Temp1, pArg, 0, pos);
  560.         if (!DecodeReg(&Temp1, &reg1, eRn)) return False;
  561.  
  562.         StrCompCopySub(&Temp1, pArg, pos + 1, len - pos - 1);
  563.         if (!DecodeReg(&Temp1, &reg2, eRn)) return False;
  564.  
  565.         if (reg1 == 0 || reg1 >= reg2) return False;
  566.  
  567.         *range = (reg1 << 4) | reg2;
  568.         return True;
  569. }
  570.  
  571. static Boolean DecodeIndirect(tStrComp *pArg, Byte *reg)
  572. {
  573.         const char *str = pArg->str.p_str;
  574.         const int len = strlen(str);
  575.  
  576.         if (str[0] != '[') return False;
  577.         if (str[len-1] != ']') return False;
  578.  
  579.         StrCompCopySub(&Temp1, pArg, 1, len - 2);
  580.         if (!DecodeReg(&Temp1, reg, eRn)) return False;
  581.  
  582.         return True;
  583. }
  584.  
  585. static Boolean DecodeAcc(tStrComp *pArg, Byte *acc)
  586. {
  587.         const char *str = pArg->str.p_str;
  588.         const int len = strlen(str);
  589.  
  590.         if (len != 2) return False;
  591.         if (as_toupper(str[0]) != 'A') return False;
  592.         if (str[1] != '0' && str[1] != '1') return False;
  593.  
  594.         *acc = str[1] - '0';
  595.         return True;
  596. }
  597.  
  598. static Boolean DecodeAttrDouble(Byte *size)
  599. {
  600.         if (strlen(AttrPart.str.p_str) != 1)
  601.         {
  602.                 WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart);
  603.                 return False;
  604.         }
  605.         switch (as_toupper(AttrPart.str.p_str[0]))
  606.         {
  607.         case 'L':
  608.                 *size = 0;
  609.                 break;
  610.         case 'D':
  611.                 *size = 1;
  612.                 break;
  613.         default:
  614.                 WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  615.                 return False;
  616.         }
  617.  
  618.         return True;
  619. }
  620.  
  621. /*---------------------------------------------------------------------------*/
  622.  
  623. static void DecodeABS(Word Index)
  624. {
  625.         if (!ChkNoAttr()) return;
  626.         if (!ChkArgCnt(1,2)) return;
  627.  
  628.         if (ArgCnt == 1)
  629.         {
  630.                 Byte reg;
  631.  
  632.                 if (!DecodeReg(&ArgStr[1], &reg, eRn))
  633.                 {
  634.                         WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  635.                         return;
  636.                 }
  637.                
  638.                 BAsmCode[0] = 0x7E;
  639.                 BAsmCode[1] = (Index >> 8) | reg;
  640.                 CodeLen = 2;
  641.         }
  642.         else
  643.         {
  644.                 Byte regs;
  645.                 Byte regd;
  646.  
  647.                 if (!DecodeReg(&ArgStr[1], &regs, eRn))
  648.                 {
  649.                         WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  650.                         return;
  651.                 }
  652.                 if (!DecodeReg(&ArgStr[2], &regd, eRn))
  653.                 {
  654.                         WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  655.                         return;
  656.                 }
  657.  
  658.                 BAsmCode[0] = 0xFC;
  659.                 BAsmCode[1] = Index & 0xFF;
  660.                 BAsmCode[2] = (regs << 4) | regd;
  661.                 CodeLen = 3;
  662.         }
  663. }
  664.  
  665. static void DecodeADC(Word Index)
  666. {
  667.         Byte regs;
  668.         Byte regd;
  669.         Byte size;
  670.         LongInt imm;
  671.         tSymbolFlags flags;
  672.         LongInt disp;
  673.  
  674.         if (!ChkNoAttr()) return;
  675.         if (!ChkArgCnt(2,2)) return;
  676.  
  677.         if (!DecodeReg(&ArgStr[2], &regd, eRn))
  678.         {
  679.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  680.                 return;
  681.         }
  682.  
  683.         if ((Index & 0x0800) && DecodeImm(&ArgStr[1], &imm, &flags))    /* ADC only */
  684.         {
  685.                 size = ImmSize32(imm, flags);
  686.  
  687.                 BAsmCode[0] = 0xFD;
  688.                 BAsmCode[1] = 0x70 | (size << 2);
  689.                 BAsmCode[2] = 0x20 | regd;
  690.                 CodeLen = ImmOut(3, size, imm);
  691.  
  692.                 return;
  693.         }
  694.  
  695.         if (DecodeReg(&ArgStr[1], &regs, eRn))
  696.         {
  697.                 BAsmCode[0] = 0xFC;
  698.                 BAsmCode[1] = 0x03 | (Index >> 8);
  699.                 BAsmCode[2] = (regs << 4) | regd;
  700.                 CodeLen = 3;
  701.  
  702.                 return;
  703.         }
  704.  
  705.         if (DecodeIndirectL(&ArgStr[1], &regs, &disp, &flags))
  706.         {
  707.                 if (mFirstPassUnknown(flags)) size = 0x02;
  708.                 else size = DispSize(disp, flags, 4);
  709.  
  710.                 BAsmCode[0] = 0x06;
  711.                 BAsmCode[1] = 0xA0 | size;
  712.                 BAsmCode[2] = Index & 0xFF;
  713.                 BAsmCode[3] = (regs << 4) | regd;
  714.                 CodeLen = DispOut(4, size, disp, 4);
  715.         }
  716. }
  717.  
  718. static const struct {
  719.         Byte OpcImm4;   /* #IMM:4,Rd */
  720.         Byte OpcImm1;   /* #IMM:*(,Rs),Rd 1st byte */
  721.         Byte OpcImm2;   /* 2nd byte */
  722.         Byte Opc2;      /* Rs,Rd / [Rs].UB,Rd */
  723.         Byte Opc3;      /* Rs,Rs2,Rd */
  724.         Byte Opc4;      /* [Rs],Rd */
  725.         Byte flags;     /* 1<<0:, 1<<1:, 1<<2:#UIMM8 1<<3:Rs,Rs,Rd */
  726. } OpTabADD[] = {
  727.         { 0x62, 0x70, 0x00, 0x48, 0x20, 0x08, 0x0B },   /* ADD */
  728.         { 0x64, 0x74, 0x20, 0x50, 0x40, 0x10, 0x09 },   /* AND */
  729.         { 0x61, 0x74, 0x00, 0x44, 0,    0x04, 0x05 },   /* CMP */
  730.         { 0x63, 0x74, 0x10, 0x4C, 0x30, 0x0C, 0x09 },   /* MUL */
  731.         { 0x65, 0x74, 0x30, 0x54, 0x50, 0x14, 0x09 },   /* OR */
  732.         { 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x08 },   /* SUB */
  733. };
  734.  
  735. static void DecodeADD(Word Index)
  736. {
  737.         Byte regs1;
  738.         Byte regs2;
  739.         Byte regd;
  740.         Byte size;
  741.         LongInt imm;
  742.         tSymbolFlags flags;
  743.         LongInt disp;
  744.         Byte memex;
  745.         Byte scale;
  746.  
  747.         if (!ChkNoAttr()) return;
  748.         if (!ChkArgCnt(2,3)) return;
  749.  
  750.         if (!DecodeReg(&ArgStr[2], &regs2, eRn))
  751.         {
  752.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  753.                 return;
  754.         }
  755.         if (ArgCnt == 2)
  756.                 regd = regs2;
  757.         else
  758.         {
  759.                 if (!DecodeReg(&ArgStr[3], &regd, eRn))
  760.                 {
  761.                         WrStrErrorPos(ErrNum_InvRegName, &ArgStr[3]);
  762.                         return;
  763.                 }
  764.         }
  765.  
  766.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  767.         {
  768.                 if (ArgCnt == 2 && !mFirstPassUnknown(flags) && imm >= 0 && imm < 16 )
  769.                 {       /* #UIMM:4 */
  770.                         BAsmCode[0] = OpTabADD[Index].OpcImm4;
  771.                         BAsmCode[1] = (imm << 4) | regd;
  772.                         CodeLen = 2;
  773.                         return;
  774.                 }
  775.  
  776.                 if ((OpTabADD[Index].flags & 0x04) && ArgCnt == 2 &&
  777.                         !mFirstPassUnknown(flags) && imm >= 0 && imm < 256)
  778.                 {       /* #UIMM:8 */
  779.                         BAsmCode[0] = 0x75;
  780.                         BAsmCode[1] = 0x50 | regd;
  781.                         BAsmCode[2] = imm;
  782.                         CodeLen = 3;
  783.                         return;
  784.                 }
  785.  
  786.                 if (((OpTabADD[Index].flags & 0x01) && ArgCnt == 2) || (OpTabADD[Index].flags & 0x02))
  787.                 {       /* #SIMM:* */
  788.                         size = ImmSize32(imm, flags);
  789.  
  790.                         BAsmCode[0] = OpTabADD[Index].OpcImm1 | size;
  791.                         if (OpTabADD[Index].flags & 0x02)
  792.                                 if (ArgCnt == 2)
  793.                                         BAsmCode[1] = (regd << 4) | regd;       /* #Imm,Rd */
  794.                                 else
  795.                                         BAsmCode[1] = (regs2 << 4) | regd;      /* #imm,Rs,Rd */
  796.                         else
  797.                                 BAsmCode[1] = OpTabADD[Index].OpcImm2 | regd;
  798.                         CodeLen = ImmOut(2, size, imm);
  799.                         return;
  800.                 }
  801.         }
  802.  
  803.         if (DecodeReg(&ArgStr[1], &regs1, eRn))
  804.         {       /* Rs */
  805.                 if (ArgCnt == 2)
  806.                 {
  807.                         BAsmCode[0] = OpTabADD[Index].Opc2 | 0x03;
  808.                         BAsmCode[1] = (regs1 << 4) | regd;
  809.                         CodeLen = 2;
  810.                 }
  811.                 else if (OpTabADD[Index].flags & 0x08)
  812.                 {
  813.                         BAsmCode[0] = 0xFF;
  814.                         BAsmCode[1] = OpTabADD[Index].Opc3 | regd;
  815.                         BAsmCode[2] = (regs1 << 4) | regs2;
  816.                         CodeLen = 3;
  817.                 }
  818.                 else WrStrErrorPos(ErrNum_TooManyArgs, &ArgStr[3]);
  819.                 return;
  820.         }
  821.  
  822.         if (ArgCnt == 2 && DecodeIndirectADD(&ArgStr[1], &regs1, &disp, &flags, &memex, &scale))
  823.         {
  824.                 if (memex == 0x80)
  825.                 {
  826.                         size = DispSize(disp, flags, 1);
  827.  
  828.                         BAsmCode[0] = OpTabADD[Index].Opc2 | size;
  829.                         BAsmCode[1] = (regs1 << 4) | regd;
  830.                         CodeLen = DispOut(2, size, disp, 1);
  831.                         return;
  832.                 }
  833.  
  834.                 size = DispSize(disp, flags, scale);
  835.  
  836.                 BAsmCode[0] = 0x06;
  837.                 BAsmCode[1] = OpTabADD[Index].Opc4 | (memex << 6) | size;
  838.                 BAsmCode[2] = (regs1 << 4) | regd;
  839.                 CodeLen = DispOut(3, size, disp, scale);
  840.                 return;
  841.         }
  842.  
  843.         WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
  844. }
  845.  
  846. static const struct {
  847.         Byte OpcIM1;    /* Imm3,[Rd] */
  848.         Byte OpcIM2;
  849.         Byte OpcRM;             /* Rs,[Rd] / Rs,Rd */
  850.         Byte OpcIR;     /* #Imm5,Rd */
  851.         Byte flags;
  852. } OpTabBCLR[] = {
  853.         { 0xF0, 0x08, 0x64, 0x7A, 0x00 },       /* BCLR */
  854.         { 0xF0, 0x00, 0x6C, 0,    0x01 },       /* BNOT */
  855.         { 0xF0, 0x00, 0x60, 0x78, 0x00 },       /* BSET */
  856.         { 0xF4, 0x00, 0x68, 0x7C, 0x00 },       /* BTST */
  857. };
  858.  
  859. static void DecodeBCLR(Word Index)
  860. {
  861.         Byte regs;
  862.         Byte regd;
  863.         Byte size;
  864.         Byte memex;
  865.         Byte scale;
  866.         LongInt imm;
  867.         LongInt disp;
  868.         tSymbolFlags flags;
  869.  
  870.         if (!ChkNoAttr()) return;
  871.         if (!ChkArgCnt(2,2)) return;
  872.  
  873.         memex = 0;
  874.         if (DecodeIndirectADD(&ArgStr[2], &regd, &disp, &flags, &memex, &scale))
  875.         {
  876.                 if (memex)
  877.                 {
  878.                         WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]);
  879.                         return;
  880.                 }
  881.                 size = DispSize(disp, flags, 1);
  882.                 if (size > 0x02){
  883.                         WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  884.                         return;
  885.                 }
  886.  
  887.                 if (DecodeImm(&ArgStr[1], &imm, &flags))
  888.                 {
  889.                         if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 7))
  890.                         {
  891.                                 WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
  892.                                 return;
  893.                         }
  894.  
  895.                         if (OpTabBCLR[Index].flags & 0x01)
  896.                         {       /* BNOT */
  897.                                 BAsmCode[0] = 0xFC;
  898.                                 BAsmCode[1] = 0xE0 | (imm << 2) | size;
  899.                                 BAsmCode[2] = 0x0F | (regd << 4);
  900.                                 CodeLen = DispOut(3, size, disp, 1);
  901.                         }
  902.                         else
  903.                         {       /* BCLR, BSET, BTST */
  904.                                 BAsmCode[0] = OpTabBCLR[Index].OpcIM1 | size;
  905.                                 BAsmCode[1] = OpTabBCLR[Index].OpcIM2 | (regd << 4) | imm;
  906.                                 CodeLen = DispOut(2, size, disp, 1);
  907.                         }
  908.                         return;
  909.                 }
  910.                 if (DecodeReg(&ArgStr[1], &regs, eRn))
  911.                 {
  912.                         BAsmCode[0] = 0xFC;
  913.                         BAsmCode[1] = OpTabBCLR[Index].OpcRM | size;
  914.                         BAsmCode[2] = regs | (regd << 4);
  915.                         CodeLen = DispOut(3, size, disp, 1);
  916.                         return;
  917.                 }
  918.  
  919.                 WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);         
  920.         }
  921.         else if (DecodeReg(&ArgStr[2], &regd, eRn))
  922.         {
  923.                 if (DecodeImm(&ArgStr[1], &imm, &flags))
  924.                 {
  925.                         if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 31))
  926.                         {
  927.                                 WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
  928.                                 return;
  929.                         }
  930.  
  931.                         if (OpTabBCLR[Index].flags & 0x01)
  932.                         {
  933.                                 BAsmCode[0] = 0xFD;
  934.                                 BAsmCode[1] = 0xE0 | imm;
  935.                                 BAsmCode[2] = 0xF0 | regd;
  936.                                 CodeLen = 3;
  937.                         }
  938.                         else
  939.                         {
  940.                                 BAsmCode[0] = OpTabBCLR[Index].OpcIR | (imm >> 4);
  941.                                 BAsmCode[1] = ((imm & 0x0F) << 4) | regd;
  942.                                 CodeLen = 2;
  943.                         }
  944.                         return;
  945.                 }
  946.                 if (DecodeReg(&ArgStr[1], &regs, eRn))
  947.                 {
  948.                         BAsmCode[0] = 0xFC;
  949.                         BAsmCode[1] = OpTabBCLR[Index].OpcRM | 0x03;
  950.                         BAsmCode[2] = regs | (regd << 4);
  951.                         CodeLen = 3;
  952.                         return;
  953.                 }
  954.  
  955.                 WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  956.         }
  957.  
  958.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  959. }
  960.  
  961. static void DecodeBCnd(Word Index)
  962. {
  963.         const char *str = AttrPart.str.p_str;
  964.         const int len = strlen(str);
  965.         Byte attr = 0;
  966.         Byte reg;
  967.         LongInt addr;
  968.         tSymbolFlags flags;
  969.         Boolean ValOK;
  970.         LongInt disp;
  971.  
  972.         if (len > 1)
  973.         {
  974.                 WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart);
  975.                 return;
  976.         }
  977.         if (len == 1)
  978.         {
  979.                 attr = as_toupper(str[0]);
  980.                 switch (attr)
  981.                 {
  982.                 case 'S':
  983.                         break;
  984.                 case 'B':
  985.                         break;
  986.                 case 'W':
  987.                         break;
  988.                 case 'A':
  989.                 case 'L':
  990.                         if (Index != 14)
  991.                         {
  992.                                 WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  993.                                 return;
  994.                         }
  995.                         break;
  996.                 default:
  997.                         WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  998.                         return;
  999.                 }
  1000.         }
  1001.  
  1002.         if (!ChkArgCnt(1,1)) return;
  1003.  
  1004.         if ((attr == 0 || attr == 'L') && DecodeReg(&ArgStr[1], &reg, eRn))
  1005.         {
  1006.                 BAsmCode[0] = 0x7F;
  1007.                 BAsmCode[1] = 0x40 | reg;
  1008.                 CodeLen = 2;
  1009.                 return;
  1010.         }
  1011.  
  1012.         addr = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &flags);
  1013.         if (ValOK)
  1014.         {
  1015.                 if (attr == 'L')
  1016.                 {
  1017.                         WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
  1018.                         return;
  1019.                 }
  1020.  
  1021.                 disp = addr - EProgCounter();
  1022.  
  1023.                 /* Try 3 bit */
  1024.                 if ((attr == 0 || attr == 'S') && disp >= 3 && disp <= 10)
  1025.                 {
  1026.                         if (disp > 7) disp -= 8;
  1027.  
  1028.                         if (Index == 0 || Index == 1)
  1029.                         {
  1030.  
  1031.                                 BAsmCode[0] = 0x10 | (Index << 3) | disp;
  1032.                                 CodeLen = 1;
  1033.                                 return;
  1034.                         }
  1035.  
  1036.                         if (Index == 14)
  1037.                         {
  1038.                                 BAsmCode[0] = 0x08 | disp;
  1039.                                 CodeLen = 1;
  1040.                                 return;
  1041.                         }
  1042.  
  1043.                         WrError(ErrNum_InternalError);
  1044.                 }
  1045.  
  1046.                 if (attr == 'S' && !mFirstPassUnknownOrQuestionable(flags))
  1047.                 {
  1048.                         WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  1049.                         return;
  1050.                 }
  1051.  
  1052.                 /* Try 8 bit */
  1053.                 if ((attr == 0 || attr == 'B') &&
  1054.                         ((disp & 0xFFFFFF80) == 0xFFFFFF80 ||
  1055.                          (disp & 0xFFFFFF80) == 0x00000000))
  1056.                 {
  1057.                         BAsmCode[0] = 0x20 | Index;
  1058.                         BAsmCode[1] = disp & 0xFF;
  1059.                         CodeLen = 2;
  1060.                         return;
  1061.                 }
  1062.  
  1063.                 if (attr == 'B' && !mFirstPassUnknownOrQuestionable(flags))
  1064.                 {
  1065.                         WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  1066.                         return;
  1067.                 }
  1068.  
  1069.                 /* Try 16 bit */
  1070.                 if ((attr == 0 || attr == 'W') &&
  1071.                         ((disp & 0xFFFF8000) == 0xFFFF8000 ||
  1072.                          (disp & 0xFFFF8000) == 0x00000000))
  1073.                 {
  1074.                         if (Index == 0 || Index == 1)
  1075.                         {
  1076.                                 BAsmCode[0] = 0x3A | Index;
  1077.                                 BAsmCode[1] = disp & 0xFF;
  1078.                                 BAsmCode[2] = (disp >> 8) & 0xFF;
  1079.                                 CodeLen = 3;
  1080.                                 return;
  1081.                         }
  1082.  
  1083.                         if (Index == 14)
  1084.                         {
  1085.                                 BAsmCode[0] = 0x38;
  1086.                                 BAsmCode[1] = disp & 0xFF;
  1087.                                 BAsmCode[2] = (disp >> 8) & 0xFF;
  1088.                                 CodeLen = 3;
  1089.                                 return;
  1090.                         }
  1091.  
  1092.                         WrError(ErrNum_JmpDistTooBig);
  1093.                         return;
  1094.                 }
  1095.                
  1096.                 if (attr == 'W' && !mFirstPassUnknownOrQuestionable(flags))
  1097.                 {
  1098.                         WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  1099.                         return;
  1100.                 }
  1101.                
  1102.                 /* Try 24 bit */
  1103.                 if ((disp & 0xFF800000) == 0xFF800000 ||
  1104.                         (disp & 0xFF800000) == 0x00000000)
  1105.                 {
  1106.                         if (Index == 14)
  1107.                         {
  1108.                                 BAsmCode[0] = 0x04;
  1109.                                 BAsmCode[1] = disp & 0xFF;
  1110.                                 BAsmCode[2] = (disp >> 8) & 0xFF;
  1111.                                 BAsmCode[3] = (disp >> 16) & 0xFF;
  1112.                                 CodeLen = 4;
  1113.                                 return;
  1114.                         }
  1115.                 }
  1116.  
  1117.                 WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  1118.         }
  1119. }
  1120.  
  1121. static void DecodeBMCnd(Word Index)
  1122. {
  1123.         Byte regd;
  1124.         Byte size;
  1125.         Byte memex;
  1126.         Byte scale;
  1127.         LongInt imm;
  1128.         LongInt disp;
  1129.         tSymbolFlags flags;
  1130.  
  1131.         if (!ChkNoAttr()) return;
  1132.         if (!ChkArgCnt(2,2)) return;
  1133.  
  1134.         memex = 0;
  1135.         if (DecodeIndirectADD(&ArgStr[2], &regd, &disp, &flags, &memex, &scale))
  1136.         {
  1137.                 if (memex)
  1138.                 {
  1139.                         WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[2]);
  1140.                         return;
  1141.                 }
  1142.                 size = DispSize(disp, flags, 1);
  1143.                 if (size > 0x02){
  1144.                         WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  1145.                         return;
  1146.                 }
  1147.         }
  1148.         else if (DecodeReg(&ArgStr[2], &regd, eRn))
  1149.         {
  1150.                 size = 0x03;
  1151.         }
  1152.         else
  1153.         {
  1154.                 WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  1155.                 return;
  1156.         }
  1157.  
  1158.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  1159.         {
  1160.                 if (size < 0x03)
  1161.                 {
  1162.                         /* #imm,disp[Rd] */
  1163.                         if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 7))
  1164.                         {
  1165.                                 WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
  1166.                                 return;
  1167.                         }
  1168.  
  1169.                         BAsmCode[0] = 0xFC;
  1170.                         BAsmCode[1] = 0xE0 | (imm << 2) | size;
  1171.                         BAsmCode[2] = (regd << 4) | Index;
  1172.                         CodeLen = DispOut(3, size, disp, 1);
  1173.                         return;
  1174.                 }
  1175.                 else
  1176.                 {
  1177.                         /* #imm,Rd */
  1178.                         if (!mSymbolQuestionable(flags) && (imm < 0 || imm > 31))
  1179.                         {
  1180.                                 WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
  1181.                                 return;
  1182.                         }
  1183.                        
  1184.                         BAsmCode[0] = 0xFD;
  1185.                         BAsmCode[1] = 0xE0 | imm;
  1186.                         BAsmCode[2] = (Index << 4) | regd;
  1187.                         CodeLen = 3;
  1188.                         return;
  1189.                 }
  1190.         }
  1191.  
  1192.         WrError(ErrNum_OverRange);
  1193. }
  1194.  
  1195. static void DecodeBRK(Word Index)
  1196. {
  1197.         if (!ChkNoAttr()) return;
  1198.         if (!ChkArgCnt(0,0)) return;
  1199.  
  1200.         BAsmCode[0] = Index;
  1201.         CodeLen = 1;
  1202. }
  1203.  
  1204. static void DecodeBSR(Word Index)
  1205. {
  1206.         const char *str = AttrPart.str.p_str;
  1207.         const int len = strlen(str);
  1208.         Byte attr = 0;
  1209.         Byte reg;
  1210.         LongInt addr;
  1211.         tSymbolFlags flags;
  1212.         Boolean ValOK;
  1213.         LongInt disp;
  1214.  
  1215.   UNUSED(Index);
  1216.  
  1217.         if (len > 1)
  1218.         {
  1219.                 WrStrErrorPos(ErrNum_TooLongAttr, &AttrPart);
  1220.                 return;
  1221.         }
  1222.         if (len == 1)
  1223.         {
  1224.                 attr = as_toupper(str[0]);
  1225.                 switch (attr)
  1226.                 {
  1227.                 case 'W':
  1228.                 case 'A':
  1229.                 case 'L':
  1230.                         break;
  1231.                 default:
  1232.                         WrStrErrorPos(ErrNum_UndefAttr, &AttrPart);
  1233.                         return;
  1234.                 }
  1235.         }
  1236.  
  1237.         if (!ChkArgCnt(1,1)) return;
  1238.  
  1239.         if ((attr == 0 || attr == 'L') && DecodeReg(&ArgStr[1], &reg, eRn))
  1240.         {
  1241.                 BAsmCode[0] = 0x7F;
  1242.                 BAsmCode[1] = 0x50 | reg;
  1243.                 CodeLen = 2;
  1244.                 return;
  1245.         }
  1246.  
  1247.         addr = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &ValOK, &flags);
  1248.         if (ValOK)
  1249.         {
  1250.                 if (attr == 'L')
  1251.                 {
  1252.                         WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
  1253.                         return;
  1254.                 }
  1255.  
  1256.                 disp = addr - EProgCounter();
  1257.  
  1258.                 /* Try 16 bit */
  1259.                 if ((attr == 0 || attr == 'W') &&
  1260.                         ((disp & 0xFFFF8000) == 0xFFFF8000 ||
  1261.                          (disp & 0xFFFF8000) == 0x00000000))
  1262.                 {
  1263.                         BAsmCode[0] = 0x39;
  1264.                         BAsmCode[1] = disp & 0xFF;
  1265.                         BAsmCode[2] = (disp >> 8) & 0xFF;
  1266.                         CodeLen = 3;
  1267.                         return;
  1268.                 }
  1269.  
  1270.                 if (attr == 'W' && !mFirstPassUnknownOrQuestionable(flags))
  1271.                 {
  1272.                         WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  1273.                         return;
  1274.                 }
  1275.                
  1276.                 /* Try 24 bit */
  1277.                 if ((disp & 0xFF800000) == 0xFF800000 ||
  1278.                         (disp & 0xFF800000) == 0x00000000)
  1279.                 {
  1280.                         BAsmCode[0] = 0x05;
  1281.                         BAsmCode[1] = disp & 0xFF;
  1282.                         BAsmCode[2] = (disp >> 8) & 0xFF;
  1283.                         BAsmCode[3] = (disp >> 16) & 0xFF;
  1284.                         CodeLen = 4;
  1285.                         return;
  1286.                 }
  1287.  
  1288.                 WrStrErrorPos(ErrNum_JmpDistTooBig, &ArgStr[1]);
  1289.         }              
  1290. }
  1291.  
  1292. static const char *BitPSW[] = {
  1293.         "C",  "Z",  "S",  "O",  NULL, NULL, NULL, NULL,
  1294.         "I",  "U",  NULL, NULL, NULL, NULL, NULL, NULL };
  1295.  
  1296. static void DecodeCLRPSW(Word Index)
  1297. {
  1298.         int i;
  1299.  
  1300.         if (!ChkNoAttr()) return;
  1301.         if (!ChkArgCnt(1,1)) return;
  1302.  
  1303.         for (i = 0; i < 16; i++)
  1304.         {
  1305.                 if (BitPSW[i] && !as_strcasecmp(ArgStr[1].str.p_str, BitPSW[i])) break;
  1306.         }
  1307.  
  1308.         if (i < 16)
  1309.         {
  1310.                 BAsmCode[0] = 0x7F;
  1311.                 BAsmCode[1] = Index | i;
  1312.                 CodeLen = 2;
  1313.         }
  1314.         else WrStrErrorPos(ErrNum_UnknownFlag, &ArgStr[1]);
  1315. }
  1316.  
  1317. static const struct {
  1318.         Byte OpcI;
  1319.         Byte Opc2;
  1320.         Byte OpcM;
  1321. } OpTabDIV[] = {
  1322.         { 0x80, 0x20, 0x08 },   /* DIV */
  1323.         { 0x90, 0x24, 0x09 },   /* DIVU */
  1324.         { 0x60, 0x18, 0x06 },   /* EMUL */
  1325.         { 0x70, 0x1C, 0x07 },   /* EMULU */
  1326.         { 0x40, 0x10, 0x04 },   /* MAX */
  1327.         { 0x50, 0x14, 0x05 },   /* MIN */
  1328. };
  1329.  
  1330. static void DecodeDIV(Word Index)
  1331. {
  1332.         Byte regs;
  1333.         Byte regd;
  1334.         Byte size;
  1335.         LongInt imm;
  1336.         tSymbolFlags flags;
  1337.         LongInt disp;
  1338.         Byte memex;
  1339.         Byte scale;
  1340.  
  1341.         if (!ChkNoAttr()) return;
  1342.         if (!ChkArgCnt(2,2)) return;
  1343.  
  1344.         if (!DecodeReg(&ArgStr[2], &regd, eRn))
  1345.         {
  1346.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  1347.                 return;
  1348.         }
  1349.  
  1350.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  1351.         {
  1352.                 size = ImmSize32(imm, flags);
  1353.  
  1354.                 BAsmCode[0] = 0xFD;
  1355.                 BAsmCode[1] = 0x70 | (size << 2);
  1356.                 BAsmCode[2] = OpTabDIV[Index].OpcI | regd;
  1357.                 CodeLen = ImmOut(3, size, imm);
  1358.                 return;
  1359.         }
  1360.  
  1361.         if (DecodeReg(&ArgStr[1], &regs, eRn))
  1362.         {
  1363.                 BAsmCode[0] = 0xFC;
  1364.                 BAsmCode[1] = OpTabDIV[Index].Opc2 | 0x03;
  1365.                 BAsmCode[2] = (regs << 4) | regd;
  1366.                 CodeLen = 3;
  1367.                 return;
  1368.         }
  1369.  
  1370.         if (DecodeIndirectADD(&ArgStr[1], &regs, &disp, &flags, &memex, &scale))
  1371.         {
  1372.                 if (memex == 0x80)
  1373.                 {
  1374.                         size = DispSize(disp, flags, 1);
  1375.  
  1376.                         BAsmCode[0] = 0xFC;
  1377.                         BAsmCode[1] = OpTabDIV[Index].Opc2 | size;
  1378.                         BAsmCode[2] = (regs << 4) | regd;
  1379.                         CodeLen = DispOut(3, size, disp, 1);
  1380.                         return;
  1381.                 }
  1382.  
  1383.                 size = DispSize(disp, flags, scale);
  1384.  
  1385.                 BAsmCode[0] = 0x06;
  1386.                 BAsmCode[1] = 0x20 | (memex << 6) | size;
  1387.                 BAsmCode[2] = OpTabDIV[Index].OpcM;
  1388.                 BAsmCode[3] = (regs << 4) | regd;
  1389.                 CodeLen = DispOut(4, size, disp, scale);
  1390.                 return;
  1391.         }
  1392.  
  1393.         WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
  1394. }
  1395.  
  1396. static const struct {
  1397.         Byte OpcI;
  1398.         Byte OpcM;
  1399.         Byte Opc3;
  1400.         Byte flags;
  1401. } OpTabFADD[] = {
  1402.         { 0x20, 0x88, 0xA0, 0x03 },     /* FADD */
  1403.         { 0x10, 0x84, 0,    0x01 },     /* FCMP */
  1404.         { 0x40, 0x90, 0,    0x01 },     /* FDIV */
  1405.         { 0x30, 0x8C, 0xB0, 0x03 },     /* FMUL */
  1406.         { 0x00, 0x80, 0x80, 0x03 },     /* FSUB */
  1407.         { 0,    0x94, 0,    0x00 },     /* FTOI */
  1408.         { 0,    0x98, 0,    0x00 },     /* ROUND */
  1409.         { 0,    0xA0, 0,    0x10 },     /* FSQRT */
  1410.         { 0,    0xA4, 0,    0x10 },     /* FTOU */
  1411. };
  1412.  
  1413. static void DecodeFADD(Word Index)
  1414. {
  1415.         Byte regs;
  1416.         Byte regd;
  1417.         Byte size;
  1418.         LongInt imm;
  1419.         LongInt disp;
  1420.         tSymbolFlags flags;
  1421.  
  1422.         if (!ChkNoAttr()) return;
  1423.         if (!CheckFloat()) return;
  1424.  
  1425.         if ((OpTabFADD[Index].flags & 0x02) && ArgCnt == 3)
  1426.         {
  1427.                 Byte regs2;
  1428.  
  1429.                 if (!DecodeReg(&ArgStr[1], &regs, eRn))
  1430.                 {
  1431.                         WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
  1432.                         return;
  1433.                 }
  1434.                 if (!DecodeReg(&ArgStr[2], &regs2, eRn))
  1435.                 {
  1436.                         WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
  1437.                         return;
  1438.                 }
  1439.                 if (!DecodeReg(&ArgStr[3], &regd, eRn))
  1440.                 {
  1441.                         WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[3]);
  1442.                         return;
  1443.                 }
  1444.  
  1445.                 BAsmCode[0] = 0xFF;
  1446.                 BAsmCode[1] = OpTabFADD[Index].Opc3 | regd;
  1447.                 BAsmCode[2] = (regs << 4) | regs2;
  1448.                 CodeLen = 3;
  1449.                 return;
  1450.         }
  1451.  
  1452.         if (!ChkArgCnt(2,2)) return;
  1453.  
  1454.         if (OpTabFADD[Index].flags & 0x10)
  1455.         {
  1456.                 if (!CheckV2()) return;
  1457.         }
  1458.  
  1459.         if (!DecodeReg(&ArgStr[2], &regd, eRn))
  1460.         {
  1461.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  1462.                 return;
  1463.         }
  1464.  
  1465.         if ((OpTabFADD[Index].flags & 0x01) &&
  1466.                 DecodeFloat(&ArgStr[1], &imm))
  1467.         {
  1468.                 BAsmCode[0] = 0xFD;
  1469.                 BAsmCode[1] = 0x72;
  1470.                 BAsmCode[2] = OpTabFADD[Index].OpcI | regd;
  1471.                 CodeLen = ImmOut(3, 0, imm);    /* size==0 means 4 byte */
  1472.                 return;
  1473.         }
  1474.  
  1475.         if (DecodeReg(&ArgStr[1], &regs, eRn))
  1476.         {
  1477.                 size = 0x03;
  1478.                 disp = 0;
  1479.         }
  1480.         else if (DecodeIndirectL(&ArgStr[1], &regs, &disp, &flags))
  1481.         {
  1482.                 if (mFirstPassUnknown(flags)) size = 0x02;
  1483.                 else size = DispSize(disp, flags, 4);
  1484.         }
  1485.         else
  1486.         {
  1487.                 WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
  1488.                 return;
  1489.         }
  1490.  
  1491.         BAsmCode[0] = 0xFC;
  1492.         BAsmCode[1] = OpTabFADD[Index].OpcM | size;
  1493.         BAsmCode[2] = (regs << 4) | regd;
  1494.         CodeLen = DispOut(3, size, disp, 4);
  1495. }
  1496.  
  1497. static void DecodeINT(Word Index)
  1498. {
  1499.         LongInt imm;
  1500.         tSymbolFlags flags;
  1501.  
  1502.         UNUSED(Index);
  1503.  
  1504.         if (!ChkNoAttr()) return;
  1505.         if (!ChkArgCnt(1,1)) return;
  1506.  
  1507.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  1508.         {
  1509.                 if (!mFirstPassUnknown(flags) && (imm < -128 || imm > 255))
  1510.                 {
  1511.                         WrStrErrorPos(ErrNum_ArgOutOfRange, &ArgStr[1]);
  1512.                         return;
  1513.                 }
  1514.  
  1515.                 BAsmCode[0] = 0x75;
  1516.                 BAsmCode[1] = 0x60;
  1517.                 BAsmCode[2] = imm & 0xFF;
  1518.                 CodeLen = 3;
  1519.                 return;
  1520.         }
  1521.  
  1522.         WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
  1523. }
  1524.  
  1525. static const struct {
  1526.         Byte Opc1;
  1527.         Byte Opc2;
  1528.         Byte flags;
  1529. } OpTabITOF[] = {
  1530.         { 0x44, 0x11, 0x00 },   /* ITOF */
  1531.         { 0x54, 0x15, 0x10 },   /* UTOF */
  1532. };
  1533.  
  1534. static void DecodeITOF(Word Index)
  1535. {
  1536.         Byte regs;
  1537.         Byte regd;
  1538.         Byte size;
  1539.         Byte memex;
  1540.         Byte scale;
  1541.         LongInt disp;
  1542.         tSymbolFlags flags;
  1543.  
  1544.         if (!ChkNoAttr()) return;
  1545.         if (!ChkArgCnt(2,2)) return;
  1546.         if (!CheckFloat()) return;
  1547.  
  1548.         if ((OpTabITOF[Index].flags & 0x10) && !CheckV2()) return;
  1549.  
  1550.         if (!DecodeReg(&ArgStr[2], &regd, eRn))
  1551.         {
  1552.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  1553.                 return;
  1554.         }
  1555.  
  1556.         if (DecodeReg(&ArgStr[1], &regs, eRn))
  1557.         {
  1558.                 size = 0x03;
  1559.                 disp = 0;
  1560.                 memex = 0;
  1561.         }
  1562.         else if (DecodeIndirectADD(&ArgStr[1], &regs, &disp, &flags, &memex, &scale))
  1563.         {
  1564.                 if (mFirstPassUnknown(flags)) size = 0x02;
  1565.                 else size = DispSize(disp, flags, scale);
  1566.         }
  1567.         else
  1568.         {
  1569.                 WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
  1570.                 return;
  1571.         }
  1572.  
  1573.         if (memex == 0x80 || size == 0x03)
  1574.         {
  1575.                 BAsmCode[0] = 0xFC;
  1576.                 BAsmCode[1] = OpTabITOF[Index].Opc1 | size;
  1577.                 BAsmCode[2] = (regs << 4) | regd;
  1578.                 if (size < 0x03) CodeLen = DispOut(3, size, disp, scale);
  1579.                 else CodeLen = 3;
  1580.                 return;
  1581.         }
  1582.  
  1583.         BAsmCode[0] = 0x06;
  1584.         BAsmCode[1] = 0x20 | (memex << 6) | size;
  1585.         BAsmCode[2] = OpTabITOF[Index].Opc2;
  1586.         BAsmCode[3] = (regs << 4) | regd;
  1587.         CodeLen = DispOut(4, size, disp, scale);
  1588. }
  1589.  
  1590. static const struct {
  1591.         Byte Opc1;
  1592.         Byte Opc2;
  1593. } OpTabJMP[] = {
  1594.         { 0x7F, 0x00 }, /* JMP */
  1595.         { 0x7F, 0x10 }, /* JSR */
  1596.         { 0x7E, 0xB0 }, /* POP */
  1597.         { 0x7E, 0x50 }, /* ROLC */
  1598.         { 0x7E, 0x40 }, /* RORC */
  1599.         { 0x7E, 0x30 }, /* SAT */
  1600. };
  1601.  
  1602. static void DecodeJMP(Word Index)
  1603. {
  1604.         Byte reg;
  1605.  
  1606.         if (!ChkNoAttr()) return;
  1607.         if (!ChkArgCnt(1,1)) return;
  1608.  
  1609.         if (DecodeReg(&ArgStr[1], &reg, eRn))
  1610.         {
  1611.                 BAsmCode[0] = OpTabJMP[Index].Opc1;
  1612.                 BAsmCode[1] = OpTabJMP[Index].Opc2 | reg;
  1613.                 CodeLen = 2;
  1614.                 return;
  1615.         }
  1616.        
  1617.         WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
  1618. }
  1619.  
  1620. static const struct {
  1621.         Byte Opc;
  1622.         Byte flags;
  1623. } OpTabMACHI[] = {
  1624.         { 0x04, 0x01 }, /* MACHI */
  1625.         { 0x05, 0x01 }, /* MACLO */
  1626.         { 0x00, 0x01 }, /* MULHI */
  1627.         { 0x01, 0x01 }, /* MULLO */
  1628.         { 0x67, 0x00 }, /* REVL */
  1629.        
  1630.         { 0x65, 0x00 }, /* REVW */
  1631.         { 0x07, 0x11 }, /* EMACA */
  1632.         { 0x47, 0x11 }, /* EMSBA */
  1633.         { 0x03, 0x11 }, /* EMULA */
  1634.         { 0x06, 0x11 }, /* MACLH */
  1635.  
  1636.         { 0x44, 0x11 }, /* MSBHI */
  1637.         { 0x46, 0x11 }, /* MSBLH */
  1638.         { 0x45, 0x11 }, /* MSBLO */
  1639.         { 0x02, 0x11 }, /* MULLH */
  1640. };
  1641.  
  1642. static void DecodeMACHI(Word Index)
  1643. {
  1644.         Byte reg1;
  1645.         Byte reg2;
  1646.         Byte acc = 0;
  1647.  
  1648.         if ((OpTabMACHI[Index].flags & 0x10) && !CheckV2()) return;
  1649.         if (!ChkNoAttr()) return;
  1650.         if (pCurrCPUProps->InstSet == eRXv1)
  1651.         {
  1652.                 if (!ChkArgCnt(2,2)) return;
  1653.         }
  1654.         else
  1655.         {
  1656.                 if (OpTabMACHI[Index].flags & 0x01)
  1657.                 {
  1658.                         if (!ChkArgCnt(3,3)) return;
  1659.                         if (!DecodeAcc(&ArgStr[3], &acc))
  1660.                         {
  1661.                                 WrStrErrorPos(ErrNum_InvArg, &ArgStr[3]);
  1662.                                 return;
  1663.                         }
  1664.                 }
  1665.                 else
  1666.                 {
  1667.                         if (!ChkArgCnt(2,2)) return;
  1668.                 }
  1669.         }
  1670.  
  1671.         if (!DecodeReg(&ArgStr[1], &reg1, eRn))
  1672.         {
  1673.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[1]);
  1674.                 return;
  1675.         }
  1676.  
  1677.         if (!DecodeReg(&ArgStr[2], &reg2, eRn))
  1678.         {
  1679.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  1680.                 return;
  1681.         }
  1682.  
  1683.         BAsmCode[0] = 0xFD;
  1684.         BAsmCode[1] = OpTabMACHI[Index].Opc | (acc << 3);
  1685.         BAsmCode[2] = (reg1 << 4) | reg2;
  1686.         CodeLen = 3;
  1687. }
  1688.  
  1689. static void DecodeMOV(Word Index)
  1690. {
  1691.         tSymbolSize size;
  1692.         Byte regs;
  1693.         Byte regd;
  1694.         LongInt imm;
  1695.         LongInt disp;
  1696.         tSymbolFlags flags;
  1697.         tSymbolFlags flags2;
  1698.         Byte disp2;
  1699.         Byte isize;
  1700.         Byte dsize;
  1701.         Byte scale;
  1702.         Byte regi;
  1703.  
  1704.         UNUSED(Index);
  1705.  
  1706.         size = DecodeAttrSize();
  1707.         if (size == eSymbolSizeUnknown) return;
  1708.         scale = Size2Scale(size);
  1709.        
  1710.         if (DecodeReg(&ArgStr[1], &regs, eRn) && regs < 8 &&
  1711.                 DecodeRelative(&ArgStr[2], &regd, &disp, &flags))
  1712.         {       /* (1) */
  1713.                 if (ChkDisp5(size, disp, flags))
  1714.                 {
  1715.                         disp2 = DispSize5(size, disp);
  1716.                        
  1717.                         BAsmCode[0] = 0x80 | (size << 4) | ((disp2 >> 2) & 0x07);
  1718.                         BAsmCode[1] = ((disp2 << 6) & 0x80) | (regd << 4) | ((disp2 << 3) & 0x08) | regs;
  1719.                         CodeLen = 2;
  1720.                         return;
  1721.                 }
  1722.         }
  1723.  
  1724.         if (DecodeRelative(&ArgStr[1], &regs, &disp, &flags) &&
  1725.                 DecodeReg(&ArgStr[2], &regd, eRn) && regd < 8)
  1726.         {       /* (2) */
  1727.                 if (ChkDisp5(size, disp, flags))
  1728.                 {
  1729.                         disp2 = DispSize5(size, disp);
  1730.                        
  1731.                         BAsmCode[0] = 0x88 | (size << 4) | ((disp2 >> 2) & 0x07);
  1732.                         BAsmCode[1] = ((disp2 << 6) & 0x80) | (regs << 4) | ((disp2 << 3) & 0x08) | regd;
  1733.                         CodeLen = 2;
  1734.                         return;
  1735.                 }
  1736.         }
  1737.  
  1738.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  1739.         {
  1740.                 if (size == 0x02 && DecodeReg(&ArgStr[2], &regd, eRn) &&
  1741.                         !mFirstPassUnknown(flags) && imm >= 0 && imm < 16)
  1742.                 {       /* (3) */
  1743.                         BAsmCode[0] = 0x66;
  1744.                         BAsmCode[1] = (imm << 4) | regd;
  1745.                         CodeLen = 2;
  1746.                         return;
  1747.                 }
  1748.  
  1749.                 if (DecodeRelative(&ArgStr[2], &regd, &disp, &flags))
  1750.                 {       /* (4) */
  1751.                         if ((size == 0x00 && imm >= -128 && imm < 256) ||
  1752.                                 (size != 0x00 && imm >= 0 && imm < 256))
  1753.                         {
  1754.                                 disp2 = DispSize5(size, disp);
  1755.  
  1756.                                 BAsmCode[0] = 0x3C | size;
  1757.                                 BAsmCode[1] = ((disp2 << 3) & 0x80) | (regd << 4) | (disp2 & 0x0F);
  1758.                                 BAsmCode[2] = imm;
  1759.                                 CodeLen = 3;
  1760.                                 return;
  1761.                         }
  1762.                 }
  1763.  
  1764.                 if (DecodeReg(&ArgStr[2], &regd, eRn))
  1765.                 {
  1766.                         if (size == 0x02 && !mFirstPassUnknown(flags) &&
  1767.                                 imm >= 0 && imm < 256)
  1768.                         {       /* (5) */
  1769.                                 BAsmCode[0] = 0x75;
  1770.                                 BAsmCode[1] = 0x40 | regd;
  1771.                                 BAsmCode[2] = imm;
  1772.                                 CodeLen = 3;
  1773.                                 return;
  1774.                         }
  1775.  
  1776.                         /* (6) */
  1777.                         isize = ImmSize32(imm, flags);
  1778.  
  1779.                         BAsmCode[0] = 0xFB;
  1780.                         BAsmCode[1] = (regd << 4) | (isize << 2) | 0x02;
  1781.  
  1782.                         CodeLen = ImmOut(2, isize, imm);
  1783.                         return;
  1784.                 }
  1785.  
  1786.                 if (DecodeIndirectADC(&ArgStr[2], &regd, &disp, &flags2))
  1787.                 {       /* (8) */
  1788.                         switch (size)
  1789.                         {
  1790.                                 case 0x00:      /* B */
  1791.                                         if (imm < -128 || imm > 255)
  1792.                                         {
  1793.                                                 WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
  1794.                                                 return;
  1795.                                         }
  1796.                                         isize = 0x01;
  1797.                                         break;
  1798.                                 case 0x01:      /* W */
  1799.                                         if (imm < -32768 || imm > 65535)
  1800.                                         {
  1801.                                                 WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
  1802.                                                 return;
  1803.                                         }
  1804.                                         isize = ImmSize16(imm, flags);
  1805.                                         break;
  1806.                                 case 0x02:      /* L */
  1807.                                         isize = ImmSize32(imm, flags);
  1808.                                         break;
  1809.                                 default:
  1810.                                         WrError(ErrNum_InternalError);
  1811.                                         return;
  1812.                         }
  1813.  
  1814.                         dsize = DispSize(disp, flags2, scale);
  1815.  
  1816.                         BAsmCode[0] = 0xF8 | dsize;
  1817.                         BAsmCode[1] = (regd << 4) | (isize << 2) | size;
  1818.                         CodeLen = DispOut(2, dsize, disp, scale);
  1819.                         CodeLen = ImmOut(CodeLen, isize, imm);
  1820.                         return;
  1821.                 }
  1822.  
  1823.                 WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);                 
  1824.         }
  1825.  
  1826.         if (DecodeReg(&ArgStr[1], &regs, eRn))
  1827.         {
  1828.                 if (DecodeReg(&ArgStr[2], &regd, eRn))
  1829.                 {       /* (7) */
  1830.                         BAsmCode[0] = 0xCF | (size << 4);
  1831.                         BAsmCode[1] = (regs << 4) | regd;
  1832.                         CodeLen = 2;
  1833.                         return;
  1834.                 }
  1835.  
  1836.                 if (DecodeIndirectADC(&ArgStr[2], &regd, &disp, &flags))
  1837.                 {       /* (11) */
  1838.                         dsize = DispSize(disp, flags, scale);
  1839.  
  1840.                         BAsmCode[0] = 0xC3 | (size << 4) | (dsize << 2);
  1841.                         BAsmCode[1] = (regd << 4) | regs;
  1842.                         CodeLen = DispOut(2, dsize, disp, scale);
  1843.                         return;
  1844.                 }
  1845.  
  1846.                 if (DecodeIndexed(&ArgStr[2], &regi, &regd))
  1847.                 {       /* (12) */
  1848.                         BAsmCode[0] = 0xFE;
  1849.                         BAsmCode[1] = (size << 4) | regi;
  1850.                         BAsmCode[2] = (regd << 4) | regs;
  1851.                         CodeLen = 3;
  1852.                         return;
  1853.                 }
  1854.  
  1855.                 if (DecodeIncDec(&ArgStr[2], &regd, &regi))
  1856.                 {       /* (14) */
  1857.                         BAsmCode[0] = 0xFD;
  1858.                         BAsmCode[1] = 0x20 | (regi << 2) | size;
  1859.                         BAsmCode[2] = (regd << 4) | regs;
  1860.                         CodeLen = 3;
  1861.                         return;
  1862.                 }
  1863.         }
  1864.  
  1865.         if (DecodeIndirectADC(&ArgStr[1], &regs, &disp, &flags))
  1866.         {
  1867.                 if (DecodeReg(&ArgStr[2], &regd, eRn))
  1868.                 {       /* (9) */
  1869.                         dsize = DispSize(disp, flags, scale);
  1870.  
  1871.                         BAsmCode[0] = 0xCC | (size << 4) | dsize;
  1872.                         BAsmCode[1] = (regs << 4) | regd;
  1873.                         CodeLen = DispOut(2, dsize, disp, scale);
  1874.                         return;
  1875.                 }
  1876.  
  1877.                 if (DecodeIndirectADC(&ArgStr[2], &regd, &imm, &flags2))
  1878.                 {       /* (13) */
  1879.                         dsize = DispSize(disp, flags, scale);   /* src */
  1880.                         isize = DispSize(imm, flags2, scale);   /* dst */
  1881.  
  1882.                         BAsmCode[0] = 0xC0 | (size << 4) | (isize << 2) | dsize;
  1883.                         BAsmCode[1] = (regs << 4) | regd;
  1884.                         CodeLen = DispOut(2, dsize, disp, scale);
  1885.                         CodeLen = DispOut(CodeLen, isize, imm, scale);
  1886.                         return;
  1887.                 }
  1888.         }
  1889.  
  1890.         if (DecodeIndexed(&ArgStr[1], &regi, &regs) &&
  1891.                 DecodeReg(&ArgStr[2], &regd, eRn))
  1892.         {       /* (10) */
  1893.                 BAsmCode[0] = 0xFE;
  1894.                 BAsmCode[1] = 0x40 | (size << 4) | regi;
  1895.                 BAsmCode[2] = (regs << 4) | regd;
  1896.                 CodeLen = 3;
  1897.                 return;
  1898.         }
  1899.  
  1900.         if (DecodeIncDec(&ArgStr[1], &regs, &regi) &&
  1901.                 DecodeReg(&ArgStr[2], &regd, eRn))
  1902.         {
  1903.                 BAsmCode[0] = 0xFD;
  1904.                 BAsmCode[1] = 0x28 | (regi << 2) | size;
  1905.                 BAsmCode[2] = (regs << 4) | regd;
  1906.                 CodeLen = 3;
  1907.                 return;
  1908.         }
  1909.  
  1910.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]); 
  1911. }
  1912.  
  1913. static void DecodeMOVU(Word Index)
  1914. {
  1915.         tSymbolSize size;
  1916.         Byte regs;
  1917.         Byte regd;
  1918.         Byte scale;
  1919.         LongInt disp;
  1920.         tSymbolFlags flags;
  1921.         Byte disp2;
  1922.         Byte dsize;
  1923.         Byte regi;
  1924.  
  1925.         UNUSED(Index);
  1926.  
  1927.         size = DecodeAttrSize();
  1928.         if (size == eSymbolSizeUnknown || size == eSymbolSize32Bit) return;
  1929.         scale = Size2Scale(size);
  1930.  
  1931.         if (DecodeReg(&ArgStr[2], &regd, eRn))
  1932.         {
  1933.                 if (DecodeRelative(&ArgStr[1], &regs, &disp, &flags) &&
  1934.                         ChkDisp5(size, disp, flags) && regd < 8)
  1935.                 {       /* (1) */
  1936.                         disp2 = DispSize5(size, disp);
  1937.  
  1938.                         BAsmCode[0] = 0xB0 | (size << 3) | ((disp2 >> 2) & 0x07);
  1939.                         BAsmCode[1] = ((disp2 << 6) & 0x80) | (regs << 4) | ((disp2 << 3) & 0x08) | regd;
  1940.                         CodeLen = 2;
  1941.                         return;
  1942.                 }
  1943.  
  1944.                 if (DecodeReg(&ArgStr[1], &regs, eRn))
  1945.                 {       /* (2)-1 */
  1946.                         BAsmCode[0] = 0x5B | (size << 2);
  1947.                         BAsmCode[1] = (regs << 4) | regd;
  1948.                         CodeLen = 2;
  1949.                         return;
  1950.                 }
  1951.  
  1952.                 if (DecodeIndirectADC(&ArgStr[1], &regs, &disp, &flags))
  1953.                 {       /* (2)-2 */
  1954.                         dsize = DispSize(disp, flags, scale);
  1955.  
  1956.                         BAsmCode[0] = 0x58 | (size << 2) | dsize;
  1957.                         BAsmCode[1] = (regs << 4) | regd;
  1958.                         CodeLen = DispOut(2, dsize, disp, scale);
  1959.                         return;
  1960.                 }
  1961.  
  1962.                 if (DecodeIndexed(&ArgStr[1], &regi, &regs))
  1963.                 {       /* (3) */
  1964.                         BAsmCode[0] = 0xFE;
  1965.                         BAsmCode[1] = 0xC0 | (size << 4) | regi;
  1966.                         BAsmCode[2] = (regs << 4) | regd;
  1967.                         CodeLen = 3;
  1968.                         return;
  1969.                 }
  1970.  
  1971.                 if (DecodeIncDec(&ArgStr[1], &regs, &regi))
  1972.                 {       /* (4) */
  1973.                         BAsmCode[0] = 0xFD;
  1974.                         BAsmCode[1] = 0x38 | (regi << 2) | size;
  1975.                         BAsmCode[2] = (regs << 4) | regd;
  1976.                         CodeLen = 3;
  1977.                         return;
  1978.                 }
  1979.         }
  1980.  
  1981.         WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
  1982. }
  1983.  
  1984. static const struct {
  1985.         Byte Opc2;
  1986.         Byte Opc3;
  1987.         Byte flags;
  1988. } OpTabMVFACHI[] = {
  1989.         { 0x1E, 0x00, 0x00 },   /* MVFACHI */
  1990.         { 0x1E, 0x20, 0x00 },   /* MVFACMI */
  1991.         { 0x1E, 0x30, 0x10 },   /* MVFACGU */
  1992.         { 0x1E, 0x10, 0x10 },   /* MVFACLO */
  1993. };
  1994.  
  1995. static void DecodeMVFACHI(Word Index)
  1996. {
  1997.         LongInt imm;
  1998.         tSymbolFlags flags;
  1999.         Byte acc;
  2000.         Byte reg;
  2001.        
  2002.         if ((OpTabMVFACHI[Index].flags & 0x10) && !CheckV2()) return;
  2003.         if (!ChkNoAttr()) return;
  2004.  
  2005.         if (pCurrCPUProps->InstSet == eRXv1)
  2006.         {
  2007.                 if (!ChkArgCnt(1,1)) return;
  2008.                 imm = 0x02;
  2009.                 acc = 0x00;
  2010.         }
  2011.         else
  2012.         {
  2013.                 if (!ChkArgCnt(3,3)) return;
  2014.                 if (!DecodeImm(&ArgStr[1], &imm, &flags))
  2015.                 {
  2016.                         WrStrErrorPos(ErrNum_OnlyImmAddr, &ArgStr[1]); 
  2017.                         return;
  2018.                 }
  2019.                 switch (imm)
  2020.                 {
  2021.                 case 0:
  2022.                         imm = 0x02;
  2023.                         break;
  2024.                 case 1:
  2025.                         imm = 0x03;
  2026.                         break;
  2027.                 case 2:
  2028.                         imm = 0x00;
  2029.                         break;
  2030.                 default:
  2031.                         if (mSymbolQuestionable(flags)) break;
  2032.                         WrStrErrorPos(ErrNum_ArgOutOfRange, &ArgStr[1]);
  2033.                         return;
  2034.                 }
  2035.  
  2036.                 if (!DecodeAcc(&ArgStr[2], &acc))
  2037.                 {
  2038.                         WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
  2039.                         return;
  2040.                 }
  2041.         }
  2042.        
  2043.         if (!DecodeReg(&ArgStr[ArgCnt], &reg, eRn))
  2044.         {
  2045.                 WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[ArgCnt]);   
  2046.                 return;
  2047.         }
  2048.  
  2049.         BAsmCode[0] = 0xFD;
  2050.         BAsmCode[1] = OpTabMVFACHI[Index].Opc2 | ((imm >> 1) & 0x01);
  2051.         BAsmCode[2] = OpTabMVFACHI[Index].Opc3 | (acc << 7) | ((imm << 6) & 0x40) | reg;
  2052.         CodeLen = 3;
  2053. }
  2054.  
  2055. static const char *SPReg[] = {
  2056.         "PSW",   "PC",    "USP",   "FPSW",   NULL,    NULL,    NULL,    NULL,
  2057.         "BPSW",  "BPC",   "ISP",   "FINTV",  "INTB",  "EXTB",  NULL,    NULL,
  2058. };
  2059.  
  2060. static void DecodeMVFC(Word Index)
  2061. {
  2062.         Byte reg;
  2063.         size_t i;
  2064.  
  2065.         UNUSED(Index);
  2066.  
  2067.         if (!ChkNoAttr()) return;
  2068.         if (!ChkArgCnt(2,2)) return;
  2069.  
  2070.         if (DecodeReg(&ArgStr[2], &reg, eRn))
  2071.         {
  2072.                 for (i = 0; i < as_array_size(SPReg); i++)
  2073.                 {
  2074.                         if (i == 13 && pCurrCPUProps->InstSet == eRXv1)
  2075.                         {
  2076.                                 WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
  2077.                         }
  2078.  
  2079.                         if (SPReg[i] && !as_strcasecmp(SPReg[i], ArgStr[1].str.p_str))
  2080.                         {
  2081.                                 BAsmCode[0] = 0xFD;
  2082.                                 BAsmCode[1] = 0x6A;
  2083.                                 BAsmCode[2] = (i << 4) | reg;
  2084.                                 CodeLen = 3;
  2085.                                 return;
  2086.                         }
  2087.                 }
  2088.                
  2089.                 WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
  2090.         }
  2091.  
  2092.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);                 
  2093. }
  2094.  
  2095. static const struct {
  2096.         Byte Opc2;
  2097.         Byte Opc3;
  2098.         Byte flags;
  2099. } OpTabMVTACHI[] = {
  2100.         { 0x17, 0x00, 0x00 },   /* MVTACHI */
  2101.         { 0x17, 0x10, 0x00 },   /* MVTACLO */
  2102.         { 0x17, 0x30, 0x10 },   /* MVTACGU */
  2103. };
  2104.  
  2105. static void DecodeMVTACHI(Word Index)
  2106. {
  2107.         Byte acc;
  2108.         Byte reg;
  2109.        
  2110.         if ((OpTabMVTACHI[Index].flags & 0x10) && !CheckV2()) return;
  2111.         if (!ChkNoAttr()) return;
  2112.  
  2113.         if (pCurrCPUProps->InstSet == eRXv1)
  2114.         {
  2115.                 if (!ChkArgCnt(1,1)) return;
  2116.                 acc = 0x00;
  2117.         }
  2118.         else
  2119.         {
  2120.                 if (!ChkArgCnt(2,2)) return;
  2121.  
  2122.                 if (!DecodeAcc(&ArgStr[2], &acc))
  2123.                 {
  2124.                         WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
  2125.                         return;
  2126.                 }
  2127.         }
  2128.        
  2129.         if (!DecodeReg(&ArgStr[1], &reg, eRn))
  2130.         {
  2131.                 WrStrErrorPos(ErrNum_AddrModeNotSupported, &ArgStr[1]);
  2132.                 return;
  2133.         }
  2134.  
  2135.         BAsmCode[0] = 0xFD;
  2136.         BAsmCode[1] = OpTabMVTACHI[Index].Opc2;
  2137.         BAsmCode[2] = OpTabMVTACHI[Index].Opc3 | (acc << 7) | reg;
  2138.         CodeLen = 3;
  2139. }
  2140.  
  2141. static void DecodeMVTC(Word Index)
  2142. {
  2143.         Byte reg;
  2144.         LongInt imm;
  2145.         Byte size;
  2146.         tSymbolFlags flags;
  2147.         size_t i;
  2148.  
  2149.         UNUSED(Index);
  2150.  
  2151.         if (!ChkNoAttr()) return;
  2152.         if (!ChkArgCnt(2,2)) return;
  2153.  
  2154.         for (i = 0; i < as_array_size(SPReg); i++)
  2155.         {
  2156.                 if (SPReg[i] && !as_strcasecmp(SPReg[i], ArgStr[2].str.p_str))
  2157.                 {
  2158.                         if (i == 1)
  2159.                         {
  2160.                                 WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
  2161.                                 return;
  2162.                         }
  2163.  
  2164.                         if (i == 13 && pCurrCPUProps->InstSet == eRXv1)
  2165.                         {
  2166.                                 WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
  2167.                         }
  2168.  
  2169.                         if (DecodeImm(&ArgStr[1], &imm, &flags))
  2170.                         {
  2171.                                 size = ImmSize32(imm, flags);
  2172.  
  2173.                                 BAsmCode[0] = 0xFD;
  2174.                                 BAsmCode[1] = 0x73 | (size << 2);
  2175.                                 BAsmCode[2] = i;
  2176.                                 CodeLen = ImmOut(3, size, imm);
  2177.                                 return;
  2178.                         }
  2179.  
  2180.                         if (DecodeReg(&ArgStr[1], &reg, eRn))
  2181.                         {
  2182.                                 BAsmCode[0] = 0xFD;
  2183.                                 BAsmCode[1] = 0x68;
  2184.                                 BAsmCode[2] = (reg << 4) | i;
  2185.                                 CodeLen = 3;
  2186.                                 return;
  2187.                         }
  2188.                
  2189.                         WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
  2190.                 }
  2191.         }
  2192.  
  2193.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);                 
  2194. }
  2195.  
  2196. static void DecodeMVTIPL(Word Index)
  2197. {
  2198.         LongInt imm;
  2199.         tSymbolFlags flags;
  2200.  
  2201.         UNUSED(Index);
  2202.  
  2203.         if (!CheckSup()) return;
  2204.         if (!ChkNoAttr()) return;
  2205.         if (!ChkArgCnt(1,1)) return;
  2206.  
  2207.         if (!pCurrCPUProps->hasMVTIPL)
  2208.         {
  2209.                 WrError(ErrNum_InstructionNotSupported);
  2210.                 return;
  2211.         }
  2212.  
  2213.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  2214.         {
  2215.                 if (!mFirstPassUnknown(flags) && (imm < 0 || imm > 15))
  2216.                 {
  2217.                         WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
  2218.                         return;
  2219.                 }
  2220.  
  2221.                 BAsmCode[0] = 0x75;
  2222.                 BAsmCode[1] = 0x70;
  2223.                 BAsmCode[2] = imm;
  2224.                 CodeLen = 3;
  2225.                 return;
  2226.         }
  2227.  
  2228.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);                 
  2229. }
  2230.  
  2231. static const Byte OpTabPOPC[] = {
  2232.         0xE0,   /* POPC */
  2233.         0xC0,   /* PUSHC */
  2234. };
  2235.  
  2236. static void DecodePOPC(Word Index)
  2237. {
  2238.         size_t i;
  2239.  
  2240.         UNUSED(Index);
  2241.  
  2242.         if (!ChkNoAttr()) return;
  2243.         if (!ChkArgCnt(1,1)) return;
  2244.  
  2245.         for (i = 0; i < as_array_size(SPReg); i++)
  2246.         {
  2247.                 if (SPReg[i] && !as_strcasecmp(SPReg[i], ArgStr[1].str.p_str))
  2248.                 {
  2249.                         if (Index == 0 && i == 1)
  2250.                         {
  2251.                                 WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
  2252.                                 return;
  2253.                         }
  2254.  
  2255.                         if (i == 13 && pCurrCPUProps->InstSet == eRXv1)
  2256.                         {
  2257.                                 WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[2]);
  2258.                         }
  2259.  
  2260.                         BAsmCode[0] = 0x7E;
  2261.                         BAsmCode[1] = OpTabPOPC[Index] | i;
  2262.                         CodeLen = 2;
  2263.                         return;
  2264.                 }
  2265.         }
  2266.  
  2267.         WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[1]);
  2268. }
  2269.  
  2270. static const Byte OpTabPOPM[] = {
  2271.         0x6F,   /* POPM */
  2272.         0x6E,   /* PUSHM */
  2273. };
  2274.  
  2275. static void DecodePOPM(Word Index)
  2276. {
  2277.         Byte range;
  2278.  
  2279.         if (!ChkNoAttr()) return;
  2280.         if (!ChkArgCnt(1,1)) return;
  2281.  
  2282.         if (DecodeRegRange(&ArgStr[1], &range))
  2283.         {
  2284.                 BAsmCode[0] = OpTabPOPM[Index];
  2285.                 BAsmCode[1] = range;
  2286.                 CodeLen = 2;
  2287.                 return;
  2288.         }
  2289.  
  2290.         WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]);
  2291. }
  2292.  
  2293. static void DecodePUSH(Word Index)
  2294. {
  2295.         tSymbolSize size;
  2296.         Byte reg;
  2297.         LongInt disp;
  2298.         tSymbolFlags flags;
  2299.         Byte dsize;
  2300.         Byte scale;
  2301.  
  2302.         UNUSED(Index);
  2303.  
  2304.         size = DecodeAttrSize();
  2305.         if (size == eSymbolSizeUnknown) return;
  2306.         if (!ChkArgCnt(1,1)) return;
  2307.  
  2308.         scale = Size2Scale(size);
  2309.  
  2310.         if (DecodeReg(&ArgStr[1], &reg, eRn))
  2311.         {
  2312.                 BAsmCode[0] = 0x7E;
  2313.                 BAsmCode[1] = 0x80 | (size << 4) | reg;
  2314.                 CodeLen = 2;
  2315.                 return;
  2316.         }
  2317.  
  2318.         if (DecodeIndirectADC(&ArgStr[1], &reg, &disp, &flags))
  2319.         {
  2320.                 dsize = DispSize(disp, flags, scale);
  2321.  
  2322.                 BAsmCode[0] = 0xF4 | dsize;
  2323.                 BAsmCode[1] = 0x08 | (reg << 4) | size;
  2324.                 CodeLen = DispOut(2, dsize, disp, scale);
  2325.                 return;
  2326.         }
  2327.  
  2328.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2329. }
  2330.  
  2331. static const struct {
  2332.         Byte Opc2;
  2333.         Byte Opc3;
  2334.         Byte flags;
  2335. } OpTabRACW[] = {
  2336.         { 0x18, 0x00, 0x00 },   /* RACW */
  2337.         { 0x19, 0x00, 0x10 },   /* RACL */
  2338.         { 0x19, 0x40, 0x10 },   /* RDACL */
  2339.         { 0x18, 0x40, 0x10 },   /* RDACW */
  2340. };
  2341.  
  2342. static void DecodeRACW(Word Index)
  2343. {
  2344.         LongInt imm;
  2345.         tSymbolFlags flags;
  2346.         Byte acc = 0;
  2347.  
  2348.         if ((OpTabRACW[Index].flags & 0x10) && !CheckV2()) return;
  2349.         if (!ChkNoAttr()) return;
  2350.  
  2351.         if (pCurrCPUProps->InstSet == eRXv1)
  2352.         {
  2353.                 if (!ChkArgCnt(1,1)) return;
  2354.         }
  2355.         else
  2356.         {
  2357.                 if (!ChkArgCnt(2,2)) return;
  2358.  
  2359.                 if (!DecodeAcc(&ArgStr[2], &acc))
  2360.                 {
  2361.                         WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
  2362.                         return;
  2363.                 }
  2364.         }
  2365.  
  2366.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  2367.         {
  2368.                 if (mFirstPassUnknown(flags) || imm == 1 || imm == 2)
  2369.                 {
  2370.                         BAsmCode[0] = 0xFD;
  2371.                         BAsmCode[1] = OpTabRACW[Index].Opc2;
  2372.                         BAsmCode[2] = OpTabRACW[Index].Opc3 | (acc << 7) | ((imm - 1) << 4);
  2373.                         CodeLen = 3;
  2374.                         return;
  2375.                 }
  2376.         }
  2377.  
  2378.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[1]);
  2379. }
  2380.  
  2381. static void DecodeRMPA(Word Index)
  2382. {
  2383.         tSymbolSize size;
  2384.  
  2385.         size = DecodeAttrSize();
  2386.         if (size == eSymbolSizeUnknown) return;
  2387.         if (!ChkArgCnt(0,0)) return;
  2388.  
  2389.         BAsmCode[0] = 0x7F;
  2390.         BAsmCode[1] = Index | size;
  2391.         CodeLen = 2;
  2392. }
  2393.  
  2394. static const struct {
  2395.         Byte Opc1;
  2396.         Byte Opc2;
  2397. } OpTabROTL[] = {
  2398.         { 0x6E, 0x66 }, /* ROTL */
  2399.         { 0x6C, 0x64 }, /* ROTR */
  2400. };
  2401.  
  2402. static void DecodeROTL(Word Index)
  2403. {
  2404.         Byte regs;
  2405.         Byte regd;
  2406.         LongInt imm;
  2407.         tSymbolFlags flags;
  2408.  
  2409.         if (!ChkNoAttr()) return;
  2410.         if (!ChkArgCnt(2,2)) return;
  2411.  
  2412.         if (!DecodeReg(&ArgStr[2], &regd, eRn))
  2413.         {
  2414.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  2415.                 return;
  2416.         }
  2417.  
  2418.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  2419.         {
  2420.                 if (!mFirstPassUnknown(flags) && (imm < 0 || imm > 31))
  2421.                 {
  2422.                         WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
  2423.                         return;
  2424.                 }
  2425.  
  2426.                 BAsmCode[0] = 0xFD;
  2427.                 BAsmCode[1] = OpTabROTL[Index].Opc1 | ((imm >> 4) & 0x01);
  2428.                 BAsmCode[2] = ((imm << 4) & 0xF0) | regd;
  2429.                 CodeLen = 3;
  2430.                 return;
  2431.         }
  2432.  
  2433.         if (DecodeReg(&ArgStr[1], &regs, eRn))
  2434.         {
  2435.                 BAsmCode[0] = 0xFD;
  2436.                 BAsmCode[1] = OpTabROTL[Index].Opc2;
  2437.                 BAsmCode[2] = (regs << 4) | regd;
  2438.                 CodeLen = 3;
  2439.                 return;
  2440.         }
  2441.  
  2442.         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2443. }
  2444.  
  2445. static void DecodeRTE(Word Index)
  2446. {
  2447.         if (!ChkNoAttr()) return;
  2448.         if (!ChkArgCnt(0,0)) return;
  2449.  
  2450.         switch (Index)
  2451.         {
  2452.         case 0x7F95:    /* RTE */
  2453.         case 0x7F94:    /* RTFI */
  2454.         case 0x7F96:    /* WAIT */
  2455.                 if (!CheckSup()) return;
  2456.         }
  2457.  
  2458.         BAsmCode[0] = Index >> 8;
  2459.         BAsmCode[1] = Index;
  2460.         CodeLen = 2;
  2461. }
  2462.  
  2463. static void DecodeRTSD(Word Index)
  2464. {
  2465.         LongInt imm;
  2466.         tSymbolFlags flags;
  2467.         Byte range;
  2468.  
  2469.         UNUSED(Index);
  2470.  
  2471.         if (!ChkNoAttr()) return;
  2472.         if (!ChkArgCnt(1,2)) return;
  2473.  
  2474.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  2475.         {
  2476.                 if (mSymbolQuestionable(flags) && (imm < 0 || imm > 255))
  2477.                 {
  2478.                         WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
  2479.                         return;
  2480.                 }
  2481.  
  2482.                 if (ArgCnt == 2 && DecodeRegRange(&ArgStr[2], &range))
  2483.                 {
  2484.                         BAsmCode[0] = 0x3F;
  2485.                         BAsmCode[1] = range;
  2486.                         BAsmCode[2] = imm;
  2487.                         CodeLen = 3;
  2488.                         return;
  2489.                 }
  2490.  
  2491.                 if (ArgCnt > 1)
  2492.                 {
  2493.                         WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
  2494.                         return;
  2495.                 }
  2496.  
  2497.                 BAsmCode[0] = 0x67;
  2498.                 BAsmCode[1] = imm;
  2499.                 CodeLen = 2;
  2500.                 return;
  2501.         }
  2502.  
  2503.         WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
  2504. }
  2505.  
  2506. static void DecodeSCCnd(Word Index)
  2507. {
  2508.         tSymbolSize size;
  2509.         Byte reg;
  2510.         LongInt disp;
  2511.         tSymbolFlags flags;
  2512.         Byte dsize;
  2513.         Byte scale;
  2514.  
  2515.         size = DecodeAttrSize();
  2516.         if (size == eSymbolSizeUnknown) return;
  2517.         if (!ChkArgCnt(1,1)) return;
  2518.  
  2519.         scale = Size2Scale(size);
  2520.  
  2521.         if (DecodeReg(&ArgStr[1], &reg, eRn))
  2522.         {
  2523.                 if (size != 0x02)
  2524.                 {
  2525.                         WrStrErrorPos(ErrNum_InvOpSize, &ArgStr[1]);
  2526.                         return;
  2527.                 }
  2528.  
  2529.                 BAsmCode[0] = 0xFC;
  2530.                 BAsmCode[1] = 0xD3 | (size << 2);
  2531.                 BAsmCode[2] = (reg << 4) | Index;
  2532.                 CodeLen = 3;
  2533.                 return;
  2534.         }
  2535.  
  2536.         if (DecodeIndirectADC(&ArgStr[1], &reg, &disp, &flags))
  2537.         {
  2538.                 dsize = DispSize(disp, flags, scale);
  2539.  
  2540.                 BAsmCode[0] = 0xFC;
  2541.                 BAsmCode[1] = 0xD0 | (size << 2) | dsize;
  2542.                 BAsmCode[2] = (reg << 4) | Index;
  2543.                 CodeLen = DispOut(3, dsize, disp, scale);
  2544.                 return;
  2545.         }
  2546.  
  2547.         WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
  2548. }
  2549.  
  2550. static const struct {
  2551.         Byte Opc1;
  2552.         Byte Opc2;
  2553.         Byte Opc3;
  2554. } OpTabSHAR[] = {
  2555.         { 0x6A, 0x61, 0xA0 },   /* SHAR */
  2556.         { 0x6C, 0x62, 0xC0 },   /* SHLL */
  2557.         { 0x68, 0x60, 0x80 },   /* SHLR */
  2558. };
  2559.  
  2560. static void DecodeSHAR(Word Index)
  2561. {
  2562.         Byte regs;
  2563.         Byte regd;
  2564.         LongInt imm;
  2565.         tSymbolFlags flags;
  2566.  
  2567.         if (!ChkNoAttr()) return;
  2568.         if (!ChkArgCnt(2,3)) return;
  2569.  
  2570.         if (!DecodeReg(&ArgStr[ArgCnt], &regd, eRn))
  2571.         {
  2572.                 WrStrErrorPos(ErrNum_InvRegName, &ArgStr[2]);
  2573.                 return;
  2574.         }
  2575.  
  2576.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  2577.         {
  2578.                 if (!mFirstPassUnknown(flags) && (imm < 0 || imm > 31))
  2579.                 {
  2580.                         WrStrErrorPos(ErrNum_OverRange, &ArgStr[1]);
  2581.                         return;
  2582.                 }
  2583.  
  2584.                 if (ArgCnt == 3)
  2585.                 {
  2586.                         if (DecodeReg(&ArgStr[2], &regs, eRn))
  2587.                         {       /* (3) */
  2588.                                 BAsmCode[0] = 0xFD;
  2589.                                 BAsmCode[1] = OpTabSHAR[Index].Opc3 | imm;
  2590.                                 BAsmCode[2] = (regs << 4) | regd;
  2591.                                 CodeLen = 3;
  2592.                                 return;
  2593.                         }
  2594.  
  2595.                         WrStrErrorPos(ErrNum_InvAddrMode, &ArgStr[2]);
  2596.                         return;
  2597.                 }
  2598.  
  2599.                 /* (1) */
  2600.                 BAsmCode[0] = OpTabSHAR[Index].Opc1 | (imm >> 4);
  2601.                 BAsmCode[1] = ((imm << 4) & 0xF0) | regd;
  2602.                 CodeLen = 2;
  2603.                 return;
  2604.         }
  2605.  
  2606.         if (ArgCnt > 2)
  2607.         {
  2608.                 WrStrErrorPos(ErrNum_TooManyArgs, &ArgStr[2]);
  2609.                 return;
  2610.         }
  2611.  
  2612.         if (DecodeReg(&ArgStr[1], &regs, eRn))
  2613.         {       /* (2) */
  2614.                 BAsmCode[0] = 0xFD;
  2615.                 BAsmCode[1] = OpTabSHAR[Index].Opc2;
  2616.                 BAsmCode[2] = (regs << 4) | regd;
  2617.                 CodeLen = 3;
  2618.                 return;
  2619.         }
  2620.  
  2621.         WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
  2622. }
  2623.  
  2624. static const struct {
  2625.         Byte OpcIR;
  2626.         Byte OpcRR;
  2627. } OpTabSTNZ[] = {
  2628.         { 0xF0, 0x4F }, /* STNZ */
  2629.         { 0xE0, 0x4B }, /* STZ */
  2630. };
  2631.  
  2632. static void DecodeSTNZ(Word Index)
  2633. {
  2634.         LongInt imm;
  2635.         tSymbolFlags flags;
  2636.         Byte regd;
  2637.         Byte regs;
  2638.         Byte size;
  2639.        
  2640.         if (!ChkNoAttr()) return;
  2641.         if (!ChkArgCnt(2,2)) return;
  2642.  
  2643.         if (!DecodeReg(&ArgStr[2], &regd, eRn))
  2644.         {
  2645.                 WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
  2646.                 return;
  2647.         }
  2648.  
  2649.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  2650.         {
  2651.                 size = ImmSize32(imm, flags);
  2652.  
  2653.                 BAsmCode[0] = 0xFD;
  2654.                 BAsmCode[1] = 0x70 | (size << 2);
  2655.                 BAsmCode[2] = OpTabSTNZ[Index].OpcIR | regd;
  2656.                 CodeLen = ImmOut(3, size, imm);
  2657.                 return;
  2658.         }
  2659.  
  2660.         if (DecodeReg(&ArgStr[1], &regs, eRn))
  2661.         {
  2662.                 if (!CheckV2()) return;
  2663.  
  2664.                 BAsmCode[0] = 0xFC;
  2665.                 BAsmCode[1] = OpTabSTNZ[Index].OpcRR;
  2666.                 BAsmCode[2] = (regs << 4) | regd;
  2667.                 CodeLen = 3;
  2668.                 return;
  2669.         }
  2670.  
  2671.         WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
  2672. }
  2673.  
  2674. static const struct {
  2675.         Byte Opc1;
  2676.         Byte Opc2;
  2677.         Byte Opc3;
  2678.         Byte flags;
  2679. } OpTabTST[] = {
  2680.         { 0xC0, 0x30, 0x0C, 0x01 },     /* TST */
  2681.         { 0,    0x40, 0x10, 0x00 },     /* XCHG */
  2682.         { 0xD0, 0x34, 0x0D, 0x03 },     /* XOR */
  2683. };
  2684.  
  2685. static void DecodeTST(Word Index)
  2686. {
  2687.         Byte reg1;
  2688.         Byte reg2;
  2689.         LongInt imm;
  2690.         LongInt disp;
  2691.         tSymbolFlags flags;
  2692.         Byte size;
  2693.         Byte memex;
  2694.         Byte scale;
  2695.  
  2696.         if (!ChkNoAttr()) return;
  2697.         if ((OpTabTST[Index].flags & 0x02) && ArgCnt == 3)
  2698.         {
  2699.                 Byte reg3;
  2700.  
  2701.                 if (!CheckV3()) return;
  2702.  
  2703.                 if (!DecodeReg(&ArgStr[1], &reg1, eRn))
  2704.                 {
  2705.                         WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
  2706.                         return;        
  2707.                 }
  2708.  
  2709.                 if (!DecodeReg(&ArgStr[2], &reg2, eRn))
  2710.                 {
  2711.                         WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
  2712.                         return;        
  2713.                 }
  2714.  
  2715.                 if (!DecodeReg(&ArgStr[3], &reg3, eRn))
  2716.                 {
  2717.                         WrStrErrorPos(ErrNum_InvArg, &ArgStr[3]);
  2718.                         return;        
  2719.                 }
  2720.  
  2721.                 BAsmCode[0] = 0xFF;
  2722.                 BAsmCode[1] = 0x60 | reg3;
  2723.                 BAsmCode[2] = (reg1 << 4) | reg2;
  2724.                 CodeLen = 3;
  2725.                 return;
  2726.         }
  2727.                
  2728.         if (!ChkArgCnt(2,2)) return;
  2729.  
  2730.         if (!DecodeReg(&ArgStr[2], &reg2, eRn))
  2731.         {
  2732.                 WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
  2733.                 return;        
  2734.         }
  2735.  
  2736.         if ((OpTabTST[Index].flags & 0x01) &&
  2737.                 DecodeImm(&ArgStr[1], &imm, &flags))
  2738.         {
  2739.                 size = ImmSize32(imm, flags);
  2740.  
  2741.                 BAsmCode[0] = 0xFD;
  2742.                 BAsmCode[1] = 0x70 | (size << 2);
  2743.                 BAsmCode[2] = OpTabTST[Index].Opc1 | reg2;
  2744.                 CodeLen = ImmOut(3, size, imm);
  2745.                 return;
  2746.         }
  2747.  
  2748.         if (DecodeReg(&ArgStr[1], &reg1, eRn))
  2749.         {
  2750.                 BAsmCode[0] = 0xFC;
  2751.                 BAsmCode[1] = OpTabTST[Index].Opc2 | 0x03;
  2752.                 BAsmCode[2] = (reg1 << 4) | reg2;
  2753.                 CodeLen = 3;
  2754.                 return;
  2755.         }
  2756.  
  2757.         if (DecodeIndirectADD(&ArgStr[1], &reg1, &disp, &flags, &memex, &scale))
  2758.         {
  2759.                 if (memex == 0x80)
  2760.                 {
  2761.                         size = DispSize(disp, flags, 1);
  2762.                        
  2763.                         BAsmCode[0] = 0xFC;
  2764.                         BAsmCode[1] = OpTabTST[Index].Opc2 | size;
  2765.                         BAsmCode[2] = (reg1 << 4) | reg2;
  2766.                         CodeLen = DispOut(3, size, disp, 1);
  2767.                         return;
  2768.                 }
  2769.  
  2770.                 size = DispSize(disp, flags, scale);
  2771.  
  2772.                 BAsmCode[0] = 0x06;
  2773.                 BAsmCode[1] = 0x20 | (memex << 6) | size;
  2774.                 BAsmCode[2] = OpTabTST[Index].Opc3;
  2775.                 BAsmCode[3] = (reg1 << 4) | reg2;
  2776.                 CodeLen = DispOut(4, size, disp, scale);
  2777.                 return;
  2778.         }
  2779.                        
  2780. }
  2781.  
  2782. static void DecodeMOVCO(Word Index)
  2783. {
  2784.         Byte regs;
  2785.         Byte regd;
  2786.  
  2787.         UNUSED(Index);
  2788.  
  2789.         if (!CheckV2()) return;
  2790.  
  2791.         if (!ChkNoAttr()) return;
  2792.         if (!ChkArgCnt(2,2)) return;
  2793.  
  2794.         if (!DecodeReg(&ArgStr[1], &regs, eRn))
  2795.         {
  2796.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
  2797.                 return;
  2798.         }
  2799.  
  2800.         if (!DecodeIndirect(&ArgStr[2], &regd))
  2801.         {
  2802.                 WrStrErrorPos(ErrNum_InvArg, &ArgStr[2]);
  2803.                 return;
  2804.         }
  2805.  
  2806.         BAsmCode[0] = 0xFD;
  2807.         BAsmCode[1] = 0x27;
  2808.         BAsmCode[2] = (regd << 4) | regs;
  2809.         CodeLen = 3;
  2810. }
  2811.  
  2812. static void DecodeMOVLI(Word Index)
  2813. {
  2814.         Byte regs;
  2815.         Byte regd;
  2816.  
  2817.         UNUSED(Index);
  2818.  
  2819.         if (!ChkNoAttr()) return;
  2820.         if (!ChkArgCnt(2,2)) return;
  2821.  
  2822.         if (!DecodeIndirect(&ArgStr[1], &regs))
  2823.         {
  2824.                 WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
  2825.                 return;
  2826.         }
  2827.  
  2828.         if (!DecodeReg(&ArgStr[2], &regd, eRn))
  2829.         {
  2830.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
  2831.                 return;
  2832.         }
  2833.  
  2834.         BAsmCode[0] = 0xFD;
  2835.         BAsmCode[1] = 0x2F;
  2836.         BAsmCode[2] = (regs << 4) | regd;
  2837.         CodeLen = 3;
  2838. }
  2839.  
  2840. static const Byte OpTabBFMOV[] = {
  2841.         0x5E,   /* BFMOV */
  2842.         0x5A,   /* BFMOVZ */
  2843. };
  2844.  
  2845. static void DecodeBFMOV(Word Index)
  2846. {
  2847.         LongInt slsb;
  2848.         LongInt dlsb;
  2849.         LongInt width;
  2850.         tSymbolFlags flags;
  2851.         Byte regs;
  2852.         Byte regd;
  2853.  
  2854.         if (!ChkNoAttr()) return;
  2855.         if (!ChkArgCnt(5,5)) return;
  2856.         if (!CheckV3()) return;
  2857.  
  2858.         if (!DecodeImm(&ArgStr[1], &slsb, &flags))
  2859.         {
  2860.                 WrStrErrorPos(ErrNum_ExpectInt, &ArgStr[1]);
  2861.                 return;
  2862.         }
  2863.         if (!mFirstPassUnknownOrQuestionable(flags) && !ChkRange(slsb, 0, 31)) return;
  2864.  
  2865.         if (!DecodeImm(&ArgStr[2], &dlsb, &flags))
  2866.         {
  2867.                 WrStrErrorPos(ErrNum_ExpectInt, &ArgStr[2]);
  2868.                 return;
  2869.         }
  2870.         if (!mFirstPassUnknownOrQuestionable(flags) && !ChkRange(dlsb, 0, 31)) return;
  2871.  
  2872.         if (!DecodeImm(&ArgStr[3], &width, &flags))
  2873.         {
  2874.                 WrStrErrorPos(ErrNum_ExpectInt, &ArgStr[3]);
  2875.                 return;
  2876.         }
  2877.         if (!mFirstPassUnknownOrQuestionable(flags) && !ChkRange(width, 1, 31)) return;
  2878.  
  2879.         if (!DecodeReg(&ArgStr[4], &regs, eRn))
  2880.         {
  2881.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[4]);
  2882.                 return;
  2883.         }
  2884.  
  2885.         if (!DecodeReg(&ArgStr[5], &regd, eRn))
  2886.         {
  2887.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[5]);
  2888.                 return;
  2889.         }
  2890.  
  2891.         if (slsb + width > 32 || dlsb + width > 32)
  2892.         {
  2893.                 WrError(ErrNum_OverRange);
  2894.                 return;
  2895.         }
  2896.  
  2897.         BAsmCode[0] = 0xFC;
  2898.         BAsmCode[1] = OpTabBFMOV[Index];
  2899.         BAsmCode[2] = (regs << 4) | regd;
  2900.         BAsmCode[3] = ((dlsb - slsb) & 0x1f) | ((dlsb << 5) & 0xE0);
  2901.         BAsmCode[4] = ((dlsb >> 3) & 0x03) | (((dlsb + width) << 2) & 0x7C);
  2902.         CodeLen = 5;
  2903. }
  2904.  
  2905. static const struct {
  2906.         Byte OpcI;
  2907.         Byte OpcR;
  2908. } OpTabRSTR[] = {
  2909.         { 0xF0, 0xD0 }, /* RSTR */
  2910.         { 0xE0, 0xC0 }, /* SAVE */
  2911. };
  2912.  
  2913. static void DecodeRSTR(Word Index)
  2914. {
  2915.         LongInt imm;
  2916.         tSymbolFlags flags;
  2917.         Byte reg;
  2918.  
  2919.         if (!ChkNoAttr()) return;
  2920.         if (!ChkArgCnt(1,1)) return;
  2921.         if (!CheckV3()) return;
  2922.  
  2923.         if (!pCurrCPUProps->RegBank)
  2924.         {
  2925.                 WrError(ErrNum_InstructionNotSupported);
  2926.                 return;
  2927.         }
  2928.  
  2929.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  2930.         {
  2931.                 if (!ChkRange(imm, 0, pCurrCPUProps->RegBank - 1)) return;
  2932.  
  2933.                 BAsmCode[0] = 0xFD;
  2934.                 BAsmCode[1] = 0x76;
  2935.                 BAsmCode[2] = OpTabRSTR[Index].OpcI;
  2936.                 BAsmCode[3] = imm;
  2937.                 CodeLen = 4;
  2938.                 return;
  2939.         }
  2940.  
  2941.         if (DecodeReg(&ArgStr[1], &reg, eRn))
  2942.         {
  2943.                 BAsmCode[0] = 0xFD;
  2944.                 BAsmCode[1] = 0x76;
  2945.                 BAsmCode[2] = OpTabRSTR[Index].OpcR | reg;
  2946.                 BAsmCode[3] = 0x00;
  2947.                 CodeLen = 4;
  2948.                 return;
  2949.         }
  2950.  
  2951.         WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
  2952. }
  2953.  
  2954. static const struct {
  2955.         Byte Opc1;
  2956.         Byte Opc2;
  2957. } OpTabDABS[] = {
  2958.         { 0x0C, 0x01 }, /* DABS */
  2959.         { 0x0C, 0x02 }, /* DNEG */
  2960.         { 0x0D, 0x0D }, /* DROUND */
  2961.         { 0x0D, 0x00 }, /* DSQRT */
  2962.         { 0x0D, 0x0C }, /* DTOF */
  2963.         { 0x0D, 0x08 }, /* DTOI */
  2964.         { 0x0D, 0x09 }, /* DTOU */
  2965. };
  2966.  
  2967. static void DecodeDABS(Word Index)
  2968. {
  2969.         Byte regs;
  2970.         Byte regd;
  2971.  
  2972.         if (!ChkNoAttr()) return;
  2973.         if (!ChkArgCnt(2,2)) return;
  2974.         if (!CheckV3()) return;
  2975.         if (!CheckDouble()) return;
  2976.  
  2977.         if (!DecodeReg(&ArgStr[1], &regs, eDRn))
  2978.         {
  2979.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
  2980.                 return;
  2981.         }
  2982.  
  2983.         if (!DecodeReg(&ArgStr[2], &regd, eDRn))
  2984.         {
  2985.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
  2986.                 return;
  2987.         }
  2988.  
  2989.         BAsmCode[0] = 0x76;
  2990.         BAsmCode[1] = 0x90;
  2991.         BAsmCode[2] = OpTabDABS[Index].Opc1 | (regs << 4);
  2992.         BAsmCode[3] = OpTabDABS[Index].Opc2 | (regd << 4);
  2993.         CodeLen = 4;
  2994. }
  2995.  
  2996. static const struct {
  2997.         Byte Opc;
  2998. } OpTabDADD[] = {
  2999.         { 0x00 },       /* DADD */
  3000.         { 0x05 },       /* DDIV */
  3001.         { 0x02 },       /* DMUL */
  3002.         { 0x01 },       /* DSUB */
  3003. };
  3004.  
  3005. static void DecodeDADD(Word Index)
  3006. {
  3007.         Byte regs1;
  3008.         Byte regs2;
  3009.         Byte regd;
  3010.  
  3011.         if (!ChkNoAttr()) return;
  3012.         if (!ChkArgCnt(3,3)) return;
  3013.         if (!CheckV3()) return;
  3014.         if (!CheckDouble()) return;
  3015.  
  3016.         if (!DecodeReg(&ArgStr[1], &regs1, eDRn))
  3017.         {
  3018.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
  3019.                 return;
  3020.         }
  3021.  
  3022.         if (!DecodeReg(&ArgStr[2], &regs2, eDRn))
  3023.         {
  3024.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
  3025.                 return;
  3026.         }
  3027.  
  3028.         if (!DecodeReg(&ArgStr[3], &regd, eDRn))
  3029.         {
  3030.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[3]);
  3031.                 return;
  3032.         }
  3033.  
  3034.         BAsmCode[0] = 0x76;
  3035.         BAsmCode[1] = 0x90;
  3036.         BAsmCode[2] = OpTabDADD[Index].Opc | (regs2 << 4);
  3037.         BAsmCode[3] = (regd << 4) | regs1;
  3038.         CodeLen = 4;
  3039. }
  3040.  
  3041. static void DecodeDCMPcm(Word Index)
  3042. {
  3043.         Byte regs1;
  3044.         Byte regs2;
  3045.  
  3046.         if (!ChkNoAttr()) return;
  3047.         if (!ChkArgCnt(2,2)) return;
  3048.         if (!CheckV3()) return;
  3049.         if (!CheckDouble()) return;
  3050.  
  3051.         if (!DecodeReg(&ArgStr[1], &regs1, eDRn))
  3052.         {
  3053.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
  3054.                 return;
  3055.         }
  3056.  
  3057.         if (!DecodeReg(&ArgStr[2], &regs2, eDRn))
  3058.         {
  3059.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
  3060.                 return;
  3061.         }
  3062.  
  3063.         BAsmCode[0] = 0x76;
  3064.         BAsmCode[1] = 0x90;
  3065.         BAsmCode[2] = 0x08 | (regs2 << 4);
  3066.         BAsmCode[3] = ((Index << 4) & 0xF0) | regs1;
  3067.         CodeLen = 4;
  3068. }
  3069.  
  3070. static void DecodeDMOV(Word Index)
  3071. {
  3072.         Byte size;
  3073.         Byte regs;
  3074.         Byte regd;
  3075.         LongInt disp;
  3076.         LongInt imm;
  3077.         tSymbolFlags flags;
  3078.         Byte dsize;
  3079.  
  3080.         UNUSED(Index);
  3081.  
  3082.         if (!ChkArgCnt(2,2)) return;
  3083.         if (!CheckV3()) return;
  3084.         if (!CheckDouble()) return;
  3085.  
  3086.         if (!DecodeAttrDouble(&size)) return;
  3087.  
  3088.         if (DecodeReg(&ArgStr[1], &regs, eRn))
  3089.         {
  3090.                 if (DecodeReg(&ArgStr[2], &regd, eDRHn))
  3091.                 {       /* (1) / (2) */
  3092.                         BAsmCode[0] = 0xFD;
  3093.                         BAsmCode[1] = 0x77;
  3094.                         BAsmCode[2] = 0x80 | regs;
  3095.                         BAsmCode[3] = 0x02 | (regd << 4) | size;
  3096.                         CodeLen = 4;
  3097.                         return;
  3098.                 }
  3099.  
  3100.                 if (DecodeReg(&ArgStr[2], &regd, eDRLn) && !size)
  3101.                 {       /* (3) */
  3102.                         BAsmCode[0] = 0xFD;
  3103.                         BAsmCode[1] = 0x77;
  3104.                         BAsmCode[2] = 0x80 | regs;
  3105.                         BAsmCode[3] = 0x00 | (regd << 4);
  3106.                         CodeLen = 4;
  3107.                         return;
  3108.                 }
  3109.         }
  3110.  
  3111.         if (DecodeReg(&ArgStr[2], &regd, eRn))
  3112.         {
  3113.                 if (DecodeReg(&ArgStr[1], &regs, eDRHn) && !size)
  3114.                 {       /* (4) */
  3115.                         BAsmCode[0] = 0xFD;
  3116.                         BAsmCode[1] = 0x75;
  3117.                         BAsmCode[2] = 0x80 | regd;
  3118.                         BAsmCode[3] = 0x02 | (regs << 4);
  3119.                         CodeLen = 4;
  3120.                         return;
  3121.                 }
  3122.  
  3123.                 if (DecodeReg(&ArgStr[1], &regs, eDRLn) && !size)
  3124.                 {       /* (5) */
  3125.                         BAsmCode[0] = 0xFD;
  3126.                         BAsmCode[1] = 0x75;
  3127.                         BAsmCode[2] = 0x80 | regd;
  3128.                         BAsmCode[3] = 0x00 | (regs << 4);
  3129.                         CodeLen = 4;
  3130.                         return;
  3131.                 }
  3132.         }
  3133.  
  3134.         if (DecodeReg(&ArgStr[1], &regs, eDRn) && size)
  3135.         {
  3136.                 if (DecodeReg(&ArgStr[2], &regd, eDRn))
  3137.                 {       /* (6) */
  3138.                         BAsmCode[0] = 0xFD;
  3139.                         BAsmCode[1] = 0x90;
  3140.                         BAsmCode[2] = 0x0C | (regs << 4);
  3141.                         BAsmCode[3] = 0x00 | (regd << 4);
  3142.                         CodeLen = 4;
  3143.                         return;
  3144.                 }
  3145.  
  3146.                 if (DecodeIndirectADC(&ArgStr[2], &regd, &disp, &flags) && size)
  3147.                 {       /* (7) */
  3148.                         dsize = DispSize(disp, flags, 8);
  3149.  
  3150.                         BAsmCode[0] = 0xFC;
  3151.                         BAsmCode[1] = 0x78 | dsize;
  3152.                         BAsmCode[2] = 0x08 | (regd << 4);
  3153.                         CodeLen = DispOut(3, dsize, disp, 8);
  3154.                         BAsmCode[CodeLen++] = 0x00 | (regs << 4);
  3155.                         return;
  3156.                 }
  3157.         }
  3158.  
  3159.         if (DecodeIndirectADC(&ArgStr[1], &regs, &disp, &flags) && size)
  3160.         {
  3161.                 if (DecodeReg(&ArgStr[2], &regd, eDRn))
  3162.                 {       /* (8) */
  3163.                         dsize = DispSize(disp, flags, 8);
  3164.  
  3165.                         BAsmCode[0] = 0xFC;
  3166.                         BAsmCode[1] = 0xC8 | dsize;
  3167.                         BAsmCode[2] = 0x08 | (regs << 4);
  3168.                         CodeLen = DispOut(3, dsize, disp, 8);
  3169.                         BAsmCode[CodeLen++] = 0x00 | (regd << 4);
  3170.                         return;
  3171.                 }
  3172.         }
  3173.  
  3174.         if (DecodeImm(&ArgStr[1], &imm, &flags))
  3175.         {
  3176.                 if (DecodeReg(&ArgStr[2], &regd, eDRHn))
  3177.                 {       /* (9) / (10) */
  3178.                         BAsmCode[0] = 0xF9;
  3179.                         BAsmCode[1] = 0x03;
  3180.                         BAsmCode[2] = 0x02 | (regd << 4) | size;
  3181.                         CodeLen = ImmOut(3, 0, imm);
  3182.                         return;
  3183.                 }
  3184.  
  3185.                 if (DecodeReg(&ArgStr[2], &regd, eDRLn) && !size)
  3186.                 {       /* (11) */
  3187.                         BAsmCode[0] = 0xF9;
  3188.                         BAsmCode[1] = 0x03;
  3189.                         BAsmCode[2] = 0x00 | (regd << 4);
  3190.                         CodeLen = ImmOut(3, 0, imm);
  3191.                         return;
  3192.                 }
  3193.         }
  3194.  
  3195.         WrError(ErrNum_InvArg);
  3196. }
  3197.  
  3198. static const Byte OpTabDPOPM[] = {
  3199.         0xA8,   /* DPOPM */
  3200.         0xA0    /* DPUSHM */
  3201. };
  3202.  
  3203. static void DecodeDPOPM(Word Index)
  3204. {
  3205.         const int len = strlen(ArgStr[1].str.p_str);
  3206.         Byte size;
  3207.         Byte reg1;
  3208.         Byte reg2;
  3209.         int i;
  3210.  
  3211.         if (!DecodeAttrDouble(&size)) return;
  3212.         if (!ChkArgCnt(1,1)) return;
  3213.         if (!CheckV3()) return;
  3214.         if (!CheckDouble()) return;
  3215.  
  3216.         for (i = 0; i < len; i++)
  3217.         {
  3218.                 if (ArgStr[1].str.p_str[i] == '-') break;
  3219.         }
  3220.         if (i >= len)
  3221.         {
  3222.                 WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]);
  3223.                 return;
  3224.         }
  3225.  
  3226.         StrCompCopySub(&Temp1, &ArgStr[1], 0, i);
  3227.         if (!DecodeReg(&Temp1, &reg1, size ? eDRn : eDCRn))
  3228.         {
  3229.                 WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]);
  3230.                 return;
  3231.         }
  3232.                
  3233.         StrCompCopySub(&Temp1, &ArgStr[1], i + 1, len - i - 1);
  3234.         if (!DecodeReg(&Temp1, &reg2, size ? eDRn : eDCRn))
  3235.         {
  3236.                 WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]);
  3237.                 return;
  3238.         }
  3239.  
  3240.         if (reg2 >= reg1)
  3241.         {
  3242.                 BAsmCode[0] = 0x75;
  3243.                 BAsmCode[1] = OpTabDPOPM[Index] | (size << 4);
  3244.                 BAsmCode[2] = (reg1 << 4) | (reg2 - reg1);
  3245.                 CodeLen = 3;
  3246.                 return;
  3247.         }
  3248.  
  3249.         WrStrErrorPos(ErrNum_InvRegList, &ArgStr[1]);
  3250. }
  3251.  
  3252. static const struct {
  3253.         Byte Opc1;
  3254.         Byte Opc2;
  3255. } OpTabFTOD[] = {
  3256.         { 0x80, 0x0A }, /* FTOD */
  3257.         { 0x80, 0x09 }, /* ITOD */
  3258.         { 0x80, 0x0D }, /* UTOD */
  3259. };
  3260.  
  3261. static void DecodeFTOD(Word Index)
  3262. {
  3263.         Byte regs;
  3264.         Byte regd;
  3265.  
  3266.         UNUSED(Index);
  3267.  
  3268.         if (!ChkNoAttr()) return;
  3269.         if (!ChkArgCnt(2,2)) return;
  3270.         if (!CheckV3()) return;
  3271.         if (!CheckDouble()) return;
  3272.  
  3273.         if (!DecodeReg(&ArgStr[1], &regs, eRn))
  3274.         {
  3275.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[1]);
  3276.                 return;
  3277.         }
  3278.  
  3279.         if (!DecodeReg(&ArgStr[2], &regd, eDRn))
  3280.         {
  3281.                 WrStrErrorPos(ErrNum_ExpectReg, &ArgStr[2]);
  3282.                 return;
  3283.         }
  3284.  
  3285.         BAsmCode[0] = 0xFD;
  3286.         BAsmCode[1] = 0x77;
  3287.         BAsmCode[2] = OpTabFTOD[Index].Opc1 | regs;
  3288.         BAsmCode[3] = OpTabFTOD[Index].Opc2 | (regd << 4);
  3289.         CodeLen = 4;
  3290. }
  3291.  
  3292. static void DecodeMVFDC(Word Index)
  3293. {
  3294.         Byte regc;
  3295.         Byte reg;
  3296.  
  3297.         UNUSED(Index);
  3298.  
  3299.         if (!ChkNoAttr()) return;
  3300.         if (!ChkArgCnt(2,2)) return;
  3301.         if (!CheckV3()) return;
  3302.         if (!CheckDouble()) return;
  3303.  
  3304.         if (!DecodeReg(&ArgStr[Index + 1], &regc, eDCRn))
  3305.         {
  3306.                 WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[Index + 1]);
  3307.                 return;
  3308.         }
  3309.        
  3310.         if (!DecodeReg(&ArgStr[2 - Index], &reg, eRn))
  3311.         {
  3312.                 WrStrErrorPos(ErrNum_InvReg, &ArgStr[2 - Index]);
  3313.                 return;
  3314.         }
  3315.  
  3316.         BAsmCode[0] = 0xFD;
  3317.         BAsmCode[1] = 0x75 | (Index << 1);
  3318.         BAsmCode[2] = 0x80 | reg;
  3319.         BAsmCode[3] = 0x04 | (regc << 4);
  3320.         CodeLen = 4;
  3321. }
  3322.  
  3323. static void DecodeMVFDR(Word Index)
  3324. {
  3325.         UNUSED(Index);
  3326.  
  3327.         if (!ChkNoAttr()) return;
  3328.         if (!ChkArgCnt(0,0)) return;
  3329.         if (!CheckV3()) return;
  3330.         if (!CheckDouble()) return;
  3331.  
  3332.         BAsmCode[0] = 0x75;
  3333.         BAsmCode[1] = 0x90;
  3334.         BAsmCode[2] = 0x1B;
  3335.         CodeLen = 3;
  3336. }
  3337.  
  3338. #ifdef COMPAT
  3339.  
  3340. #define BigEndianSymName "BIGENDIAN" /* T.B.D. */
  3341. static void DecodeENDIAN(Word Index)
  3342. {
  3343.         const char *str;
  3344.  
  3345.         UNUSED(Index);
  3346.  
  3347.         if (!ChkNoAttr()) return;
  3348.         if (!ChkArgCnt(1,1)) return;
  3349.  
  3350.         str = ArgStr[1].str.p_str;
  3351.         if (!as_strcasecmp(str, "BIG"))
  3352.                 SetFlag(&TargetBigEndian, BigEndianSymName, True);
  3353.         else if (!as_strcasecmp(str, "LITTLE"))
  3354.                 SetFlag(&TargetBigEndian, BigEndianSymName, False);
  3355.         else
  3356.                 WrStrErrorPos(ErrNum_InvArg, &ArgStr[1]);
  3357. }
  3358.  
  3359. #endif /* COMPAT */
  3360.  
  3361. /*---------------------------------------------------------------------------*/
  3362.  
  3363. static void AddABS(const char *NName, Word NCode)
  3364. {
  3365.         AddInstTable(InstTable, NName, NCode, DecodeABS);
  3366. }
  3367.  
  3368. static void AddADC(const char *NName, Word NCode)
  3369. {
  3370.         AddInstTable(InstTable, NName, NCode, DecodeADC);
  3371. }
  3372.  
  3373. static void AddADD(const char *NName, Word NCode)
  3374. {
  3375.         AddInstTable(InstTable, NName, NCode, DecodeADD);
  3376. }
  3377.  
  3378. static void AddBCLR(const char *NName, Word NCode)
  3379. {
  3380.         AddInstTable(InstTable, NName, NCode, DecodeBCLR);
  3381. }
  3382.  
  3383. static void AddBCnd(const char *NName, Word NCode)
  3384. {
  3385.         AddInstTable(InstTable, NName, NCode, DecodeBCnd);
  3386. }
  3387.  
  3388. static void AddBMCnd(const char *NName, Word NCode)
  3389. {
  3390.         AddInstTable(InstTable, NName, NCode, DecodeBMCnd);
  3391. }
  3392.  
  3393. static void AddBRK(const char *NName, Word NCode)
  3394. {
  3395.         AddInstTable(InstTable, NName, NCode, DecodeBRK);
  3396. }
  3397.  
  3398. static void AddBSR(const char *NName, Word NCode)
  3399. {
  3400.         AddInstTable(InstTable, NName, NCode, DecodeBSR);
  3401. }
  3402.  
  3403. static void AddCLRPSW(const char *NName, Word NCode)
  3404. {
  3405.         AddInstTable(InstTable, NName, NCode, DecodeCLRPSW);
  3406. }
  3407.  
  3408. static void AddDIV(const char *NName, Word NCode)
  3409. {
  3410.         AddInstTable(InstTable, NName, NCode, DecodeDIV);
  3411. }
  3412.  
  3413. static void AddFADD(const char *NName, Word NCode)
  3414. {
  3415.         AddInstTable(InstTable, NName, NCode, DecodeFADD);
  3416. }
  3417.  
  3418. static void AddINT(const char *NName, Word NCode)
  3419. {
  3420.         AddInstTable(InstTable, NName, NCode, DecodeINT);
  3421. }
  3422.  
  3423. static void AddITOF(const char *NName, Word NCode)
  3424. {
  3425.         AddInstTable(InstTable, NName, NCode, DecodeITOF);
  3426. }
  3427.  
  3428. static void AddJMP(const char *NName, Word NCode)
  3429. {
  3430.         AddInstTable(InstTable, NName, NCode, DecodeJMP);
  3431. }
  3432.  
  3433. static void AddMACHI(const char *NName, Word NCode)
  3434. {
  3435.         AddInstTable(InstTable, NName, NCode, DecodeMACHI);
  3436. }
  3437.  
  3438. static void AddMOV(const char *NName, Word NCode)
  3439. {
  3440.         AddInstTable(InstTable, NName, NCode, DecodeMOV);
  3441. }
  3442.  
  3443. static void AddMOVU(const char *NName, Word NCode)
  3444. {
  3445.         AddInstTable(InstTable, NName, NCode, DecodeMOVU);
  3446. }
  3447.  
  3448. static void AddMVFACHI(const char *NName, Word NCode)
  3449. {
  3450.         AddInstTable(InstTable, NName, NCode, DecodeMVFACHI);
  3451. }
  3452.  
  3453. static void AddMVFC(const char *NName, Word NCode)
  3454. {
  3455.         AddInstTable(InstTable, NName, NCode, DecodeMVFC);
  3456. }
  3457.  
  3458. static void AddMVTACHI(const char *NName, Word NCode)
  3459. {
  3460.         AddInstTable(InstTable, NName, NCode, DecodeMVTACHI);
  3461. }
  3462.  
  3463. static void AddMVTC(const char *NName, Word NCode)
  3464. {
  3465.         AddInstTable(InstTable, NName, NCode, DecodeMVTC);
  3466. }
  3467.  
  3468. static void AddMVTIPL(const char *NName, Word NCode)
  3469. {
  3470.         AddInstTable(InstTable, NName, NCode, DecodeMVTIPL);
  3471. }
  3472.  
  3473. static void AddPOPC(const char *NName, Word NCode)
  3474. {
  3475.         AddInstTable(InstTable, NName, NCode, DecodePOPC);
  3476. }
  3477.  
  3478. static void AddPOPM(const char *NName, Word NCode)
  3479. {
  3480.         AddInstTable(InstTable, NName, NCode, DecodePOPM);
  3481. }
  3482.  
  3483. static void AddPUSH(const char *NName, Word NCode)
  3484. {
  3485.         AddInstTable(InstTable, NName, NCode, DecodePUSH);
  3486. }
  3487.  
  3488. static void AddRACW(const char *NName, Word NCode)
  3489. {
  3490.         AddInstTable(InstTable, NName, NCode, DecodeRACW);
  3491. }
  3492.  
  3493. static void AddRMPA(const char *NName, Word NCode)
  3494. {
  3495.         AddInstTable(InstTable, NName, NCode, DecodeRMPA);
  3496. }
  3497.  
  3498. static void AddROTL(const char *NName, Word NCode)
  3499. {
  3500.         AddInstTable(InstTable, NName, NCode, DecodeROTL);
  3501. }
  3502.  
  3503. static void AddRTE(const char *NName, Word NCode)
  3504. {
  3505.         AddInstTable(InstTable, NName, NCode, DecodeRTE);
  3506. }
  3507.  
  3508. static void AddRTSD(const char *NName, Word NCode)
  3509. {
  3510.         AddInstTable(InstTable, NName, NCode, DecodeRTSD);
  3511. }
  3512.  
  3513. static void AddSCCnd(const char *NName, Word NCode)
  3514. {
  3515.         AddInstTable(InstTable, NName, NCode, DecodeSCCnd);
  3516. }
  3517.  
  3518. static void AddSHAR(const char *NName, Word NCode)
  3519. {
  3520.         AddInstTable(InstTable, NName, NCode, DecodeSHAR);
  3521. }
  3522.  
  3523. static void AddSTNZ(const char *NName, Word NCode)
  3524. {
  3525.         AddInstTable(InstTable, NName, NCode, DecodeSTNZ);
  3526. }
  3527.  
  3528. static void AddTST(const char *NName, Word NCode)
  3529. {
  3530.         AddInstTable(InstTable, NName, NCode, DecodeTST);
  3531. }
  3532.  
  3533. static void AddMOVCO(const char *NName, Word NCode)
  3534. {
  3535.         AddInstTable(InstTable, NName, NCode, DecodeMOVCO);
  3536. }
  3537.  
  3538. static void AddMOVLI(const char *NName, Word NCode)
  3539. {
  3540.         AddInstTable(InstTable, NName, NCode, DecodeMOVLI);
  3541. }
  3542.  
  3543. static void AddBFMOV(const char *NName, Word NCode)
  3544. {
  3545.         AddInstTable(InstTable, NName, NCode, DecodeBFMOV);
  3546. }
  3547.  
  3548. static void AddRSTR(const char *NName, Word NCode)
  3549. {
  3550.         AddInstTable(InstTable, NName, NCode, DecodeRSTR);
  3551. }
  3552.  
  3553. static void AddDABS(const char *NName, Word NCode)
  3554. {
  3555.         AddInstTable(InstTable, NName, NCode, DecodeDABS);
  3556. }
  3557.  
  3558. static void AddDADD(const char *NName, Word NCode)
  3559. {
  3560.         AddInstTable(InstTable, NName, NCode, DecodeDADD);
  3561. }
  3562.  
  3563. static void AddDCMPcm(const char *NName, Word NCode)
  3564. {
  3565.         AddInstTable(InstTable, NName, NCode, DecodeDCMPcm);
  3566. }
  3567.  
  3568. static void AddDMOV(const char *NName, Word NCode)
  3569. {
  3570.         AddInstTable(InstTable, NName, NCode, DecodeDMOV);
  3571. }
  3572.  
  3573. static void AddDPOPM(const char *NName, Word NCode)
  3574. {
  3575.         AddInstTable(InstTable, NName, NCode, DecodeDPOPM);
  3576. }
  3577.  
  3578. static void AddFTOD(const char *NName, Word NCode)
  3579. {
  3580.         AddInstTable(InstTable, NName, NCode, DecodeFTOD);
  3581. }
  3582.  
  3583. static void AddMVFDC(const char *NName, Word NCode)
  3584. {
  3585.         AddInstTable(InstTable, NName, NCode, DecodeMVFDC);
  3586. }
  3587.  
  3588. static void AddMVFDR(const char *NName, Word NCode)
  3589. {
  3590.         AddInstTable(InstTable, NName, NCode, DecodeMVFDR);
  3591. }
  3592.  
  3593. #ifdef COMPAT
  3594.  
  3595. static void AddBLK(const char *NName, Word NCode)
  3596. {
  3597.         AddInstTable(InstTable, NName, NCode, DecodeIntelDS);
  3598. }
  3599.  
  3600. #endif /* COMPAT */
  3601.  
  3602. static Boolean TrueFnc(void)
  3603. {
  3604.   return True;
  3605. }
  3606.  
  3607. static void InitFields(void)
  3608. {
  3609.         InstTable = CreateInstTable(201);
  3610.  
  3611.   add_null_pseudo(InstTable);
  3612.  
  3613.         /* RXv1 */
  3614.         AddABS("ABS", 0x200F);
  3615.         AddADC("ADC", 0x0802);
  3616.         AddADD("ADD", 0);
  3617.         AddADD("AND", 1);
  3618.         AddBCLR("BCLR", 0);
  3619.         AddBCnd("BEQ",  0);
  3620.         AddBCnd("BZ",   0);
  3621.         AddBCnd("BNE",  1);
  3622.         AddBCnd("BNZ",  1);
  3623.         AddBCnd("BGEU", 2);
  3624.         AddBCnd("BC",   2);
  3625.         AddBCnd("BLTU", 3);
  3626.         AddBCnd("BNC",  3);
  3627.         AddBCnd("BGTU", 4);
  3628.         AddBCnd("BLEU", 5);
  3629.         AddBCnd("BPZ",  6);
  3630.         AddBCnd("BN",   7);
  3631.         AddBCnd("BGE",  8);
  3632.         AddBCnd("BLT",  9);
  3633.         AddBCnd("BGT",  10);
  3634.         AddBCnd("BLE",  11);
  3635.         AddBCnd("BO",   12);
  3636.         AddBCnd("BNO",  13);
  3637.         AddBMCnd("BMEQ",  0);
  3638.         AddBMCnd("BMZ", 0);
  3639.         AddBMCnd("BMNE", 1);
  3640.         AddBMCnd("BMNZ", 1);
  3641.         AddBMCnd("BMGEU", 2);
  3642.         AddBMCnd("BMC", 2);
  3643.         AddBMCnd("BMLTU", 3);
  3644.         AddBMCnd("BMNC", 3);
  3645.         AddBMCnd("BMGTU", 4);
  3646.         AddBMCnd("BMLEU", 5);
  3647.         AddBMCnd("BMPZ", 6);
  3648.         AddBMCnd("BMN", 7);
  3649.         AddBMCnd("BMGE", 8);
  3650.         AddBMCnd("BMLT", 9);
  3651.         AddBMCnd("BMGT", 10);
  3652.         AddBMCnd("BMLE", 11);
  3653.         AddBMCnd("BMO", 12);
  3654.         AddBMCnd("BMNO", 13);
  3655.         AddBCLR("BNOT", 1);
  3656.         AddBCnd("BRA", 14);
  3657.         AddBRK("BRK", 0x0000);
  3658.         AddBCLR("BSET", 2);
  3659.         AddBSR("BSR", 0);
  3660.         AddBCLR("BTST", 3);
  3661.         AddCLRPSW("CLRPSW", 0xB0);
  3662.         AddADD("CMP", 2);
  3663.         AddDIV("DIV", 0);
  3664.         AddDIV("DIVU", 1);
  3665.         AddDIV("EMUL", 2);
  3666.         AddDIV("EMULU", 3);
  3667.         AddFADD("FADD", 0);
  3668.         AddFADD("FCMP", 1);
  3669.         AddFADD("FDIV", 2);
  3670.         AddFADD("FMUL", 3);
  3671.         AddFADD("FSUB", 4);
  3672.         AddFADD("FTOI", 5);
  3673.         AddINT("INT", 0);
  3674.         AddITOF("ITOF", 0);
  3675.         AddJMP("JMP", 0);
  3676.         AddJMP("JSR", 1);
  3677.         AddMACHI("MACHI", 0);
  3678.         AddMACHI("MACLO", 1);
  3679.         AddDIV("MAX", 4);
  3680.         AddDIV("MIN", 5);
  3681.         AddMOV("MOV", 0);
  3682.         AddMOVU("MOVU", 0);
  3683.         AddADD("MUL", 3);
  3684.         AddMACHI("MULHI", 2);
  3685.         AddMACHI("MULLO", 3);
  3686.         AddMVFACHI("MVFACHI", 0);
  3687.         AddMVFACHI("MVFACMI", 1);
  3688.         AddMVFC("MVFC", 0);
  3689.         AddMVTACHI("MVTACHI", 0);
  3690.         AddMVTACHI("MVTACLO", 1);
  3691.         AddMVTC("MVTC", 0);
  3692.         AddMVTIPL("MVTIPL", 0);
  3693.         AddABS("NEG", 0x1007);
  3694.         AddBRK("NOP", 0x0003);
  3695.         AddABS("NOT", 0x003B);
  3696.         AddADD("OR", 4);
  3697.         AddJMP("POP", 2);
  3698.         AddPOPC("POPC", 0);
  3699.         AddPOPM("POPM", 0);
  3700.         AddPUSH("PUSH", 0);
  3701.         AddPOPC("PUSHC", 1);
  3702.         AddPOPM("PUSHM", 1);
  3703.         AddRACW("RACW", 0);
  3704.         AddMACHI("REVL", 4);
  3705.         AddMACHI("REVW", 5);
  3706.         AddRMPA("RMPA", 0x8C);
  3707.         AddJMP("ROLC", 3);
  3708.         AddJMP("RORC", 4);
  3709.         AddROTL("ROTL", 0);
  3710.         AddROTL("ROTR", 1);
  3711.         AddFADD("ROUND", 6);
  3712.         AddRTE("RTE", 0x7F95);
  3713.         AddRTE("RTFI", 0x7F94);
  3714.         AddBRK("RTS", 0x0002);
  3715.         AddRTSD("RTSD", 0);
  3716.         AddJMP("SAT", 5);
  3717.         AddRTE("SATR", 0x7F93);
  3718.         AddADC("SBB", 0x0000);
  3719.         AddSCCnd("SCEQ", 0);
  3720.         AddSCCnd("SCZ", 0);
  3721.         AddSCCnd("SCNE", 1);
  3722.         AddSCCnd("SCNZ", 1);
  3723.         AddSCCnd("SCGEU", 2);
  3724.         AddSCCnd("SCC", 2);
  3725.         AddSCCnd("SCLTU", 3);
  3726.         AddSCCnd("SCNC", 3);
  3727.         AddSCCnd("SCGTU", 4);
  3728.         AddSCCnd("SCLEU", 5);
  3729.         AddSCCnd("SCPZ", 6);
  3730.         AddSCCnd("SCN", 7);
  3731.         AddSCCnd("SCGE", 8);
  3732.         AddSCCnd("SCLT", 9);
  3733.         AddSCCnd("SCGT", 10);
  3734.         AddSCCnd("SCLE", 11);
  3735.         AddSCCnd("SCO", 12);
  3736.         AddSCCnd("SCNO", 13);
  3737.         AddRTE("SCMPU", 0x7F83);
  3738.         AddCLRPSW("SETPSW", 0xA0);
  3739.         AddSHAR("SHAR", 0);
  3740.         AddSHAR("SHLL", 1);
  3741.         AddSHAR("SHLR", 2);
  3742.         AddRTE("SMOVB", 0x7F8B);
  3743.         AddRTE("SMOVF", 0x7F8F);
  3744.         AddRTE("SMOVU", 0x7F87);
  3745.         AddRMPA("SSTR", 0x88);
  3746.         AddSTNZ("STNZ", 0);
  3747.         AddSTNZ("STZ", 1);
  3748.         AddADD("SUB", 5);
  3749.         AddRMPA("SUNTIL", 0x80);
  3750.         AddRMPA("SWHILE", 0x84);
  3751.         AddTST("TST", 0);
  3752.         AddRTE("WAIT", 0x7F96);
  3753.         AddTST("XCHG", 1);
  3754.         AddTST("XOR", 2);
  3755.  
  3756.         /* RXv2 */
  3757.         AddFADD("FSQRT", 7);
  3758.         AddFADD("FTOU", 8);
  3759.         AddITOF("UTOF", 1);
  3760.         AddMOVCO("MOVCO", 0);
  3761.         AddMOVLI("MOVLI", 0);
  3762.         AddMACHI("EMACA", 6);
  3763.         AddMACHI("EMSBA", 7);
  3764.         AddMACHI("EMULA", 8);
  3765.         AddMACHI("MACLH", 9);
  3766.         AddMACHI("MSBHI", 10);
  3767.         AddMACHI("MSBLH", 11);
  3768.         AddMACHI("MSBLO", 12);
  3769.         AddMACHI("MULLH", 13);
  3770.         AddMVFACHI("MVFACGU", 2);
  3771.         AddMVFACHI("MVFACLO", 3);
  3772.         AddMVTACHI("MVTACGU", 2);
  3773.         AddRACW("RACL", 1);
  3774.         AddRACW("RDACL", 2);
  3775.         AddRACW("RDACW", 3);
  3776.  
  3777.         /* RXv3 */
  3778.         AddBFMOV("BFMOV", 0);
  3779.         AddBFMOV("BFMOVZ", 1);
  3780.         AddRSTR("RSTR", 0);
  3781.         AddRSTR("SAVE", 1); SaveIsOccupiedFnc = TrueFnc;
  3782.         AddDABS("DABS", 0);
  3783.         AddDADD("DADD", 0);
  3784.         AddDCMPcm("DCMPUN", 0x01);
  3785.         AddDCMPcm("DCMPEQ", 0x02);
  3786.         AddDCMPcm("DCMPLT", 0x04);
  3787.         AddDCMPcm("DCMPLE", 0x06);
  3788.         AddDADD("DDIV", 1);
  3789.         AddDMOV("DMOV", 0);
  3790.         AddDADD("DMUL", 2);
  3791.         AddDABS("DNEG", 1);
  3792.         AddDPOPM("DPOPM", 0);
  3793.         AddDPOPM("DPUSHM", 1);
  3794.         AddDABS("DROUND", 2);
  3795.         AddDABS("DSQRT", 3);
  3796.         AddDADD("DSUB", 3);
  3797.         AddDABS("DTOF", 4);
  3798.         AddDABS("DTOI", 5);
  3799.         AddDABS("DTOU", 6);
  3800.         AddFTOD("FTOD", 0);
  3801.         AddFTOD("ITOD", 1);
  3802.         AddMVFDC("MVFDC", 0);
  3803.         AddMVFDR("MVFDR", 0);
  3804.         AddMVFDC("MVTDC", 1);
  3805.         AddFTOD("UTOD", 2);
  3806.  
  3807.         /* Pseudo Instructions */
  3808. #ifdef COMPAT
  3809.         AddInstTable(InstTable, "ENDIAN", 0, DecodeENDIAN);
  3810.         AddBLK("BLKB", 1);
  3811.         AddBLK("BLKW", 2);
  3812.         AddBLK("BLKL", 4);
  3813.         AddBLK("BLKD", 8);
  3814.         AddInstTable(InstTable, "BYTE", eIntPseudoFlag_LittleEndian | eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString, DecodeIntelDB);
  3815.         AddInstTable(InstTable, "WORD", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowInt, DecodeIntelDW);
  3816.         AddInstTable(InstTable, "LWORD", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowInt, DecodeIntelDD);
  3817.         AddInstTable(InstTable, "FLOAT", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowFloat, DecodeIntelDD);
  3818.         AddInstTable(InstTable, "DOUBLE", eIntPseudoFlag_DynEndian | eIntPseudoFlag_AllowFloat, DecodeIntelDQ);
  3819. #endif
  3820.  
  3821.         StrCompAlloc(&Temp1, STRINGSIZE);
  3822.         StrCompAlloc(&Temp2, STRINGSIZE);
  3823. }
  3824.  
  3825. static void DeinitFields(void)
  3826. {
  3827.         StrCompFree(&Temp2);
  3828.         StrCompFree(&Temp1);
  3829.  
  3830.         DestroyInstTable(InstTable);
  3831. }
  3832.  
  3833. /*---------------------------------------------------------------------------*/
  3834.  
  3835. static void MakeCode_RX(void)
  3836. {
  3837.         if (!LookupInstTable(InstTable, OpPart.str.p_str))
  3838.                 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  3839. }
  3840.  
  3841. static Boolean IsDef_RX(void)
  3842. {
  3843.         return False;
  3844. }
  3845.  
  3846. static void SwitchFrom_RX(void)
  3847. {
  3848.         DeinitFields();
  3849. }
  3850.  
  3851. static void SwitchTo_RX(void *pUser)
  3852. {
  3853.         const TFamilyDescr *pDescr;
  3854.  
  3855.         TurnWords = False;
  3856.         SetIntConstMode(eIntConstModeIntel);
  3857.  
  3858.         pDescr = FindFamilyByName("RX");
  3859.         PCSymbol = "$";
  3860.         HeaderID = pDescr->Id;
  3861.         NOPCode = 0x03;
  3862.         DivideChars = ",";
  3863.         HasAttrs = True;
  3864.         AttrChars = ".";
  3865.  
  3866.         ValidSegs = (1 << SegCode);
  3867.         Grans[SegCode] = 1;
  3868.         ListGrans[SegCode] = 1;
  3869.         SegInits[SegCode] = 0x0000;
  3870.         SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
  3871.  
  3872.         MakeCode = MakeCode_RX;
  3873.         IsDef = IsDef_RX;
  3874.         SwitchFrom = SwitchFrom_RX;
  3875.         InitFields();
  3876.         onoff_supmode_add();
  3877.         onoff_bigendian_add();
  3878.  
  3879.         pCurrCPUProps = (const tCPUProps *)pUser;
  3880. }
  3881.  
  3882. static const tCPUProps CPUProps[] =
  3883. {
  3884.         /* Group   InsSet FLT    DBL    RegB MVTIPL */
  3885.         { "RXV1",  eRXv1, True,  False, 0,   True  },   /* Generic RXv1 (Full option) */
  3886.         { "RX110", eRXv1, False, False, 0,   True  },
  3887.         { "RX111", eRXv1, False, False, 0,   True  },
  3888.         { "RX113", eRXv1, False, False, 0,   True  },
  3889.         { "RX130", eRXv1, False, False, 0,   True  },
  3890.         { "RX210", eRXv1, False, False, 0,   True  },
  3891.         { "RX21A", eRXv1, False, False, 0,   True  },
  3892.         { "RX220", eRXv1, False, False, 0,   True  },
  3893.         { "RX610", eRXv1, True,  False, 0,   False },
  3894.         { "RX621", eRXv1, True,  False, 0,   True  },
  3895.         { "RX62N", eRXv1, True,  False, 0,   True  },
  3896.         { "RX630", eRXv1, True,  False, 0,   True  },
  3897.         { "RX631", eRXv1, True,  False, 0,   True  },
  3898.  
  3899.         { "RXV2",  eRXv2, True,  False, 0,   True  },   /* Generic RXv2 */
  3900.         { "RX140", eRXv2, True,  False, 0,   True  },
  3901.         { "RX230", eRXv2, True,  False, 0,   True  },
  3902.         { "RX231", eRXv2, True,  False, 0,   True  },
  3903.         { "RX64M", eRXv2, True,  False, 0,   True  },
  3904.         { "RX651", eRXv2, True,  False, 0,   True  },
  3905.        
  3906.         { "RXV3",  eRXv3, True,  True,  256, True  },   /* Generic RXv3 (Full option) */
  3907.         { "RX660", eRXv3, True,  False, 16,  True  },
  3908.         { "RX671", eRXv3, True,  True,  16,  True  },
  3909.         { "RX72M", eRXv3, True,  True,  16,  True  },
  3910.         { "RX72N", eRXv3, True,  True,  16,  True  },
  3911.  
  3912.         { ""     ,    eRXv1, False, False, 0,   False }
  3913. };
  3914.  
  3915. void coderx_init(void)
  3916. {
  3917.         const tCPUProps *pProp;
  3918.  
  3919.         for (pProp = CPUProps; pProp->Name[0]; pProp++)
  3920.                 (void)AddCPUUser(pProp->Name, SwitchTo_RX, (void *)pProp, NULL);
  3921.  
  3922.         AddCopyright("Renesas RX Generator (C) 2023 Haruo Asano");
  3923. }
  3924.