Subversion Repositories pentevo

Rev

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

  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;
  267.  
  268.   if (ChkArgCnt(2, 3) && DecodeArgReg(1, &Dest))
  269.   {
  270.     LongWord Src1;
  271.     Boolean OK;
  272.  
  273.     if (ArgCnt == 2)
  274.     {
  275.       Src1 = Dest;
  276.       OK = True;
  277.     }
  278.     else
  279.       OK = DecodeArgReg(2, &Src1);
  280.     if (OK)
  281.     {
  282.       LongWord Src2, Src3 = 0;
  283.  
  284.       switch (DecodeReg(&ArgStr[ArgCnt], &Src2, False))
  285.       {
  286.         case eIsReg:
  287.           OK = True;
  288.           break;
  289.         case eIsNoReg:
  290.           Src2 = EvalStrIntExpression(&ArgStr[ArgCnt], UInt8, &OK);
  291.           Src3 = 0x1000000;
  292.           break;
  293.         case eRegAbort:
  294.           return;
  295.       }
  296.       if (OK)
  297.       {
  298.         CodeLen = 4;
  299.         DAsmCode[0] = (pOrder->Code << 24) + Src3 + (Dest << 16) + (Src1 << 8) + Src2;
  300.         if (pOrder->MustSup)
  301.           ChkSup();
  302.       }
  303.     }
  304.   }
  305. }
  306.  
  307. /* Variante 2: Register <-- Register op Register */
  308.  
  309. static void DecodeNoImm(Word Index)
  310. {
  311.   const StdOrder *pOrder = NoImmOrders + Index;
  312.   Boolean OK;
  313.   LongWord Dest, Src1, Src2;
  314.  
  315.   if (ChkArgCnt(2, 3) && DecodeArgReg(1, &Dest))
  316.   {
  317.     OK = True;
  318.     if (ArgCnt == 2) Src1 = Dest;
  319.     else OK = DecodeArgReg(2, &Src1);
  320.     if (OK && DecodeArgReg(ArgCnt, &Src2))
  321.     {
  322.       CodeLen = 4;
  323.       DAsmCode[0] = (pOrder->Code << 24) + (Dest << 16) + (Src1 << 8) + Src2;
  324.       if (pOrder->MustSup)
  325.         ChkSup();
  326.     }
  327.   }
  328. }
  329.  
  330. /* Variante 3: Vektor <-- Register op Register/uimm8 */
  331.  
  332. static void DecodeVec(Word Index)
  333. {
  334.   const StdOrder *pOrder = VecOrders + Index;
  335.   Boolean OK;
  336.   tSymbolFlags Flags;
  337.   LongWord Dest, Src1, Src2, Src3;
  338.  
  339.   if (ChkArgCnt(3, 3))
  340.   {
  341.     Dest = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt8, &OK, &Flags);
  342.     if (mFirstPassUnknown(Flags)) Dest = 64;
  343.     if (OK)
  344.     {
  345.       if (DecodeArgReg(2, &Src1))
  346.       {
  347.         switch (DecodeReg(&ArgStr[ArgCnt], &Src2, False))
  348.         {
  349.           case eIsReg:
  350.             OK = True; Src3 = 0;
  351.             break;
  352.           case eIsNoReg:
  353.             Src2 = EvalStrIntExpression(&ArgStr[ArgCnt], UInt8, &OK);
  354.             Src3 = 0x1000000;
  355.             break;
  356.           default:
  357.             return;
  358.         }
  359.         if (OK)
  360.         {
  361.           CodeLen = 4;
  362.           DAsmCode[0] = (pOrder->Code << 24) + Src3 + (Dest << 16) + (Src1 << 8) + Src2;
  363.           if ((pOrder->MustSup) || (Dest <= 63))
  364.             ChkSup();
  365.         }
  366.       }
  367.     }
  368.   }
  369. }
  370.  
  371. /* Variante 4: ohne Operanden */
  372.  
  373. static void DecodeFixed(Word Code)
  374. {
  375.   const StdOrder *pOrder = FixedOrders + Code;
  376.  
  377.   if (ChkArgCnt(0, 0))
  378.   {
  379.     CodeLen = 4;
  380.     DAsmCode[0] = pOrder->Code << 24;
  381.     if (pOrder->MustSup)
  382.       ChkSup();
  383.   }
  384. }
  385.  
  386. /* Variante 5 : [0], Speichersteuerwort, Register, Register/uimm8 */
  387.  
  388. static void DecodeMem(Word Index)
  389. {
  390.   const StdOrder *pOrder = MemOrders + Index;
  391.   Boolean OK;
  392.   LongWord AdrLong, Dest, Src1, Src2, Src3;
  393.  
  394.   if (ChkArgCnt(3, 4))
  395.   {
  396.     if (ArgCnt == 3)
  397.     {
  398.       OK = True; AdrLong = 0;
  399.     }
  400.     else
  401.     {
  402.       AdrLong = EvalStrIntExpression(&ArgStr[1], Int32, &OK);
  403.       if (OK) OK = ChkRange(AdrLong, 0, 0);
  404.     }
  405.     if (OK)
  406.     {
  407.       Dest = EvalStrIntExpression(&ArgStr[ArgCnt - 2], UInt7, &OK);
  408.       if (OK && DecodeArgReg(ArgCnt - 1, &Src1))
  409.       {
  410.         switch (DecodeReg(&ArgStr[ArgCnt], &Src2, False))
  411.         {
  412.           case eIsReg:
  413.             OK = True; Src3 = 0;
  414.             break;
  415.           case eIsNoReg:
  416.             Src2 = EvalStrIntExpression(&ArgStr[ArgCnt], UInt8, &OK);
  417.             Src3 = 0x1000000;
  418.             break;
  419.           default:
  420.             return;
  421.         }
  422.         if (OK)
  423.         {
  424.           CodeLen = 4;
  425.           DAsmCode[0] = (pOrder->Code << 24) + Src3 + (Dest << 16) + (Src1 << 8) + Src2;
  426.           if (pOrder->MustSup)
  427.             ChkSup();
  428.         }
  429.       }
  430.     }
  431.   }
  432. }
  433.  
  434. /* Sprungbefehle */
  435.  
  436. static void DecodeJmp(Word Index)
  437. {
  438.   const JmpOrder *pOrder = JmpOrders + (Index & 0xff);
  439.   Word Immediate = Index & 0x100;
  440.   LongWord Dest, Src1, AdrLong;
  441.   LongInt AdrInt;
  442.   Boolean OK;
  443.   tSymbolFlags Flags;
  444.   unsigned NumArgs = 1 + Ord(pOrder->HasReg);
  445.  
  446.   if (!ChkArgCnt(NumArgs, NumArgs))
  447.     return;
  448.  
  449.   switch (DecodeReg(&ArgStr[ArgCnt], &Src1, False))
  450.   {
  451.     case eIsReg:
  452.       if (!pOrder->HasReg)
  453.       {
  454.         Dest = 0;
  455.         OK = True;
  456.       }
  457.       else
  458.         OK = DecodeReg(&ArgStr[1], &Dest, True);
  459.       if (OK)
  460.       {
  461.         CodeLen = 4;
  462.         DAsmCode[0] = ((pOrder->Code + 0x20) << 24) + (Dest << 8) + Src1;
  463.       }
  464.       break;
  465.     case eRegAbort:
  466.       return;
  467.     case eIsNoReg:
  468.       if (Immediate) WrError(ErrNum_InvAddrMode);
  469.       else
  470.       {
  471.         if (!pOrder->HasReg)
  472.         {
  473.           Dest = 0;
  474.           OK = True;
  475.         }
  476.         else
  477.           OK = DecodeReg(&ArgStr[1], &Dest, True);
  478.         if (OK)
  479.         {
  480.           AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[ArgCnt], Int32, &OK, &Flags);
  481.           AdrInt = AdrLong - EProgCounter();
  482.           if (OK)
  483.           {
  484.             if ((AdrLong & 3) != 0) WrError(ErrNum_NotAligned);
  485.              else if ((AdrInt <= 0x1ffff) && (AdrInt >= -0x20000))
  486.             {
  487.               CodeLen = 4;
  488.               AdrLong -= EProgCounter();
  489.               DAsmCode[0] = (pOrder->Code << 24)
  490.                           + ((AdrLong & 0x3fc00) << 6)
  491.                           + (Dest << 8) + ((AdrLong & 0x3fc) >> 2);
  492.             }
  493.             else if (!mSymbolQuestionable(Flags) && (AdrLong > 0x3fffff)) WrError(ErrNum_JmpDistTooBig);
  494.             else
  495.             {
  496.               CodeLen = 4;
  497.               DAsmCode[0] = ((pOrder->Code + 1) << 24)
  498.                           + ((AdrLong & 0x3fc00) << 6)
  499.                           + (Dest << 8) + ((AdrLong & 0x3fc) >> 2);
  500.             }
  501.           }
  502.         }
  503.       }
  504.   }
  505. }
  506.  
  507. static void DecodeCLASS(Word Code)
  508. {
  509.   LongWord Dest, Src1, Src2;
  510.   Boolean OK;
  511.  
  512.   UNUSED(Code);
  513.  
  514.   if (ChkArgCnt(3, 3)
  515.    && ChkCPU(CPU29000)
  516.    && DecodeArgReg(1, &Dest)
  517.    && DecodeArgReg(2, &Src1))
  518.   {
  519.     Src2 = EvalStrIntExpression(&ArgStr[3], UInt2, &OK);
  520.     if (OK)
  521.     {
  522.       CodeLen = 4;
  523.       DAsmCode[0] = 0xe6000000 + (Dest << 16) + (Src1 << 8) + Src2;
  524.     }
  525.   }
  526. }
  527.  
  528. static void DecodeEMULATE(Word Code)
  529. {
  530.   LongWord Dest, Src1, Src2;
  531.   Boolean OK;
  532.   tSymbolFlags Flags;
  533.  
  534.   UNUSED(Code);
  535.  
  536.   if (ChkArgCnt(3, 3))
  537.   {
  538.     Dest = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt8, &OK, &Flags);
  539.     if (mFirstPassUnknown(Flags)) Dest = 64;
  540.     if (OK)
  541.     {
  542.       if (DecodeArgReg(2, &Src1)
  543.        && DecodeArgReg(ArgCnt, &Src2))
  544.       {
  545.         CodeLen = 4;
  546.         DAsmCode[0] = 0xd7000000 + (Dest << 16) + (Src1 << 8) + Src2;
  547.         if (Dest <= 63)
  548.           ChkSup();
  549.       }
  550.     }
  551.   }
  552. }
  553.  
  554. static void DecodeSQRT(Word Code)
  555. {
  556.   Boolean OK;
  557.   LongWord Src1, Src2, Dest;
  558.  
  559.   UNUSED(Code);
  560.  
  561.   if (ChkArgCnt(2, 3)
  562.    && ChkCPU(CPU29000)
  563.    && DecodeArgReg(1, &Dest))
  564.   {
  565.     if (ArgCnt == 2)
  566.     {
  567.       OK = True;
  568.       Src1 = Dest;
  569.     }
  570.     else
  571.       OK = DecodeArgReg(2, &Src1);
  572.     if (OK)
  573.     {
  574.       Src2 = EvalStrIntExpression(&ArgStr[ArgCnt], UInt2, &OK);
  575.       if (OK)
  576.       {
  577.         CodeLen = 4;
  578.         DAsmCode[0] = 0xe5000000 + (Dest << 16) + (Src1 << 8) + Src2;
  579.       }
  580.     }
  581.   }
  582. }
  583.  
  584. static void DecodeCLZ(Word Code)
  585. {
  586.   Boolean OK;
  587.   LongWord Src1, Src3, Dest;
  588.  
  589.   UNUSED(Code);
  590.  
  591.   if (ChkArgCnt(2, 2) && DecodeArgReg(1, &Dest))
  592.   {
  593.     switch (DecodeReg(&ArgStr[2], &Src1, False))
  594.     {
  595.       case eIsReg:
  596.         OK = True; Src3 = 0;
  597.         break;
  598.       case eIsNoReg:
  599.         Src1 = EvalStrIntExpression(&ArgStr[2], UInt8, &OK);
  600.         Src3 = 0x1000000;
  601.         break;
  602.       default:
  603.         return;
  604.     }
  605.     if (OK)
  606.     {
  607.       CodeLen = 4;
  608.       DAsmCode[0] = 0x08000000 + Src3 + (Dest << 16) + Src1;
  609.     }
  610.   }
  611. }
  612.  
  613. static void DecodeCONST(Word Code)
  614. {
  615.   Boolean OK;
  616.   LongWord AdrLong, Dest;
  617.   UNUSED(Code);
  618.  
  619.   if (ChkArgCnt(2, 2) && DecodeArgReg(1, &Dest))
  620.   {
  621.     AdrLong = EvalStrIntExpression(&ArgStr[2], Int32, &OK);
  622.     if (OK)
  623.     {
  624.       CodeLen = 4;
  625.       DAsmCode[0] = ((AdrLong & 0xff00) << 8) + (Dest << 8) + (AdrLong & 0xff);
  626.       AdrLong = AdrLong >> 16;
  627.       if (AdrLong == 0xffff) DAsmCode[0] += 0x01000000;
  628.       else
  629.       {
  630.         DAsmCode[0] += 0x03000000;
  631.         if (AdrLong != 0)
  632.         {
  633.           CodeLen = 8;
  634.           DAsmCode[1] = 0x02000000 + ((AdrLong & 0xff00) << 16) + (Dest << 8) + (AdrLong & 0xff);
  635.         }
  636.       }
  637.     }
  638.   }
  639.   return;
  640. }
  641.  
  642. static void DecodeCONSTH_CONSTN(Word IsHi)
  643. {
  644.   Boolean OK;
  645.   LongWord AdrLong, Dest;
  646.   tSymbolFlags Flags;
  647.  
  648.   if (ChkArgCnt(2, 2) && DecodeArgReg(1, &Dest))
  649.   {
  650.     AdrLong = EvalStrIntExpressionWithFlags(&ArgStr[2], Int32, &OK, &Flags);
  651.     if (mFirstPassUnknown(Flags))
  652.       AdrLong &= 0xffff;
  653.     if ((!IsHi) && ((AdrLong >> 16) == 0xffff))
  654.       AdrLong &= 0xffff;
  655.     if (ChkRange(AdrLong, 0, 0xffff))
  656.     {
  657.       CodeLen = 4;
  658.       DAsmCode[0] = 0x1000000 + ((AdrLong & 0xff00) << 8) + (Dest << 8) + (AdrLong & 0xff);
  659.       if (IsHi)
  660.         DAsmCode[0] += 0x1000000;
  661.     }
  662.   }
  663. }
  664.  
  665. static void DecodeCONVERT(Word Code)
  666. {
  667.   Boolean OK;
  668.   LongWord Src1, Src2, Dest;
  669.  
  670.   UNUSED(Code);
  671.  
  672.   if (ChkArgCnt(6, 6)
  673.    && ChkCPU(CPU29000)
  674.    && DecodeArgReg(1, &Dest)
  675.    && DecodeArgReg(2, &Src1))
  676.   {
  677.     Src2 = 0;
  678.     Src2 += EvalStrIntExpression(&ArgStr[3], UInt1, &OK) << 7;
  679.     if (OK)
  680.     {
  681.       Src2 += EvalStrIntExpression(&ArgStr[4], UInt3, &OK) << 4;
  682.       if (OK)
  683.       {
  684.         Src2 += EvalStrIntExpression(&ArgStr[5], UInt2, &OK) << 2;
  685.         if (OK)
  686.         {
  687.           Src2 += EvalStrIntExpression(&ArgStr[6], UInt2, &OK);
  688.           if (OK)
  689.           {
  690.             CodeLen = 4;
  691.             DAsmCode[0] = 0xe4000000 + (Dest << 16) + (Src1 << 8) + Src2;
  692.           }
  693.         }
  694.       }
  695.     }
  696.   }
  697. }
  698.  
  699. static void DecodeEXHWS(Word Code)
  700. {
  701.   LongWord Src1, Dest;
  702.  
  703.   UNUSED(Code);
  704.  
  705.   if (ChkArgCnt(2, 2)
  706.    && DecodeArgReg(1, &Dest)
  707.    && DecodeArgReg(2, &Src1))
  708.   {
  709.     CodeLen = 4;
  710.     DAsmCode[0] = 0x7e000000 + (Dest << 16) + (Src1 << 8);
  711.   }
  712. }
  713.  
  714. static void DecodeINV_IRETINV(Word Code)
  715. {
  716.   Boolean OK;
  717.   LongWord Src1;
  718.  
  719.   if (ChkArgCnt(0, 1))
  720.   {
  721.     if (ArgCnt == 0)
  722.     {
  723.       Src1 = 0; OK = True;
  724.     }
  725.     else Src1 = EvalStrIntExpression(&ArgStr[1], UInt2, &OK);
  726.     if (OK)
  727.     {
  728.       CodeLen = 4;
  729.       DAsmCode[0] = (((LongWord)Code) << 16) | Src1 << 16;
  730.       ChkSup();
  731.     }
  732.   }
  733. }
  734.  
  735. static void DecodeMFSR(Word Code)
  736. {
  737.   LongWord Src1, Dest;
  738.  
  739.   UNUSED(Code);
  740.  
  741.   if (ChkArgCnt(2, 2)
  742.    && DecodeArgReg(1, &Dest)
  743.    && DecodeArgSpReg(2, &Src1))
  744.   {
  745.     DAsmCode[0] = 0xc6000000 + (Dest << 16) + (Src1 << 8);
  746.     CodeLen = 4;
  747.     if (IsSup(Src1))
  748.       ChkSup();
  749.   }
  750. }
  751.  
  752. static void DecodeMTSR(Word Code)
  753. {
  754.   LongWord Src1, Dest;
  755.  
  756.   UNUSED(Code);
  757.  
  758.   if (ChkArgCnt(2, 2)
  759.    && DecodeArgSpReg(1, &Dest)
  760.    && DecodeArgReg(2, &Src1))
  761.   {
  762.     DAsmCode[0] = 0xce000000 + (Dest << 8) + Src1;
  763.     CodeLen = 4;
  764.     if (IsSup(Dest))
  765.       ChkSup();
  766.   }
  767. }
  768.  
  769. static void DecodeMTSRIM(Word Code)
  770. {
  771.   LongWord Src1, Dest;
  772.   Boolean OK;
  773.  
  774.   UNUSED(Code);
  775.  
  776.   if (ChkArgCnt(2, 2) && DecodeArgSpReg(1, &Dest))
  777.   {
  778.     Src1 = EvalStrIntExpression(&ArgStr[2], UInt16, &OK);
  779.     if (OK)
  780.     {
  781.       DAsmCode[0] = 0x04000000 + ((Src1 & 0xff00) << 8) + (Dest << 8) + Lo(Src1);
  782.       CodeLen = 4;
  783.       if (IsSup(Dest))
  784.         ChkSup();
  785.     }
  786.   }
  787. }
  788.  
  789. static void DecodeMFTLB(Word Code)
  790. {
  791.   LongWord Src1, Dest;
  792.  
  793.   UNUSED(Code);
  794.  
  795.   if (ChkArgCnt(2, 2)
  796.    && DecodeArgReg(1, &Dest)
  797.    && DecodeArgReg(2, &Src1))
  798.   {
  799.     DAsmCode[0] = 0xb6000000 + (Dest << 16) + (Src1 << 8);
  800.     CodeLen = 4;
  801.     ChkSup();
  802.   }
  803. }
  804.  
  805. static void DecodeMTTLB(Word Code)
  806. {
  807.   LongWord Src1, Dest;
  808.  
  809.   UNUSED(Code);
  810.  
  811.   if (ChkArgCnt(2, 2)
  812.    && DecodeArgReg(1, &Dest)
  813.    && DecodeArgReg(2, &Src1))
  814.   {
  815.     DAsmCode[0] = 0xbe000000 + (Dest << 8) + Src1;
  816.     CodeLen = 4;
  817.     ChkSup();
  818.   }
  819. }
  820.  
  821. static void DecodeEMULATED(Word Code)
  822. {
  823.   int z;
  824.  
  825.   UNUSED(Code);
  826.  
  827.   if (ChkArgCnt(1, ArgCntMax))
  828.     for (z = 1; z <= ArgCnt; z++)
  829.     {
  830.       NLS_UpString(ArgStr[z].str.p_str);
  831.       if (!StringListPresent(Emulations, ArgStr[z].str.p_str))
  832.         AddStringListLast(&Emulations, ArgStr[z].str.p_str);
  833.     }
  834. }
  835.  
  836. /*-------------------------------------------------------------------------*/
  837.  
  838. static void AddStd(const char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
  839. {
  840.   order_array_rsv_end(StdOrders, StdOrder);
  841.   StdOrders[InstrZ].Code = NCode;
  842.   StdOrders[InstrZ].MustSup = NSup;
  843.   StdOrders[InstrZ].MinCPU = NMin;
  844.   AddInstTable(InstTable, NName, InstrZ++, DecodeStd);
  845. }
  846.  
  847. static void AddNoImm(const char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
  848. {
  849.   order_array_rsv_end(NoImmOrders, StdOrder);
  850.   NoImmOrders[InstrZ].Code = NCode;
  851.   NoImmOrders[InstrZ].MustSup = NSup;
  852.   NoImmOrders[InstrZ].MinCPU = NMin;
  853.   AddInstTable(InstTable, NName, InstrZ++, DecodeNoImm);
  854. }
  855.  
  856. static void AddVec(const char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
  857. {
  858.   order_array_rsv_end(VecOrders, StdOrder);
  859.   VecOrders[InstrZ].Code = NCode;
  860.   VecOrders[InstrZ].MustSup = NSup;
  861.   VecOrders[InstrZ].MinCPU = NMin;
  862.   AddInstTable(InstTable, NName, InstrZ++, DecodeVec);
  863. }
  864.  
  865. static void AddJmp(const char *NName, CPUVar NMin, Boolean NHas, Boolean NInd, LongWord NCode)
  866. {
  867.   char IName[30];
  868.  
  869.   order_array_rsv_end(JmpOrders, JmpOrder);
  870.   JmpOrders[InstrZ].HasReg = NHas;
  871.   JmpOrders[InstrZ].HasInd = NInd;
  872.   JmpOrders[InstrZ].Code = NCode;
  873.   JmpOrders[InstrZ].MinCPU = NMin;
  874.   AddInstTable(InstTable, NName, InstrZ, DecodeJmp);
  875.   as_snprintf(IName, sizeof(IName), "%sI", NName);
  876.   AddInstTable(InstTable, IName, 0x100 | InstrZ, DecodeJmp);
  877.   InstrZ++;
  878. }
  879.  
  880. static void AddFixed(const char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
  881. {
  882.   order_array_rsv_end(FixedOrders, StdOrder);
  883.   FixedOrders[InstrZ].Code = NCode;
  884.   FixedOrders[InstrZ].MustSup = NSup;
  885.   FixedOrders[InstrZ].MinCPU = NMin;
  886.   AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
  887. }
  888.  
  889. static void AddMem(const char *NName, CPUVar NMin, Boolean NSup, LongWord NCode)
  890. {
  891.   order_array_rsv_end(MemOrders, StdOrder);
  892.   MemOrders[InstrZ].Code = NCode;
  893.   MemOrders[InstrZ].MustSup = NSup;
  894.   MemOrders[InstrZ].MinCPU = NMin;
  895.   AddInstTable(InstTable, NName, InstrZ++, DecodeMem);
  896. }
  897.  
  898. static void AddSP(const char *NName, LongWord NCode)
  899. {
  900.   order_array_rsv_end(SPRegs, SPReg);
  901.   SPRegs[InstrZ].Name = NName;
  902.   SPRegs[InstrZ++].Code = NCode;
  903. }
  904.  
  905. static void InitFields(void)
  906. {
  907.   InstTable = CreateInstTable(307);
  908.   SetDynamicInstTable(InstTable);
  909.   AddInstTable(InstTable, "CLASS", 0, DecodeCLASS);
  910.   AddInstTable(InstTable, "EMULATE", 0, DecodeEMULATE);
  911.   AddInstTable(InstTable, "SQRT", 0, DecodeSQRT);
  912.   AddInstTable(InstTable, "CLZ", 0, DecodeCLZ);
  913.   AddInstTable(InstTable, "CONST", 0, DecodeCONST);
  914.   AddInstTable(InstTable, "CONSTH", True, DecodeCONSTH_CONSTN);
  915.   AddInstTable(InstTable, "CONSTN", False, DecodeCONSTH_CONSTN);
  916.   AddInstTable(InstTable, "CONVERT", 0, DecodeCONVERT);
  917.   AddInstTable(InstTable, "EXHWS", 0, DecodeEXHWS);
  918.   AddInstTable(InstTable, "INV", 0x9f00, DecodeINV_IRETINV);
  919.   AddInstTable(InstTable, "IRETINV", 0x8c00, DecodeINV_IRETINV);
  920.   AddInstTable(InstTable, "MFSR", 0, DecodeMFSR);
  921.   AddInstTable(InstTable, "MTSR", 0, DecodeMTSR);
  922.   AddInstTable(InstTable, "MTSRIM", 0, DecodeMTSRIM);
  923.   AddInstTable(InstTable, "MFTLB", 0, DecodeMFTLB);
  924.   AddInstTable(InstTable, "MTTLB", 0, DecodeMTTLB);
  925.   AddInstTable(InstTable, "EMULATED", 0, DecodeEMULATED);
  926.   AddInstTable(InstTable, "REG", 0, CodeREG);
  927.  
  928.   InstrZ = 0;
  929.   AddStd("ADD"    , CPU29245, False, 0x14); AddStd("ADDC"   , CPU29245, False, 0x1c);
  930.   AddStd("ADDCS"  , CPU29245, False, 0x18); AddStd("ADDCU"  , CPU29245, False, 0x1a);
  931.   AddStd("ADDS"   , CPU29245, False, 0x10); AddStd("ADDU"   , CPU29245, False, 0x12);
  932.   AddStd("AND"    , CPU29245, False, 0x90); AddStd("ANDN"   , CPU29245, False, 0x9c);
  933.   AddStd("CPBYTE" , CPU29245, False, 0x2e); AddStd("CPEQ"   , CPU29245, False, 0x60);
  934.   AddStd("CPGE"   , CPU29245, False, 0x4c); AddStd("CPGEU"  , CPU29245, False, 0x4e);
  935.   AddStd("CPGT"   , CPU29245, False, 0x48); AddStd("CPGTU"  , CPU29245, False, 0x4a);
  936.   AddStd("CPLE"   , CPU29245, False, 0x44); AddStd("CPLEU"  , CPU29245, False, 0x46);
  937.   AddStd("CPLT"   , CPU29245, False, 0x40); AddStd("CPLTU"  , CPU29245, False, 0x42);
  938.   AddStd("CPNEQ"  , CPU29245, False, 0x62); AddStd("DIV"    , CPU29245, False, 0x6a);
  939.   AddStd("DIV0"   , CPU29245, False, 0x68); AddStd("DIVL"   , CPU29245, False, 0x6c);
  940.   AddStd("DIVREM" , CPU29245, False, 0x6e); AddStd("EXBYTE" , CPU29245, False, 0x0a);
  941.   AddStd("EXHW"   , CPU29245, False, 0x7c); AddStd("EXTRACT", CPU29245, False, 0x7a);
  942.   AddStd("INBYTE" , CPU29245, False, 0x0c); AddStd("INHW"   , CPU29245, False, 0x78);
  943.   AddStd("MUL"    , CPU29245, False, 0x64); AddStd("MULL"   , CPU29245, False, 0x66);
  944.   AddStd("MULU"   , CPU29245, False, 0x74); AddStd("NAND"   , CPU29245, False, 0x9a);
  945.   AddStd("NOR"    , CPU29245, False, 0x98); AddStd("OR"     , CPU29245, False, 0x92);
  946.   AddStd("SLL"    , CPU29245, False, 0x80); AddStd("SRA"    , CPU29245, False, 0x86);
  947.   AddStd("SRL"    , CPU29245, False, 0x82); AddStd("SUB"    , CPU29245, False, 0x24);
  948.   AddStd("SUBC"   , CPU29245, False, 0x2c); AddStd("SUBCS"  , CPU29245, False, 0x28);
  949.   AddStd("SUBCU"  , CPU29245, False, 0x2a); AddStd("SUBR"   , CPU29245, False, 0x34);
  950.   AddStd("SUBRC"  , CPU29245, False, 0x3c); AddStd("SUBRCS" , CPU29245, False, 0x38);
  951.   AddStd("SUBRCU" , CPU29245, False, 0x3a); AddStd("SUBRS"  , CPU29245, False, 0x30);
  952.   AddStd("SUBRU"  , CPU29245, False, 0x32); AddStd("SUBS"   , CPU29245, False, 0x20);
  953.   AddStd("SUBU"   , CPU29245, False, 0x22); AddStd("XNOR"   , CPU29245, False, 0x96);
  954.   AddStd("XOR"    , CPU29245, False, 0x94);
  955.  
  956.   InstrZ = 0;
  957.   AddNoImm("DADD"    , CPU29000, False, 0xf1); AddNoImm("DDIV"    , CPU29000, False, 0xf7);
  958.   AddNoImm("DEQ"     , CPU29000, False, 0xeb); AddNoImm("DGE"     , CPU29000, False, 0xef);
  959.   AddNoImm("DGT"     , CPU29000, False, 0xed); AddNoImm("DIVIDE"  , CPU29000, False, 0xe1);
  960.   AddNoImm("DIVIDU"  , CPU29000, False, 0xe3); AddNoImm("DMUL"    , CPU29000, False, 0xf5);
  961.   AddNoImm("DSUB"    , CPU29000, False, 0xf3); AddNoImm("FADD"    , CPU29000, False, 0xf0);
  962.   AddNoImm("FDIV"    , CPU29000, False, 0xf6); AddNoImm("FDMUL"   , CPU29000, False, 0xf9);
  963.   AddNoImm("FEQ"     , CPU29000, False, 0xea); AddNoImm("FGE"     , CPU29000, False, 0xee);
  964.   AddNoImm("FGT"     , CPU29000, False, 0xec); AddNoImm("FMUL"    , CPU29000, False, 0xf4);
  965.   AddNoImm("FSUB"    , CPU29000, False, 0xf2); AddNoImm("MULTIPLU", CPU29243, False, 0xe2);
  966.   AddNoImm("MULTIPLY", CPU29243, False, 0xe0); AddNoImm("MULTM"   , CPU29243, False, 0xde);
  967.   AddNoImm("MULTMU"  , CPU29243, False, 0xdf); AddNoImm("SETIP"   , CPU29245, False, 0x9e);
  968.  
  969.   InstrZ = 0;
  970.   AddVec("ASEQ"   , CPU29245, False, 0x70); AddVec("ASGE"   , CPU29245, False, 0x5c);
  971.   AddVec("ASGEU"  , CPU29245, False, 0x5e); AddVec("ASGT"   , CPU29245, False, 0x58);
  972.   AddVec("ASGTU"  , CPU29245, False, 0x5a); AddVec("ASLE"   , CPU29245, False, 0x54);
  973.   AddVec("ASLEU"  , CPU29245, False, 0x56); AddVec("ASLT"   , CPU29245, False, 0x50);
  974.   AddVec("ASLTU"  , CPU29245, False, 0x52); AddVec("ASNEQ"  , CPU29245, False, 0x72);
  975.  
  976.   InstrZ = 0;
  977.   AddJmp("CALL"   , CPU29245, True , True , 0xa8); AddJmp("JMP"    , CPU29245, False, True , 0xa0);
  978.   AddJmp("JMPF"   , CPU29245, True , True , 0xa4); AddJmp("JMPFDEC", CPU29245, True , False, 0xb4);
  979.   AddJmp("JMPT"   , CPU29245, True , True , 0xac);
  980.  
  981.   InstrZ = 0;
  982.   AddFixed("HALT"   , CPU29245, True, 0x89); AddFixed("IRET"   , CPU29245, True, 0x88);
  983.  
  984.   InstrZ = 0;
  985.   AddMem("LOAD"   , CPU29245, False, 0x16); AddMem("LOADL"  , CPU29245, False, 0x06);
  986.   AddMem("LOADM"  , CPU29245, False, 0x36); AddMem("LOADSET", CPU29245, False, 0x26);
  987.   AddMem("STORE"  , CPU29245, False, 0x1e); AddMem("STOREL" , CPU29245, False, 0x0e);
  988.   AddMem("STOREM" , CPU29245, False, 0x3e);
  989.  
  990.   InstrZ = 0;
  991.   AddSP("VAB",   0);
  992.   AddSP("OPS",   1);
  993.   AddSP("CPS",   2);
  994.   AddSP("CFG",   3);
  995.   AddSP("CHA",   4);
  996.   AddSP("CHD",   5);
  997.   AddSP("CHC",   6);
  998.   AddSP("RBP",   7);
  999.   AddSP("TMC",   8);
  1000.   AddSP("TMR",   9);
  1001.   AddSP("PC0",  10);
  1002.   AddSP("PC1",  11);
  1003.   AddSP("PC2",  12);
  1004.   AddSP("MMU",  13);
  1005.   AddSP("LRU",  14);
  1006.   AddSP("CIR",  29);
  1007.   AddSP("CDR",  30);
  1008.   AddSP("IPC", 128);
  1009.   AddSP("IPA", 129);
  1010.   AddSP("IPB", 130);
  1011.   AddSP("Q",   131);
  1012.   AddSP("ALU", 132);
  1013.   AddSP("BP",  133);
  1014.   AddSP("FC",  134);
  1015.   AddSP("CR",  135);
  1016.   AddSP("FPE", 160);
  1017.   AddSP("INTE",161);
  1018.   AddSP("FPS", 162);
  1019.   AddSP(NULL ,   0);
  1020.  
  1021.   AddIntelPseudo(InstTable, eIntPseudoFlag_BigEndian);
  1022. }
  1023.  
  1024. static void DeinitFields(void)
  1025. {
  1026.   DestroyInstTable(InstTable);
  1027.   order_array_free(StdOrders);
  1028.   order_array_free(NoImmOrders);
  1029.   order_array_free(VecOrders);
  1030.   order_array_free(JmpOrders);
  1031.   order_array_free(FixedOrders);
  1032.   order_array_free(MemOrders);
  1033.   order_array_free(SPRegs);
  1034. }
  1035.  
  1036. /*-------------------------------------------------------------------------*/
  1037.  
  1038. /*!------------------------------------------------------------------------
  1039.  * \fn     InternSymbol_29K(char *pArg, TempResult *pResult)
  1040.  * \brief  handle built-in symbols on 29K
  1041.  * \param  pArg source argument
  1042.  * \param  pResult result buffer
  1043.  * ------------------------------------------------------------------------ */
  1044.  
  1045. static void InternSymbol_29K(char *pArg, TempResult *pResult)
  1046. {
  1047.   LongWord Reg;
  1048.  
  1049.   if (DecodeRegCore(pArg, &Reg))
  1050.   {
  1051.     pResult->Typ = TempReg;
  1052.     pResult->DataSize = eSymbolSize32Bit;
  1053.     pResult->Contents.RegDescr.Reg = Reg;
  1054.     pResult->Contents.RegDescr.Dissect = DissectReg_29K;
  1055.     pResult->Contents.RegDescr.compare = compare_reg_29k;
  1056.   }
  1057. }
  1058.  
  1059. static void MakeCode_29K(void)
  1060. {
  1061.   /* Nullanweisung */
  1062.  
  1063.   if (Memo("") && !*AttrPart.str.p_str && (ArgCnt == 0))
  1064.     return;
  1065.  
  1066.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  1067.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  1068. }
  1069.  
  1070. static void InitCode_29K(void)
  1071. {
  1072.   Reg_RBP = 0;
  1073.   ClearStringList(&Emulations);
  1074. }
  1075.  
  1076. static Boolean IsDef_29K(void)
  1077. {
  1078.   return Memo("REG");
  1079. }
  1080.  
  1081. static void SwitchTo_29K(void)
  1082. {
  1083.   static ASSUMERec ASSUME29Ks[] =
  1084.   {
  1085.     {"RBP", &Reg_RBP, 0, 0xff, 0x00000000, NULL}
  1086.   };
  1087.   static const int ASSUME29KCount = sizeof(ASSUME29Ks) / sizeof(*ASSUME29Ks);
  1088.   TurnWords = True;
  1089.   SetIntConstMode(eIntConstModeC);
  1090.  
  1091.   PCSymbol = "$";
  1092.   HeaderID = 0x29;
  1093.   NOPCode = 0x000000000;
  1094.   DivideChars = ",";
  1095.   HasAttrs = False;
  1096.  
  1097.   ValidSegs = 1 << SegCode;
  1098.   Grans[SegCode] = 1; ListGrans[SegCode] = 4; SegInits[SegCode] = 0;
  1099.   SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
  1100.  
  1101.   MakeCode = MakeCode_29K;
  1102.   IsDef = IsDef_29K;
  1103.   InternSymbol = InternSymbol_29K;
  1104.   DissectReg = DissectReg_29K;
  1105.   onoff_supmode_add();
  1106.  
  1107.   pASSUMERecs = ASSUME29Ks;
  1108.   ASSUMERecCnt = ASSUME29KCount;
  1109.  
  1110.   SwitchFrom = DeinitFields; InitFields();
  1111. }
  1112.  
  1113. void code29k_init(void)
  1114. {
  1115.   CPU29245 = AddCPU("AM29245", SwitchTo_29K);
  1116.   CPU29243 = AddCPU("AM29243", SwitchTo_29K);
  1117.   CPU29240 = AddCPU("AM29240", SwitchTo_29K);
  1118.   CPU29000 = AddCPU("AM29000", SwitchTo_29K);
  1119.  
  1120.   Emulations = NULL;
  1121.  
  1122.   AddInitPassProc(InitCode_29K);
  1123. }
  1124.