Subversion Repositories pentevo

Rev

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

  1. /* codens32k.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Code Generator National Semiconductor NS32000                             */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include "bpemu.h"
  14. #include "strutil.h"
  15. #include "ieeefloat.h"
  16.  
  17. #include "headids.h"
  18. #include "asmdef.h"
  19. #include "asmsub.h"
  20. #include "asmpars.h"
  21. #include "asmallg.h"
  22. #include "onoff_common.h"
  23. #include "asmitree.h"
  24. #include "codevars.h"
  25. #include "codepseudo.h"
  26. #include "intpseudo.h"
  27.  
  28. #include "codepseudo.h"
  29. #include "intpseudo.h"
  30. #include "codens32k.h"
  31.  
  32. typedef enum
  33. {
  34.   eCoreNone,
  35.   eCoreGen1,
  36.   eCoreGen1Ext,
  37.   eCoreGenE,
  38.   eCoreGen2,
  39.   eCoreCount
  40. } tCore;
  41.  
  42. typedef enum
  43. {
  44.   eFPUNone,
  45.   eFPU16081,
  46.   eFPU32081,
  47.   eFPU32181,
  48.   eFPU32381,
  49.   eFPU32580,
  50.   eFPUCount
  51. } tFPU;
  52.  
  53. typedef enum
  54. {
  55.   ePMMUNone,
  56.   ePMMU16082,
  57.   ePMMU32082,
  58.   ePMMU32382,
  59.   ePMMU32532,
  60.   ePMMUCount
  61. } tPMMU;
  62.  
  63. typedef struct
  64. {
  65.   const char *pName;
  66.   Byte CPUType, DefFPU, DefPMMU;
  67.   IntType MemIntType;
  68. } tCPUProps;
  69.  
  70. static char FPUNames[eFPUCount][8] = { "OFF", "NS16081", "NS32081", "NS32181", "NS32381", "NS32580" };
  71.  
  72. static char PMMUNames[ePMMUCount][8] = { "OFF", "NS16082", "NS32082", "NS32382", "NS32532" };
  73.  
  74. typedef struct
  75. {
  76.   const char *pName;
  77.   Word Code, Mask;
  78.   Boolean Privileged;
  79. } tCtlReg;
  80.  
  81. #ifdef __cplusplus
  82. #include "codens32k.hpp"
  83. #endif
  84.  
  85. #define MAllowImm (1 << 0)
  86. #define MAllowReg (1 << 1)
  87. #define MAllowRegPair (1 << 2)
  88.  
  89. static tCtlReg *CtlRegs, *MMURegs;
  90.  
  91. static tSymbolSize OpSize;
  92. static const tCPUProps *pCurrCPUProps;
  93. static tFPU MomFPU;
  94. static tPMMU MomPMMU;
  95. static Boolean CustomAvail;
  96.  
  97. /*!------------------------------------------------------------------------
  98.  * \fn     SetOpSize(tSymbolSize Size, const tStrComp *pArg)
  99.  * \brief  set (new) operand size of instruction
  100.  * \param  Size size to set
  101.  * \param  pArg source argument size was deduced from
  102.  * \return True if no conflict
  103.  * ------------------------------------------------------------------------ */
  104.  
  105. static Boolean SetOpSize(tSymbolSize Size, const tStrComp *pArg)
  106. {
  107.   if (OpSize == eSymbolSizeUnknown)
  108.     OpSize = Size;
  109.   else if ((Size != eSymbolSizeUnknown) && (Size != OpSize))
  110.   {
  111.     WrStrErrorPos(ErrNum_ConfOpSizes, pArg);
  112.     return False;
  113.   }
  114.   return True;
  115. }
  116.  
  117. /*!------------------------------------------------------------------------
  118.  * \fn     ResetOpSize(void)
  119.  * \brief  back to undefined op size
  120.  * \return constat True
  121.  * ------------------------------------------------------------------------ */
  122.  
  123. static Boolean ResetOpSize(void)
  124. {
  125.   OpSize = eSymbolSizeUnknown;
  126.   return True;
  127. }
  128.  
  129. /*!------------------------------------------------------------------------
  130.  * \fn     CheckCore(unsigned CoreMask)
  131.  * \brief  check for CPU/Core requirement
  132.  * \param  CoreMask bit mask of core type supported
  133.  * \return True if fulfilled
  134.  * ------------------------------------------------------------------------ */
  135.  
  136. static Boolean CheckCore(unsigned CoreMask)
  137. {
  138.   if ((CoreMask >> pCurrCPUProps->CPUType) & 1)
  139.     return True;
  140.   WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
  141.   return False;
  142. }
  143.  
  144. /*!------------------------------------------------------------------------
  145.  * \fn     CheckSup(Boolean Required, const tStrComp *pArg)
  146.  * \brief  check whether supervisor mode requirement is violated
  147.  * \param  Required is supervisor mode required?
  148.  * \param  pArg source argument
  149.  * \return False if violated
  150.  * ------------------------------------------------------------------------ */
  151.  
  152. static Boolean CheckSup(Boolean Required, const tStrComp *pArg)
  153. {
  154.   if (!SupAllowed && Required)
  155.   {
  156.     WrStrErrorPos(ErrNum_PrivOrder, pArg);
  157.     return False;
  158.   }
  159.   return True;
  160. }
  161.  
  162. /*!------------------------------------------------------------------------
  163.  * \fn     SetMomFPU(tFPU NewFPU)
  164.  * \brief  set new FPU type in use
  165.  * \param  NewFPU new type
  166.  * ------------------------------------------------------------------------ */
  167.  
  168. static void SetMomFPU(tFPU NewFPU)
  169. {
  170.   switch ((MomFPU = NewFPU))
  171.   {
  172.     case eFPU16081:
  173.     case eFPU32081:
  174.     case eFPU32181:
  175.     case eFPU32381:
  176.     case eFPU32580:
  177.     {
  178.       tStrComp TmpComp;
  179.       String TmpCompStr;
  180.  
  181.       StrCompMkTemp(&TmpComp, TmpCompStr, sizeof(TmpCompStr));
  182.       strmaxcpy(TmpCompStr, MomFPUIdentName, sizeof(TmpCompStr));
  183.       strmaxcpy(MomFPUIdent, FPUNames[MomFPU], sizeof(MomFPUIdent));
  184.       EnterStringSymbol(&TmpComp, FPUNames[MomFPU], True);
  185.       break;
  186.     }
  187.     default:
  188.       break;
  189.   }
  190. }
  191.  
  192. /*!------------------------------------------------------------------------
  193.  * \fn     SetMomPMMU(tFPU NewPMMU)
  194.  * \brief  set new PMMU type in use
  195.  * \param  NewPMMU new type
  196.  * ------------------------------------------------------------------------ */
  197.  
  198. static void SetMomPMMU(tPMMU NewPMMU)
  199. {
  200.   switch ((MomPMMU = NewPMMU))
  201.   {
  202.     case ePMMU16082:
  203.     case ePMMU32082:
  204.     case ePMMU32382:
  205.     case ePMMU32532:
  206.     {
  207.       tStrComp TmpComp;
  208.       String TmpCompStr;
  209.  
  210.       StrCompMkTemp(&TmpComp, TmpCompStr, sizeof(TmpCompStr));
  211.       strmaxcpy(TmpCompStr, MomPMMUIdentName, sizeof(TmpCompStr));
  212.       strmaxcpy(MomPMMUIdent, PMMUNames[MomPMMU], sizeof(MomPMMUIdent));
  213.       EnterStringSymbol(&TmpComp, PMMUNames[MomPMMU], True);
  214.       break;
  215.     }
  216.     default:
  217.       break;
  218.   }
  219. }
  220.  
  221. /*!------------------------------------------------------------------------
  222.  * \fn     CheckFPUAvail(void)
  223.  * \brief  check whether FPU instructions are enabled
  224.  * \return False if not
  225.  * ------------------------------------------------------------------------ */
  226.  
  227. static Boolean CheckFPUAvail(tFPU MinFPU)
  228. {
  229.   if (!FPUAvail)
  230.   {
  231.     WrStrErrorPos(ErrNum_FPUNotEnabled, &OpPart);
  232.     return False;
  233.   }
  234.   else if (MomFPU < MinFPU)
  235.   {
  236.     WrStrErrorPos(ErrNum_FPUInstructionNotSupported, &OpPart);
  237.     return False;
  238.   }
  239.  
  240.   return True;
  241. }
  242.  
  243. /*!------------------------------------------------------------------------
  244.  * \fn     CheckPMMUAvail(void)
  245.  * \brief  check whether PMMU instructions are enabled
  246.  * \return False if not
  247.  * ------------------------------------------------------------------------ */
  248.  
  249. static Boolean CheckPMMUAvail(void)
  250. {
  251.   if (!PMMUAvail)
  252.   {
  253.     WrStrErrorPos(ErrNum_PMMUNotEnabled, &OpPart);
  254.     return False;
  255.   }
  256.   return True;
  257. }
  258.  
  259. /*!------------------------------------------------------------------------
  260.  * \fn     CheckCustomAvail(void)
  261.  * \brief  check whether Custom instructions are enabled
  262.  * \return False if not
  263.  * ------------------------------------------------------------------------ */
  264.  
  265. static Boolean CheckCustomAvail(void)
  266. {
  267.   if (!CustomAvail)
  268.   {
  269.     WrStrErrorPos(ErrNum_CustomNotEnabled, &OpPart);
  270.     return False;
  271.   }
  272.   return True;
  273. }
  274.  
  275. /*--------------------------------------------------------------------------*/
  276. /* Register Handling */
  277.  
  278. static const char MemRegNames[][3] = { "FP", "SP", "SB" };
  279. #define MemRegCount (sizeof(MemRegNames) / sizeof(*MemRegNames))
  280.  
  281. /*!------------------------------------------------------------------------
  282.  * \fn     DecodeRegCore(const char *pArg, Word *pValue, tSymbolSize *pSize)
  283.  * \brief  check whether argument describes a register
  284.  * \param  pArg source argument
  285.  * \param  pValue register number if yes
  286.  * \param  pSize register size if yes
  287.  * \return True if it is
  288.  * ------------------------------------------------------------------------ */
  289.  
  290. static Boolean DecodeRegCore(const char *pArg, Word *pRegNum, tSymbolSize *pRegSize)
  291. {
  292.   unsigned z;
  293.  
  294.   for (z = 0; z < MemRegCount; z++)
  295.     if (!as_strcasecmp(pArg, MemRegNames[z]))
  296.     {
  297.       *pRegNum = z + 8;
  298.       *pRegSize = eSymbolSize32Bit;
  299.       return True;
  300.     }
  301.  
  302.   if ((strlen(pArg) != 2) || (pArg[1] < '0') || (pArg[1] > '7'))
  303.     return False;
  304.   *pRegNum = pArg[1] - '0';
  305.  
  306.   switch (as_toupper(*pArg))
  307.   {
  308.     case 'F': *pRegSize = eSymbolSizeFloat32Bit; return True;
  309.     case 'R': *pRegSize = eSymbolSize32Bit; return True;
  310.     case 'L': *pRegSize = eSymbolSizeFloat64Bit; return True;
  311.     default:
  312.       return False;
  313.   }
  314. }
  315.  
  316. /*!------------------------------------------------------------------------
  317.  * \fn     DissectReg_NS32K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  318.  * \brief  dissect register symbols - NS32000 variant
  319.  * \param  pDest destination buffer
  320.  * \param  DestSize destination buffer size
  321.  * \param  Value numeric register value
  322.  * \param  InpSize register size
  323.  * ------------------------------------------------------------------------ */
  324.  
  325. static void DissectReg_NS32K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  326. {
  327.   switch (InpSize)
  328.   {
  329.     case eSymbolSize32Bit:
  330.       if (Value < 8)
  331.         as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
  332.       else if (Value < 8 + MemRegCount)
  333.         as_snprintf(pDest, DestSize, "%s", MemRegNames[Value - 8]);
  334.       else
  335.         goto unknown;
  336.       break;
  337.     case eSymbolSizeFloat32Bit:
  338.       as_snprintf(pDest, DestSize, "F%u", (unsigned)Value);
  339.       break;
  340.     case eSymbolSizeFloat64Bit:
  341.       as_snprintf(pDest, DestSize, "L%u", (unsigned)Value);
  342.       break;
  343.     default:
  344.     unknown:
  345.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  346.   }
  347. }
  348.  
  349. /*!------------------------------------------------------------------------
  350.  * \fn     DecodeReg(const tStrComp *pArg, Word *pValue, tSymbolSize *pSize, tSymbolSize ChkRegSize, Boolean MustBeReg)
  351.  * \brief  check whether argument is a CPU register or user-defined register alias
  352.  * \param  pArg argument
  353.  * \param  pValue resulting register # if yes
  354.  * \param  pSize resulting register size if yes
  355.  * \param  ChkReqSize explicitly request certain register size
  356.  * \param  MustBeReg expecting register or maybe not?
  357.  * \return reg eval result
  358.  * ------------------------------------------------------------------------ */
  359.  
  360. static Boolean MatchRegSize(tSymbolSize IsSize, tSymbolSize ReqSize)
  361. {
  362.   return (ReqSize == eSymbolSizeUnknown)
  363.       || (IsSize == ReqSize)
  364.       || ((ReqSize == eSymbolSizeFloat64Bit) && (IsSize == eSymbolSizeFloat32Bit));
  365. }
  366.  
  367. static tRegEvalResult DecodeReg(const tStrComp *pArg, Word *pValue, tSymbolSize *pSize, tSymbolSize ChkRegSize, Boolean MustBeReg)
  368. {
  369.   tEvalResult EvalResult;
  370.   tRegEvalResult RegEvalResult;
  371.  
  372.   if (DecodeRegCore(pArg->str.p_str, pValue, &EvalResult.DataSize))
  373.     RegEvalResult = eIsReg;
  374.   else
  375.   {
  376.     tRegDescr RegDescr;
  377.  
  378.     RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
  379.     if (eIsReg == RegEvalResult)
  380.       *pValue = RegDescr.Reg;
  381.   }
  382.  
  383.   if ((RegEvalResult == eIsReg) && !MatchRegSize(EvalResult.DataSize, ChkRegSize))
  384.   {
  385.     WrStrErrorPos(ErrNum_InvOpSize, pArg);
  386.     RegEvalResult = MustBeReg ? eIsNoReg : eRegAbort;
  387.   }
  388.  
  389.   if (pSize) *pSize = EvalResult.DataSize;
  390.   return RegEvalResult;
  391. }
  392.  
  393. /*!------------------------------------------------------------------------
  394.  * \fn     DecodeCtlReg(const tStrComp *pArg, Word *pResult)
  395.  * \brief  decode control processor register
  396.  * \param  pArg source argument
  397.  * \param  pResult result buffer
  398.  * \return True if src expr is a register
  399.  * ------------------------------------------------------------------------ */
  400.  
  401. static Boolean DecodeCtlReg(const tStrComp *pArg, Word *pResult)
  402. {
  403.   unsigned z;
  404.  
  405.   for (z = 0; CtlRegs[z].pName; z++)
  406.     if (!as_strcasecmp(pArg->str.p_str, CtlRegs[z].pName))
  407.     {
  408.       *pResult = CtlRegs[z].Code;
  409.       return CheckSup(CtlRegs[z].Privileged, pArg);
  410.     }
  411.   WrStrErrorPos(ErrNum_InvReg, pArg);
  412.   return False;
  413. }
  414.  
  415. /*!------------------------------------------------------------------------
  416.  * \fn     DecodeMMUReg(const tStrComp *pArg, Word *pResult)
  417.  * \brief  decode MMU register
  418.  * \param  pArg source argument
  419.  * \param  pResult result buffer
  420.  * \return True if src expr is a register
  421.  * ------------------------------------------------------------------------ */
  422.  
  423. static Boolean DecodeMMUReg(const tStrComp *pArg, Word *pResult)
  424. {
  425.   unsigned z;
  426.  
  427.   for (z = 0; MMURegs[z].pName; z++)
  428.     if (!as_strcasecmp(pArg->str.p_str, MMURegs[z].pName))
  429.     {
  430.       if (!((MMURegs[z].Mask >> MomPMMU) & 1))
  431.       {
  432.         WrStrErrorPos(ErrNum_InvPMMUReg, pArg);
  433.         return False;
  434.       }
  435.       *pResult = MMURegs[z].Code;
  436.       return CheckSup(MMURegs[z].Privileged, pArg);
  437.     }
  438.   WrStrErrorPos(ErrNum_InvPMMUReg, pArg);
  439.   return False;
  440. }
  441.  
  442. /*!------------------------------------------------------------------------
  443.  * \fn     DecodeRegList(const tStrComp *pArg, Boolean BitRev, Byte *pResult)
  444.  * \brief  Decode Register List
  445.  * \param  pArg Source Argument
  446.  * \param  BitRev Reverse Bit Order, i.e. R0->Bit 7 ?
  447.  * \param  pResult Result Buffer
  448.  * \return True if successfully parsed
  449.  * ------------------------------------------------------------------------ */
  450.  
  451. static Boolean DecodeRegList(const tStrComp *pArg, Boolean BitRev, Byte *pResult)
  452. {
  453.   tStrComp Part, Remainder;
  454.   int l = strlen(pArg->str.p_str);
  455.   Word Reg;
  456.   char *pSep;
  457.  
  458.   if ((l < 2)
  459.    || (pArg->str.p_str[0] != '[')
  460.    || (pArg->str.p_str[l - 1] != ']'))
  461.   {
  462.     WrStrErrorPos(ErrNum_InvRegList, pArg);
  463.     return False;
  464.   }
  465.  
  466.   *pResult = 0;
  467.   StrCompRefRight(&Part, pArg, 1);
  468.   StrCompShorten(&Part, 1);
  469.   while (True)
  470.   {
  471.     KillPrefBlanksStrCompRef(&Part);
  472.     pSep = strchr(Part.str.p_str, ',');
  473.     if (pSep)
  474.       StrCompSplitRef(&Part, &Remainder, &Part, pSep);
  475.     KillPostBlanksStrComp(&Part);
  476.     if (DecodeReg(&Part, &Reg, NULL, eSymbolSize32Bit, True) != eIsReg)
  477.       return False;
  478.     if (Reg >= 8)
  479.     {
  480.       WrStrErrorPos(ErrNum_InvReg, &Part);
  481.       return False;
  482.     }
  483.     *pResult |= 1 << (BitRev ? 7 - Reg : Reg);
  484.     if (pSep)
  485.       Part = Remainder;
  486.     else
  487.       break;
  488.   }
  489.   return True;
  490. }
  491.  
  492. /*!------------------------------------------------------------------------
  493.  * \fn     DecodeCfgList(const tStrComp *pArg, Byte *pResult)
  494.  * \brief  Decode Config Option List
  495.  * \param  pArg Source Argument
  496.  * \param  pResult Result Buffer
  497.  * \return True if successfully parsed
  498.  * ------------------------------------------------------------------------ */
  499.  
  500. static Boolean DecodeCfgList(const tStrComp *pArg, Byte *pResult)
  501. {
  502.   tStrComp Part, Remainder;
  503.   int l = strlen(pArg->str.p_str);
  504.   char *pSep;
  505.   const char Opts[] = "IFMC", *pOpt;
  506.  
  507.   if ((l < 2)
  508.    || (pArg->str.p_str[0] != '[')
  509.    || (pArg->str.p_str[l - 1] != ']'))
  510.   {
  511.     WrStrErrorPos(ErrNum_InvCfgList, pArg);
  512.     return False;
  513.   }
  514.  
  515.   *pResult = 0;
  516.   StrCompRefRight(&Part, pArg, 1);
  517.   StrCompShorten(&Part, 1);
  518.   while (True)
  519.   {
  520.     KillPrefBlanksStrCompRef(&Part);
  521.     pSep = strchr(Part.str.p_str, ',');
  522.     if (pSep)
  523.       StrCompSplitRef(&Part, &Remainder, &Part, pSep);
  524.     KillPostBlanksStrComp(&Part);
  525.     switch (strlen(Part.str.p_str))
  526.     {
  527.       case 0:
  528.         break;
  529.       case 1:
  530.         pOpt = strchr(Opts, as_toupper(*Part.str.p_str));
  531.         if (pOpt)
  532.         {
  533.           *pResult |= 1 << (pOpt - Opts);
  534.           break;
  535.         }
  536.         /* else fall-through */
  537.       default:
  538.         WrStrErrorPos(ErrNum_InvCfgList, &Part);
  539.         return False;
  540.     }
  541.     if (pSep)
  542.       Part = Remainder;
  543.     else
  544.       break;
  545.   }
  546.   return True;
  547. }
  548.  
  549. /*--------------------------------------------------------------------------*/
  550. /* Address Decoder */
  551.  
  552. enum
  553. {
  554.   AddrCode_Reg = 0x00,
  555.   AddrCode_Relative = 0x08,
  556.   AddrCode_MemRelative = 0x10,
  557.   AddrCode_Reserved = 0x13,
  558.   AddrCode_Immediate = 0x14,
  559.   AddrCode_Absolute = 0x15,
  560.   AddrCode_External = 0x16,
  561.   AddrCode_TOS = 0x17,
  562.   AddrCode_MemSpace = 0x18,
  563.   AddrCode_ScaledIndex = 0x1c
  564. };
  565.  
  566. typedef struct
  567. {
  568.   Byte Code;
  569.   Byte Index[1], Disp[8];
  570.   unsigned IndexCnt, DispCnt;
  571. } tAdrVals;
  572.  
  573. static void ClearAdrVals(tAdrVals *pVals)
  574. {
  575.   pVals->Code = AddrCode_Reserved;
  576.   pVals->IndexCnt = pVals->DispCnt = 0;
  577. }
  578.  
  579. /*!------------------------------------------------------------------------
  580.  * \fn     EncodeDisplacement(LongInt Disp, tAdrVals *pDest, tErrorNum ErrorNum, const tStrComp *pArg)
  581.  * \brief  encode signed displacement
  582.  * \param  Disp displacement to encode
  583.  * \param  pDest destination buffer
  584.  * \param  ErrorNum error msg to print if out of range
  585.  * \param  pArg source argument for error messages
  586.  * \return True if successfully encoded
  587.  * ------------------------------------------------------------------------ */
  588.  
  589. static Boolean EncodeDisplacement(LongInt Disp, tAdrVals *pDest, tErrorNum ErrorNum, const tStrComp *pArg)
  590. {
  591.   if ((Disp >= -64) && (Disp <= 63))
  592.   {
  593.     pDest->Disp[pDest->DispCnt++] = Disp & 0x7f;
  594.     return True;
  595.   }
  596.   else if ((Disp >= -8192) && (Disp <= 8191))
  597.   {
  598.     pDest->Disp[pDest->DispCnt++] = 0x80 | ((Disp >> 8) & 0x3f);
  599.     pDest->Disp[pDest->DispCnt++] = Disp & 0xff;
  600.     return True;
  601.   }
  602.   else if ((Disp >= -520093696) && (Disp <= 536870911))
  603.   {
  604.     Byte HiByte = 0xc0 | ((Disp >> 24) & 0x3f);
  605.  
  606.     if (HiByte == 0xe0)
  607.       goto error;
  608.  
  609.     pDest->Disp[pDest->DispCnt++] = HiByte;
  610.     pDest->Disp[pDest->DispCnt++] = (Disp >> 16) & 0xff;
  611.     pDest->Disp[pDest->DispCnt++] = (Disp >> 8) & 0xff;
  612.     pDest->Disp[pDest->DispCnt++] = Disp & 0xff;
  613.     return True;
  614.   }
  615.   else
  616.   {
  617. error:
  618.     WrStrErrorPos(ErrorNum, pArg);
  619.     return False;
  620.   }
  621. }
  622.  
  623. /*!------------------------------------------------------------------------
  624.  * \fn     EncodePCRel(const tStrComp *pArg, tAdrVals *pDest)
  625.  * \brief  PC-relative encoding of address
  626.  * \param  pArg address in source
  627.  * \param  pDest dest buffer
  628.  * \return True if success
  629.  * ------------------------------------------------------------------------ */
  630.  
  631. static Boolean EncodePCRel(const tStrComp *pArg, tAdrVals *pDest)
  632. {
  633.   tEvalResult EvalResult;
  634.   LongInt Dist = EvalStrIntExpressionWithResult(pArg, pCurrCPUProps->MemIntType, &EvalResult) - EProgCounter();
  635.  
  636.   ClearAdrVals(pDest);
  637.   if (!EvalResult.OK
  638.    || !EncodeDisplacement(Dist, pDest, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_JmpDistTooBig, pArg))
  639.     return False;
  640.  
  641.   pDest->Code = AddrCode_MemSpace + 3;
  642.   return True;
  643. }
  644.  
  645. /*!------------------------------------------------------------------------
  646.  * \fn     DecodeAdr(tStrComp *pArg, tAdrVals *pDest, unsigned AddrModeMask)
  647.  * \brief  decode address expression
  648.  * \param  pArg source argument
  649.  * \param  pDest dest buffer
  650.  * \param  AddrModeMask allow immediate/register addressing?
  651.  * \return True if success
  652.  * ------------------------------------------------------------------------ */
  653.  
  654. static Boolean DecodeAdr(const tStrComp *pArg, tAdrVals *pDest, Boolean AddrModeMask)
  655. {
  656.   Byte IndexCode = 0;
  657.   Boolean OK, NeedEvenReg;
  658.   const Boolean IsFloat = (OpSize == eSymbolSizeFloat32Bit) || (OpSize == eSymbolSizeFloat64Bit);
  659.   Word RegValue, IndexReg = 0;
  660.   int ArgLen, SplitPos;
  661.   tStrComp BaseArg;
  662.   const char IndexChars[] = "BWDQ";
  663.   char *pSplit, *pSplit2, Scale;
  664.  
  665.   ClearAdrVals(pDest);
  666.  
  667.   /* split off scaled indexing, which is orthogonal to (almost) all other modes */
  668.  
  669.   pSplit = MatchCharsRev(pArg->str.p_str, " : ? ] ", IndexChars, &Scale);
  670.   pSplit2 = (pSplit && (pSplit > pArg->str.p_str))
  671.           ? FindOpeningParenthese(pArg->str.p_str, pSplit - 1, "[]")
  672.           : NULL;
  673.   if (pSplit && pSplit2)
  674.   {
  675.     tStrComp Mid, Right;
  676.     const char *pScaleIndex;
  677.  
  678.     StrCompSplitRef(&BaseArg, &Right, pArg, pSplit);
  679.     StrCompSplitRef(&BaseArg, &Mid, &BaseArg, pSplit2);
  680.     KillPrefBlanksStrCompRef(&Mid);
  681.     KillPostBlanksStrComp(&BaseArg);
  682.     pArg = &BaseArg;
  683.  
  684.     pScaleIndex = strchr(IndexChars, as_toupper(Scale));
  685.     if (!pScaleIndex)
  686.     {
  687.       WrStrErrorPos(ErrNum_InvScale, &Right);
  688.       return False;
  689.     }
  690.     IndexCode = AddrCode_ScaledIndex + (pScaleIndex - IndexChars);
  691.     if ((DecodeReg(&Mid, &IndexReg, NULL, eSymbolSize32Bit, True) == eIsReg)
  692.      && (IndexReg >= 8))
  693.     {
  694.       WrStrErrorPos(ErrNum_InvReg, &Mid);
  695.       return False;
  696.     }
  697.  
  698.     /* Immediate cannot be combined with scaling, so disallow regardless of caller's
  699.        preference: */
  700.  
  701.     AddrModeMask &= ~MAllowImm;
  702.   }
  703.  
  704.   /* absolute: */
  705.  
  706.   if (*pArg->str.p_str == '@')
  707.   {
  708.     tStrComp Arg;
  709.     LongWord Addr;
  710.  
  711.     StrCompRefRight(&Arg, pArg, 1);
  712.     Addr = EvalStrIntExpression(&Arg, pCurrCPUProps->MemIntType, &OK);
  713.     if (!OK)
  714.       return False;
  715.  
  716.     /* On a CPU with non-32-bit address bus, addresses @ the upper end may be encoded
  717.        as negative 'displacements': */
  718.  
  719.     if ((pCurrCPUProps->MemIntType == UInt24)
  720.      && (Addr & 0x800000ul))
  721.       Addr |= 0xff000000ul;
  722.     if (EncodeDisplacement((LongInt)Addr, pDest, ErrNum_OverRange, &Arg))
  723.     {
  724.       pDest->Code = AddrCode_Absolute;
  725.       goto chk;
  726.     }
  727.     else
  728.       return False;
  729.   }
  730.  
  731.   /* TOS? */
  732.  
  733.   if (!as_strcasecmp(pArg->str.p_str, "TOS"))
  734.   {
  735.     pDest->Code = AddrCode_TOS;
  736.     goto chk;
  737.   }
  738.  
  739.   /* register? */
  740.  
  741.   if (IsFloat)
  742.     NeedEvenReg = (OpSize == eSymbolSizeFloat64Bit) && (MomFPU < eFPU32181);
  743.   else
  744.     NeedEvenReg = !!(AddrModeMask & MAllowRegPair);
  745.   switch (DecodeReg(pArg, &RegValue, NULL, IsFloat ? OpSize : eSymbolSize32Bit, False))
  746.   {
  747.     case eIsReg:
  748.       if (NeedEvenReg && (RegValue & 1))
  749.       {
  750.         WrStrErrorPos(ErrNum_InvRegPair, pArg);
  751.         return False;
  752.       }
  753.       else if (!(AddrModeMask & (MAllowReg | MAllowRegPair)))
  754.       {
  755.         WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  756.         return False;
  757.       }
  758.       else
  759.       {
  760.         pDest->Code = AddrCode_Reg + RegValue;
  761.         goto chk;
  762.       }
  763.     case eIsNoReg:
  764.       break;
  765.     default:
  766.       return False;
  767.   }
  768.  
  769.   /* EXT mode */
  770.  
  771.   pSplit = MatchChars(pArg->str.p_str, " EXT (");
  772.   if (pSplit)
  773.   {
  774.     tStrComp Left, Mid, Right;
  775.     LongInt Disp1, Disp2 = 0;
  776.     Boolean OK;
  777.  
  778.     StrCompSplitRef(&Left, &Mid, pArg, pSplit - 1);
  779.     pSplit = FindClosingParenthese(Mid.str.p_str);
  780.     if (!pSplit)
  781.     {
  782.       WrStrErrorPos(ErrNum_BrackErr, pArg);
  783.       return False;
  784.     }
  785.     StrCompSplitRef(&Mid, &Right, &Mid, pSplit);
  786.     Disp1 = EvalStrIntExpression(&Mid, Int30, &OK);
  787.     if (!OK)
  788.       return False;
  789.     *(--Right.str.p_str) = '0'; Right.Pos.Len++; Right.Pos.StartCol--;
  790.     if (*Right.str.p_str)
  791.       Disp2 = EvalStrIntExpression(&Right, Int30, &OK);
  792.     if (!OK)
  793.       return False;
  794.  
  795.     pDest->Code = AddrCode_External;
  796.     if (!EncodeDisplacement(Disp1, pDest, ErrNum_OverRange, &Mid)
  797.      || !EncodeDisplacement(Disp2, pDest, ErrNum_OverRange, &Right))
  798.       return False;
  799.     goto chk;
  800.   }
  801.  
  802.   /* PC-relative */
  803.  
  804.   if (!strcmp(pArg->str.p_str, "*")
  805.    || MatchChars(pArg->str.p_str, "* ?", "+-", NULL))
  806.   {
  807.     LongInt Disp;
  808.     Boolean OK;
  809.  
  810.     *pArg->str.p_str = '0';
  811.     Disp = EvalStrIntExpression(pArg, Int30, &OK);
  812.     *pArg->str.p_str = '*';
  813.     if (!OK
  814.      || !EncodeDisplacement(Disp, pDest, ErrNum_OverRange, pArg))
  815.       return False;
  816.     pDest->Code = AddrCode_MemSpace + 3;
  817.     goto chk;
  818.   }
  819.  
  820.   /* disp(...)? */
  821.  
  822.   SplitPos = FindDispBaseSplit(pArg->str.p_str, &ArgLen);
  823.   if (SplitPos >= 0)
  824.   {
  825.     tStrComp OutDisp, InnerArg;
  826.     LongInt OutDispVal;
  827.     tEvalResult OutEvalResult;
  828.  
  829.     memset(&OutEvalResult, 0, sizeof(OutEvalResult));
  830.     StrCompSplitRef(&OutDisp, &InnerArg, pArg, &pArg->str.p_str[SplitPos]);
  831.     if (OutDisp.Pos.Len)
  832.     {
  833.       OutDispVal = EvalStrIntExpressionWithResult(&OutDisp, Int30, &OutEvalResult);
  834.       if (!OutEvalResult.OK)
  835.         return False;
  836.     }
  837.     else
  838.     {
  839.       OutEvalResult.OK = True;
  840.       OutDispVal = 0;
  841.     }
  842.  
  843.     StrCompShorten(&InnerArg, 1);
  844.     KillPrefBlanksStrCompRef(&InnerArg);
  845.     KillPostBlanksStrComp(&InnerArg);
  846.     switch (DecodeReg(&InnerArg, &RegValue, NULL, eSymbolSize32Bit, False))
  847.     {
  848.       case eIsReg: /* disp(Rn/FP/SP/SB) */
  849.         pDest->Code = (RegValue < 8) ? AddrCode_Relative + RegValue : AddrCode_MemSpace + (RegValue - 8);
  850.         if (!EncodeDisplacement(OutDispVal, pDest, ErrNum_OverRange, &OutDisp))
  851.           return False;
  852.         goto chk;
  853.       IsPCRel:
  854.         if (EncodeDisplacement(OutDispVal - EProgCounter(), pDest, mFirstPassUnknownOrQuestionable(OutEvalResult.Flags) ? ErrNum_None : ErrNum_JmpDistTooBig, &OutDisp))
  855.           pDest->Code = AddrCode_MemSpace + 3;
  856.         goto chk;
  857.       case eIsNoReg:
  858.       {
  859.         tStrComp InDisp;
  860.         LongInt InDispVal = 0;
  861.  
  862.         if (!as_strcasecmp(InnerArg.str.p_str, "PC"))
  863.           goto IsPCRel;
  864.  
  865.         SplitPos = FindDispBaseSplit(InnerArg.str.p_str, &ArgLen);
  866.         if (SplitPos < 0)
  867.         {
  868.           WrStrErrorPos(ErrNum_InvAddrMode, &InnerArg);
  869.           return False;
  870.         }
  871.         StrCompSplitRef(&InDisp, &InnerArg, &InnerArg, &InnerArg.str.p_str[SplitPos]);
  872.         if (InDisp.Pos.Len)
  873.         {
  874.           InDispVal = EvalStrIntExpression(&InDisp, Int30, &OK);
  875.           if (!OK)
  876.             return False;
  877.         }
  878.  
  879.         StrCompShorten(&InnerArg, 1);
  880.         KillPrefBlanksStrCompRef(&InnerArg);
  881.         KillPostBlanksStrComp(&InnerArg);
  882.  
  883.         /* disp2(disp1(ext)) is an alias for EXT(disp1)+disp2 */
  884.  
  885.         if (!as_strcasecmp(InnerArg.str.p_str, "EXT"))
  886.         {
  887.           pDest->Code = AddrCode_External;
  888.         }
  889.  
  890.         /* disp2(disp1(FP/SP/SB)) */
  891.  
  892.         else
  893.         {
  894.           if (DecodeReg(&InnerArg, &RegValue, NULL, eSymbolSize32Bit, True) != eIsReg)
  895.             return False;
  896.           if (RegValue < 8)
  897.           {
  898.             WrStrErrorPos(ErrNum_InvReg, &InnerArg);
  899.             return False;
  900.           }
  901.           pDest->Code = AddrCode_MemRelative + (RegValue - 8);
  902.         }
  903.         if (!EncodeDisplacement(InDispVal, pDest, ErrNum_OverRange, &InDisp)
  904.          || !EncodeDisplacement(OutDispVal, pDest, ErrNum_OverRange, &OutDisp))
  905.           return False;
  906.         goto chk;
  907.       }
  908.       default:
  909.         return False;
  910.     }
  911.   }
  912.  
  913.   /* -> immediate or PC-relative */
  914.  
  915.   if (AddrModeMask & MAllowImm)
  916.   {
  917.     switch (OpSize)
  918.     {
  919.       case eSymbolSize8Bit:
  920.         pDest->Disp[0] = EvalStrIntExpression(pArg, Int8, &OK);
  921.         if (OK)
  922.           pDest->DispCnt = 1;
  923.         break;
  924.       case eSymbolSize16Bit:
  925.       {
  926.         Word Val = EvalStrIntExpression(pArg, Int16, &OK);
  927.         if (OK)
  928.         {
  929.           pDest->Disp[pDest->DispCnt++] = Hi(Val);
  930.           pDest->Disp[pDest->DispCnt++] = Lo(Val);
  931.         }
  932.         break;
  933.       }
  934.       case eSymbolSize32Bit:
  935.       {
  936.         LongWord Val = EvalStrIntExpression(pArg, Int32, &OK);
  937.         if (OK)
  938.         {
  939.           pDest->Disp[pDest->DispCnt++] = (Val >> 24) & 0xff;
  940.           pDest->Disp[pDest->DispCnt++] = (Val >> 16) & 0xff;
  941.           pDest->Disp[pDest->DispCnt++] = (Val >>  8) & 0xff;
  942.           pDest->Disp[pDest->DispCnt++] = (Val >>  0) & 0xff;
  943.         }
  944.         break;
  945.       }
  946.       case eSymbolSize64Bit:
  947.       {
  948.         LargeWord Val = EvalStrIntExpression(pArg, LargeIntType, &OK);
  949.         if (OK)
  950.         {
  951. #ifdef HAS64
  952.           pDest->Disp[pDest->DispCnt++] = (Val >> 56) & 0xff;
  953.           pDest->Disp[pDest->DispCnt++] = (Val >> 48) & 0xff;
  954.           pDest->Disp[pDest->DispCnt++] = (Val >> 40) & 0xff;
  955.           pDest->Disp[pDest->DispCnt++] = (Val >> 32) & 0xff;
  956. #else
  957.           pDest->Disp[pDest->DispCnt + 0] =
  958.           pDest->Disp[pDest->DispCnt + 1] =
  959.           pDest->Disp[pDest->DispCnt + 2] =
  960.           pDest->Disp[pDest->DispCnt + 3] = (Val & 0x80000000ul) ? 0xff : 0x00;
  961.           pDest->DispCnt += 4;
  962. #endif
  963.           pDest->Disp[pDest->DispCnt++] = (Val >> 24) & 0xff;
  964.           pDest->Disp[pDest->DispCnt++] = (Val >> 16) & 0xff;
  965.           pDest->Disp[pDest->DispCnt++] = (Val >>  8) & 0xff;
  966.           pDest->Disp[pDest->DispCnt++] = (Val >>  0) & 0xff;
  967.         }
  968.         break;
  969.       }
  970.       case eSymbolSizeFloat32Bit:
  971.       {
  972.         Double Val = EvalStrFloatExpression(pArg, Float32, &OK);
  973.         if (OK)
  974.         {
  975.           Double_2_ieee4(Val, pDest->Disp, True);
  976.           pDest->DispCnt = 4;
  977.         }
  978.         break;
  979.       }
  980.       case eSymbolSizeFloat64Bit:
  981.       {
  982.         Double Val = EvalStrFloatExpression(pArg, Float64, &OK);
  983.         if (OK)
  984.         {
  985.           Double_2_ieee8(Val, pDest->Disp, True);
  986.           pDest->DispCnt = 8;
  987.         }
  988.         break;
  989.       }
  990.       default:
  991.         WrStrErrorPos(ErrNum_UndefOpSizes, pArg);
  992.     }
  993.     if (pDest->DispCnt)
  994.       pDest->Code = AddrCode_Immediate;
  995.     else
  996.       return False;
  997.   }
  998.   else if (!EncodePCRel(pArg, pDest))
  999.     return False;
  1000.  
  1001. chk:
  1002.   /* if we have an index code, check it's not immedate, otherwise relocate */
  1003.  
  1004.   if (IndexCode)
  1005.   {
  1006.     if (pDest->Code == AddrCode_Immediate)
  1007.     {
  1008.       WrStrErrorPos(ErrNum_InvAddrMode, pArg);
  1009.       return False;
  1010.     }
  1011.     pDest->Index[pDest->IndexCnt++] = (pDest->Code << 3) | IndexReg;
  1012.     pDest->Code = IndexCode;
  1013.   }
  1014.   return True;
  1015. }
  1016.  
  1017. /*!------------------------------------------------------------------------
  1018.  * \fn     AppendIndex(const tAdrVals *pVals)
  1019.  * \brief  append optional index byte to code
  1020.  * \param  pVals encoded addressing mode
  1021.  * ------------------------------------------------------------------------ */
  1022.  
  1023. static void AppendIndex(const tAdrVals *pVals)
  1024. {
  1025.   if (pVals->IndexCnt)
  1026.   {
  1027.     memcpy(&BAsmCode[CodeLen], pVals->Index, pVals->IndexCnt);
  1028.     CodeLen += pVals->IndexCnt;
  1029.   }
  1030. }
  1031.  
  1032. /*!------------------------------------------------------------------------
  1033.  * \fn     AppendDisp(const tAdrVals *pVals)
  1034.  * \brief  append optional displacement to code
  1035.  * \param  pVals encoded addressing mode
  1036.  * ------------------------------------------------------------------------ */
  1037.  
  1038. static void AppendDisp(const tAdrVals *pVals)
  1039. {
  1040.   if (pVals->DispCnt)
  1041.   {
  1042.     memcpy(&BAsmCode[CodeLen], pVals->Disp, pVals->DispCnt);
  1043.     CodeLen += pVals->DispCnt;
  1044.   }
  1045. }
  1046.  
  1047. /*--------------------------------------------------------------------------*/
  1048. /* Helper Functions */
  1049.  
  1050. /*!------------------------------------------------------------------------
  1051.  * \fn     SizeCodeI(tSymbolSize Size)
  1052.  * \brief  transform (integer) operand size to i size in instruction
  1053.  * \param  Size Operand Size
  1054.  * \return Size Code
  1055.  * ------------------------------------------------------------------------ */
  1056.  
  1057. static LongWord SizeCodeI(tSymbolSize Size)
  1058. {
  1059.   switch (Size)
  1060.   {
  1061.     case eSymbolSize8Bit:
  1062.       return 0;
  1063.     case eSymbolSize16Bit:
  1064.       return 1;
  1065.     case eSymbolSize32Bit:
  1066.       return 3;
  1067.     default:
  1068.       return 2;
  1069.   }
  1070. }
  1071.  
  1072. /*!------------------------------------------------------------------------
  1073.  * \fn     SizeCodeF(tSymbolSize Size)
  1074.  * \brief  transform (float) operand size to f size in instruction
  1075.  * \param  Size Operand Size
  1076.  * \return Size Code
  1077.  * ------------------------------------------------------------------------ */
  1078.  
  1079. static LongWord SizeCodeF(tSymbolSize Size)
  1080. {
  1081.   switch (Size)
  1082.   {
  1083.     case eSymbolSizeFloat64Bit:
  1084.       return 0;
  1085.     case eSymbolSizeFloat32Bit:
  1086.       return 1;
  1087.     default:
  1088.       return 0xff;
  1089.   }
  1090. }
  1091.  
  1092. /*!------------------------------------------------------------------------
  1093.  * \fn     SizeCodeC(tSymbolSize Size)
  1094.  * \brief  transform (custom) operand size to c size in instruction
  1095.  * \param  Size Operand Size
  1096.  * \return Size Code
  1097.  * ------------------------------------------------------------------------ */
  1098.  
  1099. static LongWord SizeCodeC(tSymbolSize Size)
  1100. {
  1101.   switch (Size)
  1102.   {
  1103.     case eSymbolSize64Bit:
  1104.       return 0;
  1105.     case eSymbolSize32Bit:
  1106.       return 1;
  1107.     default:
  1108.       return 0xff;
  1109.   }
  1110. }
  1111.  
  1112. /*!------------------------------------------------------------------------
  1113.  * \fn     GetOpSizeFromCode(Word Code)
  1114.  * \brief  get operand size of instruction from insn name
  1115.  * \param  Code contains size in MSB
  1116.  * \return operand size
  1117.  * ------------------------------------------------------------------------ */
  1118.  
  1119. static tSymbolSize GetOpSizeFromCode(Word Code)
  1120. {
  1121.   Byte Size = Hi(Code) & 15;
  1122.  
  1123.   return (Size == 0xff) ? eSymbolSizeUnknown : (tSymbolSize)Size;
  1124. }
  1125.  
  1126. /*!------------------------------------------------------------------------
  1127.  * \fn     SetOpSizeFromCode(Word Code)
  1128.  * \brief  set operand size of instruction from insn code MSB
  1129.  * \param  Code contains size in MSB
  1130.  * \return True if success
  1131.  * ------------------------------------------------------------------------ */
  1132.  
  1133. static Boolean SetOpSizeFromCode(Word Code)
  1134. {
  1135.   return SetOpSize(GetOpSizeFromCode(Code), &OpPart);
  1136. }
  1137.  
  1138. /*!------------------------------------------------------------------------
  1139.  * \fn     SetFOpSizeFromCode(Word Code)
  1140.  * \brief  set FP operand size of instruction from insn code
  1141.  * \param  Code contains size in LSB
  1142.  * \return True if success
  1143.  * ------------------------------------------------------------------------ */
  1144.  
  1145. static Boolean SetFOpSizeFromCode(Word Code)
  1146. {
  1147.   return SetOpSize((Code & 1) ? eSymbolSizeFloat32Bit : eSymbolSizeFloat64Bit, &OpPart);
  1148. }
  1149.  
  1150. /*!------------------------------------------------------------------------
  1151.  * \fn     SetCOpSizeFromCode(Word Code)
  1152.  * \brief  set custom operand size of instruction from insn code
  1153.  * \param  Code contains size in LSB
  1154.  * \return True if success
  1155.  * ------------------------------------------------------------------------ */
  1156.  
  1157. static Boolean SetCOpSizeFromCode(Word Code)
  1158. {
  1159.   return SetOpSize((Code & 1) ? eSymbolSize32Bit : eSymbolSize64Bit, &OpPart);
  1160. }
  1161.  
  1162. /*!------------------------------------------------------------------------
  1163.  * \fn     PutCode(LongWord Code, unsigned Count)
  1164.  * \brief  write instruction opcode to output
  1165.  * \param  Code opcode to write
  1166.  * \param  Count # of bytes to write
  1167.  * ------------------------------------------------------------------------ */
  1168.  
  1169. static void PutCode(LongWord Code, unsigned Count)
  1170. {
  1171.   BAsmCode[CodeLen++] = Code & 0xff;
  1172.   while (Count > 1)
  1173.   {
  1174.     Code >>= 8;
  1175.     Count--;
  1176.     BAsmCode[CodeLen++] = Code & 0xff;
  1177.   }
  1178. }
  1179.  
  1180. /*!------------------------------------------------------------------------
  1181.  * \fn     ChkNoAttrPart(void)
  1182.  * \brief  check for no attribute part
  1183.  * \return True if no attribute
  1184.  * ------------------------------------------------------------------------ */
  1185.  
  1186. static Boolean ChkNoAttrPart(void)
  1187. {
  1188.   if (*AttrPart.str.p_str)
  1189.   {
  1190.     WrError(ErrNum_UseLessAttr);
  1191.     return False;
  1192.   }
  1193.   return True;
  1194. }
  1195.  
  1196. /*--------------------------------------------------------------------------*/
  1197. /* Instruction De/Encoders */
  1198.  
  1199. /*!------------------------------------------------------------------------
  1200.  * \fn     DecodeFixed(Word Code)
  1201.  * \brief  decode instructions without argument
  1202.  * \param  Code machine code
  1203.  * ------------------------------------------------------------------------ */
  1204.  
  1205. static void DecodeFixed(Word Code)
  1206. {
  1207.   if (ChkArgCnt(0, 0))
  1208.     PutCode(Code, !!Hi(Code));
  1209. }
  1210.  
  1211. /*!------------------------------------------------------------------------
  1212.  * \fn     DecodeFormat0(Word Code)
  1213.  * \brief  Decode Format 0 Instructions
  1214.  * \param  Code machine code
  1215.  * ------------------------------------------------------------------------ */
  1216.  
  1217. static void DecodeFormat0(Word Code)
  1218. {
  1219.   tAdrVals AdrVals;
  1220.  
  1221.   ClearAdrVals(&AdrVals);
  1222.   if (ChkArgCnt(1, 1)
  1223.    && ChkNoAttrPart()
  1224.    && EncodePCRel(&ArgStr[1], &AdrVals))
  1225.   {
  1226.     PutCode(Code, 1);
  1227.     AppendDisp(&AdrVals);
  1228.   }
  1229. }
  1230.  
  1231. /*!------------------------------------------------------------------------
  1232.  * \fn     DecodeRET(Word Code)
  1233.  * \brief  Decode RET/RETT/RXP Instructions
  1234.  * \param  Code Machine Code
  1235.  * ------------------------------------------------------------------------ */
  1236.  
  1237. static void DecodeRET(Word Code)
  1238. {
  1239.   if (ChkArgCnt(0, 1)
  1240.    &&  ChkNoAttrPart())
  1241.   {
  1242.     tEvalResult EvalResult;
  1243.     LongInt Value;
  1244.     tAdrVals AdrVals;
  1245.  
  1246.     if (ArgCnt >= 1)
  1247.       Value = EvalStrIntExpressionWithResult(&ArgStr[1], SInt30, &EvalResult);
  1248.     else
  1249.     {
  1250.       Value = 0;
  1251.       EvalResult.OK = True;
  1252.       EvalResult.Flags = eSymbolFlag_None;
  1253.     }
  1254.  
  1255.     ClearAdrVals(&AdrVals);
  1256.     if (EncodeDisplacement(Value, &AdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[1]))
  1257.     {
  1258.       PutCode(Code, 1);
  1259.       AppendDisp(&AdrVals);
  1260.     }
  1261.   }
  1262. }
  1263.  
  1264. /*!------------------------------------------------------------------------
  1265.  * \fn     DecodeCXP(Word Code)
  1266.  * \brief  Handle CXP Instruction
  1267.  * \param  Code machine code
  1268.  * ------------------------------------------------------------------------ */
  1269.  
  1270. static void DecodeCXP(Word Code)
  1271. {
  1272.   if (ChkArgCnt(1, 1)
  1273.    &&  ChkNoAttrPart())
  1274.   {
  1275.     tEvalResult EvalResult;
  1276.     LongInt Value = EvalStrIntExpressionWithResult(&ArgStr[1], SInt30, &EvalResult);
  1277.     tAdrVals AdrVals;
  1278.  
  1279.     ClearAdrVals(&AdrVals);
  1280.     if (EncodeDisplacement(Value, &AdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[1]))
  1281.     {
  1282.       PutCode(Code, 1);
  1283.       AppendDisp(&AdrVals);
  1284.     }
  1285.   }
  1286. }
  1287.  
  1288. /*!------------------------------------------------------------------------
  1289.  * \fn     DecodeENTER(Word Code)
  1290.  * \brief  Handle ENTER Instruction (Format 1)
  1291.  * \param  Code machine code
  1292.  * ------------------------------------------------------------------------ */
  1293.  
  1294. static void DecodeENTER(Word Code)
  1295. {
  1296.   Byte RegList;
  1297.  
  1298.   if (ChkArgCnt(2, 2)
  1299.    && ChkNoAttrPart()
  1300.    && DecodeRegList(&ArgStr[1], False, &RegList))
  1301.   {
  1302.     tEvalResult EvalResult;
  1303.     LongInt Value = EvalStrIntExpressionWithResult(&ArgStr[2], SInt30, &EvalResult);
  1304.     tAdrVals AdrVals;
  1305.  
  1306.     ClearAdrVals(&AdrVals);
  1307.     if (EncodeDisplacement(Value, &AdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[1]))
  1308.     {
  1309.       PutCode(Code, 1);
  1310.       BAsmCode[CodeLen++] = RegList;
  1311.       AppendDisp(&AdrVals);
  1312.     }
  1313.   }
  1314. }
  1315.  
  1316. /*!------------------------------------------------------------------------
  1317.  * \fn     DecodeEXIT(Word Code)
  1318.  * \brief  Handle EXIT Instruction (Format 1)
  1319.  * \param  Code machine code
  1320.  * ------------------------------------------------------------------------ */
  1321.  
  1322. static void DecodeEXIT(Word Code)
  1323. {
  1324.   Byte RegList;
  1325.  
  1326.   if (ChkArgCnt(1, 1)
  1327.    && ChkNoAttrPart()
  1328.    && DecodeRegList(&ArgStr[1], True, &RegList))
  1329.   {
  1330.     PutCode(Code, 1);
  1331.     BAsmCode[CodeLen++] = RegList;
  1332.   }
  1333. }
  1334.  
  1335. /*!------------------------------------------------------------------------
  1336.  * \fn     DecodeSAVE_RESTORE(Word Code)
  1337.  * \brief  Decode SAVE/RESTORE Instructions
  1338.  * \param  Code Machine Code
  1339.  * ------------------------------------------------------------------------ */
  1340.  
  1341. static void DecodeSAVE_RESTORE(Word Code)
  1342. {
  1343.   Byte RegList;
  1344.  
  1345.   if (ChkArgCnt(1, 1)
  1346.    && ChkNoAttrPart()
  1347.    && DecodeRegList(&ArgStr[1], !!(Code & 0x10), &RegList))
  1348.   {
  1349.     PutCode(Code, 1);
  1350.     PutCode(RegList, 1);
  1351.   }
  1352. }
  1353.  
  1354. /*!------------------------------------------------------------------------
  1355.  * \fn     DecodeCINV(Word Code)
  1356.  * \brief  handle CINV instruction
  1357.  * \param  Code machine code
  1358.  * ------------------------------------------------------------------------ */
  1359.  
  1360. static void DecodeCINV(Word Code)
  1361. {
  1362.   tAdrVals AdrVals;
  1363.  
  1364.   if (ChkArgCnt(2, 4)
  1365.    && ChkNoAttrPart()
  1366.    && CheckCore(1 << eCoreGen2)
  1367.    && CheckSup(True, &OpPart)
  1368.    && DecodeAdr(&ArgStr[ArgCnt], &AdrVals, MAllowReg))
  1369.   {
  1370.     LongWord ActCode = (((LongWord)AdrVals.Code) << 19)
  1371.                      | Code;
  1372.     int z;
  1373.  
  1374.     for (z = 1; z < ArgCnt; z++)
  1375.       if (!as_strcasecmp(ArgStr[z].str.p_str, "A"))
  1376.         ActCode |= 1ul << 17;
  1377.       else if (!as_strcasecmp(ArgStr[z].str.p_str, "I"))
  1378.         ActCode |= 1ul << 16;
  1379.       else if (!as_strcasecmp(ArgStr[z].str.p_str, "D"))
  1380.         ActCode |= 1ul << 15;
  1381.       else
  1382.       {
  1383.         WrStrErrorPos(ErrNum_InvCacheInvMode, &ArgStr[z]);
  1384.         return;
  1385.       }
  1386.     PutCode(ActCode, 3);
  1387.     AppendIndex(&AdrVals);
  1388.     AppendDisp(&AdrVals);
  1389.   }
  1390. }
  1391.  
  1392. /*!------------------------------------------------------------------------
  1393.  * \fn     DecodeLPR_SPR(Word Code)
  1394.  * \brief  Decode LPR/SPR Instructions (Format 2)
  1395.  * \param  Code Machine Code & Operand Size
  1396.  * ------------------------------------------------------------------------ */
  1397.  
  1398. static void DecodeLPR_SPR(Word Code)
  1399. {
  1400.   tAdrVals SrcAdrVals;
  1401.   Word Reg;
  1402.   Boolean IsSPR = (Lo(Code) == 2);
  1403.  
  1404.   if (ChkArgCnt(2, 2)
  1405.    && ChkNoAttrPart()
  1406.    && SetOpSizeFromCode(Code)
  1407.    && DecodeAdr(&ArgStr[2], &SrcAdrVals, MAllowReg | (IsSPR ? 0 : MAllowImm))
  1408.    && DecodeCtlReg(&ArgStr[1], &Reg))
  1409.   {
  1410.     PutCode((((Word)SrcAdrVals.Code) << 11)
  1411.           | (Reg << 7)
  1412.           | (Lo(Code) << 4)
  1413.           | (SizeCodeI(OpSize) << 0)
  1414.           | 0x0c, 2);
  1415.     AppendIndex(&SrcAdrVals);
  1416.     AppendDisp(&SrcAdrVals);
  1417.   }
  1418. }
  1419.  
  1420. /*!------------------------------------------------------------------------
  1421.  * \fn     DecodeScond(Word Code)
  1422.  * \brief  Handloe Scond Instructions
  1423.  * \param  Code condition & operand size
  1424.  * ------------------------------------------------------------------------ */
  1425.  
  1426. static void DecodeScond(Word Code)
  1427. {
  1428.   tAdrVals AdrVals;
  1429.  
  1430.   if (ChkArgCnt(1, 1)
  1431.    && ChkNoAttrPart()
  1432.    && SetOpSizeFromCode(Code)
  1433.    && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg))
  1434.   {
  1435.     PutCode((((Word)AdrVals.Code) << 11)
  1436.           | ((Code & 0xff) << 7)
  1437.           | (SizeCodeI(OpSize) << 0)
  1438.           | 0x3c, 2);
  1439.     AppendIndex(&AdrVals);
  1440.     AppendDisp(&AdrVals);
  1441.   }
  1442. }
  1443.  
  1444. /*!------------------------------------------------------------------------
  1445.  * \fn     DecodeMOVQ(Word Code)
  1446.  * \brief  Handle MOVQ/ADDQ/CMPQ Instructions
  1447.  * \param  Code Machine Code & Operand Size
  1448.  * ------------------------------------------------------------------------ */
  1449.  
  1450. #define MOVQ_DESTMAYIMM 0x80
  1451.  
  1452. static void DecodeMOVQ(Word Code)
  1453. {
  1454.   tAdrVals DestAdrVals;
  1455.   Boolean DestMayImm = !!(Code & MOVQ_DESTMAYIMM);
  1456.  
  1457.   Code &= ~MOVQ_DESTMAYIMM;
  1458.   if (ChkArgCnt(2, 2)
  1459.    && ChkNoAttrPart()
  1460.    && SetOpSizeFromCode(Code)
  1461.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
  1462.   {
  1463.     Boolean OK;
  1464.     Integer Val = EvalStrIntExpression(&ArgStr[1], SInt4, &OK);
  1465.  
  1466.     if (OK)
  1467.     {
  1468.       PutCode((((Word)DestAdrVals.Code) << 11)
  1469.             | ((Val & 0x0f) << 7)
  1470.             | (Lo(Code) << 4)
  1471.             | (SizeCodeI(OpSize) << 0)
  1472.             | 0x0c, 2);
  1473.       AppendIndex(&DestAdrVals);
  1474.       AppendDisp(&DestAdrVals);
  1475.     }
  1476.   }
  1477. }
  1478.  
  1479. /*!------------------------------------------------------------------------
  1480.  * \fn     DecodeACB(Word Code)
  1481.  * \brief  handle ACBi Instrucion
  1482.  * \param  Code machine code & operand size
  1483.  * ------------------------------------------------------------------------ */
  1484.  
  1485. static void DecodeACB(Word Code)
  1486. {
  1487.   tAdrVals DestAdrVals;
  1488.  
  1489.   if (ChkArgCnt(3, 3)
  1490.    && ChkNoAttrPart()
  1491.    && SetOpSizeFromCode(Code)
  1492.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
  1493.   {
  1494.     Boolean OK;
  1495.     tAdrVals DistAdrVals;
  1496.     Integer Val = EvalStrIntExpression(&ArgStr[1], SInt4, &OK);
  1497.  
  1498.     if (OK && EncodePCRel(&ArgStr[3], &DistAdrVals))
  1499.     {
  1500.       PutCode((((Word)DestAdrVals.Code) << 11)
  1501.             | ((Val & 0x0f) << 7)
  1502.             | (Lo(Code) << 4)
  1503.             | (SizeCodeI(OpSize) << 0)
  1504.             | 0x0c, 2);
  1505.       AppendIndex(&DestAdrVals);
  1506.       AppendDisp(&DestAdrVals);
  1507.       AppendDisp(&DistAdrVals);
  1508.     }
  1509.   }
  1510. }
  1511.  
  1512. /*!------------------------------------------------------------------------
  1513.  * \fn     DecodeFormat3(Word Code)
  1514.  * \brief  Decode Format 3 Instructions
  1515.  * \param  Code Machine Code
  1516.  * ------------------------------------------------------------------------ */
  1517.  
  1518. static void DecodeFormat3(Word Code)
  1519. {
  1520.   tAdrVals AdrVals;
  1521.  
  1522.   if (ChkArgCnt(1, 1)
  1523.    && ChkNoAttrPart()
  1524.    && SetOpSizeFromCode(Code)
  1525.    && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | MAllowImm))
  1526.   {
  1527.     PutCode((((Word)AdrVals.Code) << 11)
  1528.           | (Lo(Code) << 7)
  1529.           | (SizeCodeI(OpSize) << 0)
  1530.           | 0x7c, 2);
  1531.     AppendIndex(&AdrVals);
  1532.     AppendDisp(&AdrVals);
  1533.   }
  1534. }
  1535.  
  1536. /*!------------------------------------------------------------------------
  1537.  * \fn     DecodeFormat4(Word Code)
  1538.  * \brief  decode Format 4 instructions
  1539.  * \param  Code machine code
  1540.  * ------------------------------------------------------------------------ */
  1541.  
  1542. #define FMT4_SRCISADDR 0x80
  1543. #define FMT4_DESTMAYIMM 0x40
  1544.  
  1545. static void DecodeFormat4(Word Code)
  1546. {
  1547.   tAdrVals SrcAdrVals, DestAdrVals;
  1548.   Boolean SrcIsAddr = !!(Code & FMT4_SRCISADDR),
  1549.           DestMayImm = !!(Code & FMT4_DESTMAYIMM);
  1550.  
  1551.   Code &= ~(FMT4_SRCISADDR | FMT4_DESTMAYIMM);
  1552.   if (ChkArgCnt(2, 2)
  1553.    && ChkNoAttrPart()
  1554.    && SetOpSizeFromCode(Code)
  1555.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | (SrcIsAddr ? 0 : MAllowImm))
  1556.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
  1557.   {
  1558.     PutCode((((Word)SrcAdrVals.Code) << 11)
  1559.           | (((Word)DestAdrVals.Code) << 6)
  1560.           | (Lo(Code) << 2)
  1561.           | (SizeCodeI(OpSize)), 2);
  1562.     AppendIndex(&SrcAdrVals);
  1563.     AppendIndex(&DestAdrVals);
  1564.     AppendDisp(&SrcAdrVals);
  1565.     AppendDisp(&DestAdrVals);
  1566.   }
  1567. }
  1568.  
  1569. /*!------------------------------------------------------------------------
  1570.  * \fn     DecodeMOVS_CMPS_SKPS(Word Code)
  1571.  * \brief  Handle MOVSi/CMPSi/SKPSi Instructions (Format 5)
  1572.  * \param  Code machine code & operand size
  1573.  * ------------------------------------------------------------------------ */
  1574.  
  1575. static void DecodeMOVS_CMPS_SKPS(Word Code)
  1576. {
  1577.   if (ChkArgCnt(0, 2)
  1578.    && ChkNoAttrPart()
  1579.    && SetOpSizeFromCode(Code))
  1580.   {
  1581.     Byte Options = 0;
  1582.     int z;
  1583.  
  1584.     for (z = 1; z <= ArgCnt; z++)
  1585.     {
  1586.       if (!as_strcasecmp(ArgStr[z].str.p_str, "B"))
  1587.         Options |= 1;
  1588.       else if (!as_strcasecmp(ArgStr[z].str.p_str, "U"))
  1589.       {
  1590.         if (Options & 6)
  1591.         {
  1592.           WrStrErrorPos(ErrNum_ConfStringOpt, &ArgStr[z]);
  1593.           return;
  1594.         }
  1595.         else
  1596.           Options |= 6;
  1597.       }
  1598.       else if (!as_strcasecmp(ArgStr[z].str.p_str, "W"))
  1599.       {
  1600.         if (Options & 6)
  1601.         {
  1602.           WrStrErrorPos(ErrNum_ConfStringOpt, &ArgStr[z]);
  1603.           return;
  1604.         }
  1605.         else
  1606.           Options |= 2;
  1607.       }
  1608.       else
  1609.       {
  1610.         WrStrErrorPos(ErrNum_UnknownStringOpt, &ArgStr[z]);
  1611.         return;
  1612.       }
  1613.     }
  1614.     PutCode((((LongWord)Options) << 16)
  1615.           | ((Code & 0xff) << 10)
  1616.           | (SizeCodeI(OpSize) << 8)
  1617.           | 0x0e, 3);
  1618.   }
  1619. }
  1620.  
  1621. /*!------------------------------------------------------------------------
  1622.  * \fn     DecodeSETCFG(Word Code)
  1623.  * \brief  Handle SETCFG Instruction
  1624.  * \param  Code machine code
  1625.  * ------------------------------------------------------------------------ */
  1626.  
  1627. static void DecodeSETCFG(Word Code)
  1628. {
  1629.   Byte CfgOpts;
  1630.  
  1631.   if (ChkArgCnt(1, 1)
  1632.    && ChkNoAttrPart()
  1633.    && CheckSup(True, &OpPart)
  1634.    && DecodeCfgList(&ArgStr[1], &CfgOpts))
  1635.     PutCode((((LongWord)CfgOpts) << 15)
  1636.             | Code, 3);
  1637. }
  1638.  
  1639. /*!------------------------------------------------------------------------
  1640.  * \fn     DecodeFormat6(Word Code)
  1641.  * \brief  Decode Format 6 Instructions
  1642.  * \param  Code machine code
  1643.  * ------------------------------------------------------------------------ */
  1644.  
  1645. #define FMT6_SRC8BIT 0x80
  1646.  
  1647. static void DecodeFormat6(Word Code)
  1648. {
  1649.   tAdrVals SrcAdrVals, DestAdrVals;
  1650.   Boolean SrcIs8Bit = !!(Code & FMT6_SRC8BIT);
  1651.  
  1652.   Code &= ~FMT6_SRC8BIT;
  1653.   if (ChkArgCnt(2, 2)
  1654.    && ChkNoAttrPart()
  1655.    && SetOpSizeFromCode(SrcIs8Bit ? 0x0000 : Code)
  1656.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  1657.    && ResetOpSize() && SetOpSizeFromCode(Code)
  1658.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
  1659.   {
  1660.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  1661.           | (((LongWord)DestAdrVals.Code) << 14)
  1662.           | (Lo(Code) << 10)
  1663.           | (SizeCodeI(OpSize) << 8)
  1664.           | 0x4e, 3);
  1665.     AppendIndex(&SrcAdrVals);
  1666.     AppendIndex(&DestAdrVals);
  1667.     AppendDisp(&SrcAdrVals);
  1668.     AppendDisp(&DestAdrVals);
  1669.   }
  1670. }
  1671.  
  1672. /*!------------------------------------------------------------------------
  1673.  * \fn     DecodeFormat7(Word Code)
  1674.  * \brief  Decode Format 7 Instructions
  1675.  * \param  Code machine code
  1676.  * ------------------------------------------------------------------------ */
  1677.  
  1678. static void DecodeFormat7(Word Code)
  1679. {
  1680.   tAdrVals SrcAdrVals, DestAdrVals;
  1681.  
  1682.   if (ChkArgCnt(2, 2)
  1683.    && ChkNoAttrPart()
  1684.    && SetOpSizeFromCode(Code)
  1685.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  1686.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
  1687.   {
  1688.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  1689.           | (((LongWord)DestAdrVals.Code) << 14)
  1690.           | (Lo(Code) << 10)
  1691.           | (SizeCodeI(OpSize) << 8)
  1692.           | 0xce, 3);
  1693.     AppendIndex(&SrcAdrVals);
  1694.     AppendIndex(&DestAdrVals);
  1695.     AppendDisp(&SrcAdrVals);
  1696.     AppendDisp(&DestAdrVals);
  1697.   }
  1698. }
  1699.  
  1700. /*!------------------------------------------------------------------------
  1701.  * \fn     DecodeMOVM_CMPM(Word Code)
  1702.  * \brief  Decode MOVMi/CMPMi Instruction (Format 7)
  1703.  * \param  Code machine code & size
  1704.  * ------------------------------------------------------------------------ */
  1705.  
  1706. static void DecodeMOVM_CMPM(Word Code)
  1707. {
  1708.   tAdrVals SrcAdrVals, DestAdrVals;
  1709.  
  1710.   if (ChkArgCnt(3, 3)
  1711.    && ChkNoAttrPart()
  1712.    && SetOpSizeFromCode(Code)
  1713.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg)
  1714.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
  1715.   {
  1716.     tEvalResult EvalResult;
  1717.     LongWord Count = EvalStrIntExpressionWithResult(&ArgStr[3], UInt30, &EvalResult);
  1718.  
  1719.     if (EvalResult.OK)
  1720.     {
  1721.       tAdrVals CntAdrVals;
  1722.  
  1723.       Count = (Count - 1) << OpSize;
  1724.       ClearAdrVals(&CntAdrVals);
  1725.       if (EncodeDisplacement(Count, &CntAdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[3]))
  1726.       {
  1727.         PutCode((((LongWord)SrcAdrVals.Code) << 19)
  1728.             | (((LongWord)DestAdrVals.Code) << 14)
  1729.             | (Lo(Code) << 10)
  1730.             | (SizeCodeI(OpSize) << 8)
  1731.             | 0xce, 3);
  1732.         AppendIndex(&SrcAdrVals);
  1733.         AppendIndex(&DestAdrVals);
  1734.         AppendDisp(&SrcAdrVals);
  1735.         AppendDisp(&DestAdrVals);
  1736.         AppendDisp(&CntAdrVals);
  1737.       }
  1738.     }
  1739.   }
  1740. }
  1741.  
  1742. /*!------------------------------------------------------------------------
  1743.  * \fn     DecodeINSS_EXTS(Word Code)
  1744.  * \brief  Handle INSS/EXTS Instructions (Format 7)
  1745.  * \param  Code machine code & operand size
  1746.  * ------------------------------------------------------------------------ */
  1747.  
  1748. static void DecodeINSS_EXTS(Word Code)
  1749. {
  1750.   tAdrVals Arg1AdrVals, Arg2AdrVals;
  1751.  
  1752.   if (ChkArgCnt(4, 4)
  1753.    && ChkNoAttrPart()
  1754.    && SetOpSizeFromCode(Code)
  1755.    && DecodeAdr(&ArgStr[1], &Arg1AdrVals, MAllowReg | ((Lo(Code) == 2) ? MAllowImm : 0))
  1756.    && DecodeAdr(&ArgStr[2], &Arg2AdrVals, MAllowReg))
  1757.   {
  1758.     tEvalResult EvalResult;
  1759.     Byte Offs, Length;
  1760.  
  1761.     Offs = EvalStrIntExpressionWithResult(&ArgStr[3], UInt3, &EvalResult);
  1762.     if (!EvalResult.OK)
  1763.       return;
  1764.  
  1765.     Length = EvalStrIntExpressionWithResult(&ArgStr[4], UInt5, &EvalResult);
  1766.     if (!EvalResult.OK)
  1767.       return;
  1768.     if (mFirstPassUnknownOrQuestionable(EvalResult.Flags))
  1769.       Length = (Length & 31) + 1;
  1770.     if (ChkRange(Length, 1, 32))
  1771.     {
  1772.       PutCode((((LongWord)Arg1AdrVals.Code) << 19)
  1773.             | (((LongWord)Arg2AdrVals.Code) << 14)
  1774.             | (SizeCodeI(OpSize) << 8)
  1775.             | (Lo(Code) << 10)
  1776.             | 0xce, 3);
  1777.       AppendIndex(&Arg1AdrVals);
  1778.       AppendIndex(&Arg2AdrVals);
  1779.       AppendDisp(&Arg1AdrVals);
  1780.       AppendDisp(&Arg2AdrVals);
  1781.       BAsmCode[CodeLen++] = ((Offs & 7) << 5) | ((Length - 1) & 31);
  1782.     }
  1783.   }
  1784. }
  1785.  
  1786. /*!------------------------------------------------------------------------
  1787.  * \fn     DecodeMOVExt(Word Code)
  1788.  * \brief  Decode MOV{X|Z}{BW|BD|WD} Instructions (Format 7)
  1789.  * \param  Code machine code & operand sizes
  1790.  * ------------------------------------------------------------------------ */
  1791.  
  1792. static void DecodeMOVExt(Word Code)
  1793. {
  1794.   tAdrVals SrcAdrVals, DestAdrVals;
  1795.   Byte SrcOpSize = (Code >> 8) & 15,
  1796.        DestOpSize = (Code >> 12) & 15;
  1797.  
  1798.   if (ChkArgCnt(2, 2)
  1799.    && ChkNoAttrPart()
  1800.    && SetOpSize((tSymbolSize)SrcOpSize, &OpPart)
  1801.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm))
  1802.   {
  1803.     OpSize = (tSymbolSize)DestOpSize;
  1804.  
  1805.     if (DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
  1806.     {
  1807.       Code = ((DestOpSize == eSymbolSize32Bit) ? 6 : 5) ^ (Code & 1);
  1808.       PutCode((((LongWord)SrcAdrVals.Code) << 19)
  1809.             | (((LongWord)DestAdrVals.Code) << 14)
  1810.             | (Code << 10)
  1811.             | (((LongWord)SrcOpSize) << 8)
  1812.             | 0xce, 3);
  1813.       AppendIndex(&SrcAdrVals);
  1814.       AppendIndex(&DestAdrVals);
  1815.       AppendDisp(&SrcAdrVals);
  1816.       AppendDisp(&DestAdrVals);
  1817.     }
  1818.   }
  1819. }
  1820.  
  1821. /*!------------------------------------------------------------------------
  1822.  * \fn     DecodeDoubleDest(Word Code)
  1823.  * \brief  handle instruction with double-sized dest operand (Format 8)
  1824.  * \param  Code machine code
  1825.  * ------------------------------------------------------------------------ */
  1826.  
  1827. static void DecodeDoubleDest(Word Code)
  1828. {
  1829.   tAdrVals SrcAdrVals, DestAdrVals;
  1830.  
  1831.   if (ChkArgCnt(2, 2)
  1832.    && ChkNoAttrPart()
  1833.    && SetOpSizeFromCode(Code)
  1834.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  1835.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowRegPair))
  1836.   {
  1837.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  1838.           | (((LongWord)DestAdrVals.Code) << 14)
  1839.           | (Lo(Code) << 10)
  1840.           | (SizeCodeI(OpSize) << 8)
  1841.           | 0xce, 3);
  1842.     AppendIndex(&SrcAdrVals);
  1843.     AppendIndex(&DestAdrVals);
  1844.     AppendDisp(&SrcAdrVals);
  1845.     AppendDisp(&DestAdrVals);
  1846.   }
  1847. }
  1848.  
  1849. /*!------------------------------------------------------------------------
  1850.  * \fn     DecodeCHECK_INDEX(Word Code)
  1851.  * \brief  Handle CHECK/CVTP/INDEX Instructions (Format 8)
  1852.  * \param  Code machine code & operand size
  1853.  * ------------------------------------------------------------------------ */
  1854.  
  1855. static void DecodeCHECK_INDEX(Word Code)
  1856. {
  1857.   tAdrVals BoundsAdrVals, SrcAdrVals;
  1858.   Word DestReg;
  1859.   Boolean IsINDEX = Lo(Code) == 0x42,
  1860.           IsCVTP = Lo(Code) == 0x06;
  1861.  
  1862.  
  1863.   if (ChkArgCnt(3, 3)
  1864.    && ChkNoAttrPart()
  1865.    && SetOpSizeFromCode(Code)
  1866.    && DecodeAdr(&ArgStr[2], &BoundsAdrVals, IsINDEX ? (MAllowReg | MAllowImm) : 0)
  1867.    && DecodeAdr(&ArgStr[3], &SrcAdrVals, MAllowReg | (IsCVTP ? 0 : MAllowImm))
  1868.    && DecodeReg(&ArgStr[1], &DestReg, NULL, eSymbolSize32Bit, True))
  1869.   {
  1870.     PutCode((((LongWord)BoundsAdrVals.Code) << 19)
  1871.         | (((LongWord)SrcAdrVals.Code) << 14)
  1872.         | (DestReg << 11)
  1873.         | (SizeCodeI(OpSize) << 8)
  1874.         | (Lo(Code) << 4)
  1875.         | 0x0e, 3);
  1876.     AppendIndex(&BoundsAdrVals);
  1877.     AppendIndex(&SrcAdrVals);
  1878.     AppendDisp(&BoundsAdrVals);
  1879.     AppendDisp(&SrcAdrVals);
  1880.   }
  1881. }
  1882.  
  1883. /*!------------------------------------------------------------------------
  1884.  * \fn     DecodeINS_EXT(Word Code)
  1885.  * \brief  Handle INS/EXT Instructions (Format 8)
  1886.  * \param  IsINS 1 for INS, 0 for EXT
  1887.  * ------------------------------------------------------------------------ */
  1888.  
  1889. static void DecodeINS_EXT(Word IsINS)
  1890. {
  1891.   tAdrVals Arg2AdrVals, Arg3AdrVals;
  1892.   Word OffsetReg;
  1893.  
  1894.   if (ChkArgCnt(4, 4)
  1895.    && ChkNoAttrPart()
  1896.    && SetOpSizeFromCode(IsINS)
  1897.    && DecodeReg(&ArgStr[1], &OffsetReg, NULL, eSymbolSize32Bit, True)
  1898.    && DecodeAdr(&ArgStr[2], &Arg2AdrVals, MAllowReg | (Lo(IsINS) ? MAllowImm : 0))
  1899.    && DecodeAdr(&ArgStr[3], &Arg3AdrVals, MAllowReg))
  1900.   {
  1901.     tEvalResult EvalResult;
  1902.     LongInt Disp = EvalStrIntExpressionWithResult(&ArgStr[4], SInt30, &EvalResult);
  1903.  
  1904.     if (EvalResult.OK)
  1905.     {
  1906.       tAdrVals DispAdrVals;
  1907.  
  1908.       ClearAdrVals(&DispAdrVals);
  1909.       if (EncodeDisplacement(Disp, &DispAdrVals, ErrNum_OverRange, &ArgStr[4]))
  1910.       {
  1911.         PutCode((((LongWord)Arg2AdrVals.Code) << 19)
  1912.               | (((LongWord)Arg3AdrVals.Code) << 14)
  1913.               | (OffsetReg << 11)
  1914.               | (SizeCodeI(OpSize) << 8)
  1915.               | (Lo(IsINS) << 7)
  1916.               | 0x2e, 3);
  1917.         AppendIndex(&Arg2AdrVals);
  1918.         AppendIndex(&Arg3AdrVals);
  1919.         AppendDisp(&Arg2AdrVals);
  1920.         AppendDisp(&Arg3AdrVals);
  1921.         AppendDisp(&DispAdrVals);
  1922.       }
  1923.     }
  1924.   }
  1925. }
  1926.  
  1927. /*!------------------------------------------------------------------------
  1928.  * \fn     DecodeFFS(Word Code)
  1929.  * \brief  Handle FFS Instruction
  1930.  * \param  Code machine code & operand size
  1931.  * ------------------------------------------------------------------------ */
  1932.  
  1933. static void DecodeFFS(Word Code)
  1934. {
  1935.   tAdrVals BaseAdrVals, OffsetAdrVals;
  1936.  
  1937.   if (ChkArgCnt(2, 2)
  1938.    && ChkNoAttrPart()
  1939.    && SetOpSizeFromCode(Code)
  1940.    && DecodeAdr(&ArgStr[1], &BaseAdrVals, MAllowReg | MAllowImm)
  1941.    && DecodeAdr(&ArgStr[2], &OffsetAdrVals, MAllowReg))
  1942.   {
  1943.     PutCode((((LongWord)BaseAdrVals.Code) << 19)
  1944.           | (((LongWord)OffsetAdrVals.Code) << 14)
  1945.           | (Lo(Code) << 10)
  1946.           | (SizeCodeI(OpSize) << 8)
  1947.           | 0x6e, 3);
  1948.     AppendIndex(&BaseAdrVals);
  1949.     AppendIndex(&OffsetAdrVals);
  1950.     AppendDisp(&BaseAdrVals);
  1951.     AppendDisp(&OffsetAdrVals);
  1952.   }
  1953. }
  1954.  
  1955. /*!------------------------------------------------------------------------
  1956.  * \fn     DecodeMOVSU(Word Code)
  1957.  * \brief  Handle MOVSU/MOVUS Instruction
  1958.  * \param  Code machine code & operand size
  1959.  * ------------------------------------------------------------------------ */
  1960.  
  1961. static void DecodeMOVSU(Word Code)
  1962. {
  1963.   tAdrVals SrcAdrVals, DestAdrVals;
  1964.  
  1965.   if (ChkArgCnt(2, 2)
  1966.    && ChkNoAttrPart()
  1967.    && CheckSup(True, &OpPart)
  1968.    && CheckCore((1 << eCoreGen1) | (1 << eCoreGen2))
  1969.    && SetOpSizeFromCode(Code)
  1970.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, 0)
  1971.    && DecodeAdr(&ArgStr[2], &DestAdrVals, 0))
  1972.   {
  1973.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  1974.           | (((LongWord)DestAdrVals.Code) << 14)
  1975.           | ((Code & 0xff) << 10)
  1976.           | (SizeCodeI(OpSize) << 8)
  1977.           | 0xae, 3);
  1978.     AppendIndex(&SrcAdrVals);
  1979.     AppendIndex(&DestAdrVals);
  1980.     AppendDisp(&SrcAdrVals);
  1981.     AppendDisp(&DestAdrVals);
  1982.   }
  1983. }
  1984.  
  1985. /*!------------------------------------------------------------------------
  1986.  * \fn     DecodeFLOOR_ROUND_TRUNC(Word Code)
  1987.  * \brief  Handle FLOOR.../ROUND.../TRUNC... instructions (Format 9)
  1988.  * \param  Code machine code & (integer) op size
  1989.  * ------------------------------------------------------------------------ */
  1990.  
  1991. static void DecodeFLOOR_ROUND_TRUNC(Word Code)
  1992. {
  1993.   tAdrVals SrcAdrVals, DestAdrVals;
  1994.  
  1995.   if (ChkArgCnt(2, 2)
  1996.    && ChkNoAttrPart()
  1997.    && CheckFPUAvail(eFPU16081)
  1998.    && SetFOpSizeFromCode(Code & 0x1)
  1999.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  2000.    && ResetOpSize() && SetOpSizeFromCode(Code)
  2001.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
  2002.   {
  2003.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  2004.           | (((LongWord)DestAdrVals.Code) << 14)
  2005.           | (Lo(Code) << 10)
  2006.           | (SizeCodeI(OpSize) << 8)
  2007.           | 0x3e, 3);
  2008.     AppendIndex(&SrcAdrVals);
  2009.     AppendIndex(&DestAdrVals);
  2010.     AppendDisp(&SrcAdrVals);
  2011.     AppendDisp(&DestAdrVals);
  2012.   }
  2013. }
  2014.  
  2015. /*!------------------------------------------------------------------------
  2016.  * \fn     DecodeMOVif(Word Code)
  2017.  * \brief  Handle MOV i->f Instructions (Format 9)
  2018.  * \param  Code machine code & (integer) op size
  2019.  * ------------------------------------------------------------------------ */
  2020.  
  2021. static void DecodeMOVif(Word Code)
  2022. {
  2023.   tAdrVals SrcAdrVals, DestAdrVals;
  2024.  
  2025.   if (ChkArgCnt(2, 2)
  2026.    && ChkNoAttrPart()
  2027.    && CheckFPUAvail(eFPU16081)
  2028.    && SetOpSizeFromCode(Code)
  2029.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  2030.    && ResetOpSize() && SetFOpSizeFromCode(Code & 0x1)
  2031.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
  2032.   {
  2033.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  2034.           | (((LongWord)DestAdrVals.Code) << 14)
  2035.           | ((Code & 0xff) << 10)
  2036.           | (SizeCodeI(GetOpSizeFromCode(Code)) << 8)
  2037.           | 0x3e, 3);
  2038.     AppendIndex(&SrcAdrVals);
  2039.     AppendIndex(&DestAdrVals);
  2040.     AppendDisp(&SrcAdrVals);
  2041.     AppendDisp(&DestAdrVals);
  2042.   }
  2043. }
  2044.  
  2045. /*!------------------------------------------------------------------------
  2046.  * \fn     DecodeFormatLFSR_SFSR(Word Code)
  2047.  * \brief  Handle LFSR/SFSR Instructions (Format 9)
  2048.  * \param  Code Machine Code & Flags
  2049.  * ------------------------------------------------------------------------ */
  2050.  
  2051. #define FMT9_MAYIMM (1 << 15)
  2052.  
  2053. static void DecodeLFSR_SFSR(Word Code)
  2054. {
  2055.   Boolean MayImm = !!(Code & FMT9_MAYIMM);
  2056.   tAdrVals AdrVals;
  2057.  
  2058.   Code &= ~FMT9_MAYIMM;
  2059.   if (ChkArgCnt(1, 1)
  2060.    && ChkNoAttrPart()
  2061.    && CheckFPUAvail(eFPU16081)
  2062.    && SetOpSize(eSymbolSize32Bit, &OpPart)
  2063.    && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | (MayImm ? MAllowImm : 0)))
  2064.   {
  2065.     PutCode((((LongWord)AdrVals.Code) << (MayImm ? 19 : 14))
  2066.           | (((LongWord)Code) << 8)
  2067.           | 0x3e, 3);
  2068.     AppendIndex(&AdrVals);
  2069.     AppendDisp(&AdrVals);
  2070.   }
  2071. }
  2072.  
  2073. /*!------------------------------------------------------------------------
  2074.  * \fn     DecodeMOVF(Word Code)
  2075.  * \brief  Handle MOVFL/MOVLF Instructions (Format 9)
  2076.  * \param  Code Machine Code & Flags
  2077.  * ------------------------------------------------------------------------ */
  2078.  
  2079. static void DecodeMOVF(Word Code)
  2080. {
  2081.   tAdrVals SrcAdrVals, DestAdrVals;
  2082.   Byte OpSize = (Code >> 8) & 1;
  2083.  
  2084.   if (ChkArgCnt(2, 2)
  2085.    && ChkNoAttrPart()
  2086.    && CheckFPUAvail(eFPU16081)
  2087.    && SetFOpSizeFromCode(OpSize)
  2088.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  2089.    && ResetOpSize() && SetFOpSizeFromCode(OpSize ^ 1)
  2090.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
  2091.   {
  2092.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  2093.           | (((LongWord)DestAdrVals.Code) << 14)
  2094.           | Code, 3);
  2095.     AppendIndex(&SrcAdrVals);
  2096.     AppendIndex(&DestAdrVals);
  2097.     AppendDisp(&SrcAdrVals);
  2098.     AppendDisp(&DestAdrVals);
  2099.   }
  2100. }
  2101.  
  2102. /*!------------------------------------------------------------------------
  2103.  * \fn     DecodeFormat11(Word Code)
  2104.  * \brief  Handle Format 11 Instructions
  2105.  * \param  Code Machine Code & Operand Size
  2106.  * ------------------------------------------------------------------------ */
  2107.  
  2108. #define FMT11_DESTMAYIMM 0x80
  2109.  
  2110. static void DecodeFormat11(Word Code)
  2111. {
  2112.   tAdrVals SrcAdrVals, DestAdrVals;
  2113.   Boolean DestMayImm = !!(Code & FMT11_DESTMAYIMM);
  2114.  
  2115.   Code &= ~FMT11_DESTMAYIMM;
  2116.   if (ChkArgCnt(2, 2)
  2117.    && ChkNoAttrPart()
  2118.    && CheckFPUAvail(eFPU16081)
  2119.    && SetOpSizeFromCode(Code)
  2120.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  2121.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
  2122.   {
  2123.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  2124.           | (((LongWord)DestAdrVals.Code) << 14)
  2125.           | ((Code & 0xff) << 10)
  2126.           | (SizeCodeF(OpSize) << 8)
  2127.           | 0xbe, 3);
  2128.     AppendIndex(&SrcAdrVals);
  2129.     AppendIndex(&DestAdrVals);
  2130.     AppendDisp(&SrcAdrVals);
  2131.     AppendDisp(&DestAdrVals);
  2132.   }
  2133. }
  2134.  
  2135. /*!------------------------------------------------------------------------
  2136.  * \fn     DecodeFormat12(Word Code)
  2137.  * \brief  Handle Format 12 Instructions
  2138.  * \param  Code Machine Code & Operand Size
  2139.  * ------------------------------------------------------------------------ */
  2140.  
  2141. #define FMT12_DESTMAYIMM 0x40
  2142. #define FMT12_580 0x20
  2143.  
  2144. static void DecodeFormat12(Word Code)
  2145. {
  2146.   tAdrVals SrcAdrVals, DestAdrVals;
  2147.   Boolean DestMayImm = !!(Code & FMT12_DESTMAYIMM),
  2148.           Req580 = !!(Code & FMT12_580);
  2149.  
  2150.   Code &= ~(FMT12_DESTMAYIMM | FMT12_580);
  2151.   if (ChkArgCnt(2, 2)
  2152.    && ChkNoAttrPart()
  2153.    && CheckFPUAvail(Req580 ? eFPU32580 : eFPU32181)
  2154.    && SetOpSizeFromCode(Code)
  2155.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  2156.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
  2157.   {
  2158.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  2159.           | (((LongWord)DestAdrVals.Code) << 14)
  2160.           | ((Code & 0xff) << 10)
  2161.           | (SizeCodeF(OpSize) << 8)
  2162.           | 0xfe, 3);
  2163.     AppendIndex(&SrcAdrVals);
  2164.     AppendIndex(&DestAdrVals);
  2165.     AppendDisp(&SrcAdrVals);
  2166.     AppendDisp(&DestAdrVals);
  2167.   }
  2168. }
  2169.  
  2170. /*!------------------------------------------------------------------------
  2171.  * \fn     DecodeLMR_SMR(Word Code)
  2172.  * \brief  Decode LMR/SMR Instructions (Format 14)
  2173.  * \param  Code Machine Code & Operand Size
  2174.  * ------------------------------------------------------------------------ */
  2175.  
  2176. static void DecodeLMR_SMR(Word Code)
  2177. {
  2178.   tAdrVals AdrVals;
  2179.   Word Reg;
  2180.   Boolean IsStore = (Code == 3);
  2181.  
  2182.   if (ChkArgCnt(2, 2)
  2183.    && ChkNoAttrPart()
  2184.    && CheckPMMUAvail()
  2185.    && SetOpSizeFromCode(Code)
  2186.    && DecodeAdr(&ArgStr[2], &AdrVals, MAllowReg | (IsStore ? 0 : MAllowImm))
  2187.    && DecodeMMUReg(&ArgStr[1], &Reg))
  2188.   {
  2189.     if (!IsStore && (Reg >= 14))
  2190.       WrStrErrorPos(ErrNum_Unpredictable, &ArgStr[1]);
  2191.     PutCode((((LongWord)AdrVals.Code) << 19)
  2192.           | ((LongWord)Reg << 15)
  2193.           | (Lo(Code) << 10)
  2194.           | (SizeCodeI(OpSize) << 8)
  2195.           | 0x1e, 3);
  2196.     AppendIndex(&AdrVals);
  2197.     AppendDisp(&AdrVals);
  2198.   }
  2199. }
  2200.  
  2201. /*!------------------------------------------------------------------------
  2202.  * \fn     DecodeRDVAL_WRVAL(Word Code)
  2203.  * \brief  Handle RDVAL/WRVAL Instructions
  2204.  * \param  Code Machine code & operand size
  2205.  * ------------------------------------------------------------------------ */
  2206.  
  2207. static void DecodeRDVAL_WRVAL(Word Code)
  2208. {
  2209.   tAdrVals AdrVals;
  2210.  
  2211.   if (ChkArgCnt(1, 1)
  2212.    && ChkNoAttrPart()
  2213.    && CheckSup(True, &OpPart)
  2214.    && SetOpSizeFromCode(Code)
  2215.    && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg))
  2216.   {
  2217.     PutCode((((LongWord)AdrVals.Code) << 19)
  2218.         | (Lo(Code) << 10)
  2219.         | (SizeCodeI(OpSize) << 8)
  2220.         | 0x1e, 3);
  2221.     AppendIndex(&AdrVals);
  2222.     AppendDisp(&AdrVals);
  2223.   }
  2224. }
  2225.  
  2226. /*!------------------------------------------------------------------------
  2227.  * \fn     DecodeCCVci(Word Code)
  2228.  * \brief  Handle CCVnci Instructions (Format 15.1)
  2229.  * \param  Code Machine code & (integer) operand size
  2230.  * ------------------------------------------------------------------------ */
  2231.  
  2232. static void DecodeCCVci(Word Code)
  2233. {
  2234.   tAdrVals SrcAdrVals, DestAdrVals;
  2235.  
  2236.   if (ChkArgCnt(2, 2)
  2237.    && ChkNoAttrPart()
  2238.    && CheckCustomAvail()
  2239.    && SetCOpSizeFromCode(Code & 0x01)
  2240.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  2241.    && ResetOpSize() && SetOpSizeFromCode(Code)
  2242.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
  2243.   {
  2244.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  2245.           | (((LongWord)DestAdrVals.Code) << 14)
  2246.           | (Lo(Code) << 10)
  2247.           | (SizeCodeI(OpSize) << 8)
  2248.           | 0x36, 3);
  2249.     AppendIndex(&SrcAdrVals);
  2250.     AppendIndex(&DestAdrVals);
  2251.     AppendDisp(&SrcAdrVals);
  2252.     AppendDisp(&DestAdrVals);
  2253.   }
  2254. }
  2255.  
  2256. /*!------------------------------------------------------------------------
  2257.  * \fn     DecodeCCVic(Word Code)
  2258.  * \brief  Handle CCVnic Instructions (Format 15.1)
  2259.  * \param  Code Machine code & (integer) operand size
  2260.  * ------------------------------------------------------------------------ */
  2261.  
  2262. static void DecodeCCVic(Word Code)
  2263. {
  2264.   tAdrVals SrcAdrVals, DestAdrVals;
  2265.  
  2266.   if (ChkArgCnt(2, 2)
  2267.    && ChkNoAttrPart()
  2268.    && CheckCustomAvail()
  2269.    && SetOpSizeFromCode(Code)
  2270.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  2271.    && ResetOpSize() && SetCOpSizeFromCode(Code & 0x01)
  2272.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
  2273.   {
  2274.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  2275.           | (((LongWord)DestAdrVals.Code) << 14)
  2276.           | (Lo(Code) << 10)
  2277.           | (SizeCodeI(GetOpSizeFromCode(Code)) << 8)
  2278.           | 0x36, 3);
  2279.     AppendIndex(&SrcAdrVals);
  2280.     AppendIndex(&DestAdrVals);
  2281.     AppendDisp(&SrcAdrVals);
  2282.     AppendDisp(&DestAdrVals);
  2283.   }
  2284. }
  2285.  
  2286. /*!------------------------------------------------------------------------
  2287.  * \fn     DecodeCCVcc(Word Code)
  2288.  * \brief  Handle CCVncc Instructions (Format 15.1)
  2289.  * \param  Code Machine Code & Flags
  2290.  * ------------------------------------------------------------------------ */
  2291.  
  2292. static void DecodeCCVcc(Word Code)
  2293. {
  2294.   tAdrVals SrcAdrVals, DestAdrVals;
  2295.   Byte OpSize = Code & 1;
  2296.  
  2297.   if (ChkArgCnt(2, 2)
  2298.    && ChkNoAttrPart()
  2299.    && CheckCustomAvail()
  2300.    && SetCOpSizeFromCode(OpSize)
  2301.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  2302.    && ResetOpSize() && SetCOpSizeFromCode(OpSize ^ 1)
  2303.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
  2304.   {
  2305.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  2306.           | (((LongWord)DestAdrVals.Code) << 14)
  2307.           | (Code << 10)
  2308.           | 0x36, 3);
  2309.     AppendIndex(&SrcAdrVals);
  2310.     AppendIndex(&DestAdrVals);
  2311.     AppendDisp(&SrcAdrVals);
  2312.     AppendDisp(&DestAdrVals);
  2313.   }
  2314. }
  2315.  
  2316. /*!------------------------------------------------------------------------
  2317.  * \fn     DecodeCATST(Word Code)
  2318.  * \brief  Decode CATSTx Instructions (Format 15.0)
  2319.  * \param  Code Machine Code
  2320.  * ------------------------------------------------------------------------ */
  2321.  
  2322. static void DecodeCATST(Word Code)
  2323. {
  2324.   tAdrVals AdrVals;
  2325.  
  2326.   if (ChkArgCnt(1, 1)
  2327.    && ChkNoAttrPart()
  2328.    && SetOpSize(eSymbolSize32Bit, &OpPart)
  2329.    && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | MAllowImm))
  2330.   {
  2331.     PutCode((((LongWord)AdrVals.Code) << 19)
  2332.           | (Code << 10)
  2333.           | (SizeCodeI(OpSize) << 8)
  2334.           | 0x16, 3);
  2335.     AppendIndex(&AdrVals);
  2336.     AppendDisp(&AdrVals);
  2337.   }
  2338. }
  2339.  
  2340. /*!------------------------------------------------------------------------
  2341.  * \fn     DecodeLCR_SCR(Word Code)
  2342.  * \brief  Handle LCR/SCR Instructions (Format 15.0)
  2343.  * \param  Code Machine Code & Flags
  2344.  * ------------------------------------------------------------------------ */
  2345.  
  2346. #define FMT15_0_MAYIMM (1 << 7)
  2347.  
  2348. static void DecodeLCR_SCR(Word Code)
  2349. {
  2350.   Boolean MayImm = !!(Code & FMT15_0_MAYIMM);
  2351.   tAdrVals AdrVals;
  2352.  
  2353.   Code &= ~FMT15_0_MAYIMM;
  2354.   if (ChkArgCnt(2, 2)
  2355.    && ChkNoAttrPart()
  2356.    && CheckCustomAvail()
  2357.    && CheckSup(True, &OpPart)
  2358.    && SetOpSize(eSymbolSize32Bit, &OpPart)
  2359.    && DecodeAdr(&ArgStr[2], &AdrVals, MAllowReg | (MayImm ? MAllowImm : 0)))
  2360.   {
  2361.     Boolean OK;
  2362.     LongWord Reg = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
  2363.  
  2364.     if (OK)
  2365.     {
  2366.       PutCode((((LongWord)AdrVals.Code) << 19)
  2367.            | (Reg << 15)
  2368.            | (Code << 10)
  2369.            |  (SizeCodeI(OpSize) << 8)
  2370.            | 0x16, 3);
  2371.       AppendIndex(&AdrVals);
  2372.       AppendDisp(&AdrVals);
  2373.     }
  2374.   }
  2375. }
  2376.  
  2377. /*!------------------------------------------------------------------------
  2378.  * \fn     DecodeFormatLCSR_SCSR(Word Code)
  2379.  * \brief  Handle LCSR/SCSR Instructions (Format 15.1)
  2380.  * \param  Code Machine Code & Flags
  2381.  * ------------------------------------------------------------------------ */
  2382.  
  2383. #define FMT15_1_MAYIMM (1 << 7)
  2384.  
  2385. static void DecodeLCSR_SCSR(Word Code)
  2386. {
  2387.   Boolean MayImm = !!(Code & FMT15_1_MAYIMM);
  2388.   tAdrVals AdrVals;
  2389.  
  2390.   Code &= ~FMT15_1_MAYIMM;
  2391.   if (ChkArgCnt(1, 1)
  2392.    && ChkNoAttrPart()
  2393.    && CheckCustomAvail()
  2394.    && SetOpSize(eSymbolSize32Bit, &OpPart)
  2395.    && DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | (MayImm ? MAllowImm : 0)))
  2396.   {
  2397.     PutCode((((LongWord)AdrVals.Code) << (MayImm ? 19 : 14))
  2398.           | (((LongWord)Code) << 10)
  2399.           | (SizeCodeI(OpSize) << 8)
  2400.           | 0x36, 3);
  2401.     AppendIndex(&AdrVals);
  2402.     AppendDisp(&AdrVals);
  2403.   }
  2404. }
  2405.  
  2406. /*!------------------------------------------------------------------------
  2407.  * \fn     DecodeFormat15_5_7(Word Code)
  2408.  * \brief  Handle Format 15.5/15.7 Instructions
  2409.  * \param  Code Machine code & operand size
  2410.  * ------------------------------------------------------------------------ */
  2411.  
  2412. #define FMT15_5_DESTMAYIMM 0x80
  2413. #define FMT15_7 0x40
  2414.  
  2415. static void DecodeFormat15_5_7(Word Code)
  2416. {
  2417.   tAdrVals SrcAdrVals, DestAdrVals;
  2418.   unsigned DestMayImm = (Code & FMT15_5_DESTMAYIMM) ? MAllowImm : 0,
  2419.            Is7 = !!(Code & FMT15_7);
  2420.  
  2421.   Code &= ~(FMT15_5_DESTMAYIMM | FMT15_7);
  2422.   if (ChkArgCnt(2, 2)
  2423.    && ChkNoAttrPart()
  2424.    && CheckCustomAvail()
  2425.    && (!Is7 || CheckCore((1 << eCoreGen1Ext) | (1 << eCoreGen2)))
  2426.    && SetOpSizeFromCode(Code)
  2427.    && DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
  2428.    && DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg| DestMayImm))
  2429.   {
  2430.     PutCode((((LongWord)SrcAdrVals.Code) << 19)
  2431.           | (((LongWord)DestAdrVals.Code) << 14)
  2432.           | (Lo(Code) << 10)
  2433.           | (SizeCodeC(OpSize) << 8)
  2434.           | (Is7 << 6)
  2435.           | 0xb6, 3);
  2436.     AppendIndex(&SrcAdrVals);
  2437.     AppendIndex(&DestAdrVals);
  2438.     AppendDisp(&SrcAdrVals);
  2439.     AppendDisp(&DestAdrVals);
  2440.   }
  2441. }
  2442.  
  2443. /*!------------------------------------------------------------------------
  2444.  * \fn     void CodeFPU(Word Code)
  2445.  * \brief  Handle FPU Instruction
  2446.  * ------------------------------------------------------------------------ */
  2447.  
  2448. static void CodeFPU(Word Code)
  2449. {
  2450.   UNUSED(Code);
  2451.  
  2452.   if (ChkArgCnt(1, 1))
  2453.   {
  2454.     if (!as_strcasecmp(ArgStr[1].str.p_str, "OFF"))
  2455.     {
  2456.       SetFlag(&FPUAvail, FPUAvailName, False);
  2457.       SetMomFPU(eFPUNone);
  2458.     }
  2459.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "ON"))
  2460.     {
  2461.       SetFlag(&FPUAvail, FPUAvailName, True);
  2462.       if (!MomFPU)
  2463.         SetMomFPU((tFPU)pCurrCPUProps->DefFPU);
  2464.     }
  2465.     else
  2466.     {
  2467.       tFPU FPU;
  2468.  
  2469.       for (FPU = (tFPU)1; FPU < eFPUCount; FPU++)
  2470.         if (!as_strcasecmp(ArgStr[1].str.p_str, FPUNames[FPU]))
  2471.         {
  2472.           SetFlag(&FPUAvail, FPUAvailName, True);
  2473.           SetMomFPU(FPU);
  2474.           break;
  2475.         }
  2476.       if (FPU >= eFPUCount)
  2477.         WrStrErrorPos(ErrNum_InvFPUType, &ArgStr[1]);
  2478.     }
  2479.   }
  2480. }
  2481.  
  2482. /*!------------------------------------------------------------------------
  2483.  * \fn     void CodePMMU(Word Code)
  2484.  * \brief  Handle PMMU Instruction
  2485.  * ------------------------------------------------------------------------ */
  2486.  
  2487. static void CodePMMU(Word Code)
  2488. {
  2489.   UNUSED(Code);
  2490.  
  2491.   if (ChkArgCnt(1, 1))
  2492.   {
  2493.     if (!as_strcasecmp(ArgStr[1].str.p_str, "OFF"))
  2494.     {
  2495.       SetFlag(&PMMUAvail, PMMUAvailName, False);
  2496.       SetMomPMMU(ePMMUNone);
  2497.     }
  2498.     else if (!as_strcasecmp(ArgStr[1].str.p_str, "ON"))
  2499.     {
  2500.       SetFlag(&PMMUAvail, PMMUAvailName, True);
  2501.       if (!MomPMMU)
  2502.         SetMomPMMU((tPMMU)pCurrCPUProps->DefPMMU);
  2503.     }
  2504.     else
  2505.     {
  2506.       tPMMU PMMU;
  2507.  
  2508.       for (PMMU = (tPMMU)1; PMMU < ePMMUCount; PMMU++)
  2509.         if (!as_strcasecmp(ArgStr[1].str.p_str, PMMUNames[PMMU]))
  2510.         {
  2511.           SetFlag(&PMMUAvail, PMMUAvailName, True);
  2512.           SetMomPMMU(PMMU);
  2513.           break;
  2514.         }
  2515.       if (PMMU >= ePMMUCount)
  2516.         WrStrErrorPos(ErrNum_InvPMMUType, &ArgStr[1]);
  2517.     }
  2518.   }
  2519. }
  2520.  
  2521. /*!------------------------------------------------------------------------
  2522.  * \fn     DecodeBB(Word Code)
  2523.  * \brief  Handle BitBLT Instructions
  2524.  * \param  Code Machine Code & Options
  2525.  * ------------------------------------------------------------------------ */
  2526.  
  2527. #define BB_NOOPT (1 << 15)
  2528.  
  2529. typedef struct
  2530. {
  2531.   char Name[3];
  2532.   Byte Pos, Value;
  2533. } tBitBltOpt;
  2534.  
  2535. static const tBitBltOpt BitBltOpts[] =
  2536. {
  2537.   { "DA" , 17, 1 },
  2538.   { "-S" , 15, 1 },
  2539.   { "IA" , 17, 0 },
  2540.   { "S"  , 15, 0 },
  2541.   { ""   , 0 , 0 }
  2542. };
  2543.  
  2544. static void DecodeBB(Word Code)
  2545. {
  2546.   if (ChkArgCnt(0, 2)
  2547.    && ChkNoAttrPart()
  2548.    && CheckCore(1 << eCoreGenE))
  2549.   {
  2550.     LongWord OpCode = 0x0e | ((LongWord)(Code & ~BB_NOOPT) << 8), OptMask = 0;
  2551.     tStrComp *pArg;
  2552.     const tBitBltOpt *pOpt;
  2553.  
  2554.     forallargs(pArg, True)
  2555.     {
  2556.       for (pOpt = BitBltOpts + ((Code & BB_NOOPT) ? 2 : 0); pOpt->Name[0]; pOpt++)
  2557.         if (!as_strcasecmp(pArg->str.p_str, pOpt->Name))
  2558.         {
  2559.           LongWord ThisMask = 1ul << pOpt->Pos;
  2560.  
  2561.           if (OptMask & ThisMask)
  2562.           {
  2563.             WrStrErrorPos(ErrNum_ConfBitBltOpt, pArg);
  2564.             return;
  2565.           }
  2566.           OptMask |= ThisMask;
  2567.           OpCode = pOpt->Value ? (OpCode | ThisMask) : (OpCode & ~ThisMask);
  2568.           break;
  2569.         }
  2570.       if (!pOpt->Name[0])
  2571.       {
  2572.         WrStrErrorPos(ErrNum_UnknownBitBltOpt, pArg);
  2573.         return;
  2574.       }
  2575.     }
  2576.     PutCode(OpCode, 3);
  2577.   }
  2578. }
  2579.  
  2580. /*!------------------------------------------------------------------------
  2581.  * \fn     DecodeBITxT(Word Code)
  2582.  * \brief  Handle BITBLT instructions without argument
  2583.  * \param  Code Machine Code
  2584.  * ------------------------------------------------------------------------ */
  2585.  
  2586. static void DecodeBITxT(Word Code)
  2587. {
  2588.   if (ChkArgCnt(0, 0)
  2589.    && ChkNoAttrPart()
  2590.    && CheckCore(1 << eCoreGenE))
  2591.     PutCode(((LongWord)Code) << 8 | 0x0e, 3);
  2592. }
  2593.  
  2594. /*!------------------------------------------------------------------------
  2595.  * \fn     DecodeTBITS(Word Code)
  2596.  * \brief  Handle TBITS Instruction
  2597.  * \param  Code Machine Code
  2598.  * ------------------------------------------------------------------------ */
  2599.  
  2600. static void DecodeTBITS(Word Code)
  2601. {
  2602.   if (ChkArgCnt(1, 1)
  2603.    && ChkNoAttrPart()
  2604.    && CheckCore(1 << eCoreGenE))
  2605.   {
  2606.     Boolean OK;
  2607.     LongWord Arg = EvalStrIntExpression(&ArgStr[1], UInt1, &OK);
  2608.  
  2609.     if (OK)
  2610.       PutCode((Arg << 15)
  2611.             | (((LongWord)Code) << 8)
  2612.             | 0x0e, 3);
  2613.   }
  2614. }
  2615.  
  2616. /*--------------------------------------------------------------------------*/
  2617. /* Instruction Lookup Table */
  2618.  
  2619. /*!------------------------------------------------------------------------
  2620.  * \fn     InitFields(void)
  2621.  * \brief  create lookup table
  2622.  * ------------------------------------------------------------------------ */
  2623.  
  2624. static void AddSizeInstTable(const char *pName, unsigned SizeMask, Word Code, InstProc Proc)
  2625. {
  2626.   char Name[20];
  2627.   tSymbolSize Size;
  2628.  
  2629.   for (Size = eSymbolSize8Bit; Size <= eSymbolSize32Bit; Size++)
  2630.     if (SizeMask & (1 << Size))
  2631.     {
  2632.       as_snprintf(Name, sizeof(Name), "%s%c", pName, "BWD"[Size - eSymbolSize8Bit]);
  2633.       AddInstTable(InstTable, Name, Code | (Size << 8), Proc);
  2634.     }
  2635. }
  2636.  
  2637. static void AddFSizeInstTable(const char *pName, unsigned SizeMask, Word Code, InstProc Proc)
  2638. {
  2639.   char Name[20];
  2640.   tSymbolSize Size;
  2641.  
  2642.   for (Size = eSymbolSizeFloat32Bit; Size <= eSymbolSizeFloat64Bit; Size++)
  2643.     if (SizeMask & (1 << Size))
  2644.     {
  2645.       as_snprintf(Name, sizeof(Name), "%s%c", pName, "FL"[Size - eSymbolSizeFloat32Bit]);
  2646.       AddInstTable(InstTable, Name, Code | (Size << 8), Proc);
  2647.     }
  2648. }
  2649.  
  2650. static void AddCSizeInstTable(const char *pName, unsigned SizeMask, Word Code, InstProc Proc)
  2651. {
  2652.   char Name[20];
  2653.   tSymbolSize Size;
  2654.  
  2655.   for (Size = eSymbolSize32Bit; Size <= eSymbolSize64Bit; Size++)
  2656.     if (SizeMask & (1 << Size))
  2657.     {
  2658.       as_snprintf(Name, sizeof(Name), "%s%c", pName, "DQ"[Size - eSymbolSize32Bit]);
  2659.       AddInstTable(InstTable, Name, Code | (Size << 8), Proc);
  2660.     }
  2661. }
  2662.  
  2663. static void AddCondition(const char *pCondition, Word Code)
  2664. {
  2665.   char Str[20];
  2666.  
  2667.   as_snprintf(Str, sizeof(Str), "B%s", pCondition);
  2668.   AddInstTable(InstTable, Str, (Code << 4) | 0x0a, DecodeFormat0);
  2669.   as_snprintf(Str, sizeof(Str), "S%s", pCondition);
  2670.   AddSizeInstTable(Str, (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), Code, DecodeScond);
  2671. }
  2672.  
  2673. static void AddCtl(const char *pName, Word Code, Boolean Privileged)
  2674. {
  2675.   order_array_rsv_end(CtlRegs, tCtlReg);
  2676.   CtlRegs[InstrZ  ].pName      = pName;
  2677.   CtlRegs[InstrZ  ].Code       = Code;
  2678.   CtlRegs[InstrZ++].Privileged = Privileged;
  2679. }
  2680.  
  2681. static void AddMMU(const char *pName, Word Code, Word Mask, Boolean Privileged)
  2682. {
  2683.   order_array_rsv_end(MMURegs, tCtlReg);
  2684.   MMURegs[InstrZ  ].pName      = pName;
  2685.   MMURegs[InstrZ  ].Code       = Code;
  2686.   MMURegs[InstrZ  ].Mask       = Mask;
  2687.   MMURegs[InstrZ++].Privileged = Privileged;
  2688. }
  2689.  
  2690. static void InitFields(void)
  2691. {
  2692.   InstTable = CreateInstTable(605);
  2693.   SetDynamicInstTable(InstTable);
  2694.  
  2695.   InstrZ = 0;
  2696.   AddCtl("UPSR"   , 0x00, True );
  2697.   AddCtl("DCR"    , 0x01, True );
  2698.   AddCtl("BPC"    , 0x02, True );
  2699.   AddCtl("DSR"    , 0x03, True );
  2700.   AddCtl("CAR"    , 0x04, True );
  2701.   AddCtl("FP"     , 0x08, False);
  2702.   AddCtl("SP"     , 0x09, False);
  2703.   AddCtl("SB"     , 0x0a, False);
  2704.   AddCtl("USP"    , 0x0b, True );
  2705.   AddCtl("CFG"    , 0x0c, True );
  2706.   AddCtl("PSR"    , 0x0d, False);
  2707.   AddCtl("INTBASE", 0x0e, True );
  2708.   AddCtl("MOD"    , 0x0f, False);
  2709.   AddCtl(NULL     , 0   , False);
  2710.  
  2711.   InstrZ = 0;
  2712.   AddMMU("BPR0"   , 0x00, (1 << ePMMU16082) | (1 << ePMMU32082)                                        , True );
  2713.   AddMMU("BPR1"   , 0x01, (1 << ePMMU16082) | (1 << ePMMU32082)                                        , True );
  2714.   AddMMU("MSR"    , 0x0a, (1 << ePMMU16082) | (1 << ePMMU32082)                     | (1 << ePMMU32532), True );
  2715.   AddMMU("BCNT"   , 0x0b, (1 << ePMMU16082) | (1 << ePMMU32082)                                        , True );
  2716.   AddMMU("PTB0"   , 0x0c, (1 << ePMMU16082) | (1 << ePMMU32082) | (1 << ePMMU32382) | (1 << ePMMU32532), True );
  2717.   AddMMU("PTB1"   , 0x0d, (1 << ePMMU16082) | (1 << ePMMU32082) | (1 << ePMMU32382) | (1 << ePMMU32532), True );
  2718.   AddMMU("EIA"    , 0x0f, (1 << ePMMU16082) | (1 << ePMMU32082)                                        , True );
  2719.   AddMMU("BAR"    , 0x00,                                         (1 << ePMMU32382)                    , True );
  2720.   AddMMU("BMR"    , 0x02,                                         (1 << ePMMU32382)                    , True );
  2721.   AddMMU("BDR"    , 0x03,                                         (1 << ePMMU32382)                    , True );
  2722.   AddMMU("BEAR"   , 0x06,                                         (1 << ePMMU32382)                    , True );
  2723.   AddMMU("FEW"    , 0x09,                                         (1 << ePMMU32382)                    , True );
  2724.   AddMMU("ASR"    , 0x0a,                                         (1 << ePMMU32382)                    , True );
  2725.   AddMMU("TEAR"   , 0x0b,                                         (1 << ePMMU32382) | (1 << ePMMU32532), True );
  2726.   /* TODO: 8 according to National docu, but 9 according to sample code */
  2727.   AddMMU("MCR"    , 0x09,                                                             (1 << ePMMU32532), True );
  2728.   AddMMU("IVAR0"  , 0x0e,                                         (1 << ePMMU32382) | (1 << ePMMU32532), True );/* w/o */
  2729.   AddMMU("IVAR1"  , 0x0f,                                         (1 << ePMMU32382) | (1 << ePMMU32532), True );/* w/o */
  2730.   AddMMU(NULL     , 0, 0, False);
  2731.  
  2732.   AddCondition("EQ",  0);
  2733.   AddCondition("NE",  1);
  2734.   AddCondition("CS",  2);
  2735.   AddCondition("CC",  3);
  2736.   AddCondition("HI",  4);
  2737.   AddCondition("LS",  5);
  2738.   AddCondition("GT",  6);
  2739.   AddCondition("LE",  7);
  2740.   AddCondition("FS",  8);
  2741.   AddCondition("FC",  9);
  2742.   AddCondition("LO", 10);
  2743.   AddCondition("HS", 11);
  2744.   AddCondition("LT", 12);
  2745.   AddCondition("GE", 13);
  2746.  
  2747.   /* Format 0 */
  2748.  
  2749.   AddInstTable(InstTable, "BR" , 0xea, DecodeFormat0);
  2750.   AddInstTable(InstTable, "BSR", 0x02, DecodeFormat0);
  2751.  
  2752.   /* Format 1 */
  2753.  
  2754.   AddInstTable(InstTable, "BPT" , 0xf2, DecodeFixed);
  2755.   AddInstTable(InstTable, "DIA" , 0xc2, DecodeFixed);
  2756.   AddInstTable(InstTable, "FLAG", 0xd2, DecodeFixed);
  2757.   AddInstTable(InstTable, "NOP" , NOPCode, DecodeFixed);
  2758.   AddInstTable(InstTable, "RETI", 0x52, DecodeFixed);
  2759.   AddInstTable(InstTable, "SVC" , 0xe2, DecodeFixed);
  2760.   AddInstTable(InstTable, "WAIT", 0xb2, DecodeFixed);
  2761.   AddInstTable(InstTable, "RET" , 0x12, DecodeRET);
  2762.   AddInstTable(InstTable, "RETT", 0x42, DecodeRET);
  2763.   AddInstTable(InstTable, "RXP" , 0x32, DecodeRET);
  2764.   AddInstTable(InstTable, "SAVE", 0x62, DecodeSAVE_RESTORE);
  2765.   AddInstTable(InstTable, "RESTORE", 0x72, DecodeSAVE_RESTORE);
  2766.  
  2767.   AddInstTable(InstTable, "CINV", 0x271e, DecodeCINV);
  2768.   AddInstTable(InstTable, "CXP" , 0x22, DecodeCXP);
  2769.   AddInstTable(InstTable, "ENTER", 0x82, DecodeENTER);
  2770.   AddInstTable(InstTable, "EXIT", 0x92, DecodeEXIT);
  2771.  
  2772.   /* Format 2 */
  2773.  
  2774.   AddSizeInstTable("ADDQ" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0, DecodeMOVQ);
  2775.   AddSizeInstTable("LPR"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 6, DecodeLPR_SPR);
  2776.   AddSizeInstTable("SPR"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 2, DecodeLPR_SPR);
  2777.   AddSizeInstTable("MOVQ" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 5, DecodeMOVQ);
  2778.   AddSizeInstTable("ACB"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 4, DecodeACB);
  2779.   AddSizeInstTable("CMPQ" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 1 | MOVQ_DESTMAYIMM, DecodeMOVQ);
  2780.  
  2781.   /* Format 3 */
  2782.  
  2783.   AddInstTable(InstTable, "JUMP"  , 0x04 | (eSymbolSize32Bit << 8), DecodeFormat3);
  2784.   AddInstTable(InstTable, "JSR"   , 0x0c | (eSymbolSize32Bit << 8), DecodeFormat3);
  2785.   AddSizeInstTable("ADJSP" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeFormat3);
  2786.   AddSizeInstTable("BICPSR", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit), 0x02, DecodeFormat3);
  2787.   AddSizeInstTable("BISPSR", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit), 0x06, DecodeFormat3);
  2788.   AddSizeInstTable("CASE"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat3);
  2789.   AddInstTable(InstTable, "CXPD"  , 0x00 | (eSymbolSize32Bit << 8), DecodeFormat3);
  2790.  
  2791.   /* Format 4 */
  2792.  
  2793.   AddSizeInstTable("MOV" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x05, DecodeFormat4);
  2794.   AddSizeInstTable("ADD" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x00, DecodeFormat4);
  2795.   AddSizeInstTable("ADDC", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x04, DecodeFormat4);
  2796.   AddInstTable(InstTable, "ADDR", (eSymbolSize32Bit << 8) | FMT4_SRCISADDR | 0x09, DecodeFormat4);
  2797.   AddSizeInstTable("AND" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeFormat4);
  2798.   AddSizeInstTable("BIC" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x02, DecodeFormat4);
  2799.   AddSizeInstTable("CMP" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT4_DESTMAYIMM | 0x01, DecodeFormat4);
  2800.   AddSizeInstTable("OR"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x06, DecodeFormat4);
  2801.   AddSizeInstTable("SUB" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFormat4);
  2802.   AddSizeInstTable("SUBC", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0c, DecodeFormat4);
  2803.   AddSizeInstTable("TBIT", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0d, DecodeFormat4);
  2804.   AddSizeInstTable("XOR" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat4);
  2805.  
  2806.   /* Format 5 */
  2807.  
  2808.   AddSizeInstTable("MOVS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x00, DecodeMOVS_CMPS_SKPS);
  2809.   AddSizeInstTable("CMPS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x01, DecodeMOVS_CMPS_SKPS);
  2810.   AddSizeInstTable("SKPS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x03, DecodeMOVS_CMPS_SKPS);
  2811.   AddInstTable(InstTable, "MOVST", (eSymbolSize8Bit << 8) | 0x20, DecodeMOVS_CMPS_SKPS);
  2812.   AddInstTable(InstTable, "CMPST", (eSymbolSize8Bit << 8) | 0x21, DecodeMOVS_CMPS_SKPS);
  2813.   AddInstTable(InstTable, "SKPST", (eSymbolSize8Bit << 8) | 0x23, DecodeMOVS_CMPS_SKPS);
  2814.   AddInstTable(InstTable, "SETCFG", 0xb0e, DecodeSETCFG);
  2815.  
  2816.   /* Format 6 */
  2817.  
  2818.   AddSizeInstTable("ABS"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0c, DecodeFormat6);
  2819.   AddSizeInstTable("ADDP"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeFormat6);
  2820.   AddSizeInstTable("ASH"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT6_SRC8BIT | 0x01, DecodeFormat6);
  2821.   AddSizeInstTable("CBIT"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x02, DecodeFormat6);
  2822.   AddSizeInstTable("CBITI" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x03, DecodeFormat6);
  2823.   AddSizeInstTable("COM"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0d, DecodeFormat6);
  2824.   AddSizeInstTable("IBIT"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat6);
  2825.   AddSizeInstTable("LSH"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT6_SRC8BIT | 0x05, DecodeFormat6);
  2826.   AddSizeInstTable("NEG"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFormat6);
  2827.   AddSizeInstTable("NOT"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeFormat6);
  2828.   AddSizeInstTable("ROT"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT6_SRC8BIT | 0x00, DecodeFormat6);
  2829.   AddSizeInstTable("SBIT"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x06, DecodeFormat6);
  2830.   AddSizeInstTable("SBITI" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x07, DecodeFormat6);
  2831.   AddSizeInstTable("SUBP"  , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeFormat6);
  2832.  
  2833.   /* Format 7 */
  2834.  
  2835.   AddSizeInstTable("DIV"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeFormat7);
  2836.   AddSizeInstTable("MOD"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat7);
  2837.   AddSizeInstTable("MUL"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFormat7);
  2838.   AddSizeInstTable("QUO"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0c, DecodeFormat7);
  2839.   AddSizeInstTable("REM"   , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0d, DecodeFormat7);
  2840.  
  2841.   AddInstTable(InstTable, "MOVXBW", (eSymbolSize8Bit  << 8) | (eSymbolSize16Bit << 12) | 1, DecodeMOVExt);
  2842.   AddInstTable(InstTable, "MOVXBD", (eSymbolSize8Bit  << 8) | (eSymbolSize32Bit << 12) | 1, DecodeMOVExt);
  2843.   AddInstTable(InstTable, "MOVXWD", (eSymbolSize16Bit << 8) | (eSymbolSize32Bit << 12) | 1, DecodeMOVExt);
  2844.   AddInstTable(InstTable, "MOVZBW", (eSymbolSize8Bit  << 8) | (eSymbolSize16Bit << 12) | 0, DecodeMOVExt);
  2845.   AddInstTable(InstTable, "MOVZBD", (eSymbolSize8Bit  << 8) | (eSymbolSize32Bit << 12) | 0, DecodeMOVExt);
  2846.   AddInstTable(InstTable, "MOVZWD", (eSymbolSize16Bit << 8) | (eSymbolSize32Bit << 12) | 0, DecodeMOVExt);
  2847.  
  2848.   AddSizeInstTable("MOVM", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x00, DecodeMOVM_CMPM);
  2849.   AddSizeInstTable("CMPM", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x01, DecodeMOVM_CMPM);
  2850.  
  2851.   AddSizeInstTable("DEI", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeDoubleDest);
  2852.   AddSizeInstTable("MEI", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeDoubleDest);
  2853.  
  2854.   AddSizeInstTable("EXTS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x03, DecodeINSS_EXTS);
  2855.   AddSizeInstTable("INSS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x02, DecodeINSS_EXTS);
  2856.  
  2857.   /* Format 8 */
  2858.  
  2859.   AddSizeInstTable("CHECK", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeCHECK_INDEX);
  2860.   AddInstTable(InstTable, "CVTP", (eSymbolSize32Bit << 8) | 0x06, DecodeCHECK_INDEX);
  2861.   AddSizeInstTable("INDEX", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x42, DecodeCHECK_INDEX);
  2862.  
  2863.   AddSizeInstTable("EXT", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0, DecodeINS_EXT);
  2864.   AddSizeInstTable("INS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 1, DecodeINS_EXT);
  2865.  
  2866.   AddSizeInstTable("FFS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x01, DecodeFFS);
  2867.  
  2868.   AddSizeInstTable("MOVSU", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x3, DecodeMOVSU);
  2869.   AddSizeInstTable("MOVUS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x7, DecodeMOVSU);
  2870.  
  2871.   /* Format 9 */
  2872.  
  2873.   AddSizeInstTable("FLOORF", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeFLOOR_ROUND_TRUNC);
  2874.   AddSizeInstTable("FLOORL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFLOOR_ROUND_TRUNC);
  2875.   AddSizeInstTable("ROUNDF", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeFLOOR_ROUND_TRUNC);
  2876.   AddSizeInstTable("ROUNDL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFLOOR_ROUND_TRUNC);
  2877.   AddSizeInstTable("TRUNCF", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeFLOOR_ROUND_TRUNC);
  2878.   AddSizeInstTable("TRUNCL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeFLOOR_ROUND_TRUNC);
  2879.   AddInstTable(InstTable, "MOVBF", 0x01 | (eSymbolSize8Bit << 8), DecodeMOVif);
  2880.   AddInstTable(InstTable, "MOVWF", 0x01 | (eSymbolSize16Bit << 8), DecodeMOVif);
  2881.   AddInstTable(InstTable, "MOVDF", 0x01 | (eSymbolSize32Bit << 8), DecodeMOVif);
  2882.   AddInstTable(InstTable, "MOVBL", 0x00 | (eSymbolSize8Bit << 8), DecodeMOVif);
  2883.   AddInstTable(InstTable, "MOVWL", 0x00 | (eSymbolSize16Bit << 8), DecodeMOVif);
  2884.   AddInstTable(InstTable, "MOVDL", 0x00 | (eSymbolSize32Bit << 8), DecodeMOVif);
  2885.  
  2886.   AddInstTable(InstTable, "LFSR", 0x0f | FMT9_MAYIMM, DecodeLFSR_SFSR);
  2887.   AddInstTable(InstTable, "SFSR", 0x37, DecodeLFSR_SFSR);
  2888.  
  2889.   AddInstTable(InstTable, "MOVFL"  , 0x1b3e, DecodeMOVF);
  2890.   AddInstTable(InstTable, "MOVLF"  , 0x163e, DecodeMOVF);
  2891.  
  2892.   /* Format 11 */
  2893.  
  2894.   AddFSizeInstTable("ABS", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x0d, DecodeFormat11);
  2895.   AddFSizeInstTable("ADD", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x00, DecodeFormat11);
  2896.   AddFSizeInstTable("CMP", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x02 | FMT11_DESTMAYIMM, DecodeFormat11);
  2897.   AddFSizeInstTable("DIV", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x08, DecodeFormat11);
  2898.   AddFSizeInstTable("MOV", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x01, DecodeFormat11);
  2899.   AddFSizeInstTable("MUL", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x0c, DecodeFormat11);
  2900.   AddFSizeInstTable("NEG", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x05, DecodeFormat11);
  2901.   AddFSizeInstTable("SUB", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x04, DecodeFormat11);
  2902.  
  2903.   /* Format 12 - only newer FPUs? */
  2904.  
  2905.   AddFSizeInstTable("DOT"  , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x03 | FMT12_DESTMAYIMM, DecodeFormat12);
  2906.   AddFSizeInstTable("LOGB" , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x05, DecodeFormat12);
  2907.   AddFSizeInstTable("POLY" , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x02 | FMT12_DESTMAYIMM, DecodeFormat12);
  2908.   AddFSizeInstTable("SCALB", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x04, DecodeFormat12);
  2909.   AddFSizeInstTable("REM"  , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x00, DecodeFormat12);
  2910.   AddFSizeInstTable("SQRT" , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), FMT12_580 | 0x01, DecodeFormat12);
  2911.   AddFSizeInstTable("ATAN2", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), FMT12_580 | 0x0c, DecodeFormat12);
  2912.   AddFSizeInstTable("SICOS", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), FMT12_580 | 0x0d, DecodeFormat12);
  2913.  
  2914.   /* Format 14 */
  2915.  
  2916.   AddInstTable(InstTable, "LMR"  , 0x02 | (eSymbolSize32Bit << 8), DecodeLMR_SMR);
  2917.   AddInstTable(InstTable, "SMR"  , 0x03 | (eSymbolSize32Bit << 8), DecodeLMR_SMR);
  2918.   AddInstTable(InstTable, "RDVAL", 0x00 | (eSymbolSize32Bit << 8), DecodeRDVAL_WRVAL);
  2919.   AddInstTable(InstTable, "WRVAL", 0x01 | (eSymbolSize32Bit << 8), DecodeRDVAL_WRVAL);
  2920.  
  2921.   AddInstTable(InstTable, "REG" , 0, CodeREG);
  2922.   AddInstTable(InstTable, "BYTE"   , eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString , DecodeIntelDB);
  2923.   AddInstTable(InstTable, "WORD"   , eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString , DecodeIntelDW);
  2924.   AddInstTable(InstTable, "DOUBLE" , eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString , DecodeIntelDD);
  2925.   AddInstTable(InstTable, "FLOAT"  , eIntPseudoFlag_AllowFloat , DecodeIntelDD);
  2926.   AddInstTable(InstTable, "LONG"   , eIntPseudoFlag_AllowFloat , DecodeIntelDQ);
  2927.   AddInstTable(InstTable, "FPU"    , 0, CodeFPU);
  2928.   AddInstTable(InstTable, "PMMU"   , 0, CodePMMU);
  2929.  
  2930.   /* Format 15.0 */
  2931.  
  2932.   AddInstTable(InstTable, "LCR", 0x0a | FMT15_0_MAYIMM, DecodeLCR_SCR);
  2933.   AddInstTable(InstTable, "SCR", 0x0b                 , DecodeLCR_SCR);
  2934.   AddInstTable(InstTable, "CATST0", 0x00, DecodeCATST);
  2935.   AddInstTable(InstTable, "CATST1", 0x01, DecodeCATST);
  2936.  
  2937.   /* Format 15.1 */
  2938.  
  2939.   AddSizeInstTable("CCV0Q", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeCCVci);
  2940.   AddSizeInstTable("CCV0D", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeCCVci);
  2941.   AddSizeInstTable("CCV1Q", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeCCVci);
  2942.   AddSizeInstTable("CCV1D", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeCCVci);
  2943.   AddSizeInstTable("CCV2Q", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeCCVci);
  2944.   AddSizeInstTable("CCV2D", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeCCVci);
  2945.   AddInstTable(InstTable, "CCV3BQ", (eSymbolSize8Bit  << 8) | 0x00, DecodeCCVic);
  2946.   AddInstTable(InstTable, "CCV3WQ", (eSymbolSize16Bit << 8) | 0x00, DecodeCCVic);
  2947.   AddInstTable(InstTable, "CCV3DQ", (eSymbolSize32Bit << 8) | 0x00, DecodeCCVic);
  2948.   AddInstTable(InstTable, "CCV3BD", (eSymbolSize8Bit  << 8) | 0x01, DecodeCCVic);
  2949.   AddInstTable(InstTable, "CCV3WD", (eSymbolSize16Bit << 8) | 0x01, DecodeCCVic);
  2950.   AddInstTable(InstTable, "CCV3DD", (eSymbolSize32Bit << 8) | 0x01, DecodeCCVic);
  2951.   AddInstTable(InstTable, "CCV4DQ", 0x07, DecodeCCVcc);
  2952.   AddInstTable(InstTable, "CCV5QD", 0x04, DecodeCCVcc);
  2953.   AddInstTable(InstTable, "LCSR", 0x01 | FMT15_1_MAYIMM, DecodeLCSR_SCSR);
  2954.   AddInstTable(InstTable, "SCSR", 0x06, DecodeLCSR_SCSR);
  2955.  
  2956.   /* Format 15.5/15.7 */
  2957.  
  2958.   AddCSizeInstTable("CCAL0", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x00, DecodeFormat15_5_7);
  2959.   AddCSizeInstTable("CMOV0", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x01, DecodeFormat15_5_7);
  2960.   AddCSizeInstTable("CCMP" , (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_5_DESTMAYIMM | 0x02, DecodeFormat15_5_7);
  2961.   AddCSizeInstTable("CCMP1", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_5_DESTMAYIMM | 0x03, DecodeFormat15_5_7);
  2962.   AddCSizeInstTable("CCAL1", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x04, DecodeFormat15_5_7);
  2963.   AddCSizeInstTable("CMOV2", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x05, DecodeFormat15_5_7);
  2964.   AddCSizeInstTable("CCAL3", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x08, DecodeFormat15_5_7);
  2965.   AddCSizeInstTable("CMOV3", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x09, DecodeFormat15_5_7);
  2966.   AddCSizeInstTable("CCAL2", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x0c, DecodeFormat15_5_7);
  2967.   AddCSizeInstTable("CMOV1", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x0d, DecodeFormat15_5_7);
  2968.   AddCSizeInstTable("CCAL4", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x00, DecodeFormat15_5_7);
  2969.   AddCSizeInstTable("CMOV4", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x01, DecodeFormat15_5_7);
  2970.   AddCSizeInstTable("CCAL8", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x02, DecodeFormat15_5_7);
  2971.   AddCSizeInstTable("CCAL9", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x03, DecodeFormat15_5_7);
  2972.   AddCSizeInstTable("CCAL5", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x04, DecodeFormat15_5_7);
  2973.   AddCSizeInstTable("CMOV6", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x05, DecodeFormat15_5_7);
  2974.   AddCSizeInstTable("CCAL7", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x08, DecodeFormat15_5_7);
  2975.   AddCSizeInstTable("CMOV7", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x09, DecodeFormat15_5_7);
  2976.   AddCSizeInstTable("CCAL6", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x0c, DecodeFormat15_5_7);
  2977.   AddCSizeInstTable("CMOV5", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x0d, DecodeFormat15_5_7);
  2978.  
  2979.   /* BITBLT */
  2980.  
  2981.   AddInstTable(InstTable, "BBAND"  , 0x12b, DecodeBB);
  2982.   AddInstTable(InstTable, "BBOR"   , 0x019, DecodeBB);
  2983.   AddInstTable(InstTable, "BBXOR"  , 0x039, DecodeBB);
  2984.   AddInstTable(InstTable, "BBFOR"  , BB_NOOPT | 0x031, DecodeBB);
  2985.   AddInstTable(InstTable, "BBSTOD" , 0x011, DecodeBB);
  2986.  
  2987.   AddInstTable(InstTable, "BITWT"  , 0x21, DecodeBITxT);
  2988.   AddInstTable(InstTable, "EXTBLT" , 0x17, DecodeBITxT);
  2989.   AddInstTable(InstTable, "MOVMPB" , 0x1c, DecodeBITxT);
  2990.   AddInstTable(InstTable, "MOVMPW" , 0x1d, DecodeBITxT);
  2991.   AddInstTable(InstTable, "MOVMPD" , 0x1f, DecodeBITxT);
  2992.   AddInstTable(InstTable, "SBITS"  , 0x37, DecodeBITxT);
  2993.   AddInstTable(InstTable, "SBITPS" , 0x2f, DecodeBITxT);
  2994.  
  2995.   AddInstTable(InstTable, "TBITS"  , 0x27, DecodeTBITS);
  2996. }
  2997.  
  2998. /*!------------------------------------------------------------------------
  2999.  * \fn     DeinitFields(void)
  3000.  * \brief  destroy/cleanup lookup table
  3001.  * ------------------------------------------------------------------------ */
  3002.  
  3003. static void DeinitFields(void)
  3004. {
  3005.   DestroyInstTable(InstTable);
  3006.   order_array_free(CtlRegs);
  3007.   order_array_free(MMURegs);
  3008. }
  3009.  
  3010. /*--------------------------------------------------------------------------*/
  3011. /* Interface Functions */
  3012.  
  3013. /*!------------------------------------------------------------------------
  3014.  * \fn     MakeCode_NS32K(void)
  3015.  * \brief  encode machine instruction
  3016.  * ------------------------------------------------------------------------ */
  3017.  
  3018. static void MakeCode_NS32K(void)
  3019. {
  3020.   CodeLen = 0; DontPrint = False;
  3021.   OpSize = eSymbolSizeUnknown;
  3022.  
  3023.   /* to be ignored */
  3024.  
  3025.   if (Memo("")) return;
  3026.  
  3027.   /* Pseudo Instructions */
  3028.  
  3029.   if (DecodeIntelPseudo(TargetBigEndian))
  3030.     return;
  3031.  
  3032.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  3033.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  3034. }
  3035.  
  3036. /*!------------------------------------------------------------------------
  3037.  * \fn     InternSymbol_NS32K(char *pArg, TempResult *pResult)
  3038.  * \brief  handle built-in symbols on NS32000
  3039.  * \param  pArg source argument
  3040.  * \param  pResult result buffer
  3041.  * ------------------------------------------------------------------------ */
  3042.  
  3043. static void InternSymbol_NS32K(char *pArg, TempResult *pResult)
  3044. {
  3045.   Word Reg;
  3046.   tSymbolSize Size;
  3047.  
  3048.   if (DecodeRegCore(pArg, &Reg, &Size))
  3049.   {
  3050.     pResult->Typ = TempReg;
  3051.     pResult->DataSize = Size;
  3052.     pResult->Contents.RegDescr.Reg = Reg;
  3053.     pResult->Contents.RegDescr.Dissect = DissectReg_NS32K;
  3054.     pResult->Contents.RegDescr.compare = NULL;
  3055.   }
  3056. }
  3057.  
  3058. /*!------------------------------------------------------------------------
  3059.  * \fn     InitCode_NS32K(void)
  3060.  * \brief  target-specific initializations before starting a pass
  3061.  * ------------------------------------------------------------------------ */
  3062.  
  3063. static void InitCode_NS32K(void)
  3064. {
  3065.   SetMomFPU(eFPUNone);
  3066.   SetMomPMMU(ePMMUNone);
  3067. }
  3068.  
  3069. /*!------------------------------------------------------------------------
  3070.  * \fn     IsDef_NS32K(void)
  3071.  * \brief  check whether insn makes own use of label
  3072.  * \return True if yes
  3073.  * ------------------------------------------------------------------------ */
  3074.  
  3075. static Boolean IsDef_NS32K(void)
  3076. {
  3077.   return Memo("REG");
  3078. }
  3079.  
  3080. /*!------------------------------------------------------------------------
  3081.  * \fn     SwitchTo_NS32K(void *pUser)
  3082.  * \brief  prepare to assemble code for this target
  3083.  * \param  pUser CPU properties
  3084.  * ------------------------------------------------------------------------ */
  3085.  
  3086. static Boolean ChkMoreZeroArg(void)
  3087. {
  3088.   return (ArgCnt > 0);
  3089. }
  3090.  
  3091. static void SwitchTo_NS32K(void *pUser)
  3092. {
  3093.   const TFamilyDescr *pDescr = FindFamilyByName("NS32000");
  3094.  
  3095.   TurnWords = True;
  3096.   SetIntConstMode(eIntConstModeIntel);
  3097.   SaveIsOccupiedFnc = ChkMoreZeroArg;
  3098.   RestoreIsOccupiedFnc = ChkMoreZeroArg;
  3099.  
  3100.   pCurrCPUProps = (const tCPUProps*)pUser;
  3101.  
  3102.   /* default selection of "typical" companion FPU/PMMU: */
  3103.  
  3104.   SetMomFPU((tFPU)pCurrCPUProps->DefFPU);
  3105.   SetMomPMMU((tPMMU)pCurrCPUProps->DefPMMU);
  3106.  
  3107.   PCSymbol = "*"; HeaderID = pDescr->Id;
  3108.   NOPCode = 0xa2;
  3109.   DivideChars = ",";
  3110.   HasAttrs = True; AttrChars = ".";
  3111.  
  3112.   ValidSegs = (1 << SegCode);
  3113.   Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
  3114.   SegLimits[SegCode] = IntTypeDefs[pCurrCPUProps->MemIntType].Max;
  3115.  
  3116.   MakeCode = MakeCode_NS32K;
  3117.   IsDef = IsDef_NS32K;
  3118.   DissectReg = DissectReg_NS32K;
  3119.   InternSymbol = InternSymbol_NS32K;
  3120.   SwitchFrom = DeinitFields;
  3121.   IntConstModeIBMNoTerm = True;
  3122.   QualifyQuote = QualifyQuote_SingleQuoteConstant;
  3123.   InitFields();
  3124.   onoff_supmode_add();
  3125.   onoff_bigendian_add();
  3126.   if (!onoff_test_and_set(e_onoff_reg_custom))
  3127.     SetFlag(&CustomAvail, CustomAvailSymName, False);
  3128.   AddONOFF(CustomAvailCmdName, &CustomAvail, CustomAvailSymName, False);
  3129. }
  3130.  
  3131. /*!------------------------------------------------------------------------
  3132.  * \fn     codens32000_init(void)
  3133.  * \brief  register target to AS
  3134.  * ------------------------------------------------------------------------ */
  3135.  
  3136. static const tCPUProps CPUProps[] =
  3137. {
  3138.   { "NS16008", eCoreGen1   , eFPU16081, ePMMU16082, UInt24 },
  3139.   { "NS32008", eCoreGen1   , eFPU32081, ePMMU32082, UInt24 },
  3140.   { "NS08032", eCoreGen1   , eFPU32081, ePMMU32082, UInt24 },
  3141.   { "NS16032", eCoreGen1   , eFPU16081, ePMMU16082, UInt24 },
  3142.   { "NS32016", eCoreGen1   , eFPU32081, ePMMU32082, UInt24 },
  3143.   { "NS32032", eCoreGen1   , eFPU32081, ePMMU32082, UInt24 },
  3144.   { "NS32332", eCoreGen1Ext, eFPU32381, ePMMU32382, UInt32 },
  3145.   { "NS32CG16",eCoreGenE   , eFPU32181, ePMMU32082, UInt24 },
  3146.   { "NS32532", eCoreGen2   , eFPU32381, ePMMU32532, UInt32 },
  3147.   { NULL     , eCoreNone   , eFPUNone , ePMMUNone , UInt1  }
  3148. };
  3149.  
  3150. void codens32k_init(void)
  3151. {
  3152.   const tCPUProps *pRun;
  3153.  
  3154.   for (pRun = CPUProps; pRun->pName; pRun++)
  3155.     (void)AddCPUUser(pRun->pName, SwitchTo_NS32K, (void*)pRun, NULL);
  3156.  
  3157.   AddInitPassProc(InitCode_NS32K);
  3158. }
  3159.