Subversion Repositories pentevo

Rev

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

  1. /* code29k.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator AM29xxx-Familie                                             */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "nls.h"
  16. #include "strutil.h"
  17. #include "bpemu.h"
  18. #include "stringlists.h"
  19. #include "asmdef.h"
  20. #include "asmsub.h"
  21. #include "asmpars.h"
  22. #include "asmallg.h"
  23. #include "onoff_common.h"
  24. #include "asmitree.h"
  25. #include "codepseudo.h"
  26. #include "intpseudo.h"
  27. #include "codevars.h"
  28. #include "errmsg.h"
  29.  
  30. #include "code29k.h"
  31.  
  32. typedef struct
  33. {
  34.   Boolean MustSup;
  35.   CPUVar MinCPU;
  36.   LongWord Code;
  37. } StdOrder;
  38.  
  39. typedef struct
  40. {
  41.   Boolean HasReg, HasInd;
  42.   CPUVar MinCPU;
  43.   LongWord Code;
  44. } JmpOrder;
  45.  
  46. typedef struct
  47. {
  48.   const char *Name;
  49.   LongWord Code;
  50. } SPReg;
  51.  
  52. #define REG_LRMARK 256
  53.  
  54. static StdOrder *StdOrders;
  55. static StdOrder *NoImmOrders;
  56. static StdOrder *VecOrders;
  57. static JmpOrder *JmpOrders;
  58. static StdOrder *FixedOrders;
  59. static StdOrder *MemOrders;
  60. static SPReg *SPRegs;
  61.  
  62.  
  63. static CPUVar CPU29000, CPU29240, CPU29243, CPU29245;
  64. static LongInt Reg_RBP;
  65. static StringList Emulations;
  66.  
  67. /*-------------------------------------------------------------------------*/
  68.  
  69. static Boolean ChkSup(void)
  70. {
  71.   if (!SupAllowed)
  72.     WrError(ErrNum_PrivOrder);
  73.   return SupAllowed;
  74. }
  75.  
  76. static Boolean IsSup(LongWord RegNo)
  77. {
  78.   return ((RegNo < 0x80) || (RegNo >= 0xa0));
  79. }
  80.  
  81. static Boolean ChkCPU(CPUVar Min)
  82. {
  83.   return StringListPresent(Emulations, OpPart.str.p_str) ? True : ChkMinCPU(Min);
  84. }
  85.  
  86. /*-------------------------------------------------------------------------*/
  87.  
  88. /*!------------------------------------------------------------------------
  89.  * \fn     DecodeRegCore(const char *pArg, LongWord *pResult)
  90.  * \brief  check whether argument describes a CPU register
  91.  * \param  pArg source argument
  92.  * \param  pResult resulting register # if yes
  93.  * \return True if yes
  94.  * ------------------------------------------------------------------------ */
  95.  
  96. static Boolean DecodeRegCore(const char *pArg, LongWord *pResult)
  97. {
  98.   int l = strlen(pArg);
  99.   Boolean OK;
  100.  
  101.   if ((l >= 2) && (as_toupper(*pArg) == 'R'))
  102.   {
  103.     *pResult = ConstLongInt(pArg + 1, &OK, 10);
  104.     return OK && (*pResult <= 255);
  105.   }
  106.   else if ((l >= 3) && (as_toupper(*pArg) == 'G') && (as_toupper(pArg[1]) == 'R'))
  107.   {
  108.     *pResult = ConstLongInt(pArg + 2, &OK, 10);
  109.     if (!OK || (*pResult >= 128))
  110.       return False;
  111.     *pResult |= REG_LRMARK;
  112.     return True;
  113.   }
  114.   else if ((l >= 3) && (as_toupper(*pArg) == 'L') && (as_toupper(pArg[1]) == 'R'))
  115.   {
  116.     *pResult = ConstLongInt(pArg + 2, &OK, 10);
  117.     if (!OK || (*pResult >= 128))
  118.       return False;
  119.     *pResult |= 128 | REG_LRMARK;
  120.     return True;
  121.   }
  122.   else
  123.     return False;
  124. }
  125.  
  126. /*!------------------------------------------------------------------------
  127.  * \fn     DissectReg_29K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  128.  * \brief  dissect register symbols - 29K variant
  129.  * \param  pDest destination buffer
  130.  * \param  DestSize destination buffer size
  131.  * \param  Value numeric register value
  132.  * \param  InpSize register size
  133.  * ------------------------------------------------------------------------ */
  134.  
  135. static void DissectReg_29K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
  136. {
  137.   switch (InpSize)
  138.   {
  139.     case eSymbolSize32Bit:
  140.       if (Value & REG_LRMARK)
  141.         as_snprintf(pDest, DestSize, "%cR%u", "GL"[(Value >> 7) & 1], (unsigned)(Value & 127));
  142.       else
  143.         as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
  144.       break;
  145.     default:
  146.       as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
  147.   }
  148. }
  149.  
  150. /*!------------------------------------------------------------------------
  151.  * \fn     compare_reg_29k(tRegInt reg1_num, tSymbolSize reg1_size, tRegInt reg2_num, tRegInt reg2_size)
  152.  * \brief  compare two register symbols
  153.  * \param  reg1_num 1st register's number
  154.  * \param  reg1_size 1st register's data size
  155.  * \param  reg2_num 2nd register's number
  156.  * \param  reg2_size 2nd register's data size
  157.  * \return 0, -1, 1, -2
  158.  * ------------------------------------------------------------------------ */
  159.  
  160. static int compare_reg_29k(tRegInt reg1_num, tSymbolSize size1, tRegInt reg2_num, tSymbolSize size2)
  161. {
  162.   if ((size1 != eSymbolSize32Bit) || (size2 != eSymbolSize32Bit))
  163.     return -2;
  164.  
  165.   /* We have up to 512 registers, which conflicts with the generic ALIAS flag in bit 7.
  166.      So we have to compare on our own.  R (0..255), GR (256...383), and LR (384...511)
  167.      spaces are disjoint: */
  168.  
  169.   if ((reg1_num ^ reg2_num) & REG_LRMARK)
  170.     return -2;
  171.  
  172.   if (reg1_num & REG_LRMARK)
  173.   {
  174.     if ((reg1_num ^ reg2_num) & 128)
  175.       return -2;
  176.     reg1_num &= 127;
  177.     reg2_num &= 127;
  178.   }
  179.   else
  180.   {
  181.     reg1_num &= 255;
  182.     reg2_num &= 255;
  183.   }
  184.  
  185.   if (reg1_num < reg2_num)
  186.     return -1;
  187.   else if (reg1_num > reg2_num)
  188.     return 1;
  189.   else
  190.     return 0;
  191. }
  192.  
  193. /*!------------------------------------------------------------------------
  194.  * \fn     DecodeReg(const tStrComp *pArg, LongWord *pResult, Boolean MustBeReg)
  195.  * \brief  check whether argument describes a CPU register
  196.  * \param  pArg source argument
  197.  * \param  pResult resulting register # if yes
  198.  * \param  MustBeReg True if register is expected
  199.  * \return reg eval result
  200.  * ------------------------------------------------------------------------ */
  201.  
  202. static tRegEvalResult DecodeReg(const tStrComp *pArg, LongWord *pResult, Boolean MustBeReg)
  203. {
  204.   tRegEvalResult RegEvalResult;
  205.   tEvalResult EvalResult;
  206.   tRegDescr RegDescr;
  207.  
  208.   if (DecodeRegCore(pArg->str.p_str, pResult))
  209.     RegEvalResult = eIsReg;
  210.   else
  211.   {
  212.     RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize32Bit, MustBeReg);
  213.     if (eIsReg == RegEvalResult)
  214.       *pResult = RegDescr.Reg;
  215.   }
  216.  
  217.   if (eIsReg == RegEvalResult)
  218.   {
  219.     *pResult &= ~REG_LRMARK;
  220.     if ((*pResult < 127) && (Odd(Reg_RBP >> (*pResult >> 4))))
  221.     {
  222.       if (!ChkSup())
  223.         RegEvalResult = MustBeReg ? eIsNoReg : eRegAbort;
  224.     }
  225.   }
  226.   return RegEvalResult;
  227. }
  228.  
  229. static Boolean DecodeArgReg(int ArgIndex, LongWord *pRes)
  230. {
  231.   return DecodeReg(&ArgStr[ArgIndex], pRes, True);
  232. }
  233.  
  234. static Boolean DecodeSpReg(char *Asc_O, LongWord *Erg)
  235. {
  236.   int z;
  237.   String Asc;
  238.  
  239.   strmaxcpy(Asc, Asc_O, STRINGSIZE);
  240.   NLS_UpString(Asc);
  241.   for (z = 0; SPRegs[z].Name; z++)
  242.     if (!strcmp(Asc, SPRegs[z].Name))
  243.     {
  244.       *Erg = SPRegs[z].Code;
  245.       return True;;
  246.     }
  247.   return False;;
  248. }
  249.  
  250. static Boolean DecodeArgSpReg(int ArgIndex, LongWord *pRes)
  251. {
  252.   Boolean Result = DecodeSpReg(ArgStr[ArgIndex].str.p_str, pRes);
  253.  
  254.   if (!Result)
  255.     WrStrErrorPos(ErrNum_InvCtrlReg, &ArgStr[ArgIndex]);
  256.   return Result;
  257. }
  258.  
  259. /*-------------------------------------------------------------------------*/
  260.  
  261. /* Variante 1: Register <-- Register op Register/uimm8 */
  262.  
  263. static void DecodeStd(Word Index)
  264. {
  265.   const StdOrder *pOrder = StdOrders + Index;
  266.   LongWord Dest, Src1, Src2, Src3;
  267.   Boolean OK;
  268.  
  269.   if (ChkArgCnt(2, 3) && DecodeArgReg(1, &Dest))
  270.   {
  271.     OK = True;
  272.     if (ArgCnt == 2) Src1 = Dest;
  273.     else OK = DecodeArgReg(2, &Src1);
  274.     if (OK)
  275.     {
  276.       switch (DecodeReg(&ArgStr[ArgCnt], &Src2, False))
  277.       {
  278.         case eIsReg:
  279.           OK = True; Src3 = 0;
  280.           break;
  281.         case eIsNoReg:
  282.           Src2 = EvalStrIntExpression(&ArgStr[ArgCnt], UInt8, &OK);
  283.           Src3 = 0x1000000;
  284.           break;
  285.         case eRegAbort:
  286.           return;
  287.       }
  288.       if (OK)
  289.       {
  290.         CodeLen = 4;
  291.         DAsmCode[0] = (pOrder->Code << 24) + Src3 + (Dest << 16) + (Src1 << 8) + Src2;
  292.         if (pOrder->MustSup)
  293.           ChkSup();
  294.       }
  295.     }
  296.   }
  297. }
  298.  
  299. /* Variante 2: Register <-- Register op Register */
  300.  
  301. static void DecodeNoImm(Word Index)
  302. {
  303.   const StdOrder *pOrder = NoImmOrders + Index;
  304.   Boolean OK;
  305.   LongWord Dest, Src1, Src2;
  306.  
  307.   if (ChkArgCnt(2, 3) && DecodeArgReg(1, &Dest))
  308.   {
  309.     OK = True;
  310.     if (ArgCnt == 2) Src1 = Dest;
  311.     else OK = DecodeArgReg(2, &Src1);
  312.     if (OK && DecodeArgReg(ArgCnt, &Src2))
  313.     {
  314.       CodeLen = 4;
  315.       DAsmCode[0] = (pOrder->Code << 24) + (Dest << 16) + (Src1 << 8) + Src2;
  316.       if (pOrder->MustSup)
  317.         ChkSup();
  318.     }
  319.   }
  320. }
  321.  
  322. /* Variante 3: Vektor <-- Register op Register/uimm8 */
  323.  
  324. static void DecodeVec(Word Index)
  325. {
  326.   const StdOrder *pOrder = VecOrders + Index;
  327.   Boolean OK;
  328.   tSymbolFlags Flags;
  329.   LongWord Dest, Src1, Src2, Src3;
  330.  
  331.   if (ChkArgCnt(3, 3))
  332.   {
  333.     Dest = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt8, &OK, &Flags);
  334.     if (mFirstPassUnknown(Flags)) Dest = 64;
  335.     if (OK)
  336.     {
  337.       if (DecodeArgReg(2, &Src1))
  338.       {
  339.         switch (DecodeReg(&ArgStr[ArgCnt], &Src2, False))
  340.         {
  341.           case eIsReg:
  342.             OK = True; Src3 = 0;
  343.             break;
  344.           case eIsNoReg:
  345.             Src2 = EvalStrIntExpression(&ArgStr[ArgCnt], UInt8, &OK);
  346.             Src3 = 0x1000000;
  347.             break;
  348.           default:
  349.             return;
  350.         }
  351.         if (OK)
  352.         {
  353.           CodeLen = 4;
  354.           DAsmCode[0] = (pOrder->Code << 24) + Src3 + (Dest << 16) + (Src1 << 8) + Src2;
  355.           if ((pOrder->MustSup) || (Dest <= 63))
  356.             ChkSup();
  357.         }
  358.       }
  359.     }
  360.   }
  361. }
  362.  
  363. /* Variante 4: ohne Operanden */
  364.  
  365. static void DecodeFixed(Word Code)
  366. {
  367.   const StdOrder *pOrder = FixedOrders + Code;
  368.  
  369.   if (ChkArgCnt(0, 0))
  370.   {
  371.     CodeLen = 4;
  372.     DAsmCode[0] = pOrder->Code << 24;
  373.     if (pOrder->MustSup)
  374.       ChkSup();
  375.   }
  376. }
  377.  
  378. /* Variante 5 : [0], Speichersteuerwort, Register, Register/uimm8 */
  379.  
  380. static void DecodeMem(Word Index)
  381. {
  382.   const StdOrder *pOrder = MemOrders + Index;
  383.   Boolean OK;
  384.   LongWord AdrLong, Dest, Src1, Src2, Src3;
  385.  
  386.   if (ChkArgCnt(3, 4))
  387.   {
  388.     if (ArgCnt == 3)
  389.     {
  390.       OK = True; AdrLong = 0;
  391.     }
  392.     else
  393.     {
  394.       AdrLong = EvalStrIntExpression(&ArgStr[1], Int32, &OK);
  395.       if (OK) OK = ChkRange(AdrLong, 0, 0);
  396.     }
  397.     if (OK)
  398.     {
  399.       Dest = EvalStrIntExpression(&ArgStr[ArgCnt - 2], UInt7, &OK);
  400.       if (OK && DecodeArgReg(ArgCnt - 1, &Src1))
  401.       {
  402.         switch (DecodeReg(&ArgStr[ArgCnt], &Src2, False))
  403.         {
  404.           case eIsReg:
  405.             OK = True; Src3 = 0;
  406.             break;
  407.           case eIsNoReg:
  408.             Src2 = EvalStrIntExpression(&ArgStr[ArgCnt], UInt8, &OK);
  409.             Src3 = 0x1000000;
  410.             break;
  411.           default:
  412.             return;
  413.         }
  414.         if (OK)
  415.         {
  416.           CodeLen = 4;
  417.           DAsmCode[0] = (pOrder->Code << 24) + Src3 + (Dest << 16) + (Src1 << 8) + Src2;
  418.           if (pOrder->MustSup)
  419.             ChkSup();
  420.         }
  421.       }
  422.     }
  423.   }
  424. }
  425.  
  426. /* Sprungbefehle */
  427.  
  428. static void DecodeJmp(Word Index)
  429. {
  430.   const JmpOrder *pOrder = JmpOrders + (Index & 0xff);
  431.   Word Immediate = Index & 0x100;
  432.   LongWord Dest, Src1, AdrLong;
  433.   LongInt AdrInt;
  434.   Boolean OK;
  435.   tSymbolFlags Flags;
  436.   unsigned NumArgs = 1 + Ord(pOrder->HasReg);
  437.  
  438.   if (!ChkArgCnt(NumArgs, NumArgs))
  439.     return;
  440.  
  441.   switch (DecodeReg(&ArgStr[ArgCnt], &Src1, False))
  442.   {
  443.     case eIsReg:
  444.       if (!pOrder->HasReg)
  445.       {
  446.         Dest = 0;
  447.         OK = True;
  448.       }
  449.       else
  450.         OK = DecodeReg(&ArgStr[1], &Dest, True);
  451.       if (OK)
  452.       {
  453.         CodeLen = 4;
  454.         DAsmCode[0] = ((pOrder->Code + 0x20) << 24) + (Dest << 8) + Src1;
  455.       }
  456.       break;
  457.     case eRegAbort:
  458.       return;
  459.     case eIsNoReg:
  460.       if (Immediate) WrError(ErrNum_InvAddrMode);
  461.       else
  462.       {
  463.         if (!pOrder->HasReg)
  464.         {
  465.           Dest = 0;
  466.           OK = True;
  467.         }
  468.         else
  469.           OK = DecodeReg(&ArgStr[1], &Dest, True);
  470.         if (OK)
  471.         {
  472.           AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int32, &OK, &Flags);
  473.           AdrInt = AdrLong - EProgCounter();
  474.           if (OK)
  475.           {
  476.             if ((AdrLong & 3) != 0) WrError(ErrNum_NotAligned);
  477.              else if ((AdrInt <= 0x1ffff) && (AdrInt >= -0x20000))
  478.             {
  479.               CodeLen = 4;
  480.               AdrLong -= EProgCounter();
  481.               DAsmCode[0] = (pOrder->Code << 24)
  482.                           + ((AdrLong & 0x3fc00) << 6)
  483.                           + (Dest << 8) + ((AdrLong & 0x3fc) >> 2);
  484.             }
  485.             else if (!mSymbolQuestionable(Flags) && (AdrLong > 0x3fffff)) WrError(ErrNum_JmpDistTooBig);
  486.             else
  487.             {
  488.               CodeLen = 4;
  489.               DAsmCode[0] = ((pOrder->Code + 1) << 24)
  490.                           + ((AdrLong & 0x3fc00) << 6)
  491.                           + (Dest << 8) + ((AdrLong & 0x3fc) >> 2);
  492.             }
  493.           }
  494.         }
  495.       }
  496.   }
  497. }
  498.  
  499. static void DecodeCLASS(Word Code)
  500. {
  501.   LongWord Dest, Src1, Src2;
  502.   Boolean OK;
  503.  
  504.   UNUSED(Code);
  505.  
  506.   if (ChkArgCnt(3, 3)
  507.    && ChkCPU(CPU29000)
  508.    && DecodeArgReg(1, &Dest)
  509.    && DecodeArgReg(2, &Src1))
  510.   {
  511.     Src2 = EvalStrIntExpression(&ArgStr[3], UInt2, &OK);
  512.     if (OK)
  513.     {
  514.       CodeLen = 4;
  515.       DAsmCode[0] = 0xe6000000 + (Dest << 16) + (Src1 << 8) + Src2;
  516.     }
  517.   }
  518. }
  519.  
  520. static void DecodeEMULATE(Word Code)
  521. {
  522.   LongWord Dest, Src1, Src2;
  523.   Boolean OK;
  524.   tSymbolFlags Flags;
  525.  
  526.   UNUSED(Code);
  527.  
  528.   if (ChkArgCnt(3, 3))
  529.   {
  530.     Dest = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt8, &OK, &Flags);
  531.     if (mFirstPassUnknown(Flags)) Dest = 64;
  532.     if (OK)
  533.     {
  534.       if (DecodeArgReg(2, &Src1)
  535.        && DecodeArgReg(ArgCnt, &Src2))
  536.       {
  537.         CodeLen = 4;
  538.         DAsmCode[0] = 0xd7000000 + (Dest << 16) + (Src1 << 8) + Src2;
  539.         if (Dest <= 63)
  540.           ChkSup();
  541.       }
  542.     }
  543.   }
  544. }
  545.  
  546. static void DecodeSQRT(Word Code)
  547. {
  548.   Boolean OK;
  549.   LongWord Src1, Src2, Dest;
  550.  
  551.   UNUSED(Code);
  552.  
  553.   if (ChkArgCnt(2, 3)
  554.    && ChkCPU(CPU29000)
  555.    && DecodeArgReg(1, &Dest))
  556.   {
  557.     if (ArgCnt == 2)
  558.     {
  559.       OK = True;
  560.       Src1 = Dest;
  561.     }
  562.     else
  563.       OK = DecodeArgReg(2, &Src1);
  564.     if (OK)
  565.     {
  566.       Src2 = EvalStrIntExpression(&ArgStr[ArgCnt], UInt2, &OK);
  567.       if (OK)
  568.       {
  569.         CodeLen = 4;
  570.         DAsmCode[0] = 0xe5000000 + (Dest << 16) + (Src1 << 8) + Src2;
  571.       }
  572.     }
  573.   }
  574. }
  575.  
  576. static void DecodeCLZ(Word Code)
  577. {
  578.   Boolean OK;
  579.   LongWord Src1, Src3, Dest;
  580.  
  581.   UNUSED(Code);
  582.  
  583.   if (ChkArgCnt(2, 2) && DecodeArgReg(1, &Dest))
  584.   {
  585.     switch (DecodeReg(&ArgStr[2], &Src1, False))
  586.     {
  587.       case eIsReg:
  588.         OK = True; Src3 = 0;
  589.         break;
  590.       case eIsNoReg:
  591.         Src1 = EvalStrIntExpression(&ArgStr[2], UInt8, &OK);
  592.         Src3 = 0x1000000;
  593.         break;
  594.       default:
  595.         return;
  596.     }
  597.     if (OK)
  598.     {
  599.       CodeLen = 4;
  600.       DAsmCode[0] = 0x08000000 + Src3 + (Dest << 16) + Src1;
  601.     }
  602.   }
  603. }
  604.  
  605. static void DecodeCONST(Word Code)
  606. {
  607.   Boolean OK;
  608.   LongWord AdrLong, Dest;
  609.   UNUSED(Code);
  610.  
  611.   if (ChkArgCnt(2, 2) && DecodeArgReg(1, &Dest))
  612.   {
  613.     AdrLong = EvalStrIntExpression(&ArgStr[2], Int32, &OK);
  614.     if (OK)
  615.     {
  616.       CodeLen = 4;
  617.       DAsmCode[0] = ((AdrLong & 0xff00) << 8) + (Dest << 8) + (AdrLong & 0xff);
  618.       AdrLong = AdrLong >> 16;
  619.       if (AdrLong == 0xffff) DAsmCode[0] += 0x01000000;
  620.       else
  621.       {
  622.         DAsmCode[0] += 0x03000000;
  623.         if (AdrLong != 0)
  624.         {
  625.           CodeLen = 8;
  626.           DAsmCode[1] = 0x02000000 + ((AdrLong & 0xff00) << 16) + (Dest << 8) + (AdrLong & 0xff);
  627.         }
  628.       }
  629.     }
  630.   }
  631.   return;
  632. }
  633.  
  634. static void DecodeCONSTH_CONSTN(Word IsHi)
  635. {
  636.   Boolean OK;
  637.   LongWord AdrLong, Dest;
  638.   tSymbolFlags Flags;
  639.  
  640.   if (ChkArgCnt(2, 2) && DecodeArgReg(1, &Dest))
  641.   {
  642.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &OK, &Flags);
  643.     if (mFirstPassUnknown(Flags))
  644.       AdrLong &= 0xffff;
  645.     if ((!IsHi) && ((AdrLong >> 16) == 0xffff))
  646.       AdrLong &= 0xffff;
  647.     if (ChkRange(AdrLong, 0, 0xffff))
  648.     {
  649.       CodeLen = 4;
  650.       DAsmCode[0] = 0x1000000 + ((AdrLong & 0xff00) << 8) + (Dest << 8) + (AdrLong & 0xff);
  651.       if (IsHi)
  652.         DAsmCode[0] += 0x1000000;
  653.     }
  654.   }
  655. }
  656.  
  657. static void DecodeCONVERT(Word Code)
  658. {
  659.   Boolean OK;
  660.   LongWord Src1, Src2, Dest;
  661.  
  662.   UNUSED(Code);
  663.  
  664.   if (ChkArgCnt(6, 6)
  665.    && ChkCPU(CPU29000)
  666.    && DecodeArgReg(1, &Dest)
  667.    && DecodeArgReg(2, &Src1))
  668.   {
  669.     Src2 = 0;
  670.     Src2 += EvalStrIntExpression(&ArgStr[3], UInt1, &OK) << 7;
  671.     if (OK)
  672.     {
  673.       Src2 += EvalStrIntExpression(&ArgStr[4], UInt3, &OK) << 4;
  674.       if (OK)
  675.       {
  676.         Src2 += EvalStrIntExpression(&ArgStr[5], UInt2, &OK) << 2;
  677.         if (OK)
  678.         {
  679.           Src2 += EvalStrIntExpression(&ArgStr[6], UInt2, &OK);
  680.           if (OK)
  681.           {
  682.             CodeLen = 4;
  683.             DAsmCode[0] = 0xe4000000 + (Dest << 16) + (Src1 << 8) + Src2;
  684.           }
  685.         }
  686.       }
  687.     }
  688.   }
  689. }
  690.  
  691. static void DecodeEXHWS(Word Code)
  692. {
  693.   LongWord Src1, Dest;
  694.  
  695.   UNUSED(Code);
  696.  
  697.   if (ChkArgCnt(2, 2)
  698.    && DecodeArgReg(1, &Dest)
  699.    && DecodeArgReg(2, &Src1))
  700.   {
  701.     CodeLen = 4;
  702.     DAsmCode[0] = 0x7e000000 + (Dest << 16) + (Src1 << 8);
  703.   }
  704. }
  705.  
  706. static void DecodeINV_IRETINV(Word Code)
  707. {
  708.   Boolean OK;
  709.   LongWord Src1;
  710.  
  711.   if (ChkArgCnt(0, 1))
  712.   {
  713.     if (ArgCnt == 0)
  714.     {
  715.       Src1 = 0; OK = True;
  716.     }
  717.     else Src1 = EvalStrIntExpression(&ArgStr[1], UInt2, &OK);
  718.     if (OK)
  719.     {
  720.       CodeLen = 4;
  721.       DAsmCode[0] = (((LongWord)Code) << 16) | Src1 << 16;
  722.       ChkSup();
  723.     }
  724.   }
  725. }
  726.  
  727. static void DecodeMFSR(Word Code)
  728. {
  729.   LongWord Src1, Dest;
  730.  
  731.   UNUSED(Code);
  732.  
  733.   if (ChkArgCnt(2, 2)
  734.    && DecodeArgReg(1, &Dest)
  735.    && DecodeArgSpReg(2, &Src1))
  736.   {
  737.     DAsmCode[0] = 0xc6000000 + (Dest << 16) + (Src1 << 8);
  738.     CodeLen = 4;
  739.     if (IsSup(Src1))
  740.       ChkSup();
  741.   }
  742. }
  743.  
  744. static void DecodeMTSR(Word Code)
  745. {
  746.   LongWord Src1, Dest;
  747.  
  748.   UNUSED(Code);
  749.  
  750.   if (ChkArgCnt(2, 2)
  751.    && DecodeArgSpReg(1, &Dest)
  752.    && DecodeArgReg(2, &Src1))
  753.   {
  754.     DAsmCode[0] = 0xce000000 + (Dest << 8) + Src1;
  755.     CodeLen = 4;
  756.     if (IsSup(Dest))
  757.       ChkSup();
  758.   }
  759. }
  760.  
  761. static void DecodeMTSRIM(Word Code)
  762. {
  763.   LongWord Src1, Dest;
  764.   Boolean OK;
  765.  
  766.   UNUSED(Code);
  767.  
  768.   if (ChkArgCnt(2, 2) && DecodeArgSpReg(1, &Dest))
  769.   {
  770.     Src1 = EvalStrIntExpression(&ArgStr[2], UInt16, &OK);
  771.     if (OK)
  772.     {
  773.       DAsmCode[0] = 0x04000000 + ((Src1 & 0xff00) << 8) + (Dest << 8) + Lo(Src1);
  774.       CodeLen = 4;
  775.       if (IsSup(Dest))
  776.         ChkSup();
  777.     }
  778.   }
  779. }
  780.  
  781. static void DecodeMFTLB(Word Code)
  782. {
  783.   LongWord Src1, Dest;
  784.  
  785.   UNUSED(Code);
  786.  
  787.   if (ChkArgCnt(2, 2)
  788.    && DecodeArgReg(1, &Dest)
  789.    && DecodeArgReg(2, &Src1))
  790.   {
  791.     DAsmCode[0] = 0xb6000000 + (Dest << 16) + (Src1 << 8);
  792.     CodeLen = 4;
  793.     ChkSup();
  794.   }
  795. }
  796.  
  797. static void DecodeMTTLB(Word Code)
  798. {
  799.   LongWord Src1, Dest;
  800.  
  801.   UNUSED(Code);
  802.  
  803.   if (ChkArgCnt(2, 2)
  804.    && DecodeArgReg(1, &Dest)
  805.    && DecodeArgReg(2, &Src1))
  806.   {
  807.     DAsmCode[0] = 0xbe000000 + (Dest << 8) + Src1;
  808.     CodeLen = 4;
  809.     ChkSup();
  810.   }
  811. }
  812.  
  813. static void DecodeEMULATED(Word Code)
  814. {
  815.   int z;
  816.  
  817.   UNUSED(Code);
  818.  
  819.   if (ChkArgCnt(1, ArgCntMax))
  820.     for (z = 1; z <= ArgCnt; z++)
  821.     {
  822.       NLS_UpString(ArgStr[z].str.p_str);
  823.       if (!StringListPresent(Emulations, ArgStr[z].str.p_str))
  824.         AddStringListLast(&Emulations, ArgStr[z].str.p_str);
  825.     }
  826. }
  827.  
  828. /*-------------------------------------------------------------------------*/
  829.  
  830. static void AddStd(const char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
  831. {
  832.   order_array_rsv_end(StdOrders, StdOrder);
  833.   StdOrders[InstrZ].Code = NCode;
  834.   StdOrders[InstrZ].MustSup = NSup;
  835.   StdOrders[InstrZ].MinCPU = NMin;
  836.   AddInstTable(InstTable, NName, InstrZ++, DecodeStd);
  837. }
  838.  
  839. static void AddNoImm(const char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
  840. {
  841.   order_array_rsv_end(NoImmOrders, StdOrder);
  842.   NoImmOrders[InstrZ].Code = NCode;
  843.   NoImmOrders[InstrZ].MustSup = NSup;
  844.   NoImmOrders[InstrZ].MinCPU = NMin;
  845.   AddInstTable(InstTable, NName, InstrZ++, DecodeNoImm);
  846. }
  847.  
  848. static void AddVec(const char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
  849. {
  850.   order_array_rsv_end(VecOrders, StdOrder);
  851.   VecOrders[InstrZ].Code = NCode;
  852.   VecOrders[InstrZ].MustSup = NSup;
  853.   VecOrders[InstrZ].MinCPU = NMin;
  854.   AddInstTable(InstTable, NName, InstrZ++, DecodeVec);
  855. }
  856.  
  857. static void AddJmp(const char *NName, CPUVar NMin, Boolean NHas, Boolean NInd, LongWord NCode)
  858. {
  859.   char IName[30];
  860.  
  861.   order_array_rsv_end(JmpOrders, JmpOrder);
  862.   JmpOrders[InstrZ].HasReg = NHas;
  863.   JmpOrders[InstrZ].HasInd = NInd;
  864.   JmpOrders[InstrZ].Code = NCode;
  865.   JmpOrders[InstrZ].MinCPU = NMin;
  866.   AddInstTable(InstTable, NName, InstrZ, DecodeJmp);
  867.   as_snprintf(IName, sizeof(IName), "%sI", NName);
  868.   AddInstTable(InstTable, IName, 0x100 | InstrZ, DecodeJmp);
  869.   InstrZ++;
  870. }
  871.  
  872. static void AddFixed(const char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
  873. {
  874.   order_array_rsv_end(FixedOrders, StdOrder);
  875.   FixedOrders[InstrZ].Code = NCode;
  876.   FixedOrders[InstrZ].MustSup = NSup;
  877.   FixedOrders[InstrZ].MinCPU = NMin;
  878.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  879. }
  880.  
  881. static void AddMem(const char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
  882. {
  883.   order_array_rsv_end(MemOrders, StdOrder);
  884.   MemOrders[InstrZ].Code = NCode;
  885.   MemOrders[InstrZ].MustSup = NSup;
  886.   MemOrders[InstrZ].MinCPU = NMin;
  887.   AddInstTable(InstTable, NName, InstrZ++, DecodeMem);
  888. }
  889.  
  890. static void AddSP(const char *NName, LongWord NCode)
  891. {
  892.   order_array_rsv_end(SPRegs, SPReg);
  893.   SPRegs[InstrZ].Name = NName;
  894.   SPRegs[InstrZ++].Code = NCode;
  895. }
  896.  
  897. static void InitFields(void)
  898. {
  899.   InstTable = CreateInstTable(307);
  900.   SetDynamicInstTable(InstTable);
  901.   AddInstTable(InstTable, "CLASS", 0, DecodeCLASS);
  902.   AddInstTable(InstTable, "EMULATE", 0, DecodeEMULATE);
  903.   AddInstTable(InstTable, "SQRT", 0, DecodeSQRT);
  904.   AddInstTable(InstTable, "CLZ", 0, DecodeCLZ);
  905.   AddInstTable(InstTable, "CONST", 0, DecodeCONST);
  906.   AddInstTable(InstTable, "CONSTH", True, DecodeCONSTH_CONSTN);
  907.   AddInstTable(InstTable, "CONSTN", False, DecodeCONSTH_CONSTN);
  908.   AddInstTable(InstTable, "CONVERT", 0, DecodeCONVERT);
  909.   AddInstTable(InstTable, "EXHWS", 0, DecodeEXHWS);
  910.   AddInstTable(InstTable, "INV", 0x9f00, DecodeINV_IRETINV);
  911.   AddInstTable(InstTable, "IRETINV", 0x8c00, DecodeINV_IRETINV);
  912.   AddInstTable(InstTable, "MFSR", 0, DecodeMFSR);
  913.   AddInstTable(InstTable, "MTSR", 0, DecodeMTSR);
  914.   AddInstTable(InstTable, "MTSRIM", 0, DecodeMTSRIM);
  915.   AddInstTable(InstTable, "MFTLB", 0, DecodeMFTLB);
  916.   AddInstTable(InstTable, "MTTLB", 0, DecodeMTTLB);
  917.   AddInstTable(InstTable, "EMULATED", 0, DecodeEMULATED);
  918.   AddInstTable(InstTable, "REG", 0, CodeREG);
  919.  
  920.   InstrZ = 0;
  921.   AddStd("ADD"    , CPU29245, False, 0x14); AddStd("ADDC"   , CPU29245, False, 0x1c);
  922.   AddStd("ADDCS"  , CPU29245, False, 0x18); AddStd("ADDCU"  , CPU29245, False, 0x1a);
  923.   AddStd("ADDS"   , CPU29245, False, 0x10); AddStd("ADDU"   , CPU29245, False, 0x12);
  924.   AddStd("AND"    , CPU29245, False, 0x90); AddStd("ANDN"   , CPU29245, False, 0x9c);
  925.   AddStd("CPBYTE" , CPU29245, False, 0x2e); AddStd("CPEQ"   , CPU29245, False, 0x60);
  926.   AddStd("CPGE"   , CPU29245, False, 0x4c); AddStd("CPGEU"  , CPU29245, False, 0x4e);
  927.   AddStd("CPGT"   , CPU29245, False, 0x48); AddStd("CPGTU"  , CPU29245, False, 0x4a);
  928.   AddStd("CPLE"   , CPU29245, False, 0x44); AddStd("CPLEU"  , CPU29245, False, 0x46);
  929.   AddStd("CPLT"   , CPU29245, False, 0x40); AddStd("CPLTU"  , CPU29245, False, 0x42);
  930.   AddStd("CPNEQ"  , CPU29245, False, 0x62); AddStd("DIV"    , CPU29245, False, 0x6a);
  931.   AddStd("DIV0"   , CPU29245, False, 0x68); AddStd("DIVL"   , CPU29245, False, 0x6c);
  932.   AddStd("DIVREM" , CPU29245, False, 0x6e); AddStd("EXBYTE" , CPU29245, False, 0x0a);
  933.   AddStd("EXHW"   , CPU29245, False, 0x7c); AddStd("EXTRACT", CPU29245, False, 0x7a);
  934.   AddStd("INBYTE" , CPU29245, False, 0x0c); AddStd("INHW"   , CPU29245, False, 0x78);
  935.   AddStd("MUL"    , CPU29245, False, 0x64); AddStd("MULL"   , CPU29245, False, 0x66);
  936.   AddStd("MULU"   , CPU29245, False, 0x74); AddStd("NAND"   , CPU29245, False, 0x9a);
  937.   AddStd("NOR"    , CPU29245, False, 0x98); AddStd("OR"     , CPU29245, False, 0x92);
  938.   AddStd("SLL"    , CPU29245, False, 0x80); AddStd("SRA"    , CPU29245, False, 0x86);
  939.   AddStd("SRL"    , CPU29245, False, 0x82); AddStd("SUB"    , CPU29245, False, 0x24);
  940.   AddStd("SUBC"   , CPU29245, False, 0x2c); AddStd("SUBCS"  , CPU29245, False, 0x28);
  941.   AddStd("SUBCU"  , CPU29245, False, 0x2a); AddStd("SUBR"   , CPU29245, False, 0x34);
  942.   AddStd("SUBRC"  , CPU29245, False, 0x3c); AddStd("SUBRCS" , CPU29245, False, 0x38);
  943.   AddStd("SUBRCU" , CPU29245, False, 0x3a); AddStd("SUBRS"  , CPU29245, False, 0x30);
  944.   AddStd("SUBRU"  , CPU29245, False, 0x32); AddStd("SUBS"   , CPU29245, False, 0x20);
  945.   AddStd("SUBU"   , CPU29245, False, 0x22); AddStd("XNOR"   , CPU29245, False, 0x96);
  946.   AddStd("XOR"    , CPU29245, False, 0x94);
  947.  
  948.   InstrZ = 0;
  949.   AddNoImm("DADD"    , CPU29000, False, 0xf1); AddNoImm("DDIV"    , CPU29000, False, 0xf7);
  950.   AddNoImm("DEQ"     , CPU29000, False, 0xeb); AddNoImm("DGE"     , CPU29000, False, 0xef);
  951.   AddNoImm("DGT"     , CPU29000, False, 0xed); AddNoImm("DIVIDE"  , CPU29000, False, 0xe1);
  952.   AddNoImm("DIVIDU"  , CPU29000, False, 0xe3); AddNoImm("DMUL"    , CPU29000, False, 0xf5);
  953.   AddNoImm("DSUB"    , CPU29000, False, 0xf3); AddNoImm("FADD"    , CPU29000, False, 0xf0);
  954.   AddNoImm("FDIV"    , CPU29000, False, 0xf6); AddNoImm("FDMUL"   , CPU29000, False, 0xf9);
  955.   AddNoImm("FEQ"     , CPU29000, False, 0xea); AddNoImm("FGE"     , CPU29000, False, 0xee);
  956.   AddNoImm("FGT"     , CPU29000, False, 0xec); AddNoImm("FMUL"    , CPU29000, False, 0xf4);
  957.   AddNoImm("FSUB"    , CPU29000, False, 0xf2); AddNoImm("MULTIPLU", CPU29243, False, 0xe2);
  958.   AddNoImm("MULTIPLY", CPU29243, False, 0xe0); AddNoImm("MULTM"   , CPU29243, False, 0xde);
  959.   AddNoImm("MULTMU"  , CPU29243, False, 0xdf); AddNoImm("SETIP"   , CPU29245, False, 0x9e);
  960.  
  961.   InstrZ = 0;
  962.   AddVec("ASEQ"   , CPU29245, False, 0x70); AddVec("ASGE"   , CPU29245, False, 0x5c);
  963.   AddVec("ASGEU"  , CPU29245, False, 0x5e); AddVec("ASGT"   , CPU29245, False, 0x58);
  964.   AddVec("ASGTU"  , CPU29245, False, 0x5a); AddVec("ASLE"   , CPU29245, False, 0x54);
  965.   AddVec("ASLEU"  , CPU29245, False, 0x56); AddVec("ASLT"   , CPU29245, False, 0x50);
  966.   AddVec("ASLTU"  , CPU29245, False, 0x52); AddVec("ASNEQ"  , CPU29245, False, 0x72);
  967.  
  968.   InstrZ = 0;
  969.   AddJmp("CALL"   , CPU29245, True , True , 0xa8); AddJmp("JMP"    , CPU29245, False, True , 0xa0);
  970.   AddJmp("JMPF"   , CPU29245, True , True , 0xa4); AddJmp("JMPFDEC", CPU29245, True , False, 0xb4);
  971.   AddJmp("JMPT"   , CPU29245, True , True , 0xac);
  972.  
  973.   InstrZ = 0;
  974.   AddFixed("HALT"   , CPU29245, True, 0x89); AddFixed("IRET"   , CPU29245, True, 0x88);
  975.  
  976.   InstrZ = 0;
  977.   AddMem("LOAD"   , CPU29245, False, 0x16); AddMem("LOADL"  , CPU29245, False, 0x06);
  978.   AddMem("LOADM"  , CPU29245, False, 0x36); AddMem("LOADSET", CPU29245, False, 0x26);
  979.   AddMem("STORE"  , CPU29245, False, 0x1e); AddMem("STOREL" , CPU29245, False, 0x0e);
  980.   AddMem("STOREM" , CPU29245, False, 0x3e);
  981.  
  982.   InstrZ = 0;
  983.   AddSP("VAB",   0);
  984.   AddSP("OPS",   1);
  985.   AddSP("CPS",   2);
  986.   AddSP("CFG",   3);
  987.   AddSP("CHA",   4);
  988.   AddSP("CHD",   5);
  989.   AddSP("CHC",   6);
  990.   AddSP("RBP",   7);
  991.   AddSP("TMC",   8);
  992.   AddSP("TMR",   9);
  993.   AddSP("PC0",  10);
  994.   AddSP("PC1",  11);
  995.   AddSP("PC2",  12);
  996.   AddSP("MMU",  13);
  997.   AddSP("LRU",  14);
  998.   AddSP("CIR",  29);
  999.   AddSP("CDR",  30);
  1000.   AddSP("IPC", 128);
  1001.   AddSP("IPA", 129);
  1002.   AddSP("IPB", 130);
  1003.   AddSP("Q",   131);
  1004.   AddSP("ALU", 132);
  1005.   AddSP("BP",  133);
  1006.   AddSP("FC",  134);
  1007.   AddSP("CR",  135);
  1008.   AddSP("FPE", 160);
  1009.   AddSP("INTE",161);
  1010.   AddSP("FPS", 162);
  1011.   AddSP(NULL ,   0);
  1012. }
  1013.  
  1014. static void DeinitFields(void)
  1015. {
  1016.   DestroyInstTable(InstTable);
  1017.   order_array_free(StdOrders);
  1018.   order_array_free(NoImmOrders);
  1019.   order_array_free(VecOrders);
  1020.   order_array_free(JmpOrders);
  1021.   order_array_free(FixedOrders);
  1022.   order_array_free(MemOrders);
  1023.   order_array_free(SPRegs);
  1024. }
  1025.  
  1026. /*-------------------------------------------------------------------------*/
  1027.  
  1028. /*!------------------------------------------------------------------------
  1029.  * \fn     InternSymbol_29K(char *pArg, TempResult *pResult)
  1030.  * \brief  handle built-in symbols on 29K
  1031.  * \param  pArg source argument
  1032.  * \param  pResult result buffer
  1033.  * ------------------------------------------------------------------------ */
  1034.  
  1035. static void InternSymbol_29K(char *pArg, TempResult *pResult)
  1036. {
  1037.   LongWord Reg;
  1038.  
  1039.   if (DecodeRegCore(pArg, &Reg))
  1040.   {
  1041.     pResult->Typ = TempReg;
  1042.     pResult->DataSize = eSymbolSize32Bit;
  1043.     pResult->Contents.RegDescr.Reg = Reg;
  1044.     pResult->Contents.RegDescr.Dissect = DissectReg_29K;
  1045.     pResult->Contents.RegDescr.compare = compare_reg_29k;
  1046.   }
  1047. }
  1048.  
  1049. static void MakeCode_29K(void)
  1050. {
  1051.   CodeLen = 0;
  1052.   DontPrint = False;
  1053.  
  1054.   /* Nullanweisung */
  1055.  
  1056.   if (Memo("") && !*AttrPart.str.p_str && (ArgCnt == 0))
  1057.     return;
  1058.  
  1059.   /* Pseudoanweisungen */
  1060.  
  1061.   if (DecodeIntelPseudo(True))
  1062.     return;
  1063.  
  1064.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1065.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1066. }
  1067.  
  1068. static void InitCode_29K(void)
  1069. {
  1070.   Reg_RBP = 0;
  1071.   ClearStringList(&Emulations);
  1072. }
  1073.  
  1074. static Boolean IsDef_29K(void)
  1075. {
  1076.   return Memo("REG");
  1077. }
  1078.  
  1079. static void SwitchTo_29K(void)
  1080. {
  1081.   static ASSUMERec ASSUME29Ks[] =
  1082.   {
  1083.     {"RBP", &Reg_RBP, 0, 0xff, 0x00000000, NULL}
  1084.   };
  1085.   static const int ASSUME29KCount = sizeof(ASSUME29Ks) / sizeof(*ASSUME29Ks);
  1086.   TurnWords = True;
  1087.   SetIntConstMode(eIntConstModeC);
  1088.  
  1089.   PCSymbol = "$";
  1090.   HeaderID = 0x29;
  1091.   NOPCode = 0x000000000;
  1092.   DivideChars = ",";
  1093.   HasAttrs = False;
  1094.  
  1095.   ValidSegs = 1 << SegCode;
  1096.   Grans[SegCode] = 1; ListGrans[SegCode] = 4; SegInits[SegCode] = 0;
  1097.   SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
  1098.  
  1099.   MakeCode = MakeCode_29K;
  1100.   IsDef = IsDef_29K;
  1101.   InternSymbol = InternSymbol_29K;
  1102.   DissectReg = DissectReg_29K;
  1103.   onoff_supmode_add();
  1104.  
  1105.   pASSUMERecs = ASSUME29Ks;
  1106.   ASSUMERecCnt = ASSUME29KCount;
  1107.  
  1108.   SwitchFrom = DeinitFields; InitFields();
  1109. }
  1110.  
  1111. void code29k_init(void)
  1112. {
  1113.   CPU29245 = AddCPU("AM29245", SwitchTo_29K);
  1114.   CPU29243 = AddCPU("AM29243", SwitchTo_29K);
  1115.   CPU29240 = AddCPU("AM29240", SwitchTo_29K);
  1116.   CPU29000 = AddCPU("AM29000", SwitchTo_29K);
  1117.  
  1118.   Emulations = NULL;
  1119.  
  1120.   AddInitPassProc(InitCode_29K);
  1121. }
  1122.