Subversion Repositories pentevo

Rev

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

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